diff options
Diffstat (limited to 'util/narcparser.py')
-rw-r--r-- | util/narcparser.py | 660 |
1 files changed, 330 insertions, 330 deletions
diff --git a/util/narcparser.py b/util/narcparser.py index a14548d..7c7d0de 100644 --- a/util/narcparser.py +++ b/util/narcparser.py @@ -1,331 +1,331 @@ -import argparse, sys, os - -def main(): - try: - with open(sys.argv[1],"rb") as f: - word = f.read(4) - while word != b'BTAF': - word = f.read(4) - table_length = read_word(f) - file_count = read_word(f) - file_offsets = [] - for i in range(file_count): - file_offsets.append(read_word(f)) - f.seek(4,os.SEEK_CUR) - print(str(i) + ": ",end='') - print_hex_word(file_offsets[i]) - f.seek(-4,os.SEEK_CUR) - file_offsets.append(read_word(f)) - word = f.read(4) - while word != b'GMIF': - word = f.read(4) - file_table_length = read_word(f) - file_table_offset = f.tell() - print("File table length: ",end='') - print_hex_word(file_table_length) - print("File table offset: ",end='') - print_hex_word(file_table_offset) - readline = "" - print("Ready to search. Enter help for list of commands") - while readline != "quit": - readline = input('Enter command: ') - args = readline.split() - if args[0] == "help": - list_commands() - elif args[0] == "sr": # Search - if len(args) < 2: - print("Usage: sr x") - print("x should be a hexadecimal number") - else: - if args[1][:2] == "0x": - target = int(args[1][2:],16) - else: - target = int(args[1],16) - upper_byte = 0 - if target % 2**32 > 2**8: - upper_byte = target >> 8 - target = target & 0xFF - for i in range(file_count): - f.seek(file_table_offset + file_offsets[i]) - local_offset_in_file = read_word(f) - first_global_offset = f.tell() + local_offset_in_file - while local_offset_in_file & 0xFFFF != 0xFD13 and f.tell() - 4 < first_global_offset: - offset_in_file = f.tell() + local_offset_in_file - return_position = f.tell() - f.seek(offset_in_file) - data = 0 - while data != 0x02002F and f.tell() < file_table_offset + file_offsets[i+1]: - data = read_byte(f) - if data == target: - if upper_byte == 0: - print("Found target value in file " + str(i) + " at offset ",end='') - print_hex_word(f.tell()) - else: - data = read_byte(f) - f.seek(-1,os.SEEK_CUR) - if data == upper_byte: - print("Found target value in file " + str(i) + " at offset ",end='') - print_hex_word(f.tell()) - if data == 0x2F: - f.seek(-1,os.SEEK_CUR) - data = read_word(f) - if data != 0x02002F: - f.seek(-3,os.SEEK_CUR) - f.seek(return_position) - local_offset_in_file = read_word(f) - elif args[0] == "msr": # Multiple search - if len(args) < 2: - print("Usage: msr x [y z ...]") - print("x, y, z ... should be hexadecimal numbers") - else: - target = [] - upper_byte = [] - for i in range(1,len(args)): - if args[i][:2] == "0x": - target.append(int(args[i][2:],16)) - else: - target.append(int(args[i],16)) - if target[i-1] % 2**32 > 2**8: - upper_byte.append(target[i-1] >> 8) - target[i-1] = target[i-1] & 0xFF - else: - upper_byte.append(0) - for i in range(file_count): - found_in_file = [] - f.seek(file_table_offset + file_offsets[i]) - local_offset_in_file = read_word(f) - first_global_offset = f.tell() + local_offset_in_file - while local_offset_in_file & 0xFFFF != 0xFD13 and f.tell() - 4 < first_global_offset: - offset_in_file = f.tell() + local_offset_in_file - return_position = f.tell() - f.seek(offset_in_file) - data = 0 - while data != 0x02002F and f.tell() < file_table_offset + file_offsets[i+1]: - data = read_byte(f) - for j,t in enumerate(target): - if data == t: - if upper_byte[j] == 0: - found_in_file.append((t,f.tell())) - else: - data = read_byte(f) - f.seek(-1,os.SEEK_CUR) - if data == upper_byte[j]: - found_in_file.append((t + (upper_byte[j] << 8),f.tell()-1)) - if data == 0x2F: - f.seek(-1,os.SEEK_CUR) - data = read_word(f) - if data != 0x02002F: - f.seek(-3,os.SEEK_CUR) - f.seek(return_position) - local_offset_in_file = read_word(f) - if len(found_in_file) >= 1: - target_copy = target.copy() - for (val,_) in found_in_file: - for j,t in enumerate(target_copy): - if val == t + (upper_byte[j] << 8): - target_copy.remove(t) - if len(target_copy) == 0: - print("Found in file " + str(i) + ": ") - for (val,offset) in found_in_file: - print_hex(val,'') - print(" at offset ",end='') - print_hex_word(offset) - elif args[0] == "rsr": # Raw search - if len(args) < 2: - print("Usage: rsr x") - print("x should be a hexadecimal number") - else: - if args[1][:2] == "0x": - target = int(args[1][2:],16) - else: - target = int(args[1],16) - upper_byte = 0 - if target % 2**32 > 2**8: - upper_byte = target >> 8 - target = target & 0xFF - for i in range(file_count): - f.seek(file_table_offset + file_offsets[i]) - while f.tell() < file_table_offset + file_offsets[i+1]: - data = read_byte(f) - if data == target: - if upper_byte == 0: - print("Found target value in file " + str(i) + " at offset ",end='') - print_hex_word(f.tell()) - else: - data = read_byte(f) - f.seek(-1,os.SEEK_CUR) - if data == upper_byte: - print("Found target value in file " + str(i) + " at offset ",end='') - print_hex_word(f.tell()) - elif args[0] == "rmsr": # Raw multiple search - if len(args) < 2: - print("Usage: rmsr x [y z ...]") - print("x, y, z ... should be hexadecimal numbers") - else: - target = [] - upper_byte = [] - for i in range(1,len(args)): - if args[i][:2] == "0x": - target.append(int(args[i][2:],16)) - else: - target.append(int(args[i],16)) - if target[i-1] % 2**32 > 2**8: - upper_byte.append(target[i-1] >> 8) - target[i-1] = target[i-1] & 0xFF - else: - upper_byte.append(0) - for i in range(file_count): - found_in_file = [] - f.seek(file_table_offset + file_offsets[i]) - while f.tell() < file_table_offset + file_offsets[i+1]: - data = read_byte(f) - for j,t in enumerate(target): - if data == t: - if upper_byte[j] == 0: - found_in_file.append((t,f.tell())) - else: - data = read_byte(f) - f.seek(-1,os.SEEK_CUR) - if data == upper_byte[j]: - found_in_file.append((t + (upper_byte[j] << 8),f.tell()-1)) - if len(found_in_file) >= 1: - target_copy = target.copy() - for (val,_) in found_in_file: - for j,t in enumerate(target_copy): - if val == t + (upper_byte[j] << 8): - target_copy.remove(t) - if len(target_copy) == 0: - print("Found in file " + str(i) + ": ") - for (val,offset) in found_in_file: - print_hex(val,'') - print(" at offset ",end='') - print_hex_word(offset) - elif args[0] == "lsf": # List file - if len(args) < 2: - print("Usage: lsf fileno") - else: - print("Searching file " + args[1] + "!") - f.seek(file_table_offset + file_offsets[int(args[1])]) - local_offset_in_file = read_word(f) - first_global_offset = f.tell() + local_offset_in_file - while local_offset_in_file & 0xFFFF != 0xFD13 and f.tell() - 4 < first_global_offset: - offset_in_file = f.tell() + local_offset_in_file - print("Relative offset: 0x" + '%X' % local_offset_in_file + " read at 0x" + '%X' % (f.tell() - 4),end='') - print(", global offset: 0x" + '%X' % offset_in_file) - return_position = f.tell() - f.seek(offset_in_file) - data = 0 - while data != 0x02002F and f.tell() < file_table_offset + file_offsets[int(args[1])+1]: - data = read_byte(f) - print_hex_byte(data,'','') - print(' ',end='') - if data == 0x2F: - f.seek(-1,os.SEEK_CUR) - data = read_word(f) - if data == 0x02002F: - print_hex_byte(0x00,'','') - print(' ',end='') - print_hex_byte(0x02,'','') - print(' ',end='') - print_hex_byte(0x00,'','') - print(' ',end='') - else: - print_hex_byte(0x2F,'','') - print(' ',end='') - f.seek(-3,os.SEEK_CUR) - print("\n") - f.seek(return_position) - local_offset_in_file = read_word(f) - elif args[0] == "fof": # File offset - if len(args) < 2: - print("Usage: fof fileno") - else: - print("Offset for file " + args[1] + ": 0x" + '%X' % (file_table_offset + file_offsets[int(args[1])])) - elif args[0] == "srs": # Search static - if len(args) < 2: - print("Usage: srs index") - else: - if args[1][:2] == "0x": - target = int(args[1][2:],16) - else: - target = int(args[1],16) - for i in range(file_count): - f.seek(file_table_offset + file_offsets[i]) - local_offset_in_file = read_word(f) - first_global_offset = f.tell() + local_offset_in_file - while local_offset_in_file & 0xFFFF != 0xFD13 and f.tell() - 4 < first_global_offset: - offset_in_file = f.tell() + local_offset_in_file - return_position = f.tell() - f.seek(offset_in_file) - data = 0 - while data != 0x02002F and f.tell() < file_table_offset + file_offsets[i+1]: - data = read_byte(f) - if data == 0x2A: - f.seek(-1,os.SEEK_CUR) - data = read_word(f) - if data == 0x8000002A: - item = read_halfword(f) - if item == target: - print("Found item in file " + str(i) + " at offset 0x" + '%X' % (f.tell() - 2)) - else: - f.seek(-3,os.SEEK_CUR) - if data == 0x2F: - f.seek(-1,os.SEEK_CUR) - data = read_word(f) - if data != 0x02002F: - f.seek(-3,os.SEEK_CUR) - f.seek(return_position) - local_offset_in_file = read_word(f) - elif args[0] == "lsai": # List all items - if len(args) == 3: - range_start = int(args[1],16) - range_end = int(args[2],16) # 6A1564C - else: - range_start = 0 - range_end = file_count - with open("itemprices.txt","w") as it: - for i in range(range_start, range_end): - f.seek(file_table_offset + file_offsets[i]) - it.write("{" + str(i) + ", " + str(int.from_bytes(f.read(2),byteorder='little')) + "},\n") - #print("Item 0x" + '%X' % i + " price: " + str(int.from_bytes(f.read(2),byteorder='little') * 10)) - except IndexError: - print("Error: No file specified") - sys.exit(2) - except IOError: - print("Error: File does not exist") - sys.exit(2) - -def list_commands(): - print("") - print("List of commands:") - print(" help: You are here") - print(" sr: Search for a single hex value") - print(" msr: Search for multiple hex values, separated by spaces") - print(" rsr: Search for a single hex value, ignoring file structure") - print(" rmsr: Search for multiple hex values, separated by spaces, ignoring file structure") - print(" srs: Search for a static item (hex value). As a side effect, also lists hidden items") - print(" lsf: Search for a specific file (decimal value) and list its contents") - print(" fof: Show the base offset for a file") - print(" quit: Exit the program") - print("") - -def print_hex(hex_value,endsymbol='\n',prefix='0x'): - print(prefix + "{:X}".format(hex_value),end=endsymbol) - -def print_hex_byte(hex_value,endsymbol='\n',prefix='0x'): - print(prefix + "{:0>2X}".format(hex_value),end=endsymbol) - -def print_hex_word(hex_value,endsymbol='\n',prefix='0x'): - print(prefix + "{:0>8X}".format(hex_value),end=endsymbol) - -def read_byte(file): - return int.from_bytes(file.read(1),byteorder='little') - -def read_halfword(file): - return int.from_bytes(file.read(2),byteorder='little') - -def read_word(file): - return int.from_bytes(file.read(4),byteorder='little') - -if __name__ == "__main__": +import argparse, sys, os
+
+def main():
+ try:
+ with open(sys.argv[1],"rb") as f:
+ word = f.read(4)
+ while word != b'BTAF':
+ word = f.read(4)
+ table_length = read_word(f)
+ file_count = read_word(f)
+ file_offsets = []
+ for i in range(file_count):
+ file_offsets.append(read_word(f))
+ f.seek(4,os.SEEK_CUR)
+ print(str(i) + ": ",end='')
+ print_hex_word(file_offsets[i])
+ f.seek(-4,os.SEEK_CUR)
+ file_offsets.append(read_word(f))
+ word = f.read(4)
+ while word != b'GMIF':
+ word = f.read(4)
+ file_table_length = read_word(f)
+ file_table_offset = f.tell()
+ print("File table length: ",end='')
+ print_hex_word(file_table_length)
+ print("File table offset: ",end='')
+ print_hex_word(file_table_offset)
+ readline = ""
+ print("Ready to search. Enter help for list of commands")
+ while readline != "quit":
+ readline = input('Enter command: ')
+ args = readline.split()
+ if args[0] == "help":
+ list_commands()
+ elif args[0] == "sr": # Search
+ if len(args) < 2:
+ print("Usage: sr x")
+ print("x should be a hexadecimal number")
+ else:
+ if args[1][:2] == "0x":
+ target = int(args[1][2:],16)
+ else:
+ target = int(args[1],16)
+ upper_byte = 0
+ if target % 2**32 > 2**8:
+ upper_byte = target >> 8
+ target = target & 0xFF
+ for i in range(file_count):
+ f.seek(file_table_offset + file_offsets[i])
+ local_offset_in_file = read_word(f)
+ first_global_offset = f.tell() + local_offset_in_file
+ while local_offset_in_file & 0xFFFF != 0xFD13 and f.tell() - 4 < first_global_offset:
+ offset_in_file = f.tell() + local_offset_in_file
+ return_position = f.tell()
+ f.seek(offset_in_file)
+ data = 0
+ while data != 0x02002F and f.tell() < file_table_offset + file_offsets[i+1]:
+ data = read_byte(f)
+ if data == target:
+ if upper_byte == 0:
+ print("Found target value in file " + str(i) + " at offset ",end='')
+ print_hex_word(f.tell())
+ else:
+ data = read_byte(f)
+ f.seek(-1,os.SEEK_CUR)
+ if data == upper_byte:
+ print("Found target value in file " + str(i) + " at offset ",end='')
+ print_hex_word(f.tell())
+ if data == 0x2F:
+ f.seek(-1,os.SEEK_CUR)
+ data = read_word(f)
+ if data != 0x02002F:
+ f.seek(-3,os.SEEK_CUR)
+ f.seek(return_position)
+ local_offset_in_file = read_word(f)
+ elif args[0] == "msr": # Multiple search
+ if len(args) < 2:
+ print("Usage: msr x [y z ...]")
+ print("x, y, z ... should be hexadecimal numbers")
+ else:
+ target = []
+ upper_byte = []
+ for i in range(1,len(args)):
+ if args[i][:2] == "0x":
+ target.append(int(args[i][2:],16))
+ else:
+ target.append(int(args[i],16))
+ if target[i-1] % 2**32 > 2**8:
+ upper_byte.append(target[i-1] >> 8)
+ target[i-1] = target[i-1] & 0xFF
+ else:
+ upper_byte.append(0)
+ for i in range(file_count):
+ found_in_file = []
+ f.seek(file_table_offset + file_offsets[i])
+ local_offset_in_file = read_word(f)
+ first_global_offset = f.tell() + local_offset_in_file
+ while local_offset_in_file & 0xFFFF != 0xFD13 and f.tell() - 4 < first_global_offset:
+ offset_in_file = f.tell() + local_offset_in_file
+ return_position = f.tell()
+ f.seek(offset_in_file)
+ data = 0
+ while data != 0x02002F and f.tell() < file_table_offset + file_offsets[i+1]:
+ data = read_byte(f)
+ for j,t in enumerate(target):
+ if data == t:
+ if upper_byte[j] == 0:
+ found_in_file.append((t,f.tell()))
+ else:
+ data = read_byte(f)
+ f.seek(-1,os.SEEK_CUR)
+ if data == upper_byte[j]:
+ found_in_file.append((t + (upper_byte[j] << 8),f.tell()-1))
+ if data == 0x2F:
+ f.seek(-1,os.SEEK_CUR)
+ data = read_word(f)
+ if data != 0x02002F:
+ f.seek(-3,os.SEEK_CUR)
+ f.seek(return_position)
+ local_offset_in_file = read_word(f)
+ if len(found_in_file) >= 1:
+ target_copy = target.copy()
+ for (val,_) in found_in_file:
+ for j,t in enumerate(target_copy):
+ if val == t + (upper_byte[j] << 8):
+ target_copy.remove(t)
+ if len(target_copy) == 0:
+ print("Found in file " + str(i) + ": ")
+ for (val,offset) in found_in_file:
+ print_hex(val,'')
+ print(" at offset ",end='')
+ print_hex_word(offset)
+ elif args[0] == "rsr": # Raw search
+ if len(args) < 2:
+ print("Usage: rsr x")
+ print("x should be a hexadecimal number")
+ else:
+ if args[1][:2] == "0x":
+ target = int(args[1][2:],16)
+ else:
+ target = int(args[1],16)
+ upper_byte = 0
+ if target % 2**32 > 2**8:
+ upper_byte = target >> 8
+ target = target & 0xFF
+ for i in range(file_count):
+ f.seek(file_table_offset + file_offsets[i])
+ while f.tell() < file_table_offset + file_offsets[i+1]:
+ data = read_byte(f)
+ if data == target:
+ if upper_byte == 0:
+ print("Found target value in file " + str(i) + " at offset ",end='')
+ print_hex_word(f.tell())
+ else:
+ data = read_byte(f)
+ f.seek(-1,os.SEEK_CUR)
+ if data == upper_byte:
+ print("Found target value in file " + str(i) + " at offset ",end='')
+ print_hex_word(f.tell())
+ elif args[0] == "rmsr": # Raw multiple search
+ if len(args) < 2:
+ print("Usage: rmsr x [y z ...]")
+ print("x, y, z ... should be hexadecimal numbers")
+ else:
+ target = []
+ upper_byte = []
+ for i in range(1,len(args)):
+ if args[i][:2] == "0x":
+ target.append(int(args[i][2:],16))
+ else:
+ target.append(int(args[i],16))
+ if target[i-1] % 2**32 > 2**8:
+ upper_byte.append(target[i-1] >> 8)
+ target[i-1] = target[i-1] & 0xFF
+ else:
+ upper_byte.append(0)
+ for i in range(file_count):
+ found_in_file = []
+ f.seek(file_table_offset + file_offsets[i])
+ while f.tell() < file_table_offset + file_offsets[i+1]:
+ data = read_byte(f)
+ for j,t in enumerate(target):
+ if data == t:
+ if upper_byte[j] == 0:
+ found_in_file.append((t,f.tell()))
+ else:
+ data = read_byte(f)
+ f.seek(-1,os.SEEK_CUR)
+ if data == upper_byte[j]:
+ found_in_file.append((t + (upper_byte[j] << 8),f.tell()-1))
+ if len(found_in_file) >= 1:
+ target_copy = target.copy()
+ for (val,_) in found_in_file:
+ for j,t in enumerate(target_copy):
+ if val == t + (upper_byte[j] << 8):
+ target_copy.remove(t)
+ if len(target_copy) == 0:
+ print("Found in file " + str(i) + ": ")
+ for (val,offset) in found_in_file:
+ print_hex(val,'')
+ print(" at offset ",end='')
+ print_hex_word(offset)
+ elif args[0] == "lsf": # List file
+ if len(args) < 2:
+ print("Usage: lsf fileno")
+ else:
+ print("Searching file " + args[1] + "!")
+ f.seek(file_table_offset + file_offsets[int(args[1])])
+ local_offset_in_file = read_word(f)
+ first_global_offset = f.tell() + local_offset_in_file
+ while local_offset_in_file & 0xFFFF != 0xFD13 and f.tell() - 4 < first_global_offset:
+ offset_in_file = f.tell() + local_offset_in_file
+ print("Relative offset: 0x" + '%X' % local_offset_in_file + " read at 0x" + '%X' % (f.tell() - 4),end='')
+ print(", global offset: 0x" + '%X' % offset_in_file)
+ return_position = f.tell()
+ f.seek(offset_in_file)
+ data = 0
+ while data != 0x02002F and f.tell() < file_table_offset + file_offsets[int(args[1])+1]:
+ data = read_byte(f)
+ print_hex_byte(data,'','')
+ print(' ',end='')
+ if data == 0x2F:
+ f.seek(-1,os.SEEK_CUR)
+ data = read_word(f)
+ if data == 0x02002F:
+ print_hex_byte(0x00,'','')
+ print(' ',end='')
+ print_hex_byte(0x02,'','')
+ print(' ',end='')
+ print_hex_byte(0x00,'','')
+ print(' ',end='')
+ else:
+ print_hex_byte(0x2F,'','')
+ print(' ',end='')
+ f.seek(-3,os.SEEK_CUR)
+ print("\n")
+ f.seek(return_position)
+ local_offset_in_file = read_word(f)
+ elif args[0] == "fof": # File offset
+ if len(args) < 2:
+ print("Usage: fof fileno")
+ else:
+ print("Offset for file " + args[1] + ": 0x" + '%X' % (file_table_offset + file_offsets[int(args[1])]))
+ elif args[0] == "srs": # Search static
+ if len(args) < 2:
+ print("Usage: srs index")
+ else:
+ if args[1][:2] == "0x":
+ target = int(args[1][2:],16)
+ else:
+ target = int(args[1],16)
+ for i in range(file_count):
+ f.seek(file_table_offset + file_offsets[i])
+ local_offset_in_file = read_word(f)
+ first_global_offset = f.tell() + local_offset_in_file
+ while local_offset_in_file & 0xFFFF != 0xFD13 and f.tell() - 4 < first_global_offset:
+ offset_in_file = f.tell() + local_offset_in_file
+ return_position = f.tell()
+ f.seek(offset_in_file)
+ data = 0
+ while data != 0x02002F and f.tell() < file_table_offset + file_offsets[i+1]:
+ data = read_byte(f)
+ if data == 0x2A:
+ f.seek(-1,os.SEEK_CUR)
+ data = read_word(f)
+ if data == 0x8000002A:
+ item = read_halfword(f)
+ if item == target:
+ print("Found item in file " + str(i) + " at offset 0x" + '%X' % (f.tell() - 2))
+ else:
+ f.seek(-3,os.SEEK_CUR)
+ if data == 0x2F:
+ f.seek(-1,os.SEEK_CUR)
+ data = read_word(f)
+ if data != 0x02002F:
+ f.seek(-3,os.SEEK_CUR)
+ f.seek(return_position)
+ local_offset_in_file = read_word(f)
+ elif args[0] == "lsai": # List all items
+ if len(args) == 3:
+ range_start = int(args[1],16)
+ range_end = int(args[2],16) # 6A1564C
+ else:
+ range_start = 0
+ range_end = file_count
+ with open("itemprices.txt","w") as it:
+ for i in range(range_start, range_end):
+ f.seek(file_table_offset + file_offsets[i])
+ it.write("{" + str(i) + ", " + str(int.from_bytes(f.read(2),byteorder='little')) + "},\n")
+ #print("Item 0x" + '%X' % i + " price: " + str(int.from_bytes(f.read(2),byteorder='little') * 10))
+ except IndexError:
+ print("Error: No file specified")
+ sys.exit(2)
+ except IOError:
+ print("Error: File does not exist")
+ sys.exit(2)
+
+def list_commands():
+ print("")
+ print("List of commands:")
+ print(" help: You are here")
+ print(" sr: Search for a single hex value")
+ print(" msr: Search for multiple hex values, separated by spaces")
+ print(" rsr: Search for a single hex value, ignoring file structure")
+ print(" rmsr: Search for multiple hex values, separated by spaces, ignoring file structure")
+ print(" srs: Search for a static item (hex value). As a side effect, also lists hidden items")
+ print(" lsf: Search for a specific file (decimal value) and list its contents")
+ print(" fof: Show the base offset for a file")
+ print(" quit: Exit the program")
+ print("")
+
+def print_hex(hex_value,endsymbol='\n',prefix='0x'):
+ print(prefix + "{:X}".format(hex_value),end=endsymbol)
+
+def print_hex_byte(hex_value,endsymbol='\n',prefix='0x'):
+ print(prefix + "{:0>2X}".format(hex_value),end=endsymbol)
+
+def print_hex_word(hex_value,endsymbol='\n',prefix='0x'):
+ print(prefix + "{:0>8X}".format(hex_value),end=endsymbol)
+
+def read_byte(file):
+ return int.from_bytes(file.read(1),byteorder='little')
+
+def read_halfword(file):
+ return int.from_bytes(file.read(2),byteorder='little')
+
+def read_word(file):
+ return int.from_bytes(file.read(4),byteorder='little')
+
+if __name__ == "__main__":
main()
\ No newline at end of file |