diff --git a/DARE.py b/DARE.py index 90ad2d6075279791de4852795b7e1d2b7f175e76..1bc6e079d1aeeb6224e92202e1f7f0c75c6c1e71 100755 --- a/DARE.py +++ b/DARE.py @@ -5,70 +5,89 @@ File that implements DARE dice-system for my tabletop game import dice import codecs import copy +import random #####################---INIT AND UTILS---######################### abc = "abcdefghijklmnopqrstuvwxyz" + ##Inherit Dice, adds name support and latency (count) class SpecialDice(dice.Dice): def __init__(self, n, name): """init a special dice""" super().__init__(n) - self.name=str(name) - self.count=0 #number of time this dice was rerolled + self.name = str(name) + self.count = 0 # number of time this dice was rerolled return None - + def __str__(self): if self.value != None: - return self.name+str(self.n)+"["+str(self.value)+"]" + return self.name + str(self.n) + "[" + str(self.value) + "]" else: - return self.name+str(self.n) + return self.name + str(self.n) def __repr__(self): - return "SDice object : "+str(self) + return "SDice object : " + str(self) def __lt__(self, otherdice): return self.n <= otherdice.n + def roll(self): + """roll the dice""" + self.value = random.randrange(self.n) + 1 + self.count += 1 + return self.value + def softReset(self): - self.reset(); + self.reset() return None # I guess this is what u get when u don't do proper code dev lol # But hey, overriding is the future, right Java ? def HardReset(self): - self.reset(); - self.count = 0; + self.reset() + self.count = 0 return None -class LatencyQueue(): + +class LatencyQueue: def __init__(self): """init the Latency Queue""" self.queue = [] - + def add(self, elt): """put elt in the indexQueue""" self.queue.append(elt) - + def move(self): - ret = "TODO" + ret = [] + to_rem = [] + for e in self.queue: + if e.count == 0: + ret.append(e) + to_rem.append(e) + else: + e.count -= 1 + for e in to_rem: + self.queue.remove(e) return ret def __str__(self): return "TODO" def __repr__(self): - return "Latency Queue Object :"+str(self) + return "Latency Queue Object :" + str(self) + -#Prints the main art +# Prints the main art def art(): f = codecs.open("art", "r", encoding="utf-8") art = f.read() f.close() - print("\033[2J\033[0;0H",end="") + print("\033[2J\033[0;0H", end="") print(art) print( -""" + """ \033[38;5;148m\033[11;10H ██████ █████ ██████ ███████ \033[38;5;149m\033[12;10H ██ ██ ██ ██ ██ ██ ██ \033[38;5;150m\033[13;10H ██ ██ ███████ ██████ █████ @@ -78,640 +97,742 @@ def art(): ) return None -#Prints a line + +# Prints a line def line(): - print("\033[38;5;240m"+50*"-"+"\033[0m") + print("\033[38;5;240m" + 50 * "-" + "\033[0m") return None -ask_history=[] -#Asks the player which actions does he wants to do +ask_history = [] + + +# Asks the player which actions does he wants to do def ask(symbol): - out = input("\033[38;5;217m"+symbol+">\033[0m") + out = input("\033[38;5;217m" + symbol + ">\033[0m") return out -if __name__=="__main__": - from types import SimpleNamespace +from types import SimpleNamespace + +##INITVAR +COMMAND_LIST = {} +S = SimpleNamespace() +S.PHIdicepool = [] +S.PSIdicepool = [] +S.PDiceTray = dice.DiceTray() # PHI DiceTray +S.pDiceTray = dice.DiceTray() # pSI DiceTray +S.Latency = LatencyQueue() +S.thro = [] +S.name = "" +S.inroll = False + +# Namespace where S object can be at any moments reverted to its old self +Undoable = SimpleNamespace() +Undoable.S = S +Undoable.OldS = S +Undoable.RedoS = S + +# DEPRECATED +##S.PHIqueue = []#SpecialDice(2,"Ψ"),SpecialDice(6,"Ψ")] +##S.PSIqueue = []#SpecialDice(2,"Ψ"),SpecialDice(6,"Ψ")] +# - ##INITVAR - COMMAND_LIST={} - S = SimpleNamespace() - S.PHIdicepool = [] - S.PSIdicepool = [] - S.PDiceTray = dice.DiceTray() #PHI DiceTray - S.pDiceTray = dice.DiceTray() #pSI DiceTray - S.Latency = LatencyQueue() - S.thro = [] - S.name = "" - S.inroll = False +# S.PDiceTray.add(SpecialDice(2,"Ψ")) - #Namespace where S object can be at any moments reverted to its old self - Undoable = SimpleNamespace() - Undoable.S = S - Undoable.OldS = S - Undoable.RedoS = S +##INIT CLI +art() -#DEPRECATED - ##S.PHIqueue = []#SpecialDice(2,"Ψ"),SpecialDice(6,"Ψ")] - ##S.PSIqueue = []#SpecialDice(2,"Ψ"),SpecialDice(6,"Ψ")] -# - #S.PDiceTray.add(SpecialDice(2,"Ψ")) - - ##INIT CLI - art() - -#Badly prints mlist i think - def stupidPrint(mlist): - out = "" - for e in mlist: - out += str(e)+" " - return out - -#Print the actual dice tray. - def printDiceTray(): - #This function crash if more than 26 dice are thrown - #This won't ever happen, right ? - i = 0 - sumP = 0 - sumPMax = 0 - sump = 0 - sumpMax = 0 - for e in S.PDiceTray: - print("\t\033[38;5;217m"+abc[i]+"\033[38;5;10m"+e.name+str(e.n)+"["+"\033[0m"+str(e.value)+"\033[38;5;10m]" ,end="") - i+=1 - sumP += e.value - sumPMax += e.n - print("\n",end="") - for e in S.pDiceTray: - print("\t\033[38;5;217m"+abc[i]+"\033[38;5;159m"+e.name+str(e.n)+"["+"\033[0m"+str(e.value)+"\033[38;5;159m]" ,end="") - i+=1 - sump += e.value - sumpMax += e.n - print("\033[0m") - print("Sum of\033[38;5;10m PHI\033[0m dice is :\033[38;5;217m "+str(sumP)+"\033[0m.") - print("Sum of\033[38;5;159m PSI\033[0m dice is :\033[38;5;217m "+str(sump)+"\033[0m.") - #Todo : number of same dice - - print("\n") - def printallstat(S, ShowDiceTray=False): - print("\033[38;5;214m PHI \033[38;5;10m [ "+stupidPrint(S.PHIdicepool)+"]\033[0m " - ,end="") - print("\033[38;5;214m PSI \033[38;5;159m [ "+stupidPrint(S.PSIdicepool)+"]\033[0m " - ,end="") - - if ShowDiceTray: - print("\n\033[38;5;214m ROLL ") - printDiceTray() - - if ShowDiceTray and S.thro: - print("\033[38;5;242m DEL [ "+stupidPrint(S.thro)+"]\033[0m") +# Badly prints mlist i think +def stupidPrint(mlist): + out = "" + for e in mlist: + out += str(e) + " " + return out + + +# Print the actual dice tray. +def printDiceTray(): + # This function crash if more than 26 dice are thrown + # This won't ever happen, right ? + i = 0 + sumP = 0 + sumPMax = 0 + sump = 0 + sumpMax = 0 + for e in S.PDiceTray: + print( + "\t\033[38;5;217m" + + abc[i] + + "\033[38;5;10m" + + e.name + + str(e.n) + + "[" + + "\033[0m" + + str(e.value) + + "\033[38;5;10m]" + + str(e.count), + end="", + ) + i += 1 + sumP += e.value + sumPMax += e.n + print("\n", end="") + for e in S.pDiceTray: + print( + "\t\033[38;5;217m" + + abc[i] + + "\033[38;5;159m" + + e.name + + str(e.n) + + "[" + + "\033[0m" + + str(e.value) + + "\033[38;5;159m]" + + str(e.count), + end="", + ) + i += 1 + sump += e.value + sumpMax += e.n + print("\033[0m") + print( + "Sum of\033[38;5;10m PHI\033[0m dice is :\033[38;5;217m " + + str(sumP) + + "\033[0m." + ) + print( + "Sum of\033[38;5;159m PSI\033[0m dice is :\033[38;5;217m " + + str(sump) + + "\033[0m." + ) + # Todo : number of same dice + + print("\n") + + +def printallstat(S, ShowDiceTray=False): + print( + "\033[38;5;214m PHI \033[38;5;10m [ " + + stupidPrint(S.PHIdicepool) + + "]\033[0m ", + end="", + ) + print( + "\033[38;5;214m PSI \033[38;5;159m [ " + + stupidPrint(S.PSIdicepool) + + "]\033[0m ", + end="", + ) + + if ShowDiceTray: + print("\n\033[38;5;214m ROLL ") + printDiceTray() + + if ShowDiceTray and S.thro: + print("\033[38;5;242m DEL [ " + stupidPrint(S.thro) + "]\033[0m") + print("") + + if S.Latency.queue: + print("\033[38;5;214m LAT \033[38;5;242m [ ", end="") + for dice in S.Latency.queue: + print(dice.name + str(dice.n) + "(" + str(dice.count) + ") ", end="") + print("]\033[0m") # ##HELP - def helpDARE(args,S): - """ -USAGE : help [command name] -Show command list. If invoked with command name as -an argument, then show command's usage and -descritpion. - """ - if len(args) == 0: - print("Available commands are :") - for e in COMMAND_LIST: - print(" - \033[1m"+e+"\033[0m") - print( -""" +def helpDARE(args, S): + """ + USAGE : help [command name] + Show command list. If invoked with command name as + an argument, then show command's usage and + descritpion. + """ + if len(args) == 0: + print("Available commands are :") + for e in COMMAND_LIST: + print(" - \033[1m" + e + "\033[0m") + print( + """ Type \033[1m help <command> \033[0m to get help on a specific command""" - ) + ) + else: + if args[0] in COMMAND_LIST: + print(COMMAND_LIST[args[0]].__doc__[1:]) else: - if args[0] in COMMAND_LIST: - print(COMMAND_LIST[args[0]].__doc__[1:]) - else: - print( -""" -No command found '"""+str(args[0])+"""'""" - ) - return None + print( + """ +No command found '""" + + str(args[0]) + + """'""" + ) + return None + # -##MOVE - def move(args,S): - """ +##MOVE +def move(args, S): + """ USAGE : move -GM-purposed command. -move the LAT queue, update pools.""" - availDice = S.Latency.move() - #Update pools - for e in availDice: - if e.name == "Ψ": - S.PSIdicepool.append(e) - else: - S.PHIdicepool.append(e) - S.PSIdicepool.sort() - S.PHIdicepool.sort() - return None + GM-purposed command. + move the LAT queue, update pools.""" + availDice = S.Latency.move() + # Update pools + for e in availDice: + if e.name == "Ψ": + S.PSIdicepool.append(e) + else: + S.PHIdicepool.append(e) + S.PSIdicepool.sort() + S.PHIdicepool.sort() + return None - def Nothing(args,S): - return None + +def Nothing(args, S): + return None # ##REDO - def redo(args,S): - """ -USAGE : redo -GM-purposed command. -Restore (once) the current state before an undo ! -state.""" - if Undoable.S == Undoable.RedoS: - print( -""" +def redo(args, S): + """ + USAGE : redo + GM-purposed command. + Restore (once) the current state before an undo ! + state.""" + if Undoable.S == Undoable.RedoS: + print( + """ Nothing to revert !""" - ) - return None - else: - Undoable.OldS = deepcopy(Undoable.S) - Undoable.S = Undoable.RedoS - return None + ) + return None + else: + Undoable.OldS = deepcopy(Undoable.S) + Undoable.S = Undoable.RedoS + return None + # ##UNDO - def undo(args,S): - """ -USAGE : undo -GM-purposed command. -Restore (once) the current state to the previous -state.""" - if Undoable.S == Undoable.OldS: - print( -""" +def undo(args, S): + """ + USAGE : undo + GM-purposed command. + Restore (once) the current state to the previous + state.""" + if Undoable.S == Undoable.OldS: + print( + """ Nothing to revert !""" - ) - return None - else: - Undoable.RedoS = deepcopy(Undoable.S) - Undoable.S = Undoable.OldS - return None + ) + return None + else: + Undoable.RedoS = deepcopy(Undoable.S) + Undoable.S = Undoable.OldS + return None + # ##EXITDARE - def exitDARE(args,S): - """ -USAGE : exit -Closes this programm while being polite :)""" - print("Goodbye !") - exit() +def exitDARE(args, S): + """ + USAGE : exit + Closes this programm while being polite :)""" + print("Goodbye !") + exit() + + +def show(args, S): + """ + USAGE : show + all info about the current state.""" + print(S.name + ": ") + printallstat(S, S.inroll) + return None + - def show(args,S): - """ -USAGE : show -all info about the current state.""" - print(S.name+": ") - printallstat(S, S.inroll) - return None # ##ADD - def select(args,S,fromQueue=False): - """ - Selects dice, and removes them from dicepools, return selected dice. - Apply this to S.Queue if fromQueue is true - """ - #check for valid input first - if len(args) == 0: - print("At least one dice is expected.") - return None - - for d in args: - if d[0] != "p" and d[0] != "P": - print("Unknown dice '"+str(d)+"' !") +def select(args, S, fromQueue=False): + """ + Selects dice, and removes them from dicepools, return selected dice. + Apply this to S.Queue if fromQueue is true + """ + # check for valid input first + if len(args) == 0: + print("At least one dice is expected.") + return None + + for d in args: + if d[0] != "p" and d[0] != "P": + print("Unknown dice '" + str(d) + "' !") + return None + try: + int(d[1:]) + except ValueError: + print("Unknown dice '" + str(d) + "' !") + return None + + # our input are valid !!! + PselectedDice = [] + pselectedDice = [] + + if not fromQueue: + first = S.PSIdicepool + second = S.PHIdicepool + else: + first = S.Latency.queue + second = S.Latency.queue + for d in args: # rem from pools + if d[0] == "p": + found = False + for e in S.PSIdicepool: + if e.n == int(d[1:]): + S.pDiceTray.add(e) + pselectedDice.append(e) + first.remove(e) + found = True + break + + if not found: # valid dices, but not in pool + print("Not enough Ψ" + str(d[1:]) + " !") + first = first + pselectedDice + second = second + PselectedDice return None - try: - int(d[1:]) - except ValueError: - print("Unknown dice '"+str(d)+"' !") + + elif d[0] == "P": + found = False + for e in S.PHIdicepool: + if e.n == int(d[1:]): + S.PDiceTray.add(e) + PselectedDice.append(e) + second.remove(e) + found = True + break + + if not found: + print("Not enough Φ" + str(d[1:]) + " !") + second = second + PselectedDice + first = first + pselectedDice return None - - # our input are valid !!! - PselectedDice=[] - pselectedDice = [] - - if not fromQueue: - first = S.PSIdicepool - second = S.PHIdicepool - else: - first = S.Latency.queue - second = S.Latency.queue - for d in args: #rem from pools - if d[0] == "p": - found=False - for e in S.PSIdicepool: - if e.n == int(d[1:]): - S.pDiceTray.add(e) - pselectedDice.append(e) - first.remove(e) - found = True - break - - if not found: #valid dices, but not in pool - print("Not enough Ψ"+str(d[1:])+" !") - first = first + pselectedDice - second = second + PselectedDice - return None - - elif d[0] == "P": - found=False - for e in S.PHIdicepool: - if e.n == int(d[1:]): - S.PDiceTray.add(e) - PselectedDice.append(e) - second.remove(e) - found = True - break - - if not found: - print("Not enough Φ"+str(d[1:])+" !") - second = second + PselectedDice - first = first + pselectedDice - return None - - return pselectedDice+PselectedDice + + return pselectedDice + PselectedDice + # ##ADD - def add(args,S): - """add dice into tray""" - #check for valid input first - if len(args) == 0: - print("At least one dice is expected.") - return None - - for d in args: - if d[0] != "p" and d[0] != "P": - print("Unknown dice '"+str(d)+"' !") +def add(args, S): + """add dice into tray""" + # check for valid input first + if len(args) == 0: + print("At least one dice is expected.") + return None + + for d in args: + if d[0] != "p" and d[0] != "P": + print("Unknown dice '" + str(d) + "' !") + return None + try: + int(d[1:]) + except ValueError: + print("Unknown dice '" + str(d) + "' !") + return None + + # our input are valid !!! + p = [] + P = [] + paddedDice = [] + PaddedDice = [] + for d in args: + if d[0] == "p": + found = False + for e in S.PSIdicepool: + if e.n == int(d[1:]): + # S.pDiceTray.add(e) + paddedDice.append(e) + S.PSIdicepool.remove(e) + found = True + break + + if not found: # valid dices, but not in pool + print("Not enough Ψ" + str(d[1:]) + " !") + S.PSIdicepool = S.PSIdicepool + paddedDice + S.PHIdicepool = S.PHIdicepool + PaddedDice return None - try: - int(d[1:]) - except ValueError: - print("Unknown dice '"+str(d)+"' !") + + elif d[0] == "P": + found = False + for e in S.PHIdicepool: + if e.n == int(d[1:]): + # S.PDiceTray.add(e) + PaddedDice.append(e) + S.PHIdicepool.remove(e) + found = True + break + + if not found: + print("Not enough Φ" + str(d[1:]) + " !") + S.PSIdicepool = S.PSIdicepool + paddedDice + S.PHIdicepool = S.PHIdicepool + PaddedDice return None - - # our input are valid !!! - p = [] - P = [] - addedDice = [] - for d in args: - if d[0] == "p": - found=False - for e in S.PSIdicepool: - if e.n == int(d[1:]): - S.pDiceTray.add(e) - addedDice.append(e) - S.PSIdicepool.remove(e) - found = True - break - - if not found: #valid dices, but not in pool - print("Not enough Ψ"+str(d[1:])+" !") - S.PSIdicepool = S.PSIdicepool + S.pDiceTray.tray - S.PHIdicepool = S.PHIdicepool + S.PDiceTray.tray - S.pDiceTray.tray = [] - S.PDiceTray.tray = [] - return None - - elif d[0] == "P": - found=False - for e in S.PHIdicepool: - if e.n == int(d[1:]): - S.PDiceTray.add(e) - addedDice.append(e) - S.PHIdicepool.remove(e) - found = True - break - - if not found: - print("Not enough Φ"+str(d[1:])+" !") - S.PSIdicepool = S.PSIdicepool + S.pDiceTray.tray - S.PHIdicepool = S.PHIdicepool + S.PDiceTray.tray - S.pDiceTray.tray = [] - S.PDiceTray.tray = [] - return None - return addedDice + + for dice in PaddedDice: + S.PDiceTray.add(dice) + for dice in paddedDice: + S.pDiceTray.add(dice) + + return paddedDice + PaddedDice + # ##DEEPCOPY - def deepcopy(S): - SCopy = copy.deepcopy(S) - SCopy.PHIdicepool = copy.deepcopy(S.PHIdicepool) - SCopy.PSIdicepool = copy.deepcopy(S.PSIdicepool) - SCopy.PDiceTray = copy.deepcopy(S.PDiceTray) - SCopy.pDiceTray = copy.deepcopy(S.pDiceTray) - SCopy.Latency = copy.deepcopy(S.Latency) - SCopy.thro = copy.deepcopy(S.thro) - SCopy.inroll = S.inroll - return SCopy +def deepcopy(S): + SCopy = copy.deepcopy(S) + SCopy.PHIdicepool = copy.deepcopy(S.PHIdicepool) + SCopy.PSIdicepool = copy.deepcopy(S.PSIdicepool) + SCopy.PDiceTray = copy.deepcopy(S.PDiceTray) + SCopy.pDiceTray = copy.deepcopy(S.pDiceTray) + SCopy.Latency = copy.deepcopy(S.Latency) + SCopy.thro = copy.deepcopy(S.thro) + SCopy.inroll = S.inroll + return SCopy + # ##ROLL - def roll(args,S): - """ -USAGE : roll [dices] +def roll(args, S): + """ + USAGE : roll [dices] -Does a roll within the possibilities -of your dice pool, and show the roll -result (with PSI and PHI total sum) + Does a roll within the possibilities + of your dice pool, and show the roll + result (with PSI and PHI total sum) -To select a PSI dice, use "p" as a prefix. -To select a PHI dice, use "P" as a prefix. -For instance : + To select a PSI dice, use "p" as a prefix. + To select a PHI dice, use "P" as a prefix. + For instance : roll p4 p4 P6 -will roll Ψ4, Ψ4 and Φ6 - -Once in a roll, you can either \033[1m reroll \033[0m -up to half of the throw. -dice, \033[1m reroll ... add \033[0m to add any -dice in your roll, \033[1m reroll ... throw \033[0m to -remove any dice of your roll, or\033[1m cont \033[0m to finish -your roll. Please type \033[1m help reroll \033[0m -To better know how rerolls works in DARE. - -LAT, PSI and PHI queues and pool are proprely -updated.""" - ##UNDO MGMT - Undoable.OldS = deepcopy(Undoable.S) - - add(args,S) - S.pDiceTray.tray.sort() - S.PDiceTray.tray.sort() - S.pDiceTray.rollall() - S.PDiceTray.rollall() - #State : in roll - - S.inroll = True - - print(str(S.name)+" does a roll !") - printallstat(S, S.inroll) + will roll Ψ4, Ψ4 and Φ6 + + Once in a roll, you can either \033[1m reroll \033[0m + up to half of the throw. + dice, \033[1m reroll ... add \033[0m to add any + dice in your roll, \033[1m reroll ... throw \033[0m to + remove any dice of your roll, or\033[1m cont \033[0m to finish + your roll. Please type \033[1m help reroll \033[0m + To better know how rerolls works in DARE. + + LAT, PSI and PHI queues and pool are proprely + updated.""" + + ##ERR CHECKING + if S.inroll: + print( + "Already in a roll ! Please use\033[1m reroll\033[0m command or\033[1m cont\033[0m command." + ) return None + ##UNDO MGMT + Undoable.OldS = deepcopy(Undoable.S) + + res = add(args, S) + if not res: + return None + S.pDiceTray.tray.sort() + S.PDiceTray.tray.sort() + S.pDiceTray.rollall() + S.PDiceTray.rollall() + # State : in roll + + S.inroll = True + + print(str(S.name) + " does a roll !") + printallstat(S, S.inroll) + return None + # ##REROLL - def reroll(args, S): - """ -USAGE : reroll [dice] [throw [dice]] [add [dice]] - -reroll dice. -Additionnally, you can add any dice of your pool -with the add keyword, or throw any dice of your -current tray with the throw keyword. -For instance, consider this roll : - -Ninten: - PHI [ Φ4 Φ4 Φ6 Φ6 ] - PSI [ Ψ4 Ψ4 Ψ8 ] - ROLL +def reroll(args, S): + """ + USAGE : reroll [dice] [throw [dice]] [add [dice]] + + reroll dice. + Additionnally, you can add any dice of your pool + with the add keyword, or throw any dice of your + current tray with the throw keyword. + For instance, consider this roll : + + Ninten: + PHI [ Φ4 Φ4 Φ6 Φ6 ] + PSI [ Ψ4 Ψ4 Ψ8 ] + ROLL aΦ4[3] bΦ6[1] cΨ4[3] dΨ6[4] -Sum of PHI dice is : 4 <= 5. -Sum of PSI dice is : 7 > 5. + Sum of PHI dice is : 4 <= 5. + Sum of PSI dice is : 7 > 5. + + One could then type : + reroll ac remove b add p4 + + This would : + reroll a and c dice, + remove the b dice + add a psi4 dice into the final roll + + if you only want to add or throw dice, + you can type + + reroll ... add ... + reroll ... remove ... + reroll ... remove ... add ... + + The ordering of the keywords doesn't matter.""" + # UNDO MGMT + Undoable.OldS = deepcopy(Undoable.S) + if not (S.inroll): + print( + """ +Must start a roll first ! see \033[1m help roll\033[0m for +more info""" + ) + return None -One could then type : -reroll ac remove b add p4 + if len(args) == 0: + print("For usage see \033[1m help reroll\033[0m .") + return None -This would : -reroll a and c dice, -remove the b dice -add a psi4 dice into the final roll + doAdd = False + doThrow = False -if you only want to add or throw dice, -you can type + # which index are dice to be added in our args list + addIndex = -1 + # which index are dice to be trashed in our arglist + throwIndex = -1 -reroll ... add ... -reroll ... remove ... -reroll ... remove ... add ... + # List of dice to add + addList = [] + # List of dice to trash + throwList = [] -The ordering of the keywords doesn't matter.""" - #UNDO MGMT - Undoable.OldS = deepcopy(Undoable.S) - if not(S.inroll): - print(""" -Must start a roll first ! see \033[1m help roll\033[0m for -more info""" - ) - return None - - if len(args) == 0: - print("For usage see \033[1m help reroll\033[0m .") + # Remaining dice to reroll + rerollList = args + + # error checking + if args.count("add") > 1: + print( + "Too much 'add' keyword. see \033[1m help reroll\033[0m to see\n correct formatting" + ) + return None + if args.count("remove") > 1: + print( + "Too much 'remove' keyword. see \033[1m help reroll\033[0m to see\n correct formatting" + ) + return None + + # Populate addList accordingly and update rerollList + if "add" in args: + doAdd = True + addIndex = args.index("add") + addList = args[addIndex + 1 :] + rerollList = rerollList[:addIndex] + + # Populate throwList accordingly and update rerollList + if "remove" in args: + doThrow = True + throwIndex = args.index("remove") + throwList = args[throwIndex + 1 :] + rerollList = rerollList[:throwIndex] + + ##After these two if, rerollList is OK, + ##But it is certain that either "throw" or "add" appears in each other. + ##This is a hacky way to patch a stupid bug and idc doing it better : ) + if "add" in throwList: + throwList = throwList[: throwList.index("add")] + if "remove" in addList: + addList = addList[: addList.index("remove")] + + # Indexing dice with abc + index = 0 + diceDict = {} + for e in S.PDiceTray.tray: + diceDict[abc[index]] = e + index += 1 + for a in S.pDiceTray.tray: + diceDict[abc[index]] = a + index += 1 + + if doAdd and addList: + addedDice = add(addList, S) + if ( + not addedDice + ): # This happens when add is invoked but no dice that could be added were return None - doAdd = False - doThrow = False - - #which index are dice to be added in our args list - addIndex = -1 - #which index are dice to be trashed in our arglist - throwIndex = -1 - - #List of dice to add - addList = [] - #List of dice to trash - throwList = [] - - #Remaining dice to reroll - rerollList = args - - #error checking - if args.count("add") > 1: - print("Too much 'add' keyword. see \033[1m help reroll\033[0m to see\n correct formatting") + # Dice to remove + allstrThrow = "" + if len(throwList) > 1: + for letters in throwList: + allstrThrow = allstrThrow + letters + elif throwList: + allstrThrow = throwList[0] + + allstr = "" + if len(rerollList) > 1: + for letters in rerollList: + allstr = allstr + letters + elif rerollList: + allstr = rerollList[0] + + for c in allstr + allstrThrow: + if not (c in diceDict): + print("no dice of index'" + c + "' !") return None - if args.count("remove") > 1: - print("Too much 'remove' keyword. see \033[1m help reroll\033[0m to see\n correct formatting") + + # Verify that dices are not rerolled too much + for l in allstr: + if diceDict[l].count >= 3: + print("Cannot reroll dice " + l + "\ntoo much latency !") return None - - #Populate addList accordingly and update rerollList - if "add" in args: - doAdd = True - addIndex=args.index("add") - addList=args[addIndex+1:] - rerollList=rerollList[:addIndex] - - #Populate throwList accordingly and update rerollList - if "remove" in args: - doThrow = True - throwIndex=args.index("throw") - throwList=args[throwIndex+1:] - rerollList=rerollList[:throwIndex] - - ##After these two if, rerollList is OK, - ##But it is certain that either "throw" or "add" appears in each other. - ##This is a hacky way to patch a stupid bug and idc doing it better : ) - if "add" in throwList: - throwList=throwList[:throwList.index("add")] - if "throw" in addList: - addList=addList[:addList.index("throw")] - - #Indexing dice with abc - index = 0 - diceDict = {} - for e in S.PDiceTray.tray: - diceDict[abc[index]]=e - index+=1 - for a in S.pDiceTray.tray: - diceDict[abc[index]]=a - index+=1 - - if doAdd and addList: - addedDice = add(addList,S) - if not addedDice:#This shouldn't happen I think... - print("Argshs something awfully wrong happened qwq") - return None - - #Dice to remove - allstrThrow = "" - if len(throwList) > 1: - for letters in throwList: - allstrThrow = allstrThrow+letters - elif throwList: - allstrThrow = throwList[0] - - allstr="" - if len(rerollList) > 1: - for letters in rerollList: - allstr = allstr+letters - elif rerollList: - allstr = rerollList[0] - - for c in allstr+allstrThrow: - if not(c in diceDict): - print("no dice of index'"+c+"' !") - return None - ##Now, everything should be okay ! - if doThrow: - for l in allstrThrow: - S.thro.append(diceDict[l]) - if diceDict[l] in S.pDiceTray: - S.pDiceTray.tray.remove(diceDict[l]) - else: - S.PDiceTray.tray.remove(diceDict[l]) - - if doAdd: - for dice in addedDice: - dice.roll() - - for l in allstr: - diceDict[l].roll() - - print(S.name+" rerolls !") - printallstat(S, True) - - return None + + ##Now, everything should be okay ! + if doThrow: + for l in allstrThrow: + S.thro.append(diceDict[l]) + if diceDict[l] in S.pDiceTray: + S.pDiceTray.tray.remove(diceDict[l]) + else: + S.PDiceTray.tray.remove(diceDict[l]) + + if doAdd: + for dice in addedDice: + dice.roll() + dice.count += 1 + + for l in allstr: + diceDict[l].roll() + + print(S.name + " rerolls !") + printallstat(S, True) + + return None + # ##CONT - def cont(args,S): - """ -USAGE : cont -Skips a turn. If done during a roll, -said roll is finished.""" - if not args or not (args[0] in ["žInvokedFromRR","žInvokedFromTrash"]):#UNDO MGMT - Undoable.OldS = deepcopy(Undoable.S) - - S.inroll = False - if not args or args[0] != "žInvokedFromTrash": - move("",S) - all = S.pDiceTray.tray + S.PDiceTray.tray + S.thro - all.sort() - for e in all: - e.Softreset() - S.Latency.add(e) - - S.pDiceTray.tray = [] - S.PDiceTray.tray = [] - S.thro = [] - if args and args[0] == "žInvokedFromRR": - return None - printallstat(S) +def cont(args, S): + """ + USAGE : cont + Skips a turn. If done during a roll, + said roll is finished.""" + if not args or not ( + args[0] in ["žInvokedFromRR", "žInvokedFromTrash"] + ): # UNDO MGMT + Undoable.OldS = deepcopy(Undoable.S) + + S.inroll = False + if not args or args[0] != "žInvokedFromTrash": + move("", S) + + all = S.pDiceTray.tray + S.PDiceTray.tray + S.thro + all.sort() + for e in all: + e.softReset() + S.Latency.add(e) + + S.pDiceTray.tray = [] + S.PDiceTray.tray = [] + S.thro = [] + if args and args[0] == "žInvokedFromRR": return None + printallstat(S) + return None + # ##TRASH - def trash(args,S): - """ -USAGE : trash [dice] -GM-purposed command. -Trash dice as if they were rolled""" - Undoable.OldS = deepcopy(Undoable.S) - selected = select(args,S) - if select == None: - print("No dice found !") - return None - for dice in selected: - ##print(SCopy) - S.Latency.add(dice) +def trash(args, S): + """ + USAGE : trash [dice] + GM-purposed command. + Trash dice as if they were rolled""" + Undoable.OldS = deepcopy(Undoable.S) + selected = select(args, S) + if select == None: + print("No dice found !") return None - + for dice in selected: + ##print(SCopy) + S.Latency.add(dice) + return None -##COMMAND LIST## - COMMAND_LIST = { - "exit" : exitDARE, - "quit" : exitDARE, - "help" : helpDARE, - "show" : show, - "undo" : undo, - "redo" : redo, - "roll" : roll, - "cont" : cont, - "reroll" : reroll, - "trash": trash, - } +##COMMAND LIST## +COMMAND_LIST = { + "exit": exitDARE, + "q": exitDARE, + "quit": exitDARE, + "help": helpDARE, + "show": show, + "undo": undo, + "redo": redo, + "roll": roll, + "cont": cont, + "reroll": reroll, + "trash": trash, +} +if __name__ == "__main__": ## get init param : print( -""" -Please give your (sur)name""" + """ + Please give your (sur)name""" ) - S.name=ask("name?") - if S.name == "": S.name = "Ninten" + S.name = ask("name?") + if S.name == "": + S.name = "Ninten" print( -""" -Please give your PHI dice pool -formatting is expected to be such as : -d4,d4,d6,d4,d8 (no spaces at the start !)""" + """ + Please give your PHI dice pool + formatting is expected to be such as : + \033[1m d4 d4 d6 d4 d8 + \033[0m(no spaces at the start !)""" ) uinput = ask("Φ?") - if uinput=="":uinput="d4,d4,d4,d6,d6,d6" - argsdice = uinput.split(",") - S.PHIdicepool = [] + if uinput == "": + uinput = "d4 d4 d4 d6 d6 d6" + argsdice = uinput.split(" ") + S.PHIdicepool = [] for e in argsdice: dval = int(e[1:]) - S.PHIdicepool.append(SpecialDice(dval,"Φ")) + S.PHIdicepool.append(SpecialDice(dval, "Φ")) S.PHIdicepool.sort() print( -""" -Please give your PSI dice pool -(same format)""" + """ + Please give your PSI dice pool + (same format)""" ) - uinput=ask("Ψ?") - if uinput=="":uinput="d4,d4,d4,d6,d8" - argsdice = uinput.split(",") - S.PSIdicepool = [] + uinput = ask("Ψ?") + if uinput == "": + uinput = "d4 d4 d4 d6 d8" + argsdice = uinput.split(" ") + S.PSIdicepool = [] for e in argsdice: dval = int(e[1:]) - S.PSIdicepool.append(SpecialDice(dval,"Ψ")) + S.PSIdicepool.append(SpecialDice(dval, "Ψ")) S.PSIdicepool.sort() - line() + line() printallstat(S) - print("\nWelcome "+S.name+" !") + print("\nWelcome " + S.name + " !") print( -""" -Please type your command. Type \033[1m help \033[0m -To see available command or \033[1m help <command> \033[0m -To get an explanation of a command""" - ) + """ + Please type your command. Type \033[1m help \033[0m + To see available command or \033[1m help <command> \033[0m + To get an explanation of a command""" + ) line() ##Main While Command while True: @@ -719,12 +840,14 @@ To get an explanation of a command""" ##print(Undoable.S) uinput = ask("command?") args = uinput.split(" ") - if args[0] in COMMAND_LIST: COMMAND_LIST[args[0]](args[1:],Undoable.S) + if args[0] in COMMAND_LIST: + COMMAND_LIST[args[0]](args[1:], Undoable.S) elif args[0] != "": print( -""" -No command found '"""+str(args[0])+"""' -try \033[1mhelp\033[0m to see command list.""" + """ + No command found '""" + + str(args[0]) + + """' + try \033[1mhelp\033[0m to see command list.""" ) line() - diff --git a/TODO.md b/TODO.md new file mode 100644 index 0000000000000000000000000000000000000000..815f1319114d5cbf5a149fd60ae08257c44c29b2 --- /dev/null +++ b/TODO.md @@ -0,0 +1,3 @@ +- Trash command +- restore command +- edit command (to chaneg dice specifically) diff --git a/__pycache__/dice.cpython-311.pyc b/__pycache__/dice.cpython-311.pyc index bd66aa5f770f06cb98d4abd2db56f06329a1f4dd..18dffa00804861ca6e3f3a975d31ed10a94f242a 100644 Binary files a/__pycache__/dice.cpython-311.pyc and b/__pycache__/dice.cpython-311.pyc differ diff --git a/ascii.txt b/ascii.txt deleted file mode 100644 index 10b16e54c026a153b83cdbf8697b81e0923b9a80..0000000000000000000000000000000000000000 --- a/ascii.txt +++ /dev/null @@ -1,41 +0,0 @@ -[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m -[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m -[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m [37m [0m [37m [0m[37m.[0m[37m.[0m[37m.[0m[37m'[0m[37m,[0m[37m,[0m[37m,[0m[34m,[0m[34m,[0m[34m,[0m[34m'[0m[37m'[0m[34m.[0m[37m.[0m[37m.[0m[37m [0m[37m [0m[37m [0m [37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m -[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m.[0m[34m'[0m[34m;[0m[36mo[0m[36mO[0m[34mO[0m[34mO[0m[34mx[0m[34mo[0m[34ml[0m[34mo[0m[34mo[0m[34md[0m[34md[0m[34md[0m[34md[0m[34mx[0m[34mk[0m[34mO[0m[34mx[0m[34md[0m[34md[0m[34md[0m[34mo[0m[34m:[0m[34m,[0m[34m.[0m[37m.[0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m -[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m.[0m[34m;[0m[34md[0m[34mx[0m[34mx[0m[34mk[0m[34mO[0m[34mx[0m[34md[0m[34mx[0m[34mx[0m[34mk[0m[34mx[0m[34md[0m[34mo[0m[34mo[0m[34mo[0m[34md[0m[34md[0m[35md[0m[35md[0m[35md[0m[34md[0m[34md[0m[34mo[0m[34md[0m[34md[0m[34md[0m[34md[0m[34md[0m[34md[0m[34mx[0m[34md[0m[34mc[0m[34m,[0m[34m.[0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m -[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[34m,[0m[34ml[0m[34mx[0m[34mO[0m[37mK[0m[35mK[0m[35mK[0m[35m0[0m[31mk[0m[31md[0m[31mx[0m[31mx[0m[31mx[0m[31mx[0m[31md[0m[31md[0m[35md[0m[34mo[0m[34mc[0m[34m:[0m[34mc[0m[34ml[0m[37mo[0m[37mx[0m[35mk[0m[31mx[0m[31mx[0m[31md[0m[31md[0m[31md[0m[34mo[0m[34mo[0m[34ml[0m[34mo[0m[34mo[0m[34mc[0m[34ml[0m[34ml[0m[34ml[0m[34ml[0m[34m;[0m[34m.[0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m -[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[34m.[0m[34mc[0m[34md[0m[34md[0m[35md[0m[35md[0m[35mx[0m[31mx[0m[31mk[0m[35md[0m[31md[0m[31md[0m[31mo[0m[31md[0m[31mo[0m[31md[0m[31md[0m[31mo[0m[31mo[0m[31mo[0moo[36mo[0m[34mo[0m[34m:[0m[34mc[0m[36md[0m[37mx[0m[37mx[0m[34md[0m[34ml[0m[34mc[0m[34m:[0m[34m:[0m[34m;[0m[34m,[0m[34m;[0m[34m;[0m[34m;[0m[34m;[0m[34m;[0m[34m;[0m[34m:[0m[34mc[0m[34mc[0m[34mc[0m[34m;[0m[34m.[0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m -[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m [37m [0m[37m [0m[34m,[0m[34mo[0m[34mx[0m[34mx[0m[35md[0m[35md[0m[31md[0m[31md[0m[31md[0m[31md[0m[31md[0m[31md[0m[31md[0m[31mo[0m[31mo[0m[31mo[0m[31mo[0m[31mo[0m[33ml[0m[33ml[0m[32ml[0m[36mc[0m[34m:[0m[34m:[0m[34mc[0m[36mo[0m[34mo[0m[34md[0m[34mo[0m[34mc[0m[34m:[0m[34m:[0m[34m:[0m[34m:[0m[34m,[0m[34m,[0m[34m,[0m[34m,[0m[34m:[0m[34m:[0m[34m:[0m[34mc[0m[34m;[0m[34m,[0m[34m,[0m[34m;[0m[34mc[0m[34ml[0m[34mc[0m[34mc[0m[34m:[0m[34m.[0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m -[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[34m,[0m[34mo[0m[34md[0m[35mx[0m[35mx[0m[35mx[0m[35mx[0m[35md[0m[35md[0m[35md[0m[34mo[0m[37mo[0m[36ml[0m[36mc[0m[36mc[0m[34m:[0m[34m:[0m[34m:[0m[36m:[0m[34m:[0m[34m:[0m[34mo[0m[36mo[0m[34mc[0m[34mo[0m[34mo[0m[34mo[0m[36mo[0m[34md[0m[34mo[0m[37mo[0m[37mo[0m[37ml[0m[31mo[0m[37ml[0m[34m;[0m[34m,[0m[34m;[0m[34m;[0m[34m;[0m[34m;[0m[34m;[0m[34m,[0m[34m;[0m[34m,[0m[34m,[0m[34m,[0m[34m;[0m[34m:[0m[34mo[0m[34md[0m[34md[0m[34ml[0m[34mc[0m[34m;[0m[34m.[0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m -[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m.[0m[34mo[0m[35mx[0m[35mx[0m[35md[0m[34md[0m[34md[0m[34mo[0m[34mo[0m[34ml[0m[36ml[0m[36mc[0m[34mc[0m[34m:[0m[34m:[0m[34m:[0m[34m:[0m[34m:[0m[34m:[0m[34mc[0m[34m:[0m[34m:[0m[34m;[0m[34mc[0m[34ml[0m[34md[0m[34md[0m[36md[0m[34mo[0m[34md[0m[34mx[0m[34mo[0m[34mo[0m[34mo[0m[34mo[0m[34mc[0m[34m,[0m[34m,[0m[34m,[0m[34m,[0m[34m,[0m[34m;[0m[34m;[0m[34m;[0m[34m;[0m[34m:[0m[34m;[0m[34m;[0m[34m,[0m[34m;[0m[34m;[0m[34m:[0m[34mo[0m[34mk[0m[34md[0m[34mc[0m[34m:[0m[34m:[0m[34m,[0m[34m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m -[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[34m;[0m[34md[0m[34md[0m[34mo[0m[34mo[0m[34ml[0m[34ml[0m[34mc[0m[34ml[0m[34ml[0m[34ml[0m[34mc[0m[34mo[0m[34mo[0m[34mx[0m[34mo[0m[34ml[0m[34mo[0m[34mc[0m[34mo[0m[34mo[0m[34mo[0m[34mo[0m[34md[0m[34mx[0m[34mx[0m[34md[0m[34mx[0m[34mx[0m[34ml[0m[34md[0m[34md[0m[34mx[0m[34m:[0m[34m;[0m[34m,[0m[34m'[0m[34m;[0m[34m,[0m[34m,[0m[34m,[0m[34m;[0m[34m:[0m[34m:[0m[34m;[0m[34m;[0m[34m;[0m[34m;[0m[34ml[0m[34mO[0m[34ml[0m[34m;[0m[34m;[0m[34m;[0m[34mc[0m[34ml[0m[34ml[0m[34m:[0m[34mc[0m[34m:[0m[34m;[0m[34m.[0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m -[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[34mc[0m[34mo[0m[34ml[0m[34ml[0m[34ml[0m[34ml[0m[34mc[0m[34md[0m[34mo[0m[34mx[0m[34mo[0m[34md[0m[34mO[0m[34mx[0m[34mo[0m[34ml[0m[34mk[0m[34mO[0m[34mO[0m[34mO[0m[34ml[0m[34m,[0m[34m:[0m[34ml[0m[37mK[0m[37mN[0m[34md[0m[34mo[0m[34md[0m[34mx[0m[36mx[0m[36md[0m[34mk[0m[34mx[0m[34m:[0m[34m;[0m[34mc[0m[34mc[0m[34ml[0m[34mO[0m[34ml[0m[34m:[0m[34mo[0m[34mx[0m[34mx[0m[34mO[0m[34mk[0m[34mO[0m[34mk[0m[34md[0m[34mO[0m[37mN[0m[37mN[0m[34md[0m[34mc[0m[34m:[0m[34mc[0m[34m:[0m[34m:[0m[34m;[0m[34m:[0m[34m:[0m[34m:[0m[34m.[0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m -[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[34ml[0m[34ml[0m[34mc[0m[34mc[0m[34ml[0m[34mo[0m[34ml[0m[34ml[0m[34ml[0m[34ml[0m[34mo[0m[34mk[0m[34mk[0m[34mk[0m[34mo[0m[34ml[0m[34ml[0m[36mO[0m[34md[0m[34md[0m[36mO[0m[34mk[0m[34mc[0m[34ml[0m[34mx[0m[36mO[0mM[36m0[0m[36mx[0m[37mK[0m[37m0[0m[36mO[0m[36mO[0m[34mc[0m[34ml[0m[34m;[0m[34ml[0m[34md[0m[37mK[0m[34mk[0m[34m:[0m[34ml[0m[34md[0m[34ml[0m[34mO[0m[34ml[0m[34mc[0m[34m'[0m[34m,[0m[34m,[0m[34m;[0m[34md[0m[34m0[0m[34mO[0m[34md[0m[34mc[0m[34md[0m[34mo[0m[34m:[0m[34m:[0m[34ml[0m[34mc[0m[34m:[0m[34m:[0m[34m;[0m[34m.[0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m -[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[34mc[0m[34ml[0m[34mo[0m[34mk[0m[34md[0m[34mc[0m[34m:[0m[34mc[0m[34ml[0m[34mo[0m[34mc[0m[34mO[0m[37mX[0m[36m0[0m[36m0[0m[37mX[0m[36mO[0m[34mk[0m[34mx[0m[36mx[0m[36mk[0m[36m0[0m[36m0[0m[34mx[0m[36mk[0m[34mx[0m[36mk[0m[37mX[0m[36mk[0m[36mk[0m[36mO[0m[37m0[0m[36m0[0m[36m0[0m[36mO[0m[34mo[0m[34m;[0m[34m;[0m[34mc[0m[34mk[0m[34mk[0m[34md[0m[34ml[0m[34md[0m[34mc[0m[34m'[0m[34m'[0m[34m,[0m[34m'[0m[34m,[0m[34m'[0m[34m'[0m[34m,[0m[34m;[0m[34m:[0m[34m;[0m[34m,[0m[34m:[0m[34md[0m[34mk[0m[34ml[0m[34m:[0m[34m:[0m[34m;[0m[34mc[0m[34m:[0m[34m;[0m[34m.[0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m -[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[34m;[0m[34mo[0m[34mx[0m[34md[0m[34mc[0m[34mc[0m[34m:[0m[34m;[0m[34m;[0m[34m:[0m[34m,[0m[34ml[0m[34mc[0m[34m;[0m[34mc[0m[34ml[0m[34mo[0m[34mk[0m[34mx[0m[34mo[0m[34ml[0m[34md[0m[34md[0m[34md[0m[36mx[0m[36mO[0m[36mO[0m[36mk[0m[34md[0m[34md[0m[34mk[0m[34mO[0m[36mO[0m[36mk[0m[34mo[0m[36mO[0m[34mO[0m[34md[0m[34mk[0m[34mk[0m[34ml[0m[34mc[0m[34ml[0m[34m:[0m[34m,[0m[34m'[0m[34m'[0m[34m.[0m[34m,[0m[34m,[0m[34m,[0m[34m;[0m[34m:[0m[34m;[0m[34m,[0m[34m;[0m[34m:[0m[34m,[0m[34m,[0m[34m;[0m[34mo[0m[34mo[0m[34mo[0m[34mo[0m[34ml[0m[34m:[0m[34m:[0m[34m:[0m[34m,[0m[34m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m -[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m.[0m[34mo[0m[34mx[0m[34ml[0m[34mc[0m[34mc[0m[34ml[0m[34md[0m[34mc[0m[34m,[0m[34m;[0m[34m,[0m[34mo[0m[34mc[0m[34m:[0m[34m:[0m[34m;[0m[34m,[0m[34md[0m[36mO[0m[36mx[0m[36mk[0m[36md[0m[34md[0m[34md[0m[34mx[0m[34mk[0m[37mN[0m[37mX[0m[37mK[0m[36mO[0m[37mK[0m[36m0[0m[34mo[0m[34mo[0m[34mo[0m[34mo[0m[34m:[0m[34m;[0m[34ml[0m[34mc[0m[34ml[0m[34mx[0m[36m0[0m[34mo[0m[34mc[0m[34m;[0m[34m'[0m[34m,[0m[34m;[0m[34m,[0m[34m'[0m[34m'[0m[34m'[0m[34m,[0m[34m,[0m[34m;[0m[34m:[0m[34m;[0m[34m;[0m[34ml[0m[34m;[0m[34m;[0m[34mc[0m[34mo[0m[34mx[0m[34ml[0m[34m:[0m[34m:[0m[34m;[0m[34m.[0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m -[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[34mo[0m[34mo[0m[34ml[0m[34ml[0m[34mk[0m[34md[0m[34md[0m[34mo[0m[34m;[0m[34m;[0m[34mc[0m[34mc[0m[34mc[0m[34mo[0m[34mk[0m[34m;[0m[34m:[0m[34m:[0m[34mk[0m[37mK[0m[34md[0m[34mo[0m[36mo[0m[36mx[0m[36mo[0m[36md[0m[36mk[0m[37mN[0m[37mN[0m[37mW[0m[37mN[0m[37m0[0m[34mo[0m[34ml[0m[34ml[0m[34m:[0m[34m;[0m[34m'[0m[34m'[0m[34m'[0m[34ml[0m[34mc[0m[34mc[0m[34mx[0m[34mc[0m[34m;[0m[34md[0m[34mx[0m[34m:[0m[34m'[0m[34m.[0m[34m'[0m[34m'[0m[34m,[0m[34m,[0m[34m'[0m[34m,[0m[34m;[0m[34m:[0m[34m:[0m[34m;[0m[34m'[0m[34m;[0m[34m:[0m[34mx[0m[34mx[0m[34mo[0m[34ml[0m[34m;[0m[34m;[0m[34m,[0m[34m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m -[37m [0m[37m [0m[37m [0m[37m [0m[37m.[0m[34mx[0m[34ml[0m[34ml[0m[34md[0m[34ml[0m[34mc[0m[34mk[0m[34mO[0m[34mx[0m[34md[0m[34mo[0m[34md[0m[34mc[0m[34mo[0m[34m;[0m[34m,[0m[34m;[0m[34m:[0m[36ml[0m[36ml[0m[32mo[0m[32ml[0m[36md[0m[34md[0m[36md[0m[36md[0m[36mk[0m[36mk[0m[37mO[0m[36mk[0m[34md[0m[34ml[0m[34m;[0m[34mc[0m[34m;[0m[34m;[0m[34mc[0m[34m:[0m[34m,[0m[34m'[0m[34m:[0m[34m:[0m[34m:[0m[34m,[0m[34m.[0m[34m,[0m[34m:[0m[34m;[0m[34m;[0m[34m;[0m[34m,[0m[34ml[0m[34m'[0m[34m'[0m[34m'[0m[34m'[0m[34m'[0m[34m,[0m[34m'[0m[34m,[0m[34m;[0m[34m;[0m[34m:[0m[34m;[0m[34m:[0m[34ml[0m[34mc[0m[34mc[0m[34mc[0m[34m:[0m[34m;[0m[34m.[0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m -[37m [0m[37m [0m[37m [0m[37m [0m[34m.[0m[34ml[0m[34m:[0m[34m:[0m[34ml[0m[34md[0m[34mo[0m[37mX[0m[34mO[0m[34mx[0m[34ml[0m[34m;[0m[34m,[0m[34m'[0m[34m,[0m[34m'[0m[34m;[0m[34m:[0m[34m:[0m[34ml[0moooo[31mo[0m[33mo[0m[33md[0mkd[34ml[0m[34mc[0m[34m:[0m[34m:[0m[34ml[0m[34m:[0m[34m:[0m[34m;[0m[34m;[0m[34m,[0m[34m'[0m[34m'[0m[34m:[0m[34m:[0m[34m;[0m[34m.[0m[34m.[0m[34m.[0m[34m.[0m[34m.[0m[34m.[0m[34m.[0m[34m,[0m[34m;[0m[34m,[0m[34m;[0m[34m'[0m[34m'[0m[34m'[0m[34m;[0m[34m'[0m[34m'[0m[34m,[0m[34m'[0m[34m;[0m[34m:[0m[34m,[0m[34m;[0m[34m,[0m[34m;[0m[34m;[0m[34mc[0m[34m:[0m[34m'[0m[34m [0m[37m [0m[37m [0m[37m [0m[37m [0m -[37m [0m[37m [0m[37m [0m[37m [0m[34m,[0m[34ml[0m[34mc[0m[34mc[0m[34m:[0m[34mc[0m[34mo[0m[34mk[0m[34ml[0m[34m:[0m[34mo[0m[34mO[0m[34mO[0m[34mo[0m[34mc[0m[34mc[0m[34mx[0m[34mO[0m[34mK[0m[34m0[0m[34mO[0m[31md[0m[33mo[0m[37ml[0m[31mo[0m[31mo[0m[31mo[0m[33mo[0m[37mo[0m[34ml[0m[34mc[0m[34mc[0m[34m:[0m[34m:[0m[34m:[0m[34m:[0m[34m;[0m[34m,[0m[34m,[0m[34m'[0m[34m'[0m[34m'[0m[34m,[0m[34m.[0m[34m.[0m[34m'[0m[34m'[0m[34m.[0m[34m.[0m[34m'[0m[34m,[0m[34m,[0m[34m,[0m[34m,[0m[34m:[0m[34m'[0m[34m,[0m[34m'[0m[34m;[0m[34m,[0m[34m,[0m[34m'[0m[34m'[0m[34m,[0m[34m,[0m[34m,[0m[34m:[0m[34m;[0m[34m,[0m[34m;[0m[34m;[0m[34m;[0m[34m,[0m[34m [0m[37m [0m[37m [0m[37m [0m[37m [0m -[37m [0m[37m [0m[37m [0m[37m [0m[34m;[0m[34ml[0m[34mc[0m[34m:[0m[34m,[0m[34m,[0m[34m;[0m[34m;[0m[34m:[0m[34m,[0m[34mc[0m[34m:[0m[34m,[0m[34m,[0m[34m'[0m[34m,[0m[34m:[0m[34m;[0m[34mc[0m[34m:[0m[34m;[0m[34m:[0m[37mk[0m[37mx[0m[31mk[0m[31md[0m[31md[0m[37md[0m[37m0[0m0[36mk[0m[34m:[0m[34m:[0m[34m;[0m[34m;[0m[34ml[0m[34ml[0m[34m;[0m[34m,[0m[34m'[0m[34m'[0m[34m,[0m[34m'[0m[34m.[0m[34m.[0m[34m.[0m[34m.[0m[34m.[0m[34m.[0m[34m'[0m[34m.[0m[34m.[0m[34m'[0m[34m'[0m[34mc[0m[34mk[0m[34m:[0m[34m,[0m[34m;[0m[34ml[0m[34m;[0m[34m'[0m[34m'[0m[34m'[0m[34m,[0m[34m:[0m[34mc[0m[34m,[0m[34m;[0m[34m;[0m[34m;[0m[34m;[0m[34m,[0m[34m [0m[37m [0m[37m [0m[37m [0m[37m [0m -[37m [0m[37m [0m[37m [0m[37m [0m[34m,[0m[34ml[0m[34m:[0m[34m;[0m[34m,[0m[34m;[0m[34mc[0m[34mo[0m[34ml[0m[34m:[0m[34mc[0m[34m:[0m[34m;[0m[34m;[0m[34m;[0m[34m;[0m[34m,[0m[34m'[0m[34m'[0m[34m'[0m[34m'[0m[34m,[0m[34mc[0m[34md[0mkkO[37mk[0mkx[36mx[0m[34ml[0m[34mc[0m[34m:[0m[34m:[0m[34m;[0m[34m;[0m[34m;[0m[34m,[0m[34m'[0m[34m'[0m[34m'[0m[34m'[0m[34m.[0m[34m.[0m[34m.[0m[34m.[0m[34m'[0m[34m.[0m[34m.[0m[34m.[0m[34m.[0m[34m.[0m[34m.[0m[34m,[0m[34m;[0m[34m:[0m[34md[0m[34ml[0m[34m,[0m[34m:[0m[34ml[0m[34m,[0m[34m,[0m[34m'[0m[34m,[0m[34m'[0m[34m'[0m[34m,[0m[34m;[0m[34m;[0m[34m;[0m[34m,[0m[34m [0m[37m [0m[37m [0m[37m [0m[37m [0m -[37m [0m[37m [0m[37m [0m[37m [0m[37m.[0m[34mo[0m[34mc[0m[34m:[0m[34m;[0m[34m:[0m[34mc[0m[34mc[0m[34mc[0m[34m:[0m[34mc[0m[34ml[0m[34mO[0m[34m0[0m[34mK[0m[34mk[0m[34mx[0m[34md[0m[34mo[0m[34ml[0m[34m;[0m[34m:[0m[34mc[0m[34mo[0m[34mo[0mO[37m0[0m[37mK[0m[37mW[0mN[37m0[0m[34mk[0m[34md[0m[34mo[0m[34mc[0m[34ml[0m[34ml[0m[34ml[0m[34m;[0m[34m;[0m[34m:[0m[34m,[0m[34m:[0m[34m'[0m[34m.[0m[34m.[0m[34m.[0m[34m'[0m[34m'[0m[34m'[0m[34m'[0m[34m'[0m[34m,[0m[34m'[0m[34m.[0m[34m'[0m[34m,[0m[34m,[0m[34m:[0m[34md[0m[34mc[0m[34m'[0m[34m'[0m[34m'[0m[34m,[0m[34m;[0m[34m'[0m[34m,[0m[34m;[0m[34m;[0m[34m:[0m[34m:[0m[34m'[0m[34m [0m[37m [0m[37m [0m[37m [0m[37m [0m -[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[34ml[0m[34mx[0m[34md[0m[34mk[0m[36m0[0m[34md[0m[34ml[0m[34m;[0m[34m,[0m[34m:[0m[34m:[0m[34m;[0m[34mo[0m[34mO[0m[36mK[0m[34mO[0m[34mx[0m[34mo[0m[34ml[0m[34m;[0m[34m,[0m[34m'[0m[34m,[0m[34m;[0m[34mo[0m[34mx[0m[34mO[0m[34mk[0m[36m0[0m[37mW[0m[37mM[0m[37mM[0m[37mW[0m[37mN[0m[37mW[0m[37mW[0m[37mW[0m[37mN[0mW[36m0[0m[34mo[0m[34mo[0m[34m:[0m[34m:[0m[34m'[0m[34m'[0m[34m,[0m[34m;[0m[34m:[0m[34ml[0m[34mc[0m[34m;[0m[34m:[0m[34ml[0m[34m'[0m[34m'[0m[34m'[0m[34m'[0m[34m'[0m[34mx[0m[34ml[0m[34m'[0m[34m,[0m[34m'[0m[34m;[0m[34m,[0m[34m'[0m[34m,[0m[34m;[0m[34m:[0m[34m;[0m[34m.[0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m -[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[34m;[0m[34mk[0m[34ml[0m[34mo[0m[36m0[0m[36mK[0m[34mk[0m[34m;[0m[34m;[0m[34mc[0m[34mo[0m[34mO[0m[34mk[0m[34mc[0m[34mo[0m[34md[0m[34mo[0m[34ml[0m[34m,[0m[34m,[0m[34m'[0m[34m,[0m[34m:[0m[34mc[0m[34mc[0m[34mc[0m[34mc[0m[34ml[0m[34mc[0m[34ml[0m[34mO[0m[37mX[0m[37mW[0mM[37mW[0m[37mM[0mMMMMM[37mW[0m[34mO[0m[34mx[0m[34m:[0m[34m;[0m[34m,[0m[34m,[0m[34m;[0m[34ml[0m[34mo[0m[34ml[0m[34ml[0m[34md[0m[34md[0m[34m,[0m[34m'[0m[34m;[0m[34m;[0m[34m,[0m[34mk[0m[34md[0m[34m;[0m[34m'[0m[34m'[0m[34m,[0m[34m,[0m[34m:[0m[34mc[0m[34m:[0m[34m'[0m[34m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m -[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[34md[0m[34mk[0m[34mx[0m[37mN[0m[37mN[0m[34mO[0m[34m:[0m[34mc[0m[34mc[0m[34ml[0m[34mc[0m[34mc[0m[34ml[0m[34ml[0m[34ml[0m[34mo[0m[34mo[0m[34m,[0m[34m.[0m[34m.[0m[34m,[0m[34mc[0m[34mo[0m[34mo[0m[34md[0m[34md[0m[34mk[0m[34mo[0m[34ml[0m[34m:[0m[34m;[0m[34mo[0m[37mX[0m[37mN[0m[37mM[0mM[37mM[0mMM[37mW[0m[34mO[0m[34mo[0m[34mo[0m[34mc[0m[34m,[0m[34m;[0m[34ml[0m[34mo[0m[34mo[0m[34mx[0m[34mo[0m[34mx[0m[34md[0m[34mx[0m[34m;[0m[34m,[0m[34m,[0m[34mo[0m[34m,[0m[34ml[0m[36mK[0m[34mc[0m[34m;[0m[34m,[0m[34m,[0m[34m,[0m[34m;[0m[34m;[0m[34m,[0m[34m.[0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m -[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[34m.[0m[34mx[0m[34md[0m[36mK[0m[37mM[0m[34m0[0m[34m:[0m[34m:[0m[34mc[0m[34mk[0m[34md[0m[34md[0m[34mk[0m[34mO[0m[34m0[0m[37mK[0m[34mk[0m[34md[0m[34m:[0m[34m.[0m[34m,[0m[34m:[0m[34m;[0m[34m;[0m[34ml[0m[34mO[0m[37mX[0m[37mW[0m[34mK[0m[34m0[0m[34mk[0m[37mX[0mMMM[37mM[0mM[37mX[0m[37mK[0m[34mO[0m[34mk[0m[34md[0m[34m;[0m[34m,[0m[34m,[0m[34m:[0m[34mc[0m[34mx[0m[34ml[0m[34mo[0m[34mO[0m[34m0[0m[34mO[0m[34ml[0m[34mc[0m[34ml[0m[34mo[0m[34md[0m[34mc[0m[34mo[0m[34md[0m[34mo[0m[34mc[0m[34m:[0m[34m,[0m[34m;[0m[34m;[0m[34m,[0m[34m'[0m[34m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m -[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[34m'[0m[34ml[0m[34mc[0m[37mX[0m[37mW[0m[36mK[0m[34mo[0m[34m:[0m[34mo[0m[34ml[0m[34ml[0m[34mo[0m[34mo[0m[34ml[0m[34mo[0m[37m0[0m[37mN[0m[37mK[0m[34mO[0m[34mo[0m[34mc[0m[34ml[0m[34mx[0m[37m0[0m[37mN[0m[34m0[0m[37mK[0mM[37mW[0m[37mM[0m[37mW[0m[37mW[0m[37mN[0m[34m0[0m[34mk[0m[34mo[0m[34ml[0m[34mo[0m[34ml[0m[34md[0m[34mo[0m[34m:[0m[34m;[0m[34m:[0m[34mc[0m[34ml[0m[34mo[0m[34mc[0m[34mc[0m[34mO[0m[37mW[0m[37mN[0m[34mK[0m[34m0[0m[34m0[0m[34mO[0m[34m0[0m[34mx[0m[34mx[0m[34md[0m[34md[0m[34mo[0m[34ml[0m[34m:[0m[34m,[0m[34m;[0m[34m'[0m[34m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m -[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[34m,[0m[34mo[0m[34mO[0mW[37mN[0m[34md[0m[34mk[0m[36mK[0m[34mo[0m[34mo[0m[34mk[0m[34mx[0m[34mo[0m[34ml[0m[34ml[0m[34ml[0m[37mN[0m[37mN[0m[36mK[0m[34ml[0m[34mO[0m[34m0[0m[34mK[0m[34mO[0m[37mX[0m[37mN[0m[37mW[0m[37mX[0m[36mK[0m[37mK[0m[34m0[0m[34mO[0m[34mO[0m[34mk[0m[34md[0m[34mo[0m[34md[0m[34mo[0m[34ml[0m[34mo[0m[34mc[0m[34m;[0m[34m:[0m[34mc[0m[34m,[0m[34m:[0m[34mc[0m[34ml[0m[34mx[0m[34mo[0m[34mx[0m[34mc[0m[34m:[0m[34m;[0m[34md[0m[34mO[0m[34mO[0m[34mk[0m[34mx[0m[34ml[0m[34mc[0m[34mc[0m[34ml[0m[34m;[0m[34m'[0m[34m.[0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m -[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[34m.[0m[34md[0m[34m0[0m[34m0[0m[34m0[0m[34mk[0m[36mN[0m[34mc[0m[34ml[0m[37mX[0m[34mO[0m[34mo[0m[34mo[0m[34mo[0m[34mO[0m[37mW[0m[37mM[0m[37mW[0m[34md[0m[34mK[0m[34mO[0m[34mk[0m[34mo[0m[34mo[0m[34m0[0m[34mK[0m[34m0[0m[34mO[0m[34mk[0m[34mk[0m[34mk[0m[34mk[0m[34mk[0m[34mk[0m[34mk[0m[34md[0m[34mo[0m[34mo[0m[34ml[0m[34ml[0m[34mc[0m[34mo[0m[34md[0m[34mo[0m[34m:[0m[34mc[0m[34mc[0m[34m:[0m[34m:[0m[34m;[0m[34m'[0m[34m'[0m[34m,[0m[34m;[0m[34ml[0m[34mo[0m[34mo[0m[34mc[0m[34m;[0m[34m;[0m[34m;[0m[34m:[0m[34m.[0m[34m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m -[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m.[0m[34ml[0m[34md[0m[34md[0m[34mo[0m[36mX[0m[34mk[0m[34mc[0m[34md[0m[36mK[0m[37mN[0m[34m0[0m[34md[0m[34md[0m[34m0[0m[37mM[0m[37mW[0m[34mO[0m[34mO[0m[34mk[0m[34mK[0m[34mx[0m[34mo[0m[34mx[0m[34mO[0m[34m0[0m[34m0[0m[37mX[0m[34mO[0m[34m0[0m[34ml[0m[34mo[0m[34md[0m[34mk[0m[34md[0m[34md[0m[34mc[0m[34mo[0m[34mO[0m[34mO[0m[34md[0m[34mc[0m[34mo[0m[34mx[0m[34m:[0m[34m:[0m[34m'[0m[34m,[0m[34m,[0m[34m:[0m[34mc[0m[34ml[0m[34ml[0m[34mc[0m[34m:[0m[34m:[0m[34m;[0m[34m,[0m[34m;[0m[34m;[0m[34m.[0m[34m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m -[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[34m,[0m[34mo[0m[34ml[0m[34m:[0m[34md[0m[34md[0m[34md[0m[34m0[0m[34mK[0m[34m0[0m[34mk[0m[34mc[0m[34mc[0m[34mo[0m[34mk[0m[34mO[0m[34m0[0m[34mK[0m[34m0[0m[34mO[0m[34mO[0m[34m0[0m[37mN[0m[37mN[0m[34m0[0m[34md[0m[34md[0m[34mk[0m[34m0[0m[36mX[0m[36mK[0m[34m0[0m[34mO[0m[34mk[0m[34mK[0m[34m0[0m[34mx[0m[34md[0m[34mx[0m[34md[0m[34ml[0m[34ml[0m[34mc[0m[34ml[0m[34ml[0m[34mo[0m[34md[0m[34md[0m[34mo[0m[34md[0m[34mo[0m[34ml[0m[34mc[0m[34m:[0m[34m:[0m[34m:[0m[34m;[0m[34m.[0m[34m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m -[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[34m:[0m[34md[0m[34mo[0m[34mo[0m[34ml[0m[34ml[0m[34mx[0m[34m0[0m[34mk[0m[34mx[0m[34mo[0m[34mo[0m[34mx[0m[34m0[0m[34m0[0m[36mK[0m[37mN[0m[37mW[0m[37mW[0mM[37mW[0m[37mN[0m[36mK[0m[34m0[0m[37mN[0m[37mN[0m[37mM[0mWMW[37mW[0m[34m0[0m[34mO[0m[34mO[0m[36mK[0m[34mx[0m[34mo[0m[34ml[0m[34mk[0m[34mk[0m[34md[0m[34md[0m[34md[0m[34mo[0m[34mo[0m[34mo[0m[34mo[0m[34mo[0m[34mo[0m[34ml[0m[34ml[0m[34ml[0m[34m:[0m[34m'[0m[34m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m -[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m.[0m[34m;[0m[34mo[0m[34md[0m[34md[0m[34md[0m[34m0[0m[37mN[0m[37mN[0m[36mX[0m[37mX[0m[37mW[0m[37mW[0m[37mW[0m[37mN[0m[37mN[0m[37mX[0m[34mK[0m[37mN[0m[37mX[0m[37mN[0mMM[37mW[0m[37mW[0mW[37mN[0m[37mW[0m[36mN[0m[37mW[0m[37mW[0mWMM[36mN[0m[36mK[0m[34mO[0m[34mk[0m[34mx[0m[34mO[0m[34mO[0m[34mx[0m[34md[0m[34md[0m[34mo[0m[34ml[0m[34ml[0m[34ml[0m[34mc[0m[34m:[0m[34m'[0m[34m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m -[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[34m'[0m[34mc[0m[34md[0m[34mk[0m[34mk[0m[36mK[0m[36mN[0m[37mN[0m[37mW[0m[37mW[0m[37mW[0mW[37mN[0m[37mN[0m[34m0[0m[37mW[0m[37mW[0m[36mN[0m[37mW[0mMW[37mW[0mMMMMMMMW[37mW[0m[36mN[0m[36mN[0m[36mK[0m[34mk[0m[34mx[0m[34md[0m[34md[0m[34md[0m[34md[0m[34ml[0m[34mc[0m[34ml[0m[34mc[0m[34m:[0m[34m.[0m[34m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m -[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[34m'[0m[34mc[0m[34ml[0m[34mo[0m[34md[0m[34mk[0m[34mO[0m[34mK[0m[36mX[0m[37mN[0m[34m0[0m[34m0[0m[37mW[0mMMMMMMW[37mW[0m[37mW[0m[37mN[0m[36mN[0m[36mN[0m[36mN[0m[34mK[0m[34mO[0m[34mO[0m[34mk[0m[34mx[0m[34md[0m[34md[0m[34md[0m[34md[0m[34mo[0m[34ml[0m[34ml[0m[34m:[0m[34m'[0m[34m.[0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m -[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[34m.[0m[34m,[0m[34mc[0m[34mo[0m[34mx[0m[34mx[0m[34mk[0m[34mk[0m[34mx[0m[34mx[0m[34m0[0m[36mK[0m[36mX[0m[36mK[0m[34mK[0m[36mK[0m[34mK[0m[34m0[0m[34m0[0m[34mk[0m[34mx[0m[34mx[0m[34mx[0m[34md[0m[34md[0m[34md[0m[34md[0m[34mo[0m[34mo[0m[34mo[0m[34ml[0m[34mc[0m[34m,[0m[34m.[0m[34m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m -[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m.[0m[34m.[0m[34m,[0m[34m:[0m[34mc[0m[34ml[0m[34mo[0m[34md[0m[34md[0m[34md[0m[34md[0m[34md[0m[34md[0m[34md[0m[34md[0m[34mo[0m[34mo[0m[34mo[0m[34mo[0m[34mo[0m[34ml[0m[34mc[0m[34m:[0m[34m,[0m[34m.[0m[34m.[0m[34m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m -[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m.[0m[34m.[0m[34m.[0m[34m.[0m[34m.[0m[34m.[0m[34m.[0m[34m.[0m[37m.[0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m -[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m -[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m[37m [0m