#!/usr/bin/env python
# -*- coding: iso-8859-1 -*-
'''wmgmail

WindowMaker dockapp to display gmail information.

Copyright (C) 2004 Pasi Savolainen

Licensed under the GNU General Public License.


'''

usage = '''wmgmail [options]
Available options are:
    -h, --help                  print this help
'''

import sys
import os
import signal
import time
import string
import ConfigParser
import getopt
import popen2
import threading

import pywmhelpers

import wmgsettings
import libgmail

width = 64
height = 64

xOffset = 4
yOffset = 4

lettersStartX = 0
lettersStartY = 74
letterWidth = 6
letterHeight = 8

digitsStartX = 0
digitsStartY = 64
digitWidth = 6
digitHeight = 8

letters = 'abcdefghijklmnopqrstuvwxyz'
digits = '0123456789:/-%. '

maxChars = 9

chPid = -1
chPidRecent = -1
reConfig = 1 # start with updating settings :)
Config = {}
gAccount = None
updateAt = 0
unreadMailCnt = 0
unreadMails = []
gStatusPicSize = [46-15,26-3] # size of status picture
gStatusHave = [71, 17]          # where's 'have mail' pic
gStatusNo = [103, 17]           # where's 'no mail' pic.
gStatusAt = [15, 3]             # where status pic is.


defaultConfigFile = '~/.wmgmailrc'

defaultRGBFiles = ('/usr/lib/X11/rgb.txt', '/usr/X11R6/lib/X11/rgb.txt')

# moo
err = sys.stderr.write;

# moo.

def handlerChild(signum, frame):
    global chPid, chPidRecent
    #print "got signal %s %s" % (signum, frame)
    # cleanup child
    try:
        if (signum == signal.SIGCHLD):
            #print "getting waitpid"
            if (chPid != -1):
                status = os.waitpid(chPid, os.WNOHANG)
                if status[0]: # if it was this child that was killed.
                    chPid = -1
            if (chPidRecent != -1):
                status = os.waitpid(chPidRecent, os.WNOHANG)
                if status[0]:
                    chPidRecent = -1
    except OSError:
        # no children? so get rid of them.
        chPidRecent = -1;
        chPid = -1


def handlerHUP(signum, frame):
    global reConfig
    #print "got signal %s %s" % (signum, frame)    
    reConfig = 1
    

def readConfig():
    global Config, gAccount
    lconfig = wmgsettings.getwmgmailsettings(wmgsettings.get_settingsfname())
    if Config == lconfig or lconfig['username'] == 'nobody':
        # identical settings or settings sucked. go away.
        return
    Config = lconfig
    ga = libgmail.GmailAccount(Config['username'], Config['password'])
    try:
        ga.login()
    except libgmail.GmailLoginFailure:
        print "Login Error"
    else:
        gAccount = ga;
        global updateAt
        updateAt = 0;


def getUnread():
    """ Try initiating mail update if it's right time
    return True if did check for mail (regardless result)    
    """
    global updateAt, unreadMails, unreadMailCnt, Config, gAccount
    tm = time.time()
    if gAccount is None or ( updateAt and updateAt > tm):
        # not time to update yet.
        return False
    #print "Updating message counts.."
    # TODO:set image to 'checking mail'
    try:
        unreadMails = gAccount.getMessagesByQuery('is:unread')
        #if len( newunreadMails ):
        #    for mail in unreadMails:
        #        mail.unread = 0
        #    unreadMails = newunreadMails;
        unreadMailCnt = len(unreadMails)
    except:
        print "Connection troubles: ", sys.exc_info()[0]
        
    # TODO:set image to normal

    # set next update to target time.
    # check_interval is in minutes, tm is in seconds.
    updateAt = tm + int(Config['check_interval'])*60
    return True
    

def configureWMGmail():
    global chPid
    if chPid != -1:
        #print "nonnull %s" % chPid
        pid, status = os.waitpid(chPid, os.WNOHANG)
        #print "status %s %s %s" % (chPid, pid, status)
        if pid == 0 or not os.WIFEXITED(status):
            print "not exited"
            return
        chPid = -1
    #print "forking"
    chPid = os.fork()
    if chPid == 0:
        import wmgsettingsgui
        wmgsettingsgui.run_in_thread()
        sys.exit(0)

def showRecentMessages():
    global chPidRecent
    if chPidRecent != -1:
        #print "nonnullR %s" % chPidRecent
        pid, status = os.waitpid(chPidRecent, os.WNOHANG)
        #print "statusR %s %s %s" % (chPidRecent, pid, status)
        if pid == 0 or not os.WIFEXITED(status):
            #print "Rnot exited"
            return
        chPidRecent = -1
    #print "forking Recent"
    chPidRecent = os.fork()
    if chPidRecent == 0:
        import wmgchooser
        wmgchooser.run_in_thread(unreadMails)
        sys.exit(0)

def startBrowserInbox():
    #print "starting something, yeah.."
    if os.fork():
        # forked and am parent.
        return
    # forked, and is child.
    # start browser.
    cmd = wmgsettings.getwmgmailsettings(wmgsettings.get_settingsfname())['browser_command']
    cmd = cmd.replace('%s', 'http://gmail.google.com/gmail')
    os.execl(*['/bin/sh', '/bin/sh', '-c', cmd])


def drawStatus():
    # usually no mail.
    global gStatusNo, gStatusHave, gStatusAt, gStatusPicSize
    status = gStatusNo
    if unreadMailCnt:
        # have mail
        status = gStatusHave
    pywmhelpers.copyXPMArea(*(status+gStatusPicSize+gStatusAt))

def addString(s, x, y):
    '''Convenience function around pwymhelpers.addString.'''
    try:
        pywmhelpers.addString(s, x, y, letterWidth, letterHeight, lettersStartX,
                          lettersStartY, letters, digitWidth, digitHeight,
                          digitsStartX, digitsStartY, digits, xOffset, yOffset,
                          width, height)
    except ValueError, e:        
        err('Error when painting string ("'+s+'"):\n' + str(e) + '\n')
        sys.exit(3)

def clearLine(y):
    '''Clear a line of text at position y.'''
    pywmhelpers.copyXPMArea(72, yOffset, width - 2 * xOffset, letterHeight,
                            xOffset, y + yOffset)

def getXY(line):
    '''Return the x and y positions to be used at line line.'''
    return 0, line * (letterHeight + 3) + 1

def isTrue(s):
    '''Return true if the string s can be interpreted as a true value.

    Raises ValueError if we get a string we dont like.
    '''
    trueThings = ['on', 'yes', '1', 'true']
    falseThings = ['off', 'no', '0', 'false']
    if s in trueThings:
        return 1
    elif s in falseThings:
        return 0
    raise ValueError

class ActiveArea:
    def __init__(self, num, action, coords):
        self._num = num
        self._action = action
        self._coords = coords

    def getMouseRegion(self):
        return [self._num] + self._coords;

    def _doMouseAction(self, button):
        actions = { 'config': configureWMGmail,
                    'inbox': startBrowserInbox,
                    'mailchoose': showRecentMessages }
        if self._action in actions:
            #print "found and executing action %s" % self._action
            actions[self._action]()
            
    def tick1(self):
        pass
    def tick2(self):
        pass

    def mouseClicked(self, button):
        #print "mouse clicked"
        if 0 < button < 11:
            self._doMouseAction(button)
    

class WMGmail:
    def __init__(self):
        self._entrys = []
        line = 0
        tentry = [[0, 'inbox', [15,3,46,25]],
                  [1, 'config', [3,3,14,11]],
                  [2, 'mailchoose',[50,3, 60, 26]]]
        for entry in tentry:
            self._entrys.append(ActiveArea(*entry))
        self._setupMouseRegions()

    def _setupMouseRegions(self):
        for area in self._entrys:
            pywmhelpers.addMouseRegion(*(area.getMouseRegion()));
        # pywmhelpers.addMouseRegion(0, 16, 4, 46, 25);
        #for i in range(len(self._entrys)):
        #    x, y = getXY(i)
        #    if not self._entrys[i] is None:
        #        pywmhelpers.addMouseRegion(i, x + xOffset, y + yOffset,
        #            width - 2 * xOffset, y + yOffset + letterHeight)

    def _checkForEvents(self):
        event = pywmhelpers.getEvent()
        while not event is None:
            if event['type'] == 'destroynotify':
                sys.exit(0)
            elif event['type'] == 'buttonrelease':
                region = pywmhelpers.checkMouseRegion(event['x'], event['y'])
                button = event['button']
                if region != -1:
                    if not self._entrys[region] is None:
                        self._entrys[region].mouseClicked(button)
            event = pywmhelpers.getEvent()

    def mainLoop(self):
        global reConfig
        counter = -1
        # clear Inbox -number.
        addString("Upd.", 32, 28)
        # draw ui for viewing pleasure
        pywmhelpers.redraw()
        while 1:
            counter += 1

            if reConfig:
                #print "rereading config"
                reConfig = 0
                readConfig()

            self._checkForEvents()
            if counter % 3 == 0:
                [e.tick1() for e in self._entrys if not e is None]
            if counter % 20 == 0:
                #addString("%4d" % ((counter/20) % 9999), 32, 28)
                [e.tick2() for e in self._entrys if not e is None]

            # every second, try to initiate mail update            
            if counter % 10 == 0 and getUnread():
                # if mail was updated, update string.
                addString("%4d" % unreadMailCnt, 32, 28)
                drawStatus()
                
            if counter == 999999:
                counter = -1
            pywmhelpers.redraw()
            time.sleep(0.1)

def parseCommandLine(argv):
    '''Parse the commandline. Return a dictionary with options and values.'''
    shorts = 'ht:b:r:c:'
    longs = ['help', 'text=', 'background=', 'rgbfile=', 'configfile=']
    try:
        opts, nonOptArgs = getopt.getopt(argv[1:], shorts, longs)
    except getopt.GetoptError, e:
        err('Error when parsing commandline: ' + str(e) + '\n')
        err(usage)
        sys.exit(2)
    d = {} 
    for o, a in opts:
        if o in ('-h', '--help'):
            sys.stdout.write(usage)
            sys.exit(0)
        if o in ('-t', '--text'):
            d['textcolor'] = a
        if o in ('-b', '--background'):
            d['background'] = a
        if o in ('-r', '--rgbfile'):
            d['rgbfile'] = a
        if o in ('-c', '--configfile'):
            d['configfile'] = a
    return d

def main():
    try:
        programName = sys.argv[0].split(os.sep)[-1]
    except IndexError:
        programName = ''
    sys.argv[0] = programName
    pywmhelpers.setDefaultPixmap(new_xpm)
    pywmhelpers.openXwindow(sys.argv, width, height)
    wmgmail = WMGmail()
    wmgmail.mainLoop()

# cleanup after our children.
signal.signal(signal.SIGCHLD, handlerChild)
# signal to update from saved settings-file.
signal.signal(signal.SIGHUP, handlerHUP) 


new_xpm = \
['160 100 51 1',
' 	c None',
'.	c #000100',
'+	c #0700CE',
'@	c #1F201E',
'#	c #1600FF',
'$	c #2023D6',
'%	c #373EDC',
'&	c #0076BF',
'*	c #BC3334',
'=	c #CD3636',
'-	c #4E58E2',
';	c #DB3536',
'>	c #6E706D',
',	c #5B66E3',
'm	c #BA5152',
')	c #DD4546',
'!	c #14B3A8',
'~	c #DE5C5B',
'{	c #7E8EEE',
']	c #E67475',
'^	c #BE8787',
'/	c #8798F1',
'(	c #A2A4A1',
'_	c #EC9C9D',
':	c #A3B5F7',
'<	c #B7B7B7',
'[	c #BCBCBC',
'}	c #BEBEBE',
'|	c #C0C0C0',
'1	c #FFC514',
'2	c #C4C4C4',
'3	c #B1C4F9',
'4	c #FCB3B2',
'5	c #CBCBCB',
'6	c #CECECE',
'7	c #D3D3D3',
'8	c #E2D5D5',
'9	c #FACBCB',
'0	c #DFDFDF',
'a	c #E9E9E9',
'b	c #FFE2E1',
'c	c #ECECEC',
'd	c #F0F0F0',
'e	c #F1F4F0',
'f	c #FEEEEF',
'g	c #F7F7F7',
'h	c #F8F8F8',
'i	c #FAFAFA',
'j	c #FEFEFE',
'k	c #FDFFFC',
'l	c #FFFFFF',
'                                                                @###############################################################################################',
'                                                                @#!!!##...##!!!##...##...#######################################################################',
'                                                                @#!!!##...##!!!##...##...#######################################################################',
'    55555555555~;;;)_bbbbbbbbbbbbbbbbbbb9);;;)     555555555    @#!!!##...##!!!##...##...#######################################################################',
'   5kkkkkkkkkkk~;;;;;_kkkkkkkkkkkkkkkkk9);;;;)    5kkkkkkkkk5   @#!!!##.........................................................################################',
'   5kk1111kkkkk~;;;;;)]kkkkkkkkkkkkkkk4;;;;;;)(   5kkkkkkkkk5   @#!!!##.........................................................################################',
'   5k11||10kkkk~;;;;;;;~fkkkkkkkkkkkk]=;;;;;;)(   5kkkkkkkkk5   @#!!!##.........................................................################################',
'   5k1|kk0kkkkk~;;;~;;);~bkkkkkkkkkf~);;;);;;)(   5kkkkkkkkk5   @#!!!##.........................................................################################',
'   5k1|kkkkkkkk~;;;]_;;;;;9kkkkkkkf~;;);]4;;;)(   5kkkkkkkkk5   @#!!!##.........................................................################################',
'   5k11kk1kkkkk~;;;]k4=;;;;4kkkkk9);;;;4k_;;;)(   5kkkkkkkkk5   @#!!!##.........................................................################################',
'   5kk11110kkkk~;;;]kk9;;;;;_kkk4;;;;=9ek_;;;)(   5kkkkkkkkk5   @#!!!##.........................................................################################',
'   5kkk000kkkkk~;;;]kkkb;;;;;]f_=;;;~9kkk4;;;)(   5kk~kkkkkk5   @#!!!##.........................................................################################',
'    55555555555~;;;]kkkkf;;;=;;;;;;~fkkkk_;==)(   5kk~;;kkkk5   @#!!!##...##...##...##...#######################################################################',
'               ~;;;]kkkkkk];;;;;;=]fkkkkk_);;)(   5kk~;;;;kk5   @#!!!##...##...##...##!!!#######################################################################',
'               ~;;;]kkkkkkk];;;;;_kkkkkkk_===)(   5kk~;;;*;k5   @#!!!##...##...##...##!!!#######################################################################',
'               ~;;;]kkkkkkb4_);)_49kkkkkk_;==*(   5kk;;***4k5   @#!!!##...##...##...##!!!#######################################################################',
'               ~;;;]kkkkf49kk9)9kk94fkkkk_===*(   5kk;**4fkk5   @#!!!###########################################################################################',
'               ~;;;]kkk94bkkkkkkkkkb49kkk_==**(   5kk*fkkkkk5   @#!!!##~;;;)_bbbbbbbbbbbbbbbbbbb9);;;) 5|||20gggggggggggggggggggd2|||2(#########################',
'               ~;;;]kf49fkkkkkkkkkkkk94fk_==**(   5kkkkkkkkk5   @#!!!##~;;;;;_kkkkkkkkkkkkkkkkk9);;;;) 5|||||0jjjjjjjjjjjjjjjjjd2||||2(#########################',
'               ~;;;]94fkkkkkkkkkkkkkkkf4b_==**(   5kkkkkkkkk5   @#!!!##~;;;;;)]kkkkkkkkkkkkkkk4;;;;;;)(5|||||27jjjjjjjjjjjjjjja||||||2(#########################',
'               ~;;;~9kkkkkkkkkkkkkkkkkke9]****(   5kkkkkkkkk5   @#!!!##~;;;;;;;~fkkkkkkkkkkkk]=;;;;;;)(5|||||||5ijjjjjjjjjjjj7[||||||2(#########################',
'               ~;;;]kkkkkkkkkkkkkkkkkkkkf_=***(   5kkkkkkkkk5   @#!!!##~;;;~;;);~bkkkkkkkkkf~);;;);;;)(5|||5||2|5gjjjjjjjjji52|||2|||2(#########################',
'               ~==;]kkkkkkkkkkkkkkkkkkkee_=***(   5kkkkkkkkk5   @#!!!##~;;;]_;;;;;9kkkkkkkf~;;);]4;;;)(5|||70|||||djjjjjjji5||2|7a|||2(#########################',
'               ~;;*]kkkkkkkkkkkkkkkkkeeee_=***(   5kkkkkkkkk5   @#!!!##~;;;]k4=;;;;4kkkkk9);;;;4k_;;;)(5|||7ja[||||ajjjjjd2||||aj0|||2(#########################',
'               m===m888888888888888888888^=***(   5kkkkkkkkk5   @#!!!##~;;;]kk9;;;;;_kkk4;;;;=9ek_;;;)(5|||7jjd|||||0jjja||||[dhj0|||2(#########################',
'               ****m^^^^^^^^^^^^^^^^^^^^^m****(   5kkkkkkkkk5   @#!!!##~;;;]kkkb;;;;;]f_=;;;~9kkk4;;;)(5|||7jjjg|||||7i0[|||5djjja|||2(#########################',
'                 ((((((((((((((((((((((((((((((    555555555    @#!!!##~;;;]kkkkf;;;=;;;;;;~fkkkk_;==)(5|||7jjjji|||[||||||5ijjjj0|[[2(#########################',
'                                                                @#!!!##~;;;]kkkkkk];;;;;;=]fkkkkk_);;)(5|||7jjjjjj7||||||[7ijjjjj02||2(#########################',
'                                                                @#!!!##~;;;]kkkkkkk];;;;;_kkkkkkk_===)(5|||7jjjjjjj7|||||0jjjjjjj0[[[2(#########################',
'                                                                @#!!!##~;;;]kkkkkkb4_);)_49kkkkkk_;==*(5|||7jjjjjjga02|20adjjjjjj0|[[<(#########################',
'                                                                @#!!!##~;;;]kkkkf49kk9)9kk94fkkkk_===*(5|||7jjjjiadjjd2djjdaijjjj0[[[<(#########################',
'   lkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk   @#!!!##~;;;]kkk94bkkkkkkkkkb49kkk_==**(5|||7jjjdagjjjjjjjjjgadjjj0[[<<(#########################',
'  lk+,kkkkkkk,+kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk  @#!!!##~;;;]kf49fkkkkkkkkkkkk94fk_==**(5|||7jiadijjjjjjjjjjjjdaij0[[<<(#########################',
'  kk+-kkkkkkk-+kkkkkkkkkkkkkkkkkkkkkkk&&&&&kkk&kkk&&&&&k&&&&kk  @#!!!##~;;;]94fkkkkkkkkkkkkkkkf4b_==**(5|||7daijjjjjjjjjjjjjjjiag0[[<<(#########################',
'  kk+,k+-$+,k,+-+$:kk/$+$/k,+//+,kkkkk&kkk&kk&&kkkkkkk&kkkkkkk  @#!!!##~;;;~9kkkkkkkkkkkkkkkkkke9]****(5|||5djjjjjjjjjjjjjjjjjjhd7<<<<(#########################',
'  kk+,k++/$$k,+%{$%k:+%/%+:k$$$$kkkkkk&kkk&kkk&kkkkkkk&kkkkkkk  @#!!!##~;;;]kkkkkkkkkkkkkkkkkkkkf_=***(5|||7jjjjjjjjjjjjjjjjjjjji0[<<<(#########################',
'  kk+,k+-k-+k,+3k-+k,+3k3+,k:++:kkkkkk&kkk&kkk&kkk&&&&&kk&&&kk  @#!!!##~==;]kkkkkkkkkkkkkkkkkkkee_=***(5[[|7jjjjjjjjjjjjjjjjjjjhh0[<<<(#########################',
'  kk+-k+,k,+k,+:k-+k,+3k3+,k/++{kkkkkk&kkk&kkk&kkk&kkkkkkkkkkk  @#!!!##~;;*]kkkkkkkkkkkkkkkkkeeee_=***(5||<7jjjjjjjjjjjjjjjjjhhhh0[<<<(#########################',
'  kk+,k+,k,+k,+%{$%k:+%/%$:k$%%+3kkkkk&kkk&kkk&kkk&kkkkkkkkkkk  @#!!!##m===m888888888888888888888^=***(}[[[}ccccccccccccccccccccc6[<<<(#########################',
'  lk+,k+-k,+k,+,+$3kk/$+$/k-+::$%kkkkk&&&&&kk&&&kk&&&&&k&&&&kk  @#!!!##****m^^^^^^^^^^^^^^^^^^^^^m****(<<<<}666666666666666666666}<<<<(#########################',
'   lkkkkkkfkkkkkkkkkkkkkkkkkkfkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk   @#!!!##  (((((((((((((((((((((((((((((8((((((((((((((((((((((((((((((((#########################',
'                                                                @#!!!##                                 ########################################################',
'                                                                @#!!!###########################################################################################',
'                                                                @#!!!###########################################################################################',
'                                                                @#!!!###########################################################################################',
'                                                                @#!!!###########################################################################################',
'                                                                @#!!!###########################################################################################',
'                                                                @#!!!###########################################################################################',
'                                                                @#!!!###########################################################################################',
'                                                                @#!!!###########################################################################################',
'                                                                @#!!!###########################################################################################',
'                                                                @#!!!###########################################################################################',
'                                                                @#!!!###########################################################################################',
'                                                                @#!!!###>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>###',
'                                                                @#!!!###>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>###',
'                                                                @#!!!###>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>###',
'                                                                @#!!!###>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>###',
'                                                                @#!!!###########################################################################################',
'                                                                @#!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!###',
'                                                                .#!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!###',
'                                                                @#!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!###',
'                                                                @#!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!###',
'                                                                @###############################################################################################',
'                                                                .###############################################################################################',
'kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk############################',
'k+++++kkk+kkk+++++k+++++k+kkk+k+++++k+++++k+++++k+++++k+++++kkkkkkkkkk+kkkkkkkkkk+k+kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk############################',
'k+kkk+kk++kkkkkkk+kkkkk+k+kkk+k+kkkkk+kkkkkkkkk+k+kkk+k+kkk+kk++kkkkkk+kkkkkkkkkkkk+kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk############################',
'k+kkk+kkk+kkkkkkk+kkkkk+k+kkk+k+kkkkk+kkkkkkkkk+k+kkk+k+kkk+kk++kkkkk++kkkkkkkkkkk++kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk############################',
'k+kkk+kkk+kkk+++++kk++++k+++++k+++++k+++++kkkkk+k+++++k+++++kkkkkkkkk+kkk+++++kkkk+kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk############################',
'k+kkk+kkk+kkk+kkkkkkkkk+kkkkk+kkkkk+k+kkk+kkkkk+k+kkk+kkkkk+kkkkkkkk++kkkkkkkkkkk++kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk############################',
'k+kkk+kkk+kkk+kkkkkkkkk+kkkkk+kkkkk+k+kkk+kkkkk+k+kkk+kkkkk+kk++kkkk+kkkkkkkkkkkk+kkkkk++kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk############################',
'k+++++kk+++kk+++++k+++++kkkkk+k+++++k+++++kkkkk+k+++++k+++++kk++kkkk+kkkkkkkkkkkk+k+kkk++kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk############################',
'kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk############################',
'################################################################################################################################################################',
'kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk',
'kk+++kk++++kkk++++k++++kk++++kk+++++k+++++k+kkk+kkk+kkkkkkk+k+kkk+k+kkkkk+kkk+k++++kk+++++k+++++k+++++k+++++k+++++k+++++k+kkk+k+kkk+k+kkk+k+kkk+k+kkk+k+++++kkkk',
'k+kkk+k+kkk+k+kkkkk+kkk+k+kkkkk+kkkkk+kkkkk+kkk+kkk+kkkkkkk+k+kkk+k+kkkkk++k++k+kkk+k+kkk+k+kkk+k+kkk+k+kkk+k+kkkkkkk+kkk+kkk+k+kkk+k+kkk+k+kkk+k+kkk+kkkkk+kkkk',
'k+kkk+k+kkk+k+kkkkk+kkk+k+kkkkk+kkkkk+kkkkk+kkk+kkk+kkkkkkk+k+kk+kk+kkkkk+k+k+k+kkk+k+kkk+k+kkk+k+kkk+k+kkk+k+kkkkkkk+kkk+kkk+k+kkk+k+kkk+kk+k+kk+kkk+kkkk+kkkkk',
'k+++++k++++kk+kkkkk+kkk+k++++kk++++kk+k+++k+++++kkk+kkkkkkk+k+++kkk+kkkkk+kkk+k+kkk+k+kkk+k+++++k++kk+k++++kk+++++kkk+kkk+kkk+k+kkk+k+kkk+kkk+kkk+++++kkk+kkkkkk',
'k+kkk+k+kkk+k+kkkkk+kkk+k+kkkkk+kkkkk+kkk+k+kkk+kkk+kkkkkkk+k+kk+kk+kkkkk+kkk+k+kkk+k+kkk+k+kkkkk+k+k+k+kkk+kkkkk+kkk+kkk+kkk+kk+k+kk+k+k+kk+k+kkkkkk+kk+kkkkkkk',
'k+kkk+k+kkk+k+kkkkk+kkk+k+kkkkk+kkkkk+kkk+k+kkk+kkk+kkk+kkk+k+kkk+k+kkkkk+kkk+k+kkk+k+kkk+k+kkkkk+kk++k+kkk+kkkkk+kkk+kkk+kkk+kk+k+kk++k++k+kkk+kkkkk+k+kkkkkkkk',
'k+kkk+k++++kkk++++k++++kk++++kk+kkkkk+++++k+kkk+kkk+kkkk+++kk+kkk+k++++kk+kkk+k+kkk+k+++++k+kkkkk+++++k+kkk+k+++++kkk+kkkk++++kkk+kkk+kkk+k+kkk+k+++++k+++++kkkk',
'kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk',
'################################################################################################################################################################',
'kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk',
'kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk',
'kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk',
'kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk',
'kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk',
'kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk',
'kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk',
'kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk',
'kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk',
'################################################################################################################################################################',
'################################################################################################################################################################',
'################################################################################################################################################################',
'################################################################################################################################################################',
'################################################################################################################################################################',
'################################################################################################################################################################',
'################################################################################################################################################################']

if __name__ == '__main__':
    main()
