diff --git a/worlds/sm/Options.py b/worlds/sm/Options.py index 26b3e246..02599841 100644 --- a/worlds/sm/Options.py +++ b/worlds/sm/Options.py @@ -1,5 +1,6 @@ import typing from Options import Choice, Range, OptionDict, OptionList, Option, Toggle, DefaultOnToggle +from .variaRandomizer.utils.objectives import _goals class StartItemsRemovesFromPool(Toggle): """Remove items in starting inventory from pool.""" @@ -125,7 +126,7 @@ class AreaRandomization(Choice): display_name = "Area Randomization" option_off = 0 option_light = 1 - option_on = 2 + option_full = 2 default = 0 class AreaLayout(Toggle): @@ -183,9 +184,13 @@ class GravityBehaviour(Choice): option_Progressive = 2 default = 1 -class ElevatorsDoorsSpeed(DefaultOnToggle): - """Accelerate doors and elevators transitions.""" - display_name = "Elevators doors speed" +class ElevatorsSpeed(DefaultOnToggle): + """Accelerate elevators transitions.""" + display_name = "Elevators speed" + +class DoorsSpeed(DefaultOnToggle): + """Accelerate doors transitions.""" + display_name = "Doors speed" class SpinJumpRestart(Toggle): """Allows Samus to start spinning in mid air after jumping or falling.""" @@ -239,6 +244,94 @@ class VariaCustomPreset(OptionList): display_name = "Varia Custom Preset" default = {} + +class EscapeRando(Toggle): + """ + When leaving Tourian, get teleported to the exit of a random Map station (between Brinstar/Maridia/Norfair/Wrecked Ship). + You then have to find your way to the ship in the remaining time. Allotted time depends on area layout, but not on skill settings and is pretty generous. + + During the escape sequence: + - All doors are opened + - Maridia tube is opened + - The Hyper Beam can destroy Bomb , Power Bomb and Super Missile blocks and open blue/green gates from both sides + - All mini bosses are defeated + - All minor enemies are removed to allow you to move faster and remove lag + + During regular game only Crateria Map station door can be opened and activating the station will act as if all map stations were activated at once. + + Animals Challenges: + You can use the extra available time to: + - find the animals that are hidden behind a (now blue) map station door + - go to the vanilla animals door to cycle through the 4 available escapes, and complete as many escapes as you can + + Pick your challenge, or try to do both, but watch your timer! + """ + display_name = "Randomize the escape sequence" + +class RemoveEscapeEnemies(Toggle): + """Remove enemies during escape sequence, disable it to blast through enemies with your Hyper Beam and cause lag.""" + display_name = "Remove enemies during escape" + +class Tourian(Choice): + """ + Choose endgame Tourian behaviour: + Vanilla: regular vanilla Tourian + Fast: speed up Tourian to skip Metroids, Zebetites, and all cutscenes (including Mother Brain 3 fight). Golden Four statues are replaced by an invincible Gadora until all objectives are completed. + Disabled: skip Tourian entirely, ie. escape sequence is triggered as soon as all objectives are completed. + """ + display_name = "Endgame behavior with Tourian" + option_Vanilla = 0 + option_Fast = 1 + option_Disabled = 2 + default = 0 + +class Objective(OptionList): + """ + Choose which objectives are required to sink the Golden Four statue and to open access to Tourian. + You can choose from 0 to 5 objectives. + Note: If you leave the list empty no objective is required to access Tourian, ie. it's open. + Note: See the Tourian parameter to enable fast Tourian or trigger the escape when all objectives are completed. + Note: Current percentage of collected items is displayed in the inventory pause menu. + Note: Collect 100% items is excluded by default when randomizing the objectives list as it requires you to complete all the objectives. + Note: In AP, Items% and areas objectives are counted toward location checks, not items collected or received, except for "collect all upgrades" + + Format as a comma-separated list of objective names: ["kill three G4", "collect 75% items"]. + A full list of supported objectives can be found at: + https://github.com/ArchipelagoMW/Archipelago/blob/main/worlds/sm/utils/objectives.py + """ + display_name = "Objectives" + default = ["kill all G4"] + valid_keys = frozenset({name: goal for (name, goal) in _goals.items()}) + #valid_keys_casefold = True + +class HideItems(Toggle): + """ + Hides half of the visible items. + Items always visible: + - Energy Tank, Gauntlet + - Energy Tank, Terminator + - Morphing Ball + - Missile (Crateria moat) + - Missile (green Brinstar below super missile) + - Missile (above Crocomire) + - Power Bomb (lower Norfair above fire flea room) + - Missile (Gravity Suit) + - Missile (green Maridia shinespark) + """ + display_name = "Hide half the items" + +class RelaxedRoundRobinCF(Toggle): + """ + Changes Crystal Flashes behavior and requirements as follows: + + You can perform a Crystal Flash with any amount of ammo, but you need at least one Power Bomb to begin the process. + After consuming 1 ammo, Samus gains 50 energy, and it will try a different ammo type next, + cycling through Missiles, Supers, and Power Bombs as available. The cycling is to keep the consumption even between ammo types. + If one of your ammo types is at 0, it will be skipped. + The Crystal Flash ends when Samus is out of ammo or a total of 30 ammo has been consumed. + """ + display_name = "Relaxed round robin Crystal Flash" + sm_options: typing.Dict[str, type(Option)] = { "start_inventory_removes_from_pool": StartItemsRemovesFromPool, "preset": Preset, @@ -254,7 +347,7 @@ sm_options: typing.Dict[str, type(Option)] = { #"progression_difficulty": "normal", "morph_placement": MorphPlacement, #"suits_restriction": SuitsRestriction, - #"hide_items": "off", + "hide_items": HideItems, "strict_minors": StrictMinors, "missile_qty": MissileQty, "super_qty": SuperQty, @@ -269,8 +362,8 @@ sm_options: typing.Dict[str, type(Option)] = { #"minimizer": "off", #"minimizer_qty": "45", #"minimizer_tourian": "off", - #"escape_rando": "off", - #"remove_escape_enemies": "off", + "escape_rando": EscapeRando, + "remove_escape_enemies": RemoveEscapeEnemies, "fun_combat": FunCombat, "fun_movement": FunMovement, "fun_suits": FunSuits, @@ -279,7 +372,8 @@ sm_options: typing.Dict[str, type(Option)] = { "nerfed_charge": NerfedCharge, "gravity_behaviour": GravityBehaviour, #"item_sounds": "on", - "elevators_doors_speed": ElevatorsDoorsSpeed, + "elevators_speed": ElevatorsSpeed, + "fast_doors": DoorsSpeed, "spin_jump_restart": SpinJumpRestart, "rando_speed": SpeedKeep, "infinite_space_jump": InfiniteSpaceJump, @@ -290,4 +384,7 @@ sm_options: typing.Dict[str, type(Option)] = { "random_music": RandomMusic, "custom_preset": CustomPreset, "varia_custom_preset": VariaCustomPreset, + "tourian": Tourian, + "objective": Objective, + "relaxed_round_robin_cf": RelaxedRoundRobinCF, } diff --git a/worlds/sm/__init__.py b/worlds/sm/__init__.py index e8e4c56a..24d67603 100644 --- a/worlds/sm/__init__.py +++ b/worlds/sm/__init__.py @@ -86,7 +86,7 @@ class SMWorld(World): game: str = "Super Metroid" topology_present = True - data_version = 2 + data_version = 3 option_definitions = sm_options item_name_to_id = {value.Name: items_start_id + value.Id for key, value in ItemManager.Items.items() if value.Id != None} @@ -140,8 +140,8 @@ class SMWorld(World): if (item in itemPool): itemPool.remove(item) - missingPool = 105 - len(itemPool) + 1 - for i in range(1, missingPool): + missingPool = 109 - len(itemPool) + for i in range(missingPool): itemPool.append(ItemManager.Items['Nothing']) # Generate item pool @@ -209,10 +209,11 @@ class SMWorld(World): """ little-endian convert a 16-bit number to an array of numbers <= 255 each """ return [w & 0x00FF, (w & 0xFF00) >> 8] - # used for remote location Credits Spoiler of local items + # used for remote location Credits Spoiler of local items and Objectives' writeItemsMasks class DummyLocation: def __init__(self, name): self.Name = name + self.restricted = False def isBoss(self): return False @@ -337,7 +338,7 @@ class SMWorld(World): idx = 0 vanillaItemTypesCount = 21 for itemLoc in self.multiworld.get_locations(): - if itemLoc.player == self.player and locationsDict[itemLoc.name].Id != None: + if itemLoc.player == self.player and "Boss" not in locationsDict[itemLoc.name].Class: # item to place in this SM world: write full item data to tables if isinstance(itemLoc.item, SMItem) and itemLoc.item.type in ItemManager.Items: itemId = ItemManager.Items[itemLoc.item.type].Id @@ -522,22 +523,38 @@ class SMWorld(World): # commit all the changes we've made here to the ROM romPatcher.commitIPS() - itemLocs = [ - ItemLocation(ItemManager.Items[itemLoc.item.type - if isinstance(itemLoc.item, SMItem) and itemLoc.item.type in ItemManager.Items else - 'ArchipelagoItem'], - locationsDict[itemLoc.name], True) - for itemLoc in self.multiworld.get_locations() if itemLoc.player == self.player - ] - romPatcher.writeItemsLocs(itemLocs) - itemLocs = [ItemLocation(ItemManager.Items[itemLoc.item.type], locationsDict[itemLoc.name] if itemLoc.name in locationsDict and itemLoc.player == self.player else self.DummyLocation(self.multiworld.get_player_name(itemLoc.player) + " " + itemLoc.name), True) for itemLoc in self.multiworld.get_locations() if itemLoc.item.player == self.player] progItemLocs = [ItemLocation(ItemManager.Items[itemLoc.item.type], locationsDict[itemLoc.name] if itemLoc.name in locationsDict and itemLoc.player == self.player else self.DummyLocation(self.multiworld.get_player_name(itemLoc.player) + " " + itemLoc.name), True) for itemLoc in self.multiworld.get_locations() if itemLoc.item.player == self.player and itemLoc.item.advancement == True] - # progItemLocs = [ItemLocation(ItemManager.Items[itemLoc.item.type if itemLoc.item.type in ItemManager.Items else 'ArchipelagoItem'], locationsDict[itemLoc.name], True) for itemLoc in self.multiworld.get_locations() if itemLoc.player == self.player and itemLoc.item.player == self.player and itemLoc.item.advancement == True] - + + + romPatcher.writeObjectives(itemLocs, romPatcher.settings["tourian"]) + romPatcher.writeItemsLocs(self.itemLocs) + # romPatcher.writeSplitLocs(self.variaRando.args.majorsSplit, itemLocs, progItemLocs) + romPatcher.writeItemsNumber() + if not romPatcher.settings["isPlando"]: + romPatcher.writeSeed(romPatcher.settings["seed"]) # lol if race mode romPatcher.writeSpoiler(itemLocs, progItemLocs) romPatcher.writeRandoSettings(self.variaRando.randoExec.randoSettings, itemLocs) + romPatcher.writeDoorConnections(romPatcher.settings["doors"]) + romPatcher.writeVersion(romPatcher.settings["displayedVersion"]) + if romPatcher.settings["ctrlDict"] is not None: + romPatcher.writeControls(romPatcher.settings["ctrlDict"]) + if romPatcher.settings["moonWalk"] == True: + romPatcher.enableMoonWalk() + + romPatcher.writeMagic() + romPatcher.writeMajorsSplit(romPatcher.settings["majorsSplit"]) + + #if self.settings["isPlando"] and self.race is None: + # doorsPtrs = GraphUtils.getAps2DoorsPtrs() + # self.writePlandoTransitions(self.settings["plando"]["graphTrans"], doorsPtrs, + # self.settings["plando"]["maxTransitions"]) + # self.writePlandoAddresses(self.settings["plando"]["visitedLocations"]) + #if self.settings["isPlando"] and self.settings["plando"]["additionalETanks"] != 0: + # self.writeAdditionalETanks(self.settings["plando"]["additionalETanks"]) + + romPatcher.end() def generate_output(self, output_directory: str): outfilebase = self.multiworld.get_out_file_name_base(self.player) @@ -682,6 +699,41 @@ class SMWorld(World): loc.place_locked_item(item) loc.address = loc.item.code = None + def post_fill(self): + self.itemLocs = [ + ItemLocation(ItemManager.Items[itemLoc.item.type + if isinstance(itemLoc.item, SMItem) and itemLoc.item.type in ItemManager.Items else + 'ArchipelagoItem'], + locationsDict[itemLoc.name], itemLoc.item.player, True) + for itemLoc in self.multiworld.get_locations(self.player) + ] + self.progItemLocs = [ + ItemLocation(ItemManager.Items[itemLoc.item.type + if isinstance(itemLoc.item, SMItem) and itemLoc.item.type in ItemManager.Items else + 'ArchipelagoItem'], + locationsDict[itemLoc.name], itemLoc.item.player, True) + for itemLoc in self.multiworld.get_locations(self.player) if itemLoc.item.advancement + ] + for itemLoc in self.itemLocs: + if itemLoc.Item.Class == "Boss": + itemLoc.Item.Class = "Minor" + for itemLoc in self.progItemLocs: + if itemLoc.Item.Class == "Boss": + itemLoc.Item.Class = "Minor" + + localItemLocs = [il for il in self.itemLocs if il.player == self.player] + localprogItemLocs = [il for il in self.progItemLocs if il.player == self.player] + + escapeTrigger = (localItemLocs, localprogItemLocs, 'Full') if self.variaRando.randoExec.randoSettings.restrictions["EscapeTrigger"] else None + escapeOk = self.variaRando.randoExec.graphBuilder.escapeGraph(self.variaRando.container, self.variaRando.randoExec.areaGraph, self.variaRando.randoExec.randoSettings.maxDiff, escapeTrigger) + assert escapeOk, "Could not find a solution for escape" + + self.variaRando.doors = GraphUtils.getDoorConnections(self.variaRando.randoExec.areaGraph, + self.variaRando.args.area, self.variaRando.args.bosses, + self.variaRando.args.escapeRando) + + self.variaRando.randoExec.postProcessItemLocs(self.itemLocs, self.variaRando.args.hideItems) + @classmethod def stage_post_fill(cls, world): new_state = CollectionState(world) diff --git a/worlds/sm/data/SMBasepatch_prebuilt/multiworld-basepatch.ips b/worlds/sm/data/SMBasepatch_prebuilt/multiworld-basepatch.ips index b44fa726..88a4a308 100644 Binary files a/worlds/sm/data/SMBasepatch_prebuilt/multiworld-basepatch.ips and b/worlds/sm/data/SMBasepatch_prebuilt/multiworld-basepatch.ips differ diff --git a/worlds/sm/data/SMBasepatch_prebuilt/multiworld.sym b/worlds/sm/data/SMBasepatch_prebuilt/multiworld.sym index c49a990f..f537a73b 100644 --- a/worlds/sm/data/SMBasepatch_prebuilt/multiworld.sym +++ b/worlds/sm/data/SMBasepatch_prebuilt/multiworld.sym @@ -12,8 +12,8 @@ B8:C831 :neg_1_7 B8:C843 :neg_1_8 B8:830C :pos_1_0 B8:8693 :pos_1_1 -84:FA6B :pos_1_2 -84:FA75 :pos_1_3 +84:FE1B :pos_1_2 +84:FE25 :pos_1_3 B8:C862 :pos_1_4 B8:C86F :pos_1_5 B8:C87C :pos_1_6 @@ -27,18 +27,18 @@ B8:8503 COLLECTTANK 84:8BF2 NORMAL 85:FF4E SETFX 85:FF30 SOUNDFX -84:F9E0 SOUNDFX_84 +84:FD90 SOUNDFX_84 85:FF3C SPECIALFX -84:F896 ammo_loop_table +84:FC46 ammo_loop_table B8:85BA ap_playerid_to_rom_other_player_index B8:85DD ap_playerid_to_rom_other_player_index_checklastrow B8:85F8 ap_playerid_to_rom_other_player_index_correctindex B8:85C0 ap_playerid_to_rom_other_player_index_do_search_stage_1 B8:85F5 ap_playerid_to_rom_other_player_index_notfound -84:F874 archipelago_chozo_item_plm -84:F878 archipelago_hidden_item_plm -84:F870 archipelago_visible_item_plm -84:F892 c_item +84:FC24 archipelago_chozo_item_plm +84:FC28 archipelago_hidden_item_plm +84:FC20 archipelago_visible_item_plm +84:FC42 c_item CE:FF04 config_deathlink CE:FF00 config_flags CE:FF00 config_multiworld @@ -50,14 +50,14 @@ B8:83FD copy_memory B8:8417 copy_memory_done B8:8409 copy_memory_even B8:840F copy_memory_loop -84:F894 h_item -84:F8AD i_chozo_item -84:F8B4 i_hidden_item -84:FA5A i_hidden_item_setup +84:FC44 h_item +84:FC5D i_chozo_item +84:FC64 i_hidden_item +84:FE0A i_hidden_item_setup B8:885C i_item_setup_shared B8:8878 i_item_setup_shared_all_items B8:8883 i_item_setup_shared_alwaysloaded -84:FA79 i_live_pickup +84:FE29 i_live_pickup B8:85FD i_live_pickup_multiworld B8:8679 i_live_pickup_multiworld_end B8:8659 i_live_pickup_multiworld_item_link_item @@ -65,18 +65,18 @@ B8:8649 i_live_pickup_multiworld_otherplayers_item B8:8635 i_live_pickup_multiworld_own_item B8:8641 i_live_pickup_multiworld_own_item1 B8:8620 i_live_pickup_multiworld_send_network -84:FA1E i_load_custom_graphics -84:FA39 i_load_custom_graphics_all_items -84:FA49 i_load_custom_graphics_alwaysloaded -84:FA61 i_load_rando_item -84:FA78 i_load_rando_item_end -84:F9F1 i_start_draw_loop -84:FA0A i_start_draw_loop_all_items -84:F9EC i_start_draw_loop_hidden -84:FA1C i_start_draw_loop_non_ammo_item -84:F9E5 i_start_draw_loop_visible_or_chozo -84:F8A6 i_visible_item -84:FA53 i_visible_item_setup +84:FDCE i_load_custom_graphics +84:FDE9 i_load_custom_graphics_all_items +84:FDF9 i_load_custom_graphics_alwaysloaded +84:FE11 i_load_rando_item +84:FE28 i_load_rando_item_end +84:FDA1 i_start_draw_loop +84:FDBA i_start_draw_loop_all_items +84:FD9C i_start_draw_loop_hidden +84:FDCC i_start_draw_loop_non_ammo_item +84:FD95 i_start_draw_loop_visible_or_chozo +84:FC56 i_visible_item +84:FE03 i_visible_item_setup 85:BB73 message_PlaceholderBig 85:BAF3 message_char_table 85:BBAA message_hook_tilemap_calc @@ -126,36 +126,36 @@ B8:84C4 mw_receive_item B8:84FC mw_receive_item_end B8:8469 mw_save_sram B8:8442 mw_write_message -84:F888 nonprog_item_eight_palette_indices +84:FC38 nonprog_item_eight_palette_indices 89:9200 offworld_graphics_data_item 89:9100 offworld_graphics_data_progression_item -84:F972 p_chozo_item -84:F9A0 p_chozo_item_end -84:F98D p_chozo_item_loop -84:F999 p_chozo_item_trigger -84:F8FB p_etank_hloop -84:F8BB p_etank_loop -84:F9A6 p_hidden_item -84:F9D8 p_hidden_item_end -84:F9BD p_hidden_item_loop -84:F9A8 p_hidden_item_loop2 -84:F9D1 p_hidden_item_trigger -84:F90F p_missile_hloop -84:F8CB p_missile_loop -84:F937 p_pb_hloop -84:F8EB p_pb_loop -84:F923 p_super_hloop -84:F8DB p_super_loop -84:F94B p_visible_item -84:F96E p_visible_item_end -84:F95B p_visible_item_loop -84:F967 p_visible_item_trigger +84:FD22 p_chozo_item +84:FD50 p_chozo_item_end +84:FD3D p_chozo_item_loop +84:FD49 p_chozo_item_trigger +84:FCAB p_etank_hloop +84:FC6B p_etank_loop +84:FD56 p_hidden_item +84:FD88 p_hidden_item_end +84:FD6D p_hidden_item_loop +84:FD58 p_hidden_item_loop2 +84:FD81 p_hidden_item_trigger +84:FCBF p_missile_hloop +84:FC7B p_missile_loop +84:FCE7 p_pb_hloop +84:FC9B p_pb_loop +84:FCD3 p_super_hloop +84:FC8B p_super_loop +84:FCFB p_visible_item +84:FD1E p_visible_item_end +84:FD0B p_visible_item_loop +84:FD17 p_visible_item_trigger B8:8694 patch_load_multiworld -84:FA7E perform_item_pickup -84:F886 plm_graphics_entry_offworld_item -84:F87C plm_graphics_entry_offworld_progression_item -84:FA90 plm_sequence_generic_item_0_bitmask -84:F87E prog_item_eight_palette_indices +84:FE2E perform_item_pickup +84:FC36 plm_graphics_entry_offworld_item +84:FC2C plm_graphics_entry_offworld_progression_item +84:FE40 plm_sequence_generic_item_0_bitmask +84:FC2E prog_item_eight_palette_indices B8:E000 rando_item_table B8:DCA0 rando_player_id_table B8:DE34 rando_player_id_table_end @@ -168,20 +168,20 @@ B8:C800 start_item_data_major B8:C808 start_item_data_minor B8:C818 start_item_data_reserve B8:C856 update_graphic -84:F890 v_item +84:FC40 v_item B8:83EF write_repeated_memory B8:83F4 write_repeated_memory_loop [source files] -0000 8d746646 main.asm +0000 bf919aa9 main.asm 0001 06780555 ../common/nofanfare.asm 0002 ae952bc9 ../common/multiworld.asm -0003 613d24e1 ../common/itemextras.asm -0004 cc2c77e4 ../common/items.asm -0005 440b54fe ../common/startitem.asm +0003 f7e9db95 ../common/itemextras.asm +0004 b0dd378a ../common/items.asm +0005 dbfcb38d ../common/startitem.asm [rom checksum] -f0ac0521 +e8b10748 [addr-to-line mapping] ff:ffff 0000:00000001 @@ -767,101 +767,101 @@ b8:8884 0003:0000005a b8:8885 0003:0000005b b8:8886 0003:0000005c b8:888a 0003:0000005d -84:f8a6 0004:00000051 -84:f8a9 0004:00000052 -84:f8ac 0004:00000053 -84:f8ad 0004:00000056 -84:f8b0 0004:00000057 -84:f8b3 0004:00000058 -84:f8b4 0004:0000005b -84:f8b7 0004:0000005c -84:f8ba 0004:0000005d -84:f9e0 0004:000000d4 -84:f9e4 0004:000000d5 -84:f9e5 0004:000000d8 -84:f9e8 0004:000000d9 -84:f9ea 0004:000000da -84:f9ec 0004:000000dd -84:f9ef 0004:000000de -84:f9f1 0004:000000e5 -84:f9f2 0004:000000e6 -84:f9f5 0004:000000e7 -84:f9f8 0004:000000e7 -84:f9f9 0004:000000e8 -84:f9fd 0004:000000e9 -84:fa00 0004:000000ea -84:fa02 0004:000000ee -84:fa05 0004:000000ef -84:fa06 0004:000000f0 -84:fa0a 0004:000000f3 -84:fa0d 0004:000000f4 -84:fa0f 0004:000000f6 -84:fa11 0004:000000f7 -84:fa12 0004:000000f8 -84:fa14 0004:000000f9 -84:fa15 0004:000000fa -84:fa19 0004:000000fb -84:fa1a 0004:000000fc -84:fa1b 0004:000000fd -84:fa1c 0004:00000100 -84:fa1d 0004:00000101 -84:fa1e 0004:00000105 -84:fa1f 0004:00000105 -84:fa20 0004:00000105 -84:fa21 0004:00000106 -84:fa24 0004:00000107 -84:fa27 0004:00000108 -84:fa28 0004:00000109 -84:fa2c 0004:0000010a -84:fa2f 0004:0000010b -84:fa31 0004:0000010d -84:fa34 0004:0000010e -84:fa35 0004:0000010e -84:fa39 0004:00000110 -84:fa3a 0004:00000112 -84:fa3b 0004:00000113 -84:fa3c 0004:00000114 -84:fa40 0004:00000115 -84:fa42 0004:00000116 -84:fa43 0004:00000117 -84:fa44 0004:00000118 -84:fa47 0004:00000119 -84:fa48 0004:0000011a -84:fa49 0004:0000011d -84:fa4a 0004:0000011e -84:fa4c 0004:0000011f -84:fa4d 0004:00000120 -84:fa51 0004:00000121 -84:fa52 0004:00000122 -84:fa53 0004:00000125 -84:fa57 0004:00000126 -84:fa5a 0004:00000129 -84:fa5e 0004:0000012a -84:fa61 0004:0000012e -84:fa64 0004:0000012e -84:fa66 0004:0000012f -84:fa69 0004:00000130 -84:fa6b 0004:00000131 -84:fa6e 0004:00000131 -84:fa70 0004:00000132 -84:fa73 0004:00000133 -84:fa75 0004:00000134 -84:fa78 0004:00000137 -84:fa79 0004:0000013b -84:fa7d 0004:0000013c -84:fa7e 0004:00000141 -84:fa7f 0004:00000142 -84:fa80 0004:00000143 -84:fa81 0004:00000143 -84:fa82 0004:00000147 -84:fa86 0004:00000148 -84:fa87 0004:00000149 -84:fa88 0004:0000014a -84:fa89 0004:0000014a -84:fa8a 0004:0000014b -84:fa8d 0004:0000014c -84:fa8e 0004:0000014d -84:fa8f 0004:0000014e +84:fc56 0004:00000051 +84:fc59 0004:00000052 +84:fc5c 0004:00000053 +84:fc5d 0004:00000056 +84:fc60 0004:00000057 +84:fc63 0004:00000058 +84:fc64 0004:0000005b +84:fc67 0004:0000005c +84:fc6a 0004:0000005d +84:fd90 0004:000000d4 +84:fd94 0004:000000d5 +84:fd95 0004:000000d8 +84:fd98 0004:000000d9 +84:fd9a 0004:000000da +84:fd9c 0004:000000dd +84:fd9f 0004:000000de +84:fda1 0004:000000e5 +84:fda2 0004:000000e6 +84:fda5 0004:000000e7 +84:fda8 0004:000000e7 +84:fda9 0004:000000e8 +84:fdad 0004:000000e9 +84:fdb0 0004:000000ea +84:fdb2 0004:000000ee +84:fdb5 0004:000000ef +84:fdb6 0004:000000f0 +84:fdba 0004:000000f3 +84:fdbd 0004:000000f4 +84:fdbf 0004:000000f6 +84:fdc1 0004:000000f7 +84:fdc2 0004:000000f8 +84:fdc4 0004:000000f9 +84:fdc5 0004:000000fa +84:fdc9 0004:000000fb +84:fdca 0004:000000fc +84:fdcb 0004:000000fd +84:fdcc 0004:00000100 +84:fdcd 0004:00000101 +84:fdce 0004:00000105 +84:fdcf 0004:00000105 +84:fdd0 0004:00000105 +84:fdd1 0004:00000106 +84:fdd4 0004:00000107 +84:fdd7 0004:00000108 +84:fdd8 0004:00000109 +84:fddc 0004:0000010a +84:fddf 0004:0000010b +84:fde1 0004:0000010d +84:fde4 0004:0000010e +84:fde5 0004:0000010e +84:fde9 0004:00000110 +84:fdea 0004:00000112 +84:fdeb 0004:00000113 +84:fdec 0004:00000114 +84:fdf0 0004:00000115 +84:fdf2 0004:00000116 +84:fdf3 0004:00000117 +84:fdf4 0004:00000118 +84:fdf7 0004:00000119 +84:fdf8 0004:0000011a +84:fdf9 0004:0000011d +84:fdfa 0004:0000011e +84:fdfc 0004:0000011f +84:fdfd 0004:00000120 +84:fe01 0004:00000121 +84:fe02 0004:00000122 +84:fe03 0004:00000125 +84:fe07 0004:00000126 +84:fe0a 0004:00000129 +84:fe0e 0004:0000012a +84:fe11 0004:0000012e +84:fe14 0004:0000012e +84:fe16 0004:0000012f +84:fe19 0004:00000130 +84:fe1b 0004:00000131 +84:fe1e 0004:00000131 +84:fe20 0004:00000132 +84:fe23 0004:00000133 +84:fe25 0004:00000134 +84:fe28 0004:00000137 +84:fe29 0004:0000013b +84:fe2d 0004:0000013c +84:fe2e 0004:00000141 +84:fe2f 0004:00000142 +84:fe30 0004:00000143 +84:fe31 0004:00000143 +84:fe32 0004:00000147 +84:fe36 0004:00000148 +84:fe37 0004:00000149 +84:fe38 0004:0000014a +84:fe39 0004:0000014a +84:fe3a 0004:0000014b +84:fe3d 0004:0000014c +84:fe3e 0004:0000014d +84:fe3f 0004:0000014e 81:b303 0005:00000003 81:b307 0005:00000004 81:b308 0005:00000005 diff --git a/worlds/sm/data/SMBasepatch_prebuilt/sm-basepatch-symbols.json b/worlds/sm/data/SMBasepatch_prebuilt/sm-basepatch-symbols.json index ae911707..c5d7c1b4 100644 --- a/worlds/sm/data/SMBasepatch_prebuilt/sm-basepatch-symbols.json +++ b/worlds/sm/data/SMBasepatch_prebuilt/sm-basepatch-symbols.json @@ -9,18 +9,18 @@ "NORMAL": "84:8BF2", "SETFX": "85:FF4E", "SOUNDFX": "85:FF30", - "SOUNDFX_84": "84:F9E0", + "SOUNDFX_84": "84:FD90", "SPECIALFX": "85:FF3C", - "ammo_loop_table": "84:F896", + "ammo_loop_table": "84:FC46", "ap_playerid_to_rom_other_player_index": "B8:85BA", "ap_playerid_to_rom_other_player_index_checklastrow": "B8:85DD", "ap_playerid_to_rom_other_player_index_correctindex": "B8:85F8", "ap_playerid_to_rom_other_player_index_do_search_stage_1": "B8:85C0", "ap_playerid_to_rom_other_player_index_notfound": "B8:85F5", - "archipelago_chozo_item_plm": "84:F874", - "archipelago_hidden_item_plm": "84:F878", - "archipelago_visible_item_plm": "84:F870", - "c_item": "84:F892", + "archipelago_chozo_item_plm": "84:FC24", + "archipelago_hidden_item_plm": "84:FC28", + "archipelago_visible_item_plm": "84:FC20", + "c_item": "84:FC42", "config_deathlink": "CE:FF04", "config_flags": "CE:FF00", "config_multiworld": "CE:FF00", @@ -32,14 +32,14 @@ "copy_memory_done": "B8:8417", "copy_memory_even": "B8:8409", "copy_memory_loop": "B8:840F", - "h_item": "84:F894", - "i_chozo_item": "84:F8AD", - "i_hidden_item": "84:F8B4", - "i_hidden_item_setup": "84:FA5A", + "h_item": "84:FC44", + "i_chozo_item": "84:FC5D", + "i_hidden_item": "84:FC64", + "i_hidden_item_setup": "84:FE0A", "i_item_setup_shared": "B8:885C", "i_item_setup_shared_all_items": "B8:8878", "i_item_setup_shared_alwaysloaded": "B8:8883", - "i_live_pickup": "84:FA79", + "i_live_pickup": "84:FE29", "i_live_pickup_multiworld": "B8:85FD", "i_live_pickup_multiworld_end": "B8:8679", "i_live_pickup_multiworld_item_link_item": "B8:8659", @@ -47,18 +47,18 @@ "i_live_pickup_multiworld_own_item": "B8:8635", "i_live_pickup_multiworld_own_item1": "B8:8641", "i_live_pickup_multiworld_send_network": "B8:8620", - "i_load_custom_graphics": "84:FA1E", - "i_load_custom_graphics_all_items": "84:FA39", - "i_load_custom_graphics_alwaysloaded": "84:FA49", - "i_load_rando_item": "84:FA61", - "i_load_rando_item_end": "84:FA78", - "i_start_draw_loop": "84:F9F1", - "i_start_draw_loop_all_items": "84:FA0A", - "i_start_draw_loop_hidden": "84:F9EC", - "i_start_draw_loop_non_ammo_item": "84:FA1C", - "i_start_draw_loop_visible_or_chozo": "84:F9E5", - "i_visible_item": "84:F8A6", - "i_visible_item_setup": "84:FA53", + "i_load_custom_graphics": "84:FDCE", + "i_load_custom_graphics_all_items": "84:FDE9", + "i_load_custom_graphics_alwaysloaded": "84:FDF9", + "i_load_rando_item": "84:FE11", + "i_load_rando_item_end": "84:FE28", + "i_start_draw_loop": "84:FDA1", + "i_start_draw_loop_all_items": "84:FDBA", + "i_start_draw_loop_hidden": "84:FD9C", + "i_start_draw_loop_non_ammo_item": "84:FDCC", + "i_start_draw_loop_visible_or_chozo": "84:FD95", + "i_visible_item": "84:FC56", + "i_visible_item_setup": "84:FE03", "message_PlaceholderBig": "85:BB73", "message_char_table": "85:BAF3", "message_hook_tilemap_calc": "85:BBAA", @@ -108,36 +108,36 @@ "mw_receive_item_end": "B8:84FC", "mw_save_sram": "B8:8469", "mw_write_message": "B8:8442", - "nonprog_item_eight_palette_indices": "84:F888", + "nonprog_item_eight_palette_indices": "84:FC38", "offworld_graphics_data_item": "89:9200", "offworld_graphics_data_progression_item": "89:9100", - "p_chozo_item": "84:F972", - "p_chozo_item_end": "84:F9A0", - "p_chozo_item_loop": "84:F98D", - "p_chozo_item_trigger": "84:F999", - "p_etank_hloop": "84:F8FB", - "p_etank_loop": "84:F8BB", - "p_hidden_item": "84:F9A6", - "p_hidden_item_end": "84:F9D8", - "p_hidden_item_loop": "84:F9BD", - "p_hidden_item_loop2": "84:F9A8", - "p_hidden_item_trigger": "84:F9D1", - "p_missile_hloop": "84:F90F", - "p_missile_loop": "84:F8CB", - "p_pb_hloop": "84:F937", - "p_pb_loop": "84:F8EB", - "p_super_hloop": "84:F923", - "p_super_loop": "84:F8DB", - "p_visible_item": "84:F94B", - "p_visible_item_end": "84:F96E", - "p_visible_item_loop": "84:F95B", - "p_visible_item_trigger": "84:F967", + "p_chozo_item": "84:FD22", + "p_chozo_item_end": "84:FD50", + "p_chozo_item_loop": "84:FD3D", + "p_chozo_item_trigger": "84:FD49", + "p_etank_hloop": "84:FCAB", + "p_etank_loop": "84:FC6B", + "p_hidden_item": "84:FD56", + "p_hidden_item_end": "84:FD88", + "p_hidden_item_loop": "84:FD6D", + "p_hidden_item_loop2": "84:FD58", + "p_hidden_item_trigger": "84:FD81", + "p_missile_hloop": "84:FCBF", + "p_missile_loop": "84:FC7B", + "p_pb_hloop": "84:FCE7", + "p_pb_loop": "84:FC9B", + "p_super_hloop": "84:FCD3", + "p_super_loop": "84:FC8B", + "p_visible_item": "84:FCFB", + "p_visible_item_end": "84:FD1E", + "p_visible_item_loop": "84:FD0B", + "p_visible_item_trigger": "84:FD17", "patch_load_multiworld": "B8:8694", - "perform_item_pickup": "84:FA7E", - "plm_graphics_entry_offworld_item": "84:F886", - "plm_graphics_entry_offworld_progression_item": "84:F87C", - "plm_sequence_generic_item_0_bitmask": "84:FA90", - "prog_item_eight_palette_indices": "84:F87E", + "perform_item_pickup": "84:FE2E", + "plm_graphics_entry_offworld_item": "84:FC36", + "plm_graphics_entry_offworld_progression_item": "84:FC2C", + "plm_sequence_generic_item_0_bitmask": "84:FE40", + "prog_item_eight_palette_indices": "84:FC2E", "rando_item_table": "B8:E000", "rando_player_id_table": "B8:DCA0", "rando_player_id_table_end": "B8:DE34", @@ -150,7 +150,7 @@ "start_item_data_minor": "B8:C808", "start_item_data_reserve": "B8:C818", "update_graphic": "B8:C856", - "v_item": "84:F890", + "v_item": "84:FC40", "write_repeated_memory": "B8:83EF", "write_repeated_memory_loop": "B8:83F4", "ITEM_RAM": "7E:09A2", diff --git a/worlds/sm/data/SMBasepatch_prebuilt/variapatches.ips b/worlds/sm/data/SMBasepatch_prebuilt/variapatches.ips index c1285e16..37139ae5 100644 Binary files a/worlds/sm/data/SMBasepatch_prebuilt/variapatches.ips and b/worlds/sm/data/SMBasepatch_prebuilt/variapatches.ips differ diff --git a/worlds/sm/variaRandomizer/graph/graph.py b/worlds/sm/variaRandomizer/graph/graph.py index 3e296500..d6a3a09f 100644 --- a/worlds/sm/variaRandomizer/graph/graph.py +++ b/worlds/sm/variaRandomizer/graph/graph.py @@ -140,7 +140,7 @@ class AccessGraph(object): def addAccessPoint(self, ap): ap.distance = 0 - self.accessPoints[ap.Name] = ap + self.accessPoints[ap.Name] = copy.deepcopy(ap) def toDot(self, dotFile): colors = ['red', 'blue', 'green', 'yellow', 'skyblue', 'violet', 'orange', @@ -175,6 +175,15 @@ class AccessGraph(object): if both is True: self.addTransition(dstName, srcName, False) + # remove transitions whose source or dest matches apName + def removeTransitions(self, apName): + toRemove = [t for t in self.InterAreaTransitions if t[0].Name == apName or t[1].Name == apName] + for t in toRemove: + src, dst = t + self.InterAreaTransitions.remove(t) + src.disconnect() + dst.disconnect() + # availNodes: all already available nodes # nodesToCheck: nodes we have to check transitions for # smbm: smbm to test logic on. if None, discard logic check, assume we can reach everything diff --git a/worlds/sm/variaRandomizer/graph/graph_utils.py b/worlds/sm/variaRandomizer/graph/graph_utils.py index ccff42a4..36253343 100644 --- a/worlds/sm/variaRandomizer/graph/graph_utils.py +++ b/worlds/sm/variaRandomizer/graph/graph_utils.py @@ -238,7 +238,10 @@ class GraphUtils: for ap in unusedAPs: transitions.append((ap.Name, ap.Name)) - def createMinimizerTransitions(startApName, locLimit): + # crateria can be forced in corner cases + def createMinimizerTransitions(startApName, locLimit, forcedAreas=None): + if forcedAreas is None: + forcedAreas = [] if startApName == 'Ceres': startApName = 'Landing Site' startAp = getAccessPoint(startApName) @@ -249,7 +252,10 @@ class GraphUtils: return len([loc for loc in locList if locsPredicate(loc) == True and not loc.SolveArea.endswith(" Boss") and not loc.isBoss()]) availAreas = list(sorted({ap.GraphArea for ap in Logic.accessPoints if ap.GraphArea != startAp.GraphArea and getNLocs(lambda loc: loc.GraphArea == ap.GraphArea) > 0})) areas = [startAp.GraphArea] + if startAp.GraphArea in forcedAreas: + forcedAreas.remove(startAp.GraphArea) GraphUtils.log.debug("availAreas: {}".format(availAreas)) + GraphUtils.log.debug("forcedAreas: {}".format(forcedAreas)) GraphUtils.log.debug("areas: {}".format(areas)) inBossCheck = lambda ap: ap.Boss and ap.Name.endswith("In") nLocs = 0 @@ -260,22 +266,27 @@ class GraphUtils: def openTransitions(): nonlocal areas, inBossCheck, usedAPs return GraphUtils.getAPs(lambda ap: ap.GraphArea in areas and not ap.isInternal() and not inBossCheck(ap) and not ap in usedAPs) - while nLocs < locLimit or len(openTransitions()) < trLimit: + while nLocs < locLimit or len(openTransitions()) < trLimit or len(forcedAreas) > 0: GraphUtils.log.debug("openTransitions="+str([ap.Name for ap in openTransitions()])) fromAreas = availAreas - if nLocs >= locLimit: + if len(openTransitions()) <= 1: # dont' get stuck by adding dead ends + GraphUtils.log.debug("avoid being stuck") + fromAreas = [area for area in fromAreas if len(GraphUtils.getAPs(lambda ap: ap.GraphArea == area and not ap.isInternal())) > 1] + elif len(forcedAreas) > 0: # no risk to get stuck, we can pick a forced area if necessary + GraphUtils.log.debug("add forced area") + fromAreas = forcedAreas + elif nLocs >= locLimit: # we just need transitions, avoid adding a huge area GraphUtils.log.debug("not enough open transitions") - # we just need transitions, avoid adding a huge area fromAreas = [] n = trLimit - len(openTransitions()) while len(fromAreas) == 0: fromAreas = [area for area in availAreas if len(GraphUtils.getAPs(lambda ap: not ap.isInternal())) > n] n -= 1 - minLocs = min([getNLocs(lambda loc: loc.GraphArea == area) for area in fromAreas]) + minLocs = min([getNLocs(lambda loc: loc.GraphArea == area) for area in fromAreas]) fromAreas = [area for area in fromAreas if getNLocs(lambda loc: loc.GraphArea == area) == minLocs] - elif len(openTransitions()) <= 1: # dont' get stuck by adding dead ends - fromAreas = [area for area in fromAreas if len(GraphUtils.getAPs(lambda ap: ap.GraphArea == area and not ap.isInternal())) > 1] nextArea = random.choice(fromAreas) + if nextArea in forcedAreas: + forcedAreas.remove(nextArea) GraphUtils.log.debug("nextArea="+str(nextArea)) apCheck = lambda ap: not ap.isInternal() and not inBossCheck(ap) and ap not in usedAPs possibleSources = GraphUtils.getAPs(lambda ap: ap.GraphArea in areas and apCheck(ap)) @@ -399,18 +410,37 @@ class GraphUtils: def escapeAnimalsTransitions(graph, possibleTargets, firstEscape): n = len(possibleTargets) assert (n < 4 and firstEscape is not None) or (n <= 4 and firstEscape is None), "Invalid possibleTargets list: " + str(possibleTargets) - # first get our list of 4 entries for escape patch + GraphUtils.log.debug("escapeAnimalsTransitions. possibleTargets="+str(possibleTargets)+", firstEscape="+str(firstEscape)) if n >= 1: - # get actual animals: pick one of the remaining targets - animalsAccess = possibleTargets.pop() - graph.EscapeAttributes['Animals'] = animalsAccess - # we now have at most 3 targets left, fill up to fill cycling 4 targets for animals suprise - possibleTargets.append('Climb Bottom Left') + # complete possibleTargets. we need at least 2: one to + # hide the animals in, and one to connect the vanilla + # animals door to + if not any(t[1].Name == 'Climb Bottom Left' for t in graph.InterAreaTransitions): + # add standard Climb if not already in graph: it can be in Crateria-less minimizer + Disabled Tourian case + possibleTargets.append('Climb Bottom Left') + # make the escape possibilities loop by adding back the first escape if firstEscape is not None: possibleTargets.append(firstEscape) poss = possibleTargets[:] while len(possibleTargets) < 4: possibleTargets.append(poss.pop(random.randint(0, len(poss)-1))) + n = len(possibleTargets) + # check if we can both hide the animals and connect the vanilla animals door to a cycling escape + if n >= 2: + # get actual animals: pick the first of the remaining targets (will contain a map room AP) + animalsAccess = possibleTargets.pop(0) + graph.EscapeAttributes['Animals'] = animalsAccess + # poss will contain the remaining map room AP(s) + optional AP(s) added above, to + # get the cycling 4 escapes from vanilla animals room + poss = possibleTargets[:] + GraphUtils.log.debug("escapeAnimalsTransitions. poss="+str(poss)) + while len(possibleTargets) < 4: + if len(poss) > 1: + possibleTargets.append(poss.pop(random.randint(0, len(poss)-1))) + else: + # no more possible variety, spam the last possible escape + possibleTargets.append(poss[0]) + else: # failsafe: if not enough targets left, abort and do vanilla animals animalsAccess = 'Flyway Right' diff --git a/worlds/sm/variaRandomizer/graph/location.py b/worlds/sm/variaRandomizer/graph/location.py index fb205853..5831a4cc 100644 --- a/worlds/sm/variaRandomizer/graph/location.py +++ b/worlds/sm/variaRandomizer/graph/location.py @@ -64,6 +64,8 @@ class Location: smbm.removeItem(self.itemName) self.difficulty = self.difficulty & postAvailable + if self.locDifficulty is not None: + self.locDifficulty = self.locDifficulty & postAvailable def evalComeBack(self, smbm, areaGraph, ap): if self.difficulty.bool == True: @@ -102,7 +104,7 @@ class Location: def define_location( Area, GraphArea, SolveArea, Name, Class, CanHidden, Address, Id, - Visibility, Room, VanillaItemType=None, AccessFrom=None, Available=None, PostAvailable=None, HUD=None): + Visibility, Room, VanillaItemType=None, BossItemType=None, AccessFrom=None, Available=None, PostAvailable=None, HUD=None): name = Name.replace(' ', '').replace(',', '') + 'Location' subclass = type(name, (Location,), { 'Area': Area, @@ -116,6 +118,7 @@ def define_location( 'Visibility': Visibility, 'Room': Room, 'VanillaItemType': VanillaItemType, + 'BossItemType': BossItemType, 'HUD': HUD, 'AccessFrom': AccessFrom, 'Available': Available, @@ -322,6 +325,7 @@ define_location( Id=None, Visibility="Hidden", Room='Kraid Room', + BossItemType="Kraid" ), "Varia Suit": define_location( @@ -445,12 +449,15 @@ define_location( GraphArea="LowerNorfair", SolveArea="Ridley Boss", Name="Ridley", - Class=["Boss"], + Class=["Boss", "Scavenger"], CanHidden=False, Address=0xB055B056, - Id=None, + Id=0xaa, Visibility="Hidden", Room="Ridley's Room", + VanillaItemType="Ridley", + BossItemType="Ridley", + HUD=16 ), "Energy Tank, Ridley": define_location( @@ -531,6 +538,7 @@ define_location( Id=None, Visibility="Hidden", Room="Phantoon's Room", + BossItemType="Phantoon" ), "Right Super, Wrecked Ship": define_location( @@ -641,6 +649,7 @@ define_location( Id=None, Visibility="Hidden", Room="Draygon's Room", + BossItemType="Draygon" ), "Space Jump": define_location( @@ -669,6 +678,63 @@ define_location( Visibility="Hidden", CanHidden=False, Room='Mother Brain Room', + BossItemType="MotherBrain" +), + "Spore Spawn": +define_location( + Area="Brinstar", + GraphArea="GreenPinkBrinstar", + SolveArea="Pink Brinstar", + Name="Spore Spawn", + Class=["Boss"], + CanHidden=False, + Address=0xB055B055, + Id=None, + Visibility="Hidden", + Room='Spore Spawn Room', + BossItemType="SporeSpawn" +), + "Botwoon": +define_location( + Area="Maridia", + GraphArea="EastMaridia", + SolveArea="Maridia Pink Top", + Name="Botwoon", + Class=["Boss"], + CanHidden=False, + Address=0xB055B055, + Id=None, + Visibility="Hidden", + Room="Botwoon's Room", + BossItemType="Botwoon" +), + "Crocomire": +define_location( + Area="Norfair", + GraphArea="Crocomire", + SolveArea="Crocomire", + Name="Crocomire", + Class=["Boss"], + CanHidden=False, + Address=0xB055B055, + Id=None, + Visibility="Hidden", + Room="Crocomire's Room", + BossItemType="Crocomire" +), + "Golden Torizo": +define_location( + Area="LowerNorfair", + GraphArea="LowerNorfair", + SolveArea="Lower Norfair Screw Attack", + Name="Golden Torizo", + Class=["Boss"], + CanHidden=False, + Address=0xB055B055, + Id=None, + Visibility="Hidden", + Room="Golden Torizo's Room", + BossItemType="GoldenTorizo" ), ###### MINORS "Power Bomb (Crateria surface)": diff --git a/worlds/sm/variaRandomizer/graph/vanilla/graph_access.py b/worlds/sm/variaRandomizer/graph/vanilla/graph_access.py index 501dab8f..f49fc6fc 100644 --- a/worlds/sm/variaRandomizer/graph/vanilla/graph_access.py +++ b/worlds/sm/variaRandomizer/graph/vanilla/graph_access.py @@ -42,9 +42,8 @@ accessPoints = [ }, traverse = Cache.ldeco(lambda sm: sm.wor(RomPatches.has(sm.player, RomPatches.AreaRandoMoreBlueDoors), sm.traverse('GreenPiratesShaftBottomRight'))), roomInfo = {'RoomPtr':0x99bd, "area": 0x0, 'songs':[0x99ce]}, - # the doorAsmPtr 7FE00 is set by the g4_skip.ips patch, we have to call it exitInfo = {'DoorPtr':0x8c52, 'direction': 0x4, "cap": (0x1, 0x6), "bitFlag": 0x0, - "screen": (0x0, 0x0), "distanceToSpawn": 0x8000, "doorAsmPtr": 0xfe00}, + "screen": (0x0, 0x0), "distanceToSpawn": 0x8000, "doorAsmPtr": 0x0000}, entryInfo = {'SamusX':0xcc, 'SamusY':0x688, 'song': 0x9}, dotOrientation = 'e'), AccessPoint('Moat Right', 'Crateria', { @@ -173,7 +172,9 @@ accessPoints = [ sm.canPassSpongeBath()), sm.wand(sm.wnot(Bosses.bossDead(sm, 'Phantoon')), RomPatches.has(sm.player, RomPatches.SpongeBathBlueDoor)))), - 'PhantoonRoomOut': Cache.ldeco(lambda sm: sm.wand(sm.traverse('WreckedShipMainShaftBottom'), sm.canPassBombPassages())) + 'PhantoonRoomOut': Cache.ldeco(lambda sm: sm.wand(sm.traverse('WreckedShipMainShaftBottom'), sm.canPassBombPassages())), + 'Bowling': Cache.ldeco(lambda sm: sm.wand(sm.canMorphJump(), + sm.canPassBowling())) }, internal=True, start={'spawn':0x0300, 'doors':[0x83,0x8b], 'patches':[RomPatches.SpongeBathBlueDoor, RomPatches.WsEtankBlueDoor], @@ -183,6 +184,9 @@ accessPoints = [ 'Wrecked Ship Main': lambda sm: SMBool(True), 'Crab Maze Left': Cache.ldeco(lambda sm: sm.canPassForgottenHighway(True)) }, internal=True), + AccessPoint('Bowling', 'WreckedShip', { + 'West Ocean Left': lambda sm: SMBool(True) + }, internal=True), AccessPoint('Crab Maze Left', 'WreckedShip', { 'Wrecked Ship Back': Cache.ldeco(lambda sm: sm.canPassForgottenHighway(False)) }, traverse=Cache.ldeco(lambda sm: sm.wor(RomPatches.has(sm.player, RomPatches.AreaRandoBlueDoors), @@ -245,6 +249,8 @@ accessPoints = [ sm.canUsePowerBombs())) }, internal=True), AccessPoint('LN Above GT', 'LowerNorfair', { + 'LN Entrance': Cache.ldeco(lambda sm: sm.wand(sm.canHellRun(**Settings.hellRunsTable['LowerNorfair']['Main']), + sm.canPassBombPassages())), 'Screw Attack Bottom': Cache.ldeco(lambda sm: sm.wand(sm.canHellRun(**Settings.hellRunsTable['LowerNorfair']['Main']), sm.enoughStuffGT())) }, internal=True), @@ -423,11 +429,9 @@ accessPoints = [ entryInfo = {'SamusX':0x134, 'SamusY':0x288, 'song': 0x15}, dotOrientation = 'se'), AccessPoint('Crocomire Speedway Bottom', 'Norfair', { - 'Business Center': Cache.ldeco(lambda sm: sm.wor(sm.wand(sm.canPassFrogSpeedwayRightToLeft(), - sm.canHellRun(**Settings.hellRunsTable['Ice']['Croc -> Norfair Entrance'])), - sm.wand(sm.canHellRun(**Settings.hellRunsTable['MainUpperNorfair']['Croc -> Norfair Entrance']), - sm.canGrappleEscape(), - sm.haveItem('Super')))), + 'Grapple Escape': lambda sm: sm.canGrappleEscape(), + 'Business Center': Cache.ldeco(lambda sm: sm.wand(sm.canPassFrogSpeedwayRightToLeft(), + sm.canHellRun(**Settings.hellRunsTable['Ice']['Croc -> Norfair Entrance']))), 'Bubble Mountain Bottom': Cache.ldeco(lambda sm: sm.canHellRun(**Settings.hellRunsTable['Ice']['Croc -> Bubble Mountain'])), 'Kronic Boost Room Bottom Left': Cache.ldeco(lambda sm: sm.wand(sm.canHellRun(**Settings.hellRunsTable['MainUpperNorfair']['Kronic Boost Room <-> Croc']), sm.haveItem('Morph'))) @@ -437,6 +441,10 @@ accessPoints = [ "screen": (0x3, 0x0), "distanceToSpawn": 0x8000, "doorAsmPtr": 0x0000}, entryInfo = {'SamusX':0xc57, 'SamusY':0x2b8}, dotOrientation = 'se'), + AccessPoint('Grapple Escape', 'Norfair', { + 'Business Center': lambda sm: sm.haveItem('Super'), + 'Crocomire Speedway Bottom': lambda sm: sm.canHellRunBackFromGrappleEscape() + }, internal=True), AccessPoint('Bubble Mountain', 'Norfair', { 'Business Center': lambda sm: sm.canExitCathedral(Settings.hellRunsTable['MainUpperNorfair']['Bubble -> Norfair Entrance']), 'Bubble Mountain Top': lambda sm: sm.canClimbBubbleMountain(), @@ -494,8 +502,7 @@ accessPoints = [ dotOrientation = 'se'), ### West Maridia AccessPoint('Main Street Bottom', 'WestMaridia', { - 'Red Fish Room Left': Cache.ldeco(lambda sm: sm.wand(sm.canGoUpMtEverest(), - sm.haveItem('Morph'))), + 'Red Fish Room Bottom': lambda sm: sm.canGoUpMtEverest(), 'Crab Hole Bottom Left': Cache.ldeco(lambda sm: sm.wand(sm.haveItem('Morph'), sm.canTraverseCrabTunnelLeftToRight())), # this transition leads to EastMaridia directly @@ -532,12 +539,17 @@ accessPoints = [ entryInfo = {'SamusX':0x28, 'SamusY':0x188}, dotOrientation = 'se'), AccessPoint('Red Fish Room Left', 'WestMaridia', { - 'Main Street Bottom': Cache.ldeco(lambda sm: sm.haveItem('Morph')) # just go down + 'Red Fish Room Bottom': Cache.ldeco(lambda sm: sm.haveItem('Morph')) # just go down }, roomInfo = {'RoomPtr':0xd104, "area": 0x4}, exitInfo = {'DoorPtr':0xa480, 'direction': 0x5, "cap": (0x2e, 0x36), "bitFlag": 0x40, "screen": (0x2, 0x3), "distanceToSpawn": 0x8000, "doorAsmPtr": 0xe367}, entryInfo = {'SamusX':0x34, 'SamusY':0x88}, dotOrientation = 'w'), + AccessPoint('Red Fish Room Bottom', 'WestMaridia', { + 'Main Street Bottom': lambda sm: SMBool(True), # just go down + 'Red Fish Room Left': Cache.ldeco(lambda sm: sm.wand(sm.haveItem('Morph'), + sm.canJumpUnderwater())) + }, internal=True), AccessPoint('Crab Shaft Left', 'WestMaridia', { 'Main Street Bottom': lambda sm: SMBool(True), # fall down 'Beach': lambda sm: sm.canDoOuterMaridia(), @@ -586,7 +598,9 @@ accessPoints = [ dotOrientation = 'ne'), ### East Maridia AccessPoint('Aqueduct Top Left', 'EastMaridia', { - 'Aqueduct Bottom': lambda sm: sm.canUsePowerBombs() + 'Aqueduct Bottom': lambda sm: sm.wor(sm.wand(RomPatches.has(sm.player, RomPatches.AqueductBombBlocks), + sm.canDestroyBombWallsUnderwater()), + sm.canUsePowerBombs()) }, roomInfo = {'RoomPtr':0xd5a7, "area": 0x4}, exitInfo = {'DoorPtr':0xa708, 'direction': 0x5, "cap": (0x1e, 0x36), "bitFlag": 0x0, "screen": (0x1, 0x3), "distanceToSpawn": 0x8000, "doorAsmPtr": 0xe398}, @@ -596,7 +610,8 @@ accessPoints = [ 'Aqueduct Top Left': Cache.ldeco(lambda sm: sm.wand(sm.canDestroyBombWallsUnderwater(), # top left bomb blocks sm.canJumpUnderwater())), 'Post Botwoon': Cache.ldeco(lambda sm: sm.wand(sm.canJumpUnderwater(), - sm.canDefeatBotwoon())), # includes botwoon hallway conditions + sm.canPassBotwoonHallway(), + sm.haveItem('Botwoon'))), 'Left Sandpit': lambda sm: sm.canAccessSandPits(), 'Right Sandpit': lambda sm: sm.canAccessSandPits(), 'Aqueduct': Cache.ldeco(lambda sm: sm.wand(sm.wor(sm.haveItem('SpeedBooster'), diff --git a/worlds/sm/variaRandomizer/graph/vanilla/graph_helpers.py b/worlds/sm/variaRandomizer/graph/vanilla/graph_helpers.py index de18ab86..3d4d9b4f 100644 --- a/worlds/sm/variaRandomizer/graph/vanilla/graph_helpers.py +++ b/worlds/sm/variaRandomizer/graph/vanilla/graph_helpers.py @@ -241,6 +241,21 @@ class HelpersGraph(Helpers): sm = self.smbm return sm.canHellRun(**Settings.hellRunsTable['MainUpperNorfair']['Bubble -> Speed Booster w/Speed' if sm.haveItem('SpeedBooster') else 'Bubble -> Speed Booster']) + # with door color rando, there can be situations where you have to come back from the missile + # loc without being able to open the speed booster door + @Cache.decorator + def canHellRunBackFromSpeedBoosterMissile(self): + sm = self.smbm + # require more health to count 1st hell run + way back is slower + hellrun = 'MainUpperNorfair' + tbl = Settings.hellRunsTable[hellrun]['Bubble -> Speed Booster'] + mult = tbl['mult'] + minE = tbl['minE'] + mult *= 0.66 if sm.haveItem('SpeedBooster') else 0.33 # speed booster usable for 1st hell run + return sm.wor(RomPatches.has(sm.player, RomPatches.SpeedAreaBlueDoors), + sm.traverse('SpeedBoosterHallRight'), + sm.canHellRun(hellrun, mult, minE)) + @Cache.decorator def canAccessDoubleChamberItems(self): sm = self.smbm @@ -253,6 +268,19 @@ class HelpersGraph(Helpers): sm.knowsDoubleChamberWallJump()), sm.canHellRun(hellRun['hellRun'], hellRun['mult']*0.8, hellRun['minE']))) + @Cache.decorator + def canExitWaveBeam(self): + sm = self.smbm + return sm.wor(sm.haveItem('Morph'), # exit through lower passage under the spikes + sm.wand(sm.wor(sm.haveItem('SpaceJump'), # exit through blue gate + sm.haveItem('Grapple')), + sm.wor(sm.haveItem('Wave'), + sm.wand(sm.heatProof(), # hell run + green gate glitch is too much + sm.canBlueGateGlitch(), + # if missiles were required to open the door, require two packs as no farming around + sm.wor(sm.wnot(SMBool('Missile' in sm.traverse('DoubleChamberRight').items)), + sm.itemCountOk("Missile", 2)))))) + def canExitCathedral(self, hellRun): # from top: can use bomb/powerbomb jumps # from bottom: can do a shinespark or use space jump @@ -272,16 +300,40 @@ class HelpersGraph(Helpers): @Cache.decorator def canGrappleEscape(self): sm = self.smbm - return sm.wor(sm.wor(sm.haveItem('SpaceJump'), - sm.wand(sm.canInfiniteBombJump(), # IBJ from lava...either have grav or freeze the enemy there if hellrunning (otherwise single DBJ at the end) - sm.wor(sm.heatProof(), - sm.haveItem('Gravity'), - sm.haveItem('Ice')))), - sm.haveItem('Grapple'), - sm.wand(sm.haveItem('SpeedBooster'), - sm.wor(sm.haveItem('HiJump'), # jump from the blocks below - sm.knowsShortCharge())), # spark from across the grapple blocks - sm.wand(sm.haveItem('HiJump'), sm.canSpringBallJump())) # jump from the blocks below + access = sm.wor(sm.wor(sm.haveItem('SpaceJump'), + sm.wand(sm.canInfiniteBombJump(), # IBJ from lava...either have grav or freeze the enemy there if hellrunning (otherwise single DBJ at the end) + sm.wor(sm.heatProof(), + sm.haveItem('Gravity'), + sm.haveItem('Ice')))), + sm.haveItem('Grapple'), + sm.wand(sm.haveItem('SpeedBooster'), + sm.wor(sm.haveItem('HiJump'), # jump from the blocks below + sm.knowsShortCharge())), # spark from across the grapple blocks + sm.wand(sm.haveItem('HiJump'), sm.canSpringBallJump())) # jump from the blocks below + hellrun = 'MainUpperNorfair' + tbl = Settings.hellRunsTable[hellrun]['Croc -> Norfair Entrance'] + mult = tbl['mult'] + minE = tbl['minE'] + if 'InfiniteBombJump' in access.knows or 'ShortCharge' in access.knows: + mult *= 0.7 + elif 'SpaceJump' in access.items: + mult *= 1.5 + elif 'Grapple' in access.items: + mult *= 1.25 + return sm.wand(access, + sm.canHellRun(hellrun, mult, minE)) + + @Cache.decorator + def canHellRunBackFromGrappleEscape(self): + sm = self.smbm + # require more health to count 1st hell run from croc speedway bottom to here+hellrun back (which is faster) + hellrun = 'MainUpperNorfair' + tbl = Settings.hellRunsTable[hellrun]['Croc -> Norfair Entrance'] + mult = tbl['mult'] + minE = tbl['minE'] + mult *= 0.6 + return sm.canHellRun(hellrun, mult, minE) + @Cache.decorator def canPassFrogSpeedwayRightToLeft(self): @@ -733,7 +785,9 @@ class HelpersGraph(Helpers): @Cache.decorator def canExitPreciousRoomRandomized(self): sm = self.smbm - suitlessRoomExit = sm.canSpringBallJump() + suitlessRoomExit = sm.wand(sm.wnot(sm.haveItem('Gravity')), + sm.canJumpUnderwater(), + sm.canSpringBallJump()) if suitlessRoomExit.bool == False: if self.getDraygonConnection() == 'KraidRoomIn': suitlessRoomExit = sm.canShortCharge() # charge spark in kraid's room @@ -764,3 +818,27 @@ class HelpersGraph(Helpers): return sm.wand(sm.traverse('MainStreetBottomRight'), sm.wor(sm.haveItem('Super'), RomPatches.has(sm.player, RomPatches.AreaRandoGatesOther))) + + @Cache.decorator + def canAccessShaktoolFromPantsRoom(self): + sm = self.smbm + return sm.wor(sm.wand(sm.haveItem('Ice'), # puyo clip + sm.wor(sm.wand(sm.haveItem('Gravity'), + sm.knowsPuyoClip()), + sm.wand(sm.haveItem('Gravity'), + sm.haveItem('XRayScope'), + sm.knowsPuyoClipXRay()), + sm.knowsSuitlessPuyoClip())), + sm.wand(sm.haveItem('Grapple'), # go through grapple block + sm.wor(sm.wand(sm.haveItem('Gravity'), + sm.wor(sm.wor(sm.wand(sm.haveItem('HiJump'), sm.knowsAccessSpringBallWithHiJump()), + sm.haveItem('SpaceJump')), + sm.knowsAccessSpringBallWithGravJump(), + sm.wand(sm.haveItem('Bomb'), + sm.wor(sm.knowsAccessSpringBallWithBombJumps(), + sm.wand(sm.haveItem('SpringBall'), + sm.knowsAccessSpringBallWithSpringBallBombJumps()))), + sm.wand(sm.haveItem('SpringBall'), sm.knowsAccessSpringBallWithSpringBallJump()))), + sm.wand(sm.haveItem('SpaceJump'), sm.knowsAccessSpringBallWithFlatley()))), + sm.wand(sm.haveItem('XRayScope'), sm.knowsAccessSpringBallWithXRayClimb()), # XRay climb + sm.canCrystalFlashClip()) diff --git a/worlds/sm/variaRandomizer/graph/vanilla/graph_locations.py b/worlds/sm/variaRandomizer/graph/vanilla/graph_locations.py index 5bf3c0e6..d924811a 100644 --- a/worlds/sm/variaRandomizer/graph/vanilla/graph_locations.py +++ b/worlds/sm/variaRandomizer/graph/vanilla/graph_locations.py @@ -157,7 +157,7 @@ locationsDict["Energy Tank, Crocomire"].AccessFrom = { 'Crocomire Room Top': lambda sm: SMBool(True) } locationsDict["Energy Tank, Crocomire"].Available = ( - lambda sm: sm.wand(sm.enoughStuffCroc(), + lambda sm: sm.wand(sm.haveItem('Crocomire'), sm.wor(sm.haveItem('Grapple'), sm.haveItem('SpaceJump'), sm.energyReserveCountOk(3/sm.getDmgReduction()[0]))) @@ -176,7 +176,7 @@ locationsDict["Grapple Beam"].AccessFrom = { 'Crocomire Room Top': lambda sm: SMBool(True) } locationsDict["Grapple Beam"].Available = ( - lambda sm: sm.wand(sm.enoughStuffCroc(), + lambda sm: sm.wand(sm.haveItem('Crocomire'), sm.wor(sm.wand(sm.haveItem('Morph'), sm.canFly()), sm.wand(sm.haveItem('SpeedBooster'), @@ -220,11 +220,7 @@ locationsDict["Wave Beam"].Available = ( lambda sm: sm.traverse('DoubleChamberRight') ) locationsDict["Wave Beam"].PostAvailable = ( - lambda sm: sm.wor(sm.haveItem('Morph'), # exit through lower passage under the spikes - sm.wand(sm.wor(sm.haveItem('SpaceJump'), # exit through blue gate - sm.haveItem('Grapple')), - sm.wor(sm.wand(sm.canBlueGateGlitch(), sm.heatProof()), # hell run + green gate glitch is too much - sm.haveItem('Wave')))) + lambda sm: sm.canExitWaveBeam() ) locationsDict["Ridley"].AccessFrom = { 'RidleyRoomIn': lambda sm: SMBool(True) @@ -233,7 +229,7 @@ locationsDict["Ridley"].Available = ( lambda sm: sm.wand(sm.canHellRun(**Settings.hellRunsTable['LowerNorfair']['Main']), sm.enoughStuffsRidley()) ) locationsDict["Energy Tank, Ridley"].AccessFrom = { - 'RidleyRoomIn': lambda sm: sm.haveItem('Ridley') + 'RidleyRoomIn': lambda sm: sm.wand(sm.haveItem('Ridley'), sm.canHellRun(**Settings.hellRunsTable['LowerNorfair']['Main'])) } locationsDict["Energy Tank, Ridley"].Available = ( lambda sm: sm.haveItem('Morph') @@ -354,27 +350,8 @@ locationsDict["Spring Ball"].AccessFrom = { 'Oasis Bottom': lambda sm: sm.canTraverseSandPits() } locationsDict["Spring Ball"].Available = ( - lambda sm: sm.wand(sm.canUsePowerBombs(), # in Shaktool room to let Shaktool access the sand blocks - sm.wor(sm.wand(sm.haveItem('Ice'), # puyo clip - sm.wor(sm.wand(sm.haveItem('Gravity'), - sm.knowsPuyoClip()), - sm.wand(sm.haveItem('Gravity'), - sm.haveItem('XRayScope'), - sm.knowsPuyoClipXRay()), - sm.knowsSuitlessPuyoClip())), - sm.wand(sm.haveItem('Grapple'), # go through grapple block - sm.wor(sm.wand(sm.haveItem('Gravity'), - sm.wor(sm.wor(sm.wand(sm.haveItem('HiJump'), sm.knowsAccessSpringBallWithHiJump()), - sm.haveItem('SpaceJump')), - sm.knowsAccessSpringBallWithGravJump(), - sm.wand(sm.haveItem('Bomb'), - sm.wor(sm.knowsAccessSpringBallWithBombJumps(), - sm.wand(sm.haveItem('SpringBall'), - sm.knowsAccessSpringBallWithSpringBallBombJumps()))), - sm.wand(sm.haveItem('SpringBall'), sm.knowsAccessSpringBallWithSpringBallJump()))), - sm.wand(sm.haveItem('SpaceJump'), sm.knowsAccessSpringBallWithFlatley()))), - sm.wand(sm.haveItem('XRayScope'), sm.knowsAccessSpringBallWithXRayClimb()), # XRay climb - sm.canCrystalFlashClip()), + lambda sm: sm.wand(sm.canAccessShaktoolFromPantsRoom(), + sm.canUsePowerBombs(), # in Shaktool room to let Shaktool access the sand blocks sm.wor(sm.haveItem('Gravity'), sm.canUseSpringBall())) # acess the item in spring ball room ) locationsDict["Spring Ball"].PostAvailable = ( @@ -406,10 +383,37 @@ locationsDict["Space Jump"].PostAvailable = ( lambda sm: Bosses.bossDead(sm, 'Draygon') ) locationsDict["Mother Brain"].AccessFrom = { - 'Golden Four': lambda sm: Bosses.allBossesDead(sm) + 'Golden Four': lambda sm: sm.canPassG4() } locationsDict["Mother Brain"].Available = ( - lambda sm: sm.enoughStuffTourian() + lambda sm: sm.wor(RomPatches.has(sm.player, RomPatches.NoTourian), + sm.enoughStuffTourian()) +) +locationsDict["Spore Spawn"].AccessFrom = { + 'Big Pink': lambda sm: SMBool(True) +} +locationsDict["Spore Spawn"].Available = ( + lambda sm: sm.wand(sm.traverse('BigPinkTopRight'), + sm.enoughStuffSporeSpawn()) +) +locationsDict["Botwoon"].AccessFrom = { + 'Aqueduct Bottom': lambda sm: sm.canJumpUnderwater() +} +locationsDict["Botwoon"].Available = ( + # includes botwoon hallway conditions + lambda sm: sm.canDefeatBotwoon() +) +locationsDict["Crocomire"].AccessFrom = { + 'Crocomire Room Top': lambda sm: SMBool(True) +} +locationsDict["Crocomire"].Available = ( + lambda sm: sm.enoughStuffCroc() +) +locationsDict["Golden Torizo"].AccessFrom = { + 'Screw Attack Bottom': lambda sm: SMBool(True) +} +locationsDict["Golden Torizo"].Available = ( + lambda sm: sm.enoughStuffGT() ) locationsDict["Power Bomb (Crateria surface)"].AccessFrom = { 'Landing Site': lambda sm: SMBool(True) @@ -506,10 +510,10 @@ locationsDict["Super Missile (pink Brinstar)"].AccessFrom = { } locationsDict["Super Missile (pink Brinstar)"].Available = ( lambda sm: sm.wor(sm.wand(sm.traverse('BigPinkTopRight'), - sm.enoughStuffSporeSpawn()), + sm.haveItem('SporeSpawn')), # back way into spore spawn - sm.wand(sm.canOpenGreenDoors(), - sm.canPassBombPassages())) + sm.wand(sm.canOpenGreenDoors(), + sm.canPassBombPassages())) ) locationsDict["Super Missile (pink Brinstar)"].PostAvailable = ( lambda sm: sm.wand(sm.canOpenGreenDoors(), @@ -665,10 +669,10 @@ locationsDict["Missile (below Ice Beam)"].Available = ( lambda sm: SMBool(True) ) locationsDict["Missile (above Crocomire)"].AccessFrom = { - 'Crocomire Speedway Bottom': lambda sm: sm.canHellRun(**Settings.hellRunsTable['MainUpperNorfair']['Croc -> Grapple Escape Missiles']) + 'Grapple Escape': lambda sm: SMBool(True) } locationsDict["Missile (above Crocomire)"].Available = ( - lambda sm: sm.canGrappleEscape() + lambda sm: SMBool(True) ) locationsDict["Missile (Hi-Jump Boots)"].AccessFrom = { 'Business Center': lambda sm: sm.wor(RomPatches.has(sm.player, RomPatches.HiJumpAreaBlueDoor), sm.traverse('BusinessCenterBottomLeft')) @@ -691,7 +695,7 @@ locationsDict["Power Bomb (Crocomire)"].AccessFrom = { } locationsDict["Power Bomb (Crocomire)"].Available = ( lambda sm: sm.wand(sm.traverse('PostCrocomireUpperLeft'), - sm.enoughStuffCroc(), + sm.haveItem('Crocomire'), sm.wor(sm.wor(sm.canFly(), sm.haveItem('Grapple'), sm.wand(sm.haveItem('SpeedBooster'), @@ -706,13 +710,13 @@ locationsDict["Missile (below Crocomire)"].AccessFrom = { 'Crocomire Room Top': lambda sm: SMBool(True) } locationsDict["Missile (below Crocomire)"].Available = ( - lambda sm: sm.wand(sm.traverse('PostCrocomireShaftRight'), sm.enoughStuffCroc(), sm.haveItem('Morph')) + lambda sm: sm.wand(sm.traverse('PostCrocomireShaftRight'), sm.haveItem('Crocomire'), sm.haveItem('Morph')) ) locationsDict["Missile (Grapple Beam)"].AccessFrom = { 'Crocomire Room Top': lambda sm: SMBool(True) } locationsDict["Missile (Grapple Beam)"].Available = ( - lambda sm: sm.wand(sm.enoughStuffCroc(), + lambda sm: sm.wand(sm.haveItem('Crocomire'), sm.wor(sm.wor(sm.wand(sm.haveItem('Morph'), # from below sm.canFly()), sm.wand(sm.haveItem('SpeedBooster'), @@ -754,6 +758,9 @@ locationsDict["Missile (Speed Booster)"].AccessFrom = { locationsDict["Missile (Speed Booster)"].Available = ( lambda sm: sm.canHellRunToSpeedBooster() ) +locationsDict["Missile (Speed Booster)"].PostAvailable = ( + lambda sm: sm.canHellRunBackFromSpeedBoosterMissile() +) locationsDict["Missile (Wave Beam)"].AccessFrom = { 'Bubble Mountain Top': lambda sm: sm.canAccessDoubleChamberItems() } @@ -773,7 +780,7 @@ locationsDict["Super Missile (Gold Torizo)"].AccessFrom = { 'Screw Attack Bottom': lambda sm: SMBool(True) } locationsDict["Super Missile (Gold Torizo)"].Available = ( - lambda sm: SMBool(True) + lambda sm: sm.canDestroyBombWalls() ) locationsDict["Super Missile (Gold Torizo)"].PostAvailable = ( lambda sm: sm.enoughStuffGT() diff --git a/worlds/sm/variaRandomizer/logic/helpers.py b/worlds/sm/variaRandomizer/logic/helpers.py index 717561e7..ee173816 100644 --- a/worlds/sm/variaRandomizer/logic/helpers.py +++ b/worlds/sm/variaRandomizer/logic/helpers.py @@ -281,14 +281,23 @@ class Helpers(object): def canMorphJump(self): # small hop in morph ball form sm = self.smbm - return sm.wor(sm.canPassBombPassages(), sm.haveItem('SpringBall')) + return sm.wor(sm.canPassBombPassages(), sm.canUseSpringBall()) def canCrystalFlash(self, n=1): sm = self.smbm - return sm.wand(sm.canUsePowerBombs(), - sm.itemCountOk('Missile', 2*n), - sm.itemCountOk('Super', 2*n), - sm.itemCountOk('PowerBomb', 2*n+1)) + if not RomPatches.has(sm.player, RomPatches.RoundRobinCF).bool: + ret = sm.wand(sm.canUsePowerBombs(), + sm.itemCountOk('Missile', 2*n), + sm.itemCountOk('Super', 2*n), + sm.itemCountOk('PowerBomb', 2*n+1)) + else: + # simplified view of actual patch behavior: only count full refills to stick with base CF logic + nAmmo = 5 * (sm.itemCount('Missile') + sm.itemCount('Super') + sm.itemCount('PowerBomb')) + ret = sm.wand(sm.canUsePowerBombs(), + SMBool(nAmmo >= 30*n)) + if ret: + ret._items.append("{}-CrystalFlash".format(n)) + return ret @Cache.decorator def canCrystalFlashClip(self): @@ -363,7 +372,7 @@ class Helpers(object): # - estimation of the fight duration in seconds (well not really, it # is if you fire and land shots perfectly and constantly), giving info # to compute boss fight difficulty - def canInflictEnoughDamages(self, bossEnergy, doubleSuper=False, charge=True, power=False, givesDrops=True, ignoreMissiles=False, ignoreSupers=False): + def canInflictEnoughDamages(self, bossEnergy, doubleSuper=False, charge=True, power=False, givesDrops=True, ignoreMissiles=False, ignoreSupers=False, missilesOffset=0, supersOffset=0, powerBombsOffset=0): # TODO: handle special beam attacks ? (http://deanyd.net/sm/index.php?title=Charge_Beam_Combos) sm = self.smbm items = [] @@ -379,14 +388,14 @@ class Helpers(object): chargeDamage *= 3.0 # missile 100 damages, super missile 300 damages, PBs 200 dmg, 5 in each extension - missilesAmount = sm.itemCount('Missile') * 5 + missilesAmount = max(0, (sm.itemCount('Missile') - missilesOffset)) * 5 if ignoreMissiles == True: missilesDamage = 0 else: missilesDamage = missilesAmount * 100 if missilesAmount > 0: items.append('Missile') - supersAmount = sm.itemCount('Super') * 5 + supersAmount = max(0, (sm.itemCount('Super') - supersOffset)) * 5 if ignoreSupers == True: oneSuper = 0 else: @@ -399,7 +408,7 @@ class Helpers(object): powerDamage = 0 powerAmount = 0 if power == True and sm.haveItem('PowerBomb') == True: - powerAmount = sm.itemCount('PowerBomb') * 5 + powerAmount = max(0, (sm.itemCount('PowerBomb') - powerBombsOffset)) * 5 powerDamage = powerAmount * 200 items.append('PowerBomb') @@ -607,7 +616,9 @@ class Helpers(object): # some ammo to destroy the turrets during the fight if not sm.haveMissileOrSuper(): return smboolFalse - (ammoMargin, secs, ammoItems) = self.canInflictEnoughDamages(6000) + (ammoMargin, secs, ammoItems) = self.canInflictEnoughDamages(6000, + # underestimate missiles/supers in case a CF exit is needed + missilesOffset=2, supersOffset=2) # print('DRAY', ammoMargin, secs) if ammoMargin > 0: (diff, defenseItems) = self.computeBossDifficulty(ammoMargin, secs, @@ -749,16 +760,20 @@ class Helpers(object): class Pickup: def __init__(self, itemsPickup): self.itemsPickup = itemsPickup + self.endGameLocations = ["Mother Brain", "Gunship"] + # don't count end game location in the mix as it's now in the available locations def enoughMinors(self, smbm, minorLocations): - if self.itemsPickup == 'all': - return len(minorLocations) == 0 + if self.itemsPickup in ('all', 'all_strict'): + return (len(minorLocations) == 0 + or (len(minorLocations) == 1 and minorLocations[0].Name in self.endGameLocations)) else: return True def enoughMajors(self, smbm, majorLocations): - if self.itemsPickup == 'all': - return len(majorLocations) == 0 + if self.itemsPickup in ('all', 'all_strict'): + return (len(majorLocations) == 0 + or (len(majorLocations) == 1 and majorLocations[0].Name in self.endGameLocations)) else: return True @@ -811,9 +826,24 @@ class Bosses: 'WreckedShip Top': 'Phantoon' } + accessPoints = { + "Kraid": "KraidRoomIn", + "Phantoon": "PhantoonRoomIn", + "Draygon": "Draygon Room Bottom", + "Ridley": "RidleyRoomIn", + "SporeSpawn": "Big Pink", + "Crocomire": "Crocomire Room Top", + "Botwoon": "Aqueduct Bottom", + "GoldenTorizo": "Screw Attack Bottom" + } + @staticmethod def Golden4(): return ['Draygon', 'Kraid', 'Phantoon', 'Ridley'] + + @staticmethod + def miniBosses(): + return ['SporeSpawn', 'Crocomire', 'Botwoon', 'GoldenTorizo'] @staticmethod def bossDead(sm, boss): @@ -831,6 +861,23 @@ class Bosses: Bosses.bossDead(smbm, 'Phantoon'), Bosses.bossDead(smbm, 'Draygon'), Bosses.bossDead(smbm, 'Ridley')) + + @staticmethod + def allMiniBossesDead(smbm): + return smbm.wand(Bosses.bossDead(smbm, 'SporeSpawn'), + Bosses.bossDead(smbm, 'Botwoon'), + Bosses.bossDead(smbm, 'Crocomire'), + Bosses.bossDead(smbm, 'GoldenTorizo')) + + @staticmethod + def xBossesDead(smbm, target): + count = sum([1 for boss in Bosses.Golden4() if Bosses.bossDead(smbm, boss)]) + return SMBool(count >= target) + + @staticmethod + def xMiniBossesDead(smbm, target): + count = sum([1 for miniboss in Bosses.miniBosses() if Bosses.bossDead(smbm, miniboss)]) + return SMBool(count >= target) def diffValue2txt(diff): last = 0 diff --git a/worlds/sm/variaRandomizer/logic/smboolmanager.py b/worlds/sm/variaRandomizer/logic/smboolmanager.py index d4de6dae..bb315847 100644 --- a/worlds/sm/variaRandomizer/logic/smboolmanager.py +++ b/worlds/sm/variaRandomizer/logic/smboolmanager.py @@ -5,14 +5,16 @@ from ..logic.smbool import SMBool, smboolFalse from ..logic.helpers import Bosses from ..logic.logic import Logic from ..utils.doorsmanager import DoorsManager +from ..utils.objectives import Objectives from ..utils.parameters import Knows, isKnows import logging import sys class SMBoolManager(object): - items = ['ETank', 'Missile', 'Super', 'PowerBomb', 'Bomb', 'Charge', 'Ice', 'HiJump', 'SpeedBooster', 'Wave', 'Spazer', 'SpringBall', 'Varia', 'Plasma', 'Grapple', 'Morph', 'Reserve', 'Gravity', 'XRayScope', 'SpaceJump', 'ScrewAttack', 'Nothing', 'NoEnergy', 'MotherBrain', 'Hyper'] + Bosses.Golden4() + items = ['ETank', 'Missile', 'Super', 'PowerBomb', 'Bomb', 'Charge', 'Ice', 'HiJump', 'SpeedBooster', 'Wave', 'Spazer', 'SpringBall', 'Varia', 'Plasma', 'Grapple', 'Morph', 'Reserve', 'Gravity', 'XRayScope', 'SpaceJump', 'ScrewAttack', 'Nothing', 'NoEnergy', 'MotherBrain', 'Hyper', 'Gunship'] + Bosses.Golden4() + Bosses.miniBosses() countItems = ['Missile', 'Super', 'PowerBomb', 'ETank', 'Reserve'] + percentItems = ['Bomb', 'Charge', 'Ice', 'HiJump', 'SpeedBooster', 'Wave', 'Spazer', 'SpringBall', 'Varia', 'Plasma', 'Grapple', 'Morph', 'Gravity', 'XRayScope', 'SpaceJump', 'ScrewAttack'] def __init__(self, player=0, maxDiff=sys.maxsize, onlyBossLeft = False, lastAP = 'Landing Site'): self._items = { } self._counts = { } @@ -24,12 +26,13 @@ class SMBoolManager(object): self.lastAP = lastAP # cache related - self.cacheKey = 0 - self.computeItemsPositions() + #self.cacheKey = 0 + #self.computeItemsPositions() Cache.reset() Logic.factory('vanilla') self.helpers = Logic.HelpersGraph(self) self.doorsManager = DoorsManager() + self.objectives = Objectives.objDict[player] self.createFacadeFunctions() self.createKnowsFunctions(player) self.resetItems() @@ -97,8 +100,8 @@ class SMBoolManager(object): self._items = { item : smboolFalse for item in self.items } self._counts = { item : 0 for item in self.countItems } - self.cacheKey = 0 - Cache.update(self.cacheKey) + #self.cacheKey = 0 + #Cache.update(self.cacheKey) def addItem(self, item): # a new item is available @@ -106,11 +109,11 @@ class SMBoolManager(object): if self.isCountItem(item): count = self._counts[item] + 1 self._counts[item] = count - self.computeNewCacheKey(item, count) - else: - self.computeNewCacheKey(item, 1) + #self.computeNewCacheKey(item, count) + #else: + #self.computeNewCacheKey(item, 1) - Cache.update(self.cacheKey) + #Cache.update(self.cacheKey) def addItems(self, items): if len(items) == 0: @@ -120,11 +123,11 @@ class SMBoolManager(object): if self.isCountItem(item): count = self._counts[item] + 1 self._counts[item] = count - self.computeNewCacheKey(item, count) - else: - self.computeNewCacheKey(item, 1) + #self.computeNewCacheKey(item, count) + #else: + #self.computeNewCacheKey(item, 1) - Cache.update(self.cacheKey) + #Cache.update(self.cacheKey) def removeItem(self, item): # randomizer removed an item (or the item was added to test a post available) @@ -133,12 +136,12 @@ class SMBoolManager(object): self._counts[item] = count if count == 0: self._items[item] = smboolFalse - self.computeNewCacheKey(item, count) + #self.computeNewCacheKey(item, count) else: self._items[item] = smboolFalse - self.computeNewCacheKey(item, 0) + #self.computeNewCacheKey(item, 0) - Cache.update(self.cacheKey) + #Cache.update(self.cacheKey) def createFacadeFunctions(self): for fun in dir(self.helpers): @@ -147,22 +150,51 @@ class SMBoolManager(object): def traverse(self, doorName): return self.doorsManager.traverse(self, doorName) + + def canPassG4(self): + return self.objectives.canClearGoals(self, 'Golden Four') + + def hasItemsPercent(self, percent, totalItemsCount=None): + if totalItemsCount is None: + totalItemsCount = self.objectives.getTotalItemsCount() + currentItemsCount = self.getCollectedItemsCount() + return SMBool(100*(currentItemsCount/totalItemsCount) >= percent) + + def getCollectedItemsCount(self): + return (len([item for item in self._items if self.haveItem(item) and item in self.percentItems]) + + sum([self.itemCount(item) for item in self._items if self.isCountItem(item)])) def createKnowsFunctions(self, player): # for each knows we have a function knowsKnows (ex: knowsAlcatrazEscape()) which # take no parameter for knows in Knows.__dict__: if isKnows(knows): - if player in Knows.knowsDict and knows in Knows.knowsDict[player].__dict__: - setattr(self, 'knows'+knows, lambda knows=knows: SMBool(Knows.knowsDict[player].__dict__[knows].bool, - Knows.knowsDict[player].__dict__[knows].difficulty, - knows=[knows])) - else: - # if knows not in preset, use default values - setattr(self, 'knows'+knows, lambda knows=knows: SMBool(Knows.__dict__[knows].bool, - Knows.__dict__[knows].difficulty, - knows=[knows])) + self._createKnowsFunction(knows, player) + def _setKnowsFunction(self, knows, k): + setattr(self, 'knows'+knows, lambda: SMBool(k.bool, k.difficulty, + knows=[knows])) + + def _createKnowsFunction(self, knows, player): + if player in Knows.knowsDict and knows in Knows.knowsDict[player].__dict__: + self._setKnowsFunction(knows, Knows.knowsDict[player].__dict__[knows]) + else: + self._setKnowsFunction(knows, Knows.__dict__[knows]) + + def changeKnows(self, knows, newVal): + if isKnows(knows): + self._setKnowsFunction(knows, newVal) + #Cache.reset() + else: + raise ValueError("Invalid knows "+str(knows)) + + def restoreKnows(self, knows): + if isKnows(knows): + self._createKnowsFunction(knows) + #Cache.reset() + else: + raise ValueError("Invalid knows "+str(knows)) + def isCountItem(self, item): return item in self.countItems @@ -174,6 +206,12 @@ class SMBoolManager(object): def haveItem(self, item): #return self.state.has(item, self.player) return self._items[item] + + def haveItems(self, items): + for item in items: + if not self.haveItem(item): + return smboolFalse + return SMBool(True) wand = staticmethod(SMBool.wand) wandmax = staticmethod(SMBool.wandmax) @@ -218,11 +256,11 @@ class SMBoolManagerPlando(SMBoolManager): if isCount: count = self._counts[item] + 1 self._counts[item] = count - self.computeNewCacheKey(item, count) - else: - self.computeNewCacheKey(item, 1) + #self.computeNewCacheKey(item, count) + #else: + #self.computeNewCacheKey(item, 1) - Cache.update(self.cacheKey) + #Cache.update(self.cacheKey) def removeItem(self, item): # randomizer removed an item (or the item was added to test a post available) @@ -231,14 +269,14 @@ class SMBoolManagerPlando(SMBoolManager): self._counts[item] = count if count == 0: self._items[item] = smboolFalse - self.computeNewCacheKey(item, count) + #self.computeNewCacheKey(item, count) else: dup = 'dup_'+item if self._items.get(dup, None) is None: self._items[item] = smboolFalse - self.computeNewCacheKey(item, 0) + #self.computeNewCacheKey(item, 0) else: del self._items[dup] - self.computeNewCacheKey(item, 1) + #self.computeNewCacheKey(item, 1) - Cache.update(self.cacheKey) + #Cache.update(self.cacheKey) diff --git a/worlds/sm/variaRandomizer/patches/common/ips/beam_doors_plms.ips b/worlds/sm/variaRandomizer/patches/common/ips/beam_doors_plms.ips index 34f7bda6..d3beab48 100644 Binary files a/worlds/sm/variaRandomizer/patches/common/ips/beam_doors_plms.ips and b/worlds/sm/variaRandomizer/patches/common/ips/beam_doors_plms.ips differ diff --git a/worlds/sm/variaRandomizer/patches/common/ips/color_blind.ips b/worlds/sm/variaRandomizer/patches/common/ips/color_blind.ips new file mode 100644 index 00000000..2a03372a Binary files /dev/null and b/worlds/sm/variaRandomizer/patches/common/ips/color_blind.ips differ diff --git a/worlds/sm/variaRandomizer/patches/common/ips/credits_varia.ips b/worlds/sm/variaRandomizer/patches/common/ips/credits_varia.ips new file mode 100644 index 00000000..9c35c18d Binary files /dev/null and b/worlds/sm/variaRandomizer/patches/common/ips/credits_varia.ips differ diff --git a/worlds/sm/variaRandomizer/patches/common/ips/custom_music.ips b/worlds/sm/variaRandomizer/patches/common/ips/custom_music.ips new file mode 100644 index 00000000..5711721d Binary files /dev/null and b/worlds/sm/variaRandomizer/patches/common/ips/custom_music.ips differ diff --git a/worlds/sm/variaRandomizer/patches/common/ips/disable_screen_shake.ips b/worlds/sm/variaRandomizer/patches/common/ips/disable_screen_shake.ips new file mode 100644 index 00000000..b4d4559d Binary files /dev/null and b/worlds/sm/variaRandomizer/patches/common/ips/disable_screen_shake.ips differ diff --git a/worlds/sm/variaRandomizer/patches/common/ips/door_indicators_plms.ips b/worlds/sm/variaRandomizer/patches/common/ips/door_indicators_plms.ips new file mode 100644 index 00000000..cd940c84 Binary files /dev/null and b/worlds/sm/variaRandomizer/patches/common/ips/door_indicators_plms.ips differ diff --git a/worlds/sm/variaRandomizer/patches/common/ips/elevators_doors_speed.ips b/worlds/sm/variaRandomizer/patches/common/ips/elevators_doors_speed.ips index 3e08065b..cc95739b 100644 Binary files a/worlds/sm/variaRandomizer/patches/common/ips/elevators_doors_speed.ips and b/worlds/sm/variaRandomizer/patches/common/ips/elevators_doors_speed.ips differ diff --git a/worlds/sm/variaRandomizer/patches/common/ips/elevators_speed.ips b/worlds/sm/variaRandomizer/patches/common/ips/elevators_speed.ips new file mode 100644 index 00000000..6cbff74a Binary files /dev/null and b/worlds/sm/variaRandomizer/patches/common/ips/elevators_speed.ips differ diff --git a/worlds/sm/variaRandomizer/patches/common/ips/endingtotals.ips b/worlds/sm/variaRandomizer/patches/common/ips/endingtotals.ips new file mode 100644 index 00000000..56f20c21 Binary files /dev/null and b/worlds/sm/variaRandomizer/patches/common/ips/endingtotals.ips differ diff --git a/worlds/sm/variaRandomizer/patches/common/ips/fast_doors.ips b/worlds/sm/variaRandomizer/patches/common/ips/fast_doors.ips new file mode 100644 index 00000000..3297df21 Binary files /dev/null and b/worlds/sm/variaRandomizer/patches/common/ips/fast_doors.ips differ diff --git a/worlds/sm/variaRandomizer/patches/common/ips/fast_doors_old.ips b/worlds/sm/variaRandomizer/patches/common/ips/fast_doors_old.ips new file mode 100644 index 00000000..0785699e Binary files /dev/null and b/worlds/sm/variaRandomizer/patches/common/ips/fast_doors_old.ips differ diff --git a/worlds/sm/variaRandomizer/patches/common/ips/g4_skip.ips b/worlds/sm/variaRandomizer/patches/common/ips/g4_skip.ips deleted file mode 100644 index f75fbc5b..00000000 Binary files a/worlds/sm/variaRandomizer/patches/common/ips/g4_skip.ips and /dev/null differ diff --git a/worlds/sm/variaRandomizer/patches/common/ips/gameend.ips b/worlds/sm/variaRandomizer/patches/common/ips/gameend.ips index 25c2bbac..8e8079c7 100644 Binary files a/worlds/sm/variaRandomizer/patches/common/ips/gameend.ips and b/worlds/sm/variaRandomizer/patches/common/ips/gameend.ips differ diff --git a/worlds/sm/variaRandomizer/patches/common/ips/hell.ips b/worlds/sm/variaRandomizer/patches/common/ips/hell.ips new file mode 100644 index 00000000..10560b58 Binary files /dev/null and b/worlds/sm/variaRandomizer/patches/common/ips/hell.ips differ diff --git a/worlds/sm/variaRandomizer/patches/common/ips/intro_text.ips b/worlds/sm/variaRandomizer/patches/common/ips/intro_text.ips new file mode 100644 index 00000000..80671d51 Binary files /dev/null and b/worlds/sm/variaRandomizer/patches/common/ips/intro_text.ips differ diff --git a/worlds/sm/variaRandomizer/patches/common/ips/lava_acid_physics.ips b/worlds/sm/variaRandomizer/patches/common/ips/lava_acid_physics.ips new file mode 100644 index 00000000..e49df396 Binary files /dev/null and b/worlds/sm/variaRandomizer/patches/common/ips/lava_acid_physics.ips differ diff --git a/worlds/sm/variaRandomizer/patches/common/ips/minimizer_bosses.ips b/worlds/sm/variaRandomizer/patches/common/ips/minimizer_bosses.ips index 03b9b32a..021a06a0 100644 Binary files a/worlds/sm/variaRandomizer/patches/common/ips/minimizer_bosses.ips and b/worlds/sm/variaRandomizer/patches/common/ips/minimizer_bosses.ips differ diff --git a/worlds/sm/variaRandomizer/patches/common/ips/minimizer_tourian.ips b/worlds/sm/variaRandomizer/patches/common/ips/minimizer_tourian.ips index bd40ab11..502fdd22 100644 Binary files a/worlds/sm/variaRandomizer/patches/common/ips/minimizer_tourian.ips and b/worlds/sm/variaRandomizer/patches/common/ips/minimizer_tourian.ips differ diff --git a/worlds/sm/variaRandomizer/patches/common/ips/new_game.ips b/worlds/sm/variaRandomizer/patches/common/ips/new_game.ips new file mode 100644 index 00000000..e2864ea6 Binary files /dev/null and b/worlds/sm/variaRandomizer/patches/common/ips/new_game.ips differ diff --git a/worlds/sm/variaRandomizer/patches/common/ips/noflashing.ips b/worlds/sm/variaRandomizer/patches/common/ips/noflashing.ips new file mode 100644 index 00000000..716bbd37 Binary files /dev/null and b/worlds/sm/variaRandomizer/patches/common/ips/noflashing.ips differ diff --git a/worlds/sm/variaRandomizer/patches/common/ips/objectives.ips b/worlds/sm/variaRandomizer/patches/common/ips/objectives.ips new file mode 100644 index 00000000..466d6aff Binary files /dev/null and b/worlds/sm/variaRandomizer/patches/common/ips/objectives.ips differ diff --git a/worlds/sm/variaRandomizer/patches/common/ips/percent.ips b/worlds/sm/variaRandomizer/patches/common/ips/percent.ips new file mode 100644 index 00000000..ab895f4e Binary files /dev/null and b/worlds/sm/variaRandomizer/patches/common/ips/percent.ips differ diff --git a/worlds/sm/variaRandomizer/patches/common/ips/plm_spawn.ips b/worlds/sm/variaRandomizer/patches/common/ips/plm_spawn.ips new file mode 100644 index 00000000..ce6c43a8 Binary files /dev/null and b/worlds/sm/variaRandomizer/patches/common/ips/plm_spawn.ips differ diff --git a/worlds/sm/variaRandomizer/patches/common/ips/rando_escape.ips b/worlds/sm/variaRandomizer/patches/common/ips/rando_escape.ips index 74dac2e6..bf5efac0 100644 Binary files a/worlds/sm/variaRandomizer/patches/common/ips/rando_escape.ips and b/worlds/sm/variaRandomizer/patches/common/ips/rando_escape.ips differ diff --git a/worlds/sm/variaRandomizer/patches/common/ips/relaxed_round_robin_cf.ips b/worlds/sm/variaRandomizer/patches/common/ips/relaxed_round_robin_cf.ips new file mode 100644 index 00000000..0ce5b4b4 Binary files /dev/null and b/worlds/sm/variaRandomizer/patches/common/ips/relaxed_round_robin_cf.ips differ diff --git a/worlds/sm/variaRandomizer/patches/common/ips/remove_Infinite_Space_Jump.ips b/worlds/sm/variaRandomizer/patches/common/ips/remove_Infinite_Space_Jump.ips new file mode 100644 index 00000000..ab00c37e Binary files /dev/null and b/worlds/sm/variaRandomizer/patches/common/ips/remove_Infinite_Space_Jump.ips differ diff --git a/worlds/sm/variaRandomizer/patches/common/ips/remove_elevators_doors_speed.ips b/worlds/sm/variaRandomizer/patches/common/ips/remove_elevators_doors_speed.ips index 1c60d267..2906ec2c 100644 Binary files a/worlds/sm/variaRandomizer/patches/common/ips/remove_elevators_doors_speed.ips and b/worlds/sm/variaRandomizer/patches/common/ips/remove_elevators_doors_speed.ips differ diff --git a/worlds/sm/variaRandomizer/patches/common/ips/remove_elevators_speed.ips b/worlds/sm/variaRandomizer/patches/common/ips/remove_elevators_speed.ips new file mode 100644 index 00000000..e7a1a7fe Binary files /dev/null and b/worlds/sm/variaRandomizer/patches/common/ips/remove_elevators_speed.ips differ diff --git a/worlds/sm/variaRandomizer/patches/common/ips/remove_fast_doors.ips b/worlds/sm/variaRandomizer/patches/common/ips/remove_fast_doors.ips new file mode 100644 index 00000000..688877ef Binary files /dev/null and b/worlds/sm/variaRandomizer/patches/common/ips/remove_fast_doors.ips differ diff --git a/worlds/sm/variaRandomizer/patches/common/ips/remove_rando_speed.ips b/worlds/sm/variaRandomizer/patches/common/ips/remove_rando_speed.ips new file mode 100644 index 00000000..506bb5c8 Binary files /dev/null and b/worlds/sm/variaRandomizer/patches/common/ips/remove_rando_speed.ips differ diff --git a/worlds/sm/variaRandomizer/patches/common/ips/remove_spinjumprestart.ips b/worlds/sm/variaRandomizer/patches/common/ips/remove_spinjumprestart.ips new file mode 100644 index 00000000..6197f8f1 Binary files /dev/null and b/worlds/sm/variaRandomizer/patches/common/ips/remove_spinjumprestart.ips differ diff --git a/worlds/sm/variaRandomizer/patches/common/ips/seed_display.ips b/worlds/sm/variaRandomizer/patches/common/ips/seed_display.ips new file mode 100644 index 00000000..59286a5b Binary files /dev/null and b/worlds/sm/variaRandomizer/patches/common/ips/seed_display.ips differ diff --git a/worlds/sm/variaRandomizer/patches/common/ips/tracking.ips b/worlds/sm/variaRandomizer/patches/common/ips/tracking.ips new file mode 100644 index 00000000..d0cc9355 Binary files /dev/null and b/worlds/sm/variaRandomizer/patches/common/ips/tracking.ips differ diff --git a/worlds/sm/variaRandomizer/patches/common/ips/vanilla_bugfixes.ips b/worlds/sm/variaRandomizer/patches/common/ips/vanilla_bugfixes.ips new file mode 100644 index 00000000..c0ea25d7 Binary files /dev/null and b/worlds/sm/variaRandomizer/patches/common/ips/vanilla_bugfixes.ips differ diff --git a/worlds/sm/variaRandomizer/patches/common/ips/varia_hud.ips b/worlds/sm/variaRandomizer/patches/common/ips/varia_hud.ips index 5002a67c..d0a0ac8e 100644 Binary files a/worlds/sm/variaRandomizer/patches/common/ips/varia_hud.ips and b/worlds/sm/variaRandomizer/patches/common/ips/varia_hud.ips differ diff --git a/worlds/sm/variaRandomizer/patches/common/ips/widescreen.ips b/worlds/sm/variaRandomizer/patches/common/ips/widescreen.ips new file mode 100644 index 00000000..6d4e2093 Binary files /dev/null and b/worlds/sm/variaRandomizer/patches/common/ips/widescreen.ips differ diff --git a/worlds/sm/variaRandomizer/patches/common/patches.py b/worlds/sm/variaRandomizer/patches/common/patches.py index c61d53f4..64ee8333 100644 --- a/worlds/sm/variaRandomizer/patches/common/patches.py +++ b/worlds/sm/variaRandomizer/patches/common/patches.py @@ -51,8 +51,29 @@ patches = { "Enable_Backup_Saves": { 0xef20: [0x1] }, - 'Escape_Scavenger' : { - 0x10F5FC: [0x1] + 'Escape_Trigger' : { + 0x10F5FE: [0x1] + }, + 'Escape_Trigger_Disable' : { + 0x10F5FE: [0x0] + }, + # actually a bitmask: + # high bit is for sfx play on obj completion, low bit for trigger escape + # only in crateria (standard in rando, default in the patch) for nothing objectives. + # we want to play sfx on objective completion only with non-standard objectives + 'Objectives_sfx' : { + 0x10F5FF: [0x81] + }, + # see above, used in plandos so trigger escape whatever the start loc is + # with nothing objective. With this, we'll play sfx even in plandos + # with standard objectives, but it'll prevent to handle these patches + # as anything else that just bytes. + 'Escape_Trigger_Nothing_Objective_Anywhere' : { + 0x10F5FF: [0x80] + }, + # for development/quickmet: disable clear save files on 1st boot + "Disable_Clear_Save_Boot": { + 0x7E39: [0x4c, 0x7c, 0xfe] }, # vanilla data to restore setup asm for plandos "Escape_Animals_Disable": { @@ -96,6 +117,9 @@ patches = { "SpriteSomething_Disable_Spin_Attack": { 0xD93FE: [0x0, 0x0] }, + "Ship_Takeoff_Disable_Hide_Samus": { + 0x112B13: [0x6B] + }, # custom load points for non standard start APs "Save_G4": { # load point entry @@ -314,6 +338,32 @@ patches = { 0x78A34: [0x48, 0xc8, 0x01, 0x16, 0x47, 0x8c], 0x109F37: [0x0] }, + # only set blinking in "zebes asleep" room state to avoid having + # the door blink when not needed + # (only needed for escape peek in Crateria-less minimizer with disabled Tourian) + 'Blinking[Climb Bottom Left]': { + 0x782FE: [0x48, 0xc8, 0x01, 0x86, 0x12, 0x8c], + 0x108683: [0x0] + }, + # Climb always in "zebes asleep" state, except during escape + # (for escape peek in Crateria-less minimizer with disabled Tourian) + 'Climb_Asleep': { + # replace "zebes awake" event ID with an unused event + 0x796CC: [0x7F], + # put "Statues Hall" tension music + 0x796D6: [0x04] + }, + # Indicator PLM IDs set to ffff because they're set dynamically + 'Indicator[KihunterBottom]': { + 0x78256: [0xff, 0xff, 0x06, 0x02, 0x0e, 0x00] + }, + 'Indicator[GreenHillZoneTopRight]': { + 0x78746: [0xff, 0xff, 0x01, 0x26, 0x30, 0x00] + }, + # cancels the gamestate change by new_game.asm + "Restore_Intro": { + 0x16EDA: [0x1E] + } } additional_PLMs = { @@ -550,4 +600,101 @@ additional_PLMs = { [0x48, 0xc8, 0x01, 0x16, 0x63, 0x8c] ] }, + # Indicator PLM IDs set to ffff because they're set dynamically + 'Indicator[LandingSiteRight]': { + 'room': 0x948c, + 'plm_bytes_list': [ + [0xff, 0xff, 0x01, 0x06, 0x00, 0x00] + ] + }, + 'Indicator[KihunterRight]': { + 'room': 0x95ff, + 'plm_bytes_list': [ + [0xff, 0xff, 0x01, 0x06, 0x0d, 0x00] + ] + }, + 'Indicator[NoobBridgeRight]': { + 'room': 0xa253, + 'plm_bytes_list': [ + [0xff, 0xff, 0x01, 0x46, 0x33, 0x00] + ] + }, + 'Indicator[MainShaftBottomRight]': { + 'room': 0x9cb3, + 'plm_bytes_list': [ + [0xff, 0xff, 0x01, 0x06, 0x22, 0x00] + ] + }, + 'Indicator[BigPinkBottomRight]': { + 'room': 0x9e52, + 'plm_bytes_list': [ + [0xff, 0xff, 0x01, 0x06, 0x29, 0x00] + ] + }, + 'Indicator[RedTowerElevatorLeft]': { + 'room': 0xa2f7, + 'plm_bytes_list': [ + [0xff, 0xff, 0x2e, 0x06, 0x3c, 0x00] + ] + }, + 'Indicator[WestOceanRight]': { + 'room': 0xca08, + 'plm_bytes_list': [ + [0xff, 0xff, 0x01, 0x06, 0x0c, 0x00] + ] + }, + 'Indicator[LeCoudeBottom]': { + 'room': 0x94cc, + 'plm_bytes_list': [ + [0xff, 0xff, 0x06, 0x02, 0x0f, 0x00] + ] + }, + 'Indicator[WreckedShipMainShaftBottom]': { + 'room': 0xcc6f, + 'plm_bytes_list': [ + [0xff, 0xff, 0x26, 0x02, 0x84, 0x00] + ] + }, + 'Indicator[CathedralEntranceRight]': { + 'room': 0xa788, + 'plm_bytes_list': [ + [0xff, 0xff, 0x01, 0x06, 0x4a, 0x00] + ] + }, + 'Indicator[CathedralRight]': { + 'room': 0xafa3, + 'plm_bytes_list': [ + [0xff, 0xff, 0x01, 0x06, 0x49, 0x00] + ] + }, + 'Indicator[RedKihunterShaftBottom]': { + 'room': 0xb5d5, + 'plm_bytes_list': [ + [0xff, 0xff, 0x56, 0x02, 0x5e, 0x00] + ] + }, + 'Indicator[WastelandLeft]': { + 'room': 0xb62b, + 'plm_bytes_list': [ + [0xff, 0xff, 0x2e, 0x06, 0x5f, 0x00] + ] + }, + 'Indicator[MainStreetBottomRight]': { + 'room': 0xd08a, + 'plm_bytes_list': [ + [0xff, 0xff, 0x01, 0x06, 0x8d, 0x00] + ] + }, + 'Indicator[CrabShaftRight]': { + 'room': 0xd5a7, + 'plm_bytes_list': [ + [0xff, 0xff, 0x01, 0x16, 0x8f, 0x00] + ] + }, + 'Indicator[ColosseumBottomRight]': { + 'room': 0xd78f, + 'plm_bytes_list': [ + [0xff, 0xff, 0x01, 0x06, 0x9a, 0x00] + ] + } } diff --git a/worlds/sm/variaRandomizer/patches/vanilla/ips/aqueduct_bomb_blocks.ips b/worlds/sm/variaRandomizer/patches/vanilla/ips/aqueduct_bomb_blocks.ips new file mode 100644 index 00000000..0ca9a658 Binary files /dev/null and b/worlds/sm/variaRandomizer/patches/vanilla/ips/aqueduct_bomb_blocks.ips differ diff --git a/worlds/sm/variaRandomizer/patches/vanilla/ips/climb_disable_bomb_blocks.ips b/worlds/sm/variaRandomizer/patches/vanilla/ips/climb_disable_bomb_blocks.ips new file mode 100644 index 00000000..6c7c78eb Binary files /dev/null and b/worlds/sm/variaRandomizer/patches/vanilla/ips/climb_disable_bomb_blocks.ips differ diff --git a/worlds/sm/variaRandomizer/rando/GraphBuilder.py b/worlds/sm/variaRandomizer/rando/GraphBuilder.py index 9cde4206..3577baff 100644 --- a/worlds/sm/variaRandomizer/rando/GraphBuilder.py +++ b/worlds/sm/variaRandomizer/rando/GraphBuilder.py @@ -1,9 +1,13 @@ import random, copy from ..utils import log -from ..graph.graph_utils import GraphUtils, vanillaTransitions, vanillaBossesTransitions, escapeSource, escapeTargets +from ..graph.graph_utils import GraphUtils, vanillaTransitions, vanillaBossesTransitions, escapeSource, escapeTargets, graphAreas, getAccessPoint from ..logic.logic import Logic from ..graph.graph import AccessGraphRando as AccessGraph +from ..logic.smbool import SMBool +from ..utils.objectives import Objectives +from ..rando.ItemLocContainer import getItemLocStr +from collections import defaultdict # creates graph and handles randomized escape class GraphBuilder(object): @@ -16,12 +20,37 @@ class GraphBuilder(object): self.log = log.get('GraphBuilder') # builds everything but escape transitions - def createGraph(self): + def createGraph(self, maxDiff): transitions = self.graphSettings.plandoRandoTransitions if transitions is None: transitions = [] if self.minimizerN is not None: - transitions = GraphUtils.createMinimizerTransitions(self.graphSettings.startAP, self.minimizerN) + forcedAreas = set() + # if no Crateria and auto escape trigger, we connect door connected to G4 to climb instead (see below). + # This wouldn't work here, as Tourian is isolated in the resulting seed (see below again) + # (well we could do two different transitions on both sides of doors, but that would just be confusing) + # so we force crateria to be in the graph + if self.graphSettings.startAP == "Golden Four" and self.graphSettings.tourian == "Disabled": + forcedAreas.add('Crateria') + # force areas required by objectives + # 1st the 'clear area' ones + forcedAreas = forcedAreas.union({goal.area for goal in Objectives.objDict[self.graphSettings.player].activeGoals if goal.area is not None}) + # for the rest, base ourselves on escapeAccessPoints : + # - if only "1 of n" pick an area, preferably one already forced + # - filter out G4 AP (always there) + for goal in Objectives.objDict[self.graphSettings.player].activeGoals: + if goal.area is None: + n, apNames = goal.escapeAccessPoints + aps = [getAccessPoint(apName) for apName in apNames] + if len(aps) >= n: + n -= len([ap for ap in aps if ap.Boss]) + escAreas = {ap.GraphArea for ap in aps if not ap.Boss} + objForced = forcedAreas.intersection(escAreas) + escAreasList = sorted(list(escAreas)) + while len(objForced) < n and len(escAreasList) > 0: + objForced.add(escAreasList.pop(random.randint(0, len(escAreasList)-1))) + forcedAreas = forcedAreas.union(objForced) + transitions = GraphUtils.createMinimizerTransitions(self.graphSettings.startAP, self.minimizerN, sorted(list(forcedAreas))) else: if not self.bossRando: transitions += vanillaBossesTransitions @@ -31,26 +60,44 @@ class GraphBuilder(object): transitions += vanillaTransitions else: transitions += GraphUtils.createAreaTransitions(self.graphSettings.lightAreaRando) - return AccessGraph(Logic.accessPoints, transitions, self.graphSettings.dotFile) + ret = AccessGraph(Logic.accessPoints, transitions, self.graphSettings.dotFile) + Objectives.objDict[self.graphSettings.player].setGraph(ret, maxDiff) + return ret + + def addForeignItems(self, container, itemLocs): + itemPoolCounts = {} + for item in container.itemPool: + if item.Code is not None: + itemPoolCounts[item.Type] = itemPoolCounts.get(item.Type, 0) + 1 + itemLocsCounts = {} + for il in itemLocs: + if il.Item.Code is not None and il.player == container.sm.player: + itemLocsCounts[il.Item.Type] = itemLocsCounts.get(il.Item.Type, 0) + 1 + + for item, count in itemPoolCounts.items(): + for n in range(max(0, count - itemLocsCounts.get(item, 0))): + container.sm.addItem(item) # fills in escape transitions if escape rando is enabled - # scavEscape = None or (itemLocs, scavItemLocs) couple from filler - def escapeGraph(self, container, graph, maxDiff, scavEscape): + # escapeTrigger = None or (itemLocs, progItemlocs) couple from filler + def escapeGraph(self, container, graph, maxDiff, escapeTrigger): if not self.escapeRando: return True emptyContainer = copy.copy(container) emptyContainer.resetCollected(reassignItemLocs=True) dst = None - if scavEscape is None: + if escapeTrigger is None: possibleTargets, dst, path = self.getPossibleEscapeTargets(emptyContainer, graph, maxDiff) # update graph with escape transition graph.addTransition(escapeSource, dst) + paths = [path] else: - possibleTargets, path = self.getScavengerEscape(emptyContainer, graph, maxDiff, scavEscape) - if path is None: + self.addForeignItems(emptyContainer, escapeTrigger[0]) + possibleTargets, paths = self.escapeTrigger(emptyContainer, graph, maxDiff, escapeTrigger) + if paths is None: return False # get timer value - self.escapeTimer(graph, path, self.areaRando or scavEscape is not None) + self.escapeTimer(graph, paths, self.areaRando or escapeTrigger is not None) self.log.debug("escapeGraph: ({}, {}) timer: {}".format(escapeSource, dst, graph.EscapeAttributes['Timer'])) # animals GraphUtils.escapeAnimalsTransitions(graph, possibleTargets, dst) @@ -68,10 +115,10 @@ class GraphBuilder(object): def getPossibleEscapeTargets(self, emptyContainer, graph, maxDiff): sm = emptyContainer.sm - # setup smbm with item pool - # Ice not usable because of hyper beam - # remove energy to avoid hell runs - # (will add bosses as well) + # setup smbm with item pool: + # - Ice not usable because of hyper beam + # - remove energy to avoid hell runs + # - (will add bosses as well) sm.addItems([item.Type for item in emptyContainer.itemPool if item.Type != 'Ice' and item.Category != 'Energy']) sm.addItem('Hyper') possibleTargets = self._getTargets(sm, graph, maxDiff) @@ -80,55 +127,167 @@ class GraphBuilder(object): path = graph.accessPath(sm, dst, 'Landing Site', maxDiff) return (possibleTargets, dst, path) - def getScavengerEscape(self, emptyContainer, graph, maxDiff, scavEscape): - sm = emptyContainer.sm - itemLocs, lastScavItemLoc = scavEscape[0], scavEscape[1][-1] - # collect all item/locations up until last scav - for il in itemLocs: - emptyContainer.collect(il) - if il == lastScavItemLoc: - break + def escapeTrigger(self, emptyContainer, graph, maxDiff, escapeTrigger): + container = emptyContainer + sm = container.sm + allItemLocs,progItemLocs,split = escapeTrigger[0],escapeTrigger[1],escapeTrigger[2] + # check if crateria is connected, if not replace Tourian + # connection with Climb and add special escape patch to Climb + if not any(il.Location.GraphArea == "Crateria" for il in allItemLocs): + escapeAttr = graph.EscapeAttributes + if "patches" not in escapeAttr: + escapeAttr['patches'] = [] + escapeAttr['patches'] += ['climb_disable_bomb_blocks.ips', "Climb_Asleep"] + src, _ = next(t for t in graph.InterAreaTransitions if t[1].Name == "Golden Four") + graph.removeTransitions("Golden Four") + graph.addTransition(src.Name, "Climb Bottom Left") + # disconnect the other side of G4 + graph.addTransition("Golden Four", "Golden Four") + # remove vanilla escape transition + graph.addTransition('Tourian Escape Room 4 Top Right', 'Tourian Escape Room 4 Top Right') + # filter garbage itemLocs + ilCheck = lambda il: not il.Location.isBoss() and not il.Location.restricted and il.Item.Category != "Nothing" + # update item% objectives + accessibleItems = [il.Item for il in allItemLocs if ilCheck(il)] + majorUpgrades = [item.Type for item in accessibleItems if item.BeamBits != 0 or item.ItemBits != 0] + sm.objectives.setItemPercentFuncs(len(accessibleItems), majorUpgrades) + if split == "Scavenger": + # update escape access for scav with last scav loc + lastScavItemLoc = progItemLocs[-1] + sm.objectives.updateScavengerEscapeAccess(lastScavItemLoc.Location.accessPoint) + sm.objectives.setScavengerHuntFunc(lambda sm, ap: sm.haveItem(lastScavItemLoc.Item.Type)) + else: + # update "collect all items in areas" funcs + availLocsByArea=defaultdict(list) + for itemLoc in allItemLocs: + if ilCheck(itemLoc) and (split.startswith("Full") or itemLoc.Location.isClass(split)): + availLocsByArea[itemLoc.Location.GraphArea].append(itemLoc.Location.Name) + self.log.debug("escapeTrigger. availLocsByArea="+str(availLocsByArea)) + sm.objectives.setAreaFuncs({area:lambda sm,ap:SMBool(len(container.getLocs(lambda loc: loc.Name in availLocsByArea[area]))==0) for area in availLocsByArea}) + self.log.debug("escapeTrigger. collect locs until G4 access") + # collect all item/locations up until we can pass G4 (the escape triggers) + itemLocs = allItemLocs[:] + ap = "Landing Site" # dummy value it'll be overwritten at first collection + while len(itemLocs) > 0 and not (sm.canPassG4() and graph.canAccess(sm, ap, "Landing Site", maxDiff)): + il = itemLocs.pop(0) + if il.Location.restricted or il.Item.Type == "ArchipelagoItem": + continue + self.log.debug("collecting " + getItemLocStr(il)) + container.collect(il) + ap = il.Location.accessPoint + # final update of item% obj + collectedLocsAccessPoints = {il.Location.accessPoint for il in container.itemLocations} + sm.objectives.updateItemPercentEscapeAccess(list(collectedLocsAccessPoints)) possibleTargets = self._getTargets(sm, graph, maxDiff) - path = graph.accessPath(sm, lastScavItemLoc.Location.accessPoint, 'Landing Site', maxDiff) - return (possibleTargets, path) + # try to escape from all the possible objectives APs + possiblePaths = [] + for goal in Objectives.objDict[self.graphSettings.player].activeGoals: + n, possibleAccessPoints = goal.escapeAccessPoints + count = 0 + for ap in possibleAccessPoints: + self.log.debug("escapeTrigger. testing AP " + ap) + path = graph.accessPath(sm, ap, 'Landing Site', maxDiff) + if path is not None: + self.log.debug("escapeTrigger. add path from "+ap) + possiblePaths.append(path) + count += 1 + if count < n: + # there is a goal we cannot escape from + self.log.debug("escapeTrigger. goal %s: found %d/%d possible escapes, abort" % (goal.name, count, n)) + return (None, None) + # try and get a path from all possible areas + self.log.debug("escapeTrigger. completing paths") + allAreas = {il.Location.GraphArea for il in allItemLocs if not il.Location.restricted and not il.Location.GraphArea in ["Tourian", "Ceres"]} + def getStartArea(path): + return path[0].GraphArea + def apCheck(ap): + nonlocal graph, possiblePaths + apObj = graph.accessPoints[ap] + return apObj.GraphArea not in [getStartArea(path) for path in possiblePaths] + escapeAPs = [ap for ap in collectedLocsAccessPoints if apCheck(ap)] + for ap in escapeAPs: + path = graph.accessPath(sm, ap, 'Landing Site', maxDiff) + if path is not None: + self.log.debug("escapeTrigger. add path from "+ap) + possiblePaths.append(path) + def areaPathCheck(): + nonlocal allAreas, possiblePaths + startAreas = {getStartArea(path) for path in possiblePaths} + return len(allAreas - startAreas) == 0 + while not areaPathCheck() and len(itemLocs) > 0: + il = itemLocs.pop(0) + if il.Location.restricted or il.Item.Type == "ArchipelagoItem": + continue + self.log.debug("collecting " + getItemLocStr(il)) + container.collect(il) + ap = il.Location.accessPoint + if apCheck(ap): + path = graph.accessPath(sm, ap, 'Landing Site', maxDiff) + if path is not None: + self.log.debug("escapeTrigger. add path from "+ap) + possiblePaths.append(path) + + return (possibleTargets, possiblePaths) + + def _computeTimer(self, graph, path): + traversedAreas = list(set([ap.GraphArea for ap in path])) + self.log.debug("escapeTimer path: " + str([ap.Name for ap in path])) + self.log.debug("escapeTimer traversedAreas: " + str(traversedAreas)) + # rough estimates of navigation within areas to reach "borders" + # (can obviously be completely off wrt to actual path, but on the generous side) + traversals = { + 'Crateria':90, + 'GreenPinkBrinstar':90, + 'WreckedShip':120, + 'LowerNorfair':135, + 'WestMaridia':75, + 'EastMaridia':100, + 'RedBrinstar':75, + 'Norfair': 120, + 'Kraid': 40, + 'Crocomire': 40, + # can't be on the path + 'Tourian': 0, + } + t = 90 if self.areaRando else 0 + for area in traversedAreas: + t += traversals[area] + t = max(t, 180) + return t + # path: as returned by AccessGraph.accessPath - def escapeTimer(self, graph, path, compute): - if compute == True: - if path[0].Name == 'Climb Bottom Left': - graph.EscapeAttributes['Timer'] = None - return - traversedAreas = list(set([ap.GraphArea for ap in path])) - self.log.debug("escapeTimer path: " + str([ap.Name for ap in path])) - self.log.debug("escapeTimer traversedAreas: " + str(traversedAreas)) - # rough estimates of navigation within areas to reach "borders" - # (can obviously be completely off wrt to actual path, but on the generous side) - traversals = { - 'Crateria':90, - 'GreenPinkBrinstar':90, - 'WreckedShip':120, - 'LowerNorfair':135, - 'WestMaridia':75, - 'EastMaridia':100, - 'RedBrinstar':75, - 'Norfair': 120, - 'Kraid': 40, - 'Crocomire': 40, - # can't be on the path - 'Tourian': 0, - } - t = 90 if self.areaRando else 0 - for area in traversedAreas: - t += traversals[area] - t = max(t, 180) + def escapeTimer(self, graph, paths, compute): + if len(paths) == 1: + path = paths.pop() + if compute == True: + if path[0].Name == 'Climb Bottom Left': + graph.EscapeAttributes['Timer'] = None + return + t = self._computeTimer(graph, path) + else: + escapeTargetsTimer = { + 'Climb Bottom Left': None, # vanilla + 'Green Brinstar Main Shaft Top Left': 210, # brinstar + 'Basement Left': 210, # wrecked ship + 'Business Center Mid Left': 270, # norfair + 'Crab Hole Bottom Right': 270 # maridia + } + t = escapeTargetsTimer[path[0].Name] + self.log.debug("escapeTimer. t="+str(t)) + graph.EscapeAttributes['Timer'] = t else: - escapeTargetsTimer = { - 'Climb Bottom Left': None, # vanilla - 'Green Brinstar Main Shaft Top Left': 210, # brinstar - 'Basement Left': 210, # wrecked ship - 'Business Center Mid Left': 270, # norfair - 'Crab Hole Bottom Right': 270 # maridia - } - t = escapeTargetsTimer[path[0].Name] - self.log.debug("escapeTimer. t="+str(t)) - graph.EscapeAttributes['Timer'] = t + assert compute + graph.EscapeAttributes['Timer'] = 0 + timerValues = {} + graph.EscapeAttributes['TimerTable'] = timerValues + for path in paths: + area = path[0].GraphArea + prev = timerValues.get(area, 0) + t = max(prev, self._computeTimer(graph, path)) + timerValues[area] = t + self.log.debug("escapeTimer. area=%s, t=%d" % (area, t)) + for area in graphAreas[1:-1]: # no Ceres or Tourian + if area not in timerValues: + # area not in graph most probably, still write a 10 minute "ultra failsafe" value + timerValues[area] = 600 diff --git a/worlds/sm/variaRandomizer/rando/ItemLocContainer.py b/worlds/sm/variaRandomizer/rando/ItemLocContainer.py index 524e3190..cdde5b42 100644 --- a/worlds/sm/variaRandomizer/rando/ItemLocContainer.py +++ b/worlds/sm/variaRandomizer/rando/ItemLocContainer.py @@ -6,12 +6,13 @@ from ..logic.smboolmanager import SMBoolManager from collections import Counter class ItemLocation(object): - __slots__ = ( 'Item', 'Location', 'Accessible' ) + __slots__ = ( 'Item', 'Location', 'Accessible', 'player' ) - def __init__(self, Item=None, Location=None, accessible=True): + def __init__(self, Item=None, Location=None, player=0, accessible=True): self.Item = Item self.Location = Location self.Accessible = accessible + self.player = player def json(self): return {'Item': self.Item.json(), 'Location': self.Location.json()} diff --git a/worlds/sm/variaRandomizer/rando/Items.py b/worlds/sm/variaRandomizer/rando/Items.py index 6bfa8530..ec58b478 100644 --- a/worlds/sm/variaRandomizer/rando/Items.py +++ b/worlds/sm/variaRandomizer/rando/Items.py @@ -40,7 +40,7 @@ class ItemManager: 'ETank': Item( Category='Energy', Class='Major', - Code=0xf870, + Code=0xfc20, Name="Energy Tank", Type='ETank', Id=0 @@ -48,7 +48,7 @@ class ItemManager: 'Missile': Item( Category='Ammo', Class='Minor', - Code=0xf870, + Code=0xfc20, Name="Missile", Type='Missile', Id=1 @@ -56,7 +56,7 @@ class ItemManager: 'Super': Item( Category='Ammo', Class='Minor', - Code=0xf870, + Code=0xfc20, Name="Super Missile", Type='Super', Id=2 @@ -64,7 +64,7 @@ class ItemManager: 'PowerBomb': Item( Category='Ammo', Class='Minor', - Code=0xf870, + Code=0xfc20, Name="Power Bomb", Type='PowerBomb', Id=3 @@ -72,7 +72,7 @@ class ItemManager: 'Bomb': Item( Category='Progression', Class='Major', - Code=0xf870, + Code=0xfc20, Name="Bomb", Type='Bomb', ItemBits=0x1000, @@ -81,7 +81,7 @@ class ItemManager: 'Charge': Item( Category='Beam', Class='Major', - Code=0xf870, + Code=0xfc20, Name="Charge Beam", Type='Charge', BeamBits=0x1000, @@ -90,7 +90,7 @@ class ItemManager: 'Ice': Item( Category='Progression', Class='Major', - Code=0xf870, + Code=0xfc20, Name="Ice Beam", Type='Ice', BeamBits=0x2, @@ -99,7 +99,7 @@ class ItemManager: 'HiJump': Item( Category='Progression', Class='Major', - Code=0xf870, + Code=0xfc20, Name="Hi-Jump Boots", Type='HiJump', ItemBits=0x100, @@ -108,7 +108,7 @@ class ItemManager: 'SpeedBooster': Item( Category='Progression', Class='Major', - Code=0xf870, + Code=0xfc20, Name="Speed Booster", Type='SpeedBooster', ItemBits=0x2000, @@ -117,7 +117,7 @@ class ItemManager: 'Wave': Item( Category='Beam', Class='Major', - Code=0xf870, + Code=0xfc20, Name="Wave Beam", Type='Wave', BeamBits=0x1, @@ -126,7 +126,7 @@ class ItemManager: 'Spazer': Item( Category='Beam', Class='Major', - Code=0xf870, + Code=0xfc20, Name="Spazer", Type='Spazer', BeamBits=0x4, @@ -135,7 +135,7 @@ class ItemManager: 'SpringBall': Item( Category='Misc', Class='Major', - Code=0xf870, + Code=0xfc20, Name="Spring Ball", Type='SpringBall', ItemBits=0x2, @@ -144,7 +144,7 @@ class ItemManager: 'Varia': Item( Category='Progression', Class='Major', - Code=0xf870, + Code=0xfc20, Name="Varia Suit", Type='Varia', ItemBits=0x1, @@ -153,7 +153,7 @@ class ItemManager: 'Plasma': Item( Category='Beam', Class='Major', - Code=0xf870, + Code=0xfc20, Name="Plasma Beam", Type='Plasma', BeamBits=0x8, @@ -162,7 +162,7 @@ class ItemManager: 'Grapple': Item( Category='Progression', Class='Major', - Code=0xf870, + Code=0xfc20, Name="Grappling Beam", Type='Grapple', ItemBits=0x4000, @@ -171,7 +171,7 @@ class ItemManager: 'Morph': Item( Category='Progression', Class='Major', - Code=0xf870, + Code=0xfc20, Name="Morph Ball", Type='Morph', ItemBits=0x4, @@ -180,7 +180,7 @@ class ItemManager: 'Reserve': Item( Category='Energy', Class='Major', - Code=0xf870, + Code=0xfc20, Name="Reserve Tank", Type='Reserve', Id=20 @@ -188,7 +188,7 @@ class ItemManager: 'Gravity': Item( Category='Progression', Class='Major', - Code=0xf870, + Code=0xfc20, Name="Gravity Suit", Type='Gravity', ItemBits=0x20, @@ -197,7 +197,7 @@ class ItemManager: 'XRayScope': Item( Category='Misc', Class='Major', - Code=0xf870, + Code=0xfc20, Name="X-Ray Scope", Type='XRayScope', ItemBits=0x8000, @@ -206,7 +206,7 @@ class ItemManager: 'SpaceJump': Item( Category='Progression', Class='Major', - Code=0xf870, + Code=0xfc20, Name="Space Jump", Type='SpaceJump', ItemBits=0x200, @@ -215,7 +215,7 @@ class ItemManager: 'ScrewAttack': Item( Category='Misc', Class='Major', - Code=0xf870, + Code=0xfc20, Name="Screw Attack", Type='ScrewAttack', ItemBits= 0x8, @@ -247,7 +247,7 @@ class ItemManager: Category='Boss', Class='Boss', Name="Phantoon", - Type='Phantoon' + Type='Phantoon', ), 'Draygon': Item( Category='Boss', @@ -267,6 +267,30 @@ class ItemManager: Name="Mother Brain", Type='MotherBrain', ), + 'SporeSpawn': Item( + Category='MiniBoss', + Class='Boss', + Name="Spore Spawn", + Type='SporeSpawn', + ), + 'Crocomire': Item( + Category='MiniBoss', + Class='Boss', + Name="Crocomire", + Type='Crocomire', + ), + 'Botwoon': Item( + Category='MiniBoss', + Class='Boss', + Name="Botwoon", + Type='Botwoon', + ), + 'GoldenTorizo': Item( + Category='MiniBoss', + Class='Boss', + Name="Golden Torizo", + Type='GoldenTorizo', + ), # used only during escape path check 'Hyper': Item( Category='Beam', @@ -278,7 +302,7 @@ class ItemManager: 'ArchipelagoItem': Item( Category='ArchipelagoItem', Class='Major', - Code=0xf870, + Code=0xfc20, Name="Generic", Type='ArchipelagoItem', Id=21 @@ -311,11 +335,12 @@ class ItemManager: itemCode = item.Code + modifier return itemCode - def __init__(self, majorsSplit, qty, sm, nLocs, maxDiff): + def __init__(self, majorsSplit, qty, sm, nLocs, bossesItems, maxDiff): self.qty = qty self.sm = sm self.majorsSplit = majorsSplit self.nLocs = nLocs + self.bossesItems = bossesItems self.maxDiff = maxDiff self.majorClass = 'Chozo' if majorsSplit == 'Chozo' else 'Major' self.itemPool = [] @@ -324,7 +349,7 @@ class ItemManager: self.itemPool = [] if addBosses == True: # for the bosses - for boss in ['Kraid', 'Phantoon', 'Draygon', 'Ridley', 'MotherBrain']: + for boss in self.bossesItems: self.addMinor(boss) def getItemPool(self): @@ -372,13 +397,17 @@ class ItemManager: return len([item for item in self.itemPool if item.Type == itemName]) >= count class ItemPoolGenerator(object): + # 100 item locs, 5 bosses, 4 mini bosses + maxLocs = 109 + nbBosses = 9 + @staticmethod def factory(majorsSplit, itemManager, qty, sm, exclude, nLocs, maxDiff): if majorsSplit == 'Chozo': return ItemPoolGeneratorChozo(itemManager, qty, sm, maxDiff) elif majorsSplit == 'Plando': return ItemPoolGeneratorPlando(itemManager, qty, sm, exclude, nLocs, maxDiff) - elif nLocs == 105: + elif nLocs == ItemPoolGenerator.maxLocs: if majorsSplit == "Scavenger": return ItemPoolGeneratorScavenger(itemManager, qty, sm, maxDiff) else: @@ -390,7 +419,7 @@ class ItemPoolGenerator(object): self.itemManager = itemManager self.qty = qty self.sm = sm - self.maxItems = 105 # 100 item locs and 5 bosses + self.maxItems = ItemPoolGenerator.maxLocs self.maxEnergy = 18 # 14E, 4R self.maxDiff = maxDiff self.log = log.get('ItemPool') @@ -405,7 +434,7 @@ class ItemPoolGenerator(object): pool = self.itemManager.getItemPool() energy = [item for item in pool if item.Category == 'Energy'] if len(energy) == 0: - self.maxMinors = 0.66*(self.maxItems - 5) # 5 for bosses + self.maxMinors = 0.66*(self.maxItems - ItemPoolGenerator.nbBosses) else: # if energy has been placed, we can be as accurate as possible self.maxMinors = self.maxItems - len(pool) + self.nbMinorsAlready @@ -675,7 +704,8 @@ class ItemPoolGeneratorMinimizer(ItemPoolGeneratorMajors): else: self.maxEnergy = 8 + int(float(nLocs - 55)/50.0 * 8) self.log.debug("maxEnergy: "+str(self.maxEnergy)) - maxItems = self.maxItems - 10 # remove bosses and minimal minore + # remove bosses and minimal minors + maxItems = self.maxItems - (self.nbMinorsAlready + len(self.itemManager.bossesItems)) self.maxEnergy = int(max(self.maxEnergy, maxItems - nMajors - self.minorLocations)) if self.maxEnergy > 18: self.maxEnergy = 18 @@ -707,7 +737,7 @@ class ItemPoolGeneratorPlando(ItemPoolGenerator): if item == 'total': continue itemClass = 'Major' - if item in ['Missile', 'Super', 'PowerBomb', 'Kraid', 'Phantoon', 'Draygon', 'Ridley', 'MotherBrain']: + if item in ['Missile', 'Super', 'PowerBomb', 'Kraid', 'Phantoon', 'Draygon', 'Ridley', 'MotherBrain', 'SporeSpawn', 'Crocomire', 'Botwoon', 'GoldenTorizo']: itemClass = 'Minor' for i in range(count): self.itemManager.addItem(item, itemClass) @@ -716,7 +746,7 @@ class ItemPoolGeneratorPlando(ItemPoolGenerator): self.log.debug("Plando: remain start: {}".format(remain)) if remain > 0: # add missing bosses - for boss in ['Kraid', 'Phantoon', 'Draygon', 'Ridley', 'MotherBrain']: + for boss in self.itemManager.bossesItems: if self.exclude['alreadyPlacedItems'][boss] == 0: self.itemManager.addItem(boss, 'Minor') self.exclude['alreadyPlacedItems'][boss] = 1 diff --git a/worlds/sm/variaRandomizer/rando/MiniSolver.py b/worlds/sm/variaRandomizer/rando/MiniSolver.py deleted file mode 100644 index 818632a0..00000000 --- a/worlds/sm/variaRandomizer/rando/MiniSolver.py +++ /dev/null @@ -1,63 +0,0 @@ - -import utils.log, random - -from logic.smboolmanager import SMBoolManager -from utils.parameters import infinity - -class MiniSolver(object): - def __init__(self, startAP, areaGraph, restrictions): - self.startAP = startAP - self.areaGraph = areaGraph - self.restrictions = restrictions - self.settings = restrictions.settings - self.smbm = SMBoolManager() - self.log = utils.log.get('MiniSolver') - - # if True, does not mean it is actually beatable, unless you're sure of it from another source of information - # if False, it is certain it is not beatable - def isBeatable(self, itemLocations, maxDiff=None): - if maxDiff is None: - maxDiff = self.settings.maxDiff - minDiff = self.settings.minDiff - locations = [] - for il in itemLocations: - loc = il.Location - if loc.restricted: - continue - loc.itemName = il.Item.Type - loc.difficulty = None - locations.append(loc) - self.smbm.resetItems() - ap = self.startAP - onlyBossesLeft = -1 - hasOneLocAboveMinDiff = False - while True: - if not locations: - return hasOneLocAboveMinDiff - # only two loops to collect all remaining locations in only bosses left mode - if onlyBossesLeft >= 0: - onlyBossesLeft += 1 - if onlyBossesLeft > 2: - return False - self.areaGraph.getAvailableLocations(locations, self.smbm, maxDiff, ap) - post = [loc for loc in locations if loc.PostAvailable and loc.difficulty.bool == True] - for loc in post: - self.smbm.addItem(loc.itemName) - postAvailable = loc.PostAvailable(self.smbm) - self.smbm.removeItem(loc.itemName) - loc.difficulty = self.smbm.wand(loc.difficulty, postAvailable) - toCollect = [loc for loc in locations if loc.difficulty.bool == True and loc.difficulty.difficulty <= maxDiff] - if not toCollect: - # mini onlyBossesLeft - if maxDiff < infinity: - maxDiff = infinity - onlyBossesLeft = 0 - continue - return False - if not hasOneLocAboveMinDiff: - hasOneLocAboveMinDiff = any(loc.difficulty.difficulty >= minDiff for loc in locations) - self.smbm.addItems([loc.itemName for loc in toCollect]) - for loc in toCollect: - locations.remove(loc) - # if len(locations) > 0: - # ap = random.choice([loc.accessPoint for loc in locations]) diff --git a/worlds/sm/variaRandomizer/rando/RandoExec.py b/worlds/sm/variaRandomizer/rando/RandoExec.py index 3505b180..8dbb5ae4 100644 --- a/worlds/sm/variaRandomizer/rando/RandoExec.py +++ b/worlds/sm/variaRandomizer/rando/RandoExec.py @@ -31,7 +31,7 @@ class RandoExec(object): vcr = VCR(self.seedName, 'rando') if self.vcr == True else None self.errorMsg = "" split = self.randoSettings.restrictions['MajorMinor'] - graphBuilder = GraphBuilder(self.graphSettings) + self.graphBuilder = GraphBuilder(self.graphSettings) container = None i = 0 attempts = 500 if self.graphSettings.areaRando or self.graphSettings.doorsColorsRando or split == 'Scavenger' else 1 @@ -44,23 +44,28 @@ class RandoExec(object): self.restrictions = Restrictions(self.randoSettings) if self.graphSettings.doorsColorsRando == True: DoorsManager.randomize(self.graphSettings.allowGreyDoors, self.player) - self.areaGraph = graphBuilder.createGraph() + self.areaGraph = self.graphBuilder.createGraph(self.randoSettings.maxDiff) services = RandoServices(self.areaGraph, self.restrictions) setup = RandoSetup(self.graphSettings, Logic.locations, services, self.player) self.setup = setup container = setup.createItemLocContainer(endDate, vcr) if container is None: sys.stdout.write('*') - sys.stdout.flush() i += 1 else: - self.errorMsg += '\n'.join(setup.errorMsgs) + self.errorMsg += '; '.join(setup.errorMsgs) now = time.process_time() if container is None: if self.graphSettings.areaRando: - self.errorMsg += "Could not find an area layout with these settings" - else: - self.errorMsg += "Unable to process settings" + self.errorMsg += "Could not find an area layout with these settings; " + if self.graphSettings.doorsColorsRando: + self.errorMsg += "Could not find a door color combination with these settings; " + if split == "Scavenger": + self.errorMsg += "Scavenger seed generation timed out; " + if setup.errorMsgs: + self.errorMsg += '; '.join(setup.errorMsgs) + if self.errorMsg == "": + self.errorMsg += "Unable to process settings; " self.areaGraph.printGraph() return container diff --git a/worlds/sm/variaRandomizer/rando/RandoServices.py b/worlds/sm/variaRandomizer/rando/RandoServices.py index 60f9df74..a3ad1f39 100644 --- a/worlds/sm/variaRandomizer/rando/RandoServices.py +++ b/worlds/sm/variaRandomizer/rando/RandoServices.py @@ -26,6 +26,13 @@ class RandoServices(object): self.cache = cache self.log = log.get('RandoServices') + @staticmethod + def printProgress(s): + sys.stdout.write(s) + # avoid flushing I/O on pythonanywhere, as they are very slow + if os.getenv("PYTHONANYWHERE_DOMAIN") is None: + sys.stdout.flush() + # collect an item/loc with logic in a container from a given AP # return new AP def collect(self, ap, container, itemLoc, pickup=True): @@ -36,8 +43,7 @@ class RandoServices(object): self.currentLocations(ap, container) container.collect(itemLoc, pickup=pickup) self.log.debug("COLLECT "+itemLoc.Item.Type+" at "+itemLoc.Location.Name) - sys.stdout.write('.') - sys.stdout.flush() + RandoServices.printProgress('.') return itemLoc.Location.accessPoint if pickup == True else ap # gives all the possible theoretical locations for a given item diff --git a/worlds/sm/variaRandomizer/rando/RandoSettings.py b/worlds/sm/variaRandomizer/rando/RandoSettings.py index 6895b597..418688f1 100644 --- a/worlds/sm/variaRandomizer/rando/RandoSettings.py +++ b/worlds/sm/variaRandomizer/rando/RandoSettings.py @@ -32,11 +32,11 @@ class RandoSettings(object): def isPlandoRando(self): return self.PlandoOptions is not None - def getItemManager(self, smbm, nLocs): + def getItemManager(self, smbm, nLocs, bossesItems): if not self.isPlandoRando(): - return ItemManager(self.restrictions['MajorMinor'], self.qty, smbm, nLocs, self.maxDiff) + return ItemManager(self.restrictions['MajorMinor'], self.qty, smbm, nLocs, bossesItems, self.maxDiff) else: - return ItemManager('Plando', self.qty, smbm, nLocs, self.maxDiff) + return ItemManager('Plando', self.qty, smbm, nLocs, bossesItems, self.maxDiff) def getExcludeItems(self, locations): if not self.isPlandoRando(): @@ -67,7 +67,11 @@ class RandoSettings(object): # Holds settings and utiliy functions related to graph layout class GraphSettings(object): - def __init__(self, startAP, areaRando, lightAreaRando, bossRando, escapeRando, minimizerN, dotFile, doorsColorsRando, allowGreyDoors, plandoRandoTransitions): + def __init__(self, player, startAP, areaRando, lightAreaRando, + bossRando, escapeRando, minimizerN, dotFile, + doorsColorsRando, allowGreyDoors, tourian, + plandoRandoTransitions): + self.player = player self.startAP = startAP self.areaRando = areaRando self.lightAreaRando = lightAreaRando @@ -77,6 +81,7 @@ class GraphSettings(object): self.dotFile = dotFile self.doorsColorsRando = doorsColorsRando self.allowGreyDoors = allowGreyDoors + self.tourian = tourian self.plandoRandoTransitions = plandoRandoTransitions def isMinimizer(self): @@ -122,10 +127,16 @@ class ProgSpeedParameters(object): elif progSpeed == 'fastest': return 0.33 return 0 + + # chozo/slowest can make seed generation fail often, not much + # of a gameplay difference between slow/slowest in Chozo anyway, + # so we merge slow and slowest for some params + def isSlow(self, progSpeed): + return progSpeed == "slow" or (progSpeed == "slowest" and self.restrictions.split == "Chozo") def getItemLimit(self, progSpeed): itemLimit = self.nLocs - if progSpeed == 'slow': + if self.isSlow(progSpeed): itemLimit = int(self.nLocs*0.209) # 21 for 105 elif progSpeed == 'medium': itemLimit = int(self.nLocs*0.095) # 9 for 105 @@ -143,7 +154,7 @@ class ProgSpeedParameters(object): def getLocLimit(self, progSpeed): locLimit = -1 - if progSpeed == 'slow': + if self.isSlow(progSpeed): locLimit = 1 elif progSpeed == 'medium': locLimit = 2 @@ -158,12 +169,12 @@ class ProgSpeedParameters(object): if self.restrictions.isLateDoors(): progTypes += ['Wave','Spazer','Plasma'] progTypes.append('Charge') - if progSpeed == 'slowest': + if progSpeed == 'slowest' and self.restrictions.split != "Chozo": return progTypes else: progTypes.remove('HiJump') progTypes.remove('Charge') - if progSpeed == 'slow': + if self.isSlow(progSpeed): return progTypes else: progTypes.remove('Bomb') diff --git a/worlds/sm/variaRandomizer/rando/RandoSetup.py b/worlds/sm/variaRandomizer/rando/RandoSetup.py index 637a5fed..943e3fe5 100644 --- a/worlds/sm/variaRandomizer/rando/RandoSetup.py +++ b/worlds/sm/variaRandomizer/rando/RandoSetup.py @@ -9,7 +9,9 @@ from ..graph.graph_utils import getAccessPoint, GraphUtils from ..rando.Filler import FrontFiller from ..rando.ItemLocContainer import ItemLocContainer, getLocListStr, ItemLocation, getItemListStr from ..rando.Restrictions import Restrictions +from ..utils.objectives import Objectives from ..utils.parameters import infinity +from ..rom.rom_patches import RomPatches # checks init conditions for the randomizer: processes super fun settings, graph, start location, special restrictions # the entry point is createItemLocContainer @@ -27,7 +29,9 @@ class RandoSetup(object): self.allLocations = locations self.locations = self.areaGraph.getAccessibleLocations(locations, self.startAP) # print("nLocs Setup: "+str(len(self.locations))) - self.itemManager = self.settings.getItemManager(self.sm, len(self.locations)) + # in minimizer we can have some missing boss locs + bossesItems = [loc.BossItemType for loc in self.locations if loc.isBoss()] + self.itemManager = self.settings.getItemManager(self.sm, len(self.locations), bossesItems) self.forbiddenItems = [] self.restrictedLocs = [] self.lastRestricted = [] @@ -67,7 +71,12 @@ class RandoSetup(object): for loc in self.restrictedLocs: self.log.debug("createItemLocContainer: loc is restricted: {}".format(loc.Name)) loc.restricted = True + + # checkDoorBeams calls checkPool, so save error messages + errorMsgsBck = self.errorMsgs[:] self.checkDoorBeams() + self.errorMsgs = errorMsgsBck + self.container = ItemLocContainer(self.sm, self.getItemPool(), self.locations) if self.restrictions.isLateMorph(): self.restrictions.lateMorphInit(self.startAP, self.container, self.services) @@ -122,7 +131,9 @@ class RandoSetup(object): self.log.debug("fillRestrictedLocations. locs="+getLocListStr(locs)) for loc in locs: itemLocation = ItemLocation(None, loc) - if self.container.hasItemInPool(getPred('Nothing', loc)): + if loc.BossItemType is not None: + itemLocation.Item = self.container.getNextItemInPoolMatching(getPred(loc.BossItemType, loc)) + elif self.container.hasItemInPool(getPred('Nothing', loc)): itemLocation.Item = self.container.getNextItemInPoolMatching(getPred('Nothing', loc)) elif self.container.hasItemInPool(getPred('NoEnergy', loc)): itemLocation.Item = self.container.getNextItemInPoolMatching(getPred('NoEnergy', loc)) @@ -168,10 +179,13 @@ class RandoSetup(object): self.log.debug("checkDoorBeams. mandatoryBeams="+str(self.restrictions.mandatoryBeams)) def checkPool(self, forbidden=None): + self.errorMsgs = [] self.log.debug("checkPool. forbidden=" + str(forbidden) + ", self.forbiddenItems=" + str(self.forbiddenItems)) if not self.graphSettings.isMinimizer() and not self.settings.isPlandoRando() and len(self.allLocations) > len(self.locations): # invalid graph with looped areas - self.log.debug("checkPool: not all areas are connected, but minimizer param is off / not a plando rando") + msg = "not all areas are connected, but minimizer param is off / not a plando rando" + self.log.debug("checkPool: {}".format(msg)) + self.errorMsgs.append(msg) return False ret = True if forbidden is not None: @@ -185,7 +199,9 @@ class RandoSetup(object): container = ItemLocContainer(self.sm, pool, self.locations) except AssertionError as e: # invalid graph altogether - self.log.debug("checkPool: AssertionError when creating ItemLocContainer: {}".format(e)) + msg = "AssertionError when creating ItemLocContainer: {}".format(e) + self.log.debug("checkPool: {}".format(msg)) + self.errorMsgs.append(msg) return False # restrict item pool in chozo: game should be finishable with chozo items only contPool = [] @@ -210,25 +226,55 @@ class RandoSetup(object): self.lastRestricted = [loc for loc in self.locations if loc not in totalAvailLocs] self.log.debug("restricted=" + str([loc.Name for loc in self.lastRestricted])) - # check if all inter-area APs can reach each other - interAPs = [ap for ap in self.areaGraph.getAccessibleAccessPoints(self.startAP) if not ap.isInternal() and not ap.isLoop()] - for startAp in interAPs: - availAccessPoints = self.areaGraph.getAvailableAccessPoints(startAp, self.sm, self.settings.maxDiff) - for ap in interAPs: - if not ap in availAccessPoints: - self.log.debug("checkPool: ap {} non accessible from {}".format(ap.Name, startAp.Name)) + # check if objectives are compatible with accessible APs + startAP = self.areaGraph.accessPoints[self.startAP] + availAPs = [ap.Name for ap in self.areaGraph.getAvailableAccessPoints(startAP, self.sm, self.settings.maxDiff)] + self.log.debug("availAPs="+str(availAPs)) + for goal in Objectives.objDict[self.graphSettings.player].activeGoals: + n, aps = goal.escapeAccessPoints + if len(aps) == 0: + continue + escAPs = [ap for ap in aps if ap in availAPs] + self.log.debug("escAPs="+str(escAPs)) + if len(escAPs) < n: + msg = "goal '{}' impossible to complete due to area layout".format(goal.name) + self.log.debug("checkPool. {}".format(msg)) + self.errorMsgs.append(msg) + ret = False + continue + for ap in escAPs: + if not self.areaGraph.canAccess(self.sm, ap, "Golden Four", self.settings.maxDiff): + msg = "goal '{}' impossible to complete due to area layout".format(goal.name) + self.log.debug("checkPool. {}".format(msg)) + self.errorMsgs.append(msg) ret = False - if not ret: - self.log.debug("checkPool. inter-area APs check failed") + break + # check if all inter-area APs can reach each other + if ret: + interAPs = [ap for ap in self.areaGraph.getAccessibleAccessPoints(self.startAP) if not ap.isInternal() and not ap.isLoop()] + for startAp in interAPs: + availAccessPoints = self.areaGraph.getAvailableAccessPoints(startAp, self.sm, self.settings.maxDiff) + for ap in interAPs: + if not ap in availAccessPoints: + self.log.debug("checkPool: ap {} non accessible from {}".format(ap.Name, startAp.Name)) + ret = False + if not ret: + msg = "inter-area APs check failed" + self.log.debug("checkPool. {}".format(msg)) + self.errorMsgs.append(msg) # cleanup self.sm.resetItems() self.restoreBossChecks() # check if we can reach/beat all bosses if ret: + # always add G4 to mandatory bosses, even if not required by objectives + mandatoryBosses = set(Objectives.objDict[self.sm.player].getMandatoryBosses() + Bosses.Golden4()) + for loc in self.lastRestricted: if loc.Name in self.bossesLocs: ret = False - self.log.debug("unavail Boss: " + loc.Name) + msg = "unavail Boss: {}".format(loc.Name) + self.log.debug("checkPool. {}".format(msg)) if ret: # revive bosses self.sm.addItems([item.Type for item in contPool if item.Category != 'Boss']) @@ -238,17 +284,24 @@ class RandoSetup(object): and self.areaGraph.canAccess(self.sm, self.startAP, 'DraygonRoomIn', maxDiff) if ret: # see if we can beat bosses with this equipment (infinity as max diff for a "onlyBossesLeft" type check - beatableBosses = sorted([loc.Name for loc in self.services.currentLocations(self.startAP, container, diff=infinity) if loc.isBoss()]) + beatableBosses = sorted([loc.BossItemType for loc in self.services.currentLocations(self.startAP, container, diff=infinity) if loc.isBoss()]) self.log.debug("checkPool. beatableBosses="+str(beatableBosses)) - ret = beatableBosses == Bosses.Golden4() + self.log.debug("checkPool. mandatoryBosses: {}".format(mandatoryBosses)) + ret = mandatoryBosses.issubset(set(beatableBosses)) and Objectives.objDict[self.sm.player].checkLimitObjectives(beatableBosses) if ret: # check that we can then kill mother brain - self.sm.addItems(Bosses.Golden4()) + self.sm.addItems(Bosses.Golden4() + Bosses.miniBosses()) beatableMotherBrain = [loc.Name for loc in self.services.currentLocations(self.startAP, container, diff=infinity) if loc.Name == 'Mother Brain'] ret = len(beatableMotherBrain) > 0 self.log.debug("checkPool. beatable Mother Brain={}".format(ret)) + else: + msg = "can't kill all mandatory bosses/minibosses: {}".format(', '.join(list(mandatoryBosses - set(beatableBosses)))) + self.log.debug("checkPool. {}".format(msg)) + self.errorMsgs.append(msg) else: - self.log.debug('checkPool. locked by Phantoon or Draygon') + msg = "locked by Phantoon or Draygon" + self.log.debug('checkPool. {}'.format(msg)) + self.errorMsgs.append(msg) self.log.debug('checkPool. boss access sanity check: '+str(ret)) if self.restrictions.isChozo() or self.restrictions.isScavenger(): @@ -319,7 +372,6 @@ class RandoSetup(object): else: forb = [] self.forbiddenItems += forb - self.checkPool() self.addRestricted() return len(forb) @@ -344,6 +396,9 @@ class RandoSetup(object): def getForbiddenMovement(self): self.log.debug("getForbiddenMovement BEGIN. forbidden="+str(self.forbiddenItems)) removableMovement = [mvt for mvt in self.movementItems if self.checkPool([mvt])] + if 'Bomb' in removableMovement and not RomPatches.has(self.sm.player, RomPatches.BombTorizoWake) and Objectives.objDict[self.sm.player].isGoalActive("activate chozo robots"): + # in this objective, without VARIA tweaks, BT has to wake so give bombs + removableMovement.remove('Bomb') self.log.debug("getForbiddenMovement removable="+str(removableMovement)) if len(removableMovement) > 0: # remove at least the most important diff --git a/worlds/sm/variaRandomizer/rando/Restrictions.py b/worlds/sm/variaRandomizer/rando/Restrictions.py index 68801231..fabdfea4 100644 --- a/worlds/sm/variaRandomizer/rando/Restrictions.py +++ b/worlds/sm/variaRandomizer/rando/Restrictions.py @@ -14,11 +14,9 @@ class Restrictions(object): self.suitsRestrictions = settings.restrictions['Suits'] self.scavLocs = None self.scavIsVanilla = False - self.scavEscape = False self.restrictionDictChecker = None if self.split == 'Scavenger': self.scavIsVanilla = settings.restrictions['ScavengerParams']['vanillaItems'] - self.scavEscape = settings.restrictions['ScavengerParams']['escape'] # checker function chain used by canPlaceAtLocation self.checkers = self.getCheckers() self.static = {} @@ -84,7 +82,7 @@ class Restrictions(object): self.checkers.append(self.restrictionDictChecker) def isLocMajor(self, loc): - return not loc.isBoss() and (self.split == "Full" or loc.isClass(self.split)) + return (not loc.isBoss() and self.split == "Full") or loc.isClass(self.split) def isLocMinor(self, loc): return not loc.isBoss() and (self.split == "Full" or not loc.isClass(self.split)) @@ -93,7 +91,7 @@ class Restrictions(object): if self.split == "Full": return True elif self.split == 'Scavenger': - return not self.isItemMinor(item) + return not self.isItemMinor(item) or item.Type == "Ridley" else: return item.Class == self.split @@ -135,7 +133,7 @@ class Restrictions(object): def getCheckers(self): checkers = [] self.log.debug("add bosses restriction") - checkers.append(lambda item, loc, cont: (item.Category != 'Boss' and not loc.isBoss()) or (item.Category == 'Boss' and item.Name == loc.Name)) + checkers.append(lambda item, loc, cont: (item.Category not in ['Boss', 'MiniBoss'] and not loc.isBoss()) or (item.Category in ['Boss', 'MiniBoss'] and item.Type == loc.BossItemType)) if self.split != 'Full': if self.split != 'Scavenger': self.log.debug("add majorsSplit restriction") diff --git a/worlds/sm/variaRandomizer/rando/palettes.py b/worlds/sm/variaRandomizer/rando/palettes.py deleted file mode 100644 index 970ddd10..00000000 --- a/worlds/sm/variaRandomizer/rando/palettes.py +++ /dev/null @@ -1,23489 +0,0 @@ -palettes = { -131122: 0, -131123: 16, -131124: 186, -131125: 86, -131126: 178, -131127: 65, -131128: 71, -131129: 20, -131130: 3, -131131: 4, -131132: 21, -131133: 78, -131134: 112, -131135: 53, -131136: 203, -131137: 36, -131138: 104, -131139: 24, -131140: 127, -131141: 111, -131142: 248, -131143: 81, -131144: 14, -131145: 65, -131146: 31, -131147: 3, -131148: 218, -131149: 1, -131150: 245, -131151: 0, -131152: 99, -131153: 12, -131154: 0, -131155: 16, -131156: 219, -131157: 86, -131158: 211, -131159: 57, -131160: 71, -131161: 16, -131162: 3, -131163: 4, -131164: 54, -131165: 70, -131166: 145, -131167: 45, -131168: 236, -131169: 32, -131170: 137, -131171: 20, -131172: 155, -131173: 111, -131174: 21, -131175: 82, -131176: 44, -131177: 61, -131178: 59, -131179: 19, -131180: 246, -131181: 13, -131182: 242, -131183: 12, -131184: 99, -131185: 12, -131186: 0, -131187: 16, -131188: 251, -131189: 82, -131190: 244, -131191: 49, -131192: 103, -131193: 16, -131194: 2, -131195: 4, -131196: 118, -131197: 62, -131198: 178, -131199: 37, -131200: 45, -131201: 25, -131202: 169, -131203: 16, -131204: 150, -131205: 111, -131206: 81, -131207: 82, -131208: 106, -131209: 57, -131210: 86, -131211: 39, -131212: 19, -131213: 26, -131214: 15, -131215: 25, -131216: 99, -131217: 8, -131218: 0, -131219: 16, -131220: 28, -131221: 83, -131222: 21, -131223: 42, -131224: 103, -131225: 12, -131226: 2, -131227: 4, -131228: 151, -131229: 54, -131230: 211, -131231: 29, -131232: 78, -131233: 21, -131234: 202, -131235: 12, -131236: 178, -131237: 111, -131238: 110, -131239: 82, -131240: 136, -131241: 53, -131242: 114, -131243: 55, -131244: 47, -131245: 38, -131246: 12, -131247: 37, -131248: 99, -131249: 8, -131250: 0, -131251: 16, -131252: 92, -131253: 79, -131254: 86, -131255: 30, -131256: 136, -131257: 8, -131258: 1, -131259: 0, -131260: 184, -131261: 46, -131262: 19, -131263: 26, -131264: 111, -131265: 17, -131266: 235, -131267: 12, -131268: 173, -131269: 115, -131270: 170, -131271: 78, -131272: 166, -131273: 53, -131274: 141, -131275: 75, -131276: 75, -131277: 54, -131278: 9, -131279: 53, -131280: 67, -131281: 4, -131282: 0, -131283: 16, -131284: 125, -131285: 79, -131286: 119, -131287: 22, -131288: 136, -131289: 4, -131290: 1, -131291: 0, -131292: 217, -131293: 38, -131294: 52, -131295: 18, -131296: 144, -131297: 13, -131298: 12, -131299: 9, -131300: 201, -131301: 115, -131302: 199, -131303: 78, -131304: 196, -131305: 49, -131306: 169, -131307: 91, -131308: 103, -131309: 66, -131310: 6, -131311: 65, -131312: 67, -131313: 4, -131314: 0, -131315: 16, -131316: 157, -131317: 75, -131318: 152, -131319: 14, -131320: 168, -131321: 4, -131322: 0, -131323: 0, -131324: 25, -131325: 31, -131326: 85, -131327: 10, -131328: 209, -131329: 5, -131330: 44, -131331: 5, -131332: 196, -131333: 115, -131334: 3, -131335: 79, -131336: 2, -131337: 46, -131338: 196, -131339: 111, -131340: 132, -131341: 78, -131342: 35, -131343: 77, -131344: 67, -131345: 0, -131346: 0, -131347: 0, -131348: 190, -131349: 75, -131350: 185, -131351: 6, -131352: 168, -131353: 0, -131354: 0, -131355: 0, -131356: 58, -131357: 23, -131358: 118, -131359: 2, -131360: 242, -131361: 1, -131362: 77, -131363: 1, -131364: 224, -131365: 115, -131366: 32, -131367: 79, -131368: 32, -131369: 42, -131370: 224, -131371: 127, -131372: 160, -131373: 90, -131374: 32, -131375: 89, -131376: 67, -131377: 0, -131378: 0, -131379: 16, -131380: 21, -131381: 66, -131382: 13, -131383: 45, -131384: 2, -131385: 0, -131386: 0, -131387: 0, -131388: 112, -131389: 57, -131390: 203, -131391: 32, -131392: 38, -131393: 12, -131394: 3, -131395: 4, -131396: 58, -131397: 70, -131398: 179, -131399: 40, -131400: 9, -131401: 24, -131402: 127, -131403: 111, -131404: 253, -131405: 81, -131406: 19, -131407: 65, -131408: 99, -131409: 12, -131410: 0, -131411: 16, -131412: 54, -131413: 66, -131414: 46, -131415: 37, -131416: 2, -131417: 0, -131418: 0, -131419: 0, -131420: 145, -131421: 49, -131422: 236, -131423: 28, -131424: 71, -131425: 12, -131426: 36, -131427: 4, -131428: 86, -131429: 70, -131430: 208, -131431: 40, -131432: 40, -131433: 20, -131434: 123, -131435: 111, -131436: 249, -131437: 81, -131438: 240, -131439: 64, -131440: 99, -131441: 12, -131442: 0, -131443: 16, -131444: 86, -131445: 62, -131446: 79, -131447: 33, -131448: 2, -131449: 0, -131450: 0, -131451: 0, -131452: 209, -131453: 41, -131454: 13, -131455: 25, -131456: 136, -131457: 8, -131458: 36, -131459: 4, -131460: 147, -131461: 70, -131462: 14, -131463: 41, -131464: 70, -131465: 16, -131466: 118, -131467: 111, -131468: 245, -131469: 77, -131470: 238, -131471: 64, -131472: 66, -131473: 8, -131474: 0, -131475: 16, -131476: 119, -131477: 62, -131478: 112, -131479: 25, -131480: 2, -131481: 0, -131482: 0, -131483: 0, -131484: 242, -131485: 33, -131486: 46, -131487: 21, -131488: 169, -131489: 8, -131490: 69, -131491: 4, -131492: 175, -131493: 70, -131494: 43, -131495: 41, -131496: 101, -131497: 12, -131498: 114, -131499: 111, -131500: 241, -131501: 77, -131502: 203, -131503: 64, -131504: 66, -131505: 8, -131506: 0, -131507: 16, -131508: 183, -131509: 58, -131510: 177, -131511: 21, -131512: 3, -131513: 0, -131514: 0, -131515: 0, -131516: 19, -131517: 26, -131518: 110, -131519: 13, -131520: 202, -131521: 4, -131522: 102, -131523: 0, -131524: 203, -131525: 74, -131526: 104, -131527: 37, -131528: 132, -131529: 12, -131530: 77, -131531: 107, -131532: 12, -131533: 74, -131534: 200, -131535: 68, -131536: 33, -131537: 4, -131538: 0, -131539: 16, -131540: 216, -131541: 58, -131542: 210, -131543: 13, -131544: 3, -131545: 0, -131546: 0, -131547: 0, -131548: 52, -131549: 18, -131550: 143, -131551: 9, -131552: 235, -131553: 4, -131554: 135, -131555: 0, -131556: 231, -131557: 74, -131558: 133, -131559: 37, -131560: 163, -131561: 8, -131562: 73, -131563: 107, -131564: 8, -131565: 74, -131566: 165, -131567: 68, -131568: 33, -131569: 4, -131570: 0, -131571: 16, -131572: 248, -131573: 54, -131574: 243, -131575: 9, -131576: 3, -131577: 0, -131578: 0, -131579: 0, -131580: 116, -131581: 10, -131582: 176, -131583: 5, -131584: 44, -131585: 1, -131586: 135, -131587: 0, -131588: 36, -131589: 75, -131590: 195, -131591: 37, -131592: 193, -131593: 4, -131594: 68, -131595: 107, -131596: 4, -131597: 70, -131598: 163, -131599: 68, -131600: 0, -131601: 0, -131602: 0, -131603: 16, -131604: 25, -131605: 55, -131606: 20, -131607: 2, -131608: 3, -131609: 0, -131610: 0, -131611: 0, -131612: 149, -131613: 2, -131614: 209, -131615: 1, -131616: 77, -131617: 1, -131618: 168, -131619: 0, -131620: 64, -131621: 75, -131622: 224, -131623: 37, -131624: 224, -131625: 0, -131626: 64, -131627: 107, -131628: 0, -131629: 70, -131630: 128, -131631: 68, -131632: 0, -131633: 0, -1312391: 0, -1312392: 56, -1312393: 255, -1312394: 87, -1312395: 247, -1312396: 66, -1312397: 41, -1312398: 9, -1312399: 165, -1312400: 0, -1312401: 90, -1312402: 79, -1312403: 181, -1312404: 54, -1312405: 16, -1312406: 38, -1312407: 140, -1312408: 21, -1312409: 255, -1312410: 3, -1312411: 185, -1312412: 2, -1312413: 112, -1312414: 1, -1312415: 105, -1312416: 0, -1312417: 177, -1312418: 11, -1312419: 169, -1312420: 30, -1312421: 69, -1312422: 1, -890482: 251, -1314700: 0, -1314701: 56, -1314702: 178, -1314703: 114, -1314704: 199, -1314705: 113, -1314706: 97, -1314707: 36, -1314708: 64, -1314709: 24, -1314710: 142, -1314711: 122, -1314712: 11, -1314713: 102, -1314714: 3, -1314715: 77, -1314716: 0, -1314717: 73, -1314718: 224, -1314719: 127, -1314720: 128, -1314721: 126, -1314722: 224, -1314723: 68, -1314724: 32, -1314725: 44, -1314726: 0, -1314727: 0, -1314728: 0, -1314729: 0, -1314730: 0, -1314731: 0, -1315705: 0, -1315706: 56, -1315707: 156, -1315708: 75, -1315709: 148, -1315710: 54, -1315711: 41, -1315712: 9, -1315713: 66, -1315714: 0, -1315715: 24, -1315716: 59, -1315717: 82, -1315718: 42, -1315719: 173, -1315720: 25, -1315721: 107, -1315722: 17, -1315723: 90, -1315724: 127, -1315725: 192, -1315726: 126, -1315727: 224, -1315728: 109, -1315729: 224, -1315730: 84, -1315731: 29, -1315732: 0, -1315733: 20, -1315734: 0, -1315735: 10, -1315736: 0, -1316253: 0, -1316254: 56, -1316255: 156, -1316256: 75, -1316257: 148, -1316258: 54, -1316259: 41, -1316260: 9, -1316261: 66, -1316262: 0, -1316263: 24, -1316264: 59, -1316265: 82, -1316266: 42, -1316267: 173, -1316268: 25, -1316269: 107, -1316270: 17, -1316271: 90, -1316272: 127, -1316273: 192, -1316274: 126, -1316275: 224, -1316276: 109, -1316277: 224, -1316278: 84, -1316279: 29, -1316280: 0, -1316281: 20, -1316282: 0, -1316283: 10, -1316284: 0, -454107: 96, -1317292: 0, -1317293: 56, -1317294: 255, -1317295: 87, -1317296: 247, -1317297: 66, -1317298: 41, -1317299: 9, -1317300: 165, -1317301: 0, -1317302: 90, -1317303: 79, -1317304: 181, -1317305: 54, -1317306: 16, -1317307: 38, -1317308: 206, -1317309: 29, -1317310: 223, -1317311: 1, -1317312: 31, -1317313: 0, -1317314: 24, -1317315: 0, -1317316: 10, -1317317: 0, -1317318: 185, -1317319: 6, -1317320: 234, -1317321: 0, -1317322: 69, -1317323: 0, -454147: 160, -454148: 76, -454149: 0, -1500565: 12, -1318735: 0, -1318736: 56, -1318737: 255, -1318738: 87, -1318739: 247, -1318740: 66, -1318741: 41, -1318742: 9, -1318743: 165, -1318744: 0, -1318745: 90, -1318746: 79, -1318747: 181, -1318748: 54, -1318749: 16, -1318750: 38, -1318751: 206, -1318752: 29, -1318753: 0, -1318754: 0, -1318755: 0, -1318756: 0, -1318757: 0, -1318758: 0, -1318759: 0, -1318760: 0, -1318761: 0, -1318762: 0, -1318763: 0, -1318764: 0, -1318765: 0, -1318766: 0, -1500568: 101, -1640071: 0, -1640072: 56, -1115785: 190, -1115786: 75, -1115787: 185, -1115788: 6, -1115789: 234, -1115790: 0, -1115791: 101, -1115792: 0, -1115793: 58, -1115794: 23, -1115795: 118, -1115796: 2, -1115797: 242, -1115798: 1, -1115799: 77, -1115800: 1, -1115801: 0, -1115802: 0, -1115803: 0, -1115804: 0, -1115805: 0, -1115806: 0, -1640095: 134, -1115808: 0, -1115809: 0, -1115810: 0, -1640099: 22, -1115812: 0, -1640101: 19, -1640102: 1, -1377991: 0, -1377992: 56, -1377993: 159, -1377994: 103, -1377995: 153, -1377996: 82, -1377997: 46, -1377998: 37, -1377999: 170, -1640144: 12, -1378001: 252, -1378002: 94, -1640147: 93, -1378004: 70, -1378005: 178, -1378006: 53, -1378007: 112, -1378008: 45, -1640153: 187, -1378010: 91, -1378011: 248, -1378012: 61, -1378013: 14, -1378014: 45, -1640159: 134, -1640160: 20, -1640161: 59, -1378018: 94, -1640163: 22, -1640164: 2, -1640165: 19, -1640166: 1, -1640167: 0, -1640168: 56, -1640169: 253, -1640170: 2, -1640171: 62, -1640172: 1, -1640173: 108, -1640174: 0, -1640175: 102, -1640176: 0, -1640177: 30, -1640178: 2, -1640179: 95, -1640180: 0, -1640181: 89, -1640182: 0, -1640183: 115, -1640184: 0, -1640185: 187, -1640186: 94, -1378043: 179, -1640188: 61, -1640189: 46, -1640190: 41, -1640191: 134, -1640192: 20, -1640193: 59, -1640194: 3, -1640195: 22, -1640196: 2, -1640197: 19, -1640198: 1, -1640199: 0, -1640200: 56, -1640201: 255, -1640202: 107, -1640203: 214, -1640204: 78, -1640205: 164, -1640206: 20, -1640207: 32, -1640208: 4, -1640209: 123, -1640210: 91, -1640211: 82, -1640212: 62, -1640213: 205, -1640214: 49, -1640215: 73, -1640216: 33, -1640217: 187, -1640218: 94, -1640219: 179, -1640220: 61, -1640221: 46, -1640222: 41, -1640223: 134, -1640224: 20, -1640225: 59, -1640226: 3, -1640227: 22, -1640228: 2, -1640229: 19, -1640230: 1, -1640231: 0, -1640232: 56, -1640233: 190, -1640234: 75, -1321726: 0, -1321727: 56, -1321728: 255, -1321729: 87, -1321730: 247, -1640235: 185, -1321732: 41, -1321733: 9, -1321734: 165, -1321735: 0, -1321736: 90, -1640236: 6, -1321738: 181, -1321739: 54, -1321740: 16, -1321741: 38, -1321742: 206, -1640237: 234, -1321744: 223, -1321745: 1, -1321746: 31, -1321747: 0, -1321748: 24, -1321749: 0, -1321750: 10, -1321751: 0, -1321752: 185, -1321753: 6, -1321754: 234, -1640239: 101, -1321756: 69, -1321757: 0, -1640240: 0, -1640241: 58, -1640242: 23, -1640243: 118, -1640244: 2, -1640245: 242, -1640246: 1, -1640247: 77, -1640248: 1, -1640249: 187, -1640250: 94, -1640251: 179, -1640252: 61, -1640253: 46, -1640254: 41, -1640255: 134, -1640256: 20, -1640257: 59, -1640258: 3, -1640259: 22, -1640260: 2, -1640261: 19, -1640262: 1, -1152620: 0, -1152621: 224, -1152622: 127, -1152623: 160, -1152624: 125, -1152625: 224, -1152627: 160, -1152628: 48, -1152629: 224, -1152630: 59, -1152631: 128, -1152632: 38, -1152633: 128, -1152634: 21, -454365: 23, -1324638: 0, -1324639: 56, -1324640: 255, -1324641: 87, -1324642: 247, -1324643: 66, -1324644: 140, -1324645: 21, -1324646: 165, -1324647: 0, -1324648: 90, -1324649: 79, -1324650: 181, -1324651: 54, -1324652: 16, -1324653: 38, -1324654: 206, -1324655: 29, -1324656: 223, -1324657: 28, -1324658: 224, -1324659: 79, -1324660: 32, -1324661: 59, -1324662: 32, -1324663: 42, -1324664: 151, -1324665: 16, -1324666: 223, -1324667: 107, -1324668: 46, -1324669: 4, -890832: 121, -890833: 103, -890835: 46, -890836: 123, -1194109: 0, -1194110: 56, -1194111: 255, -1194112: 127, -1194113: 255, -1194114: 13, -1194115: 191, -1194116: 8, -1194117: 149, -1194118: 8, -1194119: 108, -1194120: 8, -1194121: 71, -1194122: 4, -1194123: 126, -1194124: 107, -1194125: 30, -1194126: 87, -1194127: 88, -1194128: 58, -1194129: 113, -1194130: 33, -1194131: 203, -1194132: 12, -1194133: 159, -1194134: 3, -1194135: 58, -1194136: 2, -1194137: 118, -1194138: 1, -1194139: 0, -1194140: 0, -1194141: 0, -1194142: 0, -1194143: 255, -1194144: 127, -1194145: 255, -1194146: 13, -1194147: 191, -1194148: 8, -1194149: 149, -1194150: 8, -1194151: 108, -1194152: 8, -1194153: 71, -1194154: 4, -1194155: 126, -1194156: 107, -1194157: 30, -1194158: 87, -1194159: 88, -1194160: 58, -1194161: 113, -1194162: 33, -1194163: 203, -1194164: 12, -1194165: 159, -1194166: 3, -1194167: 58, -1194168: 2, -1194169: 118, -1194170: 1, -1194171: 0, -1194172: 0, -1194187: 123, -1194188: 74, -1194189: 144, -1194190: 28, -1194191: 105, -1194192: 20, -1194193: 36, -1194194: 20, -1194195: 8, -1194196: 0, -1194197: 191, -1194198: 36, -1194199: 149, -1194200: 36, -1194201: 108, -1194202: 28, -1194203: 69, -1194204: 16, -1194237: 0, -1194238: 56, -1194239: 255, -1194240: 127, -1194241: 126, -1194242: 107, -1194243: 30, -1194244: 87, -1194245: 88, -1194246: 58, -1194247: 113, -1194248: 33, -1194249: 203, -1194250: 12, -1194251: 126, -1194252: 107, -1194253: 30, -1194254: 87, -1194255: 88, -1194256: 58, -1194257: 113, -1194258: 33, -1194259: 203, -1194260: 12, -1194261: 159, -1194262: 3, -1194263: 58, -1194264: 2, -1194265: 118, -1194266: 1, -1194267: 0, -1194268: 0, -890884: 31, -890886: 5, -890891: 33, -890892: 159, -890893: 87, -890894: 210, -890895: 74, -890897: 58, -890899: 0, -890900: 20, -890902: 170, -890903: 48, -890906: 4, -1327427: 0, -1327428: 56, -1327429: 255, -1327430: 87, -1327431: 247, -1327432: 66, -1327433: 41, -1327434: 9, -1327435: 165, -1327436: 0, -1327437: 90, -1327438: 79, -1327439: 181, -1327440: 54, -1327441: 16, -1327442: 38, -1327443: 206, -1327444: 29, -1327445: 255, -1327446: 2, -1327447: 191, -1327448: 1, -1327449: 15, -1327450: 0, -1327451: 8, -1327452: 0, -1327453: 255, -1327454: 3, -1327455: 55, -1327456: 2, -1327457: 209, -1327458: 0, -1291699: 0, -1291700: 56, -1291701: 157, -1291702: 85, -1291703: 22, -1291704: 24, -1291705: 13, -1291706: 16, -1291707: 29, -1291708: 51, -1291709: 183, -1291710: 42, -1291711: 145, -1291712: 42, -1291713: 12, -1291714: 30, -1291715: 170, -1291716: 25, -1291717: 72, -1160646: 36, -1291719: 229, -1291720: 12, -1291721: 132, -1160650: 20, -1160651: 71, -1291724: 0, -1160653: 224, -1160654: 3, -1160655: 160, -1160656: 2, -1291729: 0, -1160658: 1, -541665: 0, -541666: 56, -541667: 255, -541668: 127, -541669: 255, -541670: 25, -541671: 85, -541672: 29, -541673: 173, -541674: 16, -541675: 255, -541676: 83, -541677: 158, -541678: 3, -541679: 95, -541680: 41, -541681: 223, -541682: 24, -541683: 0, -541684: 0, -541685: 0, -541686: 0, -541687: 0, -541688: 0, -541689: 0, -541690: 0, -541691: 0, -541692: 0, -541693: 0, -541694: 0, -541695: 74, -541696: 16, -541697: 0, -541698: 56, -541699: 255, -541700: 127, -541701: 192, -541702: 126, -541703: 224, -541704: 109, -541705: 224, -541706: 84, -541707: 110, -541708: 127, -541709: 10, -541710: 115, -541711: 101, -541712: 102, -541713: 34, -541714: 94, -541715: 160, -541716: 127, -541717: 96, -541718: 123, -541719: 32, -541720: 119, -541721: 160, -541722: 114, -541723: 96, -541724: 110, -541725: 145, -541726: 127, -541727: 192, -541728: 32, -541729: 0, -541730: 56, -541731: 255, -541732: 127, -541733: 31, -541734: 124, -541735: 22, -541736: 88, -541737: 12, -541738: 48, -541739: 223, -541740: 126, -541741: 223, -541742: 125, -541743: 223, -541744: 124, -541745: 26, -541746: 104, -541747: 0, -541748: 0, -541749: 0, -541750: 0, -541751: 0, -541752: 0, -541753: 0, -541754: 0, -541755: 0, -541756: 0, -541757: 0, -541758: 0, -541759: 9, -541760: 36, -541761: 0, -541762: 56, -541763: 255, -541764: 127, -541765: 224, -541766: 59, -541767: 128, -541768: 38, -541769: 128, -541770: 21, -541771: 250, -541772: 107, -541773: 242, -541774: 75, -541775: 234, -541776: 43, -541777: 224, -541778: 3, -541779: 0, -541780: 0, -541781: 0, -541782: 0, -541783: 0, -541784: 0, -541785: 0, -541786: 0, -541787: 0, -541788: 0, -541789: 0, -541790: 0, -541791: 32, -541792: 9, -541793: 0, -541794: 56, -541795: 255, -541796: 127, -541797: 255, -541798: 3, -541799: 22, -541800: 2, -541801: 238, -541802: 0, -541803: 255, -541804: 107, -541805: 255, -541806: 75, -541807: 255, -541808: 43, -541809: 123, -541810: 3, -541811: 0, -541812: 0, -541813: 0, -541814: 0, -541815: 0, -541816: 0, -541817: 0, -541818: 0, -541819: 0, -541820: 0, -541821: 0, -541822: 0, -541823: 173, -541824: 0, -1328819: 0, -1328820: 56, -1328821: 255, -1328822: 87, -1328823: 247, -1328824: 66, -1328825: 41, -1328826: 9, -1328827: 165, -1328828: 0, -1328829: 90, -1328830: 79, -1328831: 181, -1328832: 54, -1328833: 16, -1328834: 38, -1328835: 206, -1328836: 29, -1328837: 31, -1328838: 0, -1328839: 24, -1328840: 0, -1328841: 15, -1328842: 0, -1328843: 8, -1328844: 0, -1328845: 10, -1328846: 0, -1328847: 255, -1328848: 3, -1328849: 181, -1328850: 2, -1500638: 66, -454551: 2, -454552: 8, -454555: 0, -454556: 0, -454557: 0, -454558: 0, -454559: 0, -454560: 0, -454565: 19, -454566: 60, -454567: 11, -454568: 24, -454570: 20, -454571: 3, -454572: 12, -454573: 1, -454574: 4, -454577: 0, -454579: 0, -454580: 0, -454591: 4, -454592: 16, -454593: 2, -454594: 8, -454595: 0, -454596: 0, -1270464: 176, -1270465: 0, -1270466: 54, -1270467: 2, -1270468: 83, -454597: 0, -1270469: 1, -1270470: 175, -1270471: 0, -1270472: 20, -1270473: 2, -454598: 0, -1270474: 49, -1270475: 1, -1270476: 142, -1270477: 0, -1270478: 210, -454599: 0, -1270479: 1, -1270480: 15, -1270481: 1, -1270482: 140, -1270483: 0, -454600: 0, -1270484: 144, -1270485: 1, -1270486: 237, -1270487: 0, -1270488: 107, -1270489: 0, -1270490: 110, -1270491: 1, -1270492: 204, -1270493: 0, -1270494: 105, -1270495: 0, -454605: 21, -454606: 68, -454607: 13, -454608: 32, -454609: 7, -454610: 28, -454611: 5, -454612: 20, -454613: 3, -454614: 12, -454615: 1, -454616: 4, -454617: 0, -1270569: 4, -454618: 0, -1270749: 20, -1333281: 0, -1333282: 56, -1333283: 87, -1333284: 63, -1333285: 77, -1333286: 46, -1333287: 226, -1333288: 0, -1333289: 96, -1333290: 0, -1333291: 176, -1333292: 58, -1333293: 11, -1333294: 34, -1333295: 102, -1333296: 17, -1333297: 36, -1333298: 9, -1333299: 90, -1333300: 67, -1333301: 148, -1333302: 54, -1333303: 173, -1333304: 21, -1333305: 8, -1333306: 5, -1333307: 255, -1333308: 3, -1333309: 55, -1333310: 2, -1333311: 209, -1333312: 0, -454670: 0, -454671: 17, -454672: 0, -1270871: 65, -1270872: 71, -1270873: 20, -1270874: 3, -1270875: 4, -1270876: 21, -1270877: 78, -1270878: 112, -1270879: 53, -1270880: 203, -1270881: 36, -1270882: 104, -1270883: 24, -1270884: 95, -1270885: 94, -1270886: 63, -1270887: 24, -1270888: 20, -1270889: 16, -1270890: 122, -1270891: 78, -1270892: 115, -1270893: 61, -1270894: 73, -1270895: 20, -1270896: 5, -1270897: 4, -1270898: 214, -1270899: 69, -1270900: 81, -1270901: 49, -1270902: 173, -1334215: 0, -1334216: 56, -1334217: 255, -1334218: 2, -1334219: 191, -1334220: 1, -1334221: 15, -1334222: 0, -1334223: 8, -1334224: 0, -1334225: 191, -1334226: 1, -1334227: 27, -1334228: 1, -1334229: 186, -1334230: 0, -1334231: 17, -1334232: 0, -1334233: 92, -1334234: 90, -1334235: 180, -1334236: 65, -1334237: 13, -1334238: 41, -1334239: 101, -1334240: 16, -1334241: 255, -1334242: 3, -1334243: 55, -1334244: 2, -1334245: 209, -1334246: 0, -1270971: 5, -1153049: 8, -1140109: 92, -1140115: 101, -1335856: 0, -1335857: 56, -1335858: 255, -1335859: 127, -1335860: 224, -1335861: 86, -1335862: 128, -1335863: 49, -1335864: 192, -1335865: 24, -1335866: 192, -1335867: 107, -1335868: 192, -1335869: 94, -1335870: 32, -1335871: 74, -1335872: 160, -1335873: 53, -1335874: 255, -1335875: 127, -1335876: 156, -1335877: 3, -1335878: 55, -1335879: 2, -1335880: 209, -1335881: 0, -1335882: 255, -1335883: 3, -1335884: 55, -1335885: 2, -1335886: 209, -1335887: 0, -1336711: 0, -1336712: 56, -1336713: 255, -1336714: 127, -1336715: 224, -1336716: 59, -1336717: 128, -1336718: 38, -1336719: 128, -1336720: 21, -1336721: 250, -1336722: 107, -1336723: 242, -1336724: 75, -1336725: 234, -1336726: 43, -1336727: 224, -1336728: 3, -1336729: 0, -1336730: 0, -1336731: 0, -1336732: 0, -1336733: 0, -1336734: 0, -1336735: 0, -1336736: 0, -1336737: 0, -1336738: 0, -1336739: 0, -1336740: 0, -1336741: 0, -1336742: 0, -1337260: 0, -1337261: 56, -1337262: 178, -1337263: 114, -1337264: 199, -1337265: 113, -1337266: 97, -1337267: 36, -1337268: 64, -1337269: 24, -1337270: 142, -1337271: 122, -1337272: 11, -1337273: 102, -1337274: 3, -1337275: 77, -1337276: 164, -1337277: 48, -1337278: 164, -1337279: 48, -1337280: 97, -1337281: 36, -1337282: 64, -1337283: 24, -1337284: 0, -1337285: 8, -1337286: 0, -1337287: 0, -1337288: 0, -1337289: 0, -1337290: 0, -1337291: 0, -1337754: 0, -1337755: 56, -1337756: 87, -1337757: 75, -1337758: 77, -1337759: 58, -1337760: 226, -1337761: 12, -1337762: 64, -1337763: 0, -1337764: 176, -1337765: 70, -1337766: 11, -1337767: 46, -1337768: 102, -1337769: 29, -1337770: 36, -1337771: 21, -1337772: 255, -1337773: 72, -1337774: 182, -1337775: 56, -1337776: 110, -1337777: 36, -1337778: 72, -1337779: 20, -1337780: 255, -1337781: 3, -1337782: 55, -1337783: 2, -1337784: 209, -1337785: 0, -1337786: 0, -1337787: 56, -1337788: 255, -1337789: 87, -1337790: 247, -1337791: 66, -1337792: 140, -1337793: 21, -1337794: 165, -1337795: 0, -1337796: 90, -1337797: 79, -1337798: 181, -1337799: 54, -1337800: 16, -1337801: 38, -1337802: 206, -1337803: 29, -1337804: 224, -1337805: 3, -1337806: 1, -1337807: 3, -1337808: 161, -1337809: 1, -1337810: 193, -1337811: 0, -1337812: 250, -1337813: 107, -1337814: 176, -1337815: 66, -1337816: 69, -1337817: 21, -1337818: 0, -1337819: 56, -1337820: 223, -1337821: 90, -1337822: 117, -1337823: 57, -1337824: 10, -1337825: 12, -1337826: 6, -1337827: 0, -1337828: 26, -1337829: 78, -1337830: 51, -1337831: 45, -1337832: 142, -1337833: 28, -1337834: 43, -1337835: 16, -1337836: 17, -1337837: 111, -1337838: 42, -1337839: 82, -1337840: 36, -1337841: 49, -1337842: 36, -1337843: 24, -1337844: 255, -1337845: 2, -1337846: 191, -1337847: 1, -1337848: 15, -1337849: 0, -1127019: 40, -1127021: 24, -1127022: 16, -1127023: 98, -1127024: 107, -1127025: 73, -1127026: 198, -1127027: 56, -1127028: 99, -1127029: 44, -1127030: 90, -1127031: 47, -1127032: 148, -1127033: 34, -1127034: 173, -1127035: 1, -1127036: 8, -1127037: 1, -1127038: 255, -1127039: 127, -1127040: 181, -1127041: 86, -1127042: 74, -1127043: 41, -1141135: 65, -1127100: 0, -1127101: 56, -1127102: 255, -1127103: 2, -1127104: 191, -1127105: 1, -1127106: 15, -1127107: 0, -1127108: 8, -1127109: 0, -1127110: 191, -1127111: 1, -1127112: 27, -1127113: 1, -1127114: 21, -1127115: 0, -1127117: 0, -1127118: 31, -1127119: 36, -1127120: 23, -1127121: 28, -1127122: 47, -1127123: 20, -1127124: 71, -1127125: 12, -1127126: 224, -1127127: 3, -1127128: 160, -1127129: 2, -1127130: 64, -1127131: 1, -1142227: 181, -1348722: 0, -1348723: 56, -1348724: 159, -1348725: 38, -1348726: 89, -1348727: 1, -1348728: 76, -1348729: 0, -1348730: 4, -1348731: 0, -1348732: 57, -1348733: 87, -1348734: 115, -1348735: 66, -1348736: 173, -1348737: 45, -1348738: 198, -1348739: 20, -1348740: 127, -1348741: 54, -1348742: 249, -1348743: 41, -1348744: 115, -1348745: 33, -1348746: 12, -1348747: 21, -1348748: 134, -1348749: 12, -1348750: 255, -1348751: 127, -1348752: 0, -1348753: 0, -1348754: 0, -1348755: 56, -1348756: 0, -1348757: 0, -1348758: 0, -1348759: 0, -1348760: 0, -1348761: 0, -1348762: 36, -1348763: 0, -1348764: 173, -1348765: 41, -1348766: 74, -1348767: 33, -1348768: 231, -1348769: 20, -1348770: 99, -1348771: 12, -1348772: 0, -1348773: 0, -1348774: 0, -1348775: 0, -1348776: 0, -1348777: 0, -1348778: 0, -1348779: 0, -1348780: 0, -1348781: 0, -1348782: 173, -1348783: 41, -1348784: 0, -1348785: 0, -1348786: 0, -1348787: 56, -1348788: 224, -1348789: 127, -1348790: 32, -1348791: 107, -1348792: 64, -1348793: 86, -1348794: 255, -1348795: 3, -1348796: 191, -1348797: 2, -1348798: 95, -1348799: 1, -1348800: 31, -1348801: 0, -1348802: 249, -1348803: 41, -1348804: 115, -1348805: 33, -1348806: 12, -1348807: 21, -1348808: 24, -1348809: 99, -1348810: 49, -1348811: 70, -1348812: 74, -1348813: 41, -1348814: 255, -1348815: 127, -1348816: 99, -1348817: 12, -1348818: 0, -1348819: 56, -1348820: 184, -1348821: 87, -1348822: 17, -1348823: 11, -1348824: 70, -1348825: 22, -1348826: 227, -1348827: 0, -1348828: 255, -1348829: 114, -1348830: 223, -1348831: 44, -1348832: 185, -1348833: 36, -1348834: 175, -1348835: 28, -1348836: 169, -1348837: 24, -1348838: 159, -1348839: 79, -1348840: 216, -1348841: 62, -1348842: 18, -1348843: 46, -1348844: 205, -1348845: 8, -1348846: 255, -1348847: 127, -1348848: 0, -1348849: 0, -1348850: 0, -1348851: 56, -1348852: 24, -1348853: 99, -1348854: 24, -1348855: 99, -1348856: 2, -1348857: 8, -1348858: 148, -1348859: 82, -1348860: 206, -1348861: 57, -1348862: 8, -1348863: 33, -1348864: 132, -1348865: 16, -1348866: 25, -1348867: 0, -1348868: 18, -1348869: 0, -1348870: 0, -1348871: 92, -1348872: 0, -1348873: 64, -1348874: 132, -1348875: 16, -1348876: 127, -1348877: 25, -1348878: 255, -1348879: 127, -1348880: 0, -1348881: 0, -1348882: 0, -1348883: 56, -1348884: 148, -1348885: 82, -1348886: 206, -1348887: 57, -1348888: 8, -1348889: 33, -1348890: 139, -1348891: 127, -1348892: 10, -1348893: 111, -1348894: 136, -1348895: 94, -1348896: 7, -1348897: 78, -1348898: 134, -1348899: 57, -1348900: 5, -1348901: 41, -1348902: 131, -1348903: 24, -1348904: 2, -1348905: 8, -1348906: 132, -1348907: 16, -1348908: 24, -1348909: 99, -1348910: 255, -1348911: 127, -1348912: 0, -1348913: 0, -1218223: 25, -1218224: 3, -1218225: 84, -1218226: 2, -1218227: 143, -1218228: 1, -1218229: 202, -1218230: 0, -1218231: 186, -1218232: 2, -1218233: 244, -1218234: 1, -1218235: 79, -1218236: 1, -1218237: 170, -1218238: 0, -1218239: 59, -1218240: 2, -1218241: 181, -1218242: 1, -1218243: 47, -1218244: 1, -1218245: 137, -1218246: 0, -1218247: 220, -1218248: 1, -1218249: 85, -1218250: 1, -1218251: 239, -1218252: 0, -1218253: 105, -1218254: 0, -1218255: 92, -1218256: 1, -1218257: 22, -1218258: 1, -1218259: 176, -1218260: 0, -1218261: 105, -1218262: 0, -1218263: 253, -1218264: 0, -1218265: 182, -1218266: 0, -1218267: 112, -1218268: 0, -1218269: 73, -1218270: 0, -1218271: 126, -1218272: 0, -1218273: 119, -1218274: 0, -1218275: 80, -1218276: 0, -1218277: 40, -1218278: 0, -1218279: 31, -1218280: 0, -1218281: 23, -1218282: 0, -1218283: 16, -1218284: 0, -1218285: 8, -1218286: 0, -1502684: 57, -1502685: 87, -1677266: 20, -1502686: 115, -1677315: 107, -1677317: 158, -1677328: 24, -1677330: 24, -1677333: 47, -1677336: 71, -1221111: 0, -1221112: 56, -1221113: 87, -1221114: 63, -1221115: 77, -1221116: 46, -1221117: 226, -1221118: 0, -1221119: 96, -1221120: 0, -1221121: 176, -1221122: 58, -1221123: 11, -1221124: 34, -1221125: 102, -1221126: 17, -1221127: 36, -1221128: 9, -1221129: 25, -1221130: 3, -1221131: 84, -1221132: 2, -1221133: 143, -1221134: 1, -1221135: 202, -1221136: 0, -1221137: 27, -1221138: 88, -1221139: 146, -1221140: 24, -1221141: 69, -1221142: 1, -1221143: 0, -1221144: 56, -1221145: 87, -1221146: 63, -1221147: 77, -1221148: 46, -1221149: 226, -1221150: 0, -1221151: 96, -1221152: 0, -1221153: 176, -1221154: 58, -1221155: 11, -1221156: 34, -1221157: 102, -1221158: 17, -1221159: 36, -1221160: 9, -1221161: 25, -1221162: 3, -1221163: 84, -1221164: 2, -1221165: 143, -1221166: 1, -1221167: 202, -1221168: 0, -1221169: 27, -1221170: 88, -1221171: 146, -1221172: 24, -1221173: 69, -1221174: 1, -1221175: 0, -1221176: 56, -1221177: 90, -1221178: 107, -1221179: 82, -1221180: 86, -1221181: 231, -1221182: 40, -1221183: 99, -1221184: 24, -1221185: 181, -1221186: 98, -1221187: 16, -1221188: 74, -1221189: 107, -1221190: 57, -1221191: 41, -1221192: 49, -1221193: 255, -1221194: 67, -1221195: 19, -1221196: 1, -1221197: 15, -1221198: 0, -1221199: 92, -1221200: 23, -1221201: 153, -1221202: 2, -1221203: 214, -1221204: 1, -1221205: 224, -1221206: 3, -1221207: 0, -1221208: 56, -1221209: 156, -1221210: 75, -1221211: 148, -1221212: 54, -1221213: 41, -1221214: 9, -1221215: 66, -1221216: 0, -1221217: 247, -1221218: 66, -1221219: 82, -1221220: 42, -1221221: 173, -1221222: 25, -1221223: 107, -1221224: 17, -1221225: 32, -1221226: 20, -1221227: 32, -1221228: 20, -1221229: 32, -1221230: 20, -1221231: 32, -1221232: 20, -1221233: 32, -1221234: 20, -1221235: 32, -1221236: 20, -1221237: 32, -1221238: 20, -1221239: 0, -1221240: 56, -1221241: 87, -1221242: 63, -1221243: 77, -1221244: 46, -1221245: 226, -1221246: 0, -1221247: 96, -1221248: 0, -1221249: 176, -1221250: 58, -1221251: 11, -1221252: 34, -1221253: 102, -1221254: 17, -1221255: 36, -1221256: 9, -1221257: 25, -1221258: 3, -1221259: 84, -1221260: 2, -1221261: 143, -1221262: 1, -1221263: 202, -1221264: 0, -1221265: 27, -1221266: 88, -1221267: 146, -1221268: 24, -1221269: 69, -1221270: 1, -1364098: 22, -1364099: 74, -1364100: 145, -1364101: 57, -1364102: 44, -1364103: 45, -1364104: 167, -1364105: 28, -1364106: 229, -1364107: 32, -1364108: 164, -1364109: 24, -1364110: 131, -1364111: 16, -1364112: 65, -1364113: 8, -1364114: 0, -1364115: 0, -1364116: 0, -1364117: 0, -1364118: 223, -1364119: 2, -1364120: 0, -1364121: 0, -1364122: 2, -1364123: 8, -1364124: 148, -1364125: 82, -1364126: 206, -1364127: 57, -1364128: 8, -1364129: 33, -1364130: 132, -1364131: 16, -1364132: 25, -1364133: 0, -1364134: 18, -1364135: 0, -1364136: 0, -1364137: 92, -1364138: 0, -1364139: 64, -1364140: 132, -1364141: 16, -1364142: 127, -1364143: 25, -1364144: 255, -1364145: 127, -1364146: 185, -1364147: 78, -1364148: 86, -1364149: 70, -1364150: 18, -1364151: 62, -1364152: 207, -1364153: 49, -1364154: 238, -1364155: 53, -1364156: 205, -1364157: 45, -1364158: 172, -1364159: 41, -1364160: 139, -1364161: 37, -1364162: 74, -1364163: 29, -1364164: 74, -1364165: 29, -1364166: 63, -1364167: 31, -1364168: 74, -1364169: 29, -1364170: 76, -1364171: 37, -1364172: 239, -1364173: 61, -1364174: 107, -1364175: 45, -1364176: 198, -1364177: 24, -1364178: 99, -1364179: 12, -1364180: 19, -1364181: 0, -1364182: 14, -1364183: 0, -1364184: 0, -1364185: 68, -1364186: 0, -1364187: 48, -1364188: 99, -1364189: 12, -1364190: 23, -1364191: 21, -1364192: 247, -1364193: 94, -1364194: 92, -1364195: 87, -1364196: 58, -1364197: 79, -1364198: 25, -1364199: 75, -1364200: 215, -1364201: 70, -1364202: 246, -1364203: 70, -1364204: 214, -1364205: 70, -1364206: 214, -1364207: 66, -1364208: 181, -1364209: 62, -1364210: 181, -1364211: 62, -1364212: 181, -1364213: 62, -1364214: 159, -1364215: 63, -1364216: 181, -1364217: 62, -1364218: 181, -1364219: 62, -1364220: 74, -1364221: 41, -1364222: 231, -1364223: 28, -1364224: 132, -1364225: 16, -1364226: 66, -1364227: 8, -1364228: 13, -1364229: 0, -1364230: 9, -1364231: 0, -1364232: 0, -1364233: 48, -1364234: 0, -1364235: 32, -1364236: 66, -1364237: 8, -1364238: 208, -1364239: 12, -1364240: 16, -1364241: 66, -1364242: 255, -1364243: 91, -1364244: 255, -1364245: 91, -1364246: 255, -1364247: 91, -1364248: 255, -1364249: 91, -1364250: 255, -1364251: 91, -1364252: 255, -1364253: 91, -1364254: 255, -1364255: 91, -1364256: 255, -1364257: 91, -1364258: 255, -1364259: 91, -1364260: 255, -1364261: 91, -1364262: 255, -1364263: 91, -1364264: 255, -1364265: 91, -1364266: 255, -1364267: 91, -1364268: 165, -1364269: 20, -1364270: 132, -1364271: 16, -1364272: 66, -1364273: 8, -1364274: 33, -1364275: 4, -1364276: 6, -1364277: 0, -1364278: 5, -1364279: 0, -1364280: 0, -1364281: 24, -1364282: 0, -1364283: 16, -1364284: 33, -1364285: 4, -1364286: 104, -1364287: 8, -1364288: 8, -1364289: 33, -1364580: 223, -1364581: 46, -1364582: 155, -1364583: 1, -1364584: 142, -1364585: 0, -1364586: 6, -1364587: 0, -1364588: 159, -1364589: 38, -1364590: 89, -1364591: 1, -1364592: 76, -1364593: 0, -1364594: 4, -1364595: 0, -1364596: 93, -1364597: 30, -1364598: 23, -1364599: 1, -1364600: 10, -1364601: 0, -1364602: 2, -1364603: 0, -1364604: 27, -1364605: 22, -1364606: 213, -1364607: 0, -1364608: 8, -1364609: 0, -1364610: 0, -1364611: 0, -1364612: 27, -1364613: 22, -1364614: 213, -1364615: 0, -1364616: 8, -1364617: 0, -1364618: 0, -1364619: 0, -1364620: 93, -1364621: 30, -1364622: 23, -1364623: 1, -1364624: 10, -1364625: 0, -1364626: 2, -1364627: 0, -1364628: 159, -1364629: 38, -1364630: 89, -1364631: 1, -1364632: 76, -1364633: 0, -1364634: 4, -1364635: 0, -1364636: 223, -1364637: 46, -1364638: 155, -1364639: 1, -1364640: 142, -1364641: 0, -1364642: 6, -1364643: 0, -1364644: 159, -1364645: 38, -1364646: 89, -1364647: 1, -1364648: 76, -1364649: 0, -1364650: 4, -1364651: 0, -1364652: 159, -1364653: 34, -1364654: 121, -1364655: 1, -1364656: 142, -1364657: 0, -1364658: 103, -1364659: 0, -1364660: 159, -1364661: 26, -1364662: 186, -1364663: 1, -1364664: 241, -1364665: 0, -1364666: 203, -1364667: 0, -1364668: 191, -1364669: 22, -1364670: 251, -1364671: 1, -1364672: 83, -1364673: 1, -1364674: 46, -1364675: 1, -1364676: 191, -1364677: 22, -1364678: 251, -1364679: 1, -1364680: 83, -1364681: 1, -1364682: 46, -1364683: 1, -1364684: 159, -1364685: 26, -1364686: 186, -1364687: 1, -1364688: 241, -1364689: 0, -1364690: 203, -1364691: 0, -1364692: 159, -1364693: 34, -1364694: 121, -1364695: 1, -1364696: 142, -1364697: 0, -1364698: 103, -1364699: 0, -1364700: 159, -1364701: 38, -1364702: 89, -1364703: 1, -1364704: 76, -1364705: 0, -1364706: 4, -1364707: 0, -449387: 0, -449388: 56, -449389: 8, -449390: 1, -449391: 189, -449392: 3, -449393: 5, -449394: 20, -449395: 224, -449396: 59, -449397: 168, -449398: 33, -449399: 159, -449400: 87, -449401: 210, -449402: 74, -449403: 78, -449404: 58, -449405: 187, -449406: 0, -449407: 181, -449408: 2, -449409: 107, -449410: 1, -449411: 82, -449412: 2, -449413: 4, -449414: 17, -449415: 116, -449416: 0, -449417: 13, -449418: 0, -449423: 0, -449424: 0, -449425: 174, -449426: 82, -449427: 189, -449428: 95, -449429: 229, -449430: 101, -449431: 224, -449432: 127, -449433: 136, -449434: 115, -449435: 255, -449436: 127, -449437: 242, -449438: 127, -449439: 238, -449440: 127, -449441: 155, -449442: 86, -449443: 85, -449444: 95, -449445: 11, -449446: 94, -449447: 246, -449448: 83, -449449: 228, -449450: 98, -449451: 84, -449452: 82, -449453: 237, -449454: 81, -449466: 0, -449467: 56, -449468: 8, -449469: 1, -449470: 189, -449471: 3, -449472: 5, -449473: 20, -449474: 224, -449475: 59, -449476: 168, -449477: 33, -449478: 159, -449479: 87, -449480: 210, -449481: 74, -449482: 78, -449483: 58, -449484: 187, -449485: 0, -449486: 181, -449487: 2, -449488: 107, -449489: 1, -449490: 82, -449491: 2, -449492: 4, -449493: 17, -449494: 116, -449495: 0, -449496: 13, -449497: 0, -449502: 0, -449503: 0, -449504: 174, -449505: 82, -449506: 189, -449507: 95, -449508: 229, -449509: 101, -449510: 224, -449511: 127, -449512: 136, -449513: 115, -449514: 255, -449515: 127, -449516: 242, -449517: 127, -449518: 238, -449519: 127, -449520: 155, -449521: 86, -449522: 85, -449523: 95, -449524: 11, -449525: 94, -449526: 246, -449527: 83, -449528: 228, -449529: 98, -449530: 84, -449531: 82, -449532: 237, -449533: 81, -449545: 0, -449546: 56, -449547: 8, -449548: 1, -449549: 189, -449550: 3, -449551: 5, -449552: 20, -449553: 224, -449554: 59, -449555: 168, -449556: 33, -449557: 159, -449558: 87, -449559: 210, -449560: 74, -449561: 78, -449562: 58, -449563: 187, -449564: 0, -449565: 181, -449566: 2, -449567: 107, -449568: 1, -449569: 82, -449570: 2, -449571: 4, -449572: 17, -449573: 116, -449574: 0, -449575: 13, -449576: 0, -449581: 3, -449582: 32, -449583: 110, -449584: 81, -449585: 189, -449586: 75, -449587: 165, -449588: 100, -449589: 224, -449590: 127, -449591: 72, -449592: 114, -449593: 255, -449594: 127, -449595: 114, -449596: 127, -449597: 238, -449598: 126, -449599: 91, -449600: 85, -449601: 181, -449602: 74, -449603: 107, -449604: 73, -449605: 182, -449606: 82, -449607: 164, -449608: 97, -449609: 20, -449610: 81, -449611: 173, -449612: 80, -449624: 0, -449625: 56, -449626: 8, -449627: 1, -449628: 189, -449629: 3, -449630: 5, -449631: 20, -449632: 224, -449633: 59, -449634: 168, -449635: 33, -449636: 159, -449637: 87, -449638: 210, -449639: 74, -449640: 78, -449641: 58, -449642: 187, -449643: 0, -449644: 181, -449645: 2, -449646: 107, -449647: 1, -449648: 82, -449649: 2, -449650: 4, -449651: 17, -449652: 116, -449653: 0, -449654: 13, -449655: 0, -449660: 3, -449661: 32, -449662: 206, -449663: 40, -449664: 189, -449665: 55, -449666: 5, -449667: 60, -449668: 224, -449669: 99, -449670: 168, -449671: 73, -449672: 159, -449673: 127, -449674: 210, -449675: 114, -449676: 78, -449677: 98, -449678: 187, -449679: 40, -449680: 181, -449681: 54, -449682: 107, -449683: 53, -449684: 22, -449685: 42, -449686: 4, -449687: 57, -449688: 116, -449689: 40, -449690: 13, -449691: 40, -449700: 0, -449701: 56, -449702: 8, -449703: 1, -449704: 189, -449705: 3, -449706: 5, -449707: 20, -449708: 224, -449709: 59, -449710: 168, -449711: 33, -449712: 159, -449713: 87, -449714: 210, -449715: 74, -449716: 78, -449717: 58, -449718: 187, -449719: 0, -449720: 181, -449721: 2, -449722: 107, -449723: 1, -449724: 82, -449725: 2, -449726: 4, -449727: 17, -449728: 116, -449729: 0, -449730: 13, -449731: 0, -449745: 0, -449746: 0, -449747: 8, -449748: 1, -449749: 255, -449750: 2, -449751: 5, -449752: 20, -449753: 224, -449754: 59, -449755: 168, -449756: 33, -449757: 159, -449758: 87, -449759: 210, -449760: 74, -449761: 78, -449762: 58, -449763: 187, -449764: 0, -449765: 190, -449766: 1, -449767: 142, -449768: 0, -449769: 82, -449770: 2, -449771: 4, -449772: 17, -449773: 116, -449774: 0, -449775: 13, -449776: 0, -449781: 0, -449782: 0, -449783: 168, -449784: 121, -449785: 159, -449786: 123, -449787: 229, -449788: 101, -449789: 224, -449790: 127, -449791: 136, -449792: 115, -449793: 255, -449794: 127, -449795: 242, -449796: 127, -449797: 238, -449798: 127, -449799: 155, -449800: 86, -449801: 94, -449802: 118, -449803: 46, -449804: 117, -449805: 77, -449806: 82, -449807: 228, -449808: 98, -449809: 84, -449810: 82, -449811: 237, -449812: 81, -449824: 0, -449825: 0, -449826: 8, -449827: 1, -449828: 255, -449829: 2, -449830: 5, -449831: 20, -449832: 224, -449833: 59, -449834: 168, -449835: 33, -449836: 159, -449837: 87, -449838: 210, -449839: 74, -449840: 78, -449841: 58, -449842: 187, -449843: 0, -449844: 190, -449845: 1, -449846: 142, -449847: 0, -449848: 82, -449849: 2, -449850: 4, -449851: 17, -449852: 116, -449853: 0, -449854: 13, -449855: 0, -449860: 0, -449861: 0, -449862: 168, -449863: 121, -449864: 159, -449865: 123, -449866: 229, -449867: 101, -449868: 224, -449869: 127, -449870: 136, -449871: 115, -449872: 255, -449873: 127, -449874: 242, -449875: 127, -449876: 238, -449877: 127, -449878: 155, -449879: 86, -449880: 94, -449881: 118, -449882: 46, -449883: 117, -449884: 77, -449885: 82, -449886: 228, -449887: 98, -449888: 84, -449889: 82, -449890: 237, -449891: 81, -449903: 0, -449904: 0, -449905: 8, -449906: 1, -449907: 255, -449908: 2, -449909: 5, -449910: 20, -449911: 224, -449912: 59, -449913: 168, -449914: 33, -449915: 159, -449916: 87, -449917: 210, -449918: 74, -449919: 78, -449920: 58, -449921: 187, -449922: 0, -449923: 190, -449924: 1, -449925: 142, -449926: 0, -449927: 82, -449928: 2, -449929: 4, -449930: 17, -449931: 116, -449932: 0, -449933: 13, -449934: 0, -449939: 3, -449940: 32, -449941: 8, -449942: 81, -449943: 255, -449944: 82, -449945: 165, -449946: 100, -449947: 224, -449948: 127, -449949: 72, -449950: 114, -449951: 255, -449952: 127, -449953: 114, -449954: 127, -449955: 238, -449956: 126, -449957: 91, -449958: 85, -449959: 190, -449960: 81, -449961: 142, -449962: 80, -449963: 77, -449964: 62, -449965: 164, -449966: 97, -449967: 20, -449968: 81, -449969: 173, -449970: 80, -449982: 0, -449983: 0, -449984: 8, -449985: 1, -449986: 255, -449987: 2, -449988: 5, -449989: 20, -449990: 224, -449991: 59, -449992: 168, -449993: 33, -449994: 159, -449995: 87, -449996: 210, -449997: 74, -449998: 78, -449999: 58, -450000: 187, -450001: 0, -450002: 190, -450003: 1, -450004: 142, -450005: 0, -450006: 82, -450007: 2, -450008: 4, -450009: 17, -450010: 116, -450011: 0, -450012: 13, -450013: 0, -450018: 3, -450019: 32, -450020: 8, -450021: 41, -450022: 255, -450023: 42, -450024: 5, -450025: 60, -450026: 224, -450027: 99, -450028: 168, -450029: 73, -450030: 159, -450031: 127, -450032: 210, -450033: 114, -450034: 78, -450035: 98, -450036: 187, -450037: 40, -450038: 190, -450039: 41, -450040: 142, -450041: 40, -450042: 77, -450043: 42, -450044: 4, -450045: 57, -450046: 116, -450047: 40, -450048: 13, -450049: 40, -450058: 0, -450059: 0, -450060: 8, -450061: 1, -450062: 255, -450063: 2, -450064: 5, -450065: 20, -450066: 224, -450067: 59, -450068: 168, -450069: 33, -450070: 159, -450071: 87, -450072: 210, -450073: 74, -450074: 78, -450075: 58, -450076: 187, -450077: 0, -450078: 190, -450079: 1, -450080: 142, -450081: 0, -450082: 82, -450083: 2, -450084: 4, -450085: 17, -450086: 116, -450087: 0, -450088: 13, -450089: 0, -450103: 0, -450104: 56, -450105: 8, -450106: 1, -450107: 31, -450108: 66, -450109: 5, -450110: 20, -450111: 224, -450112: 59, -450113: 168, -450114: 33, -450115: 159, -450116: 87, -450117: 210, -450118: 74, -450119: 78, -450120: 58, -450121: 187, -450122: 0, -450123: 20, -450124: 89, -450125: 170, -450126: 48, -450127: 116, -450128: 2, -450129: 4, -450130: 17, -450131: 116, -450132: 0, -450133: 13, -450134: 0, -450139: 0, -450140: 0, -450141: 174, -450142: 82, -450143: 255, -450144: 127, -450145: 229, -450146: 101, -450147: 224, -450148: 127, -450149: 136, -450150: 115, -450151: 255, -450152: 127, -450153: 242, -450154: 127, -450155: 238, -450156: 127, -450157: 155, -450158: 86, -450159: 244, -450160: 126, -450161: 138, -450162: 126, -450163: 246, -450164: 83, -450165: 228, -450166: 98, -450167: 84, -450168: 82, -450169: 237, -450170: 81, -450182: 0, -450183: 56, -450184: 8, -450185: 1, -450186: 31, -450187: 66, -450188: 5, -450189: 20, -450190: 224, -450191: 59, -450192: 168, -450193: 33, -450194: 159, -450195: 87, -450196: 210, -450197: 74, -450198: 78, -450199: 58, -450200: 187, -450201: 0, -450202: 20, -450203: 89, -450204: 170, -450205: 48, -450206: 116, -450207: 2, -450208: 4, -450209: 17, -450210: 116, -450211: 0, -450212: 13, -450213: 0, -450218: 0, -450219: 0, -450220: 174, -450221: 82, -450222: 255, -450223: 127, -450224: 229, -450225: 101, -450226: 224, -450227: 127, -450228: 136, -450229: 115, -450230: 255, -450231: 127, -450232: 242, -450233: 127, -450234: 238, -450235: 127, -450236: 155, -450237: 86, -450238: 244, -450239: 126, -450240: 138, -450241: 126, -450242: 246, -450243: 83, -450244: 228, -450245: 98, -450246: 84, -450247: 82, -450248: 237, -450249: 81, -450261: 0, -450262: 56, -450263: 8, -450264: 1, -450265: 31, -450266: 66, -450267: 5, -450268: 20, -450269: 224, -450270: 59, -450271: 168, -450272: 33, -450273: 159, -450274: 87, -450275: 210, -450276: 74, -450277: 78, -450278: 58, -450279: 187, -450280: 0, -450281: 20, -450282: 89, -450283: 170, -450284: 48, -450285: 116, -450286: 2, -450287: 4, -450288: 17, -450289: 116, -450290: 0, -450291: 13, -450292: 0, -450297: 3, -450298: 32, -450299: 110, -450300: 81, -450301: 191, -450302: 126, -450303: 165, -450304: 100, -450305: 224, -450306: 127, -450307: 72, -450308: 114, -450309: 255, -450310: 127, -450311: 114, -450312: 127, -450313: 238, -450314: 126, -450315: 91, -450316: 85, -450317: 180, -450318: 125, -450319: 74, -450320: 125, -450321: 182, -450322: 82, -450323: 164, -450324: 97, -450325: 20, -450326: 81, -450327: 173, -450328: 80, -450340: 0, -450341: 56, -450342: 8, -450343: 1, -450344: 31, -450345: 66, -450346: 5, -450347: 20, -450348: 224, -450349: 59, -450350: 168, -450351: 33, -450352: 159, -450353: 87, -450354: 210, -450355: 74, -450356: 78, -450357: 58, -450358: 187, -450359: 0, -450360: 20, -450361: 89, -450362: 170, -450363: 48, -450364: 116, -450365: 2, -450366: 4, -450367: 17, -450368: 116, -450369: 0, -450370: 13, -450371: 0, -450376: 3, -450377: 32, -450378: 206, -450379: 40, -450380: 31, -450381: 110, -450382: 5, -450383: 60, -450384: 224, -450385: 99, -450386: 168, -450387: 73, -450388: 159, -450389: 127, -450390: 210, -450391: 114, -450392: 78, -450393: 98, -450394: 187, -450395: 40, -450396: 20, -450397: 125, -450398: 170, -450399: 88, -450400: 22, -450401: 42, -450402: 4, -450403: 57, -450404: 116, -450405: 40, -450406: 13, -450407: 40, -450416: 0, -450417: 56, -450418: 8, -450419: 1, -450420: 31, -450421: 66, -450422: 5, -450423: 20, -450424: 224, -450425: 59, -450426: 168, -450427: 33, -450428: 159, -450429: 87, -450430: 210, -450431: 74, -450432: 78, -450433: 58, -450434: 187, -450435: 0, -450436: 20, -450437: 89, -450438: 170, -450439: 48, -450440: 116, -450441: 2, -450442: 4, -450443: 17, -450444: 116, -450445: 0, -450446: 13, -450447: 0, -1246881: 65, -1246882: 8, -1246884: 110, -451138: 255, -451139: 87, -451140: 255, -451141: 43, -451142: 60, -451143: 31, -451144: 120, -451145: 2, -451146: 176, -451147: 1, -451148: 11, -451149: 1, -451150: 135, -451151: 0, -451158: 222, -451159: 91, -451160: 222, -451161: 51, -451162: 26, -451163: 39, -451164: 87, -451165: 14, -451166: 175, -451167: 9, -451168: 10, -451169: 5, -451170: 134, -451171: 4, -451178: 221, -451179: 99, -451180: 156, -451181: 63, -451182: 249, -451183: 46, -451184: 85, -451185: 22, -451186: 142, -451187: 17, -451188: 10, -451189: 13, -451190: 134, -451191: 4, -451198: 188, -451199: 103, -451200: 123, -451201: 71, -451202: 215, -451203: 54, -451204: 52, -451205: 34, -451206: 141, -451207: 25, -451208: 9, -451209: 17, -451210: 133, -451211: 8, -451218: 155, -451219: 111, -451220: 89, -451221: 83, -451222: 214, -451223: 66, -451224: 50, -451225: 42, -451226: 141, -451227: 29, -451228: 233, -451229: 20, -451230: 133, -451231: 8, -451238: 122, -451239: 115, -451240: 56, -451241: 91, -451242: 180, -451243: 74, -451244: 17, -451245: 54, -451246: 140, -451247: 37, -451248: 232, -451249: 24, -451250: 132, -451251: 12, -451258: 121, -451259: 123, -451260: 246, -451261: 102, -451262: 147, -451263: 82, -451264: 15, -451265: 62, -451266: 107, -451267: 45, -451268: 232, -451269: 32, -451270: 132, -451271: 12, -451278: 88, -451279: 127, -451280: 213, -451281: 110, -451282: 113, -451283: 90, -451284: 238, -451285: 73, -451286: 106, -451287: 53, -451288: 231, -451289: 36, -451290: 131, -451291: 16, -1237849: 0, -1237850: 0, -1237851: 87, -1237852: 63, -1237853: 77, -1237854: 46, -1237855: 226, -1237856: 0, -1237857: 96, -1237858: 0, -1237859: 176, -1237860: 58, -1237861: 11, -1237862: 34, -1237863: 102, -1237864: 17, -1237865: 36, -1237866: 9, -1237867: 255, -1237868: 87, -1237869: 181, -1237870: 58, -1237871: 206, -1237872: 29, -1237873: 231, -1237874: 0, -1237875: 255, -1237876: 3, -1237877: 22, -1237878: 2, -1237879: 176, -1237880: 0, -1237881: 0, -1237882: 0, -1237883: 87, -1237884: 63, -1237885: 77, -1237886: 46, -1237887: 226, -1237888: 0, -1237889: 96, -1237890: 0, -1237891: 176, -1237892: 58, -1237893: 11, -1237894: 34, -1237895: 102, -1237896: 17, -1237897: 36, -1237898: 9, -1237899: 255, -1237900: 87, -1237901: 181, -1237902: 58, -1237903: 206, -1237904: 29, -1237905: 231, -1237906: 0, -1237907: 255, -1237908: 3, -1237909: 22, -1237910: 2, -1237911: 176, -1237912: 0, -1237913: 0, -1237914: 56, -1237915: 146, -1237916: 42, -1237917: 204, -1237918: 33, -1237919: 196, -1237920: 0, -1237921: 98, -1237922: 0, -1237923: 14, -1237924: 38, -1237925: 170, -1237926: 21, -1237927: 39, -1237928: 13, -1237929: 229, -1237930: 4, -1237931: 90, -1237932: 71, -1237933: 82, -1237934: 46, -1237935: 140, -1237936: 25, -1237937: 198, -1237938: 0, -1237939: 63, -1237940: 3, -1237941: 182, -1237942: 1, -1237943: 143, -1237944: 0, -1237945: 0, -1237946: 56, -1237947: 239, -1237948: 21, -1237949: 107, -1237950: 21, -1237951: 165, -1237952: 0, -1237953: 99, -1237954: 0, -1237955: 172, -1237956: 21, -1237957: 73, -1237958: 13, -1237959: 7, -1237960: 9, -1237961: 198, -1237962: 4, -1237963: 214, -1237964: 54, -1237965: 208, -1237966: 33, -1237967: 75, -1237968: 17, -1237969: 166, -1237970: 0, -1237971: 95, -1237972: 2, -1237973: 55, -1237974: 1, -1237975: 141, -1237976: 0, -1500232: 0, -1500233: 0, -1500234: 127, -1500235: 4, -1500236: 121, -1500237: 4, -1500238: 51, -1500239: 0, -1500240: 45, -1500241: 0, -1500242: 59, -1500243: 58, -1500244: 183, -1500245: 45, -1500246: 51, -1500247: 29, -1500248: 142, -1500249: 12, -1500250: 191, -1500251: 37, -1500252: 91, -1500253: 29, -1500254: 247, -1500255: 20, -1500256: 178, -1500257: 12, -1500258: 110, -1500259: 8, -1500260: 191, -1500261: 86, -451686: 16, -1500263: 0, -1500264: 80, -1500265: 4, -1500266: 77, -1500267: 4, -451692: 5, -1500269: 0, -1500270: 39, -1500271: 0, -1500272: 46, -1500273: 29, -1500274: 236, -1500275: 24, -451700: 210, -1500277: 16, -1500278: 71, -451703: 58, -451704: 187, -1500281: 20, -1500282: 174, -1500283: 16, -1500284: 140, -451709: 1, -451710: 82, -1500287: 8, -451712: 4, -1500289: 4, -1500290: 112, -1500291: 45, -1500292: 5, -1500293: 0, -1500294: 31, -1500295: 5, -451720: 4, -1500297: 4, -1500298: 211, -1500299: 0, -1500300: 173, -451725: 3, -1500302: 187, -1500303: 58, -451728: 225, -451729: 59, -451730: 202, -451731: 37, -451732: 159, -451733: 87, -451734: 211, -451735: 74, -451736: 79, -451737: 58, -451738: 188, -451739: 0, -451740: 182, -451741: 2, -451742: 108, -451743: 1, -451744: 83, -451745: 2, -451746: 5, -451747: 17, -451748: 117, -451749: 0, -451750: 14, -451751: 0, -1500328: 106, -1500329: 0, -451754: 4, -451755: 0, -451756: 9, -451757: 1, -451758: 189, -451759: 3, -1500336: 234, -451761: 20, -451762: 225, -451763: 59, -451764: 202, -451765: 37, -451766: 159, -451767: 87, -451768: 211, -451769: 74, -451770: 79, -451771: 58, -451772: 188, -451773: 0, -451774: 182, -451775: 2, -451776: 108, -451777: 1, -451778: 83, -451779: 2, -451780: 5, -451781: 17, -451782: 117, -451783: 0, -451784: 14, -451785: 0, -1500362: 123, -1500363: 59, -451788: 5, -451789: 0, -451790: 10, -451791: 1, -451792: 190, -451793: 3, -451794: 7, -451795: 20, -451796: 226, -451797: 59, -451798: 204, -451799: 37, -451800: 159, -451801: 87, -451802: 212, -451803: 74, -451804: 80, -451805: 58, -451806: 188, -451807: 0, -451808: 183, -451809: 2, -451810: 109, -451811: 1, -451812: 84, -451813: 2, -451814: 6, -451815: 17, -451816: 118, -451817: 0, -451818: 15, -451819: 0, -1500396: 74, -1500397: 17, -451822: 6, -451823: 0, -451824: 10, -451825: 1, -451826: 190, -451827: 3, -451828: 7, -451829: 20, -451830: 226, -451831: 59, -451832: 204, -451833: 37, -451834: 159, -451835: 87, -451836: 212, -451837: 74, -451838: 80, -451839: 58, -451840: 188, -451841: 0, -451842: 183, -451843: 2, -451844: 109, -451845: 1, -451846: 84, -451847: 2, -451848: 6, -451849: 17, -451850: 118, -451851: 0, -451852: 15, -451853: 0, -1500430: 245, -1500431: 38, -451856: 7, -451857: 0, -451858: 11, -451859: 1, -451860: 190, -451861: 3, -451862: 8, -451863: 20, -451864: 227, -451865: 59, -451866: 238, -451867: 41, -451868: 159, -451869: 87, -451870: 213, -451871: 74, -451872: 81, -451873: 58, -451874: 189, -451875: 0, -451876: 184, -451877: 2, -451878: 110, -451879: 1, -1500456: 69, -451881: 2, -451882: 7, -451883: 17, -451884: 119, -451885: 0, -451886: 16, -451887: 0, -1500464: 39, -1500465: 13, -451890: 8, -451891: 0, -451892: 11, -1500469: 4, -451894: 190, -451895: 3, -451896: 8, -1500473: 0, -451898: 227, -1500475: 13, -451900: 238, -451901: 41, -451902: 159, -1500479: 9, -451904: 213, -451905: 74, -451906: 81, -451907: 58, -1500484: 173, -451909: 0, -1500486: 41, -451911: 2, -451912: 110, -451913: 1, -451914: 85, -451915: 2, -451916: 7, -451917: 17, -451918: 119, -451919: 0, -451920: 16, -451921: 0, -1500498: 100, -1500499: 17, -451924: 8, -1500501: 95, -451926: 13, -451927: 1, -451928: 190, -451929: 3, -451930: 10, -451931: 20, -451932: 229, -451933: 59, -451934: 15, -1500511: 4, -451936: 159, -451937: 87, -451938: 215, -451939: 74, -1500516: 37, -451941: 58, -451942: 189, -451943: 0, -451944: 186, -451945: 2, -451946: 112, -451947: 1, -451948: 87, -451949: 2, -451950: 9, -451951: 17, -451952: 121, -451953: 0, -451954: 18, -451955: 0, -1500532: 128, -1500533: 4, -451958: 8, -451959: 0, -451960: 13, -451961: 1, -451962: 190, -451963: 3, -451964: 10, -451965: 20, -451966: 229, -451967: 59, -451968: 15, -451969: 46, -451970: 159, -451971: 87, -451972: 215, -451973: 74, -451974: 83, -451975: 58, -451976: 189, -451977: 0, -451978: 186, -451979: 2, -451980: 112, -451981: 1, -451982: 87, -451983: 2, -451984: 9, -1500561: 107, -451986: 121, -451987: 0, -451988: 18, -451989: 0, -1500566: 136, -1500567: 12, -451992: 8, -451993: 0, -451994: 11, -1500571: 12, -451996: 190, -451997: 3, -451998: 8, -451999: 20, -1500576: 229, -452001: 59, -452002: 238, -452003: 41, -1500580: 43, -452005: 87, -452006: 213, -452007: 74, -452008: 81, -452009: 58, -452010: 189, -452011: 0, -452012: 184, -452013: 2, -452014: 110, -452015: 1, -452016: 85, -452017: 2, -452018: 7, -452019: 17, -452020: 119, -452021: 0, -452022: 16, -452023: 0, -1500600: 35, -1500601: 40, -452026: 7, -452027: 0, -452028: 11, -452029: 1, -1500606: 41, -452031: 3, -452032: 8, -452033: 20, -452034: 227, -452035: 59, -452036: 238, -452037: 41, -452038: 159, -452039: 87, -452040: 213, -452041: 74, -452042: 81, -452043: 58, -452044: 189, -452045: 0, -452046: 184, -452047: 2, -452048: 110, -452049: 1, -452050: 85, -452051: 2, -452052: 7, -452053: 17, -452054: 119, -452055: 0, -452056: 16, -452057: 0, -1500634: 231, -1500635: 44, -1500636: 165, -452061: 0, -452062: 10, -452063: 1, -452064: 190, -452065: 3, -452066: 7, -452067: 20, -452068: 226, -452069: 59, -452070: 204, -452071: 37, -452072: 159, -452073: 87, -452074: 212, -452075: 74, -452076: 80, -452077: 58, -452078: 188, -452079: 0, -452080: 183, -452081: 2, -452082: 109, -452083: 1, -452084: 84, -452085: 2, -452086: 6, -452087: 17, -452088: 118, -452089: 0, -452090: 15, -452091: 0, -1500668: 137, -1500669: 56, -452094: 5, -452095: 0, -452096: 10, -452097: 1, -452098: 190, -452099: 3, -452100: 7, -452101: 20, -452102: 226, -452103: 59, -452104: 204, -452105: 37, -452106: 159, -452107: 87, -452108: 212, -452109: 74, -452110: 80, -452111: 58, -452112: 188, -452113: 0, -452114: 183, -452115: 2, -1500692: 43, -1500693: 49, -452118: 84, -1500695: 44, -452120: 6, -452121: 17, -452122: 118, -452123: 0, -452124: 15, -452125: 0, -1500702: 171, -1500703: 36, -452128: 4, -452129: 0, -452130: 9, -452131: 1, -452132: 189, -1500709: 24, -452134: 6, -452135: 20, -452136: 225, -452137: 59, -1500714: 127, -452139: 37, -452140: 159, -1500717: 44, -452142: 211, -452143: 74, -452144: 79, -452145: 58, -452146: 188, -452147: 0, -452148: 182, -452149: 2, -1500726: 51, -1500727: 73, -1500728: 142, -1500729: 56, -1500730: 191, -1500731: 77, -1500732: 91, -452157: 0, -1500734: 247, -1500735: 64, -1500736: 178, -1500737: 56, -452162: 4, -452163: 0, -452164: 9, -452165: 1, -452166: 189, -452167: 3, -452168: 6, -452169: 20, -452170: 225, -452171: 59, -452172: 202, -452173: 37, -452174: 159, -452175: 87, -452176: 211, -452177: 74, -452178: 79, -452179: 58, -452180: 188, -452181: 0, -452182: 182, -452183: 2, -452184: 108, -452185: 1, -452186: 83, -452187: 2, -452188: 5, -452189: 17, -452190: 117, -452191: 0, -452192: 14, -452193: 0, -1500770: 112, -1500771: 65, -1500772: 5, -452197: 0, -452198: 9, -452199: 1, -452200: 189, -452201: 3, -1500778: 51, -1500779: 20, -452204: 225, -452205: 59, -452206: 202, -452207: 37, -452208: 159, -1500785: 65, -452210: 211, -452211: 74, -452212: 79, -452213: 58, -452214: 188, -452215: 0, -452216: 182, -452217: 2, -452218: 108, -452219: 1, -452220: 83, -452221: 2, -452222: 5, -452223: 17, -452224: 117, -452225: 0, -452226: 14, -452227: 0, -1500804: 80, -1500805: 12, -1500806: 77, -1500807: 12, -1500808: 42, -1500809: 12, -1500810: 39, -1500811: 12, -1500812: 46, -1500813: 41, -1500814: 236, -1500815: 32, -1500816: 170, -1500817: 24, -452242: 16, -1500819: 16, -452244: 8, -452245: 1, -452246: 255, -1500823: 24, -1500824: 140, -452249: 20, -452250: 224, -452251: 59, -452252: 168, -452253: 33, -452254: 159, -452255: 87, -452256: 210, -452257: 74, -452258: 78, -452259: 58, -452260: 187, -452261: 0, -452262: 190, -452263: 1, -452264: 142, -452265: 0, -452266: 82, -452267: 2, -452268: 4, -452269: 17, -452270: 116, -1500847: 1, -452272: 13, -452273: 0, -1500850: 4, -1500851: 0, -452276: 4, -452277: 0, -452278: 9, -452279: 1, -452280: 255, -452281: 2, -452282: 6, -452283: 20, -452284: 225, -452285: 59, -452286: 202, -1500863: 41, -1500864: 115, -1500865: 33, -1500866: 12, -1500867: 21, -452292: 79, -452293: 58, -452294: 188, -452295: 0, -452296: 190, -452297: 1, -452298: 143, -452299: 0, -452300: 83, -452301: 2, -452302: 5, -452303: 17, -452304: 117, -1500881: 0, -1500882: 249, -452307: 0, -1500884: 51, -1500885: 62, -452310: 4, -452311: 0, -452312: 9, -452313: 1, -452314: 255, -452315: 2, -452316: 6, -452317: 20, -1500894: 83, -452319: 59, -452320: 202, -452321: 37, -452322: 159, -452323: 87, -452324: 211, -452325: 74, -452326: 79, -452327: 58, -452328: 188, -452329: 0, -452330: 190, -1500907: 1, -452332: 143, -1500909: 0, -452334: 83, -452335: 2, -452336: 5, -452337: 17, -452338: 117, -452339: 0, -452340: 14, -452341: 0, -1500918: 139, -1500919: 16, -452344: 5, -452345: 0, -452346: 10, -452347: 1, -452348: 255, -452349: 2, -1500926: 207, -1500927: 16, -1500928: 107, -1500929: 8, -452354: 204, -452355: 37, -452356: 159, -452357: 87, -452358: 212, -452359: 74, -1500936: 219, -452361: 58, -452362: 188, -452363: 0, -452364: 190, -1500941: 0, -452366: 144, -452367: 0, -452368: 84, -452369: 2, -1500946: 244, -452371: 17, -1500948: 112, -1500949: 12, -1500950: 127, -452375: 0, -1500952: 59, -1500953: 25, -1500954: 215, -1500955: 16, -452380: 10, -452381: 1, -452382: 255, -452383: 2, -452384: 7, -452385: 20, -452386: 226, -452387: 59, -452388: 204, -452389: 37, -452390: 159, -452391: 87, -452392: 212, -452393: 74, -452394: 80, -452395: 58, -452396: 188, -452397: 0, -452398: 190, -452399: 1, -452400: 144, -452401: 0, -452402: 84, -452403: 2, -452404: 6, -452405: 17, -452406: 118, -452407: 0, -452408: 15, -452409: 0, -1500986: 147, -1500987: 12, -452412: 7, -452413: 0, -452414: 11, -1500991: 74, -452416: 255, -452417: 2, -452418: 8, -452419: 20, -452420: 227, -452421: 59, -452422: 238, -452423: 41, -452424: 159, -452425: 87, -452426: 213, -452427: 74, -452428: 81, -452429: 58, -1501006: 0, -452431: 0, -452432: 190, -452433: 1, -452434: 145, -452435: 0, -452436: 85, -452437: 2, -452438: 7, -452439: 17, -452440: 119, -452441: 0, -452442: 16, -452443: 0, -1501020: 0, -1501021: 0, -452446: 8, -452447: 0, -452448: 11, -452449: 1, -452450: 255, -452451: 2, -452452: 8, -452453: 20, -452454: 227, -452455: 59, -452456: 238, -452457: 41, -452458: 159, -1501035: 0, -452460: 213, -452461: 74, -452462: 81, -1501039: 0, -452464: 189, -452465: 0, -1501042: 111, -452467: 1, -452468: 145, -452469: 0, -452470: 85, -452471: 2, -452472: 7, -452473: 17, -452474: 119, -452475: 0, -452476: 16, -452477: 0, -1501054: 4, -1501055: 0, -452480: 8, -452481: 0, -452482: 13, -452483: 1, -452484: 255, -452485: 2, -452486: 10, -452487: 20, -452488: 229, -452489: 59, -452490: 15, -452491: 46, -452492: 159, -452493: 87, -452494: 215, -452495: 74, -452496: 83, -452497: 58, -452498: 189, -452499: 0, -452500: 191, -452501: 1, -452502: 147, -1501079: 8, -1501080: 8, -452505: 2, -1501082: 8, -1501083: 0, -452508: 121, -1501085: 0, -452510: 18, -452511: 0, -1501088: 8, -1501089: 0, -452514: 8, -452515: 0, -452516: 13, -452517: 1, -452518: 255, -452519: 2, -452520: 10, -452521: 20, -452522: 229, -452523: 59, -452524: 15, -452525: 46, -1501102: 245, -1501103: 20, -452528: 215, -452529: 74, -452530: 83, -452531: 58, -452532: 189, -1501109: 4, -452534: 191, -452535: 1, -452536: 147, -452537: 0, -452538: 87, -452539: 2, -452540: 9, -452541: 17, -452542: 121, -452543: 0, -452544: 18, -452545: 0, -1501122: 14, -1501123: 0, -452548: 8, -452549: 0, -452550: 11, -452551: 1, -452552: 255, -452553: 2, -452554: 8, -452555: 20, -452556: 227, -452557: 59, -452558: 238, -452559: 41, -452560: 159, -452561: 87, -452562: 213, -452563: 74, -452564: 81, -452565: 58, -452566: 189, -452567: 0, -452568: 190, -452569: 1, -452570: 145, -452571: 0, -1501148: 14, -452573: 2, -1501150: 245, -452575: 17, -452576: 119, -452577: 0, -452578: 16, -452579: 0, -452582: 7, -452583: 0, -452584: 11, -452585: 1, -452586: 255, -452587: 2, -452588: 8, -452589: 20, -452590: 227, -452591: 59, -452592: 238, -452593: 41, -452594: 159, -1501171: 87, -1501172: 17, -1501173: 11, -452598: 81, -452599: 58, -452600: 189, -1501177: 0, -452602: 190, -452603: 1, -452604: 145, -452605: 0, -452606: 85, -452607: 2, -452608: 7, -452609: 17, -452610: 119, -1501187: 127, -452612: 16, -452613: 0, -1501190: 18, -1501191: 11, -452616: 6, -452617: 0, -452618: 10, -1501195: 0, -452620: 255, -452621: 2, -1501198: 183, -1501199: 58, -452624: 226, -452625: 59, -452626: 204, -452627: 37, -452628: 159, -452629: 87, -452630: 212, -452631: 74, -452632: 80, -452633: 58, -452634: 188, -452635: 0, -452636: 190, -452637: 1, -452638: 144, -1501215: 71, -1501216: 150, -1501217: 58, -452642: 6, -452643: 17, -1501220: 172, -452645: 0, -452646: 15, -1501223: 115, -1501224: 185, -1501225: 63, -1501226: 243, -1501227: 10, -1501228: 9, -1501229: 14, -1501230: 229, -452655: 2, -452656: 7, -452657: 20, -452658: 226, -452659: 59, -452660: 204, -452661: 37, -1501238: 172, -452663: 87, -452664: 212, -452665: 74, -452666: 80, -452667: 58, -452668: 188, -452669: 0, -452670: 190, -452671: 1, -452672: 144, -452673: 0, -452674: 84, -452675: 2, -1501252: 84, -1501253: 50, -1501254: 175, -452679: 0, -452680: 15, -1501257: 4, -1501258: 222, -1501259: 103, -452684: 4, -452685: 0, -452686: 9, -452687: 1, -452688: 255, -452689: 2, -452690: 6, -452691: 20, -452692: 225, -452693: 59, -452694: 202, -1501271: 46, -452696: 159, -1501273: 33, -452698: 211, -452699: 74, -452700: 79, -452701: 58, -1501278: 154, -1501279: 35, -452704: 190, -1501281: 6, -452706: 143, -1501283: 9, -452708: 83, -452709: 2, -1501286: 151, -1501287: 58, -1501288: 18, -1501289: 46, -452714: 14, -452715: 0, -1501292: 138, -1501293: 4, -452718: 4, -1501295: 91, -452720: 9, -452721: 1, -1501298: 213, -452723: 2, -1501300: 204, -1501301: 5, -452726: 225, -1501303: 0, -452728: 202, -1501305: 54, -452730: 159, -452731: 87, -1501308: 109, -452733: 74, -452734: 79, -452735: 58, -452736: 188, -452737: 0, -452738: 190, -452739: 1, -452740: 143, -452741: 0, -452742: 83, -452743: 2, -452744: 5, -452745: 17, -452746: 117, -452747: 0, -452748: 14, -452749: 0, -452752: 16, -452753: 0, -1501330: 255, -452755: 1, -452756: 255, -452757: 2, -452758: 5, -452759: 20, -1501336: 175, -1501337: 28, -452762: 168, -1501339: 24, -452764: 159, -452765: 87, -452766: 210, -1501343: 44, -452768: 78, -1501345: 40, -452770: 187, -1501347: 32, -1501348: 168, -1501349: 24, -1501350: 155, -1501351: 106, -452776: 82, -1501353: 48, -1501354: 150, -1501355: 40, -1501356: 141, -452781: 0, -1501358: 136, -1501359: 20, -1501360: 89, -1501361: 102, -1501362: 185, -1501363: 48, -1501364: 148, -1501365: 44, -1501366: 140, -1501367: 36, -1501368: 135, -1501369: 20, -1501370: 54, -1501371: 102, -1501372: 150, -1501373: 52, -1501374: 146, -1501375: 44, -1501376: 139, -1501377: 40, -1501378: 102, -1501379: 16, -1501380: 244, -1501381: 97, -1501382: 148, -1501383: 52, -1501384: 144, -1501385: 48, -1501386: 138, -1501387: 44, -1501388: 101, -1501389: 16, -1501390: 210, -1501391: 93, -1501392: 114, -1501393: 56, -1501394: 111, -1501395: 48, -1501396: 105, -1501397: 44, -1501398: 69, -1501399: 12, -1501400: 144, -1501401: 89, -1501402: 112, -1501403: 56, -1501404: 109, -1501405: 52, -1501406: 104, -1501407: 48, -1501408: 68, -1501409: 12, -452834: 9, -452835: 1, -452836: 31, -452837: 66, -452838: 6, -452839: 20, -452840: 225, -452841: 59, -452842: 202, -452843: 37, -452844: 159, -452845: 87, -452846: 211, -452847: 74, -1501424: 22, -1501425: 23, -1501426: 82, -1501427: 2, -1501428: 138, -1501429: 1, -1501430: 198, -1501431: 0, -1501432: 77, -1501433: 73, -1501434: 77, -1501435: 48, -1501436: 75, -1501437: 44, -1501438: 70, -1501439: 40, -1501440: 35, -1501441: 8, -1501442: 18, -1501443: 46, -1501444: 142, -1501445: 33, -1501446: 43, -1501447: 25, -1501448: 104, -1501449: 0, -1501450: 57, -1501451: 75, -1501452: 146, -1501453: 18, -1501454: 239, -1501455: 1, -1501456: 72, -1501457: 1, -1501458: 165, -1501459: 0, -1501460: 11, -1501461: 61, -1501462: 75, -1501463: 40, -1501464: 73, -1501465: 36, -1501466: 69, -1501467: 32, -1501468: 34, -1501469: 8, -1501470: 175, -1501471: 37, -1501472: 76, -1501473: 29, -1501474: 233, -1501475: 20, -1501476: 71, -1501477: 0, -1501478: 181, -1501479: 62, -1501480: 14, -1501481: 14, -1501482: 140, -1501483: 1, -1501484: 6, -1501485: 1, -1501486: 132, -1501487: 0, -1501488: 201, -1501489: 48, -1501490: 41, -1501491: 32, -1501492: 39, -1501493: 28, -1501494: 36, -1501495: 24, -1501496: 34, -1501497: 4, -1501498: 76, -1501499: 29, -1501500: 9, -1501501: 21, -1501502: 199, -1501503: 16, -1501504: 69, -1501505: 0, -1501506: 49, -1501507: 50, -1501508: 139, -1501509: 9, -1501510: 41, -1501511: 1, -1501512: 197, -1501513: 0, -1501514: 99, -1501515: 0, -1501516: 166, -1501517: 36, -1501518: 38, -1501519: 24, -1501520: 37, -1501521: 20, -1501522: 35, -1501523: 20, -1501524: 1, -1501525: 4, -1501526: 9, -1501527: 21, -1501528: 199, -1501529: 16, -1501530: 133, -1501531: 12, -1501532: 36, -1501533: 0, -1501534: 140, -1501535: 37, -1501536: 7, -1501537: 5, -1501538: 198, -1501539: 0, -1501540: 131, -1501541: 0, -1501542: 66, -1501543: 0, -1501544: 100, -1501545: 24, -1501546: 4, -1501547: 16, -1501548: 3, -1501549: 12, -1501550: 2, -1501551: 12, -1501552: 1, -1501553: 0, -1501554: 166, -1501555: 12, -1501556: 132, -1501557: 8, -1501558: 99, -1501559: 8, -1501560: 34, -1501561: 0, -1501562: 8, -1501563: 25, -1501564: 131, -1501565: 0, -1501566: 99, -1501567: 0, -1501568: 65, -1501569: 0, -1501570: 33, -1501571: 0, -1501572: 34, -1501573: 12, -1501574: 2, -1501575: 8, -1501576: 1, -1501577: 4, -1501578: 1, -1501579: 4, -1501580: 0, -1501581: 0, -1501582: 67, -1501583: 4, -1501584: 66, -1501585: 4, -1501586: 33, -1501587: 4, -1501588: 1, -1501589: 0, -1501590: 132, -1501591: 12, -1501592: 0, -1501593: 0, -1501594: 0, -1501595: 0, -1501596: 0, -1501597: 0, -1501598: 0, -1501599: 0, -1501600: 0, -1501601: 0, -1501602: 0, -1501603: 0, -1501604: 0, -1501605: 0, -1501606: 0, -1501607: 0, -1501608: 0, -1501609: 0, -1501610: 0, -1501611: 0, -1501612: 0, -1501613: 0, -1501614: 0, -1501615: 0, -1501616: 0, -1501617: 0, -1501618: 0, -1501619: 0, -453044: 229, -453045: 59, -453046: 15, -453047: 46, -453048: 159, -453049: 87, -453050: 215, -453051: 74, -453052: 83, -453053: 58, -453054: 189, -453055: 0, -453056: 25, -453057: 89, -453058: 175, -453059: 48, -453060: 87, -453061: 2, -453062: 9, -453063: 17, -453064: 121, -453065: 0, -453066: 18, -453067: 0, -453070: 8, -453071: 0, -453072: 13, -453073: 1, -453074: 31, -453075: 66, -453076: 10, -453077: 20, -453078: 229, -453079: 59, -453080: 15, -453081: 46, -453082: 159, -453083: 87, -453084: 215, -453085: 74, -453086: 83, -453087: 58, -453088: 189, -453089: 0, -453090: 25, -453091: 89, -453092: 175, -453093: 48, -453094: 87, -453095: 2, -453096: 9, -453097: 17, -453098: 121, -453099: 0, -453100: 18, -453101: 0, -453104: 8, -453105: 0, -453106: 11, -453107: 1, -453108: 31, -453109: 66, -453110: 8, -453111: 20, -453112: 227, -453113: 59, -453114: 238, -453115: 41, -453116: 159, -453117: 87, -453118: 213, -453119: 74, -453120: 81, -453121: 58, -453122: 189, -453123: 0, -453124: 23, -453125: 89, -453126: 173, -453127: 48, -1501704: 0, -1501705: 0, -1501706: 159, -1501707: 21, -1501708: 219, -1501709: 0, -1501710: 51, -1501711: 0, -1501712: 14, -1501713: 0, -1501714: 251, -1501715: 49, -1501716: 119, -1501717: 37, -1501718: 244, -1501719: 24, -1501720: 112, -1501721: 12, -1501722: 127, -1501723: 29, -1501724: 59, -1501725: 25, -1501726: 215, -1501727: 16, -1501728: 147, -1501729: 12, -1501730: 80, -1501731: 4, -1501732: 95, -1501733: 74, -1501734: 14, -1501735: 0, -1501736: 14, -1501737: 0, -1501738: 14, -1501739: 0, -1501740: 16, -1501741: 0, -1501742: 245, -1501743: 20, -1501744: 179, -1501745: 16, -1501746: 114, -1501747: 8, -1501748: 48, -1501749: 4, -1501750: 14, -1501751: 0, -1501752: 14, -1501753: 0, -1501754: 14, -1501755: 0, -1501756: 14, -1501757: 0, -1501758: 14, -1501759: 0, -1501760: 245, -1501761: 20, -1501762: 125, -1501763: 17, -1501764: 185, -1501765: 0, -1501766: 49, -1501767: 0, -1501768: 13, -1501769: 0, -1501770: 217, -1501771: 45, -1501772: 85, -1501773: 33, -1501774: 210, -1501775: 20, -1501776: 79, -1501777: 8, -1501778: 93, -1501779: 25, -1501780: 25, -1501781: 21, -1501782: 181, -1501783: 12, -1501784: 113, -1501785: 8, -1501786: 47, -1501787: 4, -1501788: 29, -1501789: 66, -1501790: 13, -1501791: 0, -1501792: 13, -1501793: 0, -1501794: 13, -1501795: 0, -1501796: 15, -1501797: 0, -1501798: 211, -1501799: 16, -1501800: 145, -1501801: 12, -1501802: 80, -1501803: 4, -1501804: 47, -1501805: 4, -1501806: 13, -1501807: 0, -1501808: 13, -1501809: 0, -1501810: 13, -1501811: 0, -1501812: 13, -1501813: 0, -1501814: 13, -1501815: 0, -1501816: 211, -1501817: 16, -1501818: 90, -1501819: 17, -1501820: 183, -1501821: 0, -1501822: 16, -1501823: 0, -1501824: 12, -1501825: 0, -1501826: 183, -1501827: 41, -1501828: 52, -1501829: 29, -1501830: 209, -1501831: 20, -1501832: 77, -1501833: 8, -1501834: 58, -1501835: 25, -1501836: 247, -1501837: 20, -1501838: 180, -1501839: 12, -1501840: 112, -1501841: 8, -1501842: 45, -1501843: 0, -1501844: 250, -1501845: 61, -1501846: 12, -1501847: 0, -1501848: 12, -1501849: 0, -1501850: 12, -1501851: 0, -1501852: 13, -1501853: 0, -1501854: 210, -1501855: 16, -1501856: 144, -1501857: 12, -1501858: 79, -1501859: 4, -1501860: 13, -1501861: 0, -1501862: 12, -1501863: 0, -1501864: 12, -1501865: 0, -1501866: 12, -1501867: 0, -1501868: 12, -1501869: 0, -1501870: 12, -1501871: 0, -1501872: 210, -1501873: 16, -1501874: 56, -1501875: 17, -1501876: 149, -1501877: 0, -1501878: 15, -1501879: 0, -1501880: 11, -1501881: 0, -1501882: 149, -1501883: 37, -1501884: 18, -1501885: 29, -1501886: 176, -1501887: 16, -1501888: 76, -1501889: 8, -1501890: 24, -1501891: 21, -1501892: 245, -1501893: 16, -1501894: 146, -1501895: 12, -1501896: 111, -1501897: 8, -1501898: 44, -1501899: 0, -1501900: 216, -1501901: 57, -1501902: 11, -1501903: 0, -1501904: 11, -1501905: 0, -1501906: 11, -1501907: 0, -1501908: 12, -1501909: 0, -1501910: 176, -1501911: 16, -1501912: 143, -1501913: 12, -1501914: 78, -1501915: 4, -1501916: 12, -1501917: 0, -1501918: 11, -1501919: 0, -1501920: 11, -1501921: 0, -1501922: 11, -1501923: 0, -1501924: 11, -1501925: 0, -1501926: 11, -1501927: 0, -1501928: 176, -1501929: 16, -1501930: 22, -1501931: 13, -1501932: 147, -1501933: 0, -1501934: 14, -1501935: 0, -1501936: 10, -1501937: 0, -1501938: 115, -1501939: 33, -1501940: 16, -1501941: 25, -1501942: 174, -1501943: 16, -1501944: 75, -1501945: 8, -1501946: 22, -1501947: 21, -1501948: 211, -1501949: 16, -1501950: 144, -1501951: 12, -1501952: 110, -1501953: 8, -1501954: 43, -1501955: 0, -1501956: 182, -1501957: 53, -1501958: 10, -1501959: 0, -1501960: 10, -1501961: 0, -1501962: 10, -1501963: 0, -1501964: 11, -1501965: 0, -1501966: 175, -1501967: 12, -1501968: 110, -1501969: 12, -1501970: 77, -1501971: 4, -1501972: 11, -1501973: 0, -1501974: 10, -1501975: 0, -1501976: 10, -1501977: 0, -1501978: 10, -1501979: 0, -1501980: 10, -1501981: 0, -1501982: 10, -1501983: 0, -1501984: 175, -1501985: 12, -1501986: 20, -1501987: 13, -1501988: 146, -1501989: 0, -1501990: 12, -1501991: 0, -1501992: 9, -1501993: 0, -1501994: 82, -1501995: 33, -1501996: 239, -1501997: 24, -1501998: 141, -1501999: 16, -1502000: 74, -1502001: 8, -1502002: 244, -1502003: 16, -1502004: 210, -1502005: 16, -1502006: 143, -1502007: 8, -1502008: 76, -1502009: 8, -1502010: 42, -1502011: 0, -1502012: 148, -1502013: 49, -1502014: 9, -1502015: 0, -1502016: 9, -1502017: 0, -1502018: 9, -1502019: 0, -1502020: 10, -1502021: 0, -1502022: 142, -1502023: 12, -1502024: 108, -1502025: 8, -1502026: 76, -1502027: 4, -1502028: 10, -1502029: 0, -1502030: 9, -1502031: 0, -1502032: 9, -1502033: 0, -1502034: 9, -1502035: 0, -1502036: 9, -1502037: 0, -1502038: 9, -1502039: 0, -1502040: 142, -1502041: 12, -1502042: 242, -1502043: 12, -1502044: 112, -1502045: 0, -1502046: 11, -1502047: 0, -1502048: 8, -1502049: 0, -1502050: 48, -1502051: 29, -1502052: 205, -1502053: 20, -1502054: 140, -1502055: 12, -1502056: 41, -1502057: 4, -1502058: 210, -1502059: 16, -1502060: 176, -1502061: 12, -1502062: 109, -1502063: 8, -1502064: 75, -1502065: 4, -1502066: 41, -1502067: 0, -1502068: 82, -1502069: 41, -1502070: 8, -1502071: 0, -1502072: 8, -1502073: 0, -1502074: 8, -1502075: 0, -1502076: 9, -1502077: 0, -1502078: 140, -1502079: 12, -1502080: 107, -1502081: 8, -1502082: 42, -1502083: 4, -1502084: 9, -1502085: 0, -1502086: 8, -1502087: 0, -1502088: 8, -1502089: 0, -1502090: 8, -1502091: 0, -1502092: 8, -1502093: 0, -1502094: 8, -1502095: 0, -1502096: 140, -1502097: 12, -1502098: 208, -1502099: 8, -1502100: 110, -1502101: 0, -1502102: 10, -1502103: 0, -1502104: 7, -1502105: 0, -1502106: 14, -1502107: 25, -1502108: 172, -1502109: 16, -1502110: 106, -1502111: 12, -1502112: 40, -1502113: 4, -1502114: 176, -1502115: 12, -1502116: 142, -1502117: 12, -1502118: 108, -1502119: 8, -1502120: 74, -1502121: 4, -1502122: 40, -1502123: 0, -1502124: 48, -1502125: 37, -1502126: 7, -1502127: 0, -1502128: 7, -1502129: 0, -1502130: 7, -1502131: 0, -1502132: 8, -1502133: 0, -1502134: 107, -1502135: 8, -1502136: 74, -1502137: 8, -1502138: 41, -1502139: 4, -1502140: 8, -1502141: 0, -1502142: 7, -1502143: 0, -1502144: 7, -1502145: 0, -1502146: 7, -1502147: 0, -1502148: 7, -1502149: 0, -1502150: 7, -1502151: 0, -1502152: 107, -1502153: 8, -1502154: 174, -1502155: 8, -1502156: 76, -1502157: 0, -1502158: 8, -1502159: 0, -1502160: 6, -1502161: 0, -1502162: 236, -1502163: 20, -1502164: 170, -1502165: 16, -1502166: 105, -1502167: 8, -1502168: 39, -1502169: 4, -1502170: 174, -1502171: 12, -1502172: 140, -1502173: 8, -1502174: 74, -1502175: 4, -1502176: 40, -1502177: 4, -1502178: 39, -1502179: 0, -1502180: 14, -1502181: 33, -1502182: 6, -1502183: 0, -1502184: 6, -1502185: 0, -1502186: 6, -1502187: 0, -1502188: 7, -1502189: 0, -1502190: 105, -1502191: 8, -1502192: 72, -1502193: 4, -1502194: 40, -1502195: 4, -1502196: 7, -1502197: 0, -1502198: 6, -1502199: 0, -1502200: 6, -1502201: 0, -1502202: 6, -1502203: 0, -1502204: 6, -1502205: 0, -1502206: 6, -1502207: 0, -1502208: 105, -1502209: 8, -1502210: 140, -1502211: 8, -1502212: 74, -1502213: 0, -1502214: 7, -1502215: 0, -1502216: 5, -1502217: 0, -1502218: 202, -1502219: 16, -1502220: 137, -1502221: 12, -1502222: 72, -1502223: 8, -1502224: 38, -1502225: 4, -1502226: 140, -1502227: 8, -1502228: 106, -1502229: 8, -1502230: 73, -1502231: 4, -1502232: 39, -1502233: 4, -1502234: 6, -1502235: 0, -1502236: 236, -1502237: 28, -1502238: 5, -1502239: 0, -1502240: 5, -1502241: 0, -1502242: 5, -1502243: 0, -1502244: 6, -1502245: 0, -1502246: 72, -1502247: 8, -1502248: 71, -1502249: 4, -1502250: 39, -1502251: 0, -1502252: 6, -1502253: 0, -1502254: 5, -1502255: 0, -1502256: 5, -1502257: 0, -1502258: 5, -1502259: 0, -1502260: 5, -1502261: 0, -1502262: 5, -1502263: 0, -1502264: 72, -1502265: 8, -1502266: 138, -1502267: 4, -1502268: 73, -1502269: 0, -1502270: 6, -1502271: 0, -1502272: 4, -1502273: 0, -1502274: 169, -1502275: 16, -1502276: 103, -1502277: 12, -1502278: 70, -1502279: 8, -1502280: 37, -1502281: 4, -1502282: 106, -1502283: 8, -1502284: 105, -1502285: 8, -1502286: 71, -1502287: 4, -1502288: 38, -1502289: 4, -1502290: 5, -1502291: 0, -1502292: 202, -1502293: 24, -1502294: 4, -1502295: 0, -1502296: 4, -1502297: 0, -1502298: 4, -1502299: 0, -1502300: 5, -1502301: 0, -1502302: 71, -1502303: 4, -1502304: 38, -1502305: 4, -1502306: 38, -1502307: 0, -1502308: 5, -1502309: 0, -1502310: 4, -1502311: 0, -1502312: 4, -1502313: 0, -1502314: 4, -1502315: 0, -1502316: 4, -1502317: 0, -1502318: 4, -1502319: 0, -1502320: 71, -1502321: 4, -1502322: 104, -1502323: 4, -1502324: 39, -1502325: 0, -1502326: 5, -1502327: 0, -1502328: 3, -1502329: 0, -1502330: 135, -1502331: 12, -1502332: 102, -1502333: 8, -1502334: 37, -1502335: 4, -1502336: 4, -1502337: 0, -1502338: 104, -1502339: 4, -1502340: 71, -1502341: 4, -1502342: 38, -1502343: 4, -1502344: 37, -1502345: 0, -1502346: 4, -1502347: 0, -1502348: 136, -1502349: 16, -1502350: 3, -1502351: 0, -1502352: 3, -1502353: 0, -1502354: 3, -1502355: 0, -1502356: 4, -1502357: 0, -1502358: 37, -1502359: 4, -1502360: 37, -1502361: 4, -1502362: 4, -1502363: 0, -1502364: 4, -1502365: 0, -1502366: 3, -1502367: 0, -1502368: 3, -1502369: 0, -1502370: 3, -1502371: 0, -1502372: 3, -1502373: 0, -1502374: 3, -1502375: 0, -1502376: 37, -1502377: 4, -1502378: 70, -1502379: 4, -1502380: 37, -1502381: 0, -1502382: 3, -1502383: 0, -1502384: 2, -1502385: 0, -1502386: 101, -1502387: 8, -1502388: 68, -1502389: 4, -1502390: 36, -1502391: 4, -1502392: 3, -1502393: 0, -1502394: 70, -1502395: 4, -1502396: 37, -1502397: 4, -1502398: 36, -1502399: 0, -1502400: 3, -1502401: 0, -1502402: 3, -1502403: 0, -1502404: 102, -1502405: 12, -1502406: 2, -1502407: 0, -1502408: 2, -1502409: 0, -1502410: 2, -1502411: 0, -1502412: 3, -1502413: 0, -1502414: 36, -1502415: 4, -1502416: 35, -1502417: 0, -1502418: 3, -1502419: 0, -1502420: 3, -1502421: 0, -1502422: 2, -1502423: 0, -1502424: 2, -1502425: 0, -1502426: 2, -1502427: 0, -1502428: 2, -1502429: 0, -1502430: 2, -1502431: 0, -1502432: 36, -1502433: 4, -1502434: 36, -1502435: 0, -1502436: 3, -1502437: 0, -1502438: 2, -1502439: 0, -1502440: 1, -1502441: 0, -1502442: 67, -1502443: 4, -1502444: 35, -1502445: 4, -1502446: 34, -1502447: 0, -1502448: 2, -1502449: 0, -1502450: 36, -1502451: 4, -1502452: 35, -1502453: 0, -1502454: 3, -1502455: 0, -1502456: 2, -1502457: 0, -1502458: 2, -1502459: 0, -1502460: 68, -1502461: 8, -1502462: 1, -1502463: 0, -1502464: 1, -1502465: 0, -1502466: 1, -1502467: 0, -1502468: 2, -1502469: 0, -1502470: 34, -1502471: 0, -1502472: 2, -1502473: 0, -1502474: 2, -1502475: 0, -1502476: 2, -1502477: 0, -1502478: 1, -1502479: 0, -1502480: 1, -1502481: 0, -1502482: 1, -1502483: 0, -1502484: 1, -1502485: 0, -1502486: 1, -1502487: 0, -1502488: 34, -1502489: 0, -1502490: 2, -1502491: 0, -1502492: 1, -1502493: 0, -1502494: 1, -1502495: 0, -1502496: 1, -1502497: 0, -1502498: 33, -1502499: 0, -1502500: 1, -1502501: 0, -1502502: 1, -1502503: 0, -1502504: 1, -1502505: 0, -1502506: 2, -1502507: 0, -1502508: 1, -1502509: 0, -1502510: 1, -1502511: 0, -1502512: 1, -1502513: 0, -1502514: 1, -1502515: 0, -1502516: 34, -1502517: 4, -1502518: 1, -1502519: 0, -1502520: 1, -1502521: 0, -1502522: 1, -1502523: 0, -1502524: 1, -1502525: 0, -1502526: 1, -1502527: 0, -1502528: 1, -1502529: 0, -1502530: 1, -1502531: 0, -1502532: 1, -1502533: 0, -1502534: 1, -1502535: 0, -1502536: 1, -1502537: 0, -1502538: 1, -1502539: 0, -1502540: 1, -1502541: 0, -1502542: 1, -1502543: 0, -1502544: 1, -1502545: 0, -1502546: 0, -1502547: 0, -1502548: 0, -1502549: 0, -1502550: 0, -1502551: 0, -1502552: 0, -1502553: 0, -1502554: 0, -1502555: 0, -1502556: 0, -1502557: 0, -1502558: 0, -1502559: 0, -1502560: 0, -1502561: 0, -1502562: 0, -1502563: 0, -1502564: 0, -1502565: 0, -1502566: 0, -1502567: 0, -1502568: 0, -1502569: 0, -1502570: 0, -1502571: 0, -1502572: 0, -1502573: 0, -1502574: 0, -1502575: 0, -1502576: 0, -1502577: 0, -1502578: 0, -1502579: 0, -1502580: 0, -1502581: 0, -1502582: 0, -1502583: 0, -1502584: 0, -1502585: 0, -1502586: 0, -1502587: 0, -1502588: 0, -1502589: 0, -1502590: 0, -1502591: 0, -1502592: 0, -1502593: 0, -1502594: 0, -1502595: 0, -1502596: 0, -1502597: 0, -1502598: 0, -1502599: 0, -1502600: 0, -1502601: 0, -454047: 34, -454048: 93, -454049: 99, -454050: 68, -454051: 64, -454052: 24, -454057: 1, -454058: 89, -454059: 66, -1502636: 0, -1502637: 0, -1502638: 159, -1502639: 38, -1502640: 89, -1502641: 1, -1502642: 76, -1502643: 0, -1502644: 4, -1502645: 0, -1502646: 57, -1502647: 87, -1502648: 115, -1502649: 66, -1502650: 173, -1502651: 45, -1502652: 198, -1502653: 20, -1502654: 127, -1502655: 54, -1502656: 249, -1502657: 41, -1502658: 115, -1502659: 33, -1502660: 12, -1502661: 21, -1502662: 134, -1502663: 12, -1502664: 36, -1502665: 0, -1502666: 173, -1502667: 41, -1502668: 74, -1502669: 33, -1502670: 231, -1502671: 20, -1502672: 99, -1502673: 12, -1502674: 173, -1502675: 41, -1502676: 190, -1502677: 42, -1502678: 120, -1502679: 9, -1502680: 108, -1502681: 4, -1502682: 36, -1502683: 0, -454108: 68, -454109: 0, -454110: 52, -1502687: 66, -1502688: 173, -1502689: 45, -1502690: 198, -1502691: 20, -1502692: 158, -1502693: 58, -1502694: 24, -1502695: 46, -1502696: 147, -1502697: 37, -1502698: 44, -1502699: 25, -1502700: 166, -1502701: 12, -1502702: 36, -1502703: 0, -1502704: 140, -1502705: 37, -1502706: 41, -1502707: 29, -1502708: 231, -1502709: 20, -1502710: 99, -1502711: 12, -1502712: 140, -1502713: 37, -1502714: 189, -1502715: 50, -1502716: 151, -1502717: 17, -1502718: 172, -1502719: 8, -1502720: 36, -1502721: 4, -1502722: 57, -1502723: 87, -1502724: 115, -1502725: 66, -1502726: 173, -1502727: 45, -1502728: 198, -1502729: 20, -1502730: 189, -1502731: 62, -1502732: 56, -1502733: 50, -1502734: 178, -1502735: 37, -1502736: 76, -1502737: 25, -1502738: 199, -1502739: 16, -1502740: 35, -1502741: 0, -1502742: 107, -1502743: 37, -1502744: 41, -1502745: 29, -1502746: 198, -1502747: 16, -1502748: 99, -1502749: 12, -1502750: 107, -1502751: 37, -1502752: 220, -1502753: 54, -1502754: 182, -1502755: 25, -1502756: 204, -1502757: 12, -1502758: 68, -1502759: 4, -1502760: 57, -1502761: 87, -1502762: 115, -1502763: 66, -1502764: 173, -1502765: 45, -1502766: 198, -1502767: 20, -1502768: 220, -1502769: 66, -1502770: 87, -1502771: 54, -1502772: 210, -1502773: 41, -1502774: 108, -1502775: 29, -1502776: 231, -1502777: 16, -1502778: 35, -1502779: 0, -1502780: 74, -1502781: 33, -1502782: 8, -1502783: 25, -1502784: 198, -1502785: 16, -1502786: 99, -1502787: 12, -1502788: 74, -1502789: 33, -1502790: 251, -1502791: 62, -1502792: 245, -1502793: 33, -1502794: 11, -1502795: 21, -1502796: 101, -1502797: 8, -1502798: 57, -1502799: 87, -1502800: 115, -1502801: 66, -1502802: 173, -1502803: 45, -1502804: 198, -1502805: 20, -1502806: 219, -1502807: 66, -1502808: 86, -1502809: 54, -1502810: 210, -1502811: 45, -1502812: 109, -1502813: 33, -1502814: 232, -1502815: 20, -1502816: 35, -1502817: 0, -1502818: 74, -1502819: 29, -1502820: 231, -1502821: 24, -1502822: 165, -1502823: 16, -1502824: 66, -1502825: 8, -1502826: 74, -1502827: 29, -1502828: 26, -1502829: 67, -1502830: 20, -1502831: 42, -1502832: 43, -1502833: 25, -1502834: 133, -1502835: 8, -1502836: 57, -1502837: 87, -1502838: 115, -1502839: 66, -1502840: 173, -1502841: 45, -1502842: 198, -1502843: 20, -1502844: 250, -1502845: 70, -1502846: 117, -1502847: 58, -1502848: 17, -1502849: 50, -1502850: 141, -1502851: 37, -1502852: 8, -1502853: 21, -1502854: 35, -1502855: 0, -1502856: 41, -1502857: 25, -1502858: 198, -1502859: 20, -1502860: 165, -1502861: 16, -1502862: 66, -1502863: 8, -1502864: 41, -1502865: 25, -1502866: 25, -1502867: 75, -1502868: 51, -1502869: 50, -1502870: 107, -1502871: 29, -1502872: 133, -1502873: 12, -1502874: 57, -1502875: 87, -1502876: 115, -1502877: 66, -1502878: 173, -1502879: 45, -1502880: 198, -1502881: 20, -1502882: 25, -1502883: 75, -1502884: 149, -1502885: 62, -1502886: 17, -1502887: 50, -1502888: 173, -1502889: 37, -1502890: 41, -1502891: 25, -1502892: 34, -1502893: 0, -1502894: 8, -1502895: 25, -1502896: 198, -1502897: 20, -1502898: 132, -1502899: 12, -1502900: 66, -1502901: 8, -1502902: 8, -1502903: 25, -1502904: 56, -1502905: 79, -1502906: 82, -1502907: 58, -1502908: 139, -1502909: 33, -1502910: 165, -1502911: 12, -1502912: 57, -1502913: 87, -1502914: 115, -1502915: 66, -1502916: 173, -1502917: 45, -1502918: 198, -1502919: 20, -1502920: 56, -1502921: 79, -1502922: 180, -1502923: 66, -1502924: 49, -1502925: 54, -1502926: 205, -1502927: 41, -1502928: 73, -1502929: 25, -1502930: 34, -1502931: 0, -1502932: 231, -1502933: 20, -1502934: 165, -1502935: 16, -1502936: 132, -1502937: 12, -1502938: 66, -1502939: 8, -1502940: 231, -1502941: 20, -454366: 76, -454367: 15, -454368: 40, -454369: 9, -454370: 36, -454371: 7, -454372: 28, -454373: 5, -454374: 20, -454375: 3, -454376: 12, -454377: 2, -454378: 8, -454379: 1, -454380: 4, -454385: 22, -454386: 72, -454387: 14, -454388: 36, -454389: 8, -454390: 32, -454391: 6, -454392: 24, -454393: 4, -454394: 16, -454395: 2, -454396: 8, -454397: 1, -454398: 4, -454399: 0, -454400: 0, -454405: 21, -454406: 68, -454407: 13, -454408: 32, -454409: 7, -454410: 28, -454411: 5, -454412: 20, -454413: 3, -454414: 12, -454415: 1, -454416: 4, -454417: 0, -454418: 0, -454419: 0, -454420: 0, -454425: 20, -454426: 64, -454427: 12, -454428: 28, -454429: 6, -454430: 24, -454431: 4, -454432: 16, -454433: 2, -454434: 8, -454435: 0, -454436: 0, -454437: 0, -454438: 0, -454439: 0, -454440: 0, -454445: 19, -454446: 60, -454447: 11, -454448: 24, -454449: 5, -454450: 20, -454451: 3, -454452: 12, -454453: 1, -454454: 4, -454455: 0, -454456: 0, -454457: 0, -454458: 0, -454459: 0, -454460: 0, -454465: 18, -454466: 56, -454467: 10, -454468: 20, -454469: 4, -454470: 16, -454471: 2, -454472: 8, -454473: 0, -454474: 0, -454475: 0, -454476: 0, -454477: 0, -454478: 0, -454479: 0, -454480: 0, -454485: 17, -454486: 52, -454487: 9, -454488: 16, -454489: 3, -454490: 12, -454491: 1, -454492: 4, -454493: 0, -454494: 0, -454495: 0, -454496: 0, -454497: 0, -454498: 0, -454499: 0, -454500: 0, -454505: 16, -454506: 48, -454507: 8, -454508: 12, -454509: 2, -454510: 8, -454511: 0, -454512: 0, -454513: 0, -454514: 0, -454515: 0, -454516: 0, -454517: 0, -454518: 0, -454519: 0, -454520: 0, -454525: 17, -454526: 52, -454527: 9, -454528: 16, -454529: 3, -454530: 12, -454531: 1, -454532: 4, -454533: 0, -454534: 0, -454535: 0, -454536: 0, -454537: 0, -454538: 0, -454539: 0, -454540: 0, -454545: 18, -454546: 56, -454547: 10, -454548: 20, -454549: 4, -454550: 16, -1503127: 0, -1503128: 0, -1503129: 117, -1503130: 44, -1503131: 111, -1503132: 44, -1503133: 41, -1503134: 40, -1503135: 35, -1503136: 40, -1503137: 49, -1503138: 98, -1503139: 173, -1503140: 85, -1503141: 41, -1503142: 73, -1503143: 132, -1503144: 56, -1503145: 181, -1503146: 77, -1503147: 81, -1503148: 69, -1503149: 237, -1503150: 64, -1503151: 168, -1503152: 56, -1503153: 100, -1503154: 48, -1503155: 181, -1503156: 126, -1503157: 0, -1503158: 40, -1503159: 34, -1503160: 20, -1503161: 41, -1503162: 49, -1503163: 231, -1503164: 44, -1503165: 165, -1503166: 36, -1503167: 66, -1503168: 28, -1503169: 107, -1503170: 65, -1503171: 213, -1503172: 48, -1503173: 175, -1503174: 44, -1503175: 105, -1503176: 40, -1503177: 67, -1503178: 36, -1503179: 82, -1503180: 98, -1503181: 206, -1503182: 81, -1503183: 74, -1503184: 69, -1503185: 132, -1503186: 52, -1503187: 245, -1503188: 77, -1503189: 145, -1503190: 69, -1503191: 14, -1503192: 65, -1503193: 201, -1503194: 52, -1503195: 133, -1503196: 44, -1503197: 214, -1503198: 126, -1503199: 0, -1503200: 36, -1503201: 34, -1503202: 16, -1503203: 41, -1503204: 45, -1503205: 231, -1503206: 40, -1503207: 165, -1503208: 32, -1503209: 66, -1503210: 24, -1503211: 74, -1503212: 57, -1503213: 54, -1503214: 53, -1503215: 240, -1503216: 48, -1503217: 138, -1503218: 36, -1503219: 68, -1503220: 32, -1503221: 115, -1503222: 94, -1503223: 239, -1503224: 81, -1503225: 74, -1503226: 65, -1503227: 165, -1503228: 44, -1503229: 22, -1503230: 78, -1503231: 178, -1503232: 69, -1503233: 78, -1503234: 61, -1503235: 9, -1503236: 53, -1503237: 165, -1503238: 40, -1503239: 24, -1503240: 127, -1503241: 0, -1503242: 28, -1503243: 34, -1503244: 16, -1503245: 8, -1503246: 41, -1503247: 198, -1503248: 36, -1503249: 165, -1503250: 28, -1503251: 66, -1503252: 24, -1503253: 74, -1503254: 53, -1503255: 150, -1503256: 57, -1503257: 48, -1503258: 49, -1503259: 202, -1503260: 36, -1503261: 100, -1503262: 28, -1503263: 148, -1503264: 94, -1503265: 16, -1503266: 78, -1503267: 107, -1503268: 61, -1503269: 165, -1503270: 40, -1503271: 86, -1503272: 78, -1503273: 242, -1503274: 69, -1503275: 111, -1503276: 61, -1503277: 42, -1503278: 49, -1503279: 198, -1503280: 36, -1503281: 57, -1503282: 127, -1503283: 0, -1503284: 24, -1503285: 34, -1503286: 12, -1503287: 8, -1503288: 37, -1503289: 198, -1503290: 32, -1503291: 165, -1503292: 24, -1503293: 66, -1503294: 20, -1503295: 41, -1503296: 45, -1503297: 23, -1503298: 66, -1503299: 145, -1503300: 53, -1503301: 234, -1503302: 36, -1503303: 100, -1503304: 24, -1503305: 214, -1503306: 90, -1503307: 16, -1503308: 74, -1503309: 107, -1503310: 57, -1503311: 165, -1503312: 36, -1503313: 151, -1503314: 78, -1503315: 19, -1503316: 66, -1503317: 175, -1503318: 57, -1503319: 75, -1503320: 49, -1503321: 231, -1503322: 36, -1503323: 123, -1503324: 127, -1503325: 0, -1503326: 16, -1503327: 34, -1503328: 8, -1503329: 8, -454754: 84, -1503331: 198, -1503332: 28, -1503333: 132, -454758: 11, -1503335: 66, -1503336: 16, -1503337: 41, -1503338: 41, -1503339: 119, -1503340: 70, -1503341: 209, -1503342: 53, -1503343: 42, -1503344: 37, -1503345: 132, -1503346: 20, -1503347: 247, -1503348: 90, -1503349: 49, -1503350: 70, -1503351: 140, -1503352: 53, -1503353: 165, -1503354: 32, -1503355: 215, -1503356: 78, -1503357: 83, -1503358: 66, -1503359: 208, -1503360: 57, -1503361: 108, -1503362: 45, -1503363: 8, -1503364: 33, -1503365: 156, -1503366: 127, -1503367: 0, -1503368: 12, -1503369: 34, -1503370: 4, -1503371: 8, -1503372: 29, -1503373: 198, -1503374: 24, -1503375: 132, -1503376: 20, -1503377: 66, -1503378: 12, -1503379: 8, -1503380: 33, -1503381: 216, -1503382: 74, -1503383: 18, -1503384: 58, -1503385: 75, -1503386: 33, -1503387: 133, -1503388: 16, -1503389: 24, -1503390: 87, -1503391: 82, -1503392: 70, -1503393: 140, -1503394: 49, -1503395: 198, -1503396: 24, -1503397: 248, -1503398: 78, -1503399: 116, -1503400: 66, -1503401: 16, -1503402: 54, -1503403: 172, -1503404: 45, -1503405: 40, -1503406: 29, -1503407: 222, -1503408: 127, -1503409: 0, -1503410: 4, -1503411: 34, -1503412: 4, -1503413: 231, -1503414: 24, -1503415: 165, -1503416: 20, -1503417: 132, -1503418: 16, -1503419: 66, -1503420: 12, -1503421: 8, -1503422: 29, -1503423: 56, -1503424: 79, -1503425: 82, -1503426: 58, -1503427: 139, -1503428: 33, -1503429: 165, -1503430: 12, -1503431: 57, -1503432: 87, -1503433: 115, -1503434: 66, -1503435: 173, -1503436: 45, -1503437: 198, -1503438: 20, -1503439: 56, -1503440: 79, -1503441: 180, -1503442: 66, -1503443: 49, -1503444: 54, -1503445: 205, -1503446: 41, -1503447: 73, -1503448: 25, -1503449: 255, -1503450: 127, -1503451: 0, -1503452: 0, -1503453: 34, -1503454: 0, -1503455: 231, -1503456: 20, -1503457: 165, -1503458: 16, -1503459: 132, -1503460: 12, -1503461: 66, -1503462: 8, -1503463: 231, -1503464: 20, -1503511: 0, -1503512: 0, -1503513: 159, -1503514: 21, -1503515: 219, -1503516: 0, -1503517: 51, -1503518: 0, -1503519: 14, -1503520: 0, -1503521: 251, -1503522: 49, -1503523: 119, -1503524: 37, -1503525: 244, -1503526: 24, -1503527: 112, -1503528: 12, -1503529: 127, -1503530: 29, -1503531: 59, -1503532: 25, -1503533: 215, -1503534: 16, -1503535: 147, -1503536: 12, -1503537: 80, -1503538: 4, -1503539: 95, -1503540: 74, -1503541: 12, -1503542: 0, -1503543: 222, -1503544: 29, -1503545: 26, -1503546: 9, -1503547: 114, -1503548: 4, -1503549: 45, -1503550: 0, -1503551: 27, -1503552: 54, -1503553: 150, -1503554: 41, -1503555: 19, -1503556: 29, -1503557: 111, -1503558: 12, -1503559: 190, -1503560: 37, -1503561: 122, -1503562: 29, -1503563: 22, -1503564: 21, -1503565: 178, -1503566: 16, -1503567: 111, -1503568: 8, -2175588: 27, -1503570: 82, -1503571: 10, -1503572: 0, -1503573: 29, -1503574: 38, -1503575: 56, -1503576: 17, -1503577: 145, -1503578: 8, -1503579: 43, -1503580: 4, -1503581: 90, -1503582: 62, -1503583: 182, -1503584: 45, -1503585: 50, -1503586: 29, -1503587: 141, -1503588: 16, -1503589: 253, -1503590: 41, -1503591: 153, -1503592: 37, -1503593: 53, -1503594: 29, -1503595: 241, -1503596: 20, -1503597: 142, -1503598: 8, -2175589: 0, -1503600: 90, -1503601: 9, -1503602: 0, -1503603: 92, -1503604: 46, -1503605: 119, -1503606: 25, -1503607: 208, -1503608: 12, -1503609: 74, -1503610: 4, -1503611: 122, -1503612: 66, -1503613: 213, -1503614: 49, -1503615: 81, -1503616: 33, -1503617: 140, -1503618: 16, -1503619: 60, -1503620: 50, -1503621: 216, -1503622: 41, -1503623: 116, -1503624: 33, -1503625: 16, -1503626: 25, -1503627: 173, -1503628: 12, -2175590: 0, -1503630: 99, -1503631: 7, -1503632: 0, -1503633: 123, -1503634: 54, -1503635: 182, -1503636: 33, -1503637: 238, -1503638: 20, -1503639: 105, -1503640: 8, -1503641: 186, -1503642: 70, -1503643: 21, -1503644: 54, -1503645: 80, -1503646: 37, -1503647: 170, -1503648: 16, -1503649: 123, -1503650: 58, -1503651: 23, -1503652: 50, -1503653: 148, -1503654: 37, -1503655: 80, -1503656: 29, -1503657: 236, -1503658: 16, -2175591: 223, -1503660: 103, -1503661: 5, -1503662: 0, -1503663: 186, -1503664: 62, -1503665: 245, -1503666: 41, -1503667: 45, -1503668: 25, -1503669: 136, -1503670: 8, -1503671: 218, -1503672: 74, -1503673: 52, -1503674: 58, -1503675: 111, -1503676: 41, -1503677: 169, -1503678: 16, -1503679: 186, -1503680: 66, -1503681: 86, -1503682: 54, -1503683: 211, -1503684: 41, -1503685: 111, -1503686: 33, -1503687: 11, -1503688: 21, -2175592: 2, -1503690: 111, -1503691: 3, -1503692: 0, -1503693: 249, -1503694: 70, -1503695: 19, -1503696: 50, -1503697: 76, -1503698: 29, -1503699: 134, -1503700: 12, -1503701: 25, -1503702: 83, -1503703: 84, -1503704: 62, -1503705: 142, -1503706: 41, -1503707: 199, -1503708: 20, -1503709: 249, -1503710: 70, -1503711: 117, -1503712: 62, -1503713: 242, -1503714: 49, -1503715: 174, -1503716: 37, -1503717: 42, -1503718: 21, -2175593: 215, -1503720: 119, -1503721: 2, -1503722: 0, -1503723: 56, -1503724: 79, -1503725: 82, -1503726: 58, -1503727: 139, -1503728: 33, -1503729: 165, -1503730: 12, -1503731: 57, -1503732: 87, -1503733: 115, -1503734: 66, -1503735: 173, -1503736: 45, -1503737: 198, -1503738: 20, -1503739: 56, -1503740: 79, -1503741: 180, -1503742: 66, -1503743: 49, -1503744: 54, -1503745: 205, -1503746: 41, -1503747: 73, -1503748: 25, -2175594: 1, -1503750: 127, -1503751: 0, -1503752: 0, -2175596: 0, -1503873: 0, -1503874: 0, -1503875: 178, -1503876: 114, -1503877: 199, -1503878: 113, -1503879: 99, -1503880: 68, -1503881: 22, -1503882: 74, -1503883: 145, -1503884: 57, -1503885: 44, -1503886: 45, -1503887: 167, -1503888: 28, -1503889: 229, -1503890: 32, -1503891: 164, -1503892: 24, -1503893: 131, -1503894: 16, -1503895: 65, -1503896: 8, -1503897: 0, -1503898: 0, -1503899: 0, -1503900: 0, -1503901: 223, -1503902: 2, -1503903: 24, -1503904: 99, -1503905: 24, -1503906: 99, -1503907: 2, -1503908: 8, -1503909: 148, -1503910: 82, -1503911: 206, -1503912: 57, -1503913: 8, -1503914: 33, -1503915: 132, -1503916: 16, -1503917: 25, -1503918: 0, -1503919: 18, -1503920: 0, -1503921: 0, -1503922: 92, -1503923: 0, -1503924: 64, -1503925: 132, -1503926: 16, -1503927: 127, -1503928: 25, -1503929: 255, -1503930: 127, -1503931: 79, -1503932: 98, -1503933: 134, -1503934: 97, -1503935: 66, -1503936: 56, -1503937: 178, -1503938: 61, -1503939: 78, -1503940: 49, -1503941: 234, -1503942: 36, -1503943: 134, -1503944: 24, -1503945: 196, -1503946: 24, -1503947: 131, -1503948: 20, -1503949: 98, -1503950: 12, -1503951: 32, -1503952: 4, -1503953: 0, -1503954: 0, -1503955: 0, -1503956: 0, -1503957: 90, -1503958: 2, -1503959: 148, -1503960: 82, -1503961: 148, -1503962: 82, -1503963: 1, -1503964: 4, -1503965: 49, -1503966: 70, -1503967: 140, -1503968: 49, -1503969: 198, -1503970: 24, -1503971: 99, -1503972: 12, -1503973: 21, -1503974: 0, -1503975: 15, -1503976: 0, -1503977: 0, -1503978: 76, -1503979: 0, -1503980: 52, -1503981: 99, -1503982: 12, -1503983: 58, -1503984: 21, -1503985: 90, -1503986: 107, -1503987: 236, -1503988: 81, -1503989: 69, -1503990: 81, -1503991: 66, -1503992: 48, -1503993: 111, -1503994: 49, -1503995: 12, -1503996: 41, -1503997: 200, -1503998: 28, -1503999: 101, -1504000: 20, -1504001: 163, -1504002: 20, -1504003: 98, -1504004: 16, -1504005: 66, -1504006: 8, -1504007: 32, -1504008: 4, -1504009: 0, -1504010: 0, -1504011: 0, -1504012: 0, -1504013: 246, -1504014: 1, -1504015: 49, -1504016: 70, -1504017: 49, -1504018: 70, -1504019: 1, -1504020: 4, -1504021: 206, -1504022: 57, -1504023: 74, -1504024: 41, -1504025: 165, -1504026: 20, -1504027: 66, -1504028: 8, -1504029: 17, -1504030: 0, -1504031: 12, -1504032: 0, -1504033: 0, -1504034: 64, -1504035: 0, -1504036: 44, -1504037: 66, -1504038: 8, -1504039: 246, -1504040: 16, -1504041: 214, -1504042: 90, -1504043: 138, -1504044: 65, -1504045: 4, -1504046: 65, -1504047: 33, -1504048: 36, -1504049: 44, -1504050: 41, -1504051: 201, -1504052: 32, -1504053: 166, -1504054: 24, -1504055: 68, -1504056: 16, -1504057: 130, -1504058: 16, -1504059: 66, -1504060: 12, -1504061: 65, -1504062: 8, -1504063: 32, -1504064: 4, -1504065: 0, -1504066: 0, -1504067: 0, -1504068: 0, -1504069: 145, -1504070: 1, -1504071: 173, -1504072: 53, -1504073: 173, -1504074: 53, -1504075: 1, -1504076: 4, -1504077: 107, -1504078: 45, -1504079: 8, -1504080: 33, -1504081: 132, -1504082: 16, -1504083: 66, -1504084: 8, -1504085: 14, -1504086: 0, -1504087: 10, -1504088: 0, -1504089: 0, -1504090: 52, -1504091: 0, -1504092: 36, -1504093: 66, -1504094: 8, -1504095: 209, -1504096: 12, -1504097: 49, -1504098: 70, -1504099: 39, -1504100: 49, -1504101: 195, -1504102: 48, -1504103: 33, -1504104: 28, -1504105: 201, -1504106: 28, -1504107: 167, -1504108: 24, -1504109: 101, -1504110: 16, -1504111: 67, -1504112: 12, -1504113: 98, -1504114: 12, -1504115: 65, -1504116: 8, -1504117: 33, -1504118: 4, -1504119: 0, -1504120: 0, -1504121: 0, -1504122: 0, -1504123: 0, -1504124: 0, -1504125: 45, -1504126: 1, -1504127: 74, -1504128: 41, -1504129: 74, -1504130: 41, -1504131: 0, -1504132: 0, -1504133: 8, -1504134: 33, -1504135: 198, -1504136: 24, -1504137: 99, -1504138: 12, -1504139: 33, -1504140: 4, -1504141: 10, -1504142: 0, -1504143: 7, -1504144: 0, -1504145: 0, -1504146: 36, -1504147: 0, -1504148: 24, -1504149: 33, -1504150: 4, -1504151: 141, -1504152: 8, -1504153: 173, -1504154: 53, -1504155: 197, -1504156: 32, -1504157: 130, -1504158: 32, -1504159: 0, -1504160: 16, -1504161: 134, -1504162: 20, -1504163: 100, -1504164: 16, -1504165: 67, -1504166: 12, -1504167: 34, -1504168: 8, -1504169: 65, -1504170: 8, -1504171: 33, -1504172: 4, -1504173: 32, -1504174: 4, -1504175: 0, -1504176: 0, -1504177: 0, -1504178: 0, -1504179: 0, -1504180: 0, -1504181: 200, -1504182: 0, -1504183: 198, -1504184: 24, -1504185: 198, -1504186: 24, -1504187: 0, -1504188: 0, -1504189: 165, -1504190: 20, -1504191: 132, -1504192: 16, -1504193: 66, -1504194: 8, -1504195: 33, -1504196: 4, -1504197: 7, -1504198: 0, -1504199: 5, -1504200: 0, -1504201: 0, -1504202: 24, -1504203: 0, -1504204: 16, -1504205: 33, -1504206: 4, -1504207: 104, -1504208: 4, -1504209: 8, -1504210: 33, -1504211: 98, -1504212: 16, -1504213: 65, -1504214: 16, -1504215: 0, -1504216: 8, -1504217: 67, -1504218: 8, -1504219: 34, -1504220: 8, -1504221: 33, -1504222: 4, -1504223: 1, -1504224: 4, -1504225: 32, -1504226: 4, -1504227: 0, -1504228: 0, -1504229: 0, -1504230: 0, -1504231: 0, -1504232: 0, -1504233: 0, -1504234: 0, -1504235: 0, -1504236: 0, -1504237: 100, -1504238: 0, -1504239: 99, -1504240: 12, -1504241: 99, -1504242: 12, -1504243: 0, -1504244: 0, -1504245: 66, -1504246: 8, -1504247: 66, -1504248: 8, -1504249: 33, -1504250: 4, -1504251: 0, -1504252: 0, -1504253: 3, -1504254: 0, -1504255: 2, -1504256: 0, -1504257: 0, -1504258: 12, -1504259: 0, -1504260: 8, -1504261: 0, -1504262: 0, -1504263: 36, -1504264: 0, -1504265: 132, -1504266: 16, -892443: 99, -892449: 56, -455919: 217, -455920: 62, -455921: 87, -455922: 46, -455923: 53, -455924: 42, -455925: 243, -455926: 37, -455927: 210, -455928: 37, -455929: 176, -455930: 29, -455931: 110, -455932: 25, -455933: 46, -455934: 17, -455939: 87, -455940: 46, -455941: 53, -455942: 42, -455943: 243, -455944: 37, -455945: 217, -455946: 62, -455947: 176, -455948: 29, -455949: 110, -455950: 25, -455951: 46, -455952: 17, -455953: 210, -455954: 37, -455959: 53, -455960: 42, -455961: 243, -455962: 37, -455963: 217, -455964: 62, -455965: 87, -455966: 46, -455967: 110, -455968: 25, -455969: 46, -455970: 17, -455971: 210, -455972: 37, -455973: 176, -455974: 29, -455979: 243, -455980: 37, -455981: 217, -455982: 62, -455983: 87, -455984: 46, -455985: 53, -455986: 42, -455987: 46, -455988: 17, -455989: 210, -455990: 37, -455991: 176, -455992: 29, -455993: 110, -455994: 25, -456007: 210, -456008: 37, -456009: 176, -456010: 29, -456011: 110, -456012: 25, -456013: 46, -456014: 17, -456019: 176, -456020: 29, -456021: 110, -456022: 25, -456023: 46, -456024: 17, -456025: 210, -456026: 37, -456031: 110, -456032: 25, -456033: 46, -456034: 17, -456035: 210, -456036: 37, -456037: 176, -456038: 29, -456043: 46, -456044: 17, -456045: 210, -456046: 37, -456047: 176, -456048: 29, -456049: 110, -456050: 25, -456063: 0, -456064: 4, -456065: 34, -456066: 12, -456067: 100, -456068: 24, -456069: 134, -456070: 32, -456071: 201, -456072: 44, -456073: 101, -456074: 28, -456075: 67, -456076: 16, -456077: 33, -456078: 8, -456083: 34, -456084: 12, -456085: 100, -456086: 24, -456087: 134, -456088: 32, -456089: 201, -456090: 44, -456091: 101, -456092: 28, -456093: 67, -456094: 16, -456095: 33, -456096: 8, -456097: 0, -456098: 4, -456103: 100, -456104: 24, -456105: 134, -456106: 32, -456107: 201, -456108: 44, -456109: 101, -456110: 28, -456111: 67, -456112: 16, -456113: 33, -456114: 8, -456115: 0, -456116: 4, -456117: 34, -456118: 12, -456123: 134, -456124: 32, -456125: 201, -456126: 44, -456127: 101, -456128: 28, -456129: 67, -456130: 16, -456131: 33, -456132: 8, -456133: 0, -456134: 4, -456135: 34, -456136: 12, -456137: 100, -456138: 24, -456143: 201, -456144: 44, -456145: 101, -456146: 28, -456147: 67, -456148: 16, -456149: 33, -456150: 8, -456151: 0, -456152: 4, -456153: 34, -456154: 12, -456155: 100, -456156: 24, -456157: 134, -456158: 32, -456163: 101, -456164: 28, -456165: 67, -456166: 16, -456167: 33, -456168: 8, -456169: 0, -456170: 4, -456171: 34, -456172: 12, -456173: 100, -456174: 24, -456175: 134, -456176: 32, -456177: 201, -456178: 44, -456183: 67, -456184: 16, -456185: 33, -456186: 8, -456187: 0, -456188: 4, -456189: 34, -456190: 12, -456191: 100, -456192: 24, -456193: 134, -456194: 32, -456195: 201, -456196: 44, -456197: 101, -456198: 28, -456203: 33, -456204: 8, -456205: 0, -456206: 4, -456207: 34, -456208: 12, -456209: 100, -456210: 24, -456211: 134, -456212: 32, -456213: 201, -456214: 44, -456215: 101, -456216: 28, -456217: 67, -456218: 16, -892461: 87, -456256: 25, -456257: 0, -456258: 18, -456259: 0, -456260: 0, -456261: 92, -456262: 0, -456263: 64, -456264: 132, -456265: 16, -456266: 127, -456267: 25, -456268: 255, -456269: 127, -456278: 22, -456279: 0, -456280: 15, -456281: 0, -456282: 0, -456283: 80, -456284: 0, -456285: 52, -456286: 132, -456287: 16, -456288: 28, -456289: 13, -456290: 156, -456291: 115, -456300: 19, -456301: 0, -456302: 12, -456303: 0, -456304: 0, -456305: 68, -456306: 0, -456307: 40, -456308: 132, -456309: 16, -456310: 185, -456311: 0, -456312: 57, -456313: 103, -456322: 16, -456323: 0, -456324: 9, -456325: 0, -456326: 0, -456327: 56, -456328: 0, -456329: 28, -456330: 132, -456331: 16, -456332: 86, -456333: 0, -456334: 214, -456335: 90, -456344: 13, -456345: 0, -456346: 6, -456347: 0, -456348: 0, -456349: 44, -456350: 0, -456351: 16, -456352: 132, -456353: 16, -456354: 19, -456355: 0, -456356: 115, -456357: 78, -456366: 10, -456367: 0, -456368: 3, -456369: 0, -456370: 0, -456371: 32, -456372: 0, -456373: 4, -456374: 132, -456375: 16, -456376: 16, -456377: 0, -456378: 16, -456379: 66, -456388: 10, -456389: 0, -456390: 3, -456391: 0, -456392: 0, -456393: 32, -456394: 0, -456395: 4, -456396: 132, -456397: 16, -456398: 16, -456399: 0, -456400: 16, -1373905: 255, -1373906: 114, -1373907: 223, -1373908: 44, -1373909: 185, -1373910: 36, -1373911: 175, -1373912: 28, -1373913: 95, -1373914: 94, -1373915: 63, -1373916: 24, -1373917: 20, -1373918: 16, -1373919: 10, -1373920: 8, -1373921: 186, -1373922: 73, -1373923: 26, -1373924: 4, -1373925: 15, -1373926: 0, -1373927: 5, -1373928: 0, -1373929: 21, -1373930: 53, -1373931: 21, -1373932: 0, -1373933: 10, -1373934: 0, -1373935: 5, -456432: 16, -456433: 0, -1373938: 53, -456435: 0, -1373940: 0, -1373941: 10, -1373942: 0, -1373943: 5, -1373944: 0, -1373945: 186, -1373946: 73, -1373947: 26, -1373948: 4, -1373949: 15, -1373950: 0, -1373951: 5, -1373952: 0, -1373953: 95, -1373954: 94, -1373955: 63, -1373956: 24, -1373957: 20, -1373958: 16, -1373959: 10, -1373960: 8, -1373961: 255, -1373962: 114, -1373963: 223, -1373964: 44, -1373965: 185, -1373966: 36, -1373967: 175, -1373968: 28, -1373969: 144, -1373970: 89, -1373971: 112, -1373972: 56, -1373973: 109, -1373974: 52, -1373975: 104, -1373976: 48, -1373977: 77, -1373978: 73, -1373979: 109, -1373980: 48, -1373981: 74, -1373982: 40, -1373983: 70, -1373984: 36, -1373985: 11, -1373986: 61, -1373987: 75, -1373988: 36, -1373989: 72, -1373990: 32, -1373991: 68, -1373992: 24, -1373993: 200, -1373994: 44, -1373995: 72, -1373996: 28, -1373997: 37, -1373998: 20, -1373999: 34, -1374000: 12, -1374001: 200, -1374002: 44, -1374003: 72, -1374004: 28, -1374005: 37, -1374006: 20, -1374007: 34, -1374008: 12, -1374009: 11, -1374010: 61, -1374011: 75, -1374012: 36, -1374013: 72, -1374014: 32, -1374015: 68, -1374016: 24, -1374017: 77, -1374018: 73, -1374019: 109, -1374020: 48, -1374021: 74, -1374022: 40, -1374023: 70, -1374024: 36, -1374025: 144, -1374026: 89, -1374027: 112, -1374028: 56, -1374029: 109, -1374030: 52, -1374031: 104, -1374032: 48, -456623: 148, -456624: 82, -456625: 16, -456626: 66, -456627: 140, -456628: 49, -456629: 8, -456630: 33, -456631: 132, -456632: 16, -456633: 255, -456634: 127, -456639: 117, -456640: 78, -456641: 241, -456642: 61, -456643: 109, -456644: 45, -456645: 232, -456646: 28, -456647: 100, -456648: 12, -456649: 191, -456650: 119, -456655: 85, -456656: 74, -456657: 209, -456658: 57, -456659: 109, -456660: 45, -456661: 232, -456662: 28, -456663: 100, -456664: 12, -456665: 159, -456666: 115, -456671: 54, -456672: 70, -456673: 178, -456674: 53, -456675: 77, -456676: 41, -456677: 201, -456678: 24, -456679: 68, -456680: 8, -456681: 95, -456682: 107, -456687: 246, -456688: 61, -456689: 146, -456690: 49, -456691: 45, -456692: 37, -456693: 169, -456694: 20, -456695: 68, -456696: 8, -456697: 63, -456698: 103, -456703: 215, -456704: 57, -456705: 114, -456706: 45, -456707: 14, -456708: 33, -456709: 137, -456710: 16, -456711: 36, -456712: 4, -456713: 255, -456714: 94, -456719: 183, -456720: 53, -456721: 82, -456722: 41, -456723: 238, -456724: 28, -456725: 137, -456726: 16, -456727: 36, -456728: 4, -456729: 223, -456730: 90, -456735: 152, -456736: 49, -456737: 51, -456738: 37, -456739: 206, -456740: 24, -456741: 105, -456742: 12, -456743: 4, -456744: 0, -456745: 159, -456746: 82, -456751: 183, -456752: 53, -456753: 82, -456754: 41, -456755: 238, -456756: 28, -456757: 137, -456758: 16, -456759: 36, -456760: 4, -456761: 223, -456762: 90, -456767: 215, -456768: 57, -456769: 114, -456770: 45, -456771: 14, -456772: 33, -456773: 137, -456774: 16, -456775: 36, -456776: 4, -456777: 255, -456778: 94, -456783: 246, -456784: 61, -456785: 146, -456786: 49, -456787: 45, -456788: 37, -456789: 169, -456790: 20, -456791: 68, -456792: 8, -456793: 63, -456794: 103, -456799: 54, -456800: 70, -456801: 178, -456802: 53, -456803: 77, -456804: 41, -456805: 201, -456806: 24, -456807: 68, -456808: 8, -456809: 95, -456810: 107, -456815: 85, -456816: 74, -456817: 209, -456818: 57, -456819: 109, -456820: 45, -456821: 232, -456822: 28, -456823: 100, -456824: 12, -456825: 159, -456826: 115, -456831: 117, -456832: 78, -456833: 241, -456834: 61, -456835: 109, -456836: 45, -456837: 232, -456838: 28, -456839: 100, -456840: 12, -456841: 191, -456842: 119, -456855: 26, -456856: 8, -456857: 18, -456858: 8, -456859: 43, -456860: 4, -456861: 35, -456862: 4, -456867: 55, -456868: 12, -456869: 48, -456870: 12, -456871: 42, -456872: 4, -456873: 35, -456874: 4, -456879: 84, -456880: 16, -456881: 46, -456882: 12, -456883: 73, -456884: 8, -456885: 34, -456886: 4, -456891: 113, -456892: 20, -456893: 76, -456894: 16, -456895: 72, -456896: 8, -456897: 34, -456898: 4, -456903: 142, -456904: 20, -456905: 106, -456906: 16, -456907: 102, -456908: 12, -456909: 66, -456910: 8, -456915: 171, -456916: 24, -456917: 136, -456918: 20, -456919: 101, -456920: 12, -456921: 66, -456922: 8, -456927: 200, -456928: 28, -456929: 134, -456930: 20, -456931: 132, -456932: 16, -456933: 65, -1374438: 0, -1374439: 56, -1374440: 184, -1374441: 87, -1374442: 17, -1374443: 11, -1374444: 70, -1374445: 22, -1374446: 227, -1374447: 0, -1374448: 255, -1374449: 114, -1374450: 223, -1374451: 44, -1374452: 185, -1374453: 36, -1374454: 175, -1374455: 28, -1374456: 169, -1374457: 24, -1374458: 159, -1374459: 79, -1374460: 216, -1374461: 62, -456958: 8, -1374463: 46, -1374464: 205, -1374465: 8, -1374466: 255, -1374467: 127, -1374468: 0, -1374469: 0, -456966: 20, -456967: 101, -456968: 12, -456969: 66, -456970: 8, -456975: 142, -456976: 20, -456977: 106, -456978: 16, -456979: 102, -456980: 12, -456981: 66, -456982: 8, -456987: 113, -456988: 20, -456989: 76, -456990: 16, -456991: 72, -456992: 8, -456993: 34, -456994: 4, -456999: 84, -457000: 16, -457001: 46, -457002: 12, -457003: 73, -457004: 8, -457005: 34, -457006: 4, -457011: 55, -457012: 12, -457013: 48, -457014: 12, -457015: 42, -457016: 4, -457017: 35, -457018: 4, -457039: 148, -457040: 82, -457041: 206, -457042: 57, -457043: 8, -457044: 33, -457045: 132, -457046: 16, -457047: 25, -457048: 0, -457049: 18, -457050: 0, -457059: 117, -457060: 78, -457061: 175, -457062: 53, -457063: 232, -457064: 28, -457065: 100, -457066: 12, -457067: 13, -457068: 8, -457069: 9, -457070: 8, -457079: 85, -457080: 74, -457081: 143, -457082: 49, -457083: 233, -457084: 28, -457085: 100, -457086: 12, -457087: 0, -457088: 16, -457089: 0, -457090: 16, -457099: 54, -457100: 70, -457101: 112, -457102: 45, -457103: 201, -457104: 24, -457105: 68, -457106: 8, -457107: 13, -457108: 8, -457109: 9, -457110: 8, -457119: 246, -457120: 61, -457121: 112, -457122: 45, -457123: 202, -457124: 24, -457125: 68, -457126: 8, -457127: 25, -457128: 0, -457129: 18, -457130: 0, -457139: 215, -457140: 57, -457141: 81, -457142: 41, -457143: 170, -457144: 20, -457145: 36, -457146: 4, -457147: 13, -457148: 8, -457149: 9, -457150: 8, -457159: 183, -457160: 53, -457161: 49, -457162: 37, -457163: 171, -457164: 20, -457165: 36, -457166: 4, -457167: 0, -457168: 16, -457169: 0, -457170: 16, -457179: 152, -457180: 49, -457181: 18, -457182: 33, -457183: 139, -457184: 16, -457185: 4, -457186: 0, -457187: 13, -457188: 8, -457189: 9, -457190: 8, -457199: 183, -457200: 53, -457201: 49, -457202: 37, -457203: 171, -457204: 20, -457205: 36, -457206: 4, -457207: 0, -457208: 16, -457209: 0, -457210: 16, -457219: 215, -457220: 57, -457221: 81, -457222: 41, -457223: 170, -457224: 20, -457225: 36, -457226: 4, -457227: 13, -457228: 8, -457229: 9, -457230: 8, -457239: 246, -457240: 61, -457241: 112, -457242: 45, -457243: 202, -457244: 24, -457245: 68, -457246: 8, -457247: 25, -457248: 0, -457249: 18, -457250: 0, -457259: 54, -457260: 70, -457261: 112, -457262: 45, -457263: 201, -457264: 24, -457265: 68, -457266: 8, -457267: 13, -457268: 8, -457269: 9, -457270: 8, -457279: 85, -457280: 74, -457281: 143, -457282: 49, -457283: 233, -457284: 28, -457285: 100, -457286: 12, -457287: 0, -457288: 16, -457289: 0, -457290: 16, -457299: 117, -457300: 78, -457301: 175, -457302: 53, -457303: 232, -457304: 28, -457305: 100, -457306: 12, -457307: 13, -457308: 8, -457309: 9, -457310: 8, -892503: 1, -892509: 21, -457987: 137, -457988: 29, -457989: 6, -457990: 13, -457991: 163, -457992: 12, -457993: 14, -457994: 45, -457995: 9, -457996: 45, -457997: 197, -457998: 40, -457999: 129, -458000: 12, -458005: 138, -458006: 29, -458007: 7, -458008: 13, -458009: 164, -458010: 12, -458011: 14, -458012: 45, -458013: 9, -458014: 45, -458015: 197, -458016: 40, -458017: 33, -458018: 4, -458023: 138, -458024: 29, -458025: 40, -458026: 13, -458027: 196, -458028: 12, -458029: 15, -458030: 45, -458031: 10, -458032: 45, -458033: 198, -458034: 40, -458035: 35, -458036: 4, -458041: 139, -458042: 29, -458043: 41, -458044: 13, -458045: 197, -458046: 12, -458047: 15, -458048: 45, -458049: 10, -458050: 45, -458051: 198, -458052: 40, -458053: 36, -458054: 4, -458059: 171, -458060: 29, -458061: 73, -458062: 17, -458063: 197, -458064: 16, -458065: 15, -458066: 45, -458067: 11, -458068: 45, -458069: 199, -458070: 40, -458071: 69, -458072: 8, -458077: 172, -458078: 29, -458079: 74, -458080: 17, -458081: 198, -458082: 16, -458083: 15, -458084: 45, -458085: 11, -458086: 45, -458087: 199, -458088: 40, -458089: 70, -458090: 8, -458095: 172, -458096: 29, -458097: 107, -458098: 17, -458099: 230, -458100: 16, -458101: 16, -458102: 45, -458103: 12, -458104: 45, -458105: 200, -458106: 40, -458107: 72, -458108: 8, -458113: 173, -458114: 29, -458115: 108, -2175692: 97, -458117: 231, -458118: 16, -458119: 16, -458120: 45, -458121: 12, -458122: 45, -458123: 200, -458124: 40, -458125: 21, -458126: 0, -458131: 172, -458132: 29, -458133: 107, -458134: 17, -458135: 230, -458136: 16, -458137: 16, -458138: 45, -458139: 12, -458140: 45, -458141: 200, -458142: 40, -458143: 72, -458144: 8, -458149: 172, -458150: 29, -458151: 74, -458152: 17, -458153: 198, -458154: 16, -458155: 15, -458156: 45, -458157: 11, -458158: 45, -458159: 199, -458160: 40, -458161: 70, -458162: 8, -458167: 171, -458168: 29, -458169: 73, -458170: 17, -458171: 197, -458172: 16, -458173: 15, -458174: 45, -458175: 11, -458176: 45, -458177: 199, -458178: 40, -458179: 69, -458180: 8, -458185: 139, -458186: 29, -458187: 41, -458188: 13, -458189: 197, -458190: 12, -458191: 15, -458192: 45, -458193: 10, -458194: 45, -458195: 198, -458196: 40, -458197: 36, -458198: 4, -458203: 138, -458204: 29, -458205: 40, -458206: 13, -458207: 196, -458208: 12, -458209: 15, -458210: 45, -458211: 10, -458212: 45, -458213: 198, -458214: 40, -458215: 35, -458216: 4, -458221: 138, -458222: 29, -458223: 7, -458224: 13, -458225: 164, -458226: 12, -458227: 14, -458228: 45, -458229: 9, -458230: 45, -458231: 197, -458232: 40, -458233: 33, -458234: 4, -852394: 29, -852395: 124, -852396: 20, -852397: 88, -852398: 10, -852399: 48, -1321731: 66, -1321737: 79, -1321743: 29, -1321755: 0, -1115783: 0, -1115784: 56, -1640073: 85, -1640074: 87, -1640075: 79, -1640076: 74, -1640077: 228, -1640078: 28, -1640079: 96, -1640080: 12, -1640081: 178, -1640082: 86, -1640083: 13, -1640084: 62, -1640085: 104, -1640086: 45, -1640087: 38, -1640088: 37, -1640089: 187, -1640090: 94, -1640091: 179, -1640092: 61, -1640093: 46, -1640094: 41, -1115807: 0, -1640096: 20, -1640097: 59, -1640098: 3, -1246883: 247, -1640100: 2, -1246885: 0, -1246886: 0, -1640103: 0, -1640104: 56, -1640105: 87, -1640106: 63, -1640107: 77, -1640108: 46, -1640109: 226, -1640110: 0, -1640111: 96, -1640112: 0, -1640113: 176, -1640114: 58, -1640115: 11, -1640116: 34, -1640117: 102, -1640118: 17, -1640119: 36, -1640120: 9, -1640121: 187, -1640122: 94, -1640123: 179, -1640124: 61, -1640125: 46, -1640126: 41, -1640127: 134, -1640128: 20, -1640129: 59, -1640130: 3, -1640131: 22, -1640132: 2, -1640133: 19, -1640134: 1, -1640135: 0, -1640136: 56, -1640137: 191, -1640138: 78, -1640139: 158, -1640140: 77, -1640141: 9, -1640142: 16, -1640143: 4, -1378000: 20, -1640145: 222, -1640146: 73, -1378003: 87, -1640148: 85, -1640149: 176, -1640150: 48, -1640151: 77, -1640152: 28, -1378009: 127, -1640154: 94, -1640155: 179, -1640156: 61, -1640157: 46, -1640158: 41, -1378015: 95, -1378016: 95, -1378017: 26, -1640162: 3, -1378019: 53, -1378020: 93, -1378021: 99, -1378022: 12, -1378023: 0, -1378024: 56, -1378025: 186, -1378026: 74, -1378027: 178, -1378028: 53, -1378029: 71, -1378030: 8, -1378031: 3, -1378032: 0, -1378033: 21, -1378034: 66, -1378035: 112, -1378036: 41, -1378037: 203, -1378038: 24, -1378039: 137, -1378040: 16, -1378041: 58, -1378042: 70, -1640187: 179, -1378044: 40, -1378045: 9, -1378046: 24, -1378047: 127, -1378048: 111, -1378049: 253, -1378050: 81, -1378051: 19, -1378052: 65, -1378053: 99, -1378054: 12, -1378055: 0, -1378056: 56, -1378057: 186, -1378058: 86, -1378059: 178, -1378060: 65, -1378061: 71, -1378062: 20, -1378063: 3, -1378064: 4, -1378065: 21, -1378066: 78, -1378067: 112, -1378068: 53, -1378069: 203, -1378070: 36, -1378071: 104, -1378072: 24, -1378073: 127, -1378074: 111, -1378075: 248, -1378076: 81, -1378077: 14, -1378078: 65, -1378079: 31, -1378080: 3, -1378081: 218, -1378082: 1, -1378083: 245, -1378084: 0, -1378085: 99, -1378086: 12, -1378087: 0, -1378088: 56, -1378089: 21, -1378090: 66, -1378091: 13, -1378092: 45, -1378093: 2, -1378094: 0, -1378095: 0, -1378096: 0, -1378097: 112, -1378098: 57, -1378099: 203, -1378100: 32, -1378101: 38, -1378102: 12, -1378103: 3, -1378104: 4, -1378105: 58, -1378106: 70, -1378107: 179, -1378108: 40, -1378109: 9, -1378110: 24, -1378111: 127, -1378112: 111, -1378113: 253, -1378114: 81, -1378115: 19, -1378116: 65, -1378117: 99, -1378118: 12, -1378119: 0, -1378120: 56, -1378121: 181, -1378122: 106, -1378123: 176, -1378124: 73, -1378125: 69, -1378126: 28, -1378127: 1, -1378128: 12, -1378129: 19, -1378130: 86, -1378131: 109, -1378132: 65, -1378133: 201, -1378134: 44, -1378135: 102, -1378136: 32, -1378137: 20, -1378138: 87, -1378139: 204, -1378140: 49, -1378141: 227, -1378142: 20, -1378143: 48, -1378144: 86, -1378145: 105, -1378146: 53, -1378147: 131, -1378148: 24, -1378149: 102, -1378150: 12, -1378151: 0, -1378152: 56, -1378153: 16, -1378154: 86, -1378155: 11, -1378156: 53, -1378157: 0, -1378158: 8, -1378159: 0, -1378160: 0, -1378161: 110, -1378162: 65, -1378163: 200, -1378164: 44, -1378165: 35, -1378166: 24, -1378167: 1, -1378168: 12, -1378169: 49, -1378170: 106, -1378171: 170, -1378172: 76, -1378173: 6, -1378174: 36, -1378175: 123, -1378176: 127, -1378177: 244, -1378178: 117, -1378179: 16, -1378180: 77, -1378181: 99, -1378182: 12, -1378183: 0, -1378184: 56, -1378185: 190, -1378186: 75, -1378187: 185, -1378188: 6, -1378189: 168, -1378190: 0, -1378191: 0, -1378192: 0, -1378193: 58, -1378194: 23, -1378195: 118, -1378196: 2, -1378197: 242, -1378198: 1, -1378199: 77, -1378200: 1, -1378201: 224, -1378202: 115, -1378203: 32, -1378204: 79, -1378205: 32, -1378206: 42, -1378207: 224, -1378208: 127, -1378209: 160, -1378210: 90, -1378211: 32, -1378212: 89, -1378213: 67, -1378214: 0, -1378215: 0, -1378216: 56, -1378217: 25, -1378218: 55, -1378219: 20, -1378220: 2, -1378221: 3, -1378222: 0, -1378223: 0, -1378224: 0, -1378225: 149, -1378226: 2, -1378227: 209, -1378228: 1, -1378229: 77, -1378230: 1, -1378231: 168, -1378232: 0, -1378233: 64, -1378234: 75, -1378235: 224, -1378236: 37, -1378237: 224, -1378238: 0, -1378239: 64, -1378240: 107, -1378241: 0, -1378242: 70, -1378243: 128, -1378244: 68, -1378245: 0, -1378246: 0, -1117024: 0, -1117025: 56, -1117026: 156, -1117027: 75, -1117028: 148, -1117029: 54, -1117030: 231, -1117031: 8, -1117032: 132, -1117033: 8, -1117034: 247, -1117035: 66, -1117036: 82, -1117037: 42, -1117038: 173, -1117039: 25, -1117040: 41, -1117041: 17, -1117042: 255, -1117043: 127, -1117044: 59, -1117045: 3, -1117046: 22, -1117047: 2, -1117048: 19, -1117049: 1, -1117050: 255, -1117051: 127, -1117052: 255, -1117053: 3, -1117054: 13, -1117055: 0, -1503689: 127, -1120653: 0, -1120654: 56, -1120655: 156, -1120656: 75, -1120657: 16, -1120658: 38, -1120659: 198, -1120660: 12, -1120661: 99, -1120662: 12, -1120663: 247, -1120664: 66, -1120665: 82, -1120666: 42, -1120667: 173, -1120668: 25, -1120669: 41, -1120670: 13, -1120671: 23, -1120672: 86, -1120673: 114, -1120674: 61, -1120675: 72, -1120676: 28, -1120677: 5, -1120678: 12, -1120679: 59, -1120680: 3, -1120681: 22, -1120682: 2, -1120683: 19, -1120684: 1, -1121898: 0, -1121899: 56, -1121900: 87, -1121901: 63, -1121902: 77, -1121903: 46, -1121904: 226, -1121905: 0, -1121906: 96, -1121907: 0, -1121908: 176, -1121909: 58, -1121910: 11, -1121911: 34, -1121912: 102, -1121913: 17, -1121914: 36, -1121915: 9, -1121916: 255, -1121917: 87, -1121918: 247, -1121919: 66, -1121920: 16, -1121921: 38, -1121922: 140, -1121923: 21, -1121924: 127, -1121925: 1, -1121926: 22, -1121927: 0, -1121928: 10, -1121929: 48, -2174963: 115, -2174964: 78, -2174965: 173, -2174966: 53, -2174967: 231, -2174968: 28, -2174969: 99, -2174970: 12, -2174971: 24, -2174972: 99, -2174973: 4, -2174974: 8, -2174975: 255, -2174976: 127, -2174977: 35, -2174978: 0, -2174979: 69, -2174980: 24, -2174981: 99, -2174982: 7, -2174983: 82, -2174984: 25, -2174985: 171, -2174986: 24, -2174987: 103, -2174988: 20, -2174989: 68, -2174990: 16, -2174991: 75, -2174992: 24, -2174993: 99, -2174994: 195, -1123211: 0, -1123212: 56, -1123213: 156, -1123214: 75, -1123215: 16, -1123216: 38, -1123217: 198, -1123218: 12, -1123219: 99, -1123220: 12, -1123221: 247, -1123222: 66, -1123223: 82, -1123224: 42, -1123225: 173, -1123226: 25, -1123227: 41, -1123228: 13, -1123229: 89, -1123230: 94, -1123231: 114, -1123232: 61, -1123233: 238, -1123234: 44, -1123235: 71, -1123236: 20, -1123237: 59, -1123238: 3, -1123239: 22, -1123240: 2, -1123241: 19, -1123242: 1, -1123742: 0, -1123743: 56, -1123744: 149, -1123745: 2, -1123746: 144, -1123747: 1, -1123748: 3, -1123749: 4, -1123750: 1, -1123751: 0, -1123752: 17, -1123753: 2, -1123754: 77, -1123755: 1, -1123756: 201, -1123757: 0, -1123758: 36, -1123759: 0, -1123760: 224, -1123761: 59, -1123762: 128, -1123763: 38, -1123764: 128, -1123765: 21, -1123766: 198, -1123767: 36, -1123768: 66, -1123769: 20, -1123770: 0, -1123771: 0, -1123772: 0, -1123773: 0, -1148551: 0, -1148552: 56, -1148553: 250, -1148554: 114, -1148555: 176, -1148556: 85, -1148557: 69, -1148558: 40, -1148559: 1, -1148560: 24, -1148561: 16, -1148562: 98, -1148563: 107, -1148564: 73, -1148565: 198, -1148566: 56, -1148567: 99, -1148568: 44, -1148569: 31, -1148570: 36, -1148571: 23, -1148572: 28, -1148573: 47, -1148574: 20, -1148575: 71, -1148576: 12, -1148577: 224, -1148578: 59, -1148579: 128, -1148580: 38, -1148581: 128, -1148582: 21, -456464: 185, -456465: 0, -456466: 57, -456467: 103, -2175500: 33, -2175501: 0, -2175502: 173, -2175503: 85, -2175504: 231, -2175505: 56, -2175506: 33, -2175507: 32, -2175508: 0, -2175509: 16, -2175510: 33, -1126935: 2, -2175512: 231, -1126937: 1, -2175514: 82, -2175515: 74, -2175516: 35, -2175517: 0, -2175518: 4, -2175519: 163, -2175520: 1, -2175521: 3, -2175522: 1, -1126947: 29, -1126948: 37, -1126949: 9, -2175526: 1, -2175527: 8, -2175528: 66, -2175529: 34, -2175530: 0, -2175531: 13, -456476: 22, -456477: 0, -456478: 15, -456479: 0, -2174332: 27, -2174333: 0, -2174334: 0, -2174335: 223, -2174336: 2, -2174337: 215, -2174338: 1, -2174339: 172, -2174340: 0, -2174341: 245, -2174342: 93, -2174343: 14, -2174344: 61, -2174345: 170, -2174346: 40, -2174347: 35, -2174348: 20, -2174349: 177, -2174350: 11, -2174351: 251, -2174352: 72, -2174353: 255, -2174354: 127, -2174355: 0, -2174356: 0, -2174357: 255, -2174358: 127, -2174359: 229, -2174360: 68, -2174361: 195, -2174362: 8, -2174363: 21, -2174364: 99, -2174365: 68, -2174366: 177, -2174367: 11, -2174368: 169, -2174369: 30, -2174370: 69, -2174371: 1, -2174372: 187, -2174373: 94, -2174374: 179, -2174375: 61, -2174376: 46, -2174377: 41, -2174378: 134, -2174379: 20, -2174380: 24, -2174381: 99, -2174382: 231, -2174383: 28, -2174384: 132, -2174385: 16, -2174386: 195, -2174387: 32, -2174388: 2, -2174389: 223, -2174390: 2, -2174391: 31, -2174392: 34, -2174393: 0, -2174394: 29, -2174395: 99, -2174396: 68, -2174397: 188, -2174398: 114, -2174399: 251, -2174400: 72, -2174401: 22, -2174402: 24, -2174403: 132, -2174404: 20, -2174405: 99, -2174406: 16, -2174407: 33, -2174408: 8, -2174409: 0, -2174410: 4, -2174411: 239, -2174412: 1, -2174413: 173, -2174414: 1, -2174415: 107, -2174416: 1, -2174417: 41, -2174418: 1, -2174419: 231, -2174420: 4, -2174421: 165, -2174422: 4, -2174423: 99, -2174424: 4, -2174425: 195, -2174426: 32, -2174427: 13, -2174428: 178, -2174429: 114, -2174430: 199, -2174431: 113, -2174432: 3, -2174433: 77, -2174434: 149, -2174435: 82, -2174436: 240, -2174437: 61, -2174438: 108, -2174439: 45, -2174440: 9, -2174441: 33, -2174442: 77, -2174443: 24, -2174444: 99, -2174445: 195, -2174446: 32, -2174447: 224, -2174448: 45, -2174449: 137, -2174450: 29, -2174451: 6, -2174452: 13, -2174453: 163, -2174454: 12, -2174455: 14, -2174456: 45, -2174457: 9, -2174458: 45, -2174459: 197, -2174460: 40, -2174461: 129, -2174462: 12, -2174463: 206, -2174464: 85, -2174465: 104, -2174466: 61, -2174467: 162, -2174468: 36, -2174469: 0, -2174470: 20, -2174471: 12, -2174472: 50, -2174473: 8, -2174474: 33, -2174475: 255, -2174476: 127, -2174477: 32, -2174478: 4, -2174479: 99, -2174480: 68, -2174481: 148, -2174482: 82, -2174483: 206, -2174484: 57, -2174485: 8, -2174486: 33, -2174487: 232, -2174488: 28, -2174489: 199, -2174490: 24, -2174491: 166, -2174492: 20, -2174493: 133, -2174494: 16, -2174495: 67, -2174496: 67, -2174497: 8, -2174498: 13, -2174499: 34, -2174500: 4, -2174501: 33, -2174502: 4, -2174503: 79, -2174504: 45, -2174505: 15, -2174506: 41, -2174507: 255, -2174508: 127, -2174509: 66, -2174510: 0, -2174511: 99, -2174512: 68, -2174513: 69, -2174514: 24, -2174515: 99, -2174516: 15, -2174517: 96, -2174518: 45, -2174519: 32, -2174520: 37, -2174521: 192, -2174522: 24, -2174523: 128, -2174524: 16, -2174525: 12, -2174526: 38, -2174527: 169, -2174528: 25, -2174529: 7, -2174530: 9, -2174531: 130, -2174532: 0, -2174533: 195, -2174534: 70, -2174535: 197, -2174536: 192, -2174537: 69, -2174538: 24, -2174539: 99, -2174540: 7, -2174541: 148, -2174542: 62, -2174543: 206, -2174544: 37, -2174545: 8, -2174546: 13, -2174547: 198, -2174548: 4, -2174549: 199, -2174550: 96, -2174551: 67, -2174552: 24, -2174553: 99, -2174554: 195, -2174555: 32, -2174556: 255, -2174557: 27, -2174558: 99, -2174559: 68, -2174560: 223, -2174561: 2, -2174562: 215, -2174563: 1, -2174564: 172, -2174565: 0, -2174566: 245, -2174567: 93, -2174568: 14, -2174569: 61, -2174570: 170, -2174571: 40, -2174572: 35, -2174573: 20, -2174574: 177, -2174575: 11, -2174576: 251, -2174577: 72, -2174578: 255, -2174579: 127, -2174580: 0, -2174581: 0, -2174582: 255, -2174583: 127, -2174584: 229, -2174585: 68, -2174586: 195, -2174587: 8, -2174588: 21, -2174589: 99, -2174590: 68, -2174591: 177, -2174592: 11, -2174593: 169, -2174594: 30, -2174595: 69, -2174596: 1, -2174597: 187, -2174598: 94, -2174599: 179, -2174600: 61, -2174601: 46, -2174602: 41, -2174603: 134, -2174604: 20, -2174605: 24, -2174606: 99, -2174607: 231, -2174608: 28, -2174609: 132, -2174610: 16, -2174611: 195, -2174612: 32, -2174613: 2, -2174614: 223, -2174615: 2, -2174616: 31, -2174617: 34, -2174618: 0, -2174619: 29, -2174620: 99, -2174621: 68, -2174622: 188, -2174623: 114, -2174624: 251, -2174625: 72, -2174626: 22, -2174627: 24, -2174628: 14, -2174629: 0, -2174630: 6, -2174631: 0, -2174632: 2, -2174633: 0, -2174634: 1, -2174635: 0, -2174636: 239, -2174637: 1, -2174638: 173, -2174639: 1, -2174640: 107, -2174641: 1, -2174642: 41, -2174643: 1, -2174644: 231, -2174645: 4, -2174646: 165, -2174647: 4, -2174648: 99, -2174649: 4, -2174650: 195, -2174651: 32, -2174652: 13, -2174653: 178, -2174654: 114, -2174655: 199, -2174656: 113, -2174657: 3, -2174658: 77, -2174659: 149, -2174660: 82, -2174661: 240, -2174662: 61, -2174663: 108, -2174664: 45, -2174665: 9, -2174666: 33, -2174667: 77, -2174668: 24, -2174669: 99, -2174670: 195, -2174671: 32, -2174672: 10, -2174673: 142, -2174674: 29, -2174675: 11, -2174676: 13, -2174677: 168, -2174678: 12, -2174679: 22, -2174680: 0, -2174681: 15, -2174682: 0, -2174683: 7, -2174684: 194, -2174685: 66, -2174686: 224, -2174687: 36, -2174688: 206, -2174689: 85, -2174690: 104, -2174691: 61, -2174692: 162, -2174693: 36, -2174694: 0, -2174695: 20, -2174696: 17, -2174697: 50, -2174698: 8, -2174699: 33, -2174700: 255, -2174701: 127, -2174702: 32, -2174703: 4, -2174704: 99, -2174705: 68, -2174706: 148, -2174707: 82, -2174708: 206, -2174709: 57, -2174710: 8, -2174711: 33, -2174712: 127, -2174713: 8, -2174714: 123, -2174715: 8, -2174716: 86, -2174717: 4, -2174718: 82, -2174719: 4, -2174720: 45, -2174721: 4, -2174722: 41, -2174723: 4, -2174724: 4, -2174725: 34, -2174726: 0, -2174727: 9, -2174728: 79, -2174729: 45, -2174730: 15, -2174731: 41, -2174732: 255, -2174733: 127, -2174734: 64, -2174735: 0, -2174736: 99, -2174737: 68, -2174738: 69, -2174739: 24, -2174740: 99, -2174741: 19, -2174742: 107, -2174743: 45, -2174744: 43, -2174745: 37, -2174746: 203, -2174747: 24, -2174748: 139, -2174749: 16, -2174750: 17, -2174751: 38, -2174752: 174, -2174753: 25, -2174754: 12, -2174755: 9, -2174756: 135, -2174757: 0, -2174758: 109, -2174759: 61, -2174760: 167, -2174761: 36, -2174762: 197, -2174763: 192, -2174764: 69, -2174765: 24, -2174766: 99, -2174767: 10, -2174768: 153, -2174769: 62, -2174770: 211, -2174771: 37, -2174772: 13, -2174773: 13, -2174774: 198, -2174775: 4, -2174776: 211, -2174777: 85, -2174778: 109, -2174779: 196, -2174780: 96, -2174781: 67, -2174782: 24, -2174783: 99, -2174784: 195, -2174785: 32, -2174786: 255, -2174787: 29, -2174788: 0, -2174789: 0, -2174790: 223, -2174791: 2, -2174792: 215, -2174793: 1, -2174794: 172, -2174795: 0, -2174796: 55, -2174797: 95, -2174798: 16, -2174799: 62, -2174800: 108, -2174801: 41, -2174802: 165, -2174803: 20, -2174804: 177, -2174805: 11, -2174806: 251, -2174807: 72, -2174808: 255, -2174809: 127, -2174810: 0, -2174811: 0, -2174812: 255, -2174813: 127, -2174814: 229, -2174815: 68, -2174816: 255, -2174817: 127, -2174818: 35, -2174819: 0, -2174820: 19, -2174821: 177, -2174822: 11, -2174823: 169, -2174824: 30, -2174825: 69, -2174826: 1, -2174827: 187, -2174828: 94, -2174829: 179, -2174830: 61, -2174831: 46, -2174832: 41, -2174833: 134, -2174834: 20, -2174835: 24, -2174836: 99, -2174837: 231, -2174838: 28, -2174839: 132, -2174840: 16, -2174841: 195, -2174842: 32, -2174843: 2, -2174844: 223, -2174845: 2, -2174846: 31, -2174847: 36, -2174848: 0, -2174849: 5, -2174850: 188, -2174851: 114, -2174852: 251, -2174853: 72, -2174854: 22, -2174855: 24, -2174856: 75, -2174857: 24, -2174858: 99, -2174859: 9, -2174860: 134, -2174861: 44, -2174862: 130, -2174863: 28, -2174864: 72, -2174865: 68, -2174866: 35, -2174867: 44, -2174868: 255, -2174869: 127, -2174870: 35, -2174871: 0, -2174872: 5, -2174873: 178, -2174874: 114, -2174875: 199, -2174876: 113, -2174877: 3, -2174878: 77, -2174879: 83, -2174880: 24, -2174881: 99, -2174882: 1, -2174883: 255, -2174884: 127, -2174885: 35, -2174886: 0, -2174887: 197, -2174888: 88, -2174889: 224, -2174890: 85, -2174891: 111, -2174892: 45, -2174893: 200, -2174894: 40, -2174895: 132, -2174896: 36, -2174897: 97, -2174898: 28, -2174899: 147, -2174900: 92, -2174901: 142, -2174902: 72, -2174903: 6, -2174904: 44, -2174905: 72, -2174906: 68, -2174907: 4, -2174908: 20, -2174909: 2, -2174910: 16, -2174911: 187, -2174912: 94, -2174913: 0, -2174914: 8, -2174915: 0, -2174916: 0, -2174917: 115, -2174918: 90, -2174919: 173, -2174920: 65, -2174921: 231, -2174922: 40, -2174923: 78, -2174924: 37, -2174925: 167, -2174926: 36, -2174927: 99, -2174928: 32, -2174929: 64, -2174930: 24, -2174931: 25, -2174932: 0, -2174933: 18, -2174934: 0, -2174935: 96, -2174936: 52, -2174937: 64, -2174938: 24, -2174939: 68, -2174940: 8, -2174941: 127, -2174942: 25, -2174943: 156, -2174944: 127, -2174945: 0, -2174946: 4, -2174947: 0, -2174948: 0, -2174949: 15, -2174950: 52, -2174951: 11, -2174952: 36, -2174953: 8, -2174954: 24, -2174955: 115, -2174956: 17, -2174957: 204, -2174958: 16, -2174959: 136, -2174960: 12, -2174961: 101, -2174962: 8, -1126387: 0, -1126388: 56, -1126389: 250, -1126390: 114, -1126391: 176, -1126392: 85, -1126393: 69, -1126394: 40, -1126395: 1, -1126396: 24, -1126397: 16, -1126398: 98, -1126399: 107, -1126400: 73, -1126401: 198, -1126402: 56, -1126403: 99, -1126404: 44, -1126405: 239, -1126406: 47, -1126407: 13, -1126408: 3, -1126409: 9, -1126410: 2, -1126411: 69, -1126412: 1, -1126413: 63, -1126414: 24, -1126415: 20, -1126416: 16, -1126417: 10, -1126418: 8, -2174995: 32, -2174996: 255, -2174997: 29, -2174998: 0, -2174999: 0, -2175000: 223, -2175001: 2, -2175002: 215, -2175003: 1, -2175004: 172, -2175005: 0, -2175006: 55, -2175007: 95, -2175008: 16, -2175009: 62, -2175010: 108, -2175011: 41, -2175012: 165, -2175013: 20, -2175014: 177, -2175015: 11, -2175016: 251, -2175017: 72, -2175018: 255, -2175019: 127, -2175020: 0, -2175021: 0, -2175022: 255, -2175023: 127, -2175024: 229, -2175025: 68, -2175026: 255, -2175027: 127, -2175028: 35, -2175029: 0, -2175030: 19, -2175031: 177, -2175032: 11, -2175033: 169, -2175034: 30, -2175035: 69, -2175036: 1, -2175037: 187, -2175038: 94, -2175039: 179, -2175040: 61, -2175041: 46, -2175042: 41, -2175043: 134, -2175044: 20, -2175045: 24, -2175046: 99, -2175047: 231, -2175048: 28, -2175049: 132, -2175050: 16, -2175051: 195, -2175052: 32, -2175053: 2, -2175054: 223, -2175055: 2, -2175056: 31, -2175057: 36, -2175058: 0, -2175059: 5, -2175060: 188, -2175061: 114, -2175062: 251, -2175063: 72, -2175064: 22, -2175065: 24, -2175066: 75, -2175067: 24, -2175068: 99, -2175069: 9, -2175070: 134, -2175071: 44, -2175072: 130, -2175073: 28, -2175074: 72, -2175075: 68, -2175076: 35, -2175077: 44, -2175078: 255, -2175079: 127, -2175080: 35, -2175081: 0, -2175082: 5, -2175083: 178, -2175084: 114, -2175085: 199, -2175086: 113, -2175087: 3, -2175088: 77, -2175089: 83, -2175090: 24, -2175091: 99, -2175092: 1, -2175093: 255, -2175094: 127, -2175095: 35, -2175096: 0, -2175097: 197, -2175098: 88, -2175099: 224, -2175100: 85, -2175101: 111, -2175102: 45, -2175103: 200, -2175104: 40, -2175105: 132, -2175106: 36, -2175107: 97, -2175108: 28, -2175109: 147, -2175110: 92, -2175111: 142, -2175112: 72, -2175113: 6, -2175114: 44, -2175115: 72, -2175116: 68, -2175117: 4, -2175118: 20, -2175119: 2, -2175120: 16, -2175121: 187, -2175122: 94, -2175123: 0, -2175124: 8, -2175125: 0, -2175126: 0, -2175127: 12, -2175128: 33, -2175129: 168, -2175130: 20, -2175131: 2, -2175132: 0, -2175133: 235, -2175134: 24, -2175135: 68, -2175136: 24, -2175137: 33, -2175138: 20, -2175139: 0, -2175140: 12, -2175141: 25, -2175142: 0, -2175143: 18, -2175144: 0, -2175145: 72, -2175146: 68, -2175147: 6, -2175148: 44, -2175149: 68, -2175150: 8, -2175151: 127, -2175152: 25, -2175153: 244, -2175154: 61, -2175155: 0, -2175156: 4, -2175157: 0, -2175158: 0, -2175159: 15, -2175160: 52, -2175161: 11, -2175162: 36, -2175163: 8, -2175164: 24, -2175165: 115, -2175166: 17, -2175167: 204, -2175168: 16, -2175169: 136, -2175170: 12, -2175171: 101, -2175172: 8, -2175173: 115, -2175174: 78, -2175175: 173, -2175176: 53, -2175177: 231, -2175178: 28, -2175179: 99, -2175180: 12, -2175181: 24, -2175182: 99, -2175183: 4, -2175184: 8, -2175185: 255, -2175186: 127, -2175187: 35, -2175188: 0, -2175189: 69, -2175190: 24, -2175191: 99, -2175192: 7, -2175193: 82, -2175194: 25, -2175195: 171, -2175196: 24, -2175197: 103, -2175198: 20, -2175199: 68, -2175200: 16, -2175201: 75, -2175202: 24, -2175203: 99, -2175204: 195, -2175205: 32, -2175206: 255, -2175207: 27, -2175208: 0, -2175209: 0, -2175210: 223, -2175211: 2, -2175212: 215, -2175213: 1, -2175214: 172, -2175215: 0, -2175216: 187, -2175217: 94, -2175218: 179, -2175219: 61, -2175220: 46, -2175221: 41, -2175222: 134, -2175223: 20, -2175224: 177, -2175225: 11, -2175226: 251, -2175227: 72, -2175228: 255, -2175229: 127, -2175230: 0, -2175231: 0, -2175232: 255, -2175233: 127, -2175234: 229, -2175235: 68, -2175236: 195, -2175237: 8, -2175238: 7, -2175239: 3, -2175240: 32, -2175241: 177, -2175242: 11, -2175243: 169, -2175244: 30, -2175245: 69, -2175246: 1, -2175247: 199, -2175248: 32, -2175249: 5, -2175250: 24, -2175251: 99, -2175252: 231, -2175253: 28, -2175254: 132, -2175255: 16, -2175256: 195, -2175257: 32, -2175258: 2, -2175259: 223, -2175260: 2, -2175261: 31, -2175262: 34, -2175263: 0, -2175264: 7, -2175265: 3, -2175266: 32, -2175267: 188, -2175268: 114, -2175269: 251, -2175270: 72, -2175271: 22, -2175272: 24, -2175273: 83, -2175274: 24, -2175275: 99, -2175276: 1, -2175277: 255, -2175278: 127, -2175279: 35, -2175280: 0, -2175281: 5, -2175282: 178, -2175283: 114, -2175284: 199, -2175285: 113, -2175286: 3, -2175287: 77, -2175288: 83, -2175289: 24, -2175290: 99, -2175291: 1, -2175292: 255, -2175293: 127, -2175294: 35, -2175295: 0, -2175296: 27, -2175297: 244, -2175298: 62, -2175299: 46, -2175300: 38, -2175301: 104, -2175302: 13, -2175303: 148, -2175304: 62, -2175305: 206, -2175306: 37, -2175307: 8, -2175308: 13, -2175309: 132, -2175310: 20, -2175311: 148, -2175312: 110, -2175313: 206, -2175314: 85, -2175315: 8, -2175316: 61, -2175317: 132, -2175318: 44, -2175319: 169, -2175320: 30, -2175321: 177, -2175322: 11, -2175323: 255, -2175324: 127, -2175325: 35, -2175326: 0, -2175327: 27, -2175328: 70, -2175329: 18, -2175330: 69, -2175331: 1, -2175332: 192, -2175333: 0, -2175334: 82, -2175335: 54, -2175336: 140, -2175337: 29, -2175338: 198, -2175339: 4, -2175340: 132, -2175341: 4, -2175342: 49, -2175343: 98, -2175344: 107, -2175345: 73, -2175346: 165, -2175347: 48, -2175348: 33, -2175349: 32, -2175350: 21, -2175351: 0, -2175352: 91, -2175353: 2, -2175354: 255, -2175355: 127, -2175356: 35, -2175357: 0, -2175358: 89, -2175359: 24, -2175360: 99, -2175361: 1, -2175362: 255, -2175363: 127, -2175364: 35, -2175365: 0, -2175366: 29, -2175367: 123, -2175368: 71, -2175369: 82, -2175370: 46, -2175371: 198, -2175372: 0, -2175373: 99, -2175374: 0, -2175375: 181, -2175376: 58, -2175377: 16, -2175378: 34, -2175379: 107, -2175380: 17, -2175381: 8, -2175382: 5, -2175383: 255, -2175384: 127, -2175385: 181, -2175386: 54, -2175387: 173, -2175388: 25, -2175389: 41, -2175390: 9, -2175391: 29, -2175392: 56, -2175393: 20, -2175394: 24, -2175395: 10, -2175396: 0, -2175397: 255, -2175398: 27, -2175399: 0, -2175400: 0, -2175401: 223, -2175402: 2, -2175403: 215, -2175404: 1, -2175405: 172, -2175406: 0, -2175407: 187, -2175408: 94, -2175409: 179, -2175410: 61, -2175411: 46, -2175412: 41, -2175413: 134, -2175414: 20, -2175415: 177, -2175416: 11, -2175417: 251, -2175418: 72, -2175419: 255, -2175420: 127, -2175421: 0, -2175422: 0, -2175423: 255, -2175424: 127, -2175425: 229, -2175426: 68, -2175427: 195, -2175428: 8, -2175429: 7, -2175430: 3, -2175431: 32, -2175432: 177, -2175433: 11, -2175434: 169, -2175435: 30, -2175436: 69, -2175437: 1, -2175438: 199, -2175439: 32, -2175440: 5, -2175441: 24, -2175442: 99, -2175443: 231, -2175444: 28, -2175445: 132, -2175446: 16, -2175447: 195, -2175448: 32, -2175449: 2, -2175450: 223, -2175451: 2, -2175452: 31, -2175453: 34, -2175454: 0, -2175455: 7, -2175456: 3, -2175457: 32, -2175458: 188, -2175459: 114, -2175460: 251, -2175461: 72, -2175462: 22, -2175463: 24, -2175464: 83, -2175465: 24, -2175466: 99, -2175467: 1, -2175468: 255, -2175469: 127, -2175470: 35, -2175471: 0, -2175472: 5, -2175473: 178, -2175474: 114, -2175475: 199, -2175476: 113, -2175477: 3, -2175478: 77, -2175479: 83, -2175480: 24, -2175481: 99, -2175482: 1, -2175483: 255, -2175484: 127, -2175485: 35, -2175486: 0, -2175487: 27, -2175488: 170, -2175489: 21, -2175490: 5, -2175491: 1, -2175492: 129, -2175493: 0, -2175494: 74, -2175495: 21, -2175496: 231, -2175497: 12, -2175498: 99, -2175499: 0, -1126924: 0, -1126925: 56, -1126926: 159, -1126927: 3, -1126928: 191, -1126929: 1, -1126930: 15, -1126931: 0, -1126932: 5, -1126933: 0, -1126934: 31, -2175511: 32, -1126936: 91, -2175513: 56, -1126938: 186, -1126939: 0, -1126940: 17, -1126941: 0, -1126942: 114, -1126943: 79, -1126944: 173, -1126945: 54, -1126946: 200, -2175523: 32, -2175524: 195, -2175525: 32, -1126950: 31, -1126951: 126, -1126952: 21, -1126953: 84, -1126954: 10, -1126955: 40, -2175532: 74, -2175533: 69, -2175534: 132, -2175535: 44, -2175536: 0, -2175537: 20, -2175538: 0, -2175539: 0, -2175540: 18, -2175541: 0, -2175542: 248, -2175543: 1, -2175544: 82, -2175545: 74, -2175546: 35, -2175547: 0, -2175548: 89, -2175549: 24, -2175550: 99, -2175551: 1, -2175552: 255, -2175553: 127, -2175554: 35, -2175555: 0, -2175556: 29, -2175557: 123, -2175558: 71, -2175559: 82, -2175560: 46, -2175561: 198, -2175562: 0, -2175563: 99, -2175564: 0, -2175565: 181, -2175566: 58, -2175567: 16, -2175568: 34, -2175569: 107, -2175570: 17, -2175571: 8, -2175572: 5, -2175573: 255, -2175574: 127, -2175575: 181, -2175576: 54, -2175577: 173, -2175578: 25, -2175579: 41, -2175580: 9, -2175581: 29, -2175582: 56, -2175583: 20, -2175584: 24, -2175585: 10, -2175586: 0, -2175587: 255, -1127012: 0, -1127013: 56, -1127014: 250, -1127015: 114, -1127016: 176, -1127017: 85, -1127018: 69, -2175595: 172, -1127020: 1, -2175597: 115, -2175598: 90, -2175599: 173, -2175600: 65, -2175601: 8, -2175602: 45, -2175603: 99, -2175604: 24, -2175605: 177, -2175606: 11, -2175607: 251, -2175608: 72, -2175609: 255, -2175610: 127, -2175611: 0, -2175612: 0, -2175613: 255, -2175614: 127, -2175615: 229, -2175616: 68, -2175617: 195, -2175618: 8, -2175619: 21, -2175620: 3, -2175621: 32, -2175622: 177, -2175623: 11, -2175624: 169, -2175625: 30, -2175626: 69, -2175627: 1, -2175628: 187, -2175629: 94, -2175630: 179, -2175631: 61, -2175632: 46, -2175633: 41, -2175634: 134, -2175635: 20, -2175636: 24, -2175637: 99, -2175638: 82, -2175639: 74, -2175640: 140, -2175641: 49, -2175642: 195, -2175643: 32, -2175644: 2, -2175645: 223, -2175646: 2, -2175647: 31, -2175648: 34, -2175649: 0, -2175650: 29, -2175651: 3, -2175652: 32, -2175653: 188, -2175654: 114, -2175655: 251, -2175656: 72, -2175657: 22, -2175658: 24, -2175659: 144, -2175660: 22, -2175661: 20, -2175662: 14, -2175663: 229, -2175664: 0, -2175665: 65, -2175666: 0, -2175667: 198, -2175668: 48, -2175669: 98, -2175670: 36, -2175671: 33, -2175672: 20, -2175673: 0, -2175674: 8, -2175675: 255, -2175676: 126, -2175677: 64, -2175678: 24, -2175679: 255, -2175680: 127, -2175681: 35, -2175682: 0, -2175683: 21, -2175684: 178, -2175685: 114, -2175686: 199, -2175687: 113, -2175688: 3, -2175689: 77, -2175690: 164, -2175691: 48, -1127116: 17, -2175693: 36, -2175694: 64, -2175695: 24, -2175696: 0, -2175697: 8, -2175698: 82, -2175699: 94, -2175700: 107, -2175701: 65, -2175702: 228, -2175703: 48, -2175704: 96, -2175705: 28, -2175706: 67, -2175707: 24, -2175708: 99, -2175709: 1, -2175710: 156, -2175711: 127, -2175712: 35, -2175713: 0, -2175714: 67, -2175715: 24, -2175716: 99, -2175717: 23, -2175718: 224, -2175719: 32, -2175720: 167, -2175721: 29, -2175722: 33, -2175723: 45, -2175724: 160, -2175725: 40, -2175726: 32, -2175727: 24, -2175728: 169, -2175729: 38, -2175730: 233, -2175731: 37, -2175732: 66, -2175733: 21, -2175734: 32, -2175735: 4, -2175736: 169, -2175737: 38, -2175738: 130, -2175739: 0, -2175740: 113, -2175741: 39, -2175742: 35, -2175743: 0, -2175744: 27, -2175745: 191, -2175746: 2, -2175747: 127, -2175748: 1, -2175749: 21, -2175750: 0, -2175751: 149, -2175752: 79, -2175753: 174, -2175754: 66, -2175755: 6, -2175756: 50, -2175757: 35, -2175758: 37, -2175759: 42, -2175760: 21, -2175761: 199, -2175762: 20, -2175763: 99, -2175764: 20, -2175765: 2, -2175766: 4, -2175767: 161, -2175768: 12, -2175769: 64, -2175770: 24, -2175771: 181, -2175772: 126, -2175773: 35, -2175774: 0, -2175775: 25, -2175776: 186, -2175777: 94, -2175778: 54, -2175779: 78, -2175780: 178, -2175781: 61, -2175782: 46, -2175783: 45, -2175784: 203, -2175785: 32, -2175786: 72, -2175787: 16, -2175788: 2, -2175789: 8, -2175790: 119, -2175791: 26, -2175792: 209, -2175793: 33, -2175794: 199, -2175795: 36, -2175796: 66, -2175797: 0, -2175798: 28, -2175799: 107, -2175800: 24, -2175801: 99, -2175802: 194, -2175803: 32, -2175804: 24, -2175805: 12, -2175806: 0, -2175807: 0, -2175808: 34, -2175809: 93, -2175810: 99, -2175811: 68, -2175812: 64, -2175813: 24, -2175814: 192, -2175815: 36, -2175816: 160, -2175817: 28, -2175818: 128, -2175819: 20, -2175820: 64, -2175821: 16, -2175822: 223, -2175823: 22, -2175824: 215, -2175825: 21, -2175826: 238, -2175827: 20, -2175828: 134, -2175829: 20, -2175830: 67, -2175831: 24, -2175832: 99, -2175833: 3, -2175834: 223, -2175835: 22, -2175836: 0, -2175837: 8, -2175838: 255, -2175839: 27, -2175840: 0, -2175841: 0, -2175842: 223, -2175843: 2, -2175844: 215, -2175845: 1, -2175846: 172, -2175847: 0, -2175848: 115, -2175849: 90, -2175850: 173, -2175851: 65, -2175852: 8, -2175853: 45, -2175854: 99, -2175855: 24, -2175856: 177, -2175857: 11, -2175858: 251, -2175859: 72, -2175860: 255, -2175861: 127, -2175862: 0, -2175863: 0, -2175864: 255, -2175865: 127, -2175866: 229, -2175867: 68, -2175868: 195, -2175869: 8, -2175870: 21, -2175871: 3, -2175872: 32, -2175873: 177, -2175874: 11, -2175875: 169, -2175876: 30, -2175877: 69, -2175878: 1, -2175879: 187, -2175880: 94, -2175881: 179, -2175882: 61, -2175883: 46, -2175884: 41, -2175885: 134, -2175886: 20, -2175887: 24, -2175888: 99, -2175889: 82, -2175890: 74, -2175891: 140, -2175892: 49, -2175893: 195, -2175894: 32, -2175895: 2, -2175896: 223, -2175897: 2, -2175898: 31, -2175899: 34, -2175900: 0, -2175901: 15, -2175902: 3, -2175903: 32, -2175904: 188, -2175905: 114, -2175906: 251, -2175907: 72, -2175908: 22, -2175909: 24, -2175910: 10, -2175911: 29, -2175912: 199, -2175913: 24, -2175914: 69, -2175915: 12, -2175916: 3, -2175917: 4, -2175918: 75, -2175919: 24, -2175920: 99, -2175921: 1, -2175922: 255, -2175923: 127, -2175924: 35, -2175925: 0, -2175926: 13, -2175927: 178, -2175928: 114, -2175929: 199, -2175930: 113, -2175931: 3, -2175932: 77, -2175933: 197, -2175934: 52, -2175935: 130, -2175936: 40, -2175937: 64, -2175938: 32, -2175939: 0, -2175940: 8, -2175941: 71, -2175942: 24, -2175943: 99, -2175944: 5, -2175945: 52, -2175946: 127, -2175947: 0, -2175948: 125, -2175949: 247, -2175950: 91, -2175951: 35, -2175952: 0, -2175953: 27, -2175954: 191, -2175955: 42, -2175956: 127, -2175957: 41, -2175958: 21, -2175959: 40, -2175960: 63, -2175961: 54, -2175962: 124, -2175963: 45, -2175964: 23, -2175965: 33, -2175966: 211, -2175967: 28, -2175968: 176, -2175969: 20, -2175970: 108, -2175971: 16, -2175972: 72, -2175973: 12, -2175974: 4, -2175975: 8, -2175976: 82, -2175977: 74, -2175978: 231, -2175979: 28, -2175980: 255, -2175981: 127, -2175982: 35, -2175983: 0, -2175984: 67, -2175985: 24, -2175986: 99, -2175987: 18, -2175988: 84, -2175989: 42, -2175990: 175, -2175991: 25, -2175992: 41, -2175993: 21, -2175994: 132, -2175995: 8, -2175996: 33, -2175997: 8, -2175998: 176, -2175999: 22, -2176000: 192, -2176001: 29, -2176002: 224, -2176003: 20, -2176004: 96, -2176005: 20, -2176006: 231, -2176007: 194, -2176008: 138, -2176009: 1, -2176010: 255, -2176011: 127, -2176012: 35, -2176013: 0, -2176014: 69, -2176015: 24, -2176016: 99, -2176017: 17, -2176018: 23, -2176019: 76, -2176020: 15, -2176021: 40, -2176022: 9, -2176023: 36, -2176024: 7, -2176025: 28, -2176026: 5, -2176027: 20, -2176028: 3, -2176029: 12, -2176030: 2, -2176031: 8, -2176032: 1, -2176033: 4, -2176034: 59, -2176035: 93, -2176036: 195, -2176037: 32, -2176038: 35, -2176039: 0, -2176040: 22, -2176041: 191, -2176042: 2, -2176043: 127, -2176044: 1, -2176045: 21, -2176046: 0, -2176047: 73, -2176048: 55, -2176049: 192, -2176050: 62, -2176051: 128, -2176052: 29, -2176053: 192, -2176054: 4, -2176055: 0, -2176056: 1, -2176057: 192, -2176058: 0, -2176059: 128, -2176060: 0, -2176061: 64, -2176062: 0, -2176063: 52, -2176064: 68, -2176065: 127, -2176066: 255, -2176067: 1, -2176068: 0, -2176069: 0, -2176070: 255, -2176071: 27, -2176072: 0, -2176073: 0, -2176074: 223, -2176075: 2, -2176076: 215, -2176077: 1, -2176078: 172, -2176079: 0, -2176080: 115, -2176081: 90, -2176082: 173, -2176083: 65, -2176084: 8, -2176085: 45, -2176086: 99, -2176087: 24, -2176088: 177, -2176089: 11, -2176090: 251, -2176091: 72, -2176092: 255, -2176093: 127, -2176094: 0, -2176095: 0, -2176096: 255, -2176097: 127, -2176098: 229, -2176099: 68, -2176100: 195, -2176101: 8, -2176102: 21, -2176103: 3, -2176104: 32, -2176105: 177, -2176106: 11, -2176107: 169, -2176108: 30, -2176109: 69, -2176110: 1, -2176111: 187, -2176112: 94, -2176113: 179, -2176114: 61, -2176115: 46, -2176116: 41, -2176117: 134, -2176118: 20, -2176119: 24, -2176120: 99, -2176121: 82, -2176122: 74, -2176123: 140, -2176124: 49, -2176125: 195, -2176126: 32, -2176127: 2, -2176128: 223, -2176129: 2, -2176130: 31, -2176131: 34, -2176132: 0, -2176133: 15, -2176134: 3, -2176135: 32, -2176136: 188, -2176137: 114, -2176138: 251, -2176139: 72, -2176140: 22, -2176141: 24, -2176142: 10, -2176143: 29, -2176144: 199, -2176145: 24, -2176146: 69, -2176147: 12, -2176148: 3, -2176149: 4, -2176150: 75, -2176151: 24, -2176152: 99, -2176153: 1, -2176154: 255, -2176155: 127, -2176156: 35, -2176157: 0, -2176158: 5, -2176159: 178, -2176160: 114, -2176161: 199, -2176162: 113, -2176163: 3, -2176164: 77, -2176165: 83, -2176166: 24, -2176167: 99, -2176168: 1, -2176169: 255, -2176170: 127, -2176171: 35, -2176172: 0, -2176173: 27, -2176174: 191, -2176175: 2, -2176176: 127, -2176177: 1, -2176178: 21, -2176179: 0, -2176180: 140, -2176181: 69, -2176182: 107, -2176183: 61, -2176184: 41, -2176185: 53, -2176186: 8, -2176187: 45, -2176188: 198, -2176189: 36, -2176190: 165, -2176191: 24, -2176192: 99, -2176193: 16, -2176194: 66, -2176195: 8, -2176196: 19, -2176197: 127, -2176198: 0, -2176199: 125, -2176200: 255, -2176201: 127, -2176202: 35, -2176203: 0, -2176204: 67, -2176205: 24, -2176206: 99, -2176207: 19, -2176208: 250, -2176209: 107, -2176210: 179, -2176211: 110, -2176212: 11, -2176213: 78, -2176214: 6, -2176215: 49, -2176216: 65, -2176217: 12, -2176218: 176, -2176219: 22, -2176220: 192, -2176221: 29, -2176222: 224, -2176223: 20, -2176224: 96, -2176225: 20, -2176226: 72, -2176227: 69, -2176228: 195, -2176229: 64, -2176230: 35, -2176231: 0, -2176232: 69, -2176233: 24, -2176234: 99, -2176235: 17, -2176236: 244, -2176237: 65, -2176238: 145, -2176239: 53, -2176240: 79, -2176241: 45, -2176242: 13, -2176243: 37, -2176244: 203, -2176245: 28, -2176246: 137, -2176247: 20, -2176248: 68, -2176249: 12, -2176250: 33, -2176251: 4, -2176252: 153, -2176253: 86, -2176254: 195, -2176255: 32, -2176256: 35, -2176257: 0, -2176258: 197, -2176259: 96, -2176260: 199, -2176261: 64, -2176262: 73, -2176263: 24, -2176264: 99, -2176265: 67, -2176266: 255, -2176267: 127, -2176268: 1, -2176269: 0, -2176270: 0, -2176271: 255, -2176272: 29, -2176273: 0, -2176274: 0, -2176275: 223, -2176276: 2, -2176277: 215, -2176278: 1, -2176279: 172, -2176280: 0, -2176281: 115, -2176282: 90, -2176283: 173, -2176284: 65, -2176285: 8, -2176286: 45, -2176287: 99, -2176288: 24, -2176289: 177, -2176290: 11, -2176291: 251, -2176292: 72, -2176293: 255, -2176294: 127, -2176295: 0, -2176296: 0, -2176297: 255, -2176298: 127, -2176299: 229, -2176300: 68, -2176301: 255, -2176302: 127, -2176303: 34, -2176304: 0, -2176305: 20, -2176306: 56, -2176307: 177, -2176308: 11, -2176309: 169, -2176310: 30, -2176311: 69, -2176312: 1, -2176313: 187, -2176314: 94, -2176315: 179, -2176316: 61, -2176317: 46, -2176318: 41, -2176319: 134, -2176320: 20, -2176321: 24, -2176322: 99, -2176323: 82, -2176324: 74, -2176325: 140, -2176326: 49, -2176327: 195, -2176328: 32, -2176329: 2, -2176330: 223, -2176331: 2, -2176332: 31, -2176333: 35, -2176334: 0, -2176335: 28, -2176336: 56, -2176337: 188, -2176338: 114, -2176339: 251, -2176340: 72, -2176341: 22, -2176342: 24, -2176343: 144, -2176344: 22, -2176345: 20, -2176346: 14, -2176347: 229, -2176348: 0, -2176349: 65, -2176350: 0, -2176351: 198, -2176352: 48, -2176353: 98, -2176354: 36, -2176355: 33, -2176356: 20, -2176357: 0, -2176358: 8, -2176359: 255, -2176360: 126, -2176361: 24, -2176362: 99, -2176363: 255, -2176364: 127, -2176365: 34, -2176366: 0, -2176367: 14, -2176368: 56, -2176369: 178, -2176370: 114, -2176371: 199, -2176372: 113, -2176373: 3, -2176374: 77, -2176375: 73, -2176376: 61, -2176377: 196, -2176378: 48, -2176379: 64, -2176380: 36, -2176381: 0, -2176382: 16, -2176383: 75, -2176384: 24, -2176385: 99, -2176386: 1, -2176387: 255, -2176388: 127, -2176389: 34, -2176390: 0, -2176391: 0, -2176392: 56, -2176393: 69, -2176394: 24, -2176395: 99, -2176396: 17, -2176397: 46, -2176398: 31, -2176399: 130, -2176400: 21, -2176401: 128, -2176402: 12, -2176403: 0, -2176404: 4, -2176405: 154, -2176406: 103, -2176407: 76, -2176408: 42, -2176409: 163, -2176410: 17, -2176411: 32, -2176412: 4, -2176413: 255, -2176414: 3, -2176415: 195, -2176416: 32, -2176417: 34, -2176418: 0, -2176419: 28, -2176420: 56, -2176421: 191, -2176422: 2, -2176423: 127, -2176424: 1, -2176425: 21, -2176426: 0, -2176427: 73, -2176428: 55, -2176429: 192, -2176430: 62, -2176431: 128, -2176432: 29, -2176433: 192, -2176434: 4, -2176435: 0, -2176436: 1, -2176437: 192, -2176438: 0, -2176439: 128, -2176440: 0, -2176441: 64, -2176442: 0, -2176443: 19, -2176444: 127, -2176445: 0, -2176446: 125, -2176447: 255, -2176448: 127, -2176449: 34, -2176450: 0, -2176451: 0, -2176452: 56, -2176453: 62, -2176454: 0, -2176455: 24, -2176456: 56, -2176457: 157, -2176458: 85, -2176459: 22, -2176460: 24, -2176461: 13, -2176462: 16, -2176463: 159, -2176464: 75, -2176465: 55, -2176466: 63, -2176467: 208, -2176468: 54, -2176469: 105, -2176470: 46, -2176471: 8, -2176472: 38, -2176473: 166, -2176474: 29, -2176475: 37, -2176476: 17, -2176477: 197, -2176478: 8, -2176479: 3, -2176480: 0, -2176481: 197, -2176482: 96, -2176483: 255, -2176484: 27, -2176485: 0, -2176486: 0, -2176487: 223, -2176488: 2, -2176489: 215, -2176490: 1, -2176491: 172, -2176492: 0, -2176493: 187, -2176494: 94, -2176495: 179, -2176496: 61, -2176497: 46, -2176498: 41, -2176499: 134, -2176500: 20, -2176501: 177, -2176502: 11, -2176503: 251, -2176504: 72, -2176505: 255, -2176506: 127, -2176507: 0, -2176508: 0, -2176509: 255, -2176510: 127, -2176511: 229, -2176512: 68, -2176513: 195, -2176514: 8, -2176515: 7, -2176516: 3, -2176517: 32, -2176518: 177, -2176519: 11, -2176520: 169, -2176521: 30, -2176522: 69, -2176523: 1, -2176524: 199, -2176525: 32, -2176526: 5, -2176527: 223, -2176528: 14, -2176529: 63, -2176530: 14, -2176531: 127, -2176532: 13, -2176533: 195, -2176534: 32, -2176535: 2, -2176536: 223, -2176537: 2, -2176538: 31, -2176539: 34, -2176540: 0, -2176541: 7, -2176542: 3, -2176543: 32, -2176544: 188, -2176545: 114, -2176546: 251, -2176547: 72, -2176548: 22, -2176549: 24, -2176550: 205, -2176551: 32, -2176552: 7, -2176553: 159, -2176554: 12, -2176555: 151, -2176556: 54, -2176557: 63, -2176558: 14, -2176559: 255, -2176560: 127, -2176561: 35, -2176562: 0, -2176563: 5, -2176564: 178, -2176565: 114, -2176566: 199, -2176567: 113, -2176568: 3, -2176569: 77, -2176570: 199, -2176571: 24, -2176572: 13, -2176573: 247, -2176574: 94, -2176575: 82, -2176576: 74, -2176577: 107, -2176578: 45, -2176579: 132, -2176580: 16, -2176581: 63, -2176582: 14, -2176583: 82, -2176584: 74, -2176585: 255, -2176586: 127, -2176587: 35, -2176588: 0, -2176589: 197, -2176590: 24, -2176591: 21, -2176592: 236, -2176593: 83, -2176594: 9, -2176595: 67, -2176596: 197, -2176597: 37, -2176598: 194, -2176599: 16, -2176600: 153, -2176601: 12, -2176602: 114, -2176603: 12, -2176604: 73, -2176605: 12, -2176606: 65, -2176607: 12, -2176608: 9, -2176609: 67, -2176610: 119, -2176611: 12, -2176612: 255, -2176613: 127, -2176614: 35, -2176615: 0, -2176616: 197, -2176617: 32, -2176618: 21, -2176619: 58, -2176620: 58, -2176621: 179, -2176622: 45, -2176623: 44, -2176624: 33, -2176625: 132, -2176626: 16, -2176627: 85, -2176628: 85, -2176629: 207, -2176630: 56, -2176631: 105, -2176632: 28, -2176633: 3, -2176634: 4, -2176635: 179, -2176636: 45, -2176637: 207, -2176638: 56, -2176639: 255, -2176640: 127, -2176641: 35, -2176642: 0, -2176643: 16, -2176644: 150, -2176645: 5, -2176646: 214, -2176647: 4, -2176648: 86, -2176649: 4, -2176650: 204, -2176651: 8, -2176652: 168, -2176653: 8, -2176654: 133, -2176655: 8, -2176656: 130, -2176657: 8, -2176658: 39, -2176659: 16, -2176660: 5, -2176661: 67, -2176662: 12, -2176663: 3, -2176664: 194, -2176665: 14, -2176666: 3, -2176667: 5, -2176668: 12, -2176669: 255, -2176670: 127, -2176671: 35, -2176672: 0, -2176673: 197, -2176674: 32, -2176675: 12, -2176676: 12, -2176677: 20, -2176678: 8, -2176679: 12, -2176680: 4, -2176681: 4, -2176682: 0, -2176683: 0, -2176684: 14, -2176685: 8, -2176686: 9, -2176687: 4, -2176688: 4, -2176689: 34, -2176690: 0, -2176691: 3, -2176692: 8, -2176693: 12, -2176694: 9, -2176695: 4, -2176696: 195, -2176697: 32, -2176698: 255, -2176699: 27, -2176700: 0, -2176701: 0, -2176702: 223, -2176703: 2, -2176704: 215, -2176705: 1, -2176706: 172, -2176707: 0, -2176708: 53, -2176709: 107, -2176710: 14, -2176711: 74, -2176712: 106, -2176713: 53, -2176714: 163, -2176715: 32, -2176716: 177, -2176717: 11, -2176718: 251, -2176719: 72, -2176720: 255, -2176721: 127, -2176722: 0, -2176723: 0, -2176724: 255, -2176725: 127, -2176726: 229, -2176727: 68, -2176728: 195, -2176729: 8, -2176730: 0, -2176731: 3, -2176732: 194, -2176733: 18, -2176734: 17, -2176735: 169, -2176736: 30, -2176737: 69, -2176738: 1, -2176739: 187, -2176740: 94, -2176741: 179, -2176742: 61, -2176743: 46, -2176744: 41, -2176745: 134, -2176746: 20, -2176747: 223, -2176748: 14, -2176749: 63, -2176750: 14, -2176751: 127, -2176752: 13, -2176753: 195, -2176754: 32, -2176755: 2, -2176756: 223, -2176757: 2, -2176758: 31, -2176759: 34, -2176760: 0, -2176761: 7, -2176762: 3, -2176763: 32, -2176764: 188, -2176765: 114, -2176766: 251, -2176767: 72, -2176768: 22, -2176769: 24, -2176770: 205, -2176771: 32, -2176772: 7, -2176773: 159, -2176774: 12, -2176775: 151, -2176776: 54, -2176777: 63, -2176778: 14, -2176779: 255, -2176780: 127, -2176781: 35, -2176782: 0, -2176783: 5, -2176784: 178, -2176785: 114, -2176786: 199, -2176787: 113, -2176788: 3, -2176789: 77, -2176790: 199, -2176791: 24, -2176792: 13, -2176793: 247, -2176794: 94, -2176795: 82, -2176796: 74, -2176797: 107, -2176798: 45, -2176799: 132, -2176800: 16, -2176801: 63, -2176802: 14, -2176803: 82, -2176804: 74, -2176805: 255, -2176806: 127, -2176807: 35, -2176808: 0, -2176809: 197, -2176810: 24, -2176811: 21, -2176812: 236, -2176813: 83, -2176814: 9, -2176815: 67, -2176816: 197, -2176817: 37, -2176818: 194, -2176819: 16, -2176820: 121, -2176821: 78, -2176822: 212, -2176823: 57, -2176824: 237, -2176825: 28, -2176826: 65, -2176827: 12, -2176828: 9, -2176829: 67, -2176830: 119, -2176831: 12, -2176832: 255, -2176833: 127, -2176834: 35, -2176835: 0, -2176836: 197, -2176837: 32, -2176838: 21, -2176839: 58, -2176840: 58, -2176841: 179, -2176842: 45, -2176843: 44, -2176844: 33, -2176845: 99, -2176846: 12, -2176847: 85, -2176848: 85, -2176849: 207, -2176850: 56, -2176851: 105, -2176852: 28, -2176853: 3, -2176854: 4, -2176855: 179, -2176856: 45, -2176857: 207, -2176858: 56, -2176859: 255, -2176860: 127, -2176861: 35, -2176862: 0, -2176863: 16, -2176864: 150, -2176865: 5, -2176866: 214, -2176867: 4, -2176868: 86, -2176869: 4, -2176870: 206, -2176871: 32, -2176872: 137, -2176873: 28, -2176874: 101, -2176875: 20, -2176876: 32, -2176877: 20, -2176878: 39, -2176879: 16, -2176880: 5, -2176881: 67, -2176882: 12, -2176883: 3, -2176884: 6, -2176885: 8, -2176886: 168, -2176887: 8, -2176888: 5, -2176889: 12, -2176890: 255, -2176891: 127, -2176892: 35, -2176893: 0, -2176894: 197, -2176895: 32, -2176896: 19, -2176897: 136, -2176898: 20, -2176899: 70, -2176900: 12, -2176901: 35, -2176902: 4, -2176903: 0, -2176904: 0, -2176905: 14, -2176906: 33, -2176907: 201, -2176908: 24, -2176909: 100, -2176910: 12, -2176911: 0, -2176912: 0, -2176913: 8, -2176914: 12, -2176915: 9, -2176916: 4, -2176917: 195, -2176918: 32, -2176919: 255, -2176920: 27, -2176921: 0, -2176922: 0, -2176923: 223, -2176924: 2, -2176925: 215, -2176926: 1, -2176927: 172, -2176928: 0, -2176929: 115, -2176930: 90, -2176931: 173, -2176932: 65, -2176933: 8, -2176934: 45, -2176935: 99, -2176936: 24, -2176937: 177, -2176938: 11, -2176939: 251, -2176940: 72, -2176941: 255, -2176942: 127, -2176943: 0, -2176944: 0, -2176945: 255, -2176946: 127, -2176947: 229, -2176948: 68, -2176949: 195, -2176950: 8, -2176951: 27, -2176952: 3, -2176953: 32, -2176954: 177, -2176955: 11, -2176956: 169, -2176957: 30, -2176958: 69, -2176959: 1, -2176960: 187, -2176961: 94, -2176962: 179, -2176963: 61, -2176964: 46, -2176965: 41, -2176966: 134, -2176967: 20, -2176968: 24, -2176969: 99, -2176970: 82, -2176971: 74, -2176972: 140, -2176973: 49, -2176974: 0, -2176975: 0, -2176976: 24, -2176977: 99, -2176978: 223, -2176979: 2, -2176980: 197, -2176981: 32, -2176982: 5, -2176983: 188, -2176984: 114, -2176985: 157, -2176986: 85, -2176987: 22, -2176988: 24, -2176989: 81, -2176990: 24, -2176991: 99, -2176992: 1, -2176993: 0, -2176994: 0, -2176995: 67, -2176996: 24, -2176997: 99, -2176998: 7, -2176999: 0, -2177000: 0, -2177001: 178, -2177002: 114, -2177003: 199, -2177004: 113, -2177005: 99, -2177006: 68, -2177007: 81, -2177008: 24, -2177009: 99, -2177010: 1, -2177011: 0, -2177012: 0, -2177013: 67, -2177014: 24, -2177015: 99, -2177016: 1, -2177017: 0, -2177018: 0, -2177019: 93, -2177020: 24, -2177021: 99, -2177022: 1, -2177023: 0, -2177024: 0, -2177025: 93, -2177026: 24, -2177027: 99, -2177028: 195, -2177029: 170, -2177030: 25, -2177031: 255, -2177032: 45, -2177033: 191, -2177034: 40, -2177035: 144, -2177036: 28, -2177037: 105, -2177038: 20, -2177039: 36, -2177040: 20, -2177041: 123, -2177042: 74, -2177043: 27, -2177044: 54, -2177045: 85, -2177046: 25, -2177047: 110, -2177048: 0, -2177049: 8, -2177050: 0, -2177051: 159, -2177052: 3, -2177053: 58, -2177054: 2, -2177055: 118, -2177056: 1, -2177057: 35, -2177058: 0, -2177059: 194, -2177060: 32, -2177061: 18, -2177062: 13, -2177063: 191, -2177064: 8, -2177065: 149, -2177066: 8, -2177067: 108, -2177068: 8, -2177069: 71, -2177070: 4, -2177071: 126, -2177072: 107, -2177073: 30, -2177074: 87, -2177075: 88, -2177076: 58, -2177077: 113, -2177078: 33, -2177079: 203, -2177080: 12, -2177081: 199, -2177082: 32, -2177083: 255, -2177084: 27, -2177085: 0, -2177086: 0, -2177087: 223, -2177088: 2, -2177089: 215, -2177090: 1, -2177091: 172, -2177092: 0, -2177093: 25, -2177094: 106, -2177095: 51, -2177096: 81, -2177097: 171, -2177098: 52, -2177099: 102, -2177100: 32, -2177101: 177, -2177102: 11, -2177103: 251, -2177104: 72, -2177105: 255, -2177106: 127, -2177107: 0, -2177108: 0, -2177109: 255, -2177110: 127, -2177111: 229, -2177112: 68, -2177113: 195, -2177114: 8, -2177115: 0, -2177116: 3, -2177117: 194, -2177118: 18, -2177119: 17, -2177120: 169, -2177121: 30, -2177122: 69, -2177123: 1, -2177124: 187, -2177125: 94, -2177126: 179, -2177127: 61, -2177128: 46, -2177129: 41, -2177130: 134, -2177131: 20, -2177132: 16, -2177133: 66, -2177134: 0, -2177135: 4, -2177136: 129, -2177137: 20, -2177138: 195, -2177139: 32, -2177140: 2, -2177141: 223, -2177142: 2, -2177143: 31, -2177144: 34, -2177145: 0, -2177146: 224, -2177147: 61, -2177148: 3, -2177149: 32, -2177150: 188, -2177151: 114, -2177152: 251, -2177153: 72, -2177154: 22, -2177155: 24, -2177156: 157, -2177157: 42, -2177158: 214, -2177159: 25, -2177160: 16, -2177161: 13, -2177162: 72, -2177163: 0, -2177164: 133, -2177165: 33, -2177166: 2, -2177167: 21, -2177168: 193, -2177169: 16, -2177170: 96, -2177171: 4, -2177172: 72, -2177173: 66, -2177174: 181, -2177175: 26, -2177176: 255, -2177177: 127, -2177178: 33, -2177179: 8, -2177180: 0, -2177181: 0, -2177182: 178, -2177183: 114, -2177184: 199, -2177185: 113, -2177186: 3, -2177187: 77, -2177188: 170, -2177189: 33, -2177190: 71, -2177191: 21, -2177192: 229, -2177193: 16, -2177194: 130, -2177195: 4, -2177196: 201, -2177197: 16, -2177198: 135, -2177199: 12, -2177200: 36, -2177201: 4, -2177202: 1, -2177203: 0, -2177204: 110, -2177205: 33, -2177206: 128, -2177207: 8, -2177208: 185, -2177209: 54, -2177210: 35, -2177211: 0, -2177212: 28, -2177213: 102, -2177214: 69, -2177215: 227, -2177216: 40, -2177217: 96, -2177218: 28, -2177219: 176, -2177220: 54, -2177221: 11, -2177222: 38, -2177223: 104, -2177224: 25, -2177225: 226, -2177226: 12, -2177227: 202, -2177228: 90, -2177229: 72, -2177230: 62, -2177231: 99, -2177232: 33, -2177233: 163, -2177234: 4, -2177235: 124, -2177236: 81, -2177237: 23, -2177238: 127, -2177239: 255, -2177240: 127, -2177241: 32, -2177242: 34, -2177243: 0, -2177244: 27, -2177245: 236, -2177246: 41, -2177247: 104, -2177248: 29, -2177249: 6, -2177250: 21, -2177251: 236, -2177252: 82, -2177253: 71, -2177254: 62, -2177255: 68, -2177256: 33, -2177257: 193, -2177258: 16, -2177259: 135, -2177260: 0, -2177261: 233, -2177262: 12, -2177263: 76, -2177264: 17, -2177265: 242, -2177266: 25, -2177267: 2, -2177268: 0, -2177269: 36, -2177270: 0, -2177271: 255, -2177272: 127, -2177273: 35, -2177274: 0, -2177275: 5, -2177276: 49, -2177277: 49, -2177278: 238, -2177279: 40, -2177280: 167, -2177281: 24, -2177282: 197, -2177283: 62, -2177284: 15, -2177285: 128, -2177286: 4, -2177287: 10, -2177288: 13, -2177289: 168, -2177290: 8, -2177291: 102, -2177292: 4, -2177293: 68, -2177294: 0, -2177295: 236, -2177296: 8, -2177297: 215, -2177298: 22, -2177299: 16, -2177300: 66, -2177301: 35, -2177302: 0, -2177303: 69, -2177304: 16, -2177305: 66, -2177306: 199, -2177307: 96, -2177308: 15, -2177309: 87, -2177310: 119, -2177311: 114, -2177312: 110, -2177313: 238, -2177314: 89, -2177315: 106, -2177316: 69, -2177317: 40, -2177318: 53, -2177319: 5, -2177320: 37, -2177321: 156, -2177322: 127, -2177323: 0, -2177324: 0, -2177325: 255, -2177326: 27, -2177327: 0, -2177328: 0, -2177329: 223, -2177330: 2, -2177331: 215, -2177332: 1, -2177333: 172, -2177334: 0, -2177335: 250, -2177336: 105, -2177337: 52, -2177338: 73, -2177339: 173, -2177340: 44, -2177341: 103, -2177342: 20, -2177343: 177, -2177344: 11, -2177345: 251, -2177346: 72, -2177347: 255, -2177348: 127, -2177349: 0, -2177350: 0, -2177351: 255, -2177352: 127, -2177353: 229, -2177354: 68, -2177355: 195, -2177356: 8, -2177357: 21, -2177358: 3, -2177359: 32, -2177360: 177, -2177361: 11, -2177362: 169, -2177363: 30, -2177364: 69, -2177365: 1, -2177366: 187, -2177367: 94, -2177368: 179, -2177369: 61, -2177370: 46, -2177371: 41, -2177372: 134, -2177373: 20, -2177374: 16, -2177375: 66, -2177376: 0, -2177377: 4, -2177378: 35, -2177379: 20, -2177380: 195, -2177381: 32, -2177382: 2, -2177383: 223, -2177384: 2, -2177385: 31, -2177386: 34, -2177387: 0, -2177388: 23, -2177389: 3, -2177390: 32, -2177391: 188, -2177392: 114, -2177393: 251, -2177394: 72, -2177395: 22, -2177396: 24, -2177397: 217, -2177398: 62, -2177399: 87, -2177400: 46, -2177401: 53, -2177402: 42, -2177403: 243, -2177404: 37, -2177405: 210, -2177406: 37, -2177407: 176, -2177408: 29, -2177409: 110, -2177410: 25, -2177411: 46, -2177412: 17, -2177413: 195, -2177414: 80, -2177415: 1, -2177416: 255, -2177417: 127, -2177418: 35, -2177419: 0, -2177420: 27, -2177421: 178, -2177422: 114, -2177423: 199, -2177424: 113, -2177425: 3, -2177426: 77, -2177427: 32, -2177428: 0, -2177429: 97, -2177430: 4, -2177431: 162, -2177432: 8, -2177433: 227, -2177434: 12, -2177435: 36, -2177436: 17, -2177437: 101, -2177438: 21, -2177439: 166, -2177440: 25, -2177441: 9, -2177442: 38, -2177443: 102, -2177444: 4, -2177445: 36, -2177446: 0, -2177447: 255, -2177448: 127, -2177449: 35, -2177450: 0, -2177451: 224, -2177452: 59, -2177453: 106, -2177454: 61, -2177455: 40, -2177456: 53, -2177457: 197, -2177458: 40, -2177459: 209, -2177460: 29, -2177461: 110, -2177462: 21, -2177463: 11, -2177464: 17, -2177465: 135, -2177466: 4, -2177467: 100, -2177468: 37, -2177469: 3, -2177470: 29, -2177471: 194, -2177472: 20, -2177473: 129, -2177474: 12, -2177475: 255, -2177476: 127, -2177477: 36, -2177478: 0, -2177479: 40, -2177480: 54, -2177481: 96, -2177482: 8, -2177483: 0, -2177484: 0, -2177485: 191, -2177486: 99, -2177487: 93, -2177488: 83, -2177489: 251, -2177490: 66, -2177491: 239, -2177492: 69, -2177493: 107, -2177494: 53, -2177495: 231, -2177496: 36, -2177497: 132, -2177498: 24, -2177499: 135, -2177500: 0, -2177501: 233, -2177502: 12, -2177503: 76, -2177504: 17, -2177505: 242, -2177506: 25, -2177507: 1, -2177508: 0, -2177509: 38, -2177510: 0, -2177511: 90, -2177512: 115, -2177513: 35, -2177514: 0, -2177515: 224, -2177516: 61, -2177517: 36, -2177518: 29, -2177519: 161, -2177520: 16, -2177521: 96, -2177522: 8, -2177523: 2, -2177524: 0, -2177525: 35, -2177526: 0, -2177527: 69, -2177528: 4, -2177529: 102, -2177530: 4, -2177531: 103, -2177532: 8, -2177533: 136, -2177534: 8, -2177535: 170, -2177536: 12, -2177537: 203, -2177538: 12, -2177539: 16, -2177540: 66, -2177541: 255, -2177542: 127, -2177543: 35, -2177544: 0, -2177545: 64, -2177546: 4, -2177547: 0, -2177548: 0, -2177549: 21, -2177550: 38, -2177551: 113, -2177552: 25, -2177553: 235, -2177554: 12, -2177555: 154, -2177556: 101, -2177557: 51, -2177558: 77, -2177559: 238, -2177560: 60, -2177561: 137, -2177562: 44, -2177563: 91, -2177564: 123, -2177565: 182, -2177566: 102, -2177567: 50, -2177568: 86, -2177569: 207, -2177570: 73, -2177571: 45, -2177572: 61, -2177573: 201, -2177574: 40, -2177575: 101, -2177576: 28, -2177577: 1, -2177578: 8, -2177579: 255, -2177580: 29, -2177581: 0, -2177582: 0, -2177583: 223, -2177584: 2, -2177585: 215, -2177586: 1, -2177587: 172, -2177588: 0, -2177589: 244, -2177590: 106, -2177591: 111, -2177592: 90, -2177593: 170, -2177594: 61, -2177595: 229, -2177596: 32, -2177597: 177, -2177598: 11, -2177599: 251, -2177600: 72, -2177601: 255, -2177602: 127, -2177603: 0, -2177604: 0, -2177605: 255, -2177606: 127, -2177607: 229, -2177608: 68, -2177609: 255, -2177610: 127, -2177611: 34, -2177612: 0, -2177613: 20, -2177614: 56, -2177615: 177, -2177616: 11, -2177617: 169, -2177618: 30, -2177619: 69, -2177620: 1, -2177621: 187, -2177622: 94, -2177623: 179, -2177624: 61, -2177625: 46, -2177626: 41, -2177627: 134, -2177628: 20, -2177629: 24, -2177630: 99, -2177631: 82, -2177632: 74, -2177633: 140, -2177634: 49, -2177635: 195, -2177636: 32, -2177637: 2, -2177638: 223, -2177639: 2, -2177640: 31, -2177641: 35, -2177642: 0, -2177643: 6, -2177644: 56, -2177645: 188, -2177646: 114, -2177647: 251, -2177648: 72, -2177649: 22, -2177650: 24, -2177651: 83, -2177652: 128, -2177653: 21, -2177654: 1, -2177655: 255, -2177656: 127, -2177657: 34, -2177658: 0, -2177659: 6, -2177660: 56, -2177661: 178, -2177662: 114, -2177663: 199, -2177664: 113, -2177665: 3, -2177666: 77, -2177667: 83, -2177668: 128, -2177669: 21, -2177670: 1, -2177671: 255, -2177672: 127, -2177673: 34, -1129098: 2, -2177675: 8, -2177676: 56, -2177677: 255, -2177678: 127, -2177679: 247, -2177680: 94, -2177681: 16, -2177682: 66, -2177683: 8, -2177684: 33, -2177685: 199, -2177686: 8, -2177687: 77, -2177688: 128, -2177689: 21, -2177690: 31, -2177691: 0, -2177692: 56, -2177693: 87, -2177694: 63, -2177695: 77, -2177696: 46, -2177697: 226, -2177698: 0, -2177699: 96, -2177700: 0, -2177701: 176, -2177702: 58, -2177703: 11, -2177704: 34, -2177705: 102, -2177706: 17, -2177707: 36, -2177708: 9, -2177709: 25, -2177710: 3, -2177711: 84, -2177712: 2, -2177713: 143, -2177714: 1, -2177715: 202, -2177716: 0, -2177717: 27, -2177718: 88, -2177719: 146, -2177720: 24, -2177721: 69, -2177722: 1, -2177723: 194, -2177724: 64, -2177725: 14, -2177726: 87, -2177727: 247, -2177728: 66, -2177729: 140, -2177730: 21, -2177731: 165, -2177732: 0, -2177733: 90, -2177734: 79, -2177735: 181, -2177736: 54, -2177737: 16, -2177738: 38, -2177739: 206, -2177740: 29, -2177741: 205, -2177742: 48, -2177743: 21, -2177744: 0, -2177745: 56, -2177746: 156, -2177747: 75, -2177748: 148, -2177749: 54, -2177750: 41, -2177751: 9, -2177752: 66, -2177753: 0, -2177754: 247, -2177755: 66, -2177756: 82, -2177757: 42, -2177758: 173, -2177759: 25, -2177760: 107, -2177761: 17, -2177762: 231, -2177763: 0, -2177764: 132, -2177765: 0, -2177766: 71, -2177767: 128, -2177768: 21, -2177769: 1, -2177770: 224, -2177771: 127, -2177772: 255, -2177773: 29, -2177774: 0, -2177775: 0, -2177776: 223, -2177777: 2, -2177778: 215, -2177779: 1, -2177780: 172, -2177781: 0, -2177782: 115, -2177783: 90, -2177784: 173, -2177785: 65, -2177786: 8, -2177787: 45, -2177788: 99, -2177789: 24, -2177790: 177, -2177791: 11, -2177792: 251, -2177793: 72, -2177794: 255, -2177795: 127, -2177796: 0, -2177797: 0, -2177798: 255, -2177799: 127, -2177800: 229, -2177801: 68, -2177802: 255, -2177803: 127, -2177804: 35, -2177805: 0, -2177806: 19, -2177807: 177, -2177808: 11, -2177809: 169, -2177810: 30, -2177811: 69, -2177812: 1, -2177813: 187, -2177814: 94, -2177815: 179, -2177816: 61, -2177817: 46, -2177818: 41, -2177819: 134, -2177820: 20, -2177821: 24, -2177822: 99, -2177823: 82, -2177824: 74, -2177825: 140, -2177826: 49, -2177827: 195, -2177828: 32, -2177829: 2, -2177830: 223, -2177831: 2, -2177832: 31, -2177833: 36, -2177834: 0, -2177835: 21, -2177836: 188, -2177837: 114, -2177838: 251, -2177839: 72, -2177840: 22, -2177841: 24, -2177842: 84, -2177843: 47, -2177844: 114, -2177845: 2, -2177846: 110, -2177847: 1, -2177848: 71, -2177849: 0, -2177850: 138, -2177851: 24, -2177852: 39, -2177853: 12, -2177854: 36, -2177855: 4, -2177856: 2, -2177857: 4, -2177858: 67, -2177859: 69, -2177860: 1, -2177861: 1, -2177862: 255, -2177863: 127, -2177864: 35, -2177865: 0, -2177866: 21, -2177867: 178, -2177868: 114, -2177869: 199, -2177870: 113, -2177871: 3, -2177872: 77, -2177873: 30, -2177874: 103, -2177875: 22, -2177876: 74, -2177877: 145, -2177878: 53, -2177879: 233, -2177880: 32, -2177881: 237, -2177882: 65, -2177883: 39, -2177884: 45, -2177885: 193, -2177886: 24, -2177887: 96, -2177888: 16, -2177889: 35, -2177890: 0, -2177891: 1, -2177892: 223, -2177893: 2, -2177894: 35, -2177895: 0, -2177896: 15, -2177897: 249, -2177898: 70, -2177899: 18, -2177900: 54, -2177901: 233, -2177902: 16, -2177903: 165, -2177904: 0, -2177905: 117, -2177906: 66, -2177907: 208, -2177908: 41, -2177909: 43, -2177910: 25, -2177911: 200, -2177912: 12, -2177913: 199, -2177914: 74, -2177915: 7, -2177916: 188, -2177917: 114, -2177918: 157, -2177919: 85, -2177920: 22, -2177921: 24, -2177922: 0, -2177923: 0, -2177924: 67, -2177925: 24, -2177926: 99, -2177927: 23, -2177928: 2, -2177929: 8, -2177930: 148, -2177931: 82, -2177932: 206, -2177933: 57, -2177934: 8, -2177935: 33, -2177936: 132, -2177937: 16, -2177938: 25, -2177939: 0, -2177940: 18, -2177941: 0, -2177942: 0, -2177943: 92, -2177944: 0, -2177945: 64, -2177946: 132, -2177947: 16, -2177948: 127, -2177949: 25, -2177950: 255, -2177951: 127, -2177952: 35, -2177953: 0, -2177954: 15, -2177955: 156, -2177956: 75, -2177957: 148, -2177958: 54, -2177959: 41, -2177960: 9, -2177961: 66, -2177962: 0, -2177963: 247, -2177964: 66, -2177965: 82, -2177966: 42, -2177967: 173, -2177968: 25, -2177969: 107, -2177970: 17, -2177971: 75, -2177972: 69, -2177973: 1, -2177974: 3, -2177975: 2, -2177976: 4, -2177977: 0, -2177978: 0, -2177979: 67, -2177980: 24, -2177981: 99, -2177982: 217, -2177983: 64, -2177984: 255, -2177985: 27, -2177986: 0, -2177987: 0, -2177988: 223, -2177989: 2, -2177990: 215, -2177991: 1, -2177992: 172, -2177993: 0, -2177994: 115, -2177995: 90, -2177996: 173, -2177997: 65, -2177998: 8, -2177999: 45, -2178000: 99, -2178001: 24, -2178002: 177, -2178003: 11, -2178004: 251, -2178005: 72, -2178006: 255, -2178007: 127, -2178008: 0, -2178009: 0, -2178010: 255, -2178011: 127, -2178012: 229, -2178013: 68, -2178014: 195, -2178015: 8, -2178016: 21, -2178017: 3, -2178018: 32, -2178019: 177, -2178020: 11, -2178021: 169, -2178022: 30, -2178023: 69, -2178024: 1, -2178025: 187, -2178026: 94, -2178027: 179, -2178028: 61, -2178029: 46, -2178030: 41, -2178031: 134, -2178032: 20, -2178033: 24, -2178034: 99, -2178035: 63, -2178036: 14, -2178037: 127, -2178038: 13, -2178039: 195, -2178040: 32, -2178041: 2, -2178042: 223, -2178043: 2, -2178044: 31, -2178045: 34, -2178046: 0, -2178047: 23, -2178048: 3, -2178049: 32, -2178050: 188, -2178051: 114, -2178052: 251, -2178053: 72, -2178054: 22, -2178055: 24, -2178056: 84, -2178057: 47, -2178058: 114, -2178059: 2, -2178060: 110, -2178061: 1, -2178062: 71, -2178063: 0, -2178064: 138, -2178065: 24, -2178066: 39, -2178067: 12, -2178068: 36, -2178069: 4, -2178070: 2, -2178071: 4, -2178072: 67, -2178073: 69, -2178074: 1, -2178075: 1, -2178076: 255, -2178077: 127, -2178078: 35, -2178079: 0, -2178080: 21, -2178081: 178, -2178082: 114, -2178083: 199, -2178084: 113, -2178085: 3, -2178086: 77, -2178087: 22, -2178088: 74, -2178089: 145, -2178090: 57, -2178091: 44, -2178092: 45, -2178093: 167, -2178094: 28, -2178095: 229, -2178096: 32, -2178097: 164, -2178098: 24, -2178099: 131, -2178100: 16, -2178101: 65, -2178102: 8, -2178103: 35, -2178104: 0, -2178105: 1, -2178106: 223, -2178107: 2, -2178108: 35, -2178109: 0, -2178110: 27, -2178111: 191, -2178112: 4, -2178113: 150, -2178114: 4, -2178115: 77, -2178116: 0, -2178117: 36, -2178118: 0, -2178119: 57, -2178120: 87, -2178121: 115, -2178122: 66, -2178123: 173, -2178124: 45, -2178125: 198, -2178126: 20, -2178127: 127, -2178128: 54, -2178129: 249, -2178130: 41, -2178131: 115, -2178132: 33, -2178133: 12, -2178134: 21, -2178135: 134, -2178136: 12, -2178137: 255, -2178138: 127, -2178139: 35, -2178140: 0, -2178141: 67, -2178142: 24, -2178143: 99, -2178144: 23, -2178145: 2, -2178146: 8, -2178147: 148, -2178148: 82, -2178149: 206, -2178150: 57, -2178151: 8, -2178152: 33, -2178153: 132, -2178154: 16, -2178155: 25, -2178156: 0, -2178157: 18, -2178158: 0, -2178159: 0, -2178160: 92, -2178161: 0, -2178162: 64, -2178163: 132, -2178164: 16, -2178165: 127, -2178166: 25, -2178167: 255, -2178168: 127, -2178169: 35, -2178170: 0, -2178171: 197, -2178172: 26, -2178173: 21, -2178174: 139, -2178175: 127, -2178176: 10, -2178177: 111, -2178178: 136, -2178179: 94, -2178180: 7, -2178181: 78, -2178182: 134, -2178183: 57, -2178184: 5, -2178185: 41, -2178186: 131, -2178187: 24, -2178188: 2, -2178189: 8, -2178190: 132, -2178191: 16, -2178192: 24, -2178193: 99, -2178194: 255, -2178195: 127, -2178196: 35, -2178197: 0, -2178198: 67, -2178199: 24, -2178200: 99, -2178201: 217, -2178202: 64, -2178203: 255, -2178204: 27, -2178205: 0, -2178206: 0, -2178207: 223, -2178208: 2, -2178209: 215, -2178210: 1, -2178211: 172, -2178212: 0, -2178213: 115, -2178214: 90, -2178215: 173, -2178216: 65, -2178217: 8, -2178218: 45, -2178219: 99, -2178220: 24, -2178221: 177, -2178222: 11, -2178223: 251, -2178224: 72, -2178225: 255, -2178226: 127, -2178227: 0, -2178228: 0, -2178229: 255, -2178230: 127, -2178231: 229, -2178232: 68, -2178233: 195, -2178234: 8, -2178235: 21, -2178236: 3, -2178237: 32, -2178238: 177, -2178239: 11, -2178240: 169, -2178241: 30, -2178242: 69, -2178243: 1, -2178244: 187, -2178245: 94, -2178246: 179, -2178247: 61, -2178248: 46, -2178249: 41, -2178250: 134, -2178251: 20, -2178252: 24, -2178253: 99, -2178254: 227, -2178255: 40, -2178256: 96, -2178257: 28, -2178258: 195, -2178259: 32, -2178260: 2, -2178261: 223, -2178262: 2, -2178263: 31, -2178264: 34, -2178265: 0, -2178266: 29, -2178267: 3, -2178268: 32, -2178269: 188, -2178270: 114, -2178271: 251, -2178272: 72, -2178273: 22, -2178274: 24, -2178275: 255, -2178276: 107, -2178277: 243, -2178278: 66, -2178279: 12, -2178280: 22, -2178281: 4, -2178282: 9, -2178283: 146, -2178284: 42, -2178285: 171, -2178286: 9, -2178287: 38, -2178288: 1, -2178289: 33, -2178290: 0, -2178291: 131, -2178292: 0, -2178293: 16, -2178294: 26, -2178295: 255, -2178296: 127, -2178297: 35, -2178298: 0, -2178299: 19, -2178300: 178, -2178301: 114, -2178302: 199, -2178303: 113, -2178304: 3, -2178305: 77, -2178306: 73, -2178307: 12, -2178308: 40, -2178309: 20, -2178310: 39, -2178311: 16, -2178312: 6, -2178313: 12, -2178314: 5, -2178315: 16, -2178316: 4, -2178317: 12, -2178318: 3, -2178319: 12, -2178320: 69, -2178321: 130, -2178322: 21, -2178323: 1, -2178324: 255, -2178325: 127, -2178326: 35, -2178327: 0, -2178328: 21, -2178329: 88, -2178330: 82, -2178331: 244, -2178332: 69, -2178333: 177, -2178334: 57, -2178335: 78, -2178336: 49, -2178337: 11, -2178338: 37, -2178339: 200, -2178340: 24, -2178341: 134, -2178342: 20, -2178343: 57, -2178344: 79, -2178345: 115, -2178346: 54, -2178347: 173, -2178348: 29, -2178349: 41, -2178350: 13, -2178351: 67, -2178352: 130, -2178353: 21, -2178354: 1, -2178355: 255, -2178356: 127, -2178357: 35, -2178358: 0, -2178359: 13, -2178360: 182, -2178361: 11, -2178362: 174, -2178363: 30, -2178364: 74, -2178365: 1, -2178366: 88, -2178367: 82, -2178368: 80, -2178369: 49, -2178370: 203, -2178371: 28, -2178372: 35, -2178373: 8, -2178374: 199, -2178375: 136, -2178376: 67, -2178377: 130, -2178378: 21, -2178379: 1, -2178380: 255, -2178381: 127, -2178382: 35, -2178383: 0, -2178384: 21, -2178385: 255, -2178386: 87, -2178387: 255, -2178388: 43, -2178389: 60, -2178390: 31, -2178391: 120, -2178392: 2, -2178393: 176, -2178394: 1, -2178395: 11, -2178396: 1, -2178397: 135, -2178398: 0, -2178399: 68, -2178400: 0, -2178401: 224, -2178402: 127, -2178403: 64, -2178404: 74, -2178405: 32, -2178406: 37, -2178407: 69, -2178408: 255, -2178409: 127, -2178410: 35, -2178411: 0, -2178412: 207, -2178413: 32, -2178414: 69, -2178415: 255, -2178416: 127, -2178417: 7, -2178418: 224, -2178419: 3, -2178420: 64, -2178421: 2, -2178422: 32, -2178423: 1, -2178424: 0, -2178425: 0, -2178426: 255, -2178427: 27, -2178428: 0, -2178429: 0, -2178430: 223, -2178431: 2, -2178432: 215, -2178433: 1, -2178434: 172, -2178435: 0, -2178436: 187, -2178437: 94, -2178438: 179, -2178439: 61, -2178440: 46, -2178441: 41, -2178442: 134, -2178443: 20, -2178444: 177, -2178445: 11, -2178446: 251, -2178447: 72, -2178448: 255, -2178449: 127, -2178450: 0, -2178451: 0, -2178452: 255, -2178453: 127, -2178454: 229, -2178455: 68, -2178456: 195, -2178457: 8, -2178458: 7, -2178459: 3, -2178460: 32, -2178461: 177, -2178462: 11, -2178463: 169, -2178464: 30, -2178465: 69, -2178466: 1, -2178467: 199, -2178468: 32, -2178469: 5, -2178470: 24, -2178471: 99, -2178472: 227, -2178473: 40, -2178474: 96, -2178475: 28, -2178476: 195, -2178477: 32, -2178478: 2, -2178479: 223, -2178480: 2, -2178481: 31, -2178482: 34, -2178483: 0, -2178484: 29, -2178485: 3, -2178486: 32, -2178487: 213, -2178488: 85, -2178489: 182, -2178490: 56, -2178491: 15, -2178492: 0, -2178493: 255, -2178494: 107, -2178495: 243, -2178496: 66, -2178497: 12, -2178498: 22, -2178499: 4, -2178500: 9, -2178501: 146, -2178502: 42, -2178503: 171, -2178504: 9, -2178505: 38, -2178506: 1, -2178507: 33, -2178508: 0, -2178509: 131, -2178510: 0, -2178511: 16, -2178512: 26, -2178513: 255, -2178514: 127, -2178515: 35, -2178516: 0, -2178517: 6, -2178518: 203, -2178519: 85, -2178520: 224, -2178521: 84, -2178522: 0, -2178523: 40, -2178524: 4, -2178525: 68, -2178526: 0, -2178527: 3, -2178528: 0, -2178529: 2, -2178530: 67, -2178531: 0, -2178532: 1, -2178533: 34, -2178534: 0, -2178535: 69, -2178536: 130, -2178537: 21, -2178538: 1, -2178539: 255, -2178540: 127, -2178541: 35, -2178542: 0, -2178543: 21, -2178544: 138, -2178545: 24, -2178546: 105, -2178547: 20, -2178548: 103, -2178549: 16, -2178550: 70, -2178551: 16, -2178552: 37, -2178553: 12, -2178554: 35, -2178555: 8, -2178556: 2, -2178557: 4, -2178558: 48, -2178559: 46, -2178560: 140, -2178561: 29, -2178562: 7, -2178563: 17, -2178564: 99, -2178565: 0, -2178566: 67, -2178567: 130, -2178568: 21, -2178569: 1, -2178570: 255, -2178571: 127, -2178572: 35, -2178573: 0, -2178574: 13, -2178575: 41, -2178576: 2, -2178577: 135, -2178578: 1, -2178579: 197, -2178580: 0, -2178581: 46, -2178582: 45, -2178583: 202, -2178584: 32, -2178585: 102, -2178586: 16, -2178587: 2, -2178588: 4, -2178589: 199, -2178590: 136, -2178591: 67, -2178592: 130, -2178593: 21, -2178594: 1, -2178595: 181, -2178596: 86, -2178597: 35, -2178598: 0, -2178599: 27, -1130024: 19, -1130025: 0, -2178602: 255, -2178603: 43, -1130028: 11, -1130029: 0, -2178606: 120, -1130031: 127, -1130032: 156, -2178609: 1, -2178610: 11, -1130035: 2, -2178612: 135, -2178613: 0, -2178614: 68, -2178615: 0, -2178616: 31, -2178617: 0, -2178618: 18, -2178619: 0, -2178620: 9, -2178621: 0, -2178622: 255, -2178623: 3, -2178624: 82, -2178625: 2, -2178626: 41, -2178627: 1, -2178628: 35, -2178629: 0, -2178630: 207, -2178631: 32, -2178632: 13, -2178633: 224, -2178634: 127, -2178635: 64, -2178636: 74, -2178637: 32, -2178638: 37, -2178639: 224, -2178640: 3, -2178641: 64, -2178642: 2, -2178643: 32, -2178644: 1, -2178645: 0, -2178646: 0, -2178647: 255, -2178648: 27, -2178649: 0, -2178650: 0, -2178651: 223, -2178652: 2, -2178653: 215, -2178654: 1, -2178655: 172, -2178656: 0, -2178657: 115, -2178658: 90, -2178659: 173, -2178660: 65, -2178661: 8, -2178662: 45, -2178663: 99, -2178664: 24, -2178665: 177, -2178666: 11, -2178667: 251, -2178668: 72, -2178669: 255, -2178670: 127, -2178671: 0, -2178672: 0, -2178673: 255, -2178674: 127, -2178675: 229, -2178676: 68, -2178677: 195, -2178678: 8, -2178679: 21, -2178680: 3, -2178681: 32, -2178682: 177, -2178683: 11, -2178684: 169, -2178685: 30, -2178686: 69, -2178687: 1, -2178688: 187, -2178689: 94, -2178690: 179, -2178691: 61, -2178692: 46, -2178693: 41, -2178694: 134, -2178695: 20, -2178696: 24, -2178697: 99, -2178698: 214, -2178699: 90, -2178700: 82, -2178701: 74, -2178702: 195, -2178703: 32, -2178704: 2, -2178705: 223, -2178706: 2, -2178707: 31, -2178708: 34, -2178709: 0, -2178710: 29, -2178711: 3, -2178712: 32, -2178713: 188, -2178714: 114, -2178715: 251, -2178716: 72, -2178717: 22, -2178718: 24, -2178719: 255, -2178720: 107, -2178721: 243, -2178722: 66, -2178723: 12, -2178724: 22, -2178725: 4, -2178726: 9, -2178727: 146, -2178728: 42, -2178729: 171, -2178730: 9, -2178731: 38, -2178732: 1, -2178733: 33, -2178734: 0, -2178735: 131, -2178736: 0, -2178737: 16, -2178738: 26, -2178739: 255, -2178740: 127, -2178741: 35, -2178742: 0, -2178743: 19, -2178744: 178, -2178745: 114, -2178746: 199, -2178747: 113, -2178748: 3, -2178749: 77, -2178750: 66, -2178751: 60, -2178752: 66, -2178753: 52, -2178754: 33, -2178755: 40, -2178756: 33, -2178757: 32, -2178758: 33, -2178759: 24, -2178760: 0, -2178761: 12, -2178762: 0, -2178763: 4, -2178764: 69, -2178765: 130, -2178766: 21, -2178767: 1, -2178768: 255, -2178769: 127, -2178770: 35, -2178771: 0, -2178772: 21, -2178773: 199, -2178774: 113, -2178775: 134, -2178776: 97, -2178777: 69, -2178778: 81, -2178779: 4, -2178780: 65, -2178781: 163, -2178782: 44, -2178783: 98, -2178784: 28, -2178785: 33, -2178786: 12, -2178787: 86, -2178788: 123, -2178789: 176, -2178790: 110, -2178791: 224, -2178792: 117, -2178793: 35, -2178794: 85, -2178795: 67, -2178796: 130, -2178797: 21, -2178798: 1, -2178799: 255, -2178800: 127, -2178801: 35, -2178802: 0, -2178803: 13, -2178804: 182, -2178805: 11, -2178806: 174, -2178807: 30, -2178808: 74, -2178809: 1, -2178810: 145, -2178811: 110, -2178812: 199, -2178813: 113, -2178814: 66, -2178815: 40, -2178816: 33, -2178817: 20, -2178818: 199, -2178819: 32, -2178820: 67, -2178821: 130, -2178822: 21, -2178823: 1, -2178824: 255, -2178825: 127, -2178826: 35, -2178827: 0, -2178828: 27, -2178829: 255, -2178830: 87, -2178831: 255, -2178832: 43, -2178833: 60, -2178834: 31, -2178835: 120, -2178836: 2, -2178837: 176, -2178838: 1, -2178839: 11, -2178840: 1, -2178841: 135, -2178842: 0, -2178843: 68, -2178844: 0, -2178845: 31, -2178846: 0, -2178847: 18, -2178848: 0, -2178849: 9, -2178850: 0, -2178851: 255, -2178852: 3, -2178853: 82, -2178854: 2, -2178855: 41, -2178856: 1, -2178857: 35, -2178858: 0, -2178859: 207, -2178860: 32, -2178861: 13, -2178862: 224, -2178863: 127, -2178864: 64, -2178865: 74, -2178866: 32, -2178867: 37, -2178868: 224, -2178869: 3, -2178870: 64, -2178871: 2, -2178872: 32, -2178873: 1, -2178874: 0, -2178875: 0, -2178876: 255, -2178877: 27, -2178878: 0, -2178879: 0, -2178880: 223, -2178881: 2, -2178882: 215, -2178883: 1, -2178884: 172, -2178885: 0, -2178886: 115, -2178887: 90, -2178888: 173, -2178889: 65, -2178890: 8, -2178891: 45, -2178892: 99, -2178893: 24, -2178894: 177, -2178895: 11, -2178896: 251, -2178897: 72, -2178898: 255, -2178899: 127, -2178900: 0, -2178901: 0, -2178902: 255, -2178903: 127, -2178904: 229, -2178905: 68, -2178906: 195, -2178907: 8, -2178908: 21, -2178909: 3, -2178910: 32, -2178911: 177, -2178912: 11, -2178913: 169, -2178914: 30, -2178915: 69, -2178916: 1, -2178917: 187, -2178918: 94, -2178919: 179, -2178920: 61, -2178921: 46, -2178922: 41, -2178923: 134, -2178924: 20, -2178925: 24, -2178926: 99, -2178927: 214, -2178928: 90, -2178929: 82, -2178930: 74, -2178931: 195, -2178932: 32, -2178933: 2, -2178934: 223, -2178935: 2, -2178936: 31, -2178937: 34, -2178938: 0, -2178939: 29, -2178940: 3, -2178941: 32, -2178942: 188, -2178943: 114, -2178944: 251, -2178945: 72, -2178946: 22, -2178947: 24, -2178948: 255, -2178949: 107, -2178950: 243, -2178951: 66, -2178952: 12, -2178953: 22, -2178954: 4, -2178955: 9, -2178956: 146, -2178957: 42, -2178958: 171, -2178959: 9, -2178960: 38, -2178961: 1, -2178962: 33, -2178963: 0, -2178964: 131, -2178965: 0, -2178966: 16, -2178967: 26, -2178968: 255, -2178969: 127, -2178970: 35, -2178971: 0, -2178972: 19, -2178973: 178, -2178974: 114, -2178975: 199, -2178976: 113, -2178977: 3, -2178978: 77, -2178979: 226, -2178980: 12, -2178981: 194, -2178982: 12, -2178983: 161, -2178984: 8, -2178985: 129, -2178986: 8, -2178987: 65, -2178988: 4, -2178989: 32, -2178990: 4, -2178991: 0, -2178992: 0, -2178993: 69, -2178994: 130, -2178995: 21, -2178996: 1, -2178997: 255, -2178998: 127, -2178999: 35, -2179000: 0, -2179001: 21, -2179002: 56, -2179003: 55, -2179004: 180, -2179005: 46, -2179006: 48, -2179007: 38, -2179008: 205, -2179009: 29, -2179010: 73, -2179011: 17, -2179012: 197, -2179013: 8, -2179014: 65, -2179015: 0, -2179016: 221, -2179017: 75, -2179018: 52, -2179019: 51, -2179020: 106, -2179021: 22, -2179022: 99, -2179023: 1, -2179024: 67, -2179025: 130, -2179026: 21, -2179027: 1, -2179028: 255, -2179029: 127, -2179030: 35, -2179031: 0, -2179032: 12, -2179033: 182, -2179034: 11, -2179035: 174, -2179036: 30, -2179037: 74, -2179038: 1, -2179039: 101, -2179040: 35, -2179041: 160, -2179042: 21, -2179043: 224, -2179044: 4, -2179045: 32, -2179046: 200, -2179047: 32, -2179048: 67, -2179049: 130, -2179050: 21, -2179051: 1, -2179052: 255, -2179053: 127, -2179054: 35, -2179055: 0, -2179056: 27, -2179057: 255, -2179058: 87, -2179059: 255, -2179060: 43, -2179061: 60, -2179062: 31, -2179063: 120, -2179064: 2, -2179065: 176, -2179066: 1, -2179067: 11, -2179068: 1, -2179069: 135, -2179070: 0, -2179071: 68, -2179072: 0, -2179073: 31, -2179074: 0, -2179075: 18, -2179076: 0, -2179077: 9, -2179078: 0, -2179079: 255, -2179080: 3, -2179081: 82, -2179082: 2, -2179083: 41, -2179084: 1, -2179085: 35, -2179086: 0, -2179087: 207, -2179088: 32, -2179089: 13, -2179090: 224, -2179091: 127, -2179092: 64, -2179093: 74, -2179094: 32, -2179095: 37, -2179096: 224, -2179097: 3, -2179098: 64, -2179099: 2, -2179100: 32, -2179101: 1, -2179102: 0, -2179103: 0, -2179104: 255, -2179105: 27, -2179106: 0, -2179107: 0, -2179108: 223, -2179109: 2, -2179110: 215, -2179111: 1, -2179112: 172, -2179113: 0, -2179114: 115, -2179115: 90, -2179116: 173, -2179117: 65, -2179118: 8, -2179119: 45, -2179120: 99, -2179121: 24, -2179122: 177, -2179123: 11, -2179124: 251, -2179125: 72, -2179126: 255, -2179127: 127, -2179128: 0, -2179129: 0, -2179130: 255, -2179131: 127, -2179132: 229, -2179133: 68, -2179134: 195, -2179135: 8, -2179136: 21, -2179137: 3, -2179138: 32, -2179139: 177, -2179140: 11, -2179141: 169, -2179142: 30, -2179143: 69, -2179144: 1, -2179145: 187, -2179146: 94, -2179147: 179, -2179148: 61, -2179149: 46, -2179150: 41, -2179151: 134, -2179152: 20, -2179153: 24, -2179154: 99, -2179155: 214, -2179156: 90, -2179157: 82, -2179158: 74, -2179159: 195, -2179160: 32, -2179161: 2, -2179162: 223, -2179163: 2, -2179164: 31, -2179165: 34, -2179166: 0, -2179167: 29, -2179168: 3, -2179169: 32, -2179170: 188, -2179171: 114, -2179172: 251, -2179173: 72, -2179174: 22, -2179175: 24, -2179176: 255, -2179177: 107, -2179178: 243, -2179179: 66, -2179180: 12, -2179181: 22, -2179182: 4, -2179183: 9, -2179184: 146, -2179185: 42, -2179186: 171, -2179187: 9, -2179188: 38, -2179189: 1, -2179190: 33, -2179191: 0, -2179192: 131, -2179193: 0, -2179194: 16, -2179195: 26, -2179196: 255, -2179197: 127, -2179198: 35, -2179199: 0, -2179200: 16, -2179201: 178, -2179202: 114, -2179203: 199, -2179204: 113, -2179205: 3, -2179206: 77, -2179207: 135, -2179208: 0, -2179209: 102, -2179210: 0, -2179211: 69, -2179212: 0, -2179213: 36, -2179214: 0, -2179215: 34, -2179216: 0, -2179217: 1, -2179218: 34, -2179219: 0, -2179220: 69, -2179221: 130, -2179222: 21, -2179223: 1, -2179224: 255, -2179225: 127, -2179226: 35, -2179227: 0, -2179228: 8, -2179229: 212, -2179230: 1, -2179231: 144, -2179232: 1, -2179233: 77, -2179234: 1, -2179235: 233, -2179236: 0, -2179237: 137, -2179238: 194, -2179239: 30, -2179240: 9, -2179241: 1, -2179242: 0, -2179243: 152, -2179244: 31, -2179245: 174, -2179246: 30, -2179247: 168, -2179248: 1, -2179249: 161, -2179250: 0, -2179251: 67, -2179252: 130, -2179253: 21, -2179254: 1, -2179255: 255, -2179256: 127, -2179257: 35, -2179258: 0, -2179259: 12, -2179260: 186, -2179261: 55, -2179262: 174, -2179263: 30, -2179264: 74, -2179265: 1, -2179266: 82, -2179267: 41, -2179268: 174, -2179269: 16, -2179270: 72, -2179271: 4, -2179272: 34, -2179273: 200, -2179274: 32, -2179275: 67, -2179276: 130, -2179277: 21, -2179278: 1, -2179279: 255, -2179280: 127, -1130705: 0, -1130706: 56, -1130707: 127, -1130708: 78, -1130709: 117, -1130710: 57, -1130711: 10, -1130712: 12, -1130713: 6, -1130714: 0, -1130715: 216, -1130716: 69, -1130717: 51, -1130718: 45, -1130719: 142, -1130720: 28, -1130721: 43, -1130722: 16, -1130723: 71, -1130724: 83, -1130725: 36, -2179302: 18, -1130727: 98, -1130728: 89, -1130729: 160, -1130730: 92, -1130731: 189, -1130732: 27, -1130733: 253, -1130734: 13, -1130735: 157, -1130736: 0, -2179313: 0, -2179314: 207, -2179315: 32, -2179316: 13, -2179317: 224, -2179318: 127, -2179319: 64, -2179320: 74, -2179321: 32, -2179322: 37, -2179323: 224, -2179324: 3, -2179325: 64, -2179326: 2, -2179327: 32, -2179328: 1, -2179329: 0, -2179330: 0, -2179331: 255, -2179332: 29, -2179333: 0, -2179334: 0, -2179335: 223, -2179336: 2, -2179337: 215, -2179338: 1, -2179339: 172, -2179340: 0, -2179341: 78, -2179342: 94, -2179343: 70, -2179344: 61, -2179345: 193, -2179346: 40, -2179347: 32, -2179348: 20, -2179349: 177, -2179350: 11, -2179351: 251, -2179352: 72, -2179353: 255, -2179354: 127, -2179355: 0, -2179356: 0, -2179357: 255, -2179358: 127, -2179359: 229, -2179360: 68, -2179361: 255, -2179362: 127, -2179363: 35, -2179364: 0, -2179365: 5, -2179366: 177, -2179367: 11, -2179368: 169, -2179369: 30, -2179370: 69, -2179371: 1, -2179372: 199, -2179373: 32, -2179374: 5, -2179375: 24, -2179376: 99, -2179377: 82, -2179378: 74, -2179379: 140, -2179380: 49, -2179381: 195, -2179382: 32, -2179383: 2, -2179384: 223, -2179385: 2, -2179386: 31, -2179387: 36, -2179388: 0, -2179389: 224, -2179390: 61, -2179391: 32, -2179392: 126, -2179393: 96, -2179394: 101, -2179395: 96, -2179396: 32, -2179397: 0, -2179398: 16, -2179399: 64, -2179400: 121, -2179401: 0, -2179402: 93, -2179403: 160, -2179404: 76, -2179405: 160, -2179406: 60, -2179407: 255, -2179408: 127, -2179409: 19, -2179410: 1, -2179411: 15, -2179412: 0, -2179413: 92, -2179414: 23, -2179415: 153, -2179416: 2, -2179417: 214, -2179418: 1, -2179419: 32, -2179420: 12, -2179421: 0, -2179422: 0, -2179423: 245, -2179424: 107, -2179425: 225, -2179426: 6, -2179427: 65, -2179428: 6, -2179429: 161, -2179430: 5, -2179431: 95, -2179432: 94, -2179433: 63, -2179434: 24, -2179435: 20, -2179436: 16, -2179437: 10, -2179438: 8, -2179439: 4, -2179440: 4, -2179441: 159, -2179442: 79, -2179443: 216, -2179444: 62, -2179445: 18, -2179446: 46, -2179447: 112, -2179448: 111, -2179449: 255, -2179450: 127, -2179451: 224, -2179452: 94, -2179453: 34, -2179454: 0, -2179455: 14, -2179456: 124, -2179457: 0, -2179458: 88, -2179459: 0, -2179460: 36, -2179461: 0, -2179462: 16, -2179463: 0, -2179464: 108, -2179465: 0, -2179466: 72, -2179467: 0, -2179468: 64, -2179469: 0, -2179470: 56, -2179471: 47, -2179472: 0, -2179473: 26, -2179474: 96, -2179475: 53, -2179476: 192, -2179477: 36, -2179478: 0, -2179479: 8, -2179480: 0, -2179481: 4, -2179482: 32, -2179483: 49, -2179484: 128, -2179485: 24, -2179486: 64, -2179487: 20, -2179488: 0, -2179489: 28, -2179490: 255, -2179491: 67, -2179492: 24, -2179493: 1, -2179494: 20, -2179495: 0, -2179496: 255, -2179497: 22, -2179498: 62, -2179499: 2, -2179500: 123, -2179501: 196, -2179502: 96, -2179503: 7, -2179504: 242, -2179505: 114, -2179506: 77, -2179507: 106, -2179508: 36, -2179509: 69, -2179510: 0, -2179511: 20, -2179512: 194, -2179513: 96, -2179514: 17, -2179515: 44, -2179516: 20, -2179517: 36, -2179518: 10, -2179519: 28, -2179520: 94, -2179521: 107, -2179522: 120, -2179523: 78, -2179524: 145, -2179525: 41, -2179526: 153, -2179527: 106, -2179528: 116, -2179529: 65, -2179530: 15, -2179531: 64, -2179532: 64, -2179533: 34, -2179534: 0, -2179535: 6, -2179536: 32, -2179537: 126, -2179538: 31, -2179539: 64, -2179540: 0, -2179541: 93, -2179542: 10, -2179543: 195, -2179544: 214, -2179545: 194, -2179546: 98, -2179547: 1, -2179548: 64, -2179549: 121, -2179550: 41, -2179551: 0, -2179552: 195, -2179553: 224, -2179554: 255, -2179555: 29, -2179556: 0, -2179557: 0, -2179558: 223, -2179559: 2, -2179560: 215, -2179561: 1, -2179562: 172, -2179563: 0, -2179564: 85, -2179565: 87, -2179566: 13, -2179567: 62, -2179568: 38, -2179569: 37, -2179570: 96, -2179571: 12, -2179572: 177, -2179573: 11, -2179574: 251, -2179575: 72, -2179576: 255, -2179577: 127, -2179578: 0, -2179579: 0, -2179580: 255, -2179581: 127, -2179582: 229, -2179583: 68, -2179584: 255, -2179585: 127, -2179586: 35, -2179587: 0, -2179588: 5, -2179589: 177, -2179590: 11, -2179591: 169, -2179592: 30, -2179593: 69, -2179594: 1, -2179595: 199, -2179596: 32, -2179597: 5, -2179598: 24, -2179599: 99, -2179600: 82, -2179601: 74, -2179602: 140, -2179603: 49, -2179604: 195, -2179605: 32, -2179606: 2, -2179607: 223, -2179608: 2, -2179609: 31, -2179610: 36, -2179611: 0, -2179612: 27, -2179613: 85, -2179614: 87, -2179615: 79, -2179616: 74, -2179617: 228, -2179618: 28, -2179619: 96, -2179620: 12, -2179621: 178, -2179622: 86, -2179623: 13, -2179624: 62, -2179625: 104, -2179626: 45, -2179627: 38, -2179628: 37, -2179629: 255, -2179630: 71, -2179631: 19, -2179632: 1, -2179633: 15, -2179634: 0, -2179635: 92, -2179636: 23, -2179637: 153, -2179638: 2, -2179639: 214, -2179640: 1, -2179641: 35, -2179642: 0, -2179643: 224, -2179644: 46, -2179645: 245, -2179646: 107, -2179647: 225, -2179648: 6, -2179649: 65, -2179650: 6, -2179651: 161, -2179652: 5, -2179653: 95, -2179654: 94, -2179655: 63, -2179656: 24, -2179657: 20, -2179658: 16, -2179659: 10, -2179660: 8, -2179661: 4, -2179662: 4, -2179663: 159, -2179664: 79, -2179665: 216, -2179666: 62, -2179667: 18, -2179668: 46, -2179669: 112, -2179670: 111, -2179671: 255, -2179672: 127, -2179673: 224, -2179674: 94, -2179675: 0, -2179676: 0, -2179677: 145, -2179678: 38, -2179679: 102, -2179680: 17, -2179681: 128, -2179682: 0, -2179683: 32, -2179684: 0, -2179685: 201, -2179686: 29, -2179687: 102, -2179688: 13, -2179689: 3, -2179690: 5, -2179691: 193, -2179692: 48, -2179693: 0, -2179694: 224, -2179695: 39, -2179696: 112, -2179697: 53, -2179698: 203, -2179699: 36, -2179700: 2, -2179701: 4, -2179702: 1, -2179703: 4, -2179704: 46, -2179705: 49, -2179706: 137, -2179707: 24, -2179708: 38, -2179709: 16, -2179710: 4, -2179711: 12, -2179712: 255, -2179713: 67, -2179714: 24, -2179715: 1, -2179716: 20, -2179717: 0, -2179718: 255, -2179719: 22, -2179720: 62, -2179721: 2, -2179722: 123, -2179723: 1, -2179724: 32, -2179725: 12, -2179726: 0, -2179727: 0, -2179728: 151, -2179729: 95, -2179730: 242, -2179731: 86, -2179732: 201, -2179733: 49, -2179734: 160, -2179735: 0, -2179736: 199, -2179737: 96, -2179738: 5, -2179739: 94, -2179740: 107, -2179741: 120, -2179742: 78, -2179743: 145, -2179744: 41, -2179745: 197, -2179746: 128, -2179747: 35, -2179748: 0, -2179749: 15, -2179750: 59, -2179751: 3, -2179752: 31, -2179753: 0, -2179754: 116, -2179755: 1, -2179756: 10, -2179757: 8, -2179758: 255, -2179759: 127, -2179760: 102, -2179761: 13, -2179762: 226, -2179763: 0, -2179764: 153, -2179765: 2, -2179766: 41, -2179767: 0, -2179768: 195, -2179769: 224, -2179770: 255, -1132026: 0, -1132027: 56, -1132028: 250, -1132029: 114, -1132030: 176, -1132031: 85, -1132032: 69, -1132033: 40, -1132034: 1, -1132035: 24, -1132036: 16, -1132037: 98, -1132038: 107, -1132039: 73, -1132040: 198, -1132041: 56, -1132042: 99, -1132043: 44, -1132044: 127, -1132045: 125, -1132046: 213, -1132047: 84, -1132048: 77, -1132049: 56, -1132050: 7, -1132051: 32, -1132052: 31, -1132053: 2, -1132054: 20, -1132055: 16, -1132056: 10, -1132057: 8, -452331: 1, -1133099: 0, -1133100: 56, -1133101: 87, -1133102: 63, -1133103: 77, -1133104: 46, -1133105: 226, -1133106: 0, -1133107: 96, -1133108: 0, -1133109: 176, -1133110: 58, -1133111: 11, -1133112: 34, -1133113: 102, -1133114: 17, -1133115: 36, -1133116: 9, -1133117: 185, -1133118: 33, -1133119: 51, -1133120: 21, -1133121: 206, -1133122: 12, -1133123: 72, -1133124: 4, -1133125: 224, -1133126: 3, -1133127: 160, -1133128: 2, -1133129: 64, -1133130: 1, -1115811: 0, -1115813: 0, -1115814: 0, -1398597: 0, -1398598: 56, -1398599: 255, -1398600: 87, -1398601: 255, -1398602: 43, -1398603: 60, -1398604: 31, -1398605: 120, -1398606: 2, -1398607: 176, -1398608: 1, -1398609: 11, -1398610: 1, -1398611: 135, -1398612: 0, -1398613: 68, -1398614: 0, -1398615: 31, -1398616: 0, -1398617: 18, -1398618: 0, -1398619: 9, -1398620: 0, -1398621: 255, -1398622: 127, -1398623: 255, -1398624: 127, -1398625: 255, -1398626: 127, -1398627: 0, -1398628: 0, -1398629: 0, -1398630: 56, -1398631: 255, -1398632: 87, -1398633: 255, -1398634: 43, -1398635: 60, -1398636: 31, -1398637: 120, -1398638: 2, -1398639: 176, -1398640: 1, -1398641: 11, -1398642: 1, -1398643: 135, -1398644: 0, -1398645: 68, -1398646: 0, -1398647: 255, -1398648: 127, -1398649: 255, -1398650: 127, -1398651: 255, -1398652: 127, -1398653: 255, -1398654: 3, -1398655: 82, -1398656: 2, -1398657: 41, -1398658: 1, -1398659: 0, -1398660: 0, -1398661: 0, -1398662: 56, -1398663: 249, -1398664: 39, -1398665: 117, -1398666: 35, -1398667: 210, -1398668: 26, -1398669: 78, -1398670: 22, -1398671: 171, -1398672: 17, -1398673: 39, -1398674: 13, -1398675: 132, -1398676: 4, -1398677: 0, -1398678: 0, -1398679: 95, -1398680: 127, -1398681: 31, -1398682: 124, -1398683: 22, -1398684: 88, -1398685: 12, -1398686: 48, -1398687: 148, -1398688: 82, -1398689: 206, -1398690: 57, -1398691: 8, -1398692: 33, -1136652: 0, -1136653: 56, -1136654: 156, -1136655: 75, -1136656: 16, -1136657: 38, -1136658: 198, -1136659: 12, -1136660: 99, -1136661: 12, -1136662: 247, -1136663: 66, -1136664: 82, -1136665: 42, -1136666: 173, -1136667: 25, -1136668: 41, -1136669: 13, -1136670: 89, -1136671: 94, -1136672: 114, -1136673: 61, -1136674: 238, -1136675: 44, -1136676: 71, -1136677: 20, -1136678: 59, -1136679: 3, -1136680: 22, -1136681: 2, -1136682: 19, -1136683: 1, -1399057: 0, -1399058: 56, -1399059: 85, -1399060: 87, -1399061: 79, -1399062: 74, -1399063: 228, -1399064: 28, -1399065: 96, -1399066: 12, -1399067: 178, -1399068: 86, -1399069: 13, -1399070: 62, -1399071: 104, -1399072: 45, -1399073: 38, -1399074: 37, -1399075: 255, -1399076: 3, -1399077: 247, -1399078: 2, -1399079: 16, -1399080: 2, -1399081: 8, -1399082: 1, -1399083: 31, -1399084: 0, -1399085: 24, -1399086: 0, -1399087: 14, -1399088: 0, -1500262: 10, -451687: 0, -451688: 8, -451689: 1, -451690: 189, -451691: 3, -1500268: 42, -451693: 20, -451694: 224, -451695: 59, -451696: 168, -451697: 33, -451698: 159, -451699: 87, -1500276: 170, -451701: 74, -451702: 78, -1500279: 8, -1500280: 240, -451705: 0, -451706: 181, -451707: 2, -451708: 107, -1500285: 12, -1500286: 105, -451711: 2, -1500288: 71, -451713: 17, -451714: 116, -451715: 0, -451716: 13, -451717: 0, -1500296: 249, -451721: 0, -451722: 9, -451723: 1, -451724: 189, -1500301: 0, -451726: 6, -451727: 20, -1500304: 55, -1500305: 46, -1500306: 179, -1500307: 29, -1500308: 46, -1500309: 13, -1500310: 63, -1500311: 38, -1500312: 251, -1500313: 29, -1500314: 151, -1500315: 21, -1500316: 82, -1500317: 13, -1500318: 238, -1500319: 8, -1500320: 63, -1500321: 87, -1500322: 170, -1500323: 0, -1500324: 144, -1500325: 4, -1500326: 141, -1500327: 4, -1500330: 103, -1500331: 0, -1500332: 110, -1246855: 0, -1500333: 29, -1500334: 44, -1500335: 25, -451760: 6, -1500337: 16, -1246856: 56, -1500338: 167, -1500339: 8, -1500340: 48, -1500341: 21, -1500342: 14, -1246857: 239, -1500343: 17, -1500344: 204, -1500345: 12, -1500346: 169, -1500347: 8, -1246858: 73, -1500348: 135, -1500349: 4, -1500350: 176, -1500351: 45, -1500352: 101, -1246859: 206, -1500353: 0, -1500354: 223, -1500355: 5, -1500356: 185, -1500357: 5, -1246860: 69, -1500358: 147, -1500359: 1, -1500360: 109, -1500361: 1, -1246861: 140, -1500364: 247, -1500365: 46, -1500366: 115, -1500367: 30, -1246862: 61, -1500368: 206, -1500369: 13, -1500370: 255, -1500371: 38, -1500372: 155, -1246863: 107, -1500373: 30, -1500374: 87, -1500375: 22, -1500376: 18, -1500377: 14, -1246864: 57, -1500378: 174, -1500379: 9, -1500380: 255, -1500381: 87, -1500382: 74, -1246865: 41, -1500383: 1, -1500384: 240, -1500385: 4, -1500386: 237, -1500387: 4, -1246866: 53, -1500388: 202, -1500389: 0, -1500390: 199, -1500391: 0, -1500392: 206, -1246867: 8, -1500393: 29, -1500394: 140, -1500395: 25, -1246868: 45, -1500398: 231, -1500399: 8, -1500400: 144, -1500401: 21, -1500402: 78, -1246869: 198, -1500403: 17, -1500404: 44, -1500405: 13, -1500406: 9, -1500407: 9, -1246870: 40, -1500408: 231, -1500409: 4, -1500410: 16, -1500411: 46, -1500412: 165, -1246871: 165, -1500413: 0, -1500414: 213, -1500415: 5, -1500416: 175, -1500417: 5, -1246872: 32, -1500418: 137, -1500419: 1, -1500420: 99, -1500421: 1, -1129051: 0, -1500422: 113, -1246873: 99, -1129052: 56, -1500423: 59, -1129053: 57, -1500424: 237, -1129054: 87, -1500425: 46, -1129055: 115, -1500426: 105, -1129056: 66, -1500427: 30, -1246874: 28, -1129057: 173, -1500428: 196, -1129058: 45, -1500429: 13, -1129059: 198, -1129060: 20, -1129061: 218, -1500432: 145, -1246875: 6, -1129062: 25, -1500433: 30, -1129063: 116, -1500434: 77, -1129064: 17, -1500435: 22, -1129065: 15, -1500436: 8, -1129066: 13, -1500437: 14, -1246876: 37, -1129067: 170, -1500438: 164, -1129068: 8, -1500439: 9, -1129069: 222, -1500440: 245, -1129070: 15, -1500441: 87, -1129071: 223, -1500442: 64, -1246877: 196, -1129072: 2, -1500443: 1, -1129073: 159, -1500444: 235, -1129074: 1, -1500445: 4, -1129075: 95, -1500446: 232, -1129076: 0, -1500447: 4, -1246878: 28, -1129077: 55, -1500448: 197, -1129078: 0, -1500449: 0, -1129079: 223, -1500450: 194, -1129080: 111, -1500451: 0, -1129081: 6, -1500452: 201, -1246879: 131, -1129082: 0, -1500453: 29, -1129083: 0, -1500454: 135, -1129084: 56, -1500455: 25, -1129085: 255, -451880: 85, -1129086: 47, -1500457: 17, -1246880: 16, -1500458: 226, -1129088: 26, -1500459: 8, -1129089: 74, -1500460: 139, -1129090: 1, -1500461: 21, -1129091: 99, -1500462: 73, -1129092: 0, -1500463: 17, -1129093: 90, -1129094: 39, -1129095: 181, -1500466: 4, -1129096: 14, -1500467: 9, -1129097: 16, -1500468: 226, -2177674: 0, -451893: 1, -1129099: 206, -1500470: 11, -1129100: 1, -1500471: 46, -1129101: 224, -1500472: 160, -1129102: 3, -451897: 20, -1129103: 224, -1500474: 149, -1129104: 2, -451899: 59, -1129105: 0, -1500476: 111, -1129106: 2, -1500477: 13, -1129107: 0, -1500478: 73, -1129108: 1, -451903: 87, -1129109: 0, -1500480: 35, -1129110: 127, -1500481: 9, -1129111: 224, -1500482: 49, -1129112: 109, -1500483: 67, -1129113: 224, -451908: 189, -1129114: 84, -1500485: 54, -451910: 184, -1500487: 38, -1500488: 132, -1500489: 21, -1500490: 181, -1500491: 46, -1500492: 81, -1500493: 38, -1500494: 13, -1500495: 30, -1500496: 200, -1500497: 21, -1500500: 181, -451925: 0, -1500502: 0, -1500503: 9, -1500504: 203, -1500505: 8, -1500506: 200, -1500507: 8, -1500508: 165, -1500509: 4, -1500510: 162, -451935: 46, -1500512: 169, -1500513: 33, -1500514: 103, -1150989: 114, -1500515: 29, -451940: 83, -1500517: 21, -1500518: 194, -1500519: 12, -1500520: 107, -1500521: 25, -1500522: 41, -1500523: 21, -1500524: 7, -1500525: 17, -1500526: 228, -1500527: 12, -1500528: 194, -1500529: 8, -1500530: 235, -1500531: 49, -1500534: 21, -1500535: 25, -1500536: 15, -1500537: 25, -1500538: 201, -1500539: 24, -1500540: 195, -1500541: 24, -1500542: 209, -1500543: 82, -1500544: 77, -1500545: 66, -1500546: 201, -1500547: 53, -1500548: 36, -1500549: 37, -1500550: 85, -1500551: 58, -1500552: 241, -1500553: 49, -1500554: 141, -1500555: 45, -1500556: 72, -1500557: 37, -1500558: 4, -1500559: 33, -1500560: 85, -451985: 17, -1500562: 160, -1500563: 24, -1500564: 139, -1139067: 0, -1139068: 56, -1139069: 156, -1139070: 75, -1139071: 148, -1139072: 54, -1139073: 41, -1139074: 9, -1139075: 66, -1139076: 0, -1139077: 24, -1139078: 59, -1139079: 82, -1139080: 42, -1139081: 173, -1139082: 25, -1139083: 107, -1139084: 17, -1139085: 90, -1139086: 127, -1139087: 192, -1139088: 126, -1139089: 224, -1139090: 109, -1139091: 224, -1139092: 84, -1139093: 29, -1139094: 0, -1139095: 20, -1139096: 0, -1139097: 10, -1139098: 0, -1500570: 98, -451995: 1, -1500572: 105, -1500573: 41, -1500574: 39, -1500575: 33, -452000: 227, -1500577: 28, -1500578: 162, -1500579: 20, -452004: 159, -1500581: 29, -1500582: 9, -1500583: 25, -1500584: 199, -1500585: 24, -1500586: 164, -1500587: 20, -1500588: 130, -1500589: 16, -1500590: 171, -1500591: 53, -1500592: 96, -1500593: 12, -1500594: 117, -1500595: 44, -1500596: 111, -1500597: 44, -1500598: 41, -1500599: 40, -1500602: 49, -1500603: 98, -1500604: 173, -1500605: 85, -452030: 190, -1500607: 73, -1500608: 132, -1500609: 56, -1500610: 181, -1500611: 77, -1500612: 81, -1500613: 69, -1500614: 237, -1270442: 31, -1270443: 3, -1270444: 218, -1270445: 1, -1270446: 245, -1270447: 0, -1270448: 221, -1270449: 2, -1270450: 184, -1270451: 1, -1270452: 211, -1270453: 0, -1270454: 154, -1270455: 2, -1270456: 150, -1270457: 1, -1270458: 210, -1270459: 0, -1270460: 120, -1270461: 2, -1270462: 116, -1270463: 1, -1139392: 0, -1139393: 56, -1139394: 29, -1139395: 2, -1139396: 21, -1139397: 0, -1139398: 8, -1139399: 0, -1139400: 3, -1139401: 0, -1139402: 189, -1139403: 0, -1139404: 19, -1139405: 0, -1139406: 14, -1139407: 0, -1139408: 11, -1139409: 0, -1139410: 190, -1139411: 23, -1139412: 159, -1139413: 26, -1139414: 83, -1139415: 12, -1139416: 75, -1139417: 8, -1139418: 192, -1139419: 126, -1139420: 224, -1139421: 109, -1139422: 224, -1139423: 84, -1270496: 44, -1270497: 1, -1270498: 170, -1270499: 0, -1270500: 72, -1270501: 0, -1270502: 10, -1270503: 1, -1270504: 136, -1270505: 0, -1270506: 71, -1270507: 0, -1270508: 200, -1270509: 0, -1270510: 103, -1270511: 0, -1270512: 37, -1270513: 0, -1270514: 134, -1270515: 0, -1270516: 69, -1270517: 0, -1270518: 36, -1270519: 0, -1270520: 100, -1270521: 0, -1270522: 35, -1270523: 0, -1270524: 34, -1270525: 0, -1270526: 34, -1270527: 0, -1270528: 33, -1270529: 0, -1270530: 1, -1270531: 0, -1270532: 0, -1270533: 0, -1270534: 0, -1270535: 0, -1270536: 0, -1270537: 0, -1500631: 20, -1500632: 41, -1500633: 49, -1270554: 0, -1270555: 0, -1270556: 0, -1270557: 0, -1270558: 0, -1270559: 0, -1270560: 33, -1270561: 4, -1270562: 1, -1270563: 4, -1270564: 0, -1270565: 0, -1270566: 0, -1270567: 0, -1270568: 33, -452060: 6, -1270570: 1, -1270571: 0, -1270572: 0, -1270573: 0, -1270574: 0, -1270575: 0, -1270576: 34, -1270577: 4, -1270578: 2, -1270579: 0, -1270580: 1, -1270581: 0, -1270582: 67, -1270583: 8, -1270584: 34, -1270585: 8, -1270586: 1, -1270587: 0, -1270588: 0, -1270589: 0, -1270590: 66, -1270591: 8, -1270592: 34, -1270593: 4, -1270594: 1, -1270595: 4, -1270596: 1, -1270597: 0, -1270598: 68, -1270599: 12, -1270600: 4, -1270601: 0, -1270602: 2, -1270603: 0, -1270604: 133, -1270605: 16, -1270606: 67, -1270607: 12, -1270608: 1, -1270609: 4, -1270610: 0, -1270611: 0, -1270612: 100, -1270613: 12, -1270614: 67, -1270615: 8, -1270616: 34, -1270617: 4, -1270618: 1, -1270619: 4, -1270620: 102, -1270621: 16, -1270622: 6, -1270623: 4, -1270624: 4, -1270625: 0, -1270626: 167, -1270627: 20, -1270628: 100, -1270629: 16, -1270630: 1, -1270631: 4, -1270632: 0, -1270633: 0, -1270634: 133, -1270635: 20, -1270636: 100, -1270637: 12, -1270638: 35, -1270639: 8, -1270640: 2, -1270641: 4, -1270642: 136, -1270643: 24, -1270644: 8, -1270645: 4, -1270646: 5, -1270647: 4, -1270648: 232, -1270649: 28, -1270650: 134, -1270651: 20, -1270652: 2, -1270653: 4, -1270654: 1, -1270655: 0, -1270656: 167, -1270657: 24, -1270658: 101, -1270659: 16, -1270660: 67, -1270661: 12, -1270662: 34, -1270663: 8, -1270664: 202, -1270665: 28, -1270666: 10, -1270667: 8, -1270668: 6, -1270669: 4, -1270670: 10, -1270671: 33, -1270672: 167, -1270673: 24, -1270674: 2, -1270675: 8, -1270676: 1, -1270677: 0, -1270678: 200, -1270679: 28, -1270680: 134, -1270681: 20, -1270682: 68, -1270683: 12, -1270684: 35, -1270685: 8, -1270686: 236, -1270687: 36, -1270688: 12, -1270689: 8, -1270690: 8, -1270691: 4, -1270692: 44, -1270693: 37, -1270694: 200, -1270695: 28, -1270696: 35, -1270697: 8, -1270698: 1, -1270699: 0, -1270700: 233, -1270701: 32, -1270702: 167, -1270703: 24, -1270704: 69, -1270705: 16, -1270706: 35, -1270707: 8, -1270708: 14, -1270709: 41, -1270710: 14, -1270711: 8, -1270712: 9, -1270713: 4, -1270714: 109, -1270715: 45, -1270716: 233, -1270717: 32, -1270718: 35, -1270719: 8, -1270720: 1, -1270721: 0, -1270722: 11, -1270723: 41, -1270724: 168, -1270725: 28, -1270726: 101, -1270727: 16, -1270728: 36, -1270729: 12, -1270730: 48, -1270731: 49, -1270732: 16, -1270733: 12, -1270734: 10, -1270735: 8, -1270736: 143, -1270737: 49, -1270738: 234, -1270739: 36, -1270740: 36, -1270741: 12, -1270742: 1, -1270743: 0, -1270744: 44, -1270745: 45, -1270746: 201, -1270747: 28, -1270748: 102, -1500666: 46, -1270750: 36, -1270751: 12, -1270752: 82, -1270753: 53, -1270754: 18, -1270755: 12, -1270756: 12, -1270757: 8, -1270758: 209, -1270759: 57, -1270760: 12, -1270761: 41, -1270762: 36, -1270763: 12, -1270764: 2, -1270765: 0, -1270766: 78, -1270767: 49, -1270768: 234, -1270769: 32, -1270770: 135, -1270771: 24, -1270772: 69, -1270773: 16, -1270774: 148, -1270775: 61, -1270776: 20, -1270777: 16, -1270778: 13, -1270779: 8, -1270780: 243, -1270781: 61, -1270782: 45, -1270783: 45, -1270784: 37, -1270785: 12, -1270786: 2, -1270787: 0, -1270788: 111, -1270789: 57, -1270790: 11, -1270791: 37, -1270792: 136, -1270793: 24, -1270794: 69, -1270795: 16, -1270796: 182, -1270797: 65, -1270798: 22, -1270799: 16, -1270800: 14, -1270801: 12, -1270802: 20, -1270803: 66, -1270804: 78, -1270805: 49, -1270806: 37, -1270807: 16, -1270808: 2, -1270809: 0, -1270810: 144, -1270811: 61, -1270812: 12, -1270813: 41, -1270814: 136, -1270815: 28, -1270816: 70, -1270817: 16, -1270818: 216, -1270819: 73, -1270820: 24, -1270821: 16, -1270822: 16, -1270823: 12, -1270824: 86, -1270825: 74, -1270826: 111, -1270827: 53, -1270828: 38, -1270829: 16, -1270830: 2, -1270831: 0, -1270832: 178, -1270833: 65, -1270834: 45, -1270835: 45, -1270836: 169, -1270837: 28, -1270838: 71, -1270839: 20, -1270840: 250, -1270841: 81, -1270842: 26, -1270843: 20, -1270844: 17, -1270845: 12, -1270846: 120, -1270847: 78, -1270848: 144, -1270849: 61, -1270850: 38, -1270851: 16, -1270852: 2, -1270853: 4, -1270854: 243, -1270855: 69, -1270856: 79, -1270857: 49, -1270858: 170, -1270859: 32, -1270860: 71, -1270861: 20, -1270862: 29, -1270863: 86, -1270864: 61, -1270865: 20, -1270866: 18, -1270867: 12, -1270868: 186, -1270869: 86, -1270870: 178, -1139799: 0, -1139800: 56, -1139801: 31, -1139802: 47, -1139803: 50, -1139804: 9, -1139805: 106, -1139806: 0, -1139807: 3, -1139808: 0, -1139809: 28, -1139810: 34, -1139811: 182, -1139812: 25, -1139813: 81, -1139814: 21, -1139815: 236, -1139816: 16, -1139817: 190, -1139818: 23, -1139819: 159, -1139820: 24, -1139821: 83, -1139822: 12, -1139823: 75, -1139824: 8, -1139825: 224, -1139826: 59, -1139827: 128, -1139828: 38, -1139829: 128, -1139830: 21, -1270903: 32, -1270904: 74, -1270905: 24, -1270906: 31, -1270907: 86, -1270908: 63, -1270909: 24, -1270910: 21, -1270911: 16, -1270912: 191, -1270913: 2, -1270914: 154, -1270915: 1, -1270916: 214, -1270917: 0, -1270918: 90, -1270919: 74, -1270920: 115, -1270921: 57, -1270922: 42, -1270923: 20, -1270924: 7, -1270925: 4, -1270926: 182, -1270927: 69, -1270928: 50, -1270929: 49, -1270930: 174, -1270931: 32, -1270932: 75, -1270933: 24, -1270934: 255, -1270935: 81, -1270936: 63, -1270937: 24, -1270938: 21, -1270939: 16, -1270940: 159, -1270941: 2, -1270942: 154, -1270943: 1, -1270944: 214, -1270945: 0, -1270946: 59, -1270947: 74, -1270948: 84, -1270949: 57, -1270950: 43, -1270951: 20, -1270952: 8, -1270953: 8, -1270954: 183, -1270955: 65, -1270956: 51, -1270957: 45, -1270958: 175, -1270959: 32, -1270960: 76, -1270961: 24, -1270962: 223, -1270963: 77, -1270964: 63, -1270965: 24, -1270966: 22, -1270967: 16, -1270968: 127, -1270969: 6, -1270970: 123, -1129087: 247, -1270972: 183, -1270973: 4, -1500704: 137, -1500705: 32, -1500706: 103, -1500707: 28, -1500708: 69, -452133: 3, -1500710: 109, -1500711: 65, -1500712: 3, -1500713: 20, -452138: 202, -1500715: 44, -1500716: 121, -452141: 87, -1500718: 51, -1500719: 40, -1500720: 45, -1500721: 40, -1500722: 59, -1500723: 98, -1500724: 183, -1500725: 85, -452150: 108, -452151: 1, -452152: 83, -452153: 2, -452154: 5, -452155: 17, -452156: 117, -1500733: 69, -452158: 14, -1140091: 0, -1140092: 56, -1140093: 255, -1140094: 2, -1140095: 191, -1140096: 1, -1140097: 15, -1140098: 0, -1140099: 8, -1140100: 0, -1140101: 191, -1140102: 1, -1140103: 27, -1140104: 1, -1140105: 186, -1140106: 0, -1140107: 17, -1140108: 0, -1500738: 110, -1140110: 90, -1140111: 180, -1140112: 65, -1140113: 13, -1140114: 41, -1500739: 48, -1140116: 16, -1140117: 255, -1140118: 3, -1140119: 55, -1140120: 2, -1140121: 209, -1140122: 0, -1500741: 126, -1500742: 10, -1500743: 40, -1500744: 80, -1500745: 24, -1500746: 77, -1500747: 24, -1500748: 42, -1500749: 20, -1500750: 39, -1500751: 20, -1500752: 46, -1500753: 49, -1500754: 236, -1500755: 44, -1500756: 170, -1500757: 36, -1500758: 71, -1500759: 28, -1500760: 240, -1500761: 40, -1500762: 174, -1500763: 36, -1500764: 140, -1500765: 32, -1500766: 105, -1500767: 28, -1500768: 71, -1500769: 24, -452196: 3, -1500773: 20, -1500774: 127, -1500775: 24, -1500776: 121, -1500777: 24, -452202: 6, -452203: 20, -1500780: 45, -1500781: 20, -1500782: 59, -1500783: 78, -1500784: 183, -452209: 87, -1500786: 51, -1500787: 49, -1500788: 142, -1500789: 32, -1500790: 191, -1500791: 57, -1500792: 91, -1500793: 49, -1500794: 247, -1500795: 40, -1500796: 178, -1500797: 32, -1500798: 110, -1500799: 28, -1500800: 191, -1500801: 106, -1500802: 10, -1500803: 20, -1500818: 71, -452243: 0, -1500820: 240, -1500821: 28, -1500822: 174, -452247: 2, -452248: 5, -1500825: 20, -1500826: 105, -1500827: 16, -1500828: 71, -1500829: 16, -1500830: 112, -1500831: 53, -1500832: 5, -1500833: 12, -1500844: 159, -1500845: 38, -1500846: 89, -452271: 0, -1500848: 76, -1500849: 0, -1500852: 57, -1500853: 87, -1500854: 115, -1500855: 66, -1500856: 173, -1500857: 45, -1500858: 198, -1500859: 20, -1500860: 127, -1500861: 54, -1500862: 249, -452287: 37, -452288: 159, -452289: 87, -452290: 211, -452291: 74, -1500868: 134, -1500869: 12, -1500870: 255, -1500871: 127, -1500872: 0, -1500873: 0, -1500874: 95, -1500875: 34, -1500876: 57, -1500877: 1, -1500878: 45, -1500879: 0, -1500880: 5, -452305: 0, -452306: 14, -1500883: 78, -1500886: 142, -1500887: 41, -1500888: 167, -1500889: 16, -1500890: 63, -1500891: 50, -1500892: 217, -1500893: 37, -452318: 225, -1500895: 29, -1500896: 237, -1500897: 16, -1500898: 103, -1500899: 8, -1500900: 191, -1500901: 119, -1500902: 2, -1500903: 0, -1500904: 31, -1500905: 30, -1141112: 0, -1141113: 56, -1141114: 31, -1141115: 77, -1141116: 182, -1141117: 56, -1141118: 110, -1141119: 36, -1141120: 72, -1141121: 20, -1141122: 255, -1141123: 71, -1141124: 250, -1141125: 46, -1141126: 22, -1141127: 22, -1141128: 50, -1141129: 1, -1141130: 57, -1141131: 111, -1141132: 115, -1141133: 90, -1141134: 173, -452333: 0, -1141136: 8, -1141137: 45, -1141138: 99, -1141139: 24, -1141140: 255, -1141141: 127, -1141142: 65, -1141143: 0, -1500911: 0, -1500912: 154, -1500913: 66, -1500914: 245, -1500915: 49, -1500916: 80, -1500917: 33, -1500920: 255, -1500921: 41, -1500922: 154, -1500923: 33, -1500924: 21, -1500925: 25, -452350: 7, -452351: 20, -452352: 226, -452353: 59, -1500930: 31, -1500931: 99, -1500932: 6, -1500933: 0, -1500934: 159, -1500935: 21, -452360: 80, -1500937: 0, -1500938: 51, -1500939: 0, -1500940: 14, -452365: 1, -1500942: 251, -1500943: 49, -1500944: 119, -1500945: 37, -452370: 6, -1500947: 24, -452372: 118, -452373: 0, -452374: 15, -1500951: 29, -452378: 6, -452379: 0, -1500956: 147, -1500957: 12, -1500958: 80, -1500959: 4, -1500960: 95, -1500961: 74, -1500962: 12, -1500963: 0, -1500964: 159, -1500965: 21, -1500966: 219, -1500967: 0, -1500968: 51, -1500969: 0, -1500970: 14, -1500971: 0, -1500972: 251, -1500973: 49, -1500974: 119, -1500975: 37, -1500976: 244, -1500977: 24, -1500978: 112, -1500979: 12, -1500980: 127, -1500981: 29, -1500982: 59, -1500983: 25, -1500984: 215, -1500985: 16, -1500988: 80, -1500989: 4, -1500990: 95, -452415: 1, -1500992: 12, -1500993: 0, -1501004: 0, -1501005: 0, -452430: 189, -1501007: 0, -1501008: 0, -1501009: 0, -1501010: 36, -1501011: 0, -1501012: 173, -1501013: 41, -1501014: 74, -1501015: 33, -1501016: 231, -1501017: 20, -1501018: 99, -1501019: 12, -1501022: 0, -1501023: 0, -1501024: 0, -1501025: 0, -1501026: 0, -1501027: 0, -1501028: 0, -1501029: 0, -1501030: 173, -1501031: 41, -1501032: 0, -1501033: 0, -1501034: 4, -452459: 87, -1501036: 4, -1501037: 0, -1501038: 4, -452463: 58, -1501040: 7, -1501041: 0, -452466: 190, -1501043: 33, -1501044: 12, -1501045: 29, -1501046: 202, -1501047: 16, -1501048: 70, -1501049: 8, -1501050: 4, -1501051: 0, -1501052: 4, -1501053: 0, -1501056: 4, -1501057: 0, -1501058: 4, -1501059: 0, -1501060: 111, -1501061: 33, -1501062: 4, -1501063: 0, -1501064: 8, -1501065: 0, -1501066: 8, -1501067: 0, -1501068: 8, -1501069: 0, -1501070: 11, -1501071: 0, -1501072: 49, -1501073: 29, -1501074: 239, -1501075: 20, -1501076: 173, -1501077: 12, -1501078: 74, -452503: 0, -452504: 87, -1501081: 0, -452506: 9, -452507: 17, -1501084: 8, -452509: 0, -1501086: 8, -1501087: 0, -1142215: 0, -1142216: 56, -1142217: 90, -1142218: 127, -1142219: 224, -1142220: 59, -1142221: 128, -1142222: 38, -1142223: 32, -1142224: 9, -1142225: 90, -1142226: 79, -1501091: 29, -1142228: 54, -1142229: 16, -1142230: 38, -1142231: 206, -1142232: 29, -1142233: 148, -1142234: 82, -1142235: 206, -1142236: 57, -1142237: 8, -1142238: 33, -1142239: 132, -1142240: 16, -1142241: 59, -1142242: 3, -1142243: 22, -1142244: 2, -1142245: 19, -1142246: 1, -1501095: 0, -1501096: 14, -1501097: 0, -1501098: 14, -1501099: 0, -1501100: 16, -1501101: 0, -452526: 159, -452527: 87, -1501104: 179, -1501105: 16, -1501106: 114, -1501107: 8, -1501108: 48, -452533: 0, -1501110: 14, -1501111: 0, -1501112: 14, -1501113: 0, -1501114: 14, -1501115: 0, -1501116: 14, -1501117: 0, -1501118: 14, -1501119: 0, -1501120: 245, -1501121: 20, -1501124: 14, -1501125: 0, -1501126: 14, -1501127: 0, -1501128: 14, -1501129: 0, -1501130: 16, -1501131: 0, -1501132: 245, -1501133: 20, -1501134: 179, -1501135: 16, -1501136: 114, -1501137: 8, -1501138: 48, -1501139: 4, -1501140: 14, -1501141: 0, -1501142: 14, -1501143: 0, -1501144: 14, -1501145: 0, -1501146: 14, -1501147: 0, -452572: 85, -1501149: 0, -452574: 7, -1501151: 20, -1501152: 14, -1501153: 0, -1501170: 184, -452595: 87, -452596: 213, -452597: 74, -1501174: 70, -1501175: 22, -1501176: 227, -452601: 0, -1501178: 159, -1501179: 79, -1501180: 216, -1501181: 62, -1501182: 18, -1501183: 46, -1501184: 205, -1501185: 8, -1501186: 255, -452611: 0, -1501188: 184, -1501189: 79, -1501192: 39, -1501193: 18, -1501194: 228, -452619: 1, -1501196: 126, -1501197: 75, -452622: 7, -452623: 20, -1501200: 241, -1501201: 41, -1501202: 205, -1501203: 8, -1501204: 255, -1501205: 123, -1501206: 185, -1501207: 71, -1501208: 242, -1501209: 10, -1501210: 40, -1501211: 18, -1501212: 228, -1501213: 0, -1501214: 60, -452639: 0, -452640: 84, -452641: 2, -1501218: 241, -1501219: 41, -452644: 118, -1501221: 8, -1501222: 255, -452647: 0, -452650: 5, -452651: 0, -452652: 10, -452653: 1, -452654: 255, -1501231: 0, -1501232: 27, -1501233: 67, -1501234: 117, -1501235: 54, -1501236: 208, -1501237: 37, -452662: 159, -1501239: 8, -1501240: 255, -1501241: 111, -1501242: 153, -1501243: 51, -1501244: 243, -1501245: 6, -1501246: 9, -1501247: 14, -1501248: 229, -1501249: 0, -1501250: 250, -1501251: 66, -452676: 6, -452677: 17, -452678: 118, -1501255: 37, -1501256: 171, -452681: 0, -1501260: 153, -1501261: 43, -1501262: 244, -1501263: 6, -1501264: 234, -1501265: 9, -1501266: 230, -1501267: 0, -1501268: 217, -1501269: 62, -1501270: 51, -452695: 37, -1501272: 142, -452697: 87, -1501274: 171, -1501275: 4, -1501276: 222, -1501277: 99, -452702: 188, -452703: 0, -1501280: 212, -452705: 1, -1501282: 235, -452707: 0, -1501284: 230, -1501285: 0, -452710: 5, -452711: 17, -452712: 117, -452713: 0, -1501290: 142, -1501291: 33, -1501294: 222, -452719: 0, -1501296: 154, -1501297: 27, -452722: 255, -1501299: 6, -452724: 6, -452725: 20, -1501302: 231, -452727: 59, -1501304: 118, -452729: 37, -1501306: 241, -1501307: 41, -452732: 211, -1501309: 29, -1501310: 138, -1501311: 4, -1501312: 222, -1501313: 87, -452754: 8, -1501331: 114, -1501332: 223, -1501333: 44, -1501334: 185, -1501335: 36, -452760: 224, -452761: 59, -1501338: 169, -452763: 33, -1501340: 189, -1501341: 110, -1501342: 221, -452767: 74, -1501344: 183, -452769: 58, -1501346: 174, -452771: 0, -452772: 190, -452773: 1, -452774: 142, -452775: 0, -1501352: 187, -452777: 2, -452778: 4, -452779: 17, -452780: 116, -1501357: 32, -452782: 13, -452783: 0, -452798: 16, -452799: 0, -452800: 8, -452801: 1, -452802: 31, -452803: 66, -452804: 5, -452805: 20, -452806: 224, -1130012: 0, -452807: 59, -1130013: 56, -452808: 168, -1130014: 29, -452809: 33, -1130015: 2, -452810: 159, -1130016: 21, -452811: 87, -1130017: 0, -452812: 210, -1130018: 8, -452813: 74, -1130019: 0, -452814: 78, -1130020: 3, -452815: 58, -1130021: 0, -452816: 187, -1130022: 189, -452817: 0, -1130023: 0, -452818: 20, -2178600: 255, -452819: 89, -2178601: 87, -452820: 170, -1130026: 14, -452821: 48, -1130027: 0, -452822: 116, -2178604: 60, -452823: 2, -2178605: 31, -452824: 4, -1130030: 255, -452825: 17, -2178607: 2, -452826: 116, -2178608: 176, -452827: 0, -1130033: 3, -452828: 13, -1130034: 55, -452829: 0, -2178611: 1, -1130036: 209, -1130037: 0, -452832: 4, -1130038: 160, -452833: 0, -1130039: 3, -1130040: 192, -1130041: 2, -1130042: 224, -1130043: 5, -452848: 79, -452849: 58, -452850: 188, -452851: 0, -452852: 21, -452853: 89, -452854: 171, -452855: 48, -452856: 83, -452857: 2, -452858: 5, -452859: 17, -452860: 117, -452861: 0, -452862: 14, -452863: 0, -452866: 4, -452867: 0, -452868: 9, -452869: 1, -452870: 31, -452871: 66, -452872: 6, -452873: 20, -452874: 225, -452875: 59, -452876: 202, -452877: 37, -452878: 159, -452879: 87, -452880: 211, -452881: 74, -452882: 79, -452883: 58, -452884: 188, -452885: 0, -452886: 21, -452887: 89, -452888: 171, -452889: 48, -452890: 83, -452891: 2, -452892: 5, -452893: 17, -452894: 117, -452895: 0, -452896: 14, -452897: 0, -452900: 5, -452901: 0, -452902: 10, -452903: 1, -452904: 31, -452905: 66, -452906: 7, -452907: 20, -452908: 226, -452909: 59, -452910: 204, -452911: 37, -452912: 159, -452913: 87, -452914: 212, -452915: 74, -452916: 80, -452917: 58, -452918: 188, -452919: 0, -452920: 22, -452921: 89, -452922: 172, -452923: 48, -452924: 84, -452925: 2, -452926: 6, -452927: 17, -452928: 118, -452929: 0, -452930: 15, -452931: 0, -452934: 6, -452935: 0, -452936: 10, -452937: 1, -452938: 31, -452939: 66, -452940: 7, -452941: 20, -452942: 226, -452943: 59, -452944: 204, -452945: 37, -452946: 159, -452947: 87, -452948: 212, -452949: 74, -452950: 80, -452951: 58, -452952: 188, -452953: 0, -452954: 22, -452955: 89, -452956: 172, -452957: 48, -452958: 84, -452959: 2, -452960: 6, -452961: 17, -452962: 118, -452963: 0, -452964: 15, -452965: 0, -452968: 7, -452969: 0, -452970: 11, -452971: 1, -452972: 31, -452973: 66, -452974: 8, -452975: 20, -452976: 227, -452977: 59, -452978: 238, -452979: 41, -452980: 159, -452981: 87, -452982: 213, -452983: 74, -452984: 81, -452985: 58, -452986: 189, -452987: 0, -452988: 23, -452989: 89, -452990: 173, -452991: 48, -452992: 85, -452993: 2, -452994: 7, -452995: 17, -452996: 119, -452997: 0, -452998: 16, -452999: 0, -453002: 8, -453003: 0, -453004: 11, -453005: 1, -453006: 31, -453007: 66, -453008: 8, -453009: 20, -453010: 227, -453011: 59, -453012: 238, -453013: 41, -453014: 159, -453015: 87, -453016: 213, -453017: 74, -453018: 81, -453019: 58, -453020: 189, -453021: 0, -453022: 23, -453023: 89, -453024: 173, -453025: 48, -453026: 85, -453027: 2, -453028: 7, -453029: 17, -453030: 119, -453031: 0, -453032: 16, -453033: 0, -453036: 8, -453037: 0, -453038: 13, -453039: 1, -453040: 31, -453041: 66, -456480: 0, -453042: 10, -453043: 20, -452116: 109, -453128: 85, -453129: 2, -453130: 7, -453131: 17, -453132: 119, -453133: 0, -453134: 16, -453135: 0, -453138: 7, -453139: 0, -453140: 11, -453141: 1, -453142: 31, -453143: 66, -453144: 8, -453145: 20, -453146: 227, -453147: 59, -453148: 238, -453149: 41, -453150: 159, -453151: 87, -453152: 213, -453153: 74, -453154: 81, -453155: 58, -453156: 189, -453157: 0, -453158: 23, -453159: 89, -453160: 173, -453161: 48, -453162: 85, -453163: 2, -453164: 7, -453165: 17, -453166: 119, -456481: 80, -453167: 0, -453168: 16, -453169: 0, -453172: 6, -453173: 0, -453174: 10, -453175: 1, -453176: 31, -453177: 66, -453178: 7, -453179: 20, -453180: 226, -453181: 59, -453182: 204, -453183: 37, -453184: 159, -1277319: 95, -1277320: 0, -1277321: 55, -1277322: 0, -1277323: 63, -1277324: 0, -1277325: 25, -1277326: 0, -1277327: 63, -1277328: 0, -1277329: 27, -1277330: 0, -1277331: 31, -1277332: 0, -1277333: 29, -1277334: 0, -1277335: 31, -1277336: 0, -1277337: 31, -1277338: 0, -1277339: 31, -1277340: 0, -1277341: 29, -1277342: 0, -1277343: 63, -1277344: 0, -1277345: 27, -1277346: 0, -1277347: 63, -1277348: 0, -1277349: 25, -1277350: 0, -453191: 0, -453192: 22, -453193: 89, -453194: 172, -453195: 48, -453196: 84, -453197: 2, -453198: 6, -453199: 17, -453200: 118, -453201: 0, -453202: 15, -453203: 0, -453206: 5, -453207: 0, -453208: 10, -453209: 1, -453210: 31, -453211: 66, -453212: 7, -453213: 20, -453214: 226, -453215: 59, -453216: 204, -453217: 37, -453218: 159, -453219: 87, -453220: 212, -453221: 74, -453222: 80, -453223: 58, -453224: 188, -453225: 0, -453226: 22, -453227: 89, -453228: 172, -453229: 48, -453230: 84, -453231: 2, -453232: 6, -453233: 17, -453234: 118, -453235: 0, -453236: 15, -453237: 0, -453240: 4, -453241: 0, -453242: 9, -453243: 1, -453244: 31, -453245: 66, -453246: 6, -453247: 20, -453248: 225, -453249: 59, -453250: 202, -453251: 37, -453252: 159, -453253: 87, -453254: 211, -453255: 74, -453256: 79, -453257: 58, -453258: 188, -453259: 0, -453260: 21, -453261: 89, -453262: 171, -453263: 48, -453264: 83, -453265: 2, -453266: 5, -453267: 17, -453268: 117, -453269: 0, -453270: 14, -453271: 0, -453274: 4, -453275: 0, -453276: 9, -453277: 1, -453278: 31, -453279: 66, -453280: 6, -453281: 20, -453282: 225, -453283: 59, -453284: 202, -453285: 37, -453286: 159, -453287: 87, -453288: 211, -453289: 74, -453290: 79, -453291: 58, -453292: 188, -453293: 0, -453294: 21, -453295: 89, -453296: 171, -453297: 48, -453298: 83, -453299: 2, -453300: 5, -453301: 17, -453302: 117, -453303: 0, -453304: 14, -453305: 0, -453308: 16, -453309: 0, -453310: 8, -453311: 1, -453312: 31, -453313: 66, -453314: 5, -453315: 20, -453316: 224, -453317: 59, -453318: 168, -453319: 33, -453320: 159, -453321: 87, -453322: 210, -453323: 74, -453324: 78, -453325: 58, -453326: 187, -453327: 0, -453328: 20, -453329: 89, -453330: 170, -453331: 48, -453332: 116, -453333: 2, -453334: 4, -453335: 17, -453336: 116, -453337: 0, -453338: 13, -453339: 0, -453352: 169, -453353: 30, -453354: 177, -453355: 11, -453360: 103, -453361: 22, -453362: 78, -453363: 3, -453368: 37, -453369: 14, -453370: 235, -453371: 2, -453376: 227, -453377: 5, -453378: 136, -453379: 2, -453384: 161, -453385: 1, -453386: 37, -453387: 2, -453392: 227, -453393: 5, -453394: 136, -453395: 2, -453400: 37, -453401: 14, -453402: 235, -453403: 2, -453408: 103, -453409: 22, -453410: 78, -453411: 3, -230300: 0, -230301: 56, -230302: 88, -230303: 127, -230304: 213, -230305: 110, -230306: 113, -230307: 90, -230308: 238, -230309: 73, -230310: 106, -230311: 53, -230312: 231, -230313: 36, -230314: 131, -230315: 16, -2179281: 35, -2179282: 0, -2179283: 27, -2179284: 255, -2179285: 87, -2179286: 255, -2179287: 43, -2179288: 60, -2179289: 31, -2179290: 120, -2179291: 2, -2179292: 176, -2179293: 1, -2179294: 11, -2179295: 1, -2179296: 135, -2179297: 0, -2179298: 68, -2179299: 0, -2179300: 31, -2179301: 0, -1130726: 86, -2179303: 0, -2179304: 9, -2179305: 0, -2179306: 255, -2179307: 3, -2179308: 82, -2179309: 2, -2179310: 41, -2179311: 1, -2179312: 35, -1152603: 0, -890460: 116, -1152605: 223, -1152606: 62, -890463: 0, -1152608: 0, -1152609: 15, -890466: 14, -1152611: 5, -1152612: 0, -890469: 67, -1152614: 1, -1152615: 24, -1152616: 1, -1152617: 147, -1152618: 0, -890475: 34, -1279623: 0, -1279624: 56, -1279625: 157, -1279626: 85, -1279627: 22, -1279628: 24, -1279629: 13, -1279630: 16, -1279631: 159, -1279632: 75, -1279633: 55, -1279634: 63, -1279635: 208, -1279636: 54, -1279637: 105, -1279638: 46, -1279639: 8, -1279640: 38, -1279641: 166, -1279642: 29, -1279643: 37, -1279644: 17, -1279645: 197, -1279646: 8, -1279647: 3, -1279648: 0, -1279649: 24, -1279650: 99, -1279651: 255, -1279652: 127, -1279653: 0, -1279654: 0, -1279655: 0, -1279656: 56, -1279657: 157, -1279658: 85, -1279659: 22, -1279660: 24, -1279661: 13, -1279662: 16, -1279663: 159, -1279664: 75, -1279665: 55, -1279666: 63, -1279667: 208, -1279668: 54, -1279669: 105, -1279670: 46, -1279671: 8, -1279672: 38, -1279673: 166, -1279674: 29, -1279675: 37, -1279676: 17, -1279677: 197, -1279678: 8, -1279679: 3, -1279680: 0, -1279681: 24, -1279682: 99, -1279683: 255, -1279684: 127, -1279685: 0, -1279686: 0, -1279687: 0, -1279688: 4, -1279689: 107, -1279690: 45, -1279691: 107, -1279692: 45, -1279693: 107, -1279694: 45, -1279695: 134, -1279696: 25, -1279697: 194, -1279698: 20, -1279699: 64, -1279700: 8, -1279701: 0, -1279702: 4, -1279703: 237, -1279704: 49, -1279705: 198, -1279706: 24, -1279707: 195, -1279708: 16, -1279709: 32, -1279710: 4, -1279711: 82, -1279712: 2, -1279713: 107, -1279714: 45, -1279715: 82, -1279716: 74, -1279717: 0, -1279718: 0, -1673099: 0, -1673100: 56, -1673101: 29, -1673102: 2, -1673103: 21, -1673104: 0, -1673105: 8, -1673106: 0, -1673107: 3, -1673108: 0, -1673109: 189, -1673110: 0, -1673111: 19, -1673112: 0, -1673113: 14, -1673114: 0, -1673115: 11, -1673116: 0, -1673117: 90, -1673118: 127, -1673119: 192, -1673120: 126, -1673121: 224, -1673122: 109, -1673123: 224, -1673124: 84, -1673125: 224, -1673126: 3, -1673127: 160, -1673128: 2, -1673129: 64, -1673130: 1, -1149168: 0, -1149169: 56, -1149170: 31, -1149171: 77, -1149172: 182, -1149173: 56, -1149174: 110, -1149175: 36, -1149176: 72, -1149177: 20, -1149178: 255, -1149179: 71, -1149180: 250, -1149181: 46, -1149182: 22, -1149183: 22, -1149184: 50, -1149185: 1, -1149186: 57, -1149187: 111, -1149188: 115, -1149189: 90, -1149190: 173, -1149191: 65, -1149192: 8, -1149193: 45, -1149194: 99, -1149195: 24, -1149196: 255, -1149197: 127, -1149198: 65, -1149199: 0, -1673725: 0, -1673726: 56, -1673727: 149, -1673728: 63, -1673729: 139, -1673730: 46, -1673731: 32, -1673732: 1, -1673733: 96, -1673734: 0, -1673735: 238, -1673736: 58, -1673737: 73, -1673738: 34, -1673739: 164, -1673740: 17, -1673741: 98, -1673742: 9, -1673743: 187, -1673744: 57, -1673745: 245, -1673746: 48, -1673747: 110, -1673748: 44, -1673749: 39, -1673750: 40, -1673751: 147, -1673752: 127, -1673753: 206, -1673754: 110, -1673755: 41, -1673756: 98, -1673921: 0, -1673922: 56, -1673923: 29, -1673924: 2, -1673925: 21, -1673926: 0, -1673927: 8, -1673928: 0, -1673929: 3, -1673930: 0, -1673931: 95, -1673932: 1, -1673933: 118, -1673934: 0, -1673935: 80, -1673936: 0, -1673937: 11, -1673938: 0, -1673939: 255, -1673940: 127, -1673941: 224, -1673942: 86, -1673943: 128, -1673944: 49, -1673945: 192, -1673946: 24, -1673947: 255, -1673948: 67, -1673949: 220, -1673950: 66, -1673951: 118, -1673952: 65, -1149967: 0, -1149968: 56, -1149969: 255, -1149970: 2, -1149971: 191, -1149972: 1, -1149973: 15, -1149974: 0, -1149975: 8, -1149976: 0, -1149977: 191, -1149978: 1, -1149979: 27, -1149980: 1, -1149981: 186, -1149982: 0, -1149983: 17, -1149984: 0, -1149985: 90, -1149986: 127, -1149987: 69, -1149988: 93, -1149989: 195, -1149990: 64, -1149991: 98, -1149992: 36, -1149993: 233, -1149994: 83, -1149995: 198, -1149996: 58, -1149997: 97, -1149998: 25, -1677184: 22, -1677185: 234, -1677186: 17, -1677187: 6, -1677188: 9, -1677189: 189, -1677190: 54, -1677191: 249, -1677192: 41, -1677193: 21, -1677194: 29, -890763: 33, -1677196: 16, -1677197: 223, -1677198: 17, -1677199: 123, -890768: 78, -1677201: 22, -1677202: 17, -1677203: 179, -1677204: 16, -890773: 89, -1677206: 16, -1677207: 222, -1677208: 103, -1677209: 8, -890778: 4, -1677211: 0, -1677212: 0, -1677213: 242, -890782: 13, -890783: 0, -1677216: 18, -1677217: 236, -1677218: 17, -1677219: 8, -890788: 191, -1677221: 125, -1677222: 50, -1677223: 185, -1677224: 37, -1677225: 214, -1677226: 24, -1677227: 83, -1677228: 20, -1677229: 191, -1677230: 17, -1677231: 92, -1677232: 17, -1677233: 247, -1677234: 16, -1677235: 147, -1677236: 16, -1677237: 46, -1677238: 16, -890807: 69, -890808: 185, -1677241: 8, -1677242: 4, -1677243: 0, -1677244: 0, -890813: 21, -1677246: 35, -1677247: 241, -1677248: 18, -1677249: 14, -890818: 57, -1677251: 41, -1677252: 9, -1677253: 61, -1677254: 46, -1677255: 122, -456487: 13, -1677256: 37, -1677257: 183, -1677258: 24, -1677259: 52, -890828: 223, -1677261: 159, -1677262: 21, -1677263: 60, -1674972: 0, -1674973: 56, -1674974: 255, -1674975: 87, -1674976: 247, -1674977: 66, -1674978: 140, -1674979: 21, -1674980: 165, -1674981: 0, -1674982: 90, -1674983: 79, -1674984: 181, -1674985: 54, -1674986: 16, -1674987: 38, -1674988: 206, -1674989: 29, -1674990: 224, -1674991: 63, -1674992: 224, -1674993: 46, -1674994: 0, -1674995: 34, -1674996: 0, -1674997: 17, -1674998: 91, -1674999: 126, -1675000: 47, -1675001: 85, -1675002: 135, -1675003: 40, -1677269: 46, -890838: 21, -1677271: 222, -1677272: 87, -1677273: 9, -1677274: 4, -890843: 62, -1677276: 0, -1677277: 246, -1677278: 31, -1677279: 243, -1677280: 14, -1677281: 47, -1677282: 14, -1677283: 74, -1677284: 5, -890853: 127, -1677286: 45, -1677287: 90, -890856: 240, -890857: 123, -1677290: 24, -1677291: 54, -1677292: 20, -890861: 127, -890862: 255, -890863: 127, -890864: 254, -890865: 123, -1677298: 20, -1677299: 116, -1677300: 20, -1677301: 47, -1677302: 20, -1677303: 255, -1677304: 79, -1677305: 10, -1677306: 0, -1677307: 0, -890876: 127, -1677309: 248, -1677310: 31, -1677311: 21, -1677312: 15, -1677313: 81, -1150986: 0, -1150987: 56, -1150988: 250, -1677314: 14, -1150990: 176, -1150991: 85, -1150992: 69, -1150993: 40, -1150994: 1, -1150995: 24, -1150996: 16, -1150997: 98, -1150998: 107, -1150999: 73, -1151000: 198, -1151001: 56, -1151002: 99, -1151003: 44, -1151004: 31, -1151005: 36, -1151006: 23, -1151007: 28, -1151008: 47, -1151009: 20, -1151010: 71, -1151011: 12, -1151012: 255, -1151013: 3, -1151014: 55, -1151015: 2, -1151016: 209, -1151017: 0, -1677319: 27, -1677320: 33, -1677321: 121, -1677322: 24, -1677323: 23, -1677324: 20, -1677325: 63, -1677326: 25, -1677327: 252, -1153040: 74, -1677329: 183, -1153042: 17, -1677331: 116, -1677332: 24, -1153045: 82, -1677334: 24, -1677335: 255, -1153048: 62, -1677337: 11, -1677338: 0, -1153051: 198, -1153052: 37, -890909: 0, -1153054: 3, -890911: 0, -1153056: 2, -890913: 0, -890914: 8, -890915: 1, -890916: 189, -890917: 3, -890918: 5, -890919: 20, -890920: 224, -890921: 59, -890922: 168, -454060: 64, -454061: 32, -454062: 20, -454067: 224, -454068: 84, -454069: 33, -454070: 60, -454071: 0, -454072: 16, -454077: 192, -454078: 80, -454079: 33, -454080: 60, -454081: 0, -454082: 16, -454087: 160, -454088: 76, -454089: 0, -454090: 56, -454091: 0, -454092: 12, -454097: 128, -454098: 72, -454099: 0, -454100: 56, -454101: 0, -454102: 12, -1676057: 0, -1676058: 0, -1676059: 233, -1676060: 39, -1676061: 102, -1676062: 26, -1676063: 133, -1676064: 21, -1676065: 163, -1676066: 12, -1676067: 156, -1676068: 63, -1676069: 151, -1676070: 46, -1676071: 114, -1676072: 29, -1676073: 142, -1676074: 16, -1676075: 95, -1676076: 10, -1676077: 219, -1676078: 9, -1676079: 86, -1676080: 9, -1676081: 210, -1676082: 8, -1676083: 44, -1676084: 8, -1676085: 189, -1676086: 127, -1676087: 5, -1676088: 12, -454111: 0, -454112: 8, -454117: 64, -454118: 64, -454119: 0, -454120: 52, -454121: 0, -454122: 8, -454127: 96, -454128: 68, -454129: 0, -454130: 52, -454131: 0, -454132: 8, -454137: 128, -454138: 72, -454139: 0, -454140: 56, -454141: 0, -454142: 12, -889856: 0, -889857: 56, -889858: 8, -889859: 1, -889860: 189, -889861: 3, -889862: 5, -889863: 20, -889864: 224, -889865: 59, -889866: 168, -889867: 33, -889868: 159, -889869: 87, -889870: 210, -889871: 74, -889872: 78, -889873: 58, -889874: 187, -889875: 0, -889876: 181, -889877: 2, -889878: 107, -889879: 1, -889880: 82, -889881: 2, -889882: 4, -889883: 17, -889884: 116, -889885: 0, -889886: 13, -889887: 0, -454150: 56, -454151: 0, -454152: 12, -454157: 192, -454158: 80, -454159: 33, -454160: 60, -454161: 0, -454162: 16, -454167: 224, -454168: 84, -454169: 33, -454170: 60, -454171: 0, -454172: 16, -454177: 1, -454178: 89, -454179: 66, -454180: 64, -454181: 32, -454182: 20, -890144: 0, -890145: 0, -890146: 8, -890147: 1, -890148: 255, -890149: 2, -890150: 5, -890151: 20, -890152: 224, -890153: 59, -890154: 168, -890155: 33, -890156: 159, -890157: 87, -890158: 210, -890159: 74, -890160: 78, -890161: 58, -890162: 187, -890163: 0, -890164: 190, -890165: 1, -890166: 142, -890167: 0, -890168: 82, -890169: 2, -890170: 4, -890171: 17, -890172: 116, -890173: 0, -890174: 13, -890175: 0, -890176: 224, -890177: 20, -890178: 206, -890179: 0, -890180: 31, -890181: 66, -890182: 5, -890183: 20, -890184: 224, -890185: 59, -890186: 168, -890187: 33, -890188: 159, -890189: 87, -890190: 210, -890191: 74, -890192: 78, -890193: 58, -890194: 187, -890195: 0, -890196: 20, -890197: 89, -890198: 170, -890199: 48, -890200: 22, -890201: 2, -890202: 4, -890203: 17, -890204: 116, -890205: 0, -890206: 13, -890207: 0, -890208: 3, -890209: 32, -890210: 206, -890211: 40, -890212: 31, -890213: 110, -890214: 5, -890215: 60, -890216: 224, -890217: 99, -890218: 168, -890219: 73, -890220: 159, -890221: 127, -890222: 210, -890223: 114, -890224: 78, -890225: 98, -890226: 187, -890227: 40, -890228: 20, -890229: 125, -890230: 170, -890231: 88, -890232: 22, -890233: 42, -890234: 4, -890235: 57, -890236: 116, -890237: 40, -890238: 13, -890239: 40, -890240: 3, -890241: 32, -890242: 110, -890243: 81, -890244: 191, -890245: 126, -890246: 165, -890247: 100, -890248: 224, -890249: 127, -890250: 72, -890251: 114, -890252: 255, -890253: 127, -890254: 114, -890255: 127, -890256: 238, -890257: 126, -890258: 91, -890259: 85, -890260: 180, -890261: 125, -890262: 74, -890263: 125, -890264: 182, -890265: 82, -890266: 164, -890267: 97, -890268: 20, -890269: 81, -890270: 173, -890271: 80, -890272: 0, -890273: 0, -890274: 174, -890275: 82, -890276: 255, -890277: 127, -890278: 229, -890279: 101, -890280: 224, -890281: 127, -890282: 136, -890283: 115, -890284: 255, -890285: 127, -890286: 242, -890287: 127, -890288: 238, -890289: 127, -890290: 155, -890291: 86, -890292: 244, -890293: 126, -890294: 138, -890295: 126, -890296: 246, -890297: 83, -890298: 228, -890299: 98, -890300: 84, -890301: 82, -890302: 237, -890303: 81, -890304: 0, -890305: 56, -890306: 206, -890307: 0, -890308: 31, -890309: 66, -890310: 5, -890311: 20, -890312: 224, -890313: 59, -890314: 168, -890315: 33, -890316: 159, -890317: 87, -890318: 210, -890319: 74, -890320: 78, -890321: 58, -890322: 187, -890323: 0, -890324: 20, -890325: 89, -890326: 170, -890327: 48, -890328: 22, -890329: 2, -890330: 4, -890331: 17, -890332: 116, -890333: 0, -890334: 13, -890335: 0, -890336: 0, -890337: 56, -890338: 24, -890339: 22, -890340: 95, -890341: 87, -890342: 79, -890343: 41, -890344: 234, -890345: 79, -890346: 242, -890347: 54, -890348: 255, -890349: 107, -890350: 252, -890351: 95, -890352: 152, -890353: 71, -890354: 255, -890355: 21, -890356: 94, -890357: 110, -890358: 244, -890359: 69, -890360: 95, -890361: 23, -890362: 78, -890363: 38, -890364: 190, -890365: 21, -890366: 87, -890367: 21, -890368: 0, -890369: 56, -890370: 222, -890371: 2, -890372: 255, -890373: 67, -890374: 21, -890375: 22, -890376: 240, -890377: 59, -890378: 184, -890379: 35, -890380: 255, -890381: 87, -890382: 255, -890383: 75, -890384: 254, -890385: 59, -890386: 191, -890387: 2, -890388: 31, -890389: 91, -890390: 186, -890391: 50, -890392: 255, -890393: 3, -890394: 20, -890395: 19, -890396: 127, -890397: 2, -890398: 29, -890399: 2, -890400: 0, -890401: 56, -890402: 255, -890403: 43, -890404: 255, -890405: 107, -890406: 95, -890407: 63, -890408: 250, -890409: 99, -890410: 255, -890411: 75, -890412: 255, -890413: 127, -890414: 255, -890415: 115, -890416: 255, -890417: 99, -890418: 255, -890419: 43, -890420: 255, -890421: 127, -890422: 255, -890423: 91, -890424: 255, -890425: 43, -890426: 254, -890427: 59, -890428: 191, -890429: 43, -890430: 95, -890431: 43, -890432: 0, -890433: 56, -890434: 206, -890435: 0, -890436: 31, -890437: 66, -890438: 5, -890439: 20, -890440: 224, -890441: 59, -890442: 168, -890443: 33, -890444: 159, -890445: 87, -890446: 210, -890447: 74, -890448: 78, -890449: 58, -890450: 187, -890451: 0, -890452: 20, -890453: 89, -890454: 170, -890455: 48, -890456: 22, -890457: 2, -890458: 4, -890459: 17, -1152604: 56, -890461: 0, -890462: 13, -1152607: 24, -890464: 0, -890465: 56, -1152610: 0, -890467: 2, -890468: 95, -1152613: 221, -890470: 69, -890471: 21, -890472: 224, -890473: 67, -890474: 232, -1152619: 47, -890476: 255, -890477: 87, -890478: 242, -890479: 75, -890480: 142, -890481: 59, -1152626: 72, -890483: 1, -890484: 84, -890485: 90, -890486: 234, -890487: 49, -890488: 86, -890489: 3, -890490: 68, -890491: 18, -890492: 180, -890493: 1, -890494: 77, -890495: 1, -890496: 0, -890497: 56, -890498: 78, -890499: 3, -890500: 255, -890501: 67, -890502: 133, -890503: 22, -890504: 224, -890505: 79, -890506: 232, -890507: 35, -890508: 255, -890509: 87, -890510: 242, -890511: 75, -890512: 238, -890513: 59, -890514: 59, -890515: 3, -890516: 148, -890517: 91, -890518: 42, -890519: 51, -890520: 246, -890521: 3, -890522: 132, -890523: 19, -890524: 244, -890525: 2, -890526: 141, -890527: 2, -890528: 0, -890529: 56, -890530: 238, -890531: 43, -890532: 255, -890533: 107, -890534: 197, -890535: 63, -890536: 224, -890537: 99, -890538: 232, -890539: 75, -890540: 255, -890541: 127, -890542: 242, -890543: 115, -890544: 238, -890545: 99, -890546: 251, -890547: 43, -890548: 244, -890549: 127, -890550: 234, -890551: 91, -890552: 246, -890553: 43, -890554: 228, -890555: 59, -890556: 244, -890557: 43, -890558: 237, -890559: 43, -1677083: 0, -1677084: 0, -1677085: 233, -1677086: 39, -1677087: 102, -1677088: 26, -1677089: 133, -1677090: 21, -1677091: 163, -1677092: 12, -1677093: 156, -1677094: 63, -1677095: 151, -1677096: 46, -1677097: 114, -1677098: 29, -1677099: 142, -1677100: 16, -1677101: 95, -1677102: 10, -1677103: 219, -1677104: 9, -1677105: 86, -1677106: 9, -1677107: 210, -1677108: 8, -1677109: 44, -1677110: 8, -1677111: 189, -1677112: 127, -1677113: 5, -1677114: 12, -1677115: 3, -1677116: 32, -1677117: 235, -1677118: 39, -1677119: 136, -1677120: 26, -1677121: 167, -1677122: 21, -1677123: 196, -1677124: 12, -1677125: 92, -1677126: 59, -1677127: 88, -1677128: 46, -1677129: 83, -1677130: 29, -1677131: 111, -1677132: 16, -1677133: 63, -1677134: 14, -1677135: 187, -1677136: 13, -1677137: 54, -1677138: 13, -1677139: 210, -1677140: 12, -1677141: 44, -1677142: 12, -1677143: 189, -1677144: 119, -1677145: 6, -1677146: 12, -1677147: 3, -1677148: 32, -1677149: 237, -1677150: 35, -1677151: 138, -1677152: 22, -1677153: 200, -1677154: 17, -1677155: 229, -1677156: 8, -1677157: 253, -1677158: 58, -1677159: 56, -1677160: 42, -1677161: 52, -1677162: 29, -1677163: 113, -1677164: 16, -1677165: 255, -1677166: 13, -1677167: 155, -1677168: 13, -1677169: 54, -1677170: 13, -1677171: 179, -1677172: 12, -1677173: 45, -1677174: 12, -1677175: 222, -1677176: 111, -1677177: 7, -1677178: 8, -1677179: 0, -1677180: 0, -1677181: 239, -1677182: 35, -1677183: 172, -890752: 0, -890753: 0, -890754: 206, -890755: 0, -890756: 31, -890757: 66, -890758: 5, -890759: 20, -890760: 224, -890761: 59, -890762: 168, -1677195: 82, -890764: 159, -890765: 87, -890766: 210, -890767: 74, -1677200: 17, -890769: 58, -890770: 187, -890771: 0, -890772: 20, -1677205: 45, -890774: 170, -890775: 48, -890776: 22, -890777: 2, -1677210: 8, -890779: 17, -890780: 116, -890781: 0, -1677214: 35, -1677215: 207, -890784: 0, -890785: 0, -890786: 214, -890787: 33, -1677220: 9, -890789: 86, -890790: 170, -890791: 40, -890792: 229, -890793: 79, -890794: 77, -890795: 54, -890796: 191, -890797: 99, -890798: 54, -890799: 91, -890800: 212, -890801: 82, -890802: 92, -890803: 21, -890804: 184, -890805: 101, -890806: 79, -1677239: 222, -1677240: 95, -890809: 22, -890810: 169, -890811: 37, -890812: 24, -1677245: 244, -890814: 178, -890815: 20, -890816: 0, -890817: 0, -1677250: 18, -890819: 46, -890820: 95, -890821: 107, -890822: 112, -890823: 65, -890824: 235, -890825: 103, -890826: 19, -890827: 79, -1677260: 20, -890829: 115, -890830: 155, -890831: 111, -1677264: 21, -1677265: 215, -890834: 30, -1677267: 147, -1677268: 20, -890837: 114, -1677270: 20, -890839: 94, -890840: 92, -890841: 47, -890842: 111, -1677275: 0, -890844: 219, -890845: 45, -890846: 120, -890847: 45, -890848: 0, -890849: 0, -890850: 222, -890851: 66, -890852: 255, -1677285: 222, -890854: 21, -890855: 86, -1677288: 33, -1677289: 152, -890858: 184, -890859: 99, -890860: 255, -1677293: 95, -1677294: 21, -1677295: 28, -1677296: 21, -1677297: 215, -890866: 191, -890867: 66, -890868: 31, -890869: 127, -890870: 186, -890871: 114, -890872: 255, -890873: 67, -890874: 20, -890875: 83, -1677308: 0, -890877: 66, -890878: 29, -890879: 66, -890880: 0, -890881: 56, -890882: 8, -890883: 1, -1677316: 5, -890885: 66, -1677318: 41, -890887: 20, -890888: 224, -890889: 59, -890890: 168, -1153035: 0, -1153036: 56, -1153037: 245, -1153038: 87, -1153039: 239, -890896: 78, -1153041: 130, -890898: 187, -1153043: 192, -1153044: 0, -890901: 89, -1153046: 87, -1153047: 173, -890904: 116, -890905: 2, -1153050: 46, -890907: 17, -890908: 116, -1153053: 253, -890910: 13, -1153055: 213, -890912: 0, -1153057: 15, -1153058: 2, -1153059: 73, -1153060: 1, -1153061: 223, -1153062: 62, -1153063: 24, -1153064: 0, -1153065: 15, -1153066: 0, -890923: 33, -890924: 159, -890925: 87, -890926: 210, -890927: 74, -890928: 78, -890929: 58, -890930: 187, -890931: 0, -890932: 181, -890933: 2, -890934: 107, -890935: 1, -890936: 82, -890937: 2, -890938: 4, -890939: 17, -890940: 116, -890941: 0, -890942: 13, -890943: 0, -890944: 99, -890945: 12, -890946: 74, -890947: 13, -890948: 189, -890949: 15, -890950: 104, -890951: 32, -890952: 227, -890953: 67, -890954: 234, -890955: 41, -890956: 159, -890957: 91, -890958: 243, -890959: 78, -890960: 112, -890961: 66, -890962: 27, -890963: 13, -890964: 214, -890965: 14, -890966: 173, -890967: 13, -890968: 115, -890969: 14, -890970: 71, -890971: 29, -890972: 213, -890973: 12, -890974: 111, -890975: 12, -890976: 231, -890977: 28, -890978: 173, -890979: 29, -890980: 189, -890981: 31, -890982: 235, -890983: 44, -890984: 231, -890985: 75, -890986: 45, -890987: 54, -890988: 159, -890989: 95, -890990: 21, -890991: 87, -890992: 178, -890993: 74, -890994: 124, -890995: 29, -890996: 247, -890997: 30, -890998: 16, -890999: 30, -891000: 181, -891001: 30, -891002: 170, -891003: 41, -891004: 86, -891005: 29, -891006: 241, -891007: 28, -891008: 107, -891009: 45, -891010: 16, -891011: 46, -891012: 189, -891013: 47, -891014: 110, -891015: 57, -891016: 235, -891017: 83, -891018: 112, -891019: 66, -891020: 191, -891021: 99, -891022: 54, -891023: 91, -891024: 212, -891025: 82, -891026: 220, -891027: 45, -891028: 24, -891029: 47, -891030: 82, -891031: 46, -891032: 214, -891033: 46, -891034: 14, -891035: 58, -891036: 184, -891037: 45, -891038: 115, -891039: 45, -891040: 239, -891041: 61, -891042: 115, -891043: 62, -891044: 222, -891045: 63, -891046: 242, -891047: 73, -891048: 239, -891049: 91, -891050: 211, -891051: 78, -891052: 191, -891053: 107, -891054: 88, -891055: 99, -891056: 22, -891057: 91, -891058: 93, -891059: 62, -891060: 90, -891061: 63, -891062: 181, -891063: 62, -891064: 24, -891065: 63, -891066: 113, -891067: 70, -891068: 57, -891069: 62, -891070: 246, -891071: 61, -891072: 115, -891073: 78, -891074: 214, -891075: 78, -891076: 222, -891077: 79, -891078: 117, -891079: 86, -891080: 243, -891081: 99, -891082: 22, -891083: 91, -891084: 191, -891085: 111, -891086: 122, -891087: 107, -891088: 88, -891089: 99, -891090: 189, -891091: 78, -891092: 123, -891093: 79, -891094: 247, -891095: 78, -891096: 90, -891097: 79, -891098: 212, -891099: 82, -891100: 154, -891101: 78, -891102: 120, -891103: 78, -891104: 247, -891105: 94, -891106: 57, -891107: 95, -891108: 222, -891109: 95, -891110: 248, -891111: 98, -891112: 247, -891113: 107, -891114: 89, -891115: 103, -891116: 223, -891117: 115, -891118: 155, -891119: 111, -891120: 122, -891121: 107, -891122: 30, -891123: 95, -891124: 156, -891125: 95, -891126: 90, -891127: 95, -891128: 123, -891129: 95, -891130: 56, -891131: 99, -891132: 28, -891133: 95, -891134: 250, -891135: 94, -891136: 123, -891137: 111, -891138: 156, -891139: 111, -891140: 222, -891141: 111, -891142: 123, -891143: 111, -891144: 251, -891145: 115, -891146: 156, -891147: 115, -891148: 223, -891149: 119, -891150: 189, -891151: 119, -891152: 188, -891153: 115, -891154: 126, -891155: 111, -891156: 189, -891157: 111, -891158: 156, -891159: 111, -891160: 189, -891161: 111, -891162: 155, -891163: 111, -891164: 125, -891165: 111, -891166: 124, -891167: 111, -891168: 0, -891169: 0, -891170: 8, -891171: 1, -891172: 255, -891173: 2, -891174: 5, -891175: 20, -891176: 224, -891177: 59, -891178: 168, -891179: 33, -891180: 159, -891181: 87, -891182: 210, -891183: 74, -891184: 78, -891185: 58, -891186: 187, -891187: 0, -891188: 190, -891189: 1, -891190: 142, -891191: 0, -891192: 82, -891193: 2, -891194: 4, -891195: 17, -891196: 116, -891197: 0, -891198: 13, -891199: 0, -891200: 99, -891201: 12, -891202: 74, -891203: 13, -891204: 31, -891205: 15, -891206: 104, -891207: 32, -891208: 227, -891209: 67, -891210: 234, -891211: 41, -891212: 159, -891213: 91, -891214: 243, -891215: 78, -891216: 112, -891217: 66, -891218: 27, -891219: 13, -891220: 254, -891221: 13, -891222: 240, -891223: 12, -891224: 115, -891225: 14, -891226: 71, -891227: 29, -891228: 213, -891229: 12, -891230: 111, -891231: 12, -891232: 231, -891233: 28, -891234: 173, -891235: 29, -891236: 63, -891237: 31, -891238: 235, -891239: 44, -891240: 231, -891241: 75, -891242: 45, -891243: 54, -891244: 159, -891245: 95, -891246: 21, -891247: 87, -891248: 178, -891249: 74, -891250: 124, -891251: 29, -891252: 62, -891253: 30, -891254: 82, -891255: 29, -891256: 181, -891257: 30, -891258: 170, -891259: 41, -891260: 86, -891261: 29, -891262: 241, -891263: 28, -891264: 107, -891265: 45, -891266: 16, -891267: 46, -891268: 95, -891269: 47, -891270: 110, -891271: 57, -891272: 235, -891273: 83, -891274: 112, -891275: 66, -891276: 191, -891277: 99, -891278: 54, -891279: 91, -891280: 212, -891281: 82, -891282: 220, -891283: 45, -891284: 126, -891285: 46, -891286: 212, -891287: 45, -891288: 214, -891289: 46, -891290: 14, -891291: 58, -891292: 184, -891293: 45, -891294: 115, -891295: 45, -891296: 239, -891297: 61, -891298: 115, -891299: 62, -891300: 127, -891301: 63, -891302: 242, -891303: 73, -891304: 239, -891305: 91, -891306: 211, -891307: 78, -891308: 191, -891309: 107, -891310: 88, -891311: 99, -891312: 22, -891313: 91, -891314: 93, -891315: 62, -891316: 222, -891317: 62, -891318: 54, -891319: 62, -891320: 24, -891321: 63, -891322: 113, -891323: 70, -891324: 57, -891325: 62, -891326: 246, -891327: 61, -891328: 115, -891329: 78, -891330: 214, -891331: 78, -891332: 159, -891333: 79, -891334: 117, -891335: 86, -891336: 243, -891337: 99, -891338: 22, -891339: 91, -891340: 191, -891341: 111, -891342: 122, -891343: 107, -891344: 88, -891345: 99, -891346: 189, -891347: 78, -891348: 30, -891349: 79, -891350: 152, -891351: 78, -891352: 90, -891353: 79, -891354: 212, -891355: 82, -891356: 154, -891357: 78, -891358: 120, -891359: 78, -891360: 247, -891361: 94, -891362: 57, -891363: 95, -891364: 191, -891365: 95, -891366: 248, -891367: 98, -891368: 247, -891369: 107, -891370: 89, -891371: 103, -891372: 223, -891373: 115, -891374: 155, -891375: 111, -891376: 122, -891377: 107, -891378: 30, -891379: 95, -891380: 94, -891381: 95, -891382: 26, -891383: 95, -891384: 123, -891385: 95, -891386: 56, -891387: 99, -891388: 28, -891389: 95, -891390: 250, -891391: 94, -891392: 123, -891393: 111, -891394: 156, -891395: 111, -891396: 223, -891397: 111, -891398: 123, -891399: 111, -891400: 251, -891401: 115, -891402: 156, -891403: 115, -891404: 223, -891405: 119, -891406: 189, -891407: 119, -891408: 188, -891409: 115, -891410: 126, -891411: 111, -891412: 158, -891413: 111, -891414: 124, -891415: 111, -891416: 189, -891417: 111, -891418: 155, -891419: 111, -891420: 125, -891421: 111, -891422: 124, -891423: 111, -891424: 224, -891425: 20, -891426: 206, -891427: 0, -891428: 31, -891429: 66, -891430: 5, -891431: 20, -891432: 224, -891433: 59, -891434: 168, -891435: 33, -891436: 159, -891437: 87, -891438: 210, -891439: 74, -891440: 78, -891441: 58, -891442: 187, -891443: 0, -891444: 20, -891445: 89, -891446: 170, -891447: 48, -891448: 22, -891449: 2, -891450: 4, -891451: 17, -891452: 116, -891453: 0, -891454: 13, -891455: 0, -891456: 67, -891457: 33, -891458: 48, -891459: 13, -891460: 63, -891461: 70, -891462: 104, -891463: 32, -891464: 227, -891465: 67, -891466: 234, -891467: 41, -891468: 159, -891469: 91, -891470: 243, -891471: 78, -891472: 112, -891473: 66, -891474: 27, -891475: 13, -891476: 85, -891477: 93, -891478: 12, -891479: 57, -891480: 55, -891481: 14, -891482: 71, -891483: 29, -891484: 213, -891485: 12, -891486: 111, -891487: 12, -891488: 167, -891489: 45, -891490: 146, -891491: 29, -891492: 127, -891493: 78, -891494: 235, -891495: 44, -891496: 231, -891497: 75, -891498: 45, -891499: 54, -891500: 159, -891501: 95, -891502: 21, -891503: 87, -891504: 178, -891505: 74, -891506: 124, -891507: 29, -891508: 182, -891509: 97, -891510: 111, -891511: 65, -891512: 120, -891513: 30, -891514: 170, -891515: 41, -891516: 86, -891517: 29, -891518: 241, -891519: 28, -891520: 11, -891521: 58, -891522: 244, -891523: 45, -891524: 191, -891525: 86, -891526: 110, -891527: 57, -891528: 235, -891529: 83, -891530: 112, -891531: 66, -891532: 191, -891533: 99, -891534: 54, -891535: 91, -891536: 212, -891537: 82, -891538: 220, -891539: 45, -891540: 24, -891541: 102, -891542: 209, -891543: 77, -891544: 185, -891545: 46, -891546: 14, -891547: 58, -891548: 184, -891549: 45, -891550: 115, -891551: 45, -891552: 111, -891553: 74, -891554: 86, -891555: 62, -891556: 255, -891557: 94, -891558: 242, -891559: 73, -891560: 239, -891561: 91, -891562: 211, -891563: 78, -891564: 191, -891565: 107, -891566: 88, -891567: 99, -891568: 22, -891569: 91, -891570: 93, -891571: 62, -891572: 121, -891573: 106, -891574: 84, -891575: 86, -891576: 250, -891577: 62, -891578: 113, -891579: 70, -891580: 57, -891581: 62, -891582: 246, -891583: 61, -891584: 211, -891585: 86, -891586: 184, -891587: 78, -891588: 63, -891589: 103, -891590: 117, -891591: 86, -891592: 243, -891593: 99, -891594: 22, -891595: 91, -891596: 191, -891597: 111, -891598: 122, -891599: 107, -891600: 88, -891601: 99, -891602: 189, -891603: 78, -891604: 218, -891605: 110, -891606: 183, -891607: 94, -891608: 59, -891609: 79, -891610: 212, -891611: 82, -891612: 154, -891613: 78, -891614: 120, -891615: 78, -891616: 55, -891617: 99, -891618: 26, -891619: 95, -891620: 127, -891621: 111, -891622: 248, -891623: 98, -891624: 247, -891625: 107, -891626: 89, -891627: 103, -891628: 223, -891629: 115, -891630: 155, -891631: 111, -891632: 122, -891633: 107, -891634: 30, -891635: 95, -891636: 60, -891637: 115, -891638: 25, -891639: 107, -891640: 124, -891641: 95, -891642: 56, -891643: 99, -891644: 28, -891645: 95, -891646: 250, -891647: 94, -891648: 155, -891649: 111, -891650: 124, -891651: 111, -891652: 191, -891653: 119, -891654: 123, -891655: 111, -891656: 251, -891657: 115, -891658: 156, -891659: 115, -891660: 223, -891661: 119, -891662: 189, -891663: 119, -891664: 188, -891665: 115, -891666: 126, -891667: 111, -891668: 157, -891669: 119, -891670: 124, -891671: 115, -891672: 189, -891673: 111, -891674: 155, -891675: 111, -891676: 125, -891677: 111, -891678: 124, -891679: 111, -891680: 0, -891681: 0, -891682: 8, -891683: 1, -891684: 189, -891685: 3, -891686: 5, -891687: 20, -891688: 224, -891689: 59, -891690: 168, -891691: 33, -891692: 159, -891693: 87, -891694: 210, -891695: 74, -891696: 78, -891697: 58, -891698: 187, -891699: 0, -891700: 181, -891701: 2, -891702: 107, -891703: 1, -891704: 82, -891705: 2, -891706: 4, -891707: 17, -891708: 116, -891709: 0, -891710: 13, -891711: 0, -891712: 3, -891713: 32, -891714: 206, -891715: 40, -891716: 189, -891717: 55, -891718: 5, -891719: 60, -891720: 224, -891721: 99, -891722: 168, -891723: 73, -891724: 159, -891725: 127, -891726: 210, -891727: 114, -891728: 78, -891729: 98, -891730: 187, -891731: 40, -891732: 181, -891733: 54, -891734: 107, -891735: 53, -891736: 22, -891737: 42, -891738: 4, -891739: 57, -891740: 116, -891741: 40, -891742: 13, -891743: 40, -891744: 3, -891745: 32, -891746: 110, -891747: 81, -891748: 189, -891749: 75, -891750: 165, -891751: 100, -891752: 224, -891753: 127, -891754: 72, -891755: 114, -891756: 255, -891757: 127, -891758: 114, -891759: 127, -891760: 238, -891761: 126, -891762: 91, -891763: 85, -891764: 181, -891765: 74, -891766: 107, -891767: 73, -891768: 182, -891769: 82, -891770: 164, -1153915: 0, -1153916: 56, -1153917: 87, -1153918: 63, -1153919: 77, -891776: 0, -1153921: 226, -1153922: 0, -1153923: 96, -1153924: 0, -1153925: 176, -1153926: 58, -1153927: 11, -1153928: 34, -1153929: 102, -1153930: 17, -1153931: 36, -1153932: 9, -1153933: 90, -1153934: 127, -1153935: 192, -1153936: 126, -1153937: 224, -1153938: 109, -1153939: 224, -1153940: 84, -1153941: 255, -1153942: 3, -1153943: 55, -1153944: 2, -1153945: 209, -1153946: 0, -1153947: 0, -1153948: 56, -1153949: 90, -891806: 237, -1153951: 224, -1153952: 59, -1153953: 128, -1153954: 38, -1153955: 32, -1153956: 9, -1153957: 90, -1153958: 79, -1153959: 181, -1153960: 54, -1153961: 16, -1153962: 38, -1153963: 206, -1153964: 29, -1153965: 148, -1153966: 82, -1153967: 206, -1153968: 57, -1153969: 8, -1153970: 33, -1153971: 132, -1153972: 16, -1153973: 59, -1153974: 3, -1153975: 22, -1153976: 2, -1153977: 19, -1153978: 1, -891835: 17, -891836: 116, -891837: 0, -891838: 13, -891839: 0, -891840: 0, -891841: 0, -891842: 173, -891843: 29, -891844: 189, -891845: 31, -891846: 235, -891847: 44, -891848: 231, -891849: 75, -891850: 45, -891851: 54, -891852: 159, -891853: 95, -891854: 21, -891855: 87, -891856: 178, -891857: 74, -891858: 124, -891859: 29, -891860: 247, -891861: 30, -891862: 16, -891863: 30, -891864: 181, -891865: 30, -891866: 170, -891867: 41, -891868: 86, -891869: 29, -891870: 241, -891871: 28, -891872: 0, -891873: 0, -891874: 115, -891875: 62, -891876: 222, -891877: 63, -891878: 242, -891879: 73, -891880: 239, -891881: 91, -891882: 211, -891883: 78, -891884: 191, -891885: 107, -891886: 88, -891887: 99, -891888: 22, -891889: 91, -891890: 93, -891891: 62, -891892: 90, -891893: 63, -891894: 181, -891895: 62, -891896: 24, -891897: 63, -891898: 113, -891899: 70, -891900: 57, -891901: 62, -891902: 246, -891903: 61, -891904: 0, -891905: 0, -891906: 57, -891907: 95, -891908: 222, -891909: 95, -891910: 248, -891911: 98, -891912: 247, -891913: 107, -891914: 89, -891915: 103, -891916: 223, -891917: 115, -891918: 155, -891919: 111, -891920: 122, -891921: 107, -891922: 30, -891923: 95, -891924: 156, -891925: 95, -891926: 90, -891927: 95, -891928: 123, -891929: 95, -891930: 56, -891931: 99, -891932: 28, -891933: 95, -891934: 250, -891935: 94, -891936: 0, -891937: 56, -891938: 8, -891939: 1, -891940: 189, -891941: 3, -891942: 5, -891943: 20, -891944: 224, -891945: 59, -891946: 168, -891947: 33, -891948: 159, -891949: 87, -891950: 210, -891951: 74, -891952: 78, -891953: 58, -891954: 187, -891955: 0, -891956: 181, -891957: 2, -891958: 107, -891959: 1, -891960: 82, -891961: 2, -891962: 4, -891963: 17, -891964: 116, -891965: 0, -891966: 13, -891967: 0, -891968: 0, -891969: 56, -891970: 173, -891971: 1, -891972: 255, -891973: 3, -891974: 79, -891975: 41, -891976: 234, -891977: 79, -891978: 242, -891979: 54, -891980: 255, -891981: 107, -891982: 252, -891983: 95, -891984: 152, -891985: 71, -891986: 124, -891987: 1, -891988: 24, -891989: 3, -891990: 16, -891991: 2, -891992: 181, -891993: 2, -891994: 78, -891995: 38, -891996: 190, -891997: 21, -891998: 87, -891999: 21, -892000: 0, -892001: 56, -892002: 115, -892003: 2, -892004: 255, -892005: 23, -892006: 21, -892007: 22, -892008: 240, -892009: 59, -892010: 184, -892011: 35, -892012: 255, -892013: 87, -892014: 255, -892015: 75, -892016: 254, -892017: 59, -892018: 93, -892019: 2, -892020: 123, -892021: 3, -892022: 181, -892023: 2, -892024: 24, -892025: 3, -892026: 20, -892027: 19, -892028: 127, -892029: 2, -892030: 29, -892031: 2, -892032: 0, -892033: 56, -892034: 57, -892035: 3, -892036: 255, -892037: 35, -892038: 95, -892039: 63, -892040: 250, -892041: 99, -892042: 255, -892043: 75, -892044: 255, -892045: 127, -892046: 255, -892047: 115, -892048: 255, -892049: 99, -892050: 30, -892051: 3, -892052: 222, -892053: 3, -892054: 90, -892055: 3, -892056: 123, -892057: 3, -892058: 254, -892059: 59, -892060: 191, -892061: 43, -892062: 95, -892063: 43, -892064: 0, -892065: 56, -892066: 8, -892067: 1, -892068: 189, -892069: 3, -892070: 5, -892071: 20, -892072: 224, -892073: 59, -892074: 168, -892075: 33, -892076: 159, -892077: 87, -892078: 210, -892079: 74, -892080: 78, -892081: 58, -892082: 187, -892083: 0, -892084: 181, -892085: 2, -892086: 107, -892087: 1, -892088: 82, -892089: 2, -892090: 4, -892091: 17, -892092: 116, -892093: 0, -892094: 13, -892095: 0, -892096: 0, -892097: 56, -892098: 168, -892099: 1, -892100: 248, -892101: 3, -892102: 69, -892103: 21, -892104: 224, -892105: 67, -892106: 232, -892107: 34, -892108: 255, -892109: 87, -892110: 242, -892111: 75, -892112: 142, -892113: 59, -892114: 251, -892115: 1, -892116: 85, -892117: 3, -892118: 11, -892119: 2, -892120: 86, -892121: 3, -892122: 68, -892123: 18, -892124: 180, -892125: 1, -892126: 77, -892127: 1, -892128: 0, -892129: 56, -892130: 72, -892131: 2, -892132: 243, -892133: 3, -892134: 133, -892135: 22, -892136: 224, -892137: 79, -892138: 232, -892139: 35, -892140: 255, -892141: 87, -892142: 242, -892143: 75, -892144: 238, -892145: 59, -892146: 59, -892147: 3, -892148: 245, -892149: 3, -892150: 171, -892151: 2, -892152: 246, -892153: 3, -892154: 132, -892155: 19, -892156: 244, -892157: 2, -892158: 141, -892159: 2, -892160: 0, -892161: 56, -892162: 232, -892163: 2, -892164: 238, -892165: 3, -892166: 197, -892167: 63, -892168: 224, -892169: 99, -892170: 232, -892171: 75, -892172: 255, -892173: 127, -892174: 242, -892175: 115, -892176: 238, -892177: 99, -892178: 251, -892179: 43, -892180: 240, -892181: 3, -892182: 75, -892183: 3, -892184: 246, -892185: 43, -892186: 228, -892187: 59, -892188: 244, -892189: 43, -892190: 237, -892191: 43, -892192: 0, -892193: 0, -892194: 8, -892195: 1, -892196: 255, -892197: 2, -892198: 5, -892199: 20, -892200: 224, -892201: 59, -892202: 168, -892203: 33, -892204: 159, -892205: 87, -892206: 210, -892207: 74, -892208: 78, -892209: 58, -892210: 187, -892211: 0, -892212: 190, -892213: 1, -892214: 142, -892215: 0, -892216: 82, -892217: 2, -892218: 4, -892219: 17, -892220: 116, -892221: 0, -892222: 13, -892223: 0, -892224: 3, -892225: 32, -892226: 8, -892227: 41, -892228: 255, -892229: 42, -892230: 5, -892231: 60, -892232: 224, -892233: 99, -892234: 168, -892235: 73, -892236: 159, -892237: 127, -892238: 210, -892239: 114, -892240: 78, -892241: 98, -892242: 187, -892243: 40, -892244: 190, -892245: 41, -892246: 142, -892247: 40, -892248: 77, -892249: 42, -892250: 4, -892251: 57, -892252: 116, -892253: 40, -892254: 13, -892255: 40, -892256: 3, -892257: 32, -892258: 8, -892259: 81, -892260: 255, -892261: 82, -892262: 165, -892263: 100, -892264: 224, -892265: 127, -892266: 72, -892267: 114, -892268: 255, -892269: 127, -892270: 114, -892271: 127, -892272: 238, -892273: 126, -892274: 91, -892275: 85, -892276: 190, -892277: 81, -892278: 142, -892279: 80, -892280: 77, -892281: 62, -892282: 164, -892283: 97, -892284: 20, -892285: 81, -892286: 173, -892287: 80, -892288: 0, -892289: 0, -892290: 168, -892291: 121, -892292: 159, -892293: 123, -892294: 229, -892295: 101, -892296: 224, -892297: 127, -892298: 136, -892299: 115, -892300: 255, -892301: 127, -892302: 242, -892303: 127, -892304: 238, -892305: 127, -892306: 155, -892307: 86, -892308: 94, -892309: 118, -892310: 46, -454553: 0, -892312: 77, -892313: 82, -892314: 228, -892315: 98, -892316: 84, -454554: 0, -892318: 237, -892319: 81, -892320: 0, -892321: 0, -892322: 8, -892323: 1, -892324: 255, -892325: 2, -892326: 5, -892327: 20, -892328: 224, -892329: 59, -892330: 168, -892331: 33, -892332: 159, -892333: 87, -892334: 210, -892335: 74, -892336: 78, -892337: 58, -892338: 187, -892339: 0, -892340: 190, -892341: 1, -892342: 142, -892343: 0, -892344: 82, -892345: 2, -892346: 4, -892347: 17, -892348: 116, -892349: 0, -892350: 13, -892351: 0, -892352: 0, -892353: 0, -892354: 173, -892355: 29, -892356: 63, -892357: 31, -892358: 235, -892359: 44, -892360: 231, -892361: 75, -892362: 45, -892363: 54, -892364: 159, -892365: 95, -892366: 21, -892367: 87, -892368: 178, -892369: 74, -892370: 124, -892371: 29, -892372: 62, -892373: 30, -892374: 82, -892375: 29, -892376: 181, -892377: 30, -892378: 170, -892379: 41, -892380: 86, -892381: 29, -892382: 241, -892383: 28, -892384: 0, -892385: 0, -892386: 115, -892387: 62, -892388: 127, -892389: 63, -892390: 242, -892391: 73, -892392: 239, -892393: 91, -892394: 211, -892395: 78, -892396: 191, -892397: 107, -892398: 88, -892399: 99, -892400: 22, -892401: 91, -892402: 93, -892403: 62, -892404: 222, -892405: 62, -892406: 54, -454569: 5, -892408: 24, -892409: 63, -892410: 113, -892411: 70, -892412: 57, -892413: 62, -892414: 246, -892415: 61, -892416: 0, -892417: 0, -892418: 57, -892419: 95, -892420: 191, -892421: 95, -892422: 248, -892423: 98, -892424: 247, -892425: 107, -892426: 89, -892427: 103, -892428: 223, -892429: 115, -892430: 155, -892431: 111, -892432: 122, -892433: 107, -892434: 30, -892435: 95, -892436: 94, -892437: 95, -892438: 26, -892439: 95, -892440: 123, -892441: 95, -892442: 56, -454575: 0, -892444: 28, -892445: 95, -892446: 250, -892447: 94, -892448: 0, -454576: 0, -892450: 8, -892451: 1, -892452: 255, -892453: 2, -892454: 5, -892455: 20, -892456: 224, -892457: 59, -892458: 168, -892459: 33, -892460: 159, -454578: 0, -892462: 210, -892463: 74, -892464: 78, -892465: 58, -892466: 187, -892467: 0, -892468: 190, -892469: 1, -892470: 142, -892471: 0, -892472: 82, -892473: 2, -892474: 4, -892475: 17, -892476: 116, -892477: 0, -892478: 13, -892479: 0, -892480: 0, -892481: 56, -892482: 173, -892483: 1, -892484: 159, -892485: 3, -892486: 79, -892487: 41, -892488: 234, -892489: 79, -892490: 242, -892491: 54, -892492: 255, -892493: 107, -892494: 252, -892495: 95, -892496: 152, -892497: 71, -892498: 255, -892499: 21, -892500: 94, -892501: 2, -892502: 51, -454585: 20, -892504: 247, -892505: 2, -892506: 78, -892507: 38, -892508: 190, -454586: 64, -892510: 87, -892511: 21, -892512: 0, -892513: 56, -892514: 82, -454587: 12, -892516: 255, -892517: 3, -892518: 21, -892519: 22, -892520: 240, -454588: 28, -892522: 184, -892523: 35, -892524: 255, -892525: 87, -892526: 255, -454589: 6, -892528: 254, -892529: 59, -892530: 191, -892531: 2, -892532: 254, -454590: 24, -892534: 216, -892535: 1, -892536: 156, -892537: 3, -892538: 20, -892539: 19, -892540: 127, -892541: 2, -892542: 29, -892543: 2, -892544: 0, -892545: 56, -892546: 247, -892547: 2, -892548: 255, -892549: 23, -892550: 95, -892551: 63, -892552: 250, -892553: 99, -892554: 255, -892555: 75, -892556: 255, -892557: 127, -892558: 255, -892559: 115, -892560: 255, -892561: 99, -892562: 255, -892563: 43, -892564: 158, -892565: 3, -892566: 125, -892567: 2, -892568: 255, -892569: 3, -892570: 254, -892571: 59, -892572: 191, -892573: 43, -892574: 95, -892575: 43, -892576: 0, -892577: 56, -892578: 8, -892579: 1, -892580: 255, -892581: 2, -892582: 5, -892583: 20, -892584: 224, -892585: 59, -892586: 168, -892587: 33, -892588: 159, -892589: 87, -892590: 210, -892591: 74, -892592: 78, -892593: 58, -892594: 187, -892595: 0, -892596: 190, -892597: 1, -892598: 142, -892599: 0, -892600: 82, -892601: 2, -892602: 4, -892603: 17, -892604: 116, -892605: 0, -892606: 13, -892607: 0, -892608: 0, -892609: 56, -892610: 168, -892611: 1, -892612: 159, -892613: 3, -892614: 69, -892615: 21, -892616: 224, -892617: 67, -892618: 232, -892619: 34, -892620: 255, -892621: 87, -892622: 242, -892623: 75, -892624: 142, -892625: 59, -892626: 251, -892627: 1, -892628: 94, -892629: 2, -892630: 46, -892631: 1, -892632: 242, -892633: 2, -892634: 68, -892635: 18, -892636: 180, -892637: 1, -892638: 77, -892639: 1, -892640: 0, -892641: 56, -892642: 72, -892643: 2, -892644: 154, -892645: 3, -892646: 133, -892647: 22, -892648: 224, -892649: 79, -892650: 232, -892651: 35, -892652: 255, -892653: 87, -892654: 242, -892655: 75, -892656: 238, -892657: 59, -892658: 59, -892659: 3, -892660: 254, -892661: 2, -892662: 206, -892663: 1, -892664: 146, -892665: 3, -892666: 132, -892667: 19, -892668: 244, -892669: 2, -892670: 141, -892671: 2, -892672: 0, -892673: 56, -892674: 232, -892675: 2, -892676: 148, -892677: 3, -892678: 197, -892679: 63, -892680: 224, -892681: 99, -892682: 232, -892683: 75, -892684: 255, -892685: 127, -892686: 242, -892687: 115, -892688: 238, -892689: 99, -892690: 251, -892691: 43, -892692: 158, -892693: 3, -892694: 110, -892695: 2, -892696: 242, -892697: 3, -892698: 228, -892699: 59, -892700: 244, -892701: 43, -892702: 237, -892703: 43, -1500569: 12, -892705: 20, -892706: 206, -454619: 0, -892708: 31, -892709: 66, -892710: 5, -892711: 20, -892712: 224, -454620: 0, -892714: 168, -892715: 33, -892716: 159, -892717: 87, -892718: 210, -892719: 74, -892720: 78, -892721: 58, -892722: 187, -892723: 0, -892724: 20, -892725: 89, -892726: 170, -892727: 48, -892728: 22, -892729: 2, -892730: 4, -892731: 17, -892732: 116, -892733: 0, -892734: 13, -892735: 0, -892736: 3, -892737: 32, -892738: 206, -892739: 40, -892740: 31, -892741: 110, -892742: 5, -454625: 22, -892744: 224, -892745: 99, -892746: 168, -892747: 73, -892748: 159, -454626: 72, -892750: 210, -892751: 114, -892752: 78, -892753: 98, -892754: 187, -454627: 14, -892756: 20, -892757: 125, -892758: 170, -892759: 88, -892760: 22, -454628: 36, -892762: 4, -892763: 57, -892764: 116, -892765: 40, -892766: 13, -454629: 8, -892768: 3, -892769: 32, -892770: 110, -892771: 81, -892772: 191, -454630: 32, -892774: 165, -892775: 100, -892776: 224, -892777: 127, -892778: 72, -454631: 6, -892780: 255, -892781: 127, -892782: 114, -892783: 127, -892784: 238, -454632: 24, -892786: 91, -892787: 85, -892788: 180, -892789: 125, -892790: 74, -454633: 4, -892792: 182, -892793: 82, -892794: 164, -892795: 97, -892796: 20, -454634: 16, -892798: 173, -892799: 80, -892800: 0, -892801: 0, -892802: 174, -454635: 2, -892804: 255, -892805: 127, -892806: 229, -892807: 101, -892808: 224, -454636: 8, -892810: 136, -892811: 115, -892812: 255, -892813: 127, -892814: 242, -454637: 1, -892816: 238, -892817: 127, -892818: 155, -892819: 86, -892820: 244, -454638: 4, -892822: 138, -892823: 126, -892824: 246, -892825: 83, -892826: 228, -454639: 0, -892828: 84, -892829: 82, -892830: 237, -892831: 81, -892832: 0, -454640: 0, -892834: 206, -1640238: 0, -892836: 31, -892837: 66, -892838: 5, -892839: 20, -892840: 224, -892841: 59, -892842: 168, -892843: 33, -892844: 159, -892845: 87, -892846: 210, -892847: 74, -892848: 78, -892849: 58, -892850: 187, -892851: 0, -892852: 20, -892853: 89, -892854: 170, -892855: 48, -892856: 22, -892857: 2, -892858: 4, -892859: 17, -892860: 116, -892861: 0, -892862: 13, -892863: 0, -892864: 0, -892865: 0, -892866: 146, -892867: 29, -892868: 127, -892869: 78, -892870: 235, -892871: 44, -892872: 231, -892873: 75, -892874: 45, -892875: 54, -892876: 159, -892877: 95, -892878: 21, -892879: 87, -892880: 178, -892881: 74, -892882: 124, -892883: 29, -892884: 182, -892885: 97, -892886: 111, -892887: 65, -892888: 120, -892889: 30, -892890: 170, -892891: 41, -892892: 86, -892893: 29, -892894: 241, -892895: 28, -892896: 0, -892897: 0, -892898: 86, -892899: 62, -892900: 255, -892901: 94, -892902: 242, -892903: 73, -892904: 239, -892905: 91, -892906: 211, -892907: 78, -892908: 191, -892909: 107, -892910: 88, -454653: 191, -892912: 22, -892913: 91, -892914: 93, -892915: 62, -892916: 121, -454654: 2, -892918: 84, -892919: 86, -892920: 250, -892921: 62, -892922: 113, -454655: 127, -892924: 57, -892925: 62, -892926: 246, -892927: 61, -892928: 0, -454656: 1, -892930: 26, -892931: 95, -892932: 127, -892933: 111, -892934: 248, -454657: 21, -892936: 247, -892937: 107, -892938: 89, -892939: 103, -892940: 223, -454658: 0, -892942: 155, -892943: 111, -892944: 122, -892945: 107, -892946: 30, -892947: 95, -892948: 60, -892949: 115, -892950: 25, -892951: 107, -892952: 124, -892953: 95, -892954: 56, -892955: 99, -892956: 28, -892957: 95, -892958: 250, -892959: 94, -892960: 0, -892961: 56, -892962: 206, -892963: 0, -892964: 31, -892965: 66, -892966: 5, -892967: 20, -892968: 224, -892969: 59, -892970: 168, -892971: 33, -892972: 159, -892973: 87, -892974: 210, -892975: 74, -892976: 78, -892977: 58, -892978: 187, -892979: 0, -892980: 20, -892981: 89, -892982: 170, -892983: 48, -892984: 22, -892985: 2, -892986: 4, -892987: 17, -892988: 116, -892989: 0, -892990: 13, -892991: 0, -892992: 0, -892993: 56, -892994: 24, -454667: 59, -892996: 95, -892997: 87, -892998: 79, -892999: 41, -893000: 234, -454668: 2, -893002: 242, -893003: 54, -893004: 255, -893005: 107, -893006: 252, -454669: 251, -893008: 152, -1155153: 0, -1155154: 56, -1155155: 87, -1155156: 63, -1155157: 77, -1155158: 46, -1155159: 226, -1155160: 0, -1155161: 96, -1155162: 0, -1155163: 176, -1155164: 58, -1155165: 11, -1155166: 34, -1155167: 102, -1155168: 17, -1155169: 36, -1155170: 9, -1155171: 90, -1155172: 67, -1155173: 148, -1155174: 54, -1155175: 173, -1155176: 21, -1155177: 8, -1155178: 5, -1155179: 255, -1155180: 3, -1155181: 55, -1155182: 2, -1155183: 209, -1155184: 0, -893041: 59, -893042: 191, -893043: 2, -893044: 31, -893045: 91, -893046: 186, -893047: 50, -893048: 255, -893049: 3, -893050: 20, -893051: 19, -893052: 127, -893053: 2, -893054: 29, -893055: 2, -893056: 0, -893057: 56, -893058: 255, -893059: 43, -893060: 255, -893061: 107, -893062: 95, -893063: 63, -893064: 250, -893065: 99, -893066: 255, -893067: 75, -893068: 255, -893069: 127, -893070: 255, -893071: 115, -893072: 255, -893073: 99, -893074: 255, -893075: 43, -893076: 255, -893077: 127, -893078: 255, -454681: 216, -893080: 255, -893081: 43, -893082: 254, -893083: 59, -893084: 191, -454682: 1, -893086: 95, -893087: 43, -893088: 0, -893089: 56, -893090: 206, -454683: 152, -893092: 31, -893093: 66, -893094: 5, -893095: 20, -893096: 224, -454684: 0, -893098: 168, -893099: 33, -893100: 159, -893101: 87, -893102: 210, -454685: 14, -893104: 78, -893105: 58, -893106: 187, -893107: 0, -893108: 20, -454686: 0, -893110: 170, -893111: 48, -893112: 22, -893113: 2, -893114: 4, -893115: 17, -893116: 116, -893117: 0, -893118: 13, -893119: 0, -893120: 0, -893121: 56, -893122: 14, -893123: 2, -893124: 95, -893125: 67, -893126: 69, -893127: 21, -893128: 224, -893129: 67, -893130: 232, -893131: 34, -893132: 255, -893133: 87, -893134: 242, -893135: 75, -893136: 142, -893137: 59, -893138: 251, -893139: 1, -893140: 84, -893141: 90, -893142: 234, -893143: 49, -893144: 86, -893145: 3, -893146: 68, -893147: 18, -893148: 180, -893149: 1, -893150: 77, -893151: 1, -893152: 0, -893153: 56, -893154: 78, -893155: 3, -893156: 255, -893157: 67, -893158: 133, -893159: 22, -893160: 224, -893161: 79, -893162: 232, -454695: 84, -893164: 255, -893165: 87, -893166: 242, -893167: 75, -893168: 238, -454696: 1, -893170: 59, -893171: 3, -893172: 148, -893173: 91, -893174: 42, -454697: 85, -893176: 246, -893177: 3, -893178: 132, -893179: 19, -893180: 244, -454698: 0, -893182: 141, -893183: 2, -893184: 0, -893185: 56, -893186: 238, -454699: 11, -893188: 255, -893189: 107, -893190: 197, -893191: 63, -893192: 224, -454700: 0, -893194: 232, -893195: 75, -893196: 255, -893197: 127, -893198: 242, -893199: 115, -893200: 238, -893201: 99, -893202: 251, -893203: 43, -893204: 244, -893205: 127, -893206: 234, -893207: 91, -893208: 246, -893209: 43, -893210: 228, -893211: 59, -893212: 244, -893213: 43, -893214: 237, -893215: 43, -454709: 208, -454710: 0, -454711: 16, -454712: 0, -454713: 7, -454714: 0, -454723: 170, -454724: 0, -454725: 11, -454726: 0, -454727: 4, -454728: 0, -454740: 208, -454741: 0, -454742: 16, -454743: 0, -454744: 7, -454745: 0, -1503330: 33, -454755: 1, -454756: 85, -454757: 0, -1503334: 24, -454759: 0, -454768: 216, -454769: 1, -454770: 152, -454771: 0, -454772: 14, -454773: 0, -454782: 59, -454783: 2, -454784: 251, -454785: 0, -454786: 17, -454787: 0, -1500615: 64, -1500616: 168, -1500617: 56, -1500618: 100, -891771: 97, -891772: 20, -891773: 81, -891774: 173, -891775: 80, -1500619: 48, -1153920: 46, -891777: 0, -891778: 174, -891779: 82, -891780: 189, -1500620: 181, -891781: 95, -891782: 229, -891783: 101, -891784: 224, -891785: 127, -1500621: 126, -891786: 136, -891787: 115, -891788: 255, -891789: 127, -891790: 242, -1500622: 0, -891791: 127, -891792: 238, -891793: 127, -891794: 155, -891795: 86, -1500623: 40, -891796: 85, -891797: 95, -891798: 11, -891799: 94, -891800: 246, -1500624: 75, -891801: 83, -891802: 228, -891803: 98, -891804: 84, -891805: 82, -1500625: 24, -1153950: 127, -891807: 81, -891808: 0, -891809: 0, -891810: 8, -1500626: 72, -891811: 1, -891812: 189, -891813: 3, -891814: 5, -891815: 20, -1500627: 24, -891816: 224, -891817: 59, -891818: 168, -891819: 33, -891820: 159, -1500628: 37, -891821: 87, -891822: 210, -891823: 74, -891824: 78, -891825: 58, -1500629: 20, -891826: 187, -891827: 0, -891828: 181, -891829: 2, -891830: 107, -1500630: 34, -891831: 1, -891832: 82, -891833: 2, -891834: 4, -1500637: 36, -1156901: 0, -1156902: 56, -1156903: 183, -1156904: 63, -1156905: 173, -1156906: 46, -1156907: 66, -1156908: 1, -1156909: 96, -1156910: 0, -1156911: 16, -1156912: 59, -1156913: 107, -1156914: 34, -1156915: 198, -1156916: 17, -1156917: 132, -1156918: 9, -1156919: 255, -1156920: 114, -1156921: 223, -1156922: 44, -1156923: 185, -1156924: 36, -1156925: 175, -1156926: 28, -1156927: 157, -1156928: 42, -1156929: 214, -1156930: 25, -1156931: 16, -1156932: 13, -1500639: 28, -1500640: 235, -1500641: 40, -1500642: 169, -1500643: 36, -1503569: 159, -1500644: 135, -1500645: 32, -1500646: 100, -1500647: 28, -1500648: 66, -1500649: 24, -1503599: 223, -1500650: 107, -1500651: 65, -1500652: 0, -1500653: 20, -1500654: 154, -1500655: 44, -1503629: 31, -1500656: 116, -1500657: 44, -1500658: 78, -1500659: 40, -1500660: 40, -1500661: 40, -1503659: 63, -1500662: 54, -1500663: 98, -1500664: 178, -1157704: 0, -1157705: 56, -1157706: 255, -1157707: 87, -1157708: 247, -1157709: 66, -1157710: 74, -1157711: 13, -1157712: 99, -1157713: 0, -1157714: 90, -1157715: 79, -1157716: 181, -1157717: 54, -1157718: 16, -1157719: 38, -1157720: 206, -1157721: 29, -1157722: 218, -1157723: 78, -1157724: 53, -1157725: 58, -1157726: 144, -1157727: 41, -1157728: 235, -1157729: 20, -1157730: 224, -1500665: 85, -1157732: 160, -1157733: 50, -1157734: 64, -1157735: 25, -1500667: 73, -1288880: 246, -1288881: 13, -1288882: 146, -1288883: 13, -1288884: 236, -1288885: 12, -1288886: 169, -1288887: 12, -453185: 87, -1500670: 186, -453186: 212, -1500671: 77, -453187: 74, -1500672: 86, -453188: 80, -1500673: 69, -1503719: 191, -453189: 58, -1500674: 18, -453190: 188, -1500675: 65, -1500676: 205, -1500677: 56, -1500678: 105, -1500679: 48, -1503749: 255, -1500680: 186, -1500681: 126, -1500682: 5, -1500683: 40, -1500684: 77, -1500685: 24, -1500686: 74, -1500687: 24, -1500688: 39, -1500689: 20, -1500690: 36, -1500691: 20, -1500694: 233, -1500696: 167, -1500697: 36, -1500698: 69, -1500699: 28, -1500700: 237, -1500701: 40, -1159045: 0, -1159046: 56, -1159047: 250, -1159048: 114, -1159049: 176, -1159050: 85, -1159051: 69, -1159052: 40, -1159053: 1, -1159054: 24, -1159055: 16, -1159056: 98, -1159057: 107, -1159058: 73, -1159059: 198, -1159060: 56, -1159061: 99, -1159062: 44, -1159063: 31, -1159064: 36, -1159065: 23, -1159066: 28, -1159067: 47, -1159068: 20, -1159069: 71, -1159070: 12, -1159071: 224, -1159072: 3, -1159073: 160, -1159074: 2, -1159075: 64, -1159076: 1, -1159301: 0, -1159302: 56, -1159303: 255, -1159304: 87, -1159305: 247, -1159306: 66, -1159307: 74, -1159308: 13, -1159309: 99, -1159310: 0, -1159311: 90, -1159312: 79, -1159313: 181, -1159314: 54, -1159315: 16, -1159316: 38, -1159317: 206, -1159318: 29, -1159319: 218, -1159320: 78, -1159321: 53, -1159322: 58, -1159323: 144, -1159324: 41, -1159325: 235, -1159326: 20, -1159327: 224, -1159328: 95, -1159329: 160, -1159330: 50, -1159331: 64, -1159332: 25, -1159333: 0, -1159334: 56, -1159335: 255, -1159336: 127, -1159337: 224, -1159338: 86, -1159339: 128, -1159340: 49, -1159341: 192, -1159342: 24, -1159343: 192, -1159344: 107, -1159345: 192, -1159346: 94, -1159347: 32, -1159348: 74, -1159349: 160, -1159350: 53, -1159351: 255, -1159352: 127, -1159353: 156, -1159354: 3, -1159355: 55, -1159356: 2, -1159357: 209, -1159358: 0, -1159359: 255, -1159360: 3, -1159361: 55, -1159362: 2, -1159363: 209, -1159364: 0, -892311: 117, -892317: 82, -1159703: 0, -1159704: 56, -1159705: 250, -1159706: 114, -1159707: 176, -1159708: 85, -1159709: 69, -1159710: 40, -1159711: 1, -1159712: 24, -1159713: 16, -1159714: 98, -1159715: 107, -1159716: 73, -1159717: 198, -1159718: 56, -1159719: 99, -1159720: 44, -1159721: 31, -1159722: 36, -1159723: 23, -1159724: 28, -1159725: 47, -1159726: 20, -1159727: 71, -1159728: 12, -1159729: 224, -1159730: 3, -1159731: 160, -1159732: 2, -1159733: 64, -1159734: 1, -1500740: 191, -1160097: 0, -1160098: 56, -1160099: 250, -1160100: 114, -1160101: 176, -1160102: 85, -1160103: 69, -1160104: 40, -1160105: 1, -1160106: 24, -1160107: 16, -1160108: 98, -1160109: 107, -1160110: 73, -1160111: 198, -1160112: 56, -1160113: 99, -1160114: 44, -1160115: 121, -1160116: 29, -1160117: 51, -1160118: 25, -1160119: 14, -1160120: 21, -1160121: 200, -1160122: 16, -1160123: 224, -1160124: 59, -1160125: 128, -1160126: 38, -1160127: 128, -1160128: 21, -892407: 62, -1291251: 0, -1291252: 0, -1291253: 157, -1291254: 85, -1291255: 22, -1291256: 24, -1291257: 13, -1291258: 16, -1291259: 122, -1291260: 18, -1291261: 23, -1291262: 14, -1291263: 211, -1291264: 13, -1291265: 112, -1291266: 9, -1291267: 45, -1291268: 9, -1291269: 202, -1291270: 4, -1291271: 134, -1291272: 4, -1291273: 35, -1291274: 0, -1291275: 67, -1291276: 4, -1291277: 82, -1291278: 62, -1291279: 213, -1291280: 74, -1291281: 0, -1291282: 0, -1291283: 0, -1291284: 56, -1291285: 157, -1291286: 85, -1291287: 22, -1291288: 24, -1291289: 13, -1291290: 16, -1291291: 155, -1291292: 26, -1291293: 55, -1291294: 22, -1291295: 243, -1291296: 17, -1291297: 143, -1291298: 13, -1291299: 76, -1291300: 13, -1291301: 233, -1291302: 8, -1291303: 166, -1291304: 4, -1291305: 67, -1291306: 0, -1291307: 67, -1291308: 4, -1291309: 115, -1291310: 66, -1291311: 246, -1291312: 82, -1291313: 0, -1291314: 0, -1291315: 0, -1291316: 56, -1291317: 157, -1291318: 85, -1291319: 22, -1291320: 24, -1291321: 13, -1291322: 16, -1291323: 219, -1291324: 34, -1291325: 119, -1291326: 26, -1291327: 18, -1291328: 26, -1291329: 174, -1291330: 21, -1291331: 108, -1291332: 17, -1291333: 9, -1291334: 13, -1291335: 166, -1291336: 8, -1291337: 68, -1291338: 4, -1291339: 35, -1291340: 4, -1291341: 148, -1291342: 74, -1291343: 56, -1291344: 91, -1291345: 0, -1291346: 0, -1291347: 0, -1291348: 56, -1291349: 157, -1291350: 85, -1291351: 22, -1291352: 24, -1291353: 13, -1291354: 16, -1291355: 252, -1291356: 42, -1291357: 151, -1291358: 34, -1291359: 50, -1291360: 30, -1291361: 205, -1291362: 25, -1291363: 139, -1291364: 21, -1291365: 40, -1291366: 17, -1291367: 198, -1291368: 8, -1291369: 100, -1291370: 4, -1291371: 35, -1291372: 4, -1291373: 181, -1291374: 78, -1291375: 89, -1291376: 99, -1291377: 0, -1291378: 0, -1291379: 0, -1291380: 56, -1291381: 157, -1291382: 85, -1291383: 22, -1291384: 24, -1291385: 13, -1291386: 16, -1291387: 29, -1291388: 51, -1291389: 183, -1291390: 42, -1291391: 145, -1291392: 42, -1291393: 12, -1291394: 30, -1291395: 170, -1291396: 25, -1291397: 72, -1291398: 17, -1291399: 229, -1291400: 12, -1291401: 132, -1291402: 4, -1291403: 35, -1291404: 0, -1291405: 181, -1291406: 82, -1291407: 123, -1291408: 103, -1291409: 0, -1291410: 0, -1291411: 0, -1291412: 56, -1291413: 157, -1291414: 85, -1291415: 22, -1291416: 24, -1291417: 13, -1291418: 16, -1291419: 62, -1291420: 59, -1291421: 215, -1291422: 50, -1291423: 176, -1291424: 50, -1291425: 43, -1291426: 34, -1291427: 201, -1291428: 29, -1291429: 103, -1291430: 21, -1291431: 5, -1291432: 13, -1291433: 164, -1291434: 4, -1291435: 35, -1291436: 0, -1291437: 214, -1291438: 86, -1291439: 156, -1291440: 111, -1291441: 0, -1291442: 0, -1291443: 0, -1291444: 56, -1291445: 157, -1291446: 85, -1291447: 22, -1291448: 24, -1291449: 13, -1291450: 16, -1291451: 126, -1291452: 67, -1291453: 23, -1291454: 55, -1291455: 176, -1291456: 50, -1291457: 74, -1291458: 42, -1291459: 233, -1291460: 33, -1291461: 135, -1291462: 25, -1291463: 5, -1291464: 17, -1291465: 165, -1291466: 8, -1291467: 3, -1291468: 0, -1291469: 247, -1291470: 94, -1291471: 222, -1291472: 119, -1291473: 0, -1291474: 0, -1291475: 0, -1291476: 56, -1291477: 157, -1291478: 85, -1291479: 22, -1291480: 24, -1291481: 13, -1291482: 16, -1291483: 159, -1291484: 75, -1291485: 55, -1291486: 63, -1291487: 208, -1291488: 54, -1291489: 105, -1291490: 46, -1291491: 8, -1291492: 38, -1291493: 166, -1291494: 29, -1291495: 37, -1291496: 17, -1291497: 197, -1291498: 8, -1291499: 3, -1291500: 0, -1291501: 24, -1291502: 99, -1291503: 255, -1291504: 127, -1291505: 0, -1291506: 0, -1291507: 0, -1291508: 56, -1291509: 7, -1291510: 8, -1291511: 4, -1291512: 4, -1291513: 0, -1291514: 0, -1291515: 122, -1291516: 18, -1291517: 23, -1291518: 14, -1291519: 211, -1291520: 13, -1291521: 112, -1291522: 9, -1291523: 45, -1291524: 9, -1291525: 202, -1291526: 4, -1291527: 134, -1291528: 4, -1291529: 35, -1291530: 0, -1291531: 67, -1291532: 4, -1291533: 82, -1291534: 62, -1291535: 213, -1291536: 74, -1291537: 0, -1291538: 0, -1291571: 0, -1291572: 0, -1291573: 157, -1291574: 85, -1291575: 22, -1291576: 24, -1291577: 13, -1291578: 16, -1291579: 122, -1291580: 18, -1291581: 23, -1291582: 14, -1291583: 211, -1291584: 13, -1291585: 112, -1291586: 9, -1291587: 45, -1291588: 9, -1291589: 202, -1291590: 4, -1291591: 134, -1291592: 4, -1291593: 35, -1291594: 0, -1291595: 67, -1291596: 4, -1291597: 82, -1291598: 62, -1291599: 213, -1291600: 74, -1291601: 0, -1291602: 0, -1291603: 0, -1291604: 56, -1291605: 157, -1291606: 85, -1291607: 22, -1291608: 24, -1291609: 13, -1291610: 16, -1291611: 155, -1291612: 26, -1291613: 55, -1291614: 22, -1291615: 243, -1291616: 17, -1291617: 143, -1291618: 13, -1291619: 76, -1291620: 13, -1291621: 233, -1291622: 8, -1291623: 166, -1291624: 4, -1291625: 67, -1291626: 0, -1291627: 67, -1291628: 4, -1291629: 115, -1291630: 66, -1291631: 246, -1291632: 82, -1291633: 0, -1291634: 0, -1291635: 0, -1291636: 56, -1291637: 157, -1291638: 85, -1291639: 22, -1291640: 24, -1291641: 13, -1291642: 16, -1291643: 219, -1291644: 34, -1291645: 119, -1291646: 26, -1291647: 18, -1291648: 26, -1291649: 174, -1291650: 21, -1291651: 108, -1291652: 17, -1291653: 9, -1291654: 13, -1291655: 166, -1291656: 8, -1291657: 68, -1291658: 4, -1291659: 35, -1291660: 4, -1291661: 148, -1291662: 74, -1291663: 56, -1291664: 91, -1291665: 0, -1291666: 0, -1291667: 0, -1291668: 56, -1291669: 157, -1291670: 85, -1291671: 22, -1291672: 24, -1291673: 13, -1291674: 16, -1291675: 252, -1291676: 42, -1291677: 151, -1291678: 34, -1291679: 50, -1291680: 30, -1291681: 205, -1291682: 25, -1291683: 139, -1291684: 21, -1291685: 40, -1291686: 17, -1291687: 198, -1291688: 8, -1291689: 100, -1291690: 4, -1291691: 35, -1291692: 4, -1291693: 181, -1291694: 78, -1291695: 89, -1291696: 99, -1291697: 0, -1291698: 0, -1160627: 0, -1160628: 56, -1160629: 255, -1160630: 127, -1160631: 224, -1160632: 86, -1160633: 128, -1160634: 49, -1160635: 192, -1160636: 24, -1160637: 192, -1160638: 107, -1160639: 192, -1160640: 94, -1160641: 32, -1160642: 74, -1160643: 160, -1160644: 53, -1160645: 31, -1291718: 17, -1160647: 23, -1160648: 28, -1160649: 47, -1291722: 4, -1291723: 35, -1160652: 12, -1291725: 181, -1291726: 82, -1291727: 123, -1291728: 103, -1160657: 64, -1291730: 0, -1291731: 0, -1291732: 56, -1291733: 157, -1291734: 85, -1291735: 22, -1291736: 24, -1291737: 13, -1291738: 16, -1291739: 62, -1291740: 59, -1291741: 215, -1291742: 50, -1291743: 176, -1291744: 50, -1291745: 43, -1291746: 34, -1291747: 201, -1291748: 29, -1291749: 103, -1291750: 21, -1291751: 5, -1291752: 13, -1291753: 164, -1291754: 4, -1291755: 35, -1291756: 0, -1291757: 214, -1291758: 86, -1291759: 156, -1291760: 111, -1291761: 0, -1291762: 0, -1291763: 0, -1291764: 56, -1291765: 157, -1291766: 85, -1291767: 22, -1291768: 24, -1291769: 13, -1291770: 16, -1291771: 126, -1291772: 67, -1291773: 23, -1291774: 55, -1291775: 176, -1291776: 50, -1291777: 74, -1291778: 42, -1291779: 233, -1291780: 33, -1291781: 135, -1291782: 25, -1291783: 5, -1291784: 17, -1291785: 165, -1291786: 8, -1291787: 3, -1291788: 0, -1291789: 247, -1291790: 94, -1291791: 222, -1291792: 119, -1291793: 0, -1291794: 0, -1291795: 0, -1291796: 56, -1291797: 157, -1291798: 85, -1291799: 22, -1291800: 24, -1291801: 13, -1291802: 16, -1291803: 159, -1291804: 75, -1291805: 55, -1291806: 63, -1291807: 208, -1291808: 54, -1291809: 105, -1291810: 46, -1291811: 8, -1291812: 38, -1291813: 166, -1291814: 29, -1291815: 37, -1291816: 17, -1291817: 197, -1291818: 8, -1291819: 3, -1291820: 0, -1291821: 24, -1291822: 99, -1291823: 255, -1291824: 127, -1291825: 0, -1291826: 0, -892515: 2, -892521: 59, -892527: 75, -892533: 2, -892704: 224, -892707: 0, -892713: 59, -892743: 60, -892749: 127, -892755: 40, -892761: 42, -892767: 40, -892773: 126, -892779: 114, -892785: 126, -892791: 125, -892797: 81, -892803: 82, -892809: 127, -892815: 127, -892821: 126, -892827: 98, -892833: 0, -892835: 0, -892911: 99, -892917: 106, -892923: 70, -892929: 0, -892935: 98, -892941: 115, -892995: 22, -893001: 79, -893007: 95, -893009: 71, -893010: 255, -893011: 21, -893012: 94, -893013: 110, -893014: 244, -893015: 69, -893016: 95, -893017: 23, -893018: 78, -893019: 38, -893020: 190, -893021: 21, -893022: 87, -893023: 21, -893024: 0, -893025: 56, -893026: 222, -893027: 2, -893028: 255, -893029: 67, -893030: 21, -893031: 22, -893032: 240, -893033: 59, -893034: 184, -893035: 35, -893036: 255, -893037: 87, -893038: 255, -893039: 75, -893040: 254, -893079: 91, -893085: 43, -893091: 0, -893097: 59, -893103: 74, -893109: 89, -893163: 35, -893169: 59, -893175: 51, -893181: 2, -893187: 43, -893193: 99, -1164862: 0, -1164863: 56, -1164864: 87, -1164865: 63, -1164866: 77, -1164867: 46, -1164868: 226, -1164869: 0, -1164870: 96, -1164871: 0, -1164872: 176, -1164873: 58, -1164874: 11, -1164875: 34, -1164876: 102, -1164877: 17, -1164878: 36, -1164879: 9, -1164880: 255, -1164881: 127, -1164882: 156, -1164883: 3, -1164884: 55, -1164885: 2, -1164886: 209, -1164887: 0, -1164888: 191, -1164889: 97, -1164890: 182, -1164891: 56, -1164892: 72, -1164893: 20, -902791: 145, -902792: 127, -1500906: 26, -1500908: 47, -1500910: 9, -1165478: 0, -1165479: 56, -1165480: 255, -1165481: 87, -1165482: 247, -1165483: 66, -1165484: 140, -1165485: 21, -1165486: 165, -1165487: 0, -1165488: 90, -1165489: 79, -1165490: 181, -1165491: 54, -1165492: 16, -1165493: 38, -1165494: 206, -1165495: 29, -1165496: 255, -1165497: 119, -1165498: 181, -1165499: 98, -1165500: 74, -1165501: 49, -1165502: 99, -1165503: 16, -1165504: 31, -1165505: 77, -1165506: 182, -1165507: 56, -1165508: 110, -1165509: 36, -456401: 66, -456410: 13, -456411: 0, -456412: 6, -456413: 0, -456414: 0, -456415: 44, -456416: 0, -456417: 16, -456418: 132, -456419: 16, -456420: 19, -456421: 0, -456422: 115, -456423: 78, -1373936: 0, -1373937: 21, -456434: 9, -1373939: 21, -456436: 0, -456437: 56, -456438: 0, -456439: 28, -456440: 132, -456441: 16, -456442: 86, -456443: 0, -456444: 214, -456445: 90, -1296897: 0, -1296898: 56, -1296899: 255, -1296900: 127, -1296901: 192, -1296902: 126, -1296903: 224, -1296904: 109, -1296905: 224, -1296906: 84, -1296907: 0, -1296908: 0, -1296909: 0, -1296910: 0, -1296911: 0, -1296912: 0, -1296913: 0, -1296914: 0, -1296915: 0, -1296916: 0, -1296917: 0, -1296918: 0, -1296919: 0, -1296920: 0, -1296921: 0, -1296922: 0, -1296923: 0, -1296924: 0, -1296925: 0, -1296926: 0, -1296927: 0, -1296928: 0, -456454: 19, -456455: 0, -456456: 12, -456457: 0, -456458: 0, -456459: 68, -456460: 0, -456461: 40, -456462: 132, -456463: 16, -1296993: 0, -1296994: 0, -1296995: 223, -1296996: 2, -1296997: 215, -1296998: 1, -1296999: 172, -1297000: 0, -1297001: 187, -1297002: 94, -1297003: 179, -1297004: 61, -1297005: 46, -1297006: 41, -1297007: 134, -1297008: 20, -1297009: 177, -1297010: 11, -1297011: 251, -1297012: 72, -1297013: 255, -1297014: 127, -1297015: 0, -1297016: 0, -1297017: 255, -1297018: 127, -1297019: 229, -1297020: 68, -1297021: 255, -1297022: 127, -1297023: 0, -1297024: 0, -1297025: 3, -1297026: 32, -1297027: 177, -1297028: 11, -1297029: 169, -1297030: 30, -1297031: 69, -1297032: 1, -1297033: 187, -1297034: 94, -1297035: 179, -1297036: 61, -1297037: 46, -1297038: 41, -1297039: 134, -1297040: 20, -1297041: 24, -1297042: 99, -1297043: 231, -1297044: 28, -1297045: 132, -1297046: 16, -1297047: 0, -1297048: 0, -1297049: 255, -1297050: 127, -1297051: 223, -1297052: 2, -1297053: 31, -1297054: 0, -1297055: 0, -1297056: 0, -1297057: 3, -1297058: 32, -1297059: 188, -1297060: 114, -1297061: 251, -1297062: 72, -1297063: 22, -1297064: 24, -1297065: 24, -1297066: 99, -1297067: 24, -1297068: 99, -1297069: 24, -1297070: 99, -1297071: 24, -1297072: 99, -1297073: 24, -1297074: 99, -1297075: 24, -1297076: 99, -1297077: 24, -1297078: 99, -1297079: 24, -1297080: 99, -1297081: 24, -1297082: 99, -1297083: 24, -1297084: 99, -1297085: 255, -1297086: 127, -1297087: 0, -1297088: 0, -1297089: 0, -1297090: 0, -1297091: 178, -1297092: 114, -1297093: 199, -1297094: 113, -1297095: 3, -1297096: 77, -1297097: 24, -1297098: 99, -1297099: 24, -1297100: 99, -1297101: 24, -1297102: 99, -1297103: 24, -1297104: 99, -1297105: 24, -1297106: 99, -1297107: 24, -1297108: 99, -1297109: 24, -1297110: 99, -1297111: 24, -1297112: 99, -1297113: 24, -1297114: 99, -1297115: 24, -1297116: 99, -1297117: 255, -1297118: 127, -1297119: 0, -1297120: 0, -1297121: 0, -1297122: 0, -1297123: 244, -1297124: 62, -1297125: 46, -1297126: 38, -1297127: 104, -1297128: 13, -1297129: 148, -1297130: 62, -1297131: 206, -1297132: 37, -1297133: 8, -1297134: 13, -1297135: 132, -1297136: 20, -1297137: 148, -1297138: 110, -1297139: 206, -1297140: 85, -1297141: 8, -1297142: 61, -1297143: 132, -1297144: 44, -1297145: 169, -1297146: 30, -1297147: 177, -1297148: 11, -1297149: 255, -1297150: 127, -1297151: 0, -1297152: 0, -1297153: 0, -1297154: 0, -1297155: 70, -1297156: 18, -1297157: 69, -1297158: 1, -1297159: 192, -1297160: 0, -1297161: 82, -1297162: 54, -1297163: 140, -1297164: 29, -1297165: 198, -1297166: 4, -1297167: 132, -1297168: 4, -1297169: 49, -1297170: 98, -1297171: 107, -1297172: 73, -1297173: 165, -1297174: 48, -1297175: 33, -1297176: 32, -1297177: 21, -1297178: 0, -1297179: 91, -1297180: 2, -1297181: 255, -1297182: 127, -1297183: 0, -1297184: 0, -1297185: 0, -1297186: 0, -1297187: 24, -1297188: 99, -1297189: 24, -1297190: 99, -1297191: 24, -1297192: 99, -1297193: 24, -1297194: 99, -1297195: 24, -1297196: 99, -1297197: 24, -1297198: 99, -1297199: 24, -1297200: 99, -1297201: 24, -1297202: 99, -1297203: 24, -1297204: 99, -1297205: 24, -1297206: 99, -1297207: 24, -1297208: 99, -1297209: 24, -1297210: 99, -1297211: 24, -1297212: 99, -1297213: 255, -1297214: 127, -1297215: 0, -1297216: 0, -1297217: 14, -1297218: 0, -1297219: 220, -1297220: 37, -1297221: 56, -1297222: 21, -1297223: 113, -1297224: 0, -1297225: 48, -1297226: 0, -1297227: 121, -1297228: 29, -1297229: 23, -1297230: 17, -1297231: 180, -1297232: 8, -1297233: 146, -1297234: 0, -1297235: 31, -1297236: 66, -1297237: 121, -1297238: 29, -1297239: 245, -1297240: 12, -1297241: 147, -1297242: 4, -1297243: 29, -1297244: 28, -1297245: 25, -1297246: 12, -1297247: 19, -1297248: 0, -1297249: 12, -1297250: 0, -1297251: 28, -1297252: 42, -1297253: 87, -1297254: 25, -1297255: 112, -1297256: 0, -1297257: 46, -1297258: 0, -1297259: 153, -1297260: 33, -1297261: 54, -1297262: 17, -1297263: 211, -1297264: 8, -1297265: 145, -1297266: 0, -1297267: 95, -1297268: 74, -1297269: 153, -1297270: 29, -1297271: 244, -1297272: 12, -1297273: 177, -1297274: 4, -1297275: 29, -1297276: 32, -1297277: 24, -1297278: 12, -1297279: 18, -1297280: 0, -1297281: 10, -1297282: 0, -1297283: 92, -1297284: 46, -1297285: 150, -1297286: 29, -1297287: 142, -1297288: 0, -1297289: 76, -1297290: 0, -1297291: 216, -1297292: 37, -1297293: 85, -1297294: 21, -1297295: 241, -1297296: 8, -1297297: 175, -1297298: 0, -1297299: 159, -1297300: 82, -1297301: 216, -1297302: 33, -1297303: 19, -1297304: 17, -1297305: 208, -1297306: 4, -1297307: 29, -1297308: 36, -1297309: 23, -1297310: 16, -1297311: 17, -1297312: 0, -1297313: 8, -1297314: 0, -1297315: 124, -1297316: 50, -1297317: 181, -1297318: 33, -1297319: 140, -1297320: 0, -1297321: 74, -1297322: 0, -1297323: 247, -1297324: 41, -1297325: 116, -1297326: 21, -1297327: 16, -1297328: 13, -1297329: 174, -1297330: 0, -1297331: 223, -1297332: 90, -1297333: 247, -1297334: 37, -1297335: 49, -1297336: 17, -1297337: 206, -1297338: 4, -1297339: 29, -1297340: 40, -1297341: 22, -1297342: 16, -1297343: 15, -1297344: 0, -1297345: 6, -1297346: 0, -1297347: 187, -1297348: 54, -1297349: 212, -1297350: 33, -1297351: 139, -1297352: 0, -1297353: 72, -1297354: 0, -1297355: 23, -1297356: 46, -1297357: 147, -1297358: 25, -1297359: 15, -1297360: 13, -1297361: 204, -1297362: 0, -1297363: 31, -1297364: 99, -1297365: 23, -1297366: 42, -1297367: 80, -1297368: 17, -1297369: 237, -1297370: 4, -1297371: 29, -1297372: 44, -1297373: 22, -1297374: 16, -1297375: 14, -1297376: 0, -1297377: 4, -1297378: 0, -1297379: 251, -1297380: 58, -1297381: 243, -1297382: 37, -1297383: 169, -1297384: 0, -1297385: 70, -1297386: 0, -1297387: 86, -1297388: 50, -1297389: 178, -1297390: 29, -1297391: 45, -1297392: 13, -1297393: 235, -1297394: 0, -1297395: 95, -1297396: 107, -1297397: 86, -1297398: 46, -1297399: 111, -1297400: 21, -1297401: 235, -1297402: 4, -1297403: 29, -1297404: 48, -1297405: 21, -1297406: 20, -1297407: 12, -1297408: 0, -1297409: 2, -1297410: 0, -1297411: 59, -1297412: 63, -1297413: 18, -1297414: 42, -1297415: 167, -1297416: 0, -1297417: 68, -1297418: 0, -1297419: 117, -1297420: 54, -1297421: 241, -1297422: 29, -1297423: 76, -1297424: 13, -1297425: 233, -1297426: 4, -1297427: 191, -1297428: 119, -1297429: 117, -1297430: 50, -1297431: 142, -1297432: 21, -1297433: 10, -1297434: 5, -1297435: 29, -1297436: 52, -1297437: 20, -1297438: 20, -1297439: 11, -1297440: 0, -1297441: 0, -1297442: 0, -1297443: 123, -1297444: 71, -1297445: 82, -1297446: 46, -1297447: 198, -1297448: 0, -1297449: 99, -1297450: 0, -1297451: 181, -1297452: 58, -1297453: 16, -1297454: 34, -1297455: 107, -1297456: 17, -1297457: 8, -1297458: 5, -1297459: 255, -1297460: 127, -1297461: 181, -1297462: 54, -1297463: 173, -1297464: 25, -1297465: 41, -1297466: 9, -1297467: 29, -1297468: 56, -1297469: 20, -1297470: 24, -1297471: 10, -1297472: 0, -456934: 8, -456939: 229, -456940: 32, -456941: 164, -456942: 24, -456943: 131, -456944: 16, -456945: 65, -456946: 8, -456951: 200, -456952: 28, -456953: 134, -456954: 20, -456955: 132, -456956: 16, -456957: 65, -1374462: 18, -456963: 171, -456964: 24, -456965: 136, -1501090: 49, -1501092: 8, -1501093: 0, -1501094: 14, -1171362: 0, -1171363: 56, -1171364: 90, -1171365: 127, -1171366: 224, -1171367: 59, -1171368: 128, -1171369: 38, -1171370: 32, -1171371: 9, -1171372: 90, -1171373: 79, -1171374: 181, -1171375: 54, -1171376: 16, -1171377: 38, -1171378: 206, -1171379: 29, -1171380: 148, -1171381: 82, -1171382: 206, -1171383: 57, -1171384: 8, -1171385: 33, -1171386: 132, -1171387: 16, -1171388: 59, -1171389: 3, -1171390: 22, -1171391: 2, -1171392: 19, -1171393: 1, -1172028: 0, -1172029: 56, -1172030: 90, -1172031: 63, -1172032: 80, -1172033: 46, -1172034: 229, -1172035: 0, -1172036: 99, -1172037: 0, -1172038: 179, -1172039: 58, -1172040: 14, -1172041: 34, -1172042: 105, -1172043: 17, -1172044: 39, -1172045: 9, -1172046: 255, -1172047: 3, -1172048: 247, -1172049: 2, -1172050: 16, -1172051: 2, -1172052: 8, -1172053: 1, -1172054: 255, -1172055: 127, -1172056: 153, -1172057: 2, -1172058: 112, -1172059: 1, -1697061: 0, -1697062: 56, -1697063: 151, -1697064: 95, -1697065: 242, -1697066: 86, -1697067: 135, -1697068: 41, -1697069: 160, -1697070: 0, -1697071: 85, -1697072: 99, -1697073: 176, -1697074: 74, -1697075: 11, -1697076: 58, -1697077: 201, -1697078: 49, -1697079: 255, -1697080: 87, -1697081: 247, -1697082: 66, -1697083: 16, -1697084: 38, -1697085: 140, -1697086: 21, -1697087: 255, -1697088: 3, -1697089: 121, -1697090: 2, -1697091: 41, -1697092: 0, -1172860: 0, -1172861: 56, -1172862: 255, -1172863: 2, -1172864: 191, -1172865: 1, -1172866: 15, -1172867: 0, -1172868: 8, -1172869: 0, -1172870: 191, -1172871: 1, -1172872: 27, -1172873: 1, -1172874: 186, -1172875: 0, -1172876: 17, -1172877: 0, -1172878: 255, -1172879: 127, -1172880: 156, -1172881: 3, -1172882: 55, -1172883: 2, -1172884: 209, -1172885: 0, -1172886: 224, -1172887: 59, -1172888: 128, -1172889: 38, -1172890: 128, -1172891: 21, -1172912: 0, -1172913: 56, -1172914: 250, -1172915: 114, -1172916: 176, -1172917: 85, -1172918: 69, -1172919: 40, -1172920: 1, -1172921: 24, -1172922: 16, -1172923: 98, -1172924: 107, -1172925: 73, -1172926: 198, -1172927: 56, -1172928: 99, -1172929: 44, -1172930: 224, -1172931: 127, -1172932: 160, -1172933: 125, -1172934: 224, -1172935: 72, -1172936: 160, -1172937: 48, -1172938: 255, -1172939: 3, -1172940: 55, -1172941: 2, -1172942: 209, -1172943: 0, -1172944: 0, -1172945: 56, -1172946: 255, -1172947: 127, -1172948: 211, -1172949: 78, -1172950: 38, -1172951: 25, -1172952: 129, -1172953: 4, -1172954: 87, -1172955: 95, -1172956: 145, -1172957: 70, -1172958: 13, -1172959: 54, -1172960: 203, -1172961: 45, -1172962: 186, -1172963: 107, -1172964: 178, -1172965: 86, -1172966: 71, -1172967: 41, -1172968: 195, -1172969: 24, -1172970: 255, -1172971: 127, -1172972: 211, -1172973: 78, -1172974: 38, -1172975: 25, -452117: 1, -456482: 0, -456483: 52, -452119: 2, -456484: 132, -1304574: 0, -1304575: 56, -1304576: 151, -1304577: 95, -1304578: 242, -1304579: 86, -1304580: 135, -1304581: 41, -1304582: 160, -1304583: 0, -1304584: 85, -1304585: 99, -1304586: 176, -1304587: 74, -1304588: 11, -1304589: 58, -1304590: 201, -1304591: 49, -1304592: 255, -1304593: 87, -1304594: 247, -1304595: 66, -1304596: 16, -1304597: 38, -1304598: 140, -1304599: 21, -1304600: 255, -1304601: 3, -1304602: 121, -1304603: 2, -1304604: 41, -1304605: 0, -456485: 16, -456486: 28, -1698116: 0, -1698117: 56, -1698118: 87, -1698119: 63, -1698120: 77, -1698121: 46, -1698122: 226, -1698123: 0, -1698124: 96, -1698125: 0, -1698126: 176, -1698127: 58, -1698128: 11, -1698129: 34, -1698130: 102, -1698131: 17, -1698132: 36, -1698133: 9, -1698134: 255, -1698135: 87, -1698136: 247, -1698137: 66, -1698138: 16, -1698139: 38, -1698140: 140, -1698141: 21, -1698142: 31, -1698143: 124, -1698144: 24, -1698145: 96, -1698146: 10, -1698147: 48, -1173935: 0, -1173936: 56, -1173937: 245, -1173938: 107, -1173939: 225, -1173940: 6, -1173941: 65, -1173942: 6, -1173943: 161, -1173944: 5, -1173945: 95, -1173946: 94, -1173947: 63, -1173948: 24, -1173949: 20, -1173950: 16, -1173951: 10, -1173952: 8, -1173953: 4, -1173954: 4, -1173955: 159, -1173956: 79, -1173957: 216, -1173958: 62, -1173959: 18, -1173960: 46, -1173961: 112, -1173962: 111, -1173963: 255, -1173964: 127, -1173965: 224, -1173966: 94, -456488: 156, -456489: 115, -3141200: 255, -3141201: 255, -3141202: 255, -3141203: 255, -3141204: 255, -3141205: 255, -3141206: 255, -3141207: 255, -3141208: 255, -3141209: 255, -3141210: 255, -3141211: 255, -3141212: 255, -3141213: 255, -3141214: 255, -3141215: 255, -3141216: 255, -3141217: 255, -3141218: 255, -3141219: 255, -3141220: 255, -3141221: 255, -3141222: 255, -3141223: 255, -3141224: 255, -3141225: 255, -3141226: 255, -3141227: 255, -3141228: 255, -3141229: 255, -3141230: 255, -3141231: 255, -3141232: 255, -3141233: 255, -3141234: 255, -3141235: 255, -3141236: 255, -3141237: 255, -3141238: 255, -3141239: 255, -3141240: 255, -3141241: 255, -3141242: 255, -3141243: 255, -3141244: 255, -3141245: 255, -3141246: 255, -3141247: 255, -3141248: 255, -3141249: 255, -3141250: 255, -3141251: 255, -3141252: 255, -3141253: 255, -3141254: 255, -3141255: 255, -3141256: 255, -3141257: 255, -3141258: 255, -3141259: 255, -3141260: 255, -3141261: 255, -3141262: 255, -3141263: 255, -3141264: 255, -3141265: 255, -3141266: 255, -3141267: 255, -3141268: 255, -3141269: 255, -3141270: 255, -3141271: 255, -3141272: 255, -3141273: 255, -3141274: 255, -3141275: 255, -3141276: 255, -3141277: 255, -3141278: 255, -3141279: 255, -3141280: 255, -3141281: 255, -3141282: 255, -3141283: 255, -3141284: 255, -3141285: 255, -3141286: 255, -3141287: 255, -3141288: 255, -3141289: 255, -3141290: 255, -3141291: 255, -3141292: 255, -3141293: 255, -3141294: 255, -3141295: 255, -3141296: 255, -3141297: 255, -3141298: 255, -3141299: 255, -3141300: 255, -3141301: 255, -3141302: 255, -3141303: 255, -3141304: 255, -3141305: 255, -3141306: 255, -3141307: 255, -3141308: 255, -3141309: 255, -3141310: 255, -3141311: 255, -3141312: 255, -3141313: 255, -3141314: 255, -3141315: 255, -3141316: 255, -3141317: 255, -3141318: 255, -3141319: 255, -3141320: 255, -3141321: 255, -3141322: 255, -3141323: 255, -3141324: 255, -3141325: 255, -3141326: 255, -3141327: 255, -3141328: 255, -3141329: 255, -3141330: 255, -3141331: 255, -3141332: 255, -3141333: 255, -3141334: 255, -3141335: 255, -3141336: 255, -3141337: 255, -3141338: 255, -3141339: 255, -3141340: 255, -3141341: 255, -3141342: 255, -3141343: 255, -3141344: 255, -3141345: 255, -3141346: 255, -3141347: 255, -3141348: 255, -3141349: 255, -3141350: 255, -3141351: 255, -3141352: 255, -3141353: 255, -3141354: 255, -3141355: 255, -3141356: 255, -3141357: 255, -3141358: 255, -3141359: 255, -3141360: 255, -3141361: 255, -3141362: 255, -3141363: 255, -3141364: 255, -3141365: 255, -3141366: 255, -3141367: 255, -3141368: 255, -3141369: 255, -3141370: 255, -3141371: 255, -3141372: 255, -3141373: 255, -3141374: 255, -3141375: 255, -3141376: 255, -3141377: 255, -3141378: 255, -3141379: 255, -3141380: 255, -3141381: 255, -3141382: 255, -3141383: 255, -3141384: 255, -3141385: 255, -3141386: 255, -3141387: 255, -3141388: 255, -3141389: 255, -3141390: 255, -3141391: 255, -3141392: 255, -3141393: 255, -3141394: 255, -3141395: 255, -3141396: 255, -3141397: 255, -3141398: 255, -3141399: 255, -3141400: 255, -3141401: 255, -3141402: 255, -3141403: 255, -3141404: 255, -3141405: 255, -3141406: 255, -3141407: 255, -3141408: 255, -458116: 17, -1307173: 0, -1307174: 56, -1307175: 87, -1307176: 63, -1307177: 77, -1307178: 46, -1307179: 226, -1307180: 0, -1307181: 96, -1307182: 0, -1307183: 176, -1307184: 58, -1307185: 11, -1307186: 34, -1307187: 102, -1307188: 17, -1307189: 36, -1307190: 9, -1307191: 255, -1307192: 87, -1307193: 247, -1307194: 66, -1307195: 16, -1307196: 38, -1307197: 140, -1307198: 21, -1307199: 31, -1307200: 124, -1307201: 24, -1307202: 96, -1307203: 10, -1307204: 48, -3143248: 255, -3143249: 255, -3143250: 255, -3143251: 255, -3143252: 255, -3143253: 255, -3143254: 255, -3143255: 255, -3143256: 255, -3143257: 255, -3143258: 255, -3143259: 255, -3143260: 255, -3143261: 255, -3143262: 255, -3143263: 255, -3143264: 255, -3143265: 255, -3143266: 255, -3143267: 255, -3143268: 255, -3143269: 255, -3143270: 255, -3143271: 255, -3143272: 255, -3143273: 255, -3143274: 255, -3143275: 255, -3143276: 255, -3143277: 255, -3143278: 255, -3143279: 255, -3143280: 255, -3143281: 255, -3143282: 255, -3143283: 255, -3143284: 255, -3143285: 255, -3143286: 255, -3143287: 255, -3143288: 255, -3143289: 255, -3143290: 255, -3143291: 255, -3143292: 255, -3143293: 255, -3143294: 255, -3143295: 255, -3143296: 255, -3143297: 255, -3143298: 255, -3143299: 255, -3143300: 255, -3143301: 255, -3143302: 255, -3143303: 255, -3143304: 255, -3143305: 255, -3143306: 255, -3143307: 255, -3143308: 255, -3143309: 255, -3143310: 255, -3143311: 255, -3143312: 255, -3143313: 255, -3143314: 255, -3143315: 255, -3143316: 255, -3143317: 255, -3143318: 255, -3143319: 255, -3143320: 255, -3143321: 255, -3143322: 255, -3143323: 255, -3143324: 255, -3143325: 255, -3143326: 255, -3143327: 255, -3143328: 255, -3143329: 255, -3143330: 255, -3143331: 255, -3143332: 255, -3143333: 255, -3143334: 255, -3143335: 255, -3143336: 255, -3143337: 255, -3143338: 255, -3143339: 255, -3143340: 255, -3143341: 255, -3143342: 255, -3143343: 255, -3143344: 255, -3143345: 255, -3143346: 255, -3143347: 255, -3143348: 255, -3143349: 255, -3143350: 255, -3143351: 255, -3143352: 255, -3143353: 255, -3143354: 255, -3143355: 255, -3143356: 255, -3143357: 255, -3143358: 255, -3143359: 255, -3143360: 255, -3143361: 255, -3143362: 255, -3143363: 255, -3143364: 255, -3143365: 255, -3143366: 255, -3143367: 255, -3143368: 255, -3143369: 255, -3143370: 255, -3143371: 255, -3143372: 255, -3143373: 255, -3143374: 255, -3143375: 255, -3143376: 255, -3143377: 255, -3143378: 255, -3143379: 255, -3143380: 255, -3143381: 255, -3143382: 255, -3143383: 255, -3143384: 255, -3143385: 255, -3143386: 255, -3143387: 255, -3143388: 255, -3143389: 255, -3143390: 255, -3143391: 255, -3143392: 255, -3143393: 255, -3143394: 255, -3143395: 255, -3143396: 255, -3143397: 255, -3143398: 255, -3143399: 255, -3143400: 255, -3143401: 255, -3143402: 255, -3143403: 255, -3143404: 255, -3143405: 255, -3143406: 255, -3143407: 255, -3143408: 255, -3143409: 255, -3143410: 255, -3143411: 255, -3143412: 255, -3143413: 255, -3143414: 255, -3143415: 255, -3143416: 255, -3143417: 255, -3143418: 255, -3143419: 255, -3143420: 255, -3143421: 255, -3143422: 255, -3143423: 255, -3143424: 255, -3143425: 255, -3143426: 255, -3143427: 255, -3143428: 255, -3143429: 255, -3143430: 255, -3143431: 255, -3143432: 255, -3143433: 255, -3143434: 255, -3143435: 255, -3143436: 255, -3143437: 255, -3143438: 255, -3143439: 255, -3143440: 255, -3143441: 255, -3143442: 255, -3143443: 255, -3143760: 255, -3143761: 255, -3143762: 255, -3143763: 255, -3143764: 255, -3143765: 255, -3143766: 255, -3143767: 255, -3143768: 255, -3143769: 255, -3143770: 255, -3143771: 255, -3143772: 255, -3143773: 255, -3143774: 255, -3143775: 255, -3143776: 255, -3143777: 255, -3143778: 255, -3143779: 255, -3143780: 255, -3143781: 255, -3143782: 255, -3143783: 255, -3143784: 255, -3143785: 255, -3143786: 255, -3143787: 255, -3143788: 255, -3143789: 255, -3143790: 255, -3143791: 255, -3143792: 255, -3143793: 255, -3143794: 255, -3143795: 255, -3143796: 255, -3143797: 255, -3143798: 255, -3143799: 255, -3143800: 255, -3143801: 255, -3143802: 255, -3143803: 255, -3143804: 255, -3143805: 255, -3143806: 255, -3143807: 255, -3143808: 255, -3143809: 255, -3143810: 255, -3143811: 255, -3143812: 255, -3143813: 255, -3143814: 255, -3143815: 255, -3143816: 255, -3143817: 255, -3143818: 255, -3143819: 255, -3143820: 255, -3143821: 255, -3143822: 255, -3143823: 255, -3143824: 255, -3143825: 255, -3143826: 255, -3143827: 255, -3143828: 255, -3143829: 255, -3143830: 255, -3143831: 255, -3143832: 255, -3143833: 255, -3143834: 255, -3143835: 255, -3143836: 255, -3143837: 255, -3143838: 255, -3143839: 255, -3143840: 255, -3143841: 255, -3143842: 255, -3143843: 255, -3143844: 255, -3143845: 255, -3143846: 255, -3143847: 255, -3143848: 255, -3143849: 255, -3143850: 255, -3143851: 255, -3143852: 255, -3143853: 255, -3143854: 255, -3143855: 255, -3143856: 255, -3143857: 255, -3143858: 255, -3143859: 255, -3143860: 255, -3143861: 255, -3143862: 255, -3143863: 255, -3143864: 255, -3143865: 255, -3143866: 255, -3143867: 255, -3143868: 255, -3143869: 255, -3143870: 255, -3143871: 255, -3143872: 255, -3143873: 255, -3143874: 255, -3143875: 255, -3143876: 255, -3143877: 255, -3143878: 255, -3143879: 255, -3143880: 255, -3143881: 255, -3143882: 255, -3143883: 255, -3143884: 255, -3143885: 255, -3143886: 255, -3143887: 255, -3143888: 255, -3143889: 255, -3143890: 255, -3143891: 255, -3143892: 255, -3143893: 255, -3143894: 255, -3143895: 255, -3143896: 255, -3143897: 255, -3143898: 255, -3143899: 255, -3143900: 255, -3143901: 255, -3143902: 255, -3143903: 255, -3143904: 255, -3143905: 255, -3143906: 255, -3143907: 255, -3143908: 255, -3143909: 255, -3143910: 255, -3143911: 255, -3143912: 255, -3143913: 255, -3143914: 255, -3143915: 255, -3143916: 255, -3143917: 255, -3143918: 255, -3143919: 255, -3143920: 255, -3143921: 255, -3143922: 255, -3143923: 255, -3143924: 255, -3143925: 255, -3143926: 255, -3143927: 255, -3143928: 255, -3143929: 255, -3143930: 255, -3143931: 255, -3143932: 255, -3143933: 255, -3143934: 255, -3143935: 255, -3143936: 255, -3143937: 255, -3143938: 255, -3143939: 255, -3143940: 255, -3143941: 255, -3143942: 255, -3143943: 255, -3143944: 255, -3143945: 255, -3143946: 255, -3143947: 255, -3143948: 255, -3143949: 255, -3143950: 255, -3143951: 255, -3143952: 255, -3143953: 255, -3143954: 255, -3143955: 255, -3143956: 255, -1157731: 95, -452159: 0, -852400: 224, -852401: 59, -852402: 128, -852403: 38, -852404: 128, -852405: 21, -1237977: 1, -1237978: 255, -1237979: 0, -1237980: 254, -1237981: 1, -1237982: 255, -1237983: 1, -1237984: 254, -1237985: 0, -1237986: 255, -1237987: 1, -1237988: 254, -1237989: 0, -1237990: 255, -1237991: 1, -1237992: 254, -1237993: 0, -1237994: 255, -1237995: 0, -1237996: 254, -1237997: 1, -1237998: 255, -1237999: 0, -1238000: 254, -1238001: 0, -1238002: 254, -1238003: 0, -1238004: 255, -1238005: 0, -1238006: 254, -1238007: 0, -1238008: 255, -1238009: 0, -1238010: 254, -1238011: 255, -1238012: 254, -1238013: 0, -1238014: 255, -1238015: 0, -1238016: 254, -1238017: 255, -1238018: 254, -1238019: 0, -1238020: 254, -1238021: 255, -1238022: 255, -1238023: 255, -1238024: 254, -1238025: 255, -1238026: 254, -1238027: 255, -1238028: 255, -1238029: 255, -1238030: 254, -1238031: 255, -1238032: 254, -1238033: 255, -1238034: 255, -1238035: 255, -1238036: 254, -1238037: 255, -1238038: 255, -1238039: 255, -1238040: 255, -1238041: 255, -1238042: 254, -1238043: 254, -1238044: 255, -1238045: 255, -1238046: 255, -1238047: 255, -1238048: 255, -1238049: 254, -1238050: 255, -1238051: 255, -1238052: 0, -1238053: 255, -1238054: 255, -1238055: 254, -1238056: 255, -1238057: 255, -1238058: 0, -1238059: 255, -1238060: 0, -1238061: 254, -1238062: 0, -1238063: 255, -1238064: 0, -1238065: 255, -1238066: 1, -1238067: 255, -1238068: 0, -1238069: 254, -1238070: 1, -1238071: 255, -1238072: 0, -1238073: 255, -1238074: 1, -1238075: 255, -1238076: 1, -1238077: 255, -1238078: 1, -1238079: 254, -1238080: 1, -1238081: 255, -1238082: 2, -1238083: 255, -1238084: 1, -1238085: 255, -1238086: 2, -1238087: 255, -1238088: 1, -1238089: 255, -1238090: 2, -1238091: 255, -1238092: 1, -1238093: 255, -1238094: 2, -1238095: 0, -1238096: 2, -1238097: 255, -1238098: 1, -1238099: 255, -1238100: 2, -1238101: 255, -1238102: 2, -1238103: 0, -1238104: 2, -1238105: 255, -1238106: 2, -1238107: 255, -1238108: 2, -1238109: 0, -1238110: 1, -1238111: 255, -1238112: 2, -1238113: 0, -1238114: 2, -1238115: 0, -1238116: 2, -1238117: 255, -1238118: 1, -1238119: 0, -1238120: 2, -1238121: 0, -1238122: 2, -1238123: 0, -1238124: 1, -1238125: 0, -1238126: 2, -1238127: 0, -1238128: 2, -1238129: 0, -1238130: 1, -1238131: 0, -1238132: 2, -1238133: 0, -1238134: 1, -1238135: 0, -1238136: 2, -1238137: 0, -1238138: 2, -1238139: 0, -1238140: 1, -1238141: 0, -1238142: 2, -1238143: 1, -1238144: 1, -1238145: 0, -1238146: 2, -1238147: 0, -1238148: 1, -1238149: 1, -1238150: 2, -1238151: 0, -1238152: 2, -1238153: 1, -1238154: 1, -1238155: 0, -1238156: 2, -1238157: 1, -1238158: 1, -1238159: 0, -1238160: 2, -1238161: 1, -1238162: 1, -1238163: 0, -1238164: 2, -1238165: 1, -1238166: 1, -1238167: 0, -1238168: 2, -1238169: 1, -1238170: 1, -1238171: 1, -1238172: 2, -1238173: 0, -1238174: 2, -1238175: 1, -1238176: 1, -1238177: 1, -1238178: 2, -1238179: 1, -1238180: 1, -1238181: 0, -1238182: 2, -1238183: 1, -1238184: 1, -1238185: 1, -1238186: 2, -1238187: 1, -1238188: 1, -1238189: 1, -1238190: 2, -1238191: 1, -1238192: 1, -1238193: 1, -1238194: 1, -1238195: 1, -1238196: 2, -1238197: 1, -1238198: 1, -1238199: 1, -1238200: 1, -1238201: 1, -1238202: 1, -1238203: 1, -1238204: 1, -1238205: 1, -1238206: 1, -1238207: 1, -1238208: 1, -1238209: 2, -1238210: 1, -1238211: 1, -1238212: 1, -1238213: 1, -1238214: 1, -1238215: 1, -1238216: 1, -1238217: 2, -1238218: 0, -1238219: 1, -1238220: 1, -1238221: 2, -1238222: 1, -1238223: 1, -1238224: 0, -1238225: 2, -1238226: 1, -1238227: 1, -1238228: 0, -1238229: 2, -1238230: 0, -1238231: 1, -1238232: 1, -1238233: 2, -1238234: 0, -1238235: 1, -1238236: 0, -1238237: 2, -1238238: 0, -1238239: 2, -1238240: 0, -1238241: 1, -1238242: 0, -1238243: 2, -1238244: 0, -1238245: 2, -1238246: 0, -1238247: 2, -1238248: 0, -1238249: 1, -1238250: 0, -1238251: 2, -1238252: 0, -1238253: 2, -1238254: 0, -1238255: 1, -1238256: 0, -1238257: 2, -1238258: 0, -1238259: 2, -1238260: 0, -1238261: 1, -1238262: 255, -1238263: 2, -1238264: 0 -} diff --git a/worlds/sm/variaRandomizer/randomizer.py b/worlds/sm/variaRandomizer/randomizer.py index 332c333c..924b4c5d 100644 --- a/worlds/sm/variaRandomizer/randomizer.py +++ b/worlds/sm/variaRandomizer/randomizer.py @@ -13,6 +13,8 @@ from .utils.utils import PresetLoader, loadRandoPreset, getDefaultMultiValues, g from .utils.version import displayedVersion from .utils.doorsmanager import DoorsManager from .logic.logic import Logic +from .utils.objectives import Objectives +from .utils.utils import dumpErrorMsg from .utils import log from ..Options import StartLocation @@ -33,6 +35,9 @@ progDiffs = defaultMultiValues['progressionDifficulty'] morphPlacements = defaultMultiValues['morphPlacement'] majorsSplits = defaultMultiValues['majorsSplit'] gravityBehaviours = defaultMultiValues['gravityBehaviour'] +objectives = defaultMultiValues['objective'] +tourians = defaultMultiValues['tourian'] +areaRandomizations = defaultMultiValues['areaRandomization'] def randomMulti(args, param, defaultMultiValues): value = args[param] @@ -40,7 +45,7 @@ def randomMulti(args, param, defaultMultiValues): isRandom = False if value == "random": isRandom = True - if args[param+"List"] != None: + if args[param+"List"] is not None: # use provided list choices = args[param+"List"].split(',') value = random.choice(choices) @@ -50,12 +55,6 @@ def randomMulti(args, param, defaultMultiValues): return (isRandom, value) -def dumpErrorMsg(outFileName, msg): - print("DIAG: " + msg) - if outFileName is not None: - with open(outFileName, 'w') as jsonFile: - json.dump({"errorMsg": msg}, jsonFile) - def dumpErrorMsgs(outFileName, msgs): dumpErrorMsg(outFileName, joinErrorMsgs(msgs)) @@ -74,9 +73,6 @@ def to_pascal_case_with_space(snake_str): class VariaRandomizer: parser = argparse.ArgumentParser(description="Random Metroid Randomizer") - parser.add_argument('--patchOnly', - help="only apply patches, do not perform any randomization", action='store_true', - dest='patchOnly', default=False) parser.add_argument('--param', '-p', help="the input parameters", default=None, dest='paramsFileName') parser.add_argument('--dir', @@ -86,12 +82,12 @@ class VariaRandomizer: help="generate dot file with area graph", action='store_true',dest='dot', default=False) parser.add_argument('--area', help="area mode", - dest='area', nargs='?', const=True, default=False) + dest='area', nargs='?', const=True, choices=["random"]+areaRandomizations, default='off') + parser.add_argument('--areaList', help="list to choose from when random", + dest='areaList', nargs='?', default=None) parser.add_argument('--areaLayoutBase', help="use simple layout patch for area mode", action='store_true', dest='areaLayoutBase', default=False) - parser.add_argument('--lightArea', help="keep number of transitions between vanilla areas", action='store_true', - dest='lightArea', default=False) parser.add_argument('--escapeRando', help="Randomize the escape sequence", dest='escapeRando', nargs='?', const=True, default=False) @@ -103,9 +99,6 @@ class VariaRandomizer: parser.add_argument('--minimizer', help="minimizer mode: area and boss mixed together. arg is number of non boss locations", dest='minimizerN', nargs='?', const=35, default=None, choices=[str(i) for i in range(30,101)]+["random"]) - parser.add_argument('--minimizerTourian', - help="Tourian speedup in minimizer mode", - dest='minimizerTourian', nargs='?', const=True, default=False) parser.add_argument('--startLocation', help="Name of the Access Point to start from", dest='startLocation', nargs='?', default="Landing Site", choices=['random'] + GraphUtils.getStartAccessPointNames()) @@ -135,11 +128,11 @@ class VariaRandomizer: parser.add_argument('--patch', '-c', help="optional patches to add", dest='patches', nargs='?', default=[], action='append', - choices=['itemsounds.ips', 'elevators_doors_speed.ips', 'random_music.ips', - 'spinjumprestart.ips', 'rando_speed.ips', 'No_Music', 'AimAnyButton.ips', - 'max_ammo_display.ips', 'supermetroid_msu1.ips', 'Infinite_Space_Jump', - 'refill_before_save.ips', 'remove_elevators_doors_speed.ips', - 'remove_itemsounds.ips', 'vanilla_music.ips']) + choices=['itemsounds.ips', 'random_music.ips', + 'fast_doors.ips', 'elevators_speed.ips', + 'spinjumprestart.ips', 'rando_speed.ips', 'No_Music', 'AimAnyButton.ips', + 'max_ammo_display.ips', 'supermetroid_msu1.ips', 'Infinite_Space_Jump', + 'refill_before_save.ips', 'relaxed_round_robin_cf.ips']) parser.add_argument('--missileQty', '-m', help="quantity of missiles", dest='missileQty', nargs='?', default=3, @@ -177,9 +170,6 @@ class VariaRandomizer: parser.add_argument('--scavRandomized', help="For Scavenger split, decide whether mandatory major locs will have non-vanilla items", dest='scavRandomized', nargs='?', const=True, default=False) - parser.add_argument('--scavEscape', - help="For Scavenger split, decide whether escape sequence shall be triggered as soon as the hunt is over", - dest='scavEscape', nargs='?', const=True, default=False) parser.add_argument('--suitsRestriction', help="no suits in early game", dest='suitsRestriction', nargs='?', const=True, default=False) @@ -235,46 +225,11 @@ class VariaRandomizer: parser.add_argument('--race', help="Race mode magic number, between 1 and 65535", dest='raceMagic', type=int) parser.add_argument('--vcr', help="Generate VCR output file", dest='vcr', action='store_true') - parser.add_argument('--palette', help="Randomize the palettes", dest='palette', action='store_true') - parser.add_argument('--individual_suit_shift', help="palette param", action='store_true', - dest='individual_suit_shift', default=False) - parser.add_argument('--individual_tileset_shift', help="palette param", action='store_true', - dest='individual_tileset_shift', default=False) - parser.add_argument('--no_match_ship_and_power', help="palette param", action='store_false', - dest='match_ship_and_power', default=True) - parser.add_argument('--seperate_enemy_palette_groups', help="palette param", action='store_true', - dest='seperate_enemy_palette_groups', default=False) - parser.add_argument('--no_match_room_shift_with_boss', help="palette param", action='store_false', - dest='match_room_shift_with_boss', default=True) - parser.add_argument('--no_shift_tileset_palette', help="palette param", action='store_false', - dest='shift_tileset_palette', default=True) - parser.add_argument('--no_shift_boss_palettes', help="palette param", action='store_false', - dest='shift_boss_palettes', default=True) - parser.add_argument('--no_shift_suit_palettes', help="palette param", action='store_false', - dest='shift_suit_palettes', default=True) - parser.add_argument('--no_shift_enemy_palettes', help="palette param", action='store_false', - dest='shift_enemy_palettes', default=True) - parser.add_argument('--no_shift_beam_palettes', help="palette param", action='store_false', - dest='shift_beam_palettes', default=True) - parser.add_argument('--no_shift_ship_palette', help="palette param", action='store_false', - dest='shift_ship_palette', default=True) - parser.add_argument('--min_degree', help="min hue shift", dest='min_degree', nargs='?', default=-180, type=int) - parser.add_argument('--max_degree', help="max hue shift", dest='max_degree', nargs='?', default=180, type=int) - parser.add_argument('--no_global_shift', help="", action='store_false', dest='global_shift', default=True) - parser.add_argument('--invert', help="invert color range", dest='invert', action='store_true', default=False) - parser.add_argument('--no_blue_door_palette', help="palette param", action='store_true', - dest='no_blue_door_palette', default=False) parser.add_argument('--ext_stats', help="dump extended stats SQL", nargs='?', default=None, dest='extStatsFilename') parser.add_argument('--randoPreset', help="rando preset file", dest="randoPreset", nargs='?', default=None) parser.add_argument('--fakeRandoPreset', help="for prog speed stats", dest="fakeRandoPreset", nargs='?', default=None) parser.add_argument('--plandoRando', help="json string with already placed items/locs", dest="plandoRando", nargs='?', default=None) - parser.add_argument('--sprite', help='use a custom sprite for Samus', dest='sprite', default=None) - parser.add_argument('--no_spin_attack', help='when using a custom sprite, use the same animation for screw attack with or without Space Jump', dest='noSpinAttack', action='store_true', default=False) - parser.add_argument('--customItemNames', help='add custom item names for some of them, related to the custom sprite', - dest='customItemNames', action='store_true', default=False) - parser.add_argument('--ship', help='use a custom sprite for Samus ship', dest='ship', default=None) - parser.add_argument('--seedIps', help='ips generated from previous seed', dest='seedIps', default=None) parser.add_argument('--jm,', help="display data used by jm for its stats", dest='jm', action='store_true', default=False) parser.add_argument('--doorsColorsRando', help='randomize color of colored doors', dest='doorsColorsRando', nargs='?', const=True, default=False) @@ -283,6 +238,17 @@ class VariaRandomizer: parser.add_argument('--logic', help='logic to use', dest='logic', nargs='?', default="varia", choices=["varia", "rotation"]) parser.add_argument('--hud', help='Enable VARIA hud', dest='hud', nargs='?', const=True, default=False) + parser.add_argument('--objective', + help="objectives to open G4", + dest='objective', nargs='?', default=[], action='append', + choices=Objectives.getAllGoals()+["random"]+[str(i) for i in range(6)]) + parser.add_argument('--objectiveList', help="list to choose from when random", + dest='objectiveList', nargs='?', default=None) + parser.add_argument('--tourian', help="Tourian mode", + dest='tourian', nargs='?', default='Vanilla', + choices=tourians+['random']) + parser.add_argument('--tourianList', help="list to choose from when random", + dest='tourianList', nargs='?', default=None) def __init__(self, world, rom, player): # parse args @@ -293,15 +259,13 @@ class VariaRandomizer: # args.startLocation = to_pascal_case_with_space(world.startLocation[player].current_key) if args.output is None and args.rom is None: - print("Need --output or --rom parameter") - sys.exit(-1) - elif args.output is not None and args.rom is not None: - print("Can't have both --output and --rom parameters") - sys.exit(-1) + raise Exception("Need --output or --rom parameter") - if args.plandoRando != None and args.output == None: - print("plandoRando param requires output param") - sys.exit(-1) + elif args.output is not None and args.rom is not None: + raise Exception("Can't have both --output and --rom parameters") + + if args.plandoRando is not None and args.output is None: + raise Exception("plandoRando param requires output param") log.init(args.debug) logger = log.get('Rando') @@ -320,7 +284,7 @@ class VariaRandomizer: if argDict[arg] not in okValues: argDict[arg] = value - self.forcedArgs[webArg if webArg != None else arg] = webValue if webValue != None else value + self.forcedArgs[webArg if webArg is not None else arg] = webValue if webValue is not None else value # print(msg) # optErrMsgs.append(msg) @@ -368,8 +332,7 @@ class VariaRandomizer: if args.raceMagic is not None: if args.raceMagic <= 0 or args.raceMagic >= 0x10000: - print("Invalid magic") - sys.exit(-1) + raise Exception("Invalid magic") # if no max diff, set it very high if args.maxDifficulty: @@ -401,6 +364,11 @@ class VariaRandomizer: (_, progDiff) = randomMulti(args.__dict__, "progressionDifficulty", progDiffs) (majorsSplitRandom, args.majorsSplit) = randomMulti(args.__dict__, "majorsSplit", majorsSplits) (_, self.gravityBehaviour) = randomMulti(args.__dict__, "gravityBehaviour", gravityBehaviours) + (_, args.tourian) = randomMulti(args.__dict__, "tourian", tourians) + (areaRandom, args.area) = randomMulti(args.__dict__, "area", areaRandomizations) + areaRandomization = args.area in ['light', 'full'] + lightArea = args.area == 'light' + if args.minDifficulty: minDifficulty = text2diff[args.minDifficulty] if progSpeed != "speedrun": @@ -408,7 +376,7 @@ class VariaRandomizer: else: minDifficulty = 0 - if args.area == True and args.bosses == True and args.minimizerN is not None: + if areaRandomization == True and args.bosses == True and args.minimizerN is not None: forceArg('majorsSplit', 'Full', "'Majors Split' forced to Full", altValue='FullWithHUD') if args.minimizerN == "random": self.minimizerN = random.randint(30, 60) @@ -417,11 +385,6 @@ class VariaRandomizer: self.minimizerN = int(args.minimizerN) else: self.minimizerN = None - areaRandom = False - if args.area == 'random': - areaRandom = True - args.area = bool(random.getrandbits(1)) - logger.debug("area: {}".format(args.area)) doorsColorsRandom = False if args.doorsColorsRando == 'random': @@ -443,7 +406,7 @@ class VariaRandomizer: forceArg('suitsRestriction', False, "'Suits restriction' forced to off", webValue='off') if args.suitsRestriction == 'random': - if args.morphPlacement == 'late' and args.area == True: + if args.morphPlacement == 'late' and areaRandomization == True: forceArg('suitsRestriction', False, "'Suits restriction' forced to off", webValue='off') else: args.suitsRestriction = bool(random.getrandbits(1)) @@ -453,7 +416,7 @@ class VariaRandomizer: args.hideItems = bool(random.getrandbits(1)) if args.morphPlacement == 'random': - if args.morphPlacementList != None: + if args.morphPlacementList is not None: morphPlacements = args.morphPlacementList.split(',') args.morphPlacement = random.choice(morphPlacements) # Scavenger Hunt constraints @@ -465,9 +428,10 @@ class VariaRandomizer: forceArg('startLocation', "Landing Site", "Start Location forced to Landing Site because of Scavenger mode") if args.morphPlacement == 'late': forceArg('morphPlacement', 'normal', "'Morph Placement' forced to normal instead of late") - if args.scavEscape == True: - forceArg('escapeRando', True, "'Escape randomization' forced to on", webValue='on') - forceArg('noRemoveEscapeEnemies', True, "Enemies enabled during escape sequence", webArg='removeEscapeEnemies', webValue='off') + # use escape rando for auto escape trigger + if args.tourian == 'Disabled': + forceArg('escapeRando', True, "'Escape randomization' forced to on", webValue='on') + forceArg('noRemoveEscapeEnemies', True, "Enemies enabled during escape sequence", webArg='removeEscapeEnemies', webValue='off') # random fill makes certain options unavailable if (progSpeed == 'speedrun' or progSpeed == 'basic') and args.majorsSplit != 'Scavenger': forceArg('progressionDifficulty', 'normal', "'Progression difficulty' forced to normal") @@ -485,19 +449,17 @@ class VariaRandomizer: forceArg('noLayout', False, "'Anti-softlock layout patches' forced to on", webValue='on') forceArg('suitsRestriction', False, "'Suits restriction' forced to off", webValue='off') forceArg('areaLayoutBase', False, "'Additional layout patches for easier navigation' forced to on", webValue='on') - possibleStartAPs, reasons = GraphUtils.getPossibleStartAPs(args.area, self.maxDifficulty, args.morphPlacement, self.player) + possibleStartAPs, reasons = GraphUtils.getPossibleStartAPs(areaRandomization, self.maxDifficulty, args.morphPlacement, self.player) if args.startLocation == 'random': - if args.startLocationList != None: - # to be able to give the list in jm we had to replace ' ' with '_', do the opposite operation - startLocationList = args.startLocationList.replace('_', ' ') - startLocationList = startLocationList.split(',') + if args.startLocationList is not None: + startLocationList = args.startLocationList.split(',') # intersection between user whishes and reality possibleStartAPs = sorted(list(set(possibleStartAPs).intersection(set(startLocationList)))) if len(possibleStartAPs) == 0: - optErrMsgs += ["%s : %s" % (apName, cause) for apName, cause in reasons.items() if apName in startLocationList] - optErrMsgs.append('Invalid start locations list with your settings.') - dumpErrorMsgs(args.output, optErrMsgs) - sys.exit(-1) + #optErrMsgs += ["%s : %s" % (apName, cause) for apName, cause in reasons.items() if apName in startLocationList] + raise Exception("Invalid start locations list with your settings." + + "%s : %s" % (apName, cause) for apName, cause in reasons.items() if apName in startLocationList) + #dumpErrorMsgs(args.output, optErrMsgs) args.startLocation = random.choice(possibleStartAPs) elif args.startLocation not in possibleStartAPs: args.startLocation = 'Landing Site' @@ -505,7 +467,6 @@ class VariaRandomizer: #optErrMsgs.append('Invalid start location: {}. {}'.format(args.startLocation, reasons[args.startLocation])) #optErrMsgs.append('Possible start locations with these settings: {}'.format(possibleStartAPs)) #dumpErrorMsgs(args.output, optErrMsgs) - #sys.exit(-1) ap = getAccessPoint(args.startLocation) if 'forcedEarlyMorph' in ap.Start and ap.Start['forcedEarlyMorph'] == True: forceArg('morphPlacement', 'early', "'Morph Placement' forced to early for custom start location") @@ -517,8 +478,7 @@ class VariaRandomizer: forceArg('morphPlacement', 'normal', "'Morph Placement' forced to normal for custom start location") if args.majorsSplit == 'Chozo' and args.morphPlacement == "late": forceArg('morphPlacement', 'normal', "'Morph Placement' forced to normal for Chozo") - #if args.patchOnly == False: - # print("SEED: " + str(self.seed)) + #print("SEED: " + str(self.seed)) # fill restrictions dict restrictions = { 'Suits' : args.suitsRestriction, 'Morph' : args.morphPlacement, "doors": "normal" if not args.doorsColorsRando else "late" } @@ -527,7 +487,8 @@ class VariaRandomizer: scavNumLocs = int(args.scavNumLocs) if scavNumLocs == 0: scavNumLocs = random.randint(4,16) - restrictions["ScavengerParams"] = {'numLocs':scavNumLocs, 'vanillaItems':not args.scavRandomized, 'escape': args.scavEscape} + restrictions["ScavengerParams"] = {'numLocs':scavNumLocs, 'vanillaItems':not args.scavRandomized} + restrictions["EscapeTrigger"] = args.tourian == 'Disabled' seedCode = 'X' if majorsSplitRandom == False: if restrictions['MajorMinor'] == 'Full': @@ -542,16 +503,12 @@ class VariaRandomizer: seedCode = 'B'+seedCode if args.doorsColorsRando == True and doorsColorsRandom == False: seedCode = 'D'+seedCode - if args.area == True and areaRandom == False: + if areaRandomization == True and areaRandom == False: seedCode = 'A'+seedCode - # output ROM name - #if args.patchOnly == False: - # self.fileName = 'VARIA_Randomizer_' + seedCode + str(self.seed) + '_' + preset - # if args.progressionSpeed != "random": - # self.fileName += "_" + args.progressionSpeed - #else: - # self.fileName = 'VARIA' # TODO : find better way to name the file (argument?) + #fileName = 'VARIA_Randomizer_' + seedCode + str(seed) + '_' + preset + #if args.progressionSpeed != "random": + # fileName += "_" + args.progressionSpeed self.fileName = output_path seedName = self.fileName if args.directory != '.': @@ -572,8 +529,12 @@ class VariaRandomizer: RomPatches.ActivePatches[self.player] += RomPatches.VariaTweaks if self.minimizerN is not None: RomPatches.ActivePatches[self.player].append(RomPatches.NoGadoras) - if args.minimizerTourian == True: - RomPatches.ActivePatches[self.player] += RomPatches.MinimizerTourian + if args.tourian == 'Fast': + RomPatches.ActivePatches[self.player] += RomPatches.MinimizerTourian + elif args.tourian == 'Disabled': + RomPatches.ActivePatches[self.player].append(RomPatches.NoTourian) + if 'relaxed_round_robin_cf.ips' in args.patches: + RomPatches.ActivePatches[self.player].append(RomPatches.RoundRobinCF) missileQty = float(args.missileQty) superQty = float(args.superQty) powerBombQty = float(args.powerBombQty) @@ -588,10 +549,8 @@ class VariaRandomizer: if minorQty < 1: minorQty = random.randint(25, 100) if self.energyQty == 'random': - if args.energyQtyList != None: - # with jm can't have a list with space in it - energyQtyList = args.energyQtyList.replace('_', ' ') - energyQties = energyQtyList.split(',') + if args.energyQtyList is not None: + energyQties = args.energyQtyList.split(',') self.energyQty = random.choice(energyQties) if self.energyQty == 'ultra sparse': # add nerfed rainbow beam patch @@ -620,31 +579,24 @@ class VariaRandomizer: self.ctrlDict = { getattr(ctrl, button) : button for button in ctrlButton } args.moonWalk = ctrl.Moonwalk - PlandoOptions = None + plandoSettings = None if args.plandoRando is not None: + plandoRando = json.loads(args.plandoRando) forceArg('progressionSpeed', 'speedrun', "'Progression Speed' forced to speedrun") progSpeed = 'speedrun' forceArg('majorsSplit', 'Full', "'Majors Split' forced to Full") forceArg('morphPlacement', 'normal', "'Morph Placement' forced to normal") forceArg('progressionDifficulty', 'normal', "'Progression difficulty' forced to normal") progDiff = 'normal' - args.plandoRando = json.loads(args.plandoRando) - RomPatches.ActivePatches[self.player] = args.plandoRando["patches"] - DoorsManager.unserialize(args.plandoRando["doors"]) - PlandoOptions = {"locsItems": args.plandoRando['locsItems'], "forbiddenItems": args.plandoRando['forbiddenItems']} + RomPatches.ActivePatches = plandoRando["patches"] + DoorsManager.unserialize(plandoRando["doors"]) + plandoSettings = {"locsItems": plandoRando['locsItems'], "forbiddenItems": plandoRando['forbiddenItems']} randoSettings = RandoSettings(self.maxDifficulty, progSpeed, progDiff, qty, restrictions, args.superFun, args.runtimeLimit_s, - PlandoOptions, minDifficulty) - - # print some parameters for jm's stats - if args.jm == True: - print("startLocation:{}".format(args.startLocation)) - print("progressionSpeed:{}".format(progSpeed)) - print("majorsSplit:{}".format(args.majorsSplit)) - print("morphPlacement:{}".format(args.morphPlacement)) + plandoSettings, minDifficulty) dotFile = None - if args.area == True: + if areaRandomization == True: if args.dot == True: dotFile = args.directory + '/' + seedName + '.dot' RomPatches.ActivePatches[self.player] += RomPatches.AreaBaseSet @@ -652,49 +604,84 @@ class VariaRandomizer: RomPatches.ActivePatches[self.player] += RomPatches.AreaComfortSet if args.doorsColorsRando == True: RomPatches.ActivePatches[self.player].append(RomPatches.RedDoorsMissileOnly) - graphSettings = GraphSettings(args.startLocation, args.area, args.lightArea, args.bosses, - args.escapeRando, self.minimizerN, dotFile, args.doorsColorsRando, args.allowGreyDoors, - args.plandoRando["transitions"] if args.plandoRando != None else None) + graphSettings = GraphSettings(self.player, args.startLocation, areaRandomization, lightArea, args.bosses, + args.escapeRando, self.minimizerN, dotFile, + args.doorsColorsRando, args.allowGreyDoors, args.tourian, + plandoRando["transitions"] if plandoSettings is not None else None) - if args.plandoRando is None: + if plandoSettings is None: DoorsManager.setDoorsColor(self.player) self.escapeAttr = None - if args.patchOnly == False: - try: - self.randoExec = RandoExec(seedName, args.vcr, randoSettings, graphSettings, self.player) - self.container = self.randoExec.randomize() - # if we couldn't find an area layout then the escape graph is not created either - # and getDoorConnections will crash if random escape is activated. - stuck = False - if not stuck or args.vcr == True: - self.doors = GraphUtils.getDoorConnections(self.randoExec.areaGraph, - args.area, args.bosses, - args.escapeRando) - escapeAttr = self.randoExec.areaGraph.EscapeAttributes if args.escapeRando else None - if escapeAttr is not None: - escapeAttr['patches'] = [] - if args.noRemoveEscapeEnemies == True: - escapeAttr['patches'].append("Escape_Rando_Enable_Enemies") - if args.scavEscape == True: - escapeAttr['patches'].append('Escape_Scavenger') - except Exception as e: - import traceback - traceback.print_exc(file=sys.stdout) - dumpErrorMsg(args.output, "Error: {}".format(e)) - sys.exit(-1) + if plandoSettings is None: + self.objectivesManager = Objectives(self.player, args.tourian != 'Disabled', randoSettings) + addedObjectives = 0 + if args.majorsSplit == "Scavenger": + self.objectivesManager.setScavengerHunt() + addedObjectives = 1 + + if args.objective: + try: + nbObjectives = int(args.objective[0]) + except: + nbObjectives = 0 if "random" in args.objective else None + if nbObjectives is not None: + availableObjectives = args.objectiveList.split(',') if args.objectiveList is not None else objectives + if nbObjectives == 0: + nbObjectives = random.randint(1, min(Objectives.maxActiveGoals, len(availableObjectives))) + self.objectivesManager.setRandom(nbObjectives, availableObjectives) + else: + maxActiveGoals = Objectives.maxActiveGoals - addedObjectives + if len(args.objective) > maxActiveGoals: + args.objective = args.objective[0:maxActiveGoals] + for goal in args.objective: + self.objectivesManager.addGoal(goal) + self.objectivesManager.expandGoals() + else: + if not (args.majorsSplit == "Scavenger" and args.tourian == 'Disabled'): + self.objectivesManager.setVanilla() + if len(self.objectivesManager.activeGoals) == 0: + self.objectivesManager.addGoal('nothing') + if any(goal for goal in self.objectivesManager.activeGoals if goal.area is not None): + forceArg('hud', True, "'VARIA HUD' forced to on", webValue='on') else: - stuck = False - itemLocs = [] - progItemLocs = None + args.tourian = plandoRando["tourian"] + self.objectivesManager = Objectives(self.player, args.tourian != 'Disabled') + for goal in plandoRando["objectives"]: + self.objectivesManager.addGoal(goal) + + # print some parameters for jm's stats + #if args.jm == True: + # print("startLocation:{}".format(args.startLocation)) + # print("progressionSpeed:{}".format(progSpeed)) + # print("majorsSplit:{}".format(args.majorsSplit)) + # print("morphPlacement:{}".format(args.morphPlacement)) + # print("gravity:{}".format(gravityBehaviour)) + # print("maxDifficulty:{}".format(maxDifficulty)) + # print("tourian:{}".format(args.tourian)) + # print("objectives:{}".format([g.name for g in Objectives.activeGoals])) + # print("energyQty:{}".format(energyQty)) + + #try: + self.randoExec = RandoExec(seedName, args.vcr, randoSettings, graphSettings, self.player) + self.container = self.randoExec.randomize() + # if we couldn't find an area layout then the escape graph is not created either + # and getDoorConnections will crash if random escape is activated. + stuck = False + if not stuck or args.vcr == True: + self.escapeAttr = self.randoExec.areaGraph.EscapeAttributes if args.escapeRando else None + if self.escapeAttr is not None: + self.escapeAttr['patches'] = [] + if args.noRemoveEscapeEnemies == True: + self.escapeAttr['patches'].append("Escape_Rando_Enable_Enemies") + #except Exception as e: + # import traceback + # traceback.print_exc(file=sys.stdout) + # dumpErrorMsg(args.output, "Error: {}".format(e)) + if stuck == True: - dumpErrorMsg(args.output, self.randoExec.errorMsg) - print("Can't generate " + self.fileName + " with the given parameters: {}".format(self.randoExec.errorMsg)) - # in vcr mode we still want the seed to be generated to analyze it - if args.vcr == False: - sys.exit(-1) - #if args.patchOnly == False: - # randoExec.postProcessItemLocs(itemLocs, args.hideItems) + #dumpErrorMsg(args.output, self.randoExec.errorMsg) + raise Exception("Can't generate " + self.fileName + " with the given parameters: {}".format(self.randoExec.errorMsg)) def PatchRom(self, outputFilename, customPrePatchApply = None, customPostPatchApply = None): args = self.args @@ -722,13 +709,12 @@ class VariaRandomizer: # for loc in sorted(locsItems.keys()): # print('{:>50}: {:>16} '.format(loc, locsItems[loc])) - # if args.plandoRando != None: + # if plandoSettings is not None: # with open(args.output, 'w') as jsonFile: # json.dump({"itemLocs": [il.json() for il in itemLocs], "errorMsg": randoExec.errorMsg}, jsonFile) - # sys.exit(0) # # generate extended stats - # if args.extStatsFilename != None: + # if args.extStatsFilename is not None: # with open(args.extStatsFilename, 'a') as extStatsFile: # skillPreset = os.path.splitext(os.path.basename(args.paramsFileName))[0] # if args.fakeRandoPreset is not None: @@ -738,96 +724,64 @@ class VariaRandomizer: # db.DB.dumpExtStatsItems(skillPreset, randoPreset, locsItems, extStatsFile) try: + if args.hud == True or args.majorsSplit == "FullWithHUD": + args.patches.append("varia_hud.ips") + if args.debug == True: + args.patches.append("Disable_Clear_Save_Boot") + + patcherSettings = { + "isPlando": False, + "majorsSplit": args.majorsSplit, + "startLocation": args.startLocation, + "optionalPatches": args.patches, + "layout": not args.noLayout, + "suitsMode": args.gravityBehaviour, + "area": args.area in ['light', 'full'], + "boss": args.bosses, + "areaLayout": not args.areaLayoutBase, + "variaTweaks": not args.noVariaTweaks, + "nerfedCharge": args.nerfedCharge, + "nerfedRainbowBeam": args.energyQty == 'ultra sparse', + "escapeAttr": self.escapeAttr, + "minimizerN": None, #minimizerN, + "tourian": args.tourian, + "doorsColorsRando": args.doorsColorsRando, + "vanillaObjectives": self.objectivesManager.isVanilla(), + "ctrlDict": self.ctrlDict, + "moonWalk": args.moonWalk, + "seed": self.seed, + "randoSettings": self.randoExec.randoSettings, + "doors": self.doors, + "displayedVersion": displayedVersion, + #"itemLocs": itemLocs, + #"progItemLocs": progItemLocs, + } + # args.rom is not None: generate local rom named filename.sfc with args.rom as source # args.output is not None: generate local json named args.output if args.rom is not None: # patch local rom romFileName = args.rom shutil.copyfile(romFileName, outputFilename) - romPatcher = RomPatcher(outputFilename, args.raceMagic, False, self.player) + romPatcher = RomPatcher(settings=patcherSettings, romFileName=outputFilename, magic=args.raceMagic, player=self.player) else: - romPatcher = RomPatcher(magic=args.raceMagic) + romPatcher = RomPatcher(settings=patcherSettings, magic=args.raceMagic) if customPrePatchApply != None: customPrePatchApply(romPatcher) - if args.hud == True or args.majorsSplit == "FullWithHUD": - args.patches.append("varia_hud.ips") - if args.patchOnly == False: - romPatcher.applyIPSPatches(args.startLocation, args.patches, - args.noLayout, self.gravityBehaviour, - args.area, args.bosses, args.areaLayoutBase, - args.noVariaTweaks, args.nerfedCharge, self.energyQty == 'ultra sparse', - self.escapeAttr, self.minimizerN, args.minimizerTourian, - args.doorsColorsRando) - else: - # from customizer permalink, apply previously generated seed ips first - if args.seedIps != None: - romPatcher.applyIPSPatch(args.seedIps) - - romPatcher.addIPSPatches(args.patches) - # don't color randomize custom ships - args.shift_ship_palette = False + romPatcher.patchRom() if customPostPatchApply != None: customPostPatchApply(romPatcher) - # we have to write ips to ROM before doing our direct modifications which will rewrite some parts (like in credits), - # but in web mode we only want to generate a global ips at the end -# if args.rom != None: -# romPatcher.commitIPS() - if args.patchOnly == False: -# romPatcher.writeItemsLocs(itemLocs) -# romPatcher.writeSplitLocs(args.majorsSplit, itemLocs, progItemLocs) - romPatcher.writeItemsNumber() - romPatcher.writeSeed(self.seed) # lol if race mode -# romPatcher.writeSpoiler(itemLocs, progItemLocs) -# romPatcher.writeRandoSettings(self.randoExec.randoSettings, itemLocs) - romPatcher.writeDoorConnections(self.doors) - romPatcher.writeVersion(displayedVersion) - if self.ctrlDict is not None: - romPatcher.writeControls(self.ctrlDict) - if args.moonWalk == True: - romPatcher.enableMoonWalk() - if args.patchOnly == False: - romPatcher.writeMagic() - romPatcher.writeMajorsSplit(args.majorsSplit) - # if args.palette == True: - # paletteSettings = { - # "global_shift": None, - # "individual_suit_shift": None, - # "individual_tileset_shift": None, - # "match_ship_and_power": None, - # "seperate_enemy_palette_groups": None, - # "match_room_shift_with_boss": None, - # "shift_tileset_palette": None, - # "shift_boss_palettes": None, - # "shift_suit_palettes": None, - # "shift_enemy_palettes": None, - # "shift_beam_palettes": None, - # "shift_ship_palette": None, - # "min_degree": None, - # "max_degree": None, - # "invert": None, - # "no_blue_door_palette": None - # } - # for param in paletteSettings: - # paletteSettings[param] = getattr(args, param) - # PaletteRando(romPatcher, paletteSettings, args.sprite).randomize() - - # web mode, generate only one ips at the end - if args.rom == None: - romPatcher.commitIPS() - romPatcher.end() - if args.patchOnly == False: - if len(optErrMsgs) > 0: -# optErrMsgs.append(randoExec.errorMsg) - msg = joinErrorMsgs(optErrMsgs) - else: -# msg = randoExec.errorMsg - msg = '' + if len(optErrMsgs) > 0: + #optErrMsgs.append(randoExec.errorMsg) + msg = joinErrorMsgs(optErrMsgs) else: + #msg = randoExec.errorMsg msg = '' + if args.rom is None: # web mode data = romPatcher.romFile.data self.fileName = '{}.sfc'.format(self.fileName) @@ -845,9 +799,8 @@ class VariaRandomizer: except Exception as e: import traceback traceback.print_exc(file=sys.stdout) - msg = "Error patching {}: ({}: {})".format(outputFilename, type(e).__name__, e) - dumpErrorMsg(args.output, msg) - sys.exit(-1) + raise Exception("Error patching {}: ({}: {})".format(outputFilename, type(e).__name__, e)) + #dumpErrorMsg(args.output, msg) # if stuck == True: # print("Rom generated for debug purpose: {}".format(self.fileName)) diff --git a/worlds/sm/variaRandomizer/rom/addressTypes.py b/worlds/sm/variaRandomizer/rom/addressTypes.py new file mode 100644 index 00000000..f735919d --- /dev/null +++ b/worlds/sm/variaRandomizer/rom/addressTypes.py @@ -0,0 +1,72 @@ +from .rom import snes_to_pc, pc_to_snes + +class Byte(object): + def __init__(self, value): + self.value = value + + def expand(self): + return [self.value] + +class Word(object): + def __init__(self, value): + self.value = value + + def expand(self): + return [self.value, self.value+1] + +class Long(object): + def __init__(self, value): + self.value = value + + def expand(self): + return [self.value, self.value+1, self.value+2] + +class ValueSingle(object): + def __init__(self, value, storage=Word): + self.value = snes_to_pc(value) + self.storage = storage + + def getOne(self): + return self.value + + def getAll(self): + return [self.value] + + def getWeb(self): + return self.storage(self.value).expand() + +class ValueList(object): + def __init__(self, values, storage=Word): + self.values = [snes_to_pc(value) for value in values] + self.storage = storage + + def getOne(self): + return self.values[0] + + def getAll(self): + return self.values + + def getWeb(self): + out = [] + for value in self.values: + out += self.storage(value).expand() + return out + +class ValueRange(object): + def __init__(self, start, length=-1, end=-1): + self.start = snes_to_pc(start) + if length != -1: + self.end = self.start + length + self.length = length + else: + self.end = snes_to_pc(end) + self.length = self.end - self.start + + def getOne(self): + return self.start + + def getAll(self): + return [self.start+i for i in range(self.length)] + + def getWeb(self): + return [self.start, self.end] diff --git a/worlds/sm/variaRandomizer/rom/addresses.py b/worlds/sm/variaRandomizer/rom/addresses.py new file mode 100644 index 00000000..76f149e1 --- /dev/null +++ b/worlds/sm/variaRandomizer/rom/addresses.py @@ -0,0 +1,51 @@ +from .addressTypes import ValueList, ValueSingle, ValueRange, Byte, Word, Long +from .objectivesAddresses import objectivesAddr + +# TODO::add patches + + +class Addresses(object): + @staticmethod + def getOne(key): + value = Addresses.addresses[key] + return value.getOne() + + @staticmethod + def getAll(key): + value = Addresses.addresses[key] + return value.getAll() + + @staticmethod + def getWeb(key): + value = Addresses.addresses[key] + return value.getWeb() + + @staticmethod + def getRange(key): + value = Addresses.addresses[key] + return value.getWeb() + + addresses = { + 'totalItems': ValueList([0x8BE656, 0x8BE6B3], storage=Byte), + 'majorsSplit': ValueSingle(0x82fb6c, storage=Byte), + # scavenger hunt items list (17 prog items (including ridley) + hunt over + terminator, each is a word) + 'scavengerOrder': ValueRange(0xA1F5D8, length=(17+1+1)*2), + 'plandoAddresses': ValueRange(0xdee000, length=128), + 'plandoTransitions': ValueSingle(0xdee100), + 'escapeTimer': ValueSingle(0x809e21), + 'escapeTimerTable': ValueSingle(0xA1F0AA), + 'startAP': ValueSingle(0xa1f200), + 'customDoorsAsm': ValueSingle(0x8ff800), + 'locIdsByArea': ValueRange(0xA1F568, end=0xA1F5D7), + 'plmSpawnTable': ValueSingle(0x8fe9a0), + 'plmSpawnRoomTable': ValueSingle(0x8ff000), + 'moonwalk': ValueSingle(0x81b35d), + 'additionalETanks': ValueSingle(0xA1F470, storage=Byte), + 'hellrunRate': ValueSingle(0x8DE387), + 'BTtweaksHack1': ValueSingle(0x84ba6f+3), + 'BTtweaksHack2': ValueSingle(0x84d33b+3), + # in intro_text.ips + 'introText': ValueSingle(0x8cc389) + } + +Addresses.addresses.update(objectivesAddr) diff --git a/worlds/sm/variaRandomizer/rom/ips.py b/worlds/sm/variaRandomizer/rom/ips.py index 23c52813..dd3f30a3 100644 --- a/worlds/sm/variaRandomizer/rom/ips.py +++ b/worlds/sm/variaRandomizer/rom/ips.py @@ -1,4 +1,4 @@ -import itertools +import itertools, math from ..utils.utils import range_union, openFile @@ -9,9 +9,14 @@ class IPS_Patch(object): self.truncate_length = None self.max_size = 0 if patchDict is not None: + recMaxSize = 0xffff for addr, data in patchDict.items(): - byteData = bytearray(data) - self.add_record(addr, byteData) + nrecs = int(math.ceil(float(len(data))/recMaxSize)) + for i in range(nrecs): + start = i*recMaxSize + end = min((i+1)*recMaxSize, len(data)) + byteData = bytearray(data[start:end]) + self.add_record(addr+start, byteData) def toDict(self): ret = {} diff --git a/worlds/sm/variaRandomizer/rom/objectivesAddresses.py b/worlds/sm/variaRandomizer/rom/objectivesAddresses.py new file mode 100644 index 00000000..058d4b6c --- /dev/null +++ b/worlds/sm/variaRandomizer/rom/objectivesAddresses.py @@ -0,0 +1,64 @@ +from .addressTypes import ValueList, ValueSingle, ValueRange +# generated from asar output +# A1 start: A1FA80 +objectivesAddr = { + # --- objectives checker functions: A1FA80 --- + 'objectivesList': ValueSingle(0xA1FA80), + 'objectiveEventsArray': ValueRange(0xA1FB1A, length=2*5), + 'objective[kraid_is_dead]': ValueSingle(0xA1FBCE), + 'objective[phantoon_is_dead]': ValueSingle(0xA1FBD6), + 'objective[draygon_is_dead]': ValueSingle(0xA1FBDE), + 'objective[ridley_is_dead]': ValueSingle(0xA1FBE6), + 'objective[all_g4_dead]': ValueSingle(0xA1FBEE), + 'objective[spore_spawn_is_dead]': ValueSingle(0xA1FC04), + 'objective[botwoon_is_dead]': ValueSingle(0xA1FC0C), + 'objective[crocomire_is_dead]': ValueSingle(0xA1FC14), + 'objective[golden_torizo_is_dead]': ValueSingle(0xA1FC1C), + 'objective[all_mini_bosses_dead]': ValueSingle(0xA1FC24), + 'objective[scavenger_hunt_completed]': ValueSingle(0xA1FC3A), + 'objective[boss_1_killed]': ValueSingle(0xA1FC7A), + 'objective[boss_2_killed]': ValueSingle(0xA1FC83), + 'objective[boss_3_killed]': ValueSingle(0xA1FC8C), + 'objective[miniboss_1_killed]': ValueSingle(0xA1FC95), + 'objective[miniboss_2_killed]': ValueSingle(0xA1FC9E), + 'objective[miniboss_3_killed]': ValueSingle(0xA1FCA7), + 'objective[collect_25_items]': ValueSingle(0xA1FCB0), + '__pct25': 0xA1FCB5, + 'objective[collect_50_items]': ValueSingle(0xA1FCB8), + '__pct50': 0xA1FCBD, + 'objective[collect_75_items]': ValueSingle(0xA1FCC0), + '__pct75': 0xA1FCC5, + 'objective[collect_100_items]': ValueSingle(0xA1FCC8), + '__pct100': 0xA1FCCD, + 'objective[nothing_objective]': ValueSingle(0xA1FCD0), + 'objective[fish_tickled]': ValueSingle(0xA1FCF8), + 'objective[orange_geemer]': ValueSingle(0xA1FD00), + 'objective[shak_dead]': ValueSingle(0xA1FD08), + 'itemsMask': ValueSingle(0xA1FD10), + 'beamsMask': ValueSingle(0xA1FD12), + 'objective[all_major_items]': ValueSingle(0xA1FD14), + 'objective[crateria_cleared]': ValueSingle(0xA1FD2B), + 'objective[green_brin_cleared]': ValueSingle(0xA1FD33), + 'objective[red_brin_cleared]': ValueSingle(0xA1FD3B), + 'objective[ws_cleared]': ValueSingle(0xA1FD43), + 'objective[kraid_cleared]': ValueSingle(0xA1FD4B), + 'objective[upper_norfair_cleared]': ValueSingle(0xA1FD53), + 'objective[croc_cleared]': ValueSingle(0xA1FD5B), + 'objective[lower_norfair_cleared]': ValueSingle(0xA1FD63), + 'objective[west_maridia_cleared]': ValueSingle(0xA1FD6B), + 'objective[east_maridia_cleared]': ValueSingle(0xA1FD73), + 'objective[all_chozo_robots]': ValueSingle(0xA1FD7B), + 'objective[visited_animals]': ValueSingle(0xA1FD9A), + 'objective[king_cac_dead]': ValueSingle(0xA1FDE6), + # A1 end: A1FDEE + # Pause stuff: 82FB6D + # *** completed spritemaps: 82FE83 + 'objectivesSpritesOAM': ValueSingle(0x82FE83), + # 82 end: 82FEB0 + 'objectivesText': ValueSingle(0xB6F200), +} +_pctList = [] +for pct in [25,50,75,100]: + _pctList.append(objectivesAddr['__pct%d' % pct]) + del objectivesAddr['__pct%d' % pct] +objectivesAddr['totalItemsPercent'] = ValueList(_pctList) diff --git a/worlds/sm/variaRandomizer/rom/rom.py b/worlds/sm/variaRandomizer/rom/rom.py index d173f7ab..37c15698 100644 --- a/worlds/sm/variaRandomizer/rom/rom.py +++ b/worlds/sm/variaRandomizer/rom/rom.py @@ -18,17 +18,50 @@ def snes_to_pc(B): return (A_1 << 16) | A_2 +VANILLA_ROM_SIZE = 3145728 +BANK_SIZE = 0x8000 + class ROM(object): + def __init__(self, data={}): + self.address = 0 + self.maxAddress = VANILLA_ROM_SIZE + + def close(self): + pass + + def seek(self, address): + if address > self.maxAddress: + self.maxAddress = address + self.address = address + + def tell(self): + if self.address > self.maxAddress: + self.maxAddress = self.address + return self.address + + def inc(self, n=1): + self.address += n + self.tell() + + def read(self, byteCount): + pass + def readWord(self, address=None): return self.readBytes(2, address) def readByte(self, address=None): return self.readBytes(1, address) + def readLong(self, address=None): + return self.readBytes(3, address) + def readBytes(self, size, address=None): if address != None: self.seek(address) return int.from_bytes(self.read(size), byteorder='little') + + def write(self, bytes): + pass def writeWord(self, word, address=None): self.writeBytes(word, 2, address) @@ -36,25 +69,45 @@ class ROM(object): def writeByte(self, byte, address=None): self.writeBytes(byte, 1, address) + def writeLong(self, lng, address=None): + self.writeBytes(lng, 3, address) + def writeBytes(self, value, size, address=None): if address != None: self.seek(address) self.write(value.to_bytes(size, byteorder='little')) + + def ipsPatch(self, ipsPatches): + pass + + def fillToNextBank(self): + off = self.maxAddress % BANK_SIZE + if off > 0: + self.seek(self.maxAddress + BANK_SIZE - off - 1) + self.writeByte(0xff) + assert (self.maxAddress % BANK_SIZE) == 0 class RealROM(ROM): def __init__(self, name): + super(RealROM, self).__init__() self.romFile = open(name, "rb+") - self.address = 0 def seek(self, address): - self.address = address + super(RealROM, self).seek(address) self.romFile.seek(address) + def tell(self): + self.address = self.romFile.tell() + return super(RealROM, self).tell() + def write(self, bytes): self.romFile.write(bytes) + self.tell() def read(self, byteCount): - return self.romFile.read(byteCount) + ret = self.romFile.read(byteCount) + self.tell() + return ret def close(self): self.romFile.close() diff --git a/worlds/sm/variaRandomizer/rom/rom_patches.py b/worlds/sm/variaRandomizer/rom/rom_patches.py index ff5e2aa8..f108f262 100644 --- a/worlds/sm/variaRandomizer/rom/rom_patches.py +++ b/worlds/sm/variaRandomizer/rom/rom_patches.py @@ -61,6 +61,8 @@ class RomPatches: CrabShaftBlueDoor = 107 # wrap door from sand halls left to under botwoon MaridiaSandWarp = 108 + # Replace PB blocks at Aqueduct entrance with bomb blocks + AqueductBombBlocks = 109 ## Minimizer Patches NoGadoras = 200 TourianSpeedup = 201 @@ -81,6 +83,12 @@ class RomPatches: NerfedRainbowBeam = 1005 # Red doors open with one missile, and don't react to supers: part of door color rando RedDoorsMissileOnly = 1006 + # Escape auto-trigger on objectives completion (no Tourian) + NoTourian = 1007 + # BT wakes up on its item instead of bombs + BombTorizoWake = 1008 + # Round-Robin Crystal Flash patch + RoundRobinCF = 1009 ### Hacks # rotation hack @@ -103,11 +111,11 @@ class RomPatches: AreaBaseSet = [ SingleChamberNoCrumble, AreaRandoGatesBase, AreaRandoBlueDoors, AreaRandoMoreBlueDoors, CrocBlueDoors, CrabShaftBlueDoor, MaridiaSandWarp ] - AreaComfortSet = [ AreaRandoGatesOther, SpongeBathBlueDoor, EastOceanPlatforms ] + AreaComfortSet = [ AreaRandoGatesOther, SpongeBathBlueDoor, EastOceanPlatforms, AqueductBombBlocks ] AreaSet = AreaBaseSet + AreaComfortSet # VARIA specific patch set - VariaTweaks = [ WsEtankPhantoonAlive, LNChozoSJCheckDisabled ] + VariaTweaks = [ WsEtankPhantoonAlive, LNChozoSJCheckDisabled, BombTorizoWake ] # Tourian speedup in minimizer mode MinimizerTourian = [ TourianSpeedup, OpenZebetites ] @@ -125,6 +133,6 @@ class RomPatches: @staticmethod def setDefaultPatches(startLocation): # called by the isolver in seedless mode. - # activate only layout patch (the most common one), red tower blue doors and the startLocation's patches. + # activate only layout patch (the most common one), red tower blue doors, startLocation's patches and balanced suits. from graph.graph_utils import GraphUtils - RomPatches.ActivePatches[0] = [RomPatches.RedTowerBlueDoors] + RomPatches.TotalLayout + GraphUtils.getGraphPatches(startLocation) + RomPatches.ActivePatches[0] = [RomPatches.RedTowerBlueDoors] + RomPatches.TotalLayout + GraphUtils.getGraphPatches(startLocation) + [RomPatches.NoGravityEnvProtection] diff --git a/worlds/sm/variaRandomizer/rom/rompatcher.py b/worlds/sm/variaRandomizer/rom/rompatcher.py index 0e052f20..fedb89e8 100644 --- a/worlds/sm/variaRandomizer/rom/rompatcher.py +++ b/worlds/sm/variaRandomizer/rom/rompatcher.py @@ -1,10 +1,15 @@ -import os, random, re +import os, random, re, json +from math import ceil +from enum import IntFlag from ..rando.Items import ItemManager from ..rom.ips import IPS_Patch -from ..utils.doorsmanager import DoorsManager -from ..graph.graph_utils import GraphUtils, getAccessPoint, locIdsByAreaAddresses +from ..utils.doorsmanager import DoorsManager, IndicatorFlag +from ..utils.objectives import Objectives +from ..graph.graph_utils import GraphUtils, getAccessPoint, locIdsByAreaAddresses, graphAreas from ..logic.logic import Logic from ..rom.rom import RealROM, snes_to_pc, pc_to_snes +from ..rom.addresses import Addresses +from ..rom.rom_patches import RomPatches from ..patches.patchaccess import PatchAccess from ..utils.parameters import appDir from ..utils import log @@ -20,9 +25,7 @@ class RomPatcher: # faster MB cutscene transitions 'Mother_Brain_Cutscene_Edits', # "Balanced" suit mode - 'Removes_Gravity_Suit_heat_protection', - # door ASM to skip G4 cutscene when all 4 bosses are dead - 'g4_skip.ips', + 'Removes_Gravity_Suit_heat_protection' ], # VARIA tweaks 'VariaTweaks' : ['WS_Etank', 'LN_Chozo_SpaceJump_Check_Disable', 'ln_chozo_platform.ips', 'bomb_torizo.ips'], @@ -30,20 +33,9 @@ class RomPatcher: 'Layout': ['dachora.ips', 'early_super_bridge.ips', 'high_jump.ips', 'moat.ips', 'spospo_save.ips', 'nova_boost_platform.ips', 'red_tower.ips', 'spazer.ips', 'brinstar_map_room.ips', 'kraid_save.ips', 'mission_impossible.ips'], - # comfort patches - 'Optional': ['rando_speed.ips', 'Infinite_Space_Jump', 'refill_before_save.ips', - 'spinjumprestart.ips', 'elevators_doors_speed.ips', 'No_Music', 'random_music.ips', - # animals - 'animal_enemies.ips', 'animals.ips', 'draygonimals.ips', - 'escapimals.ips', 'gameend.ips', 'grey_door_animals.ips', - 'low_timer.ips', 'metalimals.ips', 'phantoonimals.ips', 'ridleyimals.ips', - 'Escape_Animals_Change_Event', # ...end animals - # vanilla behaviour restore - 'remove_elevators_doors_speed.ips', - 'varia_hud.ips'], # base patchset+optional layout for area rando 'Area': ['area_rando_layout.ips', 'door_transition.ips', 'area_rando_doors.ips', - 'Sponge_Bath_Blinking_Door', 'east_ocean.ips', 'area_rando_warp_door.ips', + 'Sponge_Bath_Blinking_Door', 'east_ocean.ips', 'area_rando_warp_door.ips', 'aqueduct_bomb_blocks.ips', 'crab_shaft.ips', 'Save_Crab_Shaft', 'Save_Main_Street', 'no_demo.ips'], # patches for boss rando 'Bosses': ['door_transition.ips', 'no_demo.ips'], @@ -55,14 +47,16 @@ class RomPatcher: 'DoorsColors': ['beam_doors_plms.ips', 'beam_doors_gfx.ips', 'red_doors.ips'] } - def __init__(self, romFileName=None, magic=None, plando=False, player=0): + def __init__(self, settings=None, romFileName=None, magic=None, player=0): self.log = log.get('RomPatcher') + self.settings = settings self.romFileName = romFileName + self.patchAccess = PatchAccess() self.race = None self.romFile = RealROM(romFileName) #if magic is not None: # from rom.race_mode import RaceModePatcher - # self.race = RaceModePatcher(self, magic, plando) + # self.race = RaceModePatcher(self, magic) # IPS_Patch objects list self.ipsPatches = [] # loc name to alternate address. we still write to original @@ -79,18 +73,25 @@ class RomPatcher: # get out of croc room: reload CRE 0x93ea: self.forceRoomCRE } - self.patchAccess = PatchAccess() self.player = player + def patchRom(self): + self.applyIPSPatches() + self.commitIPS() + def end(self): + self.romFile.fillToNextBank() self.romFile.close() def writeItemCode(self, item, visibility, address): itemCode = ItemManager.getItemTypeCode(item, visibility) + self.writePlmWord(itemCode, address) + + def writePlmWord(self, word, address): if self.race is None: - self.romFile.writeWord(itemCode, address) + self.romFile.writeWord(word, address) else: - self.race.writeItemCode(itemCode, address) + self.race.writePlmWord(word, address) def getLocAddresses(self, loc): ret = [loc.Address] @@ -115,23 +116,24 @@ class RomPatcher: continue self.writeItem(itemLoc) if item.Category != 'Nothing': - self.nItems += 1 + if not loc.restricted: + self.nItems += 1 if loc.Name == 'Morphing Ball': self.patchMorphBallEye(item) def writeSplitLocs(self, split, itemLocs, progItemLocs): majChozoCheck = lambda itemLoc: itemLoc.Item.Class == split and itemLoc.Location.isClass(split) - fullCheck = lambda itemLoc: itemLoc.Location.Id is not None + fullCheck = lambda itemLoc: itemLoc.Location.Id is not None and itemLoc.Location.BossItemType is None splitChecks = { 'Full': fullCheck, 'Scavenger': fullCheck, 'Major': majChozoCheck, 'Chozo': majChozoCheck, - 'FullWithHUD': lambda itemLoc: itemLoc.Item.Category not in ['Energy', 'Ammo', 'Boss'] + 'FullWithHUD': lambda itemLoc: itemLoc.Item.Category not in ['Energy', 'Ammo', 'Boss', 'MiniBoss'] } itemLocCheck = lambda itemLoc: itemLoc.Item.Category != "Nothing" and splitChecks[split](itemLoc) for area,addr in locIdsByAreaAddresses.items(): - locs = [il.Location for il in itemLocs if itemLocCheck(il) and il.Location.GraphArea == area] + locs = [il.Location for il in itemLocs if itemLocCheck(il) and il.Location.GraphArea == area and not il.Location.restricted] self.log.debug("writeSplitLocs. area="+area) self.log.debug(str([loc.Name for loc in locs])) self.romFile.seek(addr) @@ -140,11 +142,14 @@ class RomPatcher: self.romFile.writeByte(0xff) if split == "Scavenger": # write required major item order - self.romFile.seek(snes_to_pc(0xA1F5D8)) + self.romFile.seek(Addresses.getOne('scavengerOrder')) for itemLoc in progItemLocs: self.romFile.writeWord((itemLoc.Location.Id << 8) | itemLoc.Location.HUD) # bogus loc ID | "HUNT OVER" index - self.romFile.writeWord(0xff10) + self.romFile.writeWord(0xff11) + # fill remaining list with 0xFFFF to avoid issue with plandomizer having less items than in the base seed + for i in range(18-len(progItemLocs)): + self.romFile.writeWord(0xffff) # trigger morph eye enemy on whatever item we put there, # not just morph ball @@ -183,8 +188,8 @@ class RomPatcher: operand = item.BeamBits else: operand = item.ItemBits - self.patchMorphBallCheck(0x1410E6, cat, comp, operand, branch) # eye main AI - self.patchMorphBallCheck(0x1468B2, cat, comp, operand, branch) # head main AI + self.patchMorphBallCheck(snes_to_pc(0xa890e6), cat, comp, operand, branch) # eye main AI + self.patchMorphBallCheck(snes_to_pc(0xa8e8b2), cat, comp, operand, branch) # head main AI def patchMorphBallCheck(self, offset, cat, comp, operand, branch): # actually patch enemy AI @@ -195,113 +200,111 @@ class RomPatcher: def writeItemsNumber(self): # write total number of actual items for item percentage patch (patch the patch) - for addr in [0x5E64E, 0x5E6AB]: + for addr in Addresses.getAll('totalItems'): self.romFile.writeByte(self.nItems, addr) + # for X% collected items objectives, precompute values and write them in objectives functions + for percent, addr in zip([25, 50, 75, 100], Addresses.getAll('totalItemsPercent')): + self.romFile.writeWord(ceil((self.nItems * percent)/100), addr) + def addIPSPatches(self, patches): for patchName in patches: self.applyIPSPatch(patchName) - def writePlmTable(self, plms, area, bosses, startLocation): - # called when saving a plando - try: - if bosses == True or area == True: - plms.append('WS_Save_Blinking_Door') - - doors = self.getStartDoors(plms, area, None) - self.writeDoorsColor(doors, self.player) - self.applyStartAP(startLocation, plms, doors) - - self.applyPLMs(plms) - except Exception as e: - raise Exception("Error patching {}. ({})".format(self.romFileName, e)) - - def applyIPSPatches(self, startLocation="Landing Site", - optionalPatches=[], noLayout=False, suitsMode="Balanced", - area=False, bosses=False, areaLayoutBase=False, - noVariaTweaks=False, nerfedCharge=False, nerfedRainbowBeam=False, - escapeAttr=None, minimizerN=None, minimizerTourian=True, - doorsColorsRando=False): + def applyIPSPatches(self): try: # apply standard patches stdPatches = [] plms = [] - # apply race mode first because it fills the rom with a bunch of crap - if self.race is not None: - stdPatches.append('race_mode.ips') + stdPatches += RomPatcher.IPSPatches['Standard'][:] + if not self.settings["layout"]: + # when disabling anti softlock protection also disable doors indicators + stdPatches.remove('door_indicators_plms.ips') if self.race is not None: - stdPatches.append('race_mode_credits.ips') - if suitsMode != "Balanced": + stdPatches.append('race_mode_post.ips') + if self.settings["suitsMode"] != "Balanced": stdPatches.remove('Removes_Gravity_Suit_heat_protection') - if suitsMode == "Progressive": + if self.settings["suitsMode"] == "Progressive": stdPatches.append('progressive_suits.ips') - if nerfedCharge == True: + if self.settings["nerfedCharge"] == True: stdPatches.append('nerfed_charge.ips') - if nerfedRainbowBeam == True: + if self.settings["nerfedRainbowBeam"] == True: stdPatches.append('nerfed_rainbow_beam.ips') - if bosses == True or area == True: + if self.settings["boss"] == True or self.settings["area"] == True: stdPatches += ["WS_Main_Open_Grey", "WS_Save_Active"] plms.append('WS_Save_Blinking_Door') - if bosses == True: + if self.settings["boss"] == True: stdPatches.append("Phantoon_Eye_Door") - if area == True or doorsColorsRando == True: + if (self.settings["area"] == True + or self.settings["doorsColorsRando"] == True + or not GraphUtils.isStandardStart(self.settings["startLocation"])): stdPatches.append("Enable_Backup_Saves") - if 'varia_hud.ips' in optionalPatches: - # varia hud has its own variant of g4_skip for scavenger mode, - # it can also make demos glitch out - stdPatches.remove("g4_skip.ips") + if 'varia_hud.ips' in self.settings["optionalPatches"]: + # varia hud can make demos glitch out self.applyIPSPatch("no_demo.ips") for patchName in stdPatches: self.applyIPSPatch(patchName) - if noLayout == False: + if not self.settings["vanillaObjectives"]: + self.applyIPSPatch("Objectives_sfx") + # show objectives and Tourian status in a shortened intro sequence + # if not full vanilla objectives+tourian + if not self.settings["vanillaObjectives"] or self.settings["tourian"] != "Vanilla": + self.applyIPSPatch("Restore_Intro") # important to apply this after new_game.ips + self.applyIPSPatch("intro_text.ips") + if self.settings["layout"]: # apply layout patches for patchName in RomPatcher.IPSPatches['Layout']: self.applyIPSPatch(patchName) - if noVariaTweaks == False: + if self.settings["variaTweaks"]: # VARIA tweaks for patchName in RomPatcher.IPSPatches['VariaTweaks']: self.applyIPSPatch(patchName) + if (self.settings["majorsSplit"] == 'Scavenger' + and any(il for il in self.settings["progItemLocs"] if il.Location.Name == "Ridley")): + # ridley as scav loc + self.applyIPSPatch("Blinking[RidleyRoomIn]") # apply optional patches - for patchName in optionalPatches: - if patchName in RomPatcher.IPSPatches['Optional']: - self.applyIPSPatch(patchName) + for patchName in self.settings["optionalPatches"]: + self.applyIPSPatch(patchName) # random escape - if escapeAttr is not None: + if self.settings["escapeAttr"] is not None: for patchName in RomPatcher.IPSPatches['Escape']: self.applyIPSPatch(patchName) # animals and timer - self.applyEscapeAttributes(escapeAttr, plms) + self.applyEscapeAttributes(self.settings["escapeAttr"], plms) # apply area patches - if area == True: + if self.settings["area"] == True: + if not self.settings["areaLayout"]: + for p in ['area_rando_layout.ips', 'Sponge_Bath_Blinking_Door', 'east_ocean.ips', 'aqueduct_bomb_blocks.ips']: + RomPatcher.IPSPatches['Area'].remove(p) + RomPatcher.IPSPatches['Area'].append('area_rando_layout_base.ips') for patchName in RomPatcher.IPSPatches['Area']: - if areaLayoutBase == True and patchName in ['area_rando_layout.ips', 'Sponge_Bath_Blinking_Door', 'east_ocean.ips']: - continue self.applyIPSPatch(patchName) - if areaLayoutBase == True: - self.applyIPSPatch('area_rando_layout_base.ips') - - else: self.applyIPSPatch('area_ids_alt.ips') - if bosses == True: + if self.settings["boss"] == True: for patchName in RomPatcher.IPSPatches['Bosses']: self.applyIPSPatch(patchName) - if minimizerN is not None: + if self.settings["minimizerN"] is not None: self.applyIPSPatch('minimizer_bosses.ips') - if minimizerTourian == True: - for patchName in RomPatcher.IPSPatches['MinimizerTourian']: - self.applyIPSPatch(patchName) - doors = self.getStartDoors(plms, area, minimizerN) - if doorsColorsRando == True: + if self.settings["tourian"] == "Fast": + for patchName in RomPatcher.IPSPatches['MinimizerTourian']: + self.applyIPSPatch(patchName) + elif self.settings["tourian"] == "Disabled": + self.applyIPSPatch("Escape_Trigger") + doors = self.getStartDoors(plms, self.settings["area"], self.settings["minimizerN"]) + if self.settings["doorsColorsRando"] == True: for patchName in RomPatcher.IPSPatches['DoorsColors']: self.applyIPSPatch(patchName) self.writeDoorsColor(doors, self.player) - self.applyStartAP(startLocation, plms, doors) + if self.settings["layout"]: + self.writeDoorIndicators(plms, self.settings["area"], self.settings["doorsColorsRando"]) + self.applyStartAP(self.settings["startLocation"], plms, doors) self.applyPLMs(plms) except Exception as e: raise Exception("Error patching {}. ({})".format(self.romFileName, e)) @@ -359,9 +362,9 @@ class RomPatcher: if 'doors' in ap.Start: doors += ap.Start['doors'] doors.append(0x0) - addr = 0x10F200 + addr = Addresses.getOne('startAP') patch = [w0, w1] + doors - assert (addr + len(patch)) < 0x10F210, "Stopped before new_game overwrite" + assert (addr + len(patch)) < addr + 0x10, "Stopped before new_game overwrite" patchDict = { 'StartAP': { addr: patch @@ -381,11 +384,22 @@ class RomPatcher: # timer escapeTimer = escapeAttr['Timer'] if escapeTimer is not None: - minute = int(escapeTimer / 60) - second = escapeTimer % 60 - minute = int(minute / 10) * 16 + minute % 10 - second = int(second / 10) * 16 + second % 10 - patchDict = {'Escape_Timer': {0x1E21:[second, minute]}} + patchDict = { 'Escape_Timer': {} } + timerPatch = patchDict["Escape_Timer"] + def getTimerBytes(t): + minute = int(t / 60) + second = t % 60 + minute = int(minute / 10) * 16 + minute % 10 + second = int(second / 10) * 16 + second % 10 + return [second, minute] + timerPatch[Addresses.getOne('escapeTimer')] = getTimerBytes(escapeTimer) + # timer table for Disabled Tourian escape + if 'TimerTable' in escapeAttr: + tableBytes = [] + timerPatch[Addresses.getOne('escapeTimerTable')] = tableBytes + for area in graphAreas[1:-1]: # no Ceres or Tourian + t = escapeAttr['TimerTable'][area] + tableBytes += getTimerBytes(t) self.applyIPSPatch('Escape_Timer', patchDict) # animals door to open if escapeAttr['Animals'] is not None: @@ -431,9 +445,9 @@ class RomPatcher: for locName, locIndex in locList: plmLocs[(k, locIndex)] = locName # make two patches out of this dict - plmTblAddr = 0x7E9A0 # moves downwards + plmTblAddr = Addresses.getOne('plmSpawnTable') # moves downwards plmPatchData = [] - roomTblAddr = 0x7EC00 # moves upwards + roomTblAddr = Addresses.getOne('plmSpawnRoomTable') # moves upwards roomPatchData = [] plmTblOffset = plmTblAddr def appendPlmBytes(bytez): @@ -463,7 +477,7 @@ class RomPatcher: addRoomPatchData(roomData) # write room table terminator addRoomPatchData([0x0] * 8) - assert plmTblOffset < roomTblAddr, "Spawn PLM table overlap" + assert plmTblOffset < roomTblAddr, "Spawn PLM table overlap. PLM table offset is 0x%x, Room table address is 0x%x" % (plmTblOffset,roomTblAddr) patchDict = { "PLM_Spawn_Tables" : { plmTblAddr: plmPatchData, @@ -479,7 +493,7 @@ class RomPatcher: random.seed(seed) seedInfo = random.randint(0, 0xFFFF) seedInfo2 = random.randint(0, 0xFFFF) - self.romFile.writeWord(seedInfo, 0x2FFF00) + self.romFile.writeWord(seedInfo, snes_to_pc(0xdfff00)) self.romFile.writeWord(seedInfo2) def writeMagic(self): @@ -487,7 +501,7 @@ class RomPatcher: self.race.writeMagic() def writeMajorsSplit(self, majorsSplit): - address = 0x17B6C + address = Addresses.getOne('majorsSplit') splits = { 'Chozo': 'Z', 'Major': 'M', @@ -528,7 +542,7 @@ class RomPatcher: totalNothing = sum(1 for il in itemLocs if il.Accessible and il.Item.Category == 'Nothing') totalEnergy = self.getItemQty(itemLocs, 'ETank')+self.getItemQty(itemLocs, 'Reserve') totalMajors = max(totalItemLocs - totalEnergy - totalAmmo - totalNothing, 0) - address = 0x2736C0 + address = snes_to_pc(0xceb6c0) value = "{:>2}".format(totalItemLocs) line = " ITEM LOCATIONS %s " % value self.writeCreditsStringBig(address, line, top=True) @@ -606,7 +620,7 @@ class RomPatcher: address += 0x40 # write ammo/energy pct - address = 0x273C40 + address = snes_to_pc(0xcebc40) (ammoPct, energyPct) = (int(self.getAmmoPct(dist)), int(100*totalEnergy/18)) line = " AVAILABLE AMMO {:>3}% ENERGY {:>3}%".format(ammoPct, energyPct) self.writeCreditsStringBig(address, line, top=True) @@ -650,7 +664,7 @@ class RomPatcher: return s isRace = self.race is not None - startCreditAddress = 0x2f5240 + startCreditAddress = snes_to_pc(0xded240) address = startCreditAddress if isRace: addr = address - 0x40 @@ -794,6 +808,12 @@ class RomPatcher: else: self.race.writeWordMagic(w) + def writeDoorTransition(self, roomPtr): + if self.race is None: + self.romFile.writeWord(roomPtr) + else: + self.race.writeDoorTransition(roomPtr) + # write area randomizer transitions to ROM # doorConnections : a list of connections. each connection is a dictionary describing # - where to write in the ROM : @@ -805,10 +825,10 @@ class RomPatcher: # property shall point to this custom ASM. # * if not, just write doorAsmPtr as the door property directly. def writeDoorConnections(self, doorConnections): - asmAddress = 0x7F800 + asmAddress = Addresses.getOne('customDoorsAsm') for conn in doorConnections: # write door ASM for transition doors (code and pointers) -# print('Writing door connection ' + conn['ID']) +# print('Writing door connection ' + conn['ID'] + ". doorPtr="+hex(doorPtr)) doorPtr = conn['DoorPtr'] roomPtr = conn['RoomPtr'] if doorPtr in self.doorConnectionSpecific: @@ -818,7 +838,7 @@ class RomPatcher: self.romFile.seek(0x10000 + doorPtr) # write room ptr - self.romFile.writeWord(roomPtr & 0xFFFF) + self.writeDoorTransition(roomPtr & 0xFFFF) # write bitflag (if area switch we have to set bit 0x40, and remove it if same area) self.romFile.writeByte(conn['bitFlag']) @@ -891,7 +911,7 @@ class RomPatcher: # change BG table to avoid scrolling sky bug when transitioning to west ocean def patchWestOcean(self, doorPtr): - self.romFile.writeWord(doorPtr, 0x7B7BB) + self.romFile.writeWord(doorPtr, snes_to_pc(0x8fb7bb)) # forces CRE graphics refresh when exiting kraid's or croc room def forceRoomCRE(self, roomPtr, creFlag=0x2): @@ -934,7 +954,7 @@ class RomPatcher: self.romFile.writeByte(RomPatcher.buttons[button][1]) def writePlandoAddresses(self, locations): - self.romFile.seek(0x2F6000) + self.romFile.seek(Addresses.getOne('plandoAddresses')) for loc in locations: self.romFile.writeWord(loc.Address & 0xFFFF) @@ -944,7 +964,7 @@ class RomPatcher: self.romFile.writeWord(0xFFFF) def writePlandoTransitions(self, transitions, doorsPtrs, maxTransitions): - self.romFile.seek(0x2F6100) + self.romFile.seek(Addresses.getOne('plandoTransitions')) for (src, dest) in transitions: self.romFile.writeWord(doorsPtrs[src]) @@ -957,7 +977,14 @@ class RomPatcher: def enableMoonWalk(self): # replace STZ with STA since A is non-zero at this point - self.romFile.writeByte(0x8D, 0xB35D) + self.romFile.writeByte(0x8D, Addresses.getOne('moonwalk')) + + def writeAdditionalETanks(self, additionalETanks): + self.romFile.writeByte(additionalETanks, Addresses.getOne("additionalETanks")) + + def writeHellrunRate(self, hellrunRatePct): + hellrunRateVal = min(int(0x40*float(hellrunRatePct)/100.0), 0xff) + self.romFile.writeByte(hellrunRateVal, Addresses.getOne("hellrunRate")) def setOamTile(self, nth, middle, newTile, y=0xFC): # an oam entry is made of five bytes: (s000000 xxxxxxxxx) (yyyyyyyy) (YXpp000t tttttttt) @@ -976,8 +1003,8 @@ class RomPatcher: # max 32 chars # new oamlist address in free space at the end of bank 8C - self.romFile.writeWord(0xF3E9, 0x5a0e3) - self.romFile.writeWord(0xF3E9, 0x5a0e9) + self.romFile.writeWord(0xF3E9, snes_to_pc(0x8ba0e3)) + self.romFile.writeWord(0xF3E9, snes_to_pc(0x8ba0e9)) # string length versionLength = len(version) @@ -986,7 +1013,7 @@ class RomPatcher: length = versionLength + rotationLength else: length = versionLength - self.romFile.writeWord(length, 0x0673e9) + self.romFile.writeWord(length, snes_to_pc(0x8cf3e9)) versionMiddle = int(versionLength / 2) + versionLength % 2 # oams @@ -998,8 +1025,64 @@ class RomPatcher: for (i, char) in enumerate('rotation'): self.setOamTile(i, rotationMiddle, char2tile[char], y=0x8e) - def writeDoorsColor(self, doors, player): - DoorsManager.writeDoorsColor(self.romFile, doors, player) + def writeDoorsColor(self, doorsStart, player): + if self.race is None: + DoorsManager.writeDoorsColor(self.romFile, doorsStart, player, self.romFile.writeWord) + else: + DoorsManager.writeDoorsColor(self.romFile, doorsStart, player, self.writePlmWord) + + def writeDoorIndicators(self, plms, area, door): + indicatorFlags = IndicatorFlag.Standard | (IndicatorFlag.AreaRando if area else 0) | (IndicatorFlag.DoorRando if door else 0) + patchDict = self.patchAccess.getDictPatches() + additionalPLMs = self.patchAccess.getAdditionalPLMs() + def updateIndicatorPLM(door, doorType): + nonlocal additionalPLMs, patchDict + plmName = 'Indicator[%s]' % door + addPlm = False + if plmName in patchDict: + for addr,bytez in patchDict[plmName].items(): + plmBytes = bytez + break + else: + plmBytes = additionalPLMs[plmName]['plm_bytes_list'][0] + addPlm = True + w = getWord(doorType) + plmBytes[0] = w[0] + plmBytes[1] = w[1] + return plmName, addPlm + indicatorPLMs = DoorsManager.getIndicatorPLMs(self.player, indicatorFlags) + for doorName,plmType in indicatorPLMs.items(): + plmName,addPlm = updateIndicatorPLM(doorName, plmType) + if addPlm: + plms.append(plmName) + else: + self.applyIPSPatch(plmName) + + def writeObjectives(self, itemLocs, tourian): + objectives = Objectives.objDict[self.player] + objectives.writeGoals(self.romFile) + objectives.writeIntroObjectives(self.romFile, tourian) + self.writeItemsMasks(itemLocs) + # hack bomb_torizo.ips to wake BT in all cases if necessary, ie chozo bots objective is on, and nothing at bombs + if objectives.isGoalActive("activate chozo robots") and RomPatches.has(RomPatches.BombTorizoWake): + bomb = next((il for il in itemLocs if il.Location.Name == "Bomb"), None) + if bomb is not None and bomb.Item.Category == "Nothing": + for addrName in ["BTtweaksHack1", "BTtweaksHack2"]: + self.romFile.seek(Addresses.getOne(addrName)) + for b in [0xA9,0x00,0x00]: # LDA #$0000 ; set zero flag to wake BT + self.romFile.writeByte(b) + + def writeItemsMasks(self, itemLocs): + # write items/beams masks for "collect all major" objective + itemsMask = 0 + beamsMask = 0 + for il in itemLocs: + if not il.Location.restricted: + item = il.Item + itemsMask |= item.ItemBits + beamsMask |= item.BeamBits + self.romFile.writeWord(itemsMask, Addresses.getOne('itemsMask')) + self.romFile.writeWord(beamsMask, Addresses.getOne('beamsMask')) # tile number in tileset char2tile = { @@ -1025,7 +1108,7 @@ class MessageBox(object): # add 0x0c/0x06 to offsets as there's 12/6 bytes before the strings, string length is either 0x13/0x1a self.offsets = { - 'ETank': (0x2877f+0x0c, 0x13), + 'ETank': (snes_to_pc(0x85877f)+0x0c, 0x13), 'Missile': (0x287bf+0x06, 0x1a), 'Super': (0x288bf+0x06, 0x1a), 'PowerBomb': (0x289bf+0x06, 0x1a), @@ -1088,3 +1171,266 @@ class MessageBox(object): def updateAttr(self, byte, address): self.rom.writeByte(byte, address) + +class RomTypeForMusic(IntFlag): + VariaSeed = 1 + AreaSeed = 2 + BossSeed = 4 + +class MusicPatcher(object): + # rom: ROM object to patch + # romType: 0 if not varia seed, or bitwise or of RomTypeForMusic enum + # baseDir: directory containing all music data/descriptors/constraints + # constraintsFile: file to constraints JSON descriptor, relative to baseDir/constraints. + # if None, will be determined automatically from romType + def __init__(self, rom, romType, + baseDir=os.path.join(appDir, 'varia_custom_sprites', 'music'), + constraintsFile=None): + self.rom = rom + self.baseDir = baseDir + variaSeed = bool(romType & RomTypeForMusic.VariaSeed) + self.area = variaSeed and bool(romType & RomTypeForMusic.AreaSeed) + self.boss = variaSeed and bool(romType & RomTypeForMusic.BossSeed) + metaDir = os.path.join(baseDir, "_metadata") + constraintsDir = os.path.join(baseDir, "_constraints") + if constraintsFile is None: + constraintsFile = 'varia.json' if variaSeed else 'vanilla.json' + with open(os.path.join(constraintsDir, constraintsFile), 'r') as f: + self.constraints = json.load(f) + nspcInfoPath = os.path.join(baseDir, "nspc_metadata.json") + with open(nspcInfoPath, "r") as f: + nspcInfo = json.load(f) + self.nspcInfo = {} + for nspc,info in nspcInfo.items(): + self.nspcInfo[self._nspc_path(nspc)] = info + self.allTracks = {} + self.vanillaTracks = None + for metaFile in os.listdir(metaDir): + metaPath = os.path.join(metaDir, metaFile) + if not metaPath.endswith(".json"): + continue + with open(metaPath, 'r') as f: + meta = json.load(f) + # will silently overwrite entries with same name, so avoid + # conflicting descriptor files ... + self.allTracks.update(meta) + if metaFile == "vanilla.json": + self.vanillaTracks = meta + assert self.vanillaTracks is not None, "MusicPatcher: missing vanilla JSON descriptor" + self.replaceableTracks = [track for track in self.vanillaTracks if track not in self.constraints['preserve'] and track not in self.constraints['discard']] + self.musicDataTableAddress = snes_to_pc(0x8FE7E4) + self.musicDataTableMaxSize = 45 # to avoid overwriting useful data in bank 8F + + # tracks: dict with track name to replace as key, and replacing track name as value + # updateReferences: change room state headers and special tracks. may be False if you're patching a rom hack or something + # output: if not None, dump a JSON file with what was done + # replaced tracks must be in + # replaceableTracks, and new tracks must be in allTracks + # tracks not in the dict will be kept vanilla + # raise RuntimeError if not possible + def replace(self, tracks, updateReferences=True, output=None): + for track in tracks: + if track not in self.replaceableTracks: + raise RuntimeError("Cannot replace track %s" % track) + trackList = self._getTrackList(tracks) + replacedVanilla = [t for t in self.replaceableTracks if t in trackList and t not in tracks] + for van in replacedVanilla: + tracks[van] = van +# print("trackList="+str(trackList)) + musicData = self._getMusicData(trackList) +# print("musicData="+str(musicData)) + if len(musicData) > self.musicDataTableMaxSize: + raise RuntimeError("Music data table too long. %d entries, max is %d" % (len(musicData, self.musicDataTableMaxSize))) + musicDataAddresses = self._getMusicDataAddresses(musicData) + self._writeMusicData(musicDataAddresses) + self._writeMusicDataTable(musicData, musicDataAddresses) + if updateReferences == True: + self._updateReferences(trackList, musicData, tracks) + if output is not None: + self._dump(output, trackList, musicData, musicDataAddresses) + + # compose a track list from vanilla tracks, replaced tracks, and constraints + def _getTrackList(self, replacedTracks): + trackList = set() + for track in self.vanillaTracks: + if track in replacedTracks: + trackList.add(replacedTracks[track]) + elif track not in self.constraints['discard']: + trackList.add(track) + return list(trackList) + + def _nspc_path(self, nspc_path): + return os.path.join(self.baseDir, nspc_path) + + # get list of music data files to include in the ROM + # can contain empty entries, marked with a None, to account + # for fixed place data ('preserve' constraint) + def _getMusicData(self, trackList): + # first, make musicData the minimum size wrt preserved tracks + preservedTracks = {trackName:self.vanillaTracks[trackName] for trackName in self.constraints['preserve']} + preservedDataIndexes = [track['data_index'] for trackName,track in preservedTracks.items()] + musicData = [None]*(max(preservedDataIndexes)+1) + # fill preserved spots + for track in self.constraints['preserve']: + idx = self.vanillaTracks[track]['data_index'] + nspc = self._nspc_path(self.vanillaTracks[track]['nspc_path']) + if nspc not in musicData: + musicData[idx] = nspc +# print("stored " + nspc + " at "+ str(idx)) + # then fill data in remaining spots + idx = 0 + for track in trackList: + previdx = idx + if track not in self.constraints['preserve']: + nspc = self._nspc_path(self.allTracks[track]['nspc_path']) + if nspc not in musicData: + for i in range(idx, len(musicData)): +# print("at " + str(i) + ": "+str(musicData[i])) + if musicData[i] is None: + musicData[i] = nspc + idx = i+1 + break + if idx == previdx: + idx += 1 + musicData.append(nspc) +# print("stored " + nspc + " at "+ str(idx)) + return musicData + + # get addresses to store each data file to. raise RuntimeError if not possible + # pretty dumb algorithm for now, just store data wherever possible, + # prioritizing first areas in usableSpace + # store data from end of usable space to make room for other data (for hacks for instance) + def _getMusicDataAddresses(self, musicData): + usableSpace = self.constraints['usable_space_ranges_pc'] + musicDataAddresses = {} + for dataFile in musicData: + if dataFile is None: + continue + sz = os.path.getsize(dataFile) + blocks = self.nspcInfo[dataFile]['block_headers_offsets'] + for r in usableSpace: + # find a suitable address so header words are not split across banks (header is 2 words) + addr = r['end'] - sz + def isCrossBank(off): + nonlocal addr + endBankOffset = pc_to_snes(addr+off+4) & 0x7fff + return endBankOffset == 1 or endBankOffset == 3 + while addr >= r['start'] and any(isCrossBank(off) for off in blocks): + addr -= 1 + if addr >= r['start']: + musicDataAddresses[dataFile] = addr + r['end'] = addr + break + if dataFile not in musicDataAddresses: + raise RuntimeError("Cannot find enough space to store music data file "+dataFile) + return musicDataAddresses + + def _writeMusicData(self, musicDataAddresses): + for dataFile, addr in musicDataAddresses.items(): + self.rom.seek(addr) + with open(dataFile, 'rb') as f: + self.rom.write(f.read()) + + def _writeMusicDataTable(self, musicData, musicDataAddresses): + self.rom.seek(self.musicDataTableAddress) + for dataFile in musicData: + addr = pc_to_snes(musicDataAddresses[dataFile]) if dataFile in musicDataAddresses else 0 + self.rom.writeLong(addr) + + def _getDataId(self, musicData, track): + return (musicData.index(self._nspc_path(self.allTracks[track]['nspc_path']))+1)*3 + + def _getTrackId(self, track): + return self.allTracks[track]['track_index'] + 5 + + def _updateReferences(self, trackList, musicData, replacedTracks): + trackAddresses = {} + def addAddresses(track, vanillaTrackData, prio=False): + nonlocal trackAddresses + addrs = [] + prioAddrs = [] + if 'pc_addresses' in vanillaTrackData: + addrs += vanillaTrackData['pc_addresses'] + if self.area and 'pc_addresses_area' in vanillaTrackData: + prioAddrs += vanillaTrackData['pc_addresses_area'] + if self.boss and 'pc_addresses_boss' in vanillaTrackData: + prioAddrs += vanillaTrackData['pc_addresses_boss'] + if track not in trackAddresses: + trackAddresses[track] = [] + # if prioAddrs are somewhere else, remove if necessary + prioSet = set(prioAddrs) + for t,tAddrs in trackAddresses.items(): + trackAddresses[t] = list(set(tAddrs) - prioSet) + # if some of addrs are somewhere else, remove them from here + for t,tAddrs in trackAddresses.items(): + addrs = list(set(addrs) - set(tAddrs)) + trackAddresses[track] += prioAddrs + addrs + for track in trackList: + if track in replacedTracks.values(): + for van,rep in replacedTracks.items(): + if rep == track: + addAddresses(track, self.vanillaTracks[van]) + else: + addAddresses(track, self.vanillaTracks[track]) + for track in trackList: + dataId = self._getDataId(musicData, track) + trackId = self._getTrackId(track) + for addr in trackAddresses[track]: + self.rom.seek(addr) + self.rom.writeByte(dataId) + self.rom.writeByte(trackId) + self._writeSpecialReferences(replacedTracks, musicData) + + # write special (boss) data + def _writeSpecialReferences(self, replacedTracks, musicData, static=True, dynamic=True): + for track,replacement in replacedTracks.items(): + # static patches are needed only when replacing tracks + if track != replacement: + staticPatches = self.vanillaTracks[track].get("static_patches", None) + else: + staticPatches = None + # dynamic patches are similar to pc_addresses*, and must be written also + # when track is vanilla, as music data table is changed + dynamicPatches = self.vanillaTracks[track].get("dynamic_patches", None) + if static and staticPatches: + for addr,bytez in staticPatches.items(): + self.rom.seek(int(addr)) + for b in bytez: + self.rom.writeByte(b) + if dynamic and dynamicPatches: + dataId = self._getDataId(musicData, replacement) + trackId = self._getTrackId(replacement) + dataIdAddrs = dynamicPatches.get("data_id", []) + trackIdAddrs = dynamicPatches.get("track_id", []) + for addr in dataIdAddrs: + self.rom.writeByte(dataId, addr) + for addr in trackIdAddrs: + self.rom.writeByte(trackId, addr) + + def _dump(self, output, trackList, musicData, musicDataAddresses): + music={} + no=0 + for md in musicData: + if md is None: + music["NoData_%d" % no] = None + no += 1 + else: + tracks = [] + h,t=os.path.split(md) + md=os.path.join(os.path.split(h)[1], t) + for track,trackData in self.allTracks.items(): + if trackData['nspc_path'] == md: + tracks.append(track) + music[md] = tracks + musicSnesAddresses = {} + for nspc, addr in musicDataAddresses.items(): + h,t=os.path.split(nspc) + nspc=os.path.join(os.path.split(h)[1], t) + musicSnesAddresses[nspc] = "$%06x" % pc_to_snes(addr) + dump = { + "track_list": sorted(trackList), + "music_data": music, + "music_data_addresses": musicSnesAddresses + } + with open(output, 'w') as f: + json.dump(dump, f, indent=4) \ No newline at end of file diff --git a/worlds/sm/variaRandomizer/solver.py b/worlds/sm/variaRandomizer/solver.py deleted file mode 100644 index 88738146..00000000 --- a/worlds/sm/variaRandomizer/solver.py +++ /dev/null @@ -1,224 +0,0 @@ -#!/usr/bin/python3 -import sys, argparse - -from solver.interactiveSolver import InteractiveSolver -from solver.standardSolver import StandardSolver -from solver.conf import Conf -import utils.log - -def interactiveSolver(args): - # to init, requires interactive/romFileName/presetFileName/output parameters in standard/plando mode - # to init, requires interactive/presetFileName/output parameters in seedless mode - # to iterate, requires interactive/state/[loc]/[item]/action/output parameters in item scope - # to iterate, requires interactive/state/[startPoint]/[endPoint]/action/output parameters in area scope - if args.action == 'init': - # init - if args.mode != 'seedless' and args.romFileName == None: - print("Missing romFileName parameter for {} mode".format(args.mode)) - sys.exit(1) - - if args.presetFileName == None or args.output == None: - print("Missing preset or output parameter") - sys.exit(1) - - solver = InteractiveSolver(args.output, args.logic) - solver.initialize(args.mode, args.romFileName, args.presetFileName, magic=args.raceMagic, fill=args.fill, startLocation=args.startLocation) - else: - # iterate - params = {} - if args.scope == 'common': - if args.action == "save": - params["lock"] = args.lock - params["escapeTimer"] = args.escapeTimer - elif args.action == "randomize": - params["minorQty"] = args.minorQty - params["energyQty"] = args.energyQty - params["forbiddenItems"] = args.forbiddenItems.split(',') if args.forbiddenItems is not None else [] - elif args.scope == 'item': - if args.state == None or args.action == None or args.output == None: - print("Missing state/action/output parameter") - sys.exit(1) - if args.action in ["add", "replace"]: - if args.mode not in ['seedless', 'race', 'debug'] and args.loc == None: - print("Missing loc parameter when using action add for item") - sys.exit(1) - if args.mode == 'plando': - if args.item == None: - print("Missing item parameter when using action add in plando/suitless mode") - sys.exit(1) - params = {'loc': args.loc, 'item': args.item, 'hide': args.hide} - elif args.action == "remove": - if args.loc != None: - params = {'loc': args.loc} - elif args.item != None: - params = {'item': args.item} - else: - params = {'count': args.count} - elif args.action == "toggle": - params = {'item': args.item} - elif args.scope == 'area': - if args.state == None or args.action == None or args.output == None: - print("Missing state/action/output parameter") - sys.exit(1) - if args.action == "add": - if args.startPoint == None or args.endPoint == None: - print("Missing start or end point parameter when using action add for item") - sys.exit(1) - params = {'startPoint': args.startPoint, 'endPoint': args.endPoint} - if args.action == "remove" and args.startPoint != None: - params = {'startPoint': args.startPoint} - elif args.scope == 'door': - if args.state == None or args.action == None or args.output == None: - print("Missing state/action/output parameter") - sys.exit(1) - if args.action == "replace": - if args.doorName is None or args.newColor is None: - print("Missing doorName or newColor parameter when using action replace for door") - sys.exit(1) - params = {'doorName': args.doorName, 'newColor': args.newColor} - elif args.action == "toggle": - if args.doorName is None: - print("Missing doorName parameter when using action toggle for door") - sys.exit(1) - params = {'doorName': args.doorName} - elif args.scope == 'dump': - if args.action == "import": - if args.dump is None: - print("Missing dump parameter when import a dump") - params = {'dump': args.dump} - params["debug"] = args.mode == 'debug' - - solver = InteractiveSolver(args.output, args.logic) - solver.iterate(args.state, args.scope, args.action, params) - -def standardSolver(args): - if args.romFileName is None: - print("Parameter --romFileName mandatory when not in interactive mode") - sys.exit(1) - - if args.difficultyTarget is None: - difficultyTarget = Conf.difficultyTarget - else: - difficultyTarget = args.difficultyTarget - - if args.pickupStrategy is None: - pickupStrategy = Conf.itemsPickup - else: - pickupStrategy = args.pickupStrategy - - # itemsForbidden is like that: [['Varia'], ['Reserve'], ['Gravity']], fix it - args.itemsForbidden = [item[0] for item in args.itemsForbidden] - - solver = StandardSolver(args.romFileName, args.presetFileName, difficultyTarget, - pickupStrategy, args.itemsForbidden, type=args.type, - firstItemsLog=args.firstItemsLog, extStatsFilename=args.extStatsFilename, - extStatsStep=args.extStatsStep, - displayGeneratedPath=args.displayGeneratedPath, - outputFileName=args.output, magic=args.raceMagic, - checkDuplicateMajor=args.checkDuplicateMajor, vcr=args.vcr, - runtimeLimit_s=args.runtimeLimit_s) - - solver.solveRom() - -if __name__ == "__main__": - parser = argparse.ArgumentParser(description="Random Metroid Solver") - parser.add_argument('--romFileName', '-r', help="the input rom", nargs='?', - default=None, dest="romFileName") - parser.add_argument('--preset', '-p', help="the preset file", nargs='?', - default=None, dest='presetFileName') - parser.add_argument('--difficultyTarget', '-t', - help="the difficulty target that the solver will aim for", - dest='difficultyTarget', nargs='?', default=None, type=int) - parser.add_argument('--pickupStrategy', '-s', help="Pickup strategy for the Solver", - dest='pickupStrategy', nargs='?', default=None, - choices=['all', 'any']) - parser.add_argument('--itemsForbidden', '-f', help="Item not picked up during solving", - dest='itemsForbidden', nargs='+', default=[], action='append') - - parser.add_argument('--type', '-y', help="web or console", dest='type', nargs='?', - default='console', choices=['web', 'console']) - parser.add_argument('--checkDuplicateMajor', dest="checkDuplicateMajor", action='store_true', - help="print a warning if the same major is collected more than once") - parser.add_argument('--debug', '-d', help="activate debug logging", dest='debug', action='store_true') - parser.add_argument('--firstItemsLog', '-1', - help="path to file where for each item type the first time it was found and where will be written (spoilers!)", - nargs='?', default=None, type=str, dest='firstItemsLog') - parser.add_argument('--ext_stats', help="Generate extended stats", - nargs='?', default=None, dest='extStatsFilename') - parser.add_argument('--ext_stats_step', help="what extended stats to generate", - nargs='?', default=None, dest='extStatsStep', type=int) - parser.add_argument('--displayGeneratedPath', '-g', help="display the generated path (spoilers!)", - dest='displayGeneratedPath', action='store_true') - parser.add_argument('--race', help="Race mode magic number", dest='raceMagic', type=int) - parser.add_argument('--vcr', help="Generate VCR output file", dest='vcr', action='store_true') - # standard/interactive, web site - parser.add_argument('--output', '-o', help="When called from the website, contains the result of the solver", - dest='output', nargs='?', default=None) - # interactive, web site - parser.add_argument('--interactive', '-i', help="Activate interactive mode for the solver", - dest='interactive', action='store_true') - parser.add_argument('--state', help="JSON file of the Solver state (used in interactive mode)", - dest="state", nargs='?', default=None) - parser.add_argument('--loc', help="Name of the location to action on (used in interactive mode)", - dest="loc", nargs='?', default=None) - parser.add_argument('--action', help="Pickup item at location, remove last pickedup location, clear all (used in interactive mode)", - dest="action", nargs="?", default=None, choices=['init', 'add', 'remove', 'clear', 'get', 'save', 'replace', 'randomize', 'toggle', 'import']) - parser.add_argument('--item', help="Name of the item to place in plando mode (used in interactive mode)", - dest="item", nargs='?', default=None) - parser.add_argument('--hide', help="Hide the item to place in plando mode (used in interactive mode)", - dest="hide", action='store_true') - parser.add_argument('--startPoint', help="The start AP to connect (used in interactive mode)", - dest="startPoint", nargs='?', default=None) - parser.add_argument('--endPoint', help="The destination AP to connect (used in interactive mode)", - dest="endPoint", nargs='?', default=None) - - parser.add_argument('--mode', help="Solver mode: standard/seedless/plando (used in interactive mode)", - dest="mode", nargs="?", default=None, choices=['standard', 'seedless', 'plando', 'race', 'debug']) - parser.add_argument('--scope', help="Scope for the action: common/area/item (used in interactive mode)", - dest="scope", nargs="?", default=None, choices=['common', 'area', 'item', 'door', 'dump']) - parser.add_argument('--count', help="Number of item rollback (used in interactive mode)", - dest="count", type=int) - parser.add_argument('--lock', help="lock the plando seed (used in interactive mode)", - dest="lock", action='store_true') - parser.add_argument('--escapeTimer', help="escape timer like 03:00", dest="escapeTimer", default=None) - parser.add_argument('--fill', help="in plando load all the source seed locations/transitions as a base (used in interactive mode)", - dest="fill", action='store_true') - parser.add_argument('--startLocation', help="in plando/seedless: the start location", dest="startLocation", default="Landing Site") - parser.add_argument('--minorQty', help="rando plando (used in interactive mode)", - dest="minorQty", nargs="?", default=None, choices=[str(i) for i in range(0,101)]) - parser.add_argument('--energyQty', help="rando plando (used in interactive mode)", - dest="energyQty", nargs="?", default=None, choices=["sparse", "medium", "vanilla"]) - parser.add_argument('--forbiddenItems', help="rando plando (used in interactive mode)", - dest="forbiddenItems", nargs="?", default=None) - parser.add_argument('--doorName', help="door to replace (used in interactive mode)", - dest="doorName", nargs="?", default=None) - parser.add_argument('--newColor', help="new color for door (used in interactive mode)", - dest="newColor", nargs="?", default=None) - parser.add_argument('--logic', help='logic to use (used in interactive mode)', dest='logic', nargs='?', default="vanilla", choices=["vanilla", "rotation"]) - parser.add_argument('--runtime', - help="Maximum runtime limit in seconds. If 0 or negative, no runtime limit.", - dest='runtimeLimit_s', nargs='?', default=0, type=int) - parser.add_argument('--dump', help="dump file with autotracker state (used in interactive mode)", - dest="dump", nargs="?", default=None) - - args = parser.parse_args() - - if args.presetFileName is None: - args.presetFileName = 'worlds/sm/variaRandomizer/standard_presets/regular.json' - - if args.raceMagic != None: - if args.raceMagic <= 0 or args.raceMagic >= 0x10000: - print("Invalid magic") - sys.exit(-1) - - if args.count != None: - if args.count < 1 or args.count > 0x80: - print("Invalid count") - sys.exit(-1) - - utils.log.init(args.debug) - - if args.interactive == True: - interactiveSolver(args) - else: - standardSolver(args) diff --git a/worlds/sm/variaRandomizer/standard_presets/Torneio_SGPT3.json b/worlds/sm/variaRandomizer/standard_presets/Torneio_SGPT3.json new file mode 100644 index 00000000..7e141439 --- /dev/null +++ b/worlds/sm/variaRandomizer/standard_presets/Torneio_SGPT3.json @@ -0,0 +1 @@ +{"Knows": {"WallJump": [true, 1], "ShineSpark": [true, 1], "MidAirMorph": [true, 1], "CrouchJump": [true, 1], "UnequipItem": [true, 1], "Mockball": [true, 1], "SimpleShortCharge": [true, 1], "InfiniteBombJump": [true, 1], "GreenGateGlitch": [true, 1], "ShortCharge": [false, 0], "GravityJump": [true, 1], "SpringBallJump": [true, 10], "SpringBallJumpFromWall": [true, 10], "GetAroundWallJump": [true, 1], "DraygonGrappleKill": [true, 1], "DraygonSparkKill": [false, 0], "MicrowaveDraygon": [true, 1], "MicrowavePhantoon": [true, 1], "LowAmmoCroc": [false, 0], "LowStuffBotwoon": [false, 0], "LowStuffGT": [false, 0], "IceZebSkip": [false, 0], "SpeedZebSkip": [false, 0], "HiJumpMamaTurtle": [false, 0], "MaridiaWallJumps": [false, 0], "MtEverestGravJump": [false, 0], "GravLessLevel1": [true, 10], "GravLessLevel2": [false, 0], "GravLessLevel3": [false, 0], "CeilingDBoost": [true, 1], "BillyMays": [true, 1], "AlcatrazEscape": [true, 1], "ReverseGateGlitch": [true, 1], "ReverseGateGlitchHiJumpLess": [true, 1], "EarlyKraid": [true, 1], "XrayDboost": [false, 0], "XrayIce": [false, 0], "RedTowerClimb": [true, 1], "RonPopeilScrew": [false, 0], "OldMBWithSpeed": [false, 0], "Moondance": [false, 0], "HiJumpLessGauntletAccess": [true, 1], "HiJumpGauntletAccess": [true, 1], "LowGauntlet": [false, 0], "IceEscape": [false, 0], "WallJumpCathedralExit": [true, 1], "BubbleMountainWallJump": [true, 1], "DoubleChamberWallJump": [false, 0], "NovaBoost": [false, 0], "NorfairReserveDBoost": [false, 0], "CrocPBsDBoost": [false, 0], "CrocPBsIce": [false, 0], "IceMissileFromCroc": [false, 0], "FrogSpeedwayWithoutSpeed": [false, 0], "LavaDive": [true, 1], "LavaDiveNoHiJump": [false, 0], "WorstRoomIceCharge": [false, 0], "WorstRoomWallJump": [false, 0], "ScrewAttackExit": [false, 0], "ScrewAttackExitWithoutScrew": [false, 0], "FirefleasWalljump": [false, 0], "DodgeLowerNorfairEnemies": [false, 0], "ContinuousWallJump": [true, 10], "DiagonalBombJump": [false, 0], "MockballWs": [true, 10], "SpongeBathBombJump": [false, 0], "SpongeBathHiJump": [true, 1], "SpongeBathSpeed": [true, 1], "TediousMountEverest": [false, 0], "DoubleSpringBallJump": [false, 0], "BotwoonToDraygonWithIce": [false, 0], "WestSandHoleSuitlessWallJumps": [false, 0], "DraygonRoomGrappleExit": [false, 0], "DraygonRoomCrystalFlash": [false, 0], "PreciousRoomXRayExit": [false, 0], "PreciousRoomGravJumpExit": [false, 0], "MochtroidClip": [true, 1], "PuyoClip": [false, 0], "PuyoClipXRay": [false, 0], "SnailClip": [false, 0], "SuitlessPuyoClip": [false, 0], "CrystalFlashClip": [false, 0], "SuitlessCrystalFlashClip": [false, 0], "KillPlasmaPiratesWithSpark": [false, 0], "KillPlasmaPiratesWithCharge": [true, 10], "AccessSpringBallWithHiJump": [true, 1], "AccessSpringBallWithSpringBallBombJumps": [false, 0], "AccessSpringBallWithBombJumps": [false, 0], "AccessSpringBallWithSpringBallJump": [false, 0], "AccessSpringBallWithXRayClimb": [false, 0], "AccessSpringBallWithGravJump": [false, 0], "AccessSpringBallWithFlatley": [false, 0]}, "Settings": {"Ice": "Gimme energy", "MainUpperNorfair": "Gimme energy", "LowerNorfair": "Default", "Kraid": "Default", "Phantoon": "Default", "Draygon": "Default", "Ridley": "Default", "MotherBrain": "Default", "X-Ray": "I don't like spikes", "Gauntlet": "Default"}, "Controller": {"A": "Jump", "B": "Dash", "X": "Shoot", "Y": "Item Cancel", "L": "Angle Down", "R": "Angle Up", "Select": "Item Select", "Moonwalk": true}, "password": "3d7e88af5a2f11e552eb2f7dc747cb1cbc810649086020eef598913c38a0a08b", "score": 221} \ No newline at end of file diff --git a/worlds/sm/variaRandomizer/utils/doorsmanager.py b/worlds/sm/variaRandomizer/utils/doorsmanager.py index 0b2a4149..6a8ecda1 100644 --- a/worlds/sm/variaRandomizer/utils/doorsmanager.py +++ b/worlds/sm/variaRandomizer/utils/doorsmanager.py @@ -1,4 +1,5 @@ import random +from enum import IntEnum,IntFlag import copy from ..logic.smbool import SMBool from ..rom.rom_patches import RomPatches @@ -11,7 +12,7 @@ colorsList = ['red', 'green', 'yellow', 'wave', 'spazer', 'plasma', 'ice'] # 1/15 chance to have the door set to grey colorsListGrey = colorsList * 2 + ['grey'] -class Facing: +class Facing(IntEnum): Left = 0 Right = 1 Top = 2 @@ -38,9 +39,48 @@ colors2plm = { 'ice': plmIce } +# door color indicators PLMs (flashing on the other side of colored doors) +indicatorsDirection = { + Facing.Left: Facing.Right, + Facing.Right: Facing.Left, + Facing.Top: Facing.Bottom, + Facing.Bottom: Facing.Top +} + +# door facing left - right - top - bottom +plmRedIndicator = [0xFBB0, 0xFBB6, 0xFBBC, 0xFBC2] +plmGreenIndicator = [0xFBC8, 0xFBCE, 0xFBD4, 0xFBDA] +plmYellowIndicator = [0xFBE0, 0xFBE6, 0xFBEC, 0xFBF2] +plmGreyIndicator = [0xFBF8, 0xFBFE, 0xFC04, 0xFC0A] +plmWaveIndicator = [0xF60B, 0xF611, 0xF617, 0xF61D] +plmSpazerIndicator = [0xF63B, 0xF641, 0xF647, 0xF64D] +plmPlasmaIndicator = [0xF623, 0xF629, 0xF62F, 0xF635] +plmIceIndicator = [0xF653, 0xF659, 0xF65F, 0xF665] + +colors2plmIndicator = { + 'red': plmRedIndicator, + 'green': plmGreenIndicator, + 'yellow': plmYellowIndicator, + 'grey': plmGreyIndicator, + 'wave': plmWaveIndicator, + 'spazer': plmSpazerIndicator, + 'plasma': plmPlasmaIndicator, + 'ice': plmIceIndicator +} + +class IndicatorFlag(IntFlag): + Standard = 1 + AreaRando = 2 + DoorRando = 4 + +# indicator always there +IndicatorAll = IndicatorFlag.Standard | IndicatorFlag.AreaRando | IndicatorFlag.DoorRando +# indicator there when not in area rando +IndicatorDoor = IndicatorFlag.Standard | IndicatorFlag.DoorRando + class Door(object): - __slots__ = ('name', 'address', 'vanillaColor', 'color', 'forced', 'facing', 'hidden', 'id', 'canGrey', 'forbiddenColors') - def __init__(self, name, address, vanillaColor, facing, id=None, canGrey=False, forbiddenColors=None): + __slots__ = ('name', 'address', 'vanillaColor', 'color', 'forced', 'facing', 'hidden', 'id', 'canGrey', 'forbiddenColors','indicator') + def __init__(self, name, address, vanillaColor, facing, id=None, canGrey=False, forbiddenColors=None,indicator=0): self.name = name self.address = address self.vanillaColor = vanillaColor @@ -52,6 +92,7 @@ class Door(object): self.id = id # list of forbidden colors self.forbiddenColors = forbiddenColors + self.indicator = indicator def forceBlue(self): # custom start location, area, patches can force doors to blue @@ -115,21 +156,21 @@ class Door(object): def isRefillSave(self): return self.address is None - def writeColor(self, rom): + def writeColor(self, rom, writeWordFunc): if self.isBlue() or self.isRefillSave(): return - rom.writeWord(colors2plm[self.color][self.facing], self.address) + writeWordFunc(colors2plm[self.color][self.facing], self.address) # also set plm args high byte to never opened, even during escape if self.color == 'grey': rom.writeByte(0x90, self.address+5) - def readColor(self, rom): + def readColor(self, rom, readWordFunc): if self.forced or self.isRefillSave(): return - plm = rom.readWord(self.address) + plm = readWordFunc(self.address) if plm in plmRed: self.setColor('red') elif plm in plmGreen: @@ -147,7 +188,15 @@ class Door(object): elif plm in plmIce: self.setColor('ice') else: - raise Exception("Unknown color {} for {}".format(hex(plm), self.name)) + # we can't read the color, handle as grey door (can happen in race protected seeds) + self.setColor('grey') + + # gives the PLM ID for matching indicator door + def getIndicatorPLM(self, indicatorFlags): + ret = None + if (indicatorFlags & self.indicator) != 0 and self.color in colors2plmIndicator: + ret = colors2plmIndicator[self.color][indicatorsDirection[self.facing]] + return ret # for tracker def canHide(self): @@ -179,10 +228,10 @@ class DoorsManager(): doorsDict = {} doors = { # crateria - 'LandingSiteRight': Door('LandingSiteRight', 0x78018, 'green', Facing.Left, canGrey=True), + 'LandingSiteRight': Door('LandingSiteRight', 0x78018, 'green', Facing.Left, canGrey=True, indicator=IndicatorAll), 'LandingSiteTopRight': Door('LandingSiteTopRight', 0x07801e, 'yellow', Facing.Left), - 'KihunterBottom': Door('KihunterBottom', 0x78228, 'yellow', Facing.Top, canGrey=True), - 'KihunterRight': Door('KihunterRight', 0x78222, 'yellow', Facing.Left, canGrey=True), + 'KihunterBottom': Door('KihunterBottom', 0x78228, 'yellow', Facing.Top, canGrey=True, indicator=IndicatorDoor), + 'KihunterRight': Door('KihunterRight', 0x78222, 'yellow', Facing.Left, canGrey=True, indicator=IndicatorAll), 'FlywayRight': Door('FlywayRight', 0x78420, 'red', Facing.Left), 'GreenPiratesShaftBottomRight': Door('GreenPiratesShaftBottomRight', 0x78470, 'red', Facing.Left, canGrey=True), 'RedBrinstarElevatorTop': Door('RedBrinstarElevatorTop', 0x78256, 'yellow', Facing.Bottom), @@ -190,34 +239,34 @@ class DoorsManager(): # blue brinstar 'ConstructionZoneRight': Door('ConstructionZoneRight', 0x78784, 'red', Facing.Left), # green brinstar - 'GreenHillZoneTopRight': Door('GreenHillZoneTopRight', 0x78670, 'yellow', Facing.Left, canGrey=True), - 'NoobBridgeRight': Door('NoobBridgeRight', 0x787a6, 'green', Facing.Left, canGrey=True), + 'GreenHillZoneTopRight': Door('GreenHillZoneTopRight', 0x78670, 'yellow', Facing.Left, canGrey=True, indicator=IndicatorFlag.DoorRando), + 'NoobBridgeRight': Door('NoobBridgeRight', 0x787a6, 'green', Facing.Left, canGrey=True, indicator=IndicatorDoor), 'MainShaftRight': Door('MainShaftRight', 0x784be, 'red', Facing.Left), - 'MainShaftBottomRight': Door('MainShaftBottomRight', 0x784c4, 'red', Facing.Left, canGrey=True), + 'MainShaftBottomRight': Door('MainShaftBottomRight', 0x784c4, 'red', Facing.Left, canGrey=True, indicator=IndicatorAll), 'EarlySupersRight': Door('EarlySupersRight', 0x78512, 'red', Facing.Left), 'EtecoonEnergyTankLeft': Door('EtecoonEnergyTankLeft', 0x787c8, 'green', Facing.Right), # pink brinstar 'BigPinkTopRight': Door('BigPinkTopRight', 0x78626, 'red', Facing.Left), 'BigPinkRight': Door('BigPinkRight', 0x7861a, 'yellow', Facing.Left), - 'BigPinkBottomRight': Door('BigPinkBottomRight', 0x78620, 'green', Facing.Left, canGrey=True), + 'BigPinkBottomRight': Door('BigPinkBottomRight', 0x78620, 'green', Facing.Left, canGrey=True, indicator=IndicatorAll), 'BigPinkBottomLeft': Door('BigPinkBottomLeft', 0x7862c, 'red', Facing.Right), # red brinstar 'RedTowerLeft': Door('RedTowerLeft', 0x78866, 'yellow', Facing.Right), 'RedBrinstarFirefleaLeft': Door('RedBrinstarFirefleaLeft', 0x7886e, 'red', Facing.Right), 'RedTowerElevatorTopLeft': Door('RedTowerElevatorTopLeft', 0x788aa, 'green', Facing.Right), - 'RedTowerElevatorLeft': Door('RedTowerElevatorLeft', 0x788b0, 'yellow', Facing.Right), + 'RedTowerElevatorLeft': Door('RedTowerElevatorLeft', 0x788b0, 'yellow', Facing.Right, indicator=IndicatorAll), 'RedTowerElevatorBottomLeft': Door('RedTowerElevatorBottomLeft', 0x788b6, 'green', Facing.Right), 'BelowSpazerTopRight': Door('BelowSpazerTopRight', 0x78966, 'green', Facing.Left), # Wrecked ship - 'WestOceanRight': Door('WestOceanRight', 0x781e2, 'green', Facing.Left, canGrey=True), - 'LeCoudeBottom': Door('LeCoudeBottom', 0x7823e, 'yellow', Facing.Top, canGrey=True), - 'WreckedShipMainShaftBottom': Door('WreckedShipMainShaftBottom', 0x7c277, 'green', Facing.Top), + 'WestOceanRight': Door('WestOceanRight', 0x781e2, 'green', Facing.Left, canGrey=True, indicator=IndicatorAll), + 'LeCoudeBottom': Door('LeCoudeBottom', 0x7823e, 'yellow', Facing.Top, canGrey=True, indicator=IndicatorDoor), + 'WreckedShipMainShaftBottom': Door('WreckedShipMainShaftBottom', 0x7c277, 'green', Facing.Top, indicator=IndicatorFlag.AreaRando), 'ElectricDeathRoomTopLeft': Door('ElectricDeathRoomTopLeft', 0x7c32f, 'red', Facing.Right), # Upper Norfair 'BusinessCenterTopLeft': Door('BusinessCenterTopLeft', 0x78b00, 'green', Facing.Right), 'BusinessCenterBottomLeft': Door('BusinessCenterBottomLeft', 0x78b0c, 'red', Facing.Right), - 'CathedralEntranceRight': Door('CathedralEntranceRight', 0x78af2, 'red', Facing.Left, canGrey=True), - 'CathedralRight': Door('CathedralRight', 0x78aea, 'green', Facing.Left), + 'CathedralEntranceRight': Door('CathedralEntranceRight', 0x78af2, 'red', Facing.Left, canGrey=True, indicator=IndicatorAll), + 'CathedralRight': Door('CathedralRight', 0x78aea, 'green', Facing.Left, indicator=IndicatorAll), 'BubbleMountainTopRight': Door('BubbleMountainTopRight', 0x78c60, 'green', Facing.Left), 'BubbleMountainTopLeft': Door('BubbleMountainTopLeft', 0x78c5a, 'green', Facing.Right), 'SpeedBoosterHallRight': Door('SpeedBoosterHallRight', 0x78c7a, 'red', Facing.Left), @@ -229,13 +278,13 @@ class DoorsManager(): 'PostCrocomireUpperLeft': Door('PostCrocomireUpperLeft', 0x78bf4, 'red', Facing.Right), 'PostCrocomireShaftRight': Door('PostCrocomireShaftRight', 0x78c0c, 'red', Facing.Left), # Lower Norfair - 'RedKihunterShaftBottom': Door('RedKihunterShaftBottom', 0x7902e, 'yellow', Facing.Top), - 'WastelandLeft': Door('WastelandLeft', 0x790ba, 'green', Facing.Right, forbiddenColors=['yellow']), + 'RedKihunterShaftBottom': Door('RedKihunterShaftBottom', 0x7902e, 'yellow', Facing.Top, indicator=IndicatorFlag.AreaRando), + 'WastelandLeft': Door('WastelandLeft', 0x790ba, 'green', Facing.Right, forbiddenColors=['yellow'], indicator=IndicatorFlag.AreaRando), # Maridia - 'MainStreetBottomRight': Door('MainStreetBottomRight', 0x7c431, 'red', Facing.Left), + 'MainStreetBottomRight': Door('MainStreetBottomRight', 0x7c431, 'red', Facing.Left, indicator=IndicatorAll), 'FishTankRight': Door('FishTankRight', 0x7c475, 'red', Facing.Left), - 'CrabShaftRight': Door('CrabShaftRight', 0x7c4fb, 'green', Facing.Left), - 'ColosseumBottomRight': Door('ColosseumBottomRight', 0x7c6fb, 'green', Facing.Left), + 'CrabShaftRight': Door('CrabShaftRight', 0x7c4fb, 'green', Facing.Left, indicator=IndicatorDoor), + 'ColosseumBottomRight': Door('ColosseumBottomRight', 0x7c6fb, 'green', Facing.Left, indicator=IndicatorFlag.AreaRando), 'PlasmaSparkBottom': Door('PlasmaSparkBottom', 0x7c577, 'green', Facing.Top), 'OasisTop': Door('OasisTop', 0x7c5d3, 'green', Facing.Bottom), # refill/save @@ -310,12 +359,12 @@ class DoorsManager(): # call from rom loader @staticmethod - def loadDoorsColor(rom): + def loadDoorsColor(rom, readWordFunc): # force to blue some doors depending on patches DoorsManager.setDoorsColor() # for each door store it's color for door in DoorsManager.doors.values(): - door.readColor(rom) + door.readColor(rom, readWordFunc) DoorsManager.debugDoorsColor() # tell that we have randomized doors @@ -342,13 +391,24 @@ class DoorsManager(): # call from rom patcher @staticmethod - def writeDoorsColor(rom, doors, player): + def writeDoorsColor(rom, doors, player, readWordFunc): for door in DoorsManager.doorsDict[player].values(): - door.writeColor(rom) + door.writeColor(rom, readWordFunc) # also set save/refill doors to blue if door.id is not None: doors.append(door.id) + # returns a dict {'DoorName': indicatorPlmType } + @staticmethod + def getIndicatorPLMs(player, indicatorFlags): + ret = {} + for doorName,door in DoorsManager.doorsDict[player].items(): + plm = door.getIndicatorPLM(indicatorFlags) + if plm is not None: + ret[doorName] = plm + return ret + + # call from web @staticmethod def getAddressesToRead(): diff --git a/worlds/sm/variaRandomizer/utils/objectives.py b/worlds/sm/variaRandomizer/utils/objectives.py new file mode 100644 index 00000000..5f585b28 --- /dev/null +++ b/worlds/sm/variaRandomizer/utils/objectives.py @@ -0,0 +1,804 @@ +import copy +import random +from ..rom.addresses import Addresses +from ..rom.rom import pc_to_snes +from ..logic.helpers import Bosses +from ..logic.smbool import SMBool +from ..logic.logic import Logic +from ..graph.location import locationsDict +from ..utils.parameters import Knows +from ..utils import log +import logging + +LOG = log.get('Objectives') + +class Synonyms(object): + killSynonyms = [ + "defeat", + "massacre", + "slay", + "wipe out", + "erase", + "finish", + "destroy", + "wreck", + "smash", + "crush", + "end" + ] + alreadyUsed = [] + @staticmethod + def getVerb(): + verb = random.choice(Synonyms.killSynonyms) + while verb in Synonyms.alreadyUsed: + verb = random.choice(Synonyms.killSynonyms) + Synonyms.alreadyUsed.append(verb) + return verb + +class Goal(object): + def __init__(self, name, gtype, logicClearFunc, romClearFunc, + escapeAccessPoints=None, objCompletedFuncAPs=lambda ap: [ap], + exclusion=None, items=None, text=None, introText=None, + available=True, expandableList=None, category=None, area=None, + conflictFunc=None): + self.name = name + self.available = available + self.clearFunc = logicClearFunc + self.objCompletedFuncAPs = objCompletedFuncAPs + # SNES addr in bank A1, see objectives.asm + self.checkAddr = pc_to_snes(Addresses.getOne("objective[%s]" % romClearFunc)) & 0xffff + self.escapeAccessPoints = escapeAccessPoints + if self.escapeAccessPoints is None: + self.escapeAccessPoints = (1, []) + self.rank = -1 + # possible values: + # - boss + # - miniboss + # - other + self.gtype = gtype + # example for kill three g4 + # { + # "list": [list of objectives], + # "type: "boss", + # "limit": 2 + # } + self.exclusion = exclusion + if self.exclusion is None: + self.exclusion = {"list": []} + self.items = items + if self.items is None: + self.items = [] + self.text = name if text is None else text + self.introText = introText + self.useSynonym = text is not None + self.expandableList = expandableList + if self.expandableList is None: + self.expandableList = [] + self.expandable = len(self.expandableList) > 0 + self.category = category + self.area = area + self.conflictFunc = conflictFunc + # used by solver/isolver to know if a goal has been completed + self.completed = False + + def setRank(self, rank): + self.rank = rank + + def canClearGoal(self, smbm, ap=None): + # not all objectives require an ap (like limit objectives) + return self.clearFunc(smbm, ap) + + def getText(self): + out = "{}. ".format(self.rank) + if self.useSynonym: + out += self.text.format(Synonyms.getVerb()) + else: + out += self.text + assert len(out) <= 28, "Goal text '{}' is too long: {}, max 28".format(out, len(out)) + if self.introText is not None: + self.introText = "%d. %s" % (self.rank, self.introText) + else: + self.introText = out + return out + + def getIntroText(self): + assert self.introText is not None + return self.introText + + def isLimit(self): + return "type" in self.exclusion + + def __repr__(self): + return self.name + +def getBossEscapeAccessPoint(boss): + return (1, [Bosses.accessPoints[boss]]) + +def getG4EscapeAccessPoints(n): + return (n, [Bosses.accessPoints[boss] for boss in Bosses.Golden4()]) + +def getMiniBossesEscapeAccessPoints(n): + return (n, [Bosses.accessPoints[boss] for boss in Bosses.miniBosses()]) + +def getAreaEscapeAccessPoints(area): + return (1, list({list(loc.AccessFrom.keys())[0] for loc in Logic.locations if loc.GraphArea == area})) + +_goalsList = [ + Goal("kill kraid", "boss", lambda sm, ap: Bosses.bossDead(sm, 'Kraid'), "kraid_is_dead", + escapeAccessPoints=getBossEscapeAccessPoint("Kraid"), + exclusion={"list": ["kill all G4", "kill one G4"]}, + items=["Kraid"], + text="{} kraid", + category="Bosses"), + Goal("kill phantoon", "boss", lambda sm, ap: Bosses.bossDead(sm, 'Phantoon'), "phantoon_is_dead", + escapeAccessPoints=getBossEscapeAccessPoint("Phantoon"), + exclusion={"list": ["kill all G4", "kill one G4"]}, + items=["Phantoon"], + text="{} phantoon", + category="Bosses"), + Goal("kill draygon", "boss", lambda sm, ap: Bosses.bossDead(sm, 'Draygon'), "draygon_is_dead", + escapeAccessPoints=getBossEscapeAccessPoint("Draygon"), + exclusion={"list": ["kill all G4", "kill one G4"]}, + items=["Draygon"], + text="{} draygon", + category="Bosses"), + Goal("kill ridley", "boss", lambda sm, ap: Bosses.bossDead(sm, 'Ridley'), "ridley_is_dead", + escapeAccessPoints=getBossEscapeAccessPoint("Ridley"), + exclusion={"list": ["kill all G4", "kill one G4"]}, + items=["Ridley"], + text="{} ridley", + category="Bosses"), + Goal("kill one G4", "other", lambda sm, ap: Bosses.xBossesDead(sm, 1), "boss_1_killed", + escapeAccessPoints=getG4EscapeAccessPoints(1), + exclusion={"list": ["kill kraid", "kill phantoon", "kill draygon", "kill ridley", + "kill all G4", "kill two G4", "kill three G4"], + "type": "boss", + "limit": 0}, + text="{} one golden4", + category="Bosses"), + Goal("kill two G4", "other", lambda sm, ap: Bosses.xBossesDead(sm, 2), "boss_2_killed", + escapeAccessPoints=getG4EscapeAccessPoints(2), + exclusion={"list": ["kill all G4", "kill one G4", "kill three G4"], + "type": "boss", + "limit": 1}, + text="{} two golden4", + category="Bosses"), + Goal("kill three G4", "other", lambda sm, ap: Bosses.xBossesDead(sm, 3), "boss_3_killed", + escapeAccessPoints=getG4EscapeAccessPoints(3), + exclusion={"list": ["kill all G4", "kill one G4", "kill two G4"], + "type": "boss", + "limit": 2}, + text="{} three golden4", + category="Bosses"), + Goal("kill all G4", "other", lambda sm, ap: Bosses.allBossesDead(sm), "all_g4_dead", + escapeAccessPoints=getG4EscapeAccessPoints(4), + exclusion={"list": ["kill kraid", "kill phantoon", "kill draygon", "kill ridley", "kill one G4", "kill two G4", "kill three G4"]}, + items=["Kraid", "Phantoon", "Draygon", "Ridley"], + text="{} all golden4", + expandableList=["kill kraid", "kill phantoon", "kill draygon", "kill ridley"], + category="Bosses"), + Goal("kill spore spawn", "miniboss", lambda sm, ap: Bosses.bossDead(sm, 'SporeSpawn'), "spore_spawn_is_dead", + escapeAccessPoints=getBossEscapeAccessPoint("SporeSpawn"), + exclusion={"list": ["kill all mini bosses", "kill one miniboss"]}, + items=["SporeSpawn"], + text="{} spore spawn", + category="Minibosses"), + Goal("kill botwoon", "miniboss", lambda sm, ap: Bosses.bossDead(sm, 'Botwoon'), "botwoon_is_dead", + escapeAccessPoints=getBossEscapeAccessPoint("Botwoon"), + exclusion={"list": ["kill all mini bosses", "kill one miniboss"]}, + items=["Botwoon"], + text="{} botwoon", + category="Minibosses"), + Goal("kill crocomire", "miniboss", lambda sm, ap: Bosses.bossDead(sm, 'Crocomire'), "crocomire_is_dead", + escapeAccessPoints=getBossEscapeAccessPoint("Crocomire"), + exclusion={"list": ["kill all mini bosses", "kill one miniboss"]}, + items=["Crocomire"], + text="{} crocomire", + category="Minibosses"), + Goal("kill golden torizo", "miniboss", lambda sm, ap: Bosses.bossDead(sm, 'GoldenTorizo'), "golden_torizo_is_dead", + escapeAccessPoints=getBossEscapeAccessPoint("GoldenTorizo"), + exclusion={"list": ["kill all mini bosses", "kill one miniboss"]}, + items=["GoldenTorizo"], + text="{} golden torizo", + category="Minibosses", + conflictFunc=lambda settings, player: settings.qty['energy'] == 'ultra sparse' and (not Knows.knowsDict[player].LowStuffGT or (Knows.knowsDict[player].LowStuffGT.difficulty > settings.maxDiff))), + Goal("kill one miniboss", "other", lambda sm, ap: Bosses.xMiniBossesDead(sm, 1), "miniboss_1_killed", + escapeAccessPoints=getMiniBossesEscapeAccessPoints(1), + exclusion={"list": ["kill spore spawn", "kill botwoon", "kill crocomire", "kill golden torizo", + "kill all mini bosses", "kill two minibosses", "kill three minibosses"], + "type": "miniboss", + "limit": 0}, + text="{} one miniboss", + category="Minibosses"), + Goal("kill two minibosses", "other", lambda sm, ap: Bosses.xMiniBossesDead(sm, 2), "miniboss_2_killed", + escapeAccessPoints=getMiniBossesEscapeAccessPoints(2), + exclusion={"list": ["kill all mini bosses", "kill one miniboss", "kill three minibosses"], + "type": "miniboss", + "limit": 1}, + text="{} two minibosses", + category="Minibosses"), + Goal("kill three minibosses", "other", lambda sm, ap: Bosses.xMiniBossesDead(sm, 3), "miniboss_3_killed", + escapeAccessPoints=getMiniBossesEscapeAccessPoints(3), + exclusion={"list": ["kill all mini bosses", "kill one miniboss", "kill two minibosses"], + "type": "miniboss", + "limit": 2}, + text="{} three minibosses", + category="Minibosses"), + Goal("kill all mini bosses", "other", lambda sm, ap: Bosses.allMiniBossesDead(sm), "all_mini_bosses_dead", + escapeAccessPoints=getMiniBossesEscapeAccessPoints(4), + exclusion={"list": ["kill spore spawn", "kill botwoon", "kill crocomire", "kill golden torizo", + "kill one miniboss", "kill two minibosses", "kill three minibosses"]}, + items=["SporeSpawn", "Botwoon", "Crocomire", "GoldenTorizo"], + text="{} all mini bosses", + expandableList=["kill spore spawn", "kill botwoon", "kill crocomire", "kill golden torizo"], + category="Minibosses", + conflictFunc=lambda settings, player: settings.qty['energy'] == 'ultra sparse' and (not Knows.knowsDict[player].LowStuffGT or (Knows.knowsDict[player].LowStuffGT.difficulty > settings.maxDiff))), + # not available in AP + #Goal("finish scavenger hunt", "other", lambda sm, ap: SMBool(True), "scavenger_hunt_completed", + # exclusion={"list": []}, # will be auto-completed + # available=False), + Goal("nothing", "other", lambda sm, ap: Objectives.objDict[sm.player].canAccess(sm, ap, "Landing Site"), "nothing_objective", + escapeAccessPoints=(1, ["Landing Site"])), # with no objectives at all, escape auto triggers only in crateria + Goal("collect 25% items", "items", lambda sm, ap: SMBool(True), "collect_25_items", + exclusion={"list": ["collect 50% items", "collect 75% items", "collect 100% items"]}, + category="Items", + introText="collect 25 percent of items"), + Goal("collect 50% items", "items", lambda sm, ap: SMBool(True), "collect_50_items", + exclusion={"list": ["collect 25% items", "collect 75% items", "collect 100% items"]}, + category="Items", + introText="collect 50 percent of items"), + Goal("collect 75% items", "items", lambda sm, ap: SMBool(True), "collect_75_items", + exclusion={"list": ["collect 25% items", "collect 50% items", "collect 100% items"]}, + category="Items", + introText="collect 75 percent of items"), + Goal("collect 100% items", "items", lambda sm, ap: SMBool(True), "collect_100_items", + exclusion={"list": ["collect 25% items", "collect 50% items", "collect 75% items", "collect all upgrades"]}, + category="Items", + introText="collect all items"), + Goal("collect all upgrades", "items", lambda sm, ap: SMBool(True), "all_major_items", + category="Items"), + Goal("clear crateria", "items", lambda sm, ap: SMBool(True), "crateria_cleared", + category="Items", + area="Crateria"), + Goal("clear green brinstar", "items", lambda sm, ap: SMBool(True), "green_brin_cleared", + category="Items", + area="GreenPinkBrinstar"), + Goal("clear red brinstar", "items", lambda sm, ap: SMBool(True), "red_brin_cleared", + category="Items", + area="RedBrinstar"), + Goal("clear wrecked ship", "items", lambda sm, ap: SMBool(True), "ws_cleared", + category="Items", + area="WreckedShip"), + Goal("clear kraid's lair", "items", lambda sm, ap: SMBool(True), "kraid_cleared", + category="Items", + area="Kraid"), + Goal("clear upper norfair", "items", lambda sm, ap: SMBool(True), "upper_norfair_cleared", + category="Items", + area="Norfair"), + Goal("clear croc's lair", "items", lambda sm, ap: SMBool(True), "croc_cleared", + category="Items", + area="Crocomire"), + Goal("clear lower norfair", "items", lambda sm, ap: SMBool(True), "lower_norfair_cleared", + category="Items", + area="LowerNorfair"), + Goal("clear west maridia", "items", lambda sm, ap: SMBool(True), "west_maridia_cleared", + category="Items", + area="WestMaridia"), + Goal("clear east maridia", "items", lambda sm, ap: SMBool(True), "east_maridia_cleared", + category="Items", + area="EastMaridia"), + Goal("tickle the red fish", "other", + lambda sm, ap: sm.wand(sm.haveItem('Grapple'), Objectives.objDict[sm.player].canAccess(sm, ap, "Red Fish Room Bottom")), + "fish_tickled", + escapeAccessPoints=(1, ["Red Fish Room Bottom"]), + objCompletedFuncAPs=lambda ap: ["Red Fish Room Bottom"], + category="Memes"), + Goal("kill the orange geemer", "other", + lambda sm, ap: sm.wand(Objectives.objDict[sm.player].canAccess(sm, ap, "Bowling"), # XXX this unnecessarily adds canPassBowling as requirement + sm.wor(sm.haveItem('Wave'), sm.canUsePowerBombs())), + "orange_geemer", + escapeAccessPoints=(1, ["Bowling"]), + objCompletedFuncAPs=lambda ap: ["Bowling"], + text="{} orange geemer", + category="Memes"), + Goal("kill shaktool", "other", + lambda sm, ap: sm.wand(Objectives.objDict[sm.player].canAccess(sm, ap, "Oasis Bottom"), + sm.canTraverseSandPits(), + sm.canAccessShaktoolFromPantsRoom()), + "shak_dead", + escapeAccessPoints=(1, ["Oasis Bottom"]), + objCompletedFuncAPs=lambda ap: ["Oasis Bottom"], + text="{} shaktool", + category="Memes"), + Goal("activate chozo robots", "other", lambda sm, ap: sm.wand(Objectives.objDict[sm.player].canAccessLocation(sm, ap, "Bomb"), + Objectives.objDict[sm.player].canAccessLocation(sm, ap, "Gravity Suit"), + sm.haveItem("GoldenTorizo"), + sm.canPassLowerNorfairChozo()), # graph access implied by GT loc + "all_chozo_robots", + category="Memes", + escapeAccessPoints=(3, ["Landing Site", "Screw Attack Bottom", "Bowling"]), + objCompletedFuncAPs=lambda ap: ["Landing Site", "Screw Attack Bottom", "Bowling"], + exclusion={"list": ["kill golden torizo"]}, + conflictFunc=lambda settings, player: settings.qty['energy'] == 'ultra sparse' and (not Knows.knowsDict[player].LowStuffGT or (Knows.knowsDict[player].LowStuffGT.difficulty > settings.maxDiff))), + Goal("visit the animals", "other", lambda sm, ap: sm.wand(Objectives.objDict[sm.player].canAccess(sm, ap, "Big Pink"), sm.haveItem("SpeedBooster"), # dachora + Objectives.objDict[sm.player].canAccess(sm, ap, "Etecoons Bottom")), # Etecoons + "visited_animals", + category="Memes", + escapeAccessPoints=(2, ["Big Pink", "Etecoons Bottom"]), + objCompletedFuncAPs=lambda ap: ["Big Pink", "Etecoons Bottom"]), + Goal("kill king cacatac", "other", + lambda sm, ap: Objectives.objDict[sm.player].canAccess(sm, ap, 'Bubble Mountain Top'), + "king_cac_dead", + category="Memes", + escapeAccessPoints=(1, ['Bubble Mountain Top']), + objCompletedFuncAPs=lambda ap: ['Bubble Mountain Top']) +] + + +_goals = {goal.name:goal for goal in _goalsList} + +def completeGoalData(): + # "nothing" is incompatible with everything + _goals["nothing"].exclusion["list"] = [goal.name for goal in _goalsList] + areaGoals = [goal.name for goal in _goalsList if goal.area is not None] + # if we need 100% items, don't require "clear area", as it covers those + _goals["collect 100% items"].exclusion["list"] += areaGoals[:] + # if we have scav hunt, don't require "clear area" (HUD behaviour incompatibility) + # not available in AP + #_goals["finish scavenger hunt"].exclusion["list"] += areaGoals[:] + # remove clear area goals if disabled tourian, as escape can trigger as soon as an area is cleared, + # even if ship is not currently reachable + for goal in areaGoals: + _goals[goal].exclusion['tourian'] = "Disabled" + +completeGoalData() + +class Objectives(object): + maxActiveGoals = 5 + vanillaGoals = ["kill kraid", "kill phantoon", "kill draygon", "kill ridley"] + scavHuntGoal = ["finish scavenger hunt"] + objDict = {} + + def __init__(self, player=0, tourianRequired=True, randoSettings=None): + self.player = player + self.activeGoals = [] + self.nbActiveGoals = 0 + self.totalItemsCount = 100 + self.goals = copy.deepcopy(_goals) + self.graph = None + self._tourianRequired = tourianRequired + self.randoSettings = randoSettings + Objectives.objDict[player] = self + + @property + def tourianRequired(self): + assert self._tourianRequired is not None + return self._tourianRequired + + def resetGoals(self): + self.activeGoals = [] + self.nbActiveGoals = 0 + + def conflict(self, newGoal): + if newGoal.exclusion.get('tourian') == "Disabled" and self.tourianRequired == False: + LOG.debug("new goal %s conflicts with disabled Tourian" % newGoal.name) + return True + LOG.debug("check if new goal {} conflicts with existing active goals".format(newGoal.name)) + count = 0 + for goal in self.activeGoals: + if newGoal.name in goal.exclusion["list"]: + LOG.debug("new goal {} in exclusion list of active goal {}".format(newGoal.name, goal.name)) + return True + if goal.name in newGoal.exclusion["list"]: + LOG.debug("active goal {} in exclusion list of new goal {}".format(goal.name, newGoal.name)) + return True + # count bosses/minibosses already active if new goal has a limit + if newGoal.exclusion.get("type") == goal.gtype: + count += 1 + LOG.debug("new goal limit type: {} same as active goal {}. count: {}".format(newGoal.exclusion["type"], goal.name, count)) + if count > newGoal.exclusion.get("limit", 0): + LOG.debug("new goal {} limit {} is lower than active goals of type: {}".format(newGoal.name, newGoal.exclusion["limit"], newGoal.exclusion["type"])) + return True + LOG.debug("no direct conflict detected for new goal {}".format(newGoal.name)) + + # if at least one active goal has a limit and new goal has the same type of one of the existing limit + # check that new goal doesn't exceed the limit + for goal in self.activeGoals: + goalExclusionType = goal.exclusion.get("type") + if goalExclusionType is not None and goalExclusionType == newGoal.gtype: + count = 0 + for lgoal in self.activeGoals: + if lgoal.gtype == newGoal.gtype: + count += 1 + # add new goal to the count + if count >= goal.exclusion["limit"]: + LOG.debug("new Goal {} would excess limit {} of active goal {}".format(newGoal.name, goal.exclusion["limit"], goal.name)) + return True + + LOG.debug("no backward conflict detected for new goal {}".format(newGoal.name)) + + if self.randoSettings is not None and newGoal.conflictFunc is not None: + if newGoal.conflictFunc(self.randoSettings, self.player): + LOG.debug("new Goal {} is conflicting with rando settings".format(newGoal.name)) + return True + LOG.debug("no conflict with rando settings detected for new goal {}".format(newGoal.name)) + + return False + + def addGoal(self, goalName, completed=False): + LOG.debug("addGoal: {}".format(goalName)) + goal = self.goals[goalName] + if self.conflict(goal): + return + self.nbActiveGoals += 1 + assert self.nbActiveGoals <= self.maxActiveGoals, "Too many active goals" + goal.setRank(self.nbActiveGoals) + goal.completed = completed + self.activeGoals.append(goal) + + def removeGoal(self, goal): + self.nbActiveGoals -= 1 + self.activeGoals.remove(goal) + + def clearGoals(self): + self.nbActiveGoals = 0 + self.activeGoals.clear() + + def isGoalActive(self, goalName): + return self.goals[goalName] in self.activeGoals + + # having graph as a global sucks but Objectives instances are all over the place, + # goals must access it, and it doesn't change often + def setGraph(self, graph, maxDiff): + self.graph = graph + self.maxDiff = maxDiff + for goalName, goal in self.goals.items(): + if goal.area is not None: + goal.escapeAccessPoints = getAreaEscapeAccessPoints(goal.area) + + def canAccess(self, sm, src, dst): + return SMBool(self.graph.canAccess(sm, src, dst, self.maxDiff)) + + def canAccessLocation(self, sm, ap, locName): + loc = locationsDict[locName] + availLocs = self.graph.getAvailableLocations([loc], sm, self.maxDiff, ap) + return SMBool(loc in availLocs) + + def setVanilla(self): + for goal in self.vanillaGoals: + self.addGoal(goal) + + def isVanilla(self): + # kill G4 and/or scav hunt + if len(self.activeGoals) == 1: + for goal in self.activeGoals: + if goal.name not in self.scavHuntGoal: + return False + return True + elif len(self.activeGoals) == 4: + for goal in self.activeGoals: + if goal.name not in self.vanillaGoals: + return False + return True + elif len(self.activeGoals) == 5: + for goal in self.activeGoals: + if goal.name not in self.vanillaGoals + self.scavHuntGoal: + return False + return True + else: + return False + + def setScavengerHunt(self): + self.addGoal("finish scavenger hunt") + + def updateScavengerEscapeAccess(self, ap): + assert self.isGoalActive("finish scavenger hunt") + (_, apList) = self.goals['finish scavenger hunt'].escapeAccessPoints + apList.append(ap) + + def _replaceEscapeAccessPoints(self, goal, aps): + (_, apList) = self.goals[goal].escapeAccessPoints + apList.clear() + apList += aps + + def updateItemPercentEscapeAccess(self, collectedLocsAccessPoints): + for pct in [25,50,75,100]: + goal = 'collect %d%% items' % pct + self._replaceEscapeAccessPoints(goal, collectedLocsAccessPoints) + # not exactly accurate, but player has all upgrades to escape + self._replaceEscapeAccessPoints("collect all upgrades", collectedLocsAccessPoints) + + def setScavengerHuntFunc(self, scavClearFunc): + self.goals["finish scavenger hunt"].clearFunc = scavClearFunc + + def setItemPercentFuncs(self, totalItemsCount=None, allUpgradeTypes=None): + def getPctFunc(pct, totalItemsCount): + def f(sm, ap): + nonlocal pct, totalItemsCount + return sm.hasItemsPercent(pct, totalItemsCount) + return f + + for pct in [25,50,75,100]: + goal = 'collect %d%% items' % pct + self.goals[goal].clearFunc = getPctFunc(pct, totalItemsCount) + if allUpgradeTypes is not None: + self.goals["collect all upgrades"].clearFunc = lambda sm, ap: sm.haveItems(allUpgradeTypes) + + def setAreaFuncs(self, funcsByArea): + goalsByArea = {goal.area:goal for goalName, goal in self.goals.items()} + for area, func in funcsByArea.items(): + if area in goalsByArea: + goalsByArea[area].clearFunc = func + + def setSolverMode(self, solver): + self.setScavengerHuntFunc(solver.scavengerHuntComplete) + # in rando we know the number of items after randomizing, so set the functions only for the solver + self.setItemPercentFuncs(allUpgradeTypes=solver.majorUpgrades) + + def getObjAreaFunc(area): + def f(sm, ap): + nonlocal solver, area + visitedLocs = set([loc.Name for loc in solver.visitedLocations]) + return SMBool(all(locName in visitedLocs for locName in solver.splitLocsByArea[area])) + return f + self.setAreaFuncs({area:getObjAreaFunc(area) for area in solver.splitLocsByArea}) + + def expandGoals(self): + LOG.debug("Active goals:"+str(self.activeGoals)) + # try to replace 'kill all G4' with the four associated objectives. + # we need at least 3 empty objectives out of the max (-1 +4) + if self.maxActiveGoals - self.nbActiveGoals < 3: + return + + expandable = None + for goal in self.activeGoals: + if goal.expandable: + expandable = goal + break + + if expandable is None: + return + + LOG.debug("replace {} with {}".format(expandable.name, expandable.expandableList)) + self.removeGoal(expandable) + for name in expandable.expandableList: + self.addGoal(name) + + # rebuild ranks + for i, goal in enumerate(self.activeGoals, 1): + goal.rank = i + + # call from logic + def canClearGoals(self, smbm, ap): + result = SMBool(True) + for goal in self.activeGoals: + result = smbm.wand(result, goal.canClearGoal(smbm, ap)) + return result + + # call from solver + def checkGoals(self, smbm, ap): + ret = {} + + for goal in self.activeGoals: + if goal.completed is True: + continue + # check if goal can be completed + ret[goal.name] = goal.canClearGoal(smbm, ap) + + return ret + + def setGoalCompleted(self, goalName, completed): + for goal in self.activeGoals: + if goal.name == goalName: + goal.completed = completed + return + assert False, "Can't set goal {} completion to {}, goal not active".format(goalName, completed) + + def allGoalsCompleted(self): + for goal in self.activeGoals: + if goal.completed is False: + return False + return True + + def getGoalFromCheckFunction(self, checkFunction): + for name, goal in self.goals.items(): + if goal.checkAddr == checkFunction: + return goal + assert True, "Goal with check function {} not found".format(hex(checkFunction)) + + def getTotalItemsCount(self): + return self.totalItemsCount + + # call from web + def getAddressesToRead(self): + terminator = 1 + objectiveSize = 2 + bytesToRead = (self.maxActiveGoals + terminator) * objectiveSize + return [Addresses.getOne('objectivesList')+i for i in range(0, bytesToRead+1)] + Addresses.getWeb('totalItems') + Addresses.getWeb("itemsMask") + Addresses.getWeb("beamsMask") + + def getExclusions(self): + # to compute exclusions in the front end + return {goalName: goal.exclusion for goalName, goal in self.goals.items()} + + def getObjectivesTypes(self): + # to compute exclusions in the front end + types = {'boss': [], 'miniboss': []} + for goalName, goal in self.goals.items(): + if goal.gtype in types: + types[goal.gtype].append(goalName) + return types + + def getObjectivesSort(self): + return list(self.goals.keys()) + + def getObjectivesCategories(self): + return {goal.name: goal.category for goal in self.goals.values() if goal.category is not None} + + # call from rando check pool and solver + + def getMandatoryBosses(self): + r = [goal.items for goal in self.activeGoals] + return [item for items in r for item in items] + + def checkLimitObjectives(self, beatableBosses): + # check that there's enough bosses/minibosses for limit objectives + from ..logic.smboolmanager import SMBoolManager + smbm = SMBoolManager(self.player) + smbm.addItems(beatableBosses) + for goal in self.activeGoals: + if not goal.isLimit(): + continue + if not goal.canClearGoal(smbm): + return False + return True + + # call from solver + def getGoalsList(self): + return [goal.name for goal in self.activeGoals] + + # call from interactivesolver + def getState(self): + return {goal.name: goal.completed for goal in self.activeGoals} + + def setState(self, state): + for goalName, completed in state.items(): + self.addGoal(goalName, completed) + + def resetGoals(self): + for goal in self.activeGoals: + goal.completed = False + + # call from rando + @staticmethod + def getAllGoals(removeNothing=False): + return [goal.name for goal in _goals.values() if goal.available and (not removeNothing or goal.name != "nothing")] + + # call from rando + def setRandom(self, nbGoals, availableGoals): + while self.nbActiveGoals < nbGoals and availableGoals: + goalName = random.choice(availableGoals) + self.addGoal(goalName) + availableGoals.remove(goalName) + + # call from solver + def readGoals(self, romReader): + self.resetGoals() + romReader.romFile.seek(Addresses.getOne('objectivesList')) + checkFunction = romReader.romFile.readWord() + while checkFunction != 0x0000: + goal = self.getGoalFromCheckFunction(checkFunction) + self.activeGoals.append(goal) + checkFunction = romReader.romFile.readWord() + + # read number of available items for items % objectives + self.totalItemsCount = romReader.romFile.readByte(Addresses.getOne('totalItems')) + + for goal in self.activeGoals: + LOG.debug("active goal: {}".format(goal.name)) + + self._tourianRequired = not romReader.patchPresent('Escape_Trigger') + LOG.debug("tourianRequired: {}".format(self.tourianRequired)) + + # call from rando + def writeGoals(self, romFile): + # write check functions + romFile.seek(Addresses.getOne('objectivesList')) + for goal in self.activeGoals: + romFile.writeWord(goal.checkAddr) + # list terminator + romFile.writeWord(0x0000) + + # compute chars + char2tile = { + '.': 0x4A, + '?': 0x4B, + '!': 0x4C, + ' ': 0x00, + '%': 0x02, + '*': 0x03, + '0': 0x04, + 'a': 0x30, + } + for i in range(1, ord('z')-ord('a')+1): + char2tile[chr(ord('a')+i)] = char2tile['a']+i + for i in range(1, ord('9')-ord('0')+1): + char2tile[chr(ord('0')+i)] = char2tile['0']+i + + # write text + tileSize = 2 + lineLength = 32 * tileSize + firstChar = 3 * tileSize + # start at 8th line + baseAddr = Addresses.getOne('objectivesText') + lineLength * 8 + firstChar + # space between two lines of text + space = 3 if self.nbActiveGoals == 5 else 4 + for i, goal in enumerate(self.activeGoals): + addr = baseAddr + i * lineLength * space + text = goal.getText() + romFile.seek(addr) + for c in text: + if c not in char2tile: + continue + romFile.writeWord(0x3800 + char2tile[c]) + + # write goal completed positions y in sprites OAM + baseY = 0x40 + addr = Addresses.getOne('objectivesSpritesOAM') + spritemapSize = 5 + 2 + for i, goal in enumerate(self.activeGoals): + y = baseY + i * space * 8 + # sprite center is at 128 + y = (y - 128) & 0xFF + romFile.writeByte(y, addr+4 + i*spritemapSize) + + def writeIntroObjectives(self, rom, tourian): + if self.isVanilla() and tourian == "Vanilla": + return + # objectives or tourian are not vanilla, prepare intro text + # two \n for an actual newline + text = "MISSION OBJECTIVES\n" + for goal in self.activeGoals: + text += "\n\n%s" % goal.getIntroText() + text += "\n\n\nTOURIAN IS %s\n\n\n" % tourian + text += "CHECK OBJECTIVES STATUS IN\n\n" + text += "THE PAUSE SCREEN" + # actually write text in ROM + self._writeIntroText(rom, text.upper()) + + def _writeIntroText(self, rom, text, startX=1, startY=2): + # for character translation + charCodes = { + ' ': 0xD67D, + '.': 0xD75D, + '!': 0xD77B, + "'": 0xD76F, + '0': 0xD721, + 'A': 0xD685 + } + def addCharRange(start, end, base): # inclusive range + for c in range(ord(start), ord(end)+1): + offset = c - ord(base) + charCodes[chr(c)] = charCodes[base]+offset*6 + addCharRange('B', 'Z', 'A') + addCharRange('1', '9', '0') + # actually write chars + x, y = startX, startY + def writeChar(c, frameDelay=2): + nonlocal rom, x, y + assert x <= 0x1F and y <= 0x18, "Intro text formatting error (x=0x%x, y=0x%x):\n%s" % (x, y, text) + if c == '\n': + x = startX + y += 1 + else: + assert c in charCodes, "Invalid intro char "+c + rom.writeWord(frameDelay) + rom.writeByte(x) + rom.writeByte(y) + rom.writeWord(charCodes[c]) + x += 1 + rom.seek(Addresses.getOne('introText')) + for c in text: + writeChar(c) + # write trailer, see intro_text.asm + rom.writeWord(0xAE5B) + rom.writeWord(0x9698) diff --git a/worlds/sm/variaRandomizer/utils/parameters.py b/worlds/sm/variaRandomizer/utils/parameters.py index 2d9313b5..4d9079a6 100644 --- a/worlds/sm/variaRandomizer/utils/parameters.py +++ b/worlds/sm/variaRandomizer/utils/parameters.py @@ -46,19 +46,19 @@ text2diff = { def diff4solver(difficulty): if difficulty == -1: - return "break" + return ("break", "break") elif difficulty < medium: - return "easy" + return ("easy", "easy") elif difficulty < hard: - return "medium" + return ("medium", "medium") elif difficulty < harder: - return "hard" + return ("hard", "hard") elif difficulty < hardcore: - return "harder" + return ("harder", "very hard") elif difficulty < mania: - return "hardcore" + return ("hardcore", "hardcore") else: - return "mania" + return ("mania", "mania") # allow multiple local repo appDir = str(Path(__file__).parents[4]) @@ -120,7 +120,7 @@ class Knows: Mockball = SMBool(True, easy, ['Mockball']) desc['Mockball'] = {'display': 'Mockball', - 'title': 'Morph from runing without loosing momentum to get Early Super and Ice Beam', + 'title': 'Morph from running without loosing momentum to get Early Super and Ice Beam', 'href': 'https://wiki.supermetroid.run/index.php?title=Mockball', 'rooms': ['Early Supers Room', 'Ice Beam Gate Room']} @@ -161,7 +161,7 @@ class Knows: SpringBallJump = SMBool(True, hard, ['SpringBallJump']) desc['SpringBallJump'] = {'display': 'SpringBall-Jump', 'title': 'Do a SpringBall Jump from a jump to Access to Wrecked Ship Etank without anything else, Suitless Maridia navigation', - 'href': 'https://www.youtube.com/watch?v=8ldQUIgBavw&t=49s', + 'href': 'https://www.twitch.tv/videos/147442861', 'rooms': ['Sponge Bath', 'East Ocean', 'Main Street', 'Crab Shaft', 'Pseudo Plasma Spark Room', 'Mama Turtle Room', 'The Precious Room', 'Spring Ball Room', 'East Sand Hole', diff --git a/worlds/sm/variaRandomizer/utils/utils.py b/worlds/sm/variaRandomizer/utils/utils.py index 46c14a16..08a8e037 100644 --- a/worlds/sm/variaRandomizer/utils/utils.py +++ b/worlds/sm/variaRandomizer/utils/utils.py @@ -56,7 +56,7 @@ def exists(resource: str): return os.path.exists(resource) def isStdPreset(preset): - return preset in ['newbie', 'casual', 'regular', 'veteran', 'expert', 'master', 'samus', 'solution', 'Season_Races', 'SMRAT2021'] + return preset in ['newbie', 'casual', 'regular', 'veteran', 'expert', 'master', 'samus', 'solution', 'Season_Races', 'SMRAT2021', 'Torneio_SGPT3'] def getPresetDir(preset) -> str: if isStdPreset(preset): @@ -316,6 +316,7 @@ class PresetLoaderDict(PresetLoader): def getDefaultMultiValues(): from ..graph.graph_utils import GraphUtils + from ..utils.objectives import Objectives defaultMultiValues = { 'startLocation': GraphUtils.getStartAccessPointNames(), 'majorsSplit': ['Full', 'FullWithHUD', 'Major', 'Chozo', 'Scavenger'], @@ -323,7 +324,10 @@ def getDefaultMultiValues(): 'progressionDifficulty': ['easier', 'normal', 'harder'], 'morphPlacement': ['early', 'normal'], #['early', 'late', 'normal'], 'energyQty': ['ultra sparse', 'sparse', 'medium', 'vanilla'], - 'gravityBehaviour': ['Vanilla', 'Balanced', 'Progressive'] + 'gravityBehaviour': ['Vanilla', 'Balanced', 'Progressive'], + 'areaRandomization': ['off', 'full', 'light'], + 'objective': Objectives.getAllGoals(removeNothing=True), + 'tourian': ['Vanilla', 'Fast', 'Disabled'] } return defaultMultiValues @@ -363,17 +367,16 @@ def loadRandoPreset(world, player, args): args.noVariaTweaks = not world.varia_tweaks[player].value args.maxDifficulty = diffs[world.max_difficulty[player].value] #args.suitsRestriction = world.suits_restriction[player].value - #args.hideItems = world.hide_items[player].value + args.hideItems = world.hide_items[player].value args.strictMinors = world.strict_minors[player].value args.noLayout = not world.layout_patches[player].value args.gravityBehaviour = defaultMultiValues["gravityBehaviour"][world.gravity_behaviour[player].value] args.nerfedCharge = world.nerfed_charge[player].value - args.area = world.area_randomization[player].value != 0 - if args.area: + args.area = world.area_randomization[player].current_key + if args.area != "off": args.areaLayoutBase = not world.area_layout[player].value - args.lightArea = world.area_randomization[player].value == 1 - #args.escapeRando - #args.noRemoveEscapeEnemies + args.escapeRando = world.escape_rando[player].value + args.noRemoveEscapeEnemies = not world.remove_escape_enemies[player].value args.doorsColorsRando = world.doors_colors_rando[player].value args.allowGreyDoors = world.allow_grey_doors[player].value args.bosses = world.boss_randomization[player].value @@ -384,7 +387,12 @@ def loadRandoPreset(world, player, args): if world.fun_suits[player].value: args.superFun.append("Suits") - ipsPatches = {"spin_jump_restart":"spinjumprestart", "rando_speed":"rando_speed", "elevators_doors_speed":"elevators_doors_speed", "refill_before_save":"refill_before_save"} + ipsPatches = { "spin_jump_restart":"spinjumprestart", + "rando_speed":"rando_speed", + "elevators_speed":"elevators_speed", + "fast_doors":"fast_doors", + "refill_before_save":"refill_before_save", + "relaxed_round_robin_cf":"relaxed_round_robin_cf"} for settingName, patchName in ipsPatches.items(): if hasattr(world, settingName) and getattr(world, settingName)[player].value: args.patches.append(patchName + '.ips') @@ -399,7 +407,6 @@ def loadRandoPreset(world, player, args): #args.majorsSplit #args.scavNumLocs #args.scavRandomized - #args.scavEscape args.startLocation = defaultMultiValues["startLocation"][world.start_location[player].value] #args.progressionDifficulty #args.progressionSpeed @@ -408,6 +415,8 @@ def loadRandoPreset(world, player, args): args.powerBombQty = world.power_bomb_qty[player].value / float(10) args.minorQty = world.minor_qty[player].value args.energyQty = defaultMultiValues["energyQty"][world.energy_qty[player].value] + args.objective = world.objective[player].value + args.tourian = defaultMultiValues["tourian"][world.tourian[player].value] #args.minimizerN #args.minimizerTourian @@ -425,7 +434,6 @@ def getRandomizerDefaultParameters(): defaultParams['majorsSplitMultiSelect'] = defaultMultiValues['majorsSplit'] defaultParams['scavNumLocs'] = "10" defaultParams['scavRandomized'] = "off" - defaultParams['scavEscape'] = "off" defaultParams['startLocation'] = "Landing Site" defaultParams['startLocationMultiSelect'] = defaultMultiValues['startLocation'] defaultParams['maxDifficulty'] = 'hardcore' @@ -444,9 +452,13 @@ def getRandomizerDefaultParameters(): defaultParams['minorQty'] = "100" defaultParams['energyQty'] = "vanilla" defaultParams['energyQtyMultiSelect'] = defaultMultiValues['energyQty'] + defaultParams['objectiveRandom'] = "off" + defaultParams['nbObjective'] = "4" + defaultParams['objective'] = ["kill all G4"] + defaultParams['objectiveMultiSelect'] = defaultMultiValues['objective'] + defaultParams['tourian'] = "Vanilla" defaultParams['areaRandomization'] = "off" defaultParams['areaLayout'] = "off" - defaultParams['lightAreaRandomization'] = "off" defaultParams['doorsColorsRando'] = "off" defaultParams['allowGreyDoors'] = "off" defaultParams['escapeRando'] = "off" @@ -454,7 +466,6 @@ def getRandomizerDefaultParameters(): defaultParams['bossRandomization'] = "off" defaultParams['minimizer'] = "off" defaultParams['minimizerQty'] = "45" - defaultParams['minimizerTourian'] = "off" defaultParams['funCombat'] = "off" defaultParams['funMovement'] = "off" defaultParams['funSuits'] = "off" @@ -463,8 +474,10 @@ def getRandomizerDefaultParameters(): defaultParams['gravityBehaviour'] = "Balanced" defaultParams['gravityBehaviourMultiSelect'] = defaultMultiValues['gravityBehaviour'] defaultParams['nerfedCharge'] = "off" + defaultParams['relaxed_round_robin_cf'] = "off" defaultParams['itemsounds'] = "on" - defaultParams['elevators_doors_speed'] = "on" + defaultParams['elevators_speed'] = "on" + defaultParams['fast_doors'] = "on" defaultParams['spinjumprestart'] = "off" defaultParams['rando_speed'] = "off" defaultParams['Infinite_Space_Jump'] = "off" @@ -496,4 +509,22 @@ def fixEnergy(items): items.append('{}-ETank'.format(maxETank)) if maxReserve > 0: items.append('{}-Reserve'.format(maxReserve)) + + + # keep biggest crystal flash + cfs = [i for i in items if i.find('CrystalFlash') != -1] + if len(cfs) > 1: + maxCf = 0 + for cf in cfs: + nCf = int(cf[0:cf.find('-CrystalFlash')]) + if nCf > maxCf: + maxCf = nCf + items.remove(cf) + items.append('{}-CrystalFlash'.format(maxCf)) return items + +def dumpErrorMsg(outFileName, msg): + print("DIAG: " + msg) + if outFileName is not None: + with open(outFileName, 'w') as jsonFile: + json.dump({"errorMsg": msg}, jsonFile) \ No newline at end of file diff --git a/worlds/sm/variaRandomizer/utils/version.py b/worlds/sm/variaRandomizer/utils/version.py index 686ade28..1c736c26 100644 --- a/worlds/sm/variaRandomizer/utils/version.py +++ b/worlds/sm/variaRandomizer/utils/version.py @@ -1,3 +1,5 @@ +import Utils + # version displayed on the title screen, must be a max 32 chars [a-z0-9.-] string # either 'beta' or 'r.yyyy.mm.dd' -displayedVersion = 'beta' +displayedVersion = 'r.2022.11.01-ap.' + Utils.__version__