""" Encoding: UTF-8 """

from math import sqrt
import pygame
from lang_translation import langues
import sys
import time

pygame.init()

pygame.display.set_caption("Jeu De Hex")

logo = pygame.image.load("Icon/Hex_icon.png")
pygame.display.set_icon(logo)

music = pygame.mixer.Sound("Music/Music.ogg")
music.play(256)
sound = pygame.mixer.Sound("Music/button_hover.mp3")

mainClock = pygame.time.Clock()

#-----Restoration of data
cookie = open("info.txt",'r')
all_txt = cookie.readlines()
for i in range(len(all_txt)):
    all_txt[i] = all_txt[i].replace("\n","")
r, g, b, LANG, global_font, volume = all_txt
music.set_volume(int(volume)/100)
#-----Dimensions
#---------------Screen Size
SIZE_X = 1080
SIZE_Y = 720
#----------------BOX
BOX_Y = 600
BOX_X = BOX_Y* sqrt(3)
BOTTOM_BOX=SIZE_Y-25
TOP_BOX = BOTTOM_BOX - BOX_Y
LEFT_BOX = (SIZE_X-BOX_X)/2
RIGHT_BOX = (SIZE_X-BOX_X)/2 + BOX_X
MIDY_BOX = (TOP_BOX + BOTTOM_BOX)/2
#-----------Colors

var_red = var_green = var_blue = False

if int(r) > 235 and int(g) > 235 and int(b) > 235:
    screen_color = (235,235,235)
elif int(r) < 50 and int(g) < 50 and int(b) < 50:
    screen_color = (50, 50, 50)
else:
    screen_color = ( int(r) , int(g) , int(b)) #255 , 224 , 0
print(screen_color)

dark_screen_color = (int(round(float(r)/1.13,0)) , int(round(float(g)/1.13,0)) , int(round(float(b)/1.13,0))) #225, 200, 0

def light_color(x):
    y = int(165.0 + float(90/255)*float(x))
    y = min(y, 255)
    return y

light_effet = (light_color(r), light_color(g), light_color(b)) #252, 244, 164
darker_color = ( max( int(r) - 50 , 0),max( int(g) - 50 , 0),max( int(b) - 50 , 0))
white = (255 , 255 , 255)
black = (0 , 0 , 0)
beige = (230, 215, 188)
gray = (200, 200, 200)
d_gray = (32, 32, 32)
l_gray = (230, 230, 230)

# ----- Screen
screen = pygame.display.set_mode((SIZE_X, SIZE_Y), pygame.RESIZABLE )#, pygame.RESIZABLE
screen.fill(screen_color)
pygame.display.flip()

#---Button
def switch_font(size, bold, italic):
    # --- Roboto
    if LANG in ['fr', 'en', 'gr', 'sw']:
        font =  pygame.font.SysFont(global_font,size, bold, italic)

    # --- Japanese
    elif LANG == 'jp':
        font = pygame.font.Font("Fonts/MPLUSRounded1c-Medium.ttf", size-10)

    # --- Korean
    elif LANG == 'kr':
        font = pygame.font.Font("Fonts/DoHyeon-Regular.ttf", size)
    a_file = open("info.txt", "r")
    list_of_lines = a_file.readlines()
    list_of_lines[4] = str(font)+"\n"

    with open("info.txt", "w") as a_file:
        a_file.writelines(list_of_lines)

    return font

def text(txt,x,y,z,color,bold, italic):
    font = switch_font(z, bold, italic)
    text2 = font.render(langues[txt].get(LANG), True, color)
    screen.blit(text2, (x,y))

def main_button(txt,x,y,color):
    font = switch_font(75,False,False)
    play_text = font.render("> "+langues[txt].get(LANG), True, color)
    rect = pygame.Rect(x, y , SIZE_X/2.5, 80)
    f_rect = pygame.draw.rect(screen, screen_color, rect )
    screen.blit(play_text, (x, y))
    return  f_rect

def exit_sys(event):
    if event.type == pygame.QUIT:
        sys.exit()
'''
def animation(button, text,y ):

    mouse_x , mouse_y = pygame.mouse.get_pos()
    if not button.collidepoint((mouse_x, mouse_y)):
        button = main_button(text,SIZE_X/15,y,black)
        var = True
    try:
        if button.collidepoint((mouse_x, mouse_y)) and var:
            for _ in range(50):
                button = main_button(text,SIZE_X/15+_,y,(int(5.1 * _),int(5.1 * _),int(5.1 * _)))
                pygame.display.flip()
            var = False
    except UnboundLocalError:
        if button.collidepoint((mouse_x, mouse_y)):
            for _ in range(50):
                button = main_button(text,SIZE_X/15+_,y,(int(5.1 * _),int(5.1 * _),int(5.1 * _)))
                pygame.display.flip()
            var = False
'''
def menu():
    screen.fill(screen_color)
    running = True
    click = True
    var_time = 0
    previousClock = 0
    time_loop = 0
    play_button = main_button("play",SIZE_X/15,2*SIZE_Y/5 ,black)
    option_button = main_button("option",SIZE_X/15,3*SIZE_Y/5 - 30,black)
    quit_button = main_button("quit",SIZE_X/15,4*SIZE_Y/5 - 60,black)
    if LANG == 'jp':
        text("hex_game",SIZE_X/20,SIZE_Y/5 - 30, 100, black, False, False)
    else:
        text("hex_game",SIZE_X/20,SIZE_Y/5 - 30, 150, black, False, False)
    text("v",SIZE_X- 75,SIZE_Y - 30, 25, black, False, False)
    rect = pygame.Rect(SIZE_X/15, 2*SIZE_Y/5 , 30, SIZE_Y/2)
    pygame.draw.rect(screen, screen_color, rect )
    while running:

        #-----Play Button
        mouse_x , mouse_y = pygame.mouse.get_pos()

        if not play_button.collidepoint((mouse_x, mouse_y)):
            play_button = main_button("play",SIZE_X/15,2*SIZE_Y/5,black)
            var = True
        if play_button.collidepoint((mouse_x, mouse_y)) and var:
            for _ in range(20):
                play_button = main_button("play",SIZE_X/15+_*2,2*SIZE_Y/5,(int(12.75 * _),int(12.75 * _),int(12.75 * _)))
                pygame.draw.rect(screen, screen_color, rect )
                pygame.display.flip()
            sound.play()
            var = False
        if play_button.collidepoint((mouse_x, mouse_y)) and click:
            game_menu()

        #-------Option Button
        if not option_button.collidepoint((mouse_x, mouse_y)):
            option_button = main_button("option",SIZE_X/15,3*SIZE_Y/5 - 30,black)
            var_opt = True
        if option_button.collidepoint((mouse_x, mouse_y)) and var_opt:
            for _ in range(20):
                option_button = main_button("option",SIZE_X/15+_*2,3*SIZE_Y/5 -30,(int(12.75 * _),int(12.75 * _),int(12.75 * _)))
                pygame.draw.rect(screen, screen_color, rect )
                pygame.display.flip()
            sound.play()

            var_opt = False
        if option_button.collidepoint((mouse_x, mouse_y)) and click:
            langue(0)

        #-------Quit Button
        if not quit_button.collidepoint((mouse_x, mouse_y)):
            quit_button = main_button("quit",SIZE_X/15,4*SIZE_Y/5 - 60,black)
            var_qt = True
        if quit_button.collidepoint((mouse_x, mouse_y)) and var_qt:
            for _ in range(20):
                quit_button = main_button("quit",SIZE_X/15+_*2,4*SIZE_Y/5 - 60,(int(12.75 * _),int(12.75 * _),int(12.75 * _)))
                pygame.draw.rect(screen, screen_color, rect )
                pygame.display.flip()
            sound.play()
            var_qt = False
        if quit_button.collidepoint((mouse_x, mouse_y)) and click:
            sys.exit()
        var_time += pygame.time.get_ticks() - previousClock
        previousClock = pygame.time.get_ticks()
        #print(pygame.time.get_ticks())
        if var_time > 15000:
            var_time = 0
            time_loop += 1
            if time_loop == 4:
                time_loop = 0
            def load_image(x,img_name,img_txt, img_txt2):
                if time_loop == x:
                    #For text bg
                    bg_rect = pygame.Rect(SIZE_X/2, 4*SIZE_Y/5 , SIZE_X/2, 90)
                    pygame.draw.rect(screen, screen_color, bg_rect )
                    # For Image bf
                    SIZE_IMG = 400
                    bg_rect_img = pygame.Rect(4*SIZE_X/5 - 200,4*SIZE_Y/5 - 400,SIZE_IMG,SIZE_IMG)
                    #Image
                    pygame.draw.rect(screen, screen_color, bg_rect_img )
                    image = pygame.image.load("Icon/"+img_name+".png")
                    image = pygame.transform.scale(image, (SIZE_IMG, SIZE_IMG))
                    screen.blit(image, [4*SIZE_X/5 - 200,4*SIZE_Y/5 - 400])
                    #Text to describe image
                    font = switch_font(30, False, False)
                    text_img = font.render(langues[img_txt].get(LANG), True, black)
                    text_rect = text_img.get_rect(center=(4*SIZE_X/5,4*SIZE_Y/5 + 30))
                    text_img2 = font.render(langues[img_txt2].get(LANG), True, black)
                    text_rect2 = text_img2.get_rect(center=(4*SIZE_X/5,4*SIZE_Y/5 + 60))
                    screen.blit(text_img, text_rect)
                    screen.blit(text_img2, text_rect2)
            load_image(0,"github","github","github2")
            load_image(1,"paint","custom_color","custom_color2")
            load_image(2,"logo_menu","mode","mode2")
            load_image(3,"flags","flags"," ")

        click = False
        for event in pygame.event.get():
            exit_sys(event)
            if event.type == pygame.MOUSEBUTTONDOWN and event.button == 1:
                click = True
        pygame.draw.rect(screen, screen_color, rect )
        pygame.display.flip()

def play(x, img, ico, txt,des,des2):

    #---Rect
    play_rect = pygame.Rect(x,SIZE_Y/3,SIZE_X/5,SIZE_Y/2)
    header_rect = pygame.Rect(x,SIZE_Y/3,SIZE_X/5,SIZE_Y/15)
    text_rect = pygame.Rect(x,SIZE_Y/3 + 0.3 *SIZE_Y,SIZE_X/5,3*SIZE_Y/15)
    pygame.draw.rect(screen, d_gray, header_rect)
    pygame.draw.rect(screen, gray, text_rect)

    #---Image
    image = pygame.image.load("Icon/"+img+".png")
    image = pygame.transform.scale(image, (int(SIZE_X/5), int(SIZE_X/5)))
    screen.blit(image, [x,SIZE_Y/3 + SIZE_Y/15])

    #---icon
    icon = pygame.image.load("Icon/"+ico+".png")
    icon = pygame.transform.scale(icon, (30, 30))
    rect_icon = icon.get_rect(center=(x + SIZE_X/10,SIZE_Y/3 + 0.3 *SIZE_Y+60))
    screen.blit(icon, rect_icon)

    #---Title
    font = switch_font(47, False, False)
    title_header = font.render(langues[txt].get(LANG), True, white)
    header_text = title_header.get_rect(center = ( x + SIZE_X/10 , SIZE_Y/3 + SIZE_Y/30))
    screen.blit(title_header, header_text)

    #---Description
    if LANG == 'gr':
        font_des = switch_font(15, False, False)
    else:
        font_des = switch_font(20, False, False)
    des = font_des.render(langues[des].get(LANG), True, black)
    des_text = des.get_rect(center = ( x + SIZE_X/10 , SIZE_Y/3 + SIZE_Y/2.4))
    screen.blit(des, des_text)

    des2 = font_des.render(langues[des2].get(LANG), True, black)
    des_text2 = des2.get_rect(center = ( x + SIZE_X/10 , SIZE_Y/3 + SIZE_Y/2.25))
    screen.blit(des2, des_text2)

    return play_rect

def play_hover(button,x,y,z, img, ico, txt,des,des2,click,function,para):
    if not button.collidepoint((x,y)):
        pygame.draw.rect(screen, screen_color, pygame.Rect(z - 5 ,SIZE_Y/3 - 5 ,SIZE_X/5 +10 ,SIZE_Y/2 + 10))
    elif button.collidepoint((x,y)) and click:
        if para =="":
            function()
        else:
            function(para)
    elif button.collidepoint((x,y)):
        pygame.draw.rect(screen, white, pygame.Rect(z - 5 ,SIZE_Y/3 - 5 ,SIZE_X/5 +10 ,SIZE_Y/2 + 10))
    play(z,img,ico,txt,des,des2)

bool_hover = False
def back_button(mx,my, click):
    global bool_hover
    x=100
    arrow = [ (x,75),
    (x+20,30),
    (x+40,30),
    (x+20,75),
    (x+40,120),
    (x+20,120)
    ]
    anti_arrow = [ (0,28),
    (x+18,28),
    (x-2,75),
    (x+18,122),
    (0,122)
    ]
    anti_anti_arrow = [ (x+42,30),
    (x+22,75),
    (x+42,120),
    (300,120),
    (300,30)
    ]

    s = pygame.Surface((40,90))  # the size of your rect
    s.set_alpha(0)                # alpha level
    s.fill((255,255,255))           # this fills the entire surface
    screen.blit(s, (100,30))
    if not screen.blit(s, (100,30)).collidepoint((mx,my)):
        _extracted_from_back_button_30(arrow, anti_arrow)
        pygame.draw.polygon(screen, dark_screen_color, anti_anti_arrow)
        bool_hover = False
    elif screen.blit(s, (100,30)).collidepoint((mx,my)) and not bool_hover:
        for _ in range(15):
            pygame.draw.polygon(screen, dark_screen_color, arrow)
            pygame.draw.polygon(screen, dark_screen_color, arrow,4)
            x -= 4
            text_rectt = pygame.Rect(x+20,40,-3.5 * (x-100),70)
            pygame.draw.rect(screen, light_effet, text_rectt)
            if LANG in {'jp','kr'}:
                back_font = switch_font(50, False, False)
            else:
                back_font = switch_font(75, False, False)
            text_back = back_font.render(langues["back"].get(LANG), True, black)
            screen.blit(text_back, (70, 53))
            arrow = [ (x,75), (x+20,30),(x+40,30),(x+20,75),(x+40,120),(x+20,120)]
            anti_arrow = [ (0,28),(x+18,28),(x-2,75),(x+18,122),(0,122)]
            _extracted_from_back_button_30(arrow, anti_arrow)
            pygame.display.flip()
        bool_hover = True
    elif screen.blit(s, (100,30)).collidepoint((mx,my)) and click:
        menu()

    return arrow

def _extracted_from_back_button_30(arrow, anti_arrow):
    pygame.draw.polygon(screen, white, arrow)
    pygame.draw.polygon(screen, black, arrow,4)
    pygame.draw.polygon(screen, dark_screen_color, anti_arrow)

def game_menu():

    screen.fill(screen_color)

    #Header
    Header = pygame.Rect(0,0,SIZE_X, 150)
    pygame.draw.rect(screen, dark_screen_color, Header)

    #-----Title
    font = switch_font(100, False, False)

    title = font.render(langues["play"].get(LANG), True, white)
    title_border = font.render(langues["play"].get(LANG), True, black )

    rect_title = title.get_rect(center=(SIZE_X/2,75))
    rect_title_bl = title.get_rect(center=(SIZE_X/2-2,73))
    rect_title_br = title.get_rect(center=(SIZE_X/2+2,73))
    rect_title_tl = title.get_rect(center=(SIZE_X/2-2,77))
    rect_title_tr = title.get_rect(center=(SIZE_X/2+2,77))
    screen.blit(title_border, rect_title_bl)
    screen.blit(title_border, rect_title_br)
    screen.blit(title_border, rect_title_tr)
    screen.blit(title_border, rect_title_tl)
    screen.blit(title, rect_title)

    local_button = play(SIZE_X/25,"local","house","local","des_local","des_local2")
    online_button = play(SIZE_X/5 + (SIZE_X/25)*2,"online","WWW","online","des_online","des_online2")
    ia_button = play(2*(SIZE_X/5)+ (SIZE_X/25)*3,"IA","ai","Computer","des_ia","des_ia2")
    _button = play(3*(SIZE_X/5)+ (SIZE_X/25)*4,"?","?2","?"," ", " ")

    #-------

    click = False
    pygame.display.flip()
    while 1:
        mouse_x , mouse_y = pygame.mouse.get_pos()
        back_button(mouse_x,mouse_y,click)
        play_hover(local_button,mouse_x,mouse_y,SIZE_X/25, "local","house","local","des_local","des_local2",click,choosing_lenght,"")
        play_hover(online_button,mouse_x,mouse_y,SIZE_X/5 + (SIZE_X/25)*2,"online","WWW","online","des_online","des_online2",click,menu,"")
        play_hover(ia_button,mouse_x,mouse_y,2*(SIZE_X/5)+ (SIZE_X/25)*3,"IA","ai","Computer","des_ia","des_ia2",click,menu,"")
        play_hover(_button,mouse_x,mouse_y,3*(SIZE_X/5)+ (SIZE_X/25)*4,"?","?2","?"," ", " ",click,menu,"")

        click = False
        for event in pygame.event.get():
            exit_sys(event)
            if event.type == pygame.MOUSEBUTTONDOWN and event.button == 1:
                click = True
        pygame.display.flip()

def flag_icon(flag,color,nb,txt,x,y,click,page):
    global LANG
    flag = pygame.image.load(f"Flags/{flag}.png")
    flag.convert()
    #---Rescale
    HEIGHT_FLAG = 33
    WIDTH_FLAG = 50
    flag = pygame.transform.scale(flag, (WIDTH_FLAG, HEIGHT_FLAG))
    margin = 50
    # --- Main
    flag_rect = pygame.Rect(margin,300+nb*80,SIZE_X - 2*margin, 60)
    pygame.draw.rect(screen, l_gray, flag_rect, border_radius= 5)
    # --- Left-border
    flag_rect_lborder = pygame.Rect(margin,300+nb*80,10, 60)
    flag_rect_lborder2 = pygame.Rect(margin+5,300+nb*80,10, 60)
    pygame.draw.rect(screen, color, flag_rect_lborder, border_radius= 5)
    pygame.draw.rect(screen, color, flag_rect_lborder2)
    screen.blit(flag, [margin + 20, 310+nb*80])
    # --- txt
    if LANG in {'jp', 'kr'}:
        flag_font =  switch_font(45, False, False)
    else:
        flag_font =  switch_font(60, False, False)
    flag_txt = flag_font.render(langues[txt].get(LANG), True, black)
    screen.blit(flag_txt,(margin + WIDTH_FLAG + 20,310+nb*80))

    if flag_rect.collidepoint((x,y)) and click:
        LANG = txt
        a_file = open("info.txt", "r")
        list_of_lines = a_file.readlines()
        list_of_lines[3] = str(txt)+"\n"

        with open("info.txt", "w") as a_file:
            a_file.writelines(list_of_lines)

        langue(page)

def underHeaderButton(x,y,nb,txt,click):
    if LANG =='gr':
        under_font =  switch_font(45, False, False)
    else:
        under_font =  switch_font(60, False, False)
    under_rect = pygame.Rect(nb * SIZE_X/3,150,SIZE_X/3,100 )
    under_txt = under_font.render(langues[txt].get(LANG), True, black)
    under_center = under_txt.get_rect(center=( (2*nb+1) * SIZE_X / 6,200))
    if pygame.draw.rect(screen, screen_color,under_rect).collidepoint((x,y)) and click:
        if txt=='languages':
            langue(0)
        elif txt == 'background-color':
            background_color()
        else:
            sound_menu()
    if pygame.draw.rect(screen, screen_color,under_rect).collidepoint((x,y)):
        pygame.draw.rect(screen, darker_color,under_rect)
    screen.blit(under_txt, under_center)

def triangle_back(x,y,click):
    arrow = [(100,30), (100, 120) , (33,75)]
    arrow_rect = pygame.draw.polygon(screen,white,arrow)
    if arrow_rect.collidepoint((x,y)) and click:
        menu()

def langue(page):
    #Header
    screen.fill(light_effet)
    Header = pygame.Rect(0,0,SIZE_X, 150)
    pygame.draw.rect(screen, dark_screen_color, Header)
    underHeader = pygame.Rect(0,150,SIZE_X, 100)
    pygame.draw.rect(screen, screen_color, underHeader)
    #-----Title
    font = switch_font(110, False, False)
    #---LAnguage

    title = font.render(langues["option"].get(LANG), True, white)
    rect_title = title.get_rect(center=(SIZE_X/2,75))
    screen.blit(title, rect_title)
    click = False

    # --- Switch Page

    arrow = font.render(">", True, black)
    rect_arrow = arrow.get_rect(center=(SIZE_X - 25, 490))
    screen.blit(arrow, rect_arrow)

    while 1:

        mouse_x, mouse_y = pygame.mouse.get_pos()

        triangle_back(mouse_x,mouse_y,click)
        underHeaderButton(mouse_x,mouse_y,0,"languages",click)
        underHeaderButton(mouse_x,mouse_y,1,"background-color",click)
        underHeaderButton(mouse_x,mouse_y,2,"music",click)

        if rect_arrow.collidepoint((mouse_x,mouse_y)) and click:
            next_page = page + 1
            if next_page > 1:
                next_page = 0
            langue(next_page)

        if page == 0:
            flag_icon('fr',(0, 85, 164),0,'fr',mouse_x,mouse_y,click,page)
            flag_icon('us',(178, 34, 52),1,'en',mouse_x,mouse_y,click,page)
            flag_icon('jp',(188, 0, 45),2,'jp',mouse_x,mouse_y,click,page)
            flag_icon('kr',(0,0,0),3,'kr',mouse_x,mouse_y,click,page)
            flag_icon('gr',(13, 94, 175),4,'gr',mouse_x,mouse_y,click,page)
        else:
            flag_icon('sw',(0, 106, 168),0,'sw',mouse_x,mouse_y,click,page)
        click = False
        for event in pygame.event.get():
            exit_sys(event)
            if event.type == pygame.MOUSEBUTTONDOWN and event.button == 1:
                click = True
        pygame.display.flip()

def slider(x,y,nb,color,realcolor):
    global var_red, var_green, var_blue
    change_volume_frame = pygame.Rect(95, SIZE_Y/2 -55+ nb * SIZE_Y/5, SIZE_X - 190, 110 )
    pygame.draw.rect(screen, black, change_volume_frame)
    change_volume_background = pygame.Rect(100, SIZE_Y/2 -50 + nb * SIZE_Y/5 , SIZE_X - 200, 100 )
    pygame.draw.rect(screen, gray, change_volume_background)
    change_volume_basic = pygame.Rect(100, SIZE_Y/2 -50 + nb * SIZE_Y/5, (SIZE_X-100)*int(realcolor)/255-100, 100 )
    if color == 'r':
        pygame.draw.rect(screen, (int(realcolor),0,0), change_volume_basic)
        varf = var_red
    elif color == 'g':
        pygame.draw.rect(screen, (0,int(realcolor),0), change_volume_basic)
        varf = var_green
    else:
        pygame.draw.rect(screen, (0,0,int(realcolor)), change_volume_basic)
        varf = var_blue
    if change_volume_background.collidepoint((x,y)) and varf:
        degre = _extracted_from_slider_18(x, nb, color, change_volume_background)
    if not change_volume_background.collidepoint((x,y)):
        if color == 'r':
            var_red = False
        elif color == 'g':
            var_green = False
        else:
            var_blue = False
    try:
        if degre is None:
            degre = realcolor
    except UnboundLocalError:
        degre = realcolor
    return degre

def _extracted_from_slider_18(x, nb, color, change_volume_background):
    result = int(round((((x -100 )/( SIZE_X -100)) * 100) * (10/8.97), 0))*2.55
    result = min(result, 255)
    result = max(result, 0)
    change_volume = pygame.Rect(100, SIZE_Y/2 -50 + nb * SIZE_Y/5, x-100, 100 )
    a_file = open("info.txt", "r")
    list_of_lines = a_file.readlines()
    if color == 'r':
        color2 = result, 0, 0
        list_of_lines[0] = str(int(result)) + "\n"

    elif color == 'g':
        color2 = 0, result, 0
        list_of_lines[1] = str(int(result)) + "\n"
    else:
        color2 = 0, 0, result
        list_of_lines[2] = str(int(result)) + "\n"

    with open("info.txt", "w") as a_file:
        a_file.writelines(list_of_lines)
    pygame.draw.rect(screen, gray, change_volume_background)
    pygame.draw.rect(screen, color2, change_volume)
    return result

def background_color():
    global var_red, var_green, var_blue
    global r, g, b , screen_color, light_effet, dark_screen_color, darker_color
    Header = pygame.Rect(0,0,SIZE_X, 150)
    underHeader = pygame.Rect(0,150,SIZE_X, 100)
    #-----Title
    font = switch_font(110, False, False)
    #---LAnguage

    title = font.render(langues["option"].get(LANG), True, white)
    rect_title = title.get_rect(center=(SIZE_X/2,75))
    click = False
    while 1:
        screen.fill(light_effet)
        pygame.draw.rect(screen, dark_screen_color, Header)
        pygame.draw.rect(screen, screen_color, underHeader)
        screen.blit(title, rect_title)
        mouse_x, mouse_y = pygame.mouse.get_pos()#54654865424654868
        r = slider(mouse_x,mouse_y,0,'r',r)
        g = slider(mouse_x,mouse_y,1,'g',g)
        b = slider(mouse_x,mouse_y,2,'b',b)

        triangle_back(mouse_x,mouse_y,click)
        underHeaderButton(mouse_x,mouse_y,0,"languages",click)
        underHeaderButton(mouse_x,mouse_y,1,"background-color",click)
        underHeaderButton(mouse_x,mouse_y,2,"music",click)

        # ---- CHanging COLORS

        if int(r) > 235 and int(g) > 235 and int(b) > 235:
            screen_color = (235,235,235)
        elif int(r) < 50 and int(g) < 50 and int(b) < 50:
            screen_color = (50, 50, 50)
        else:
            screen_color = ( int(r) , int(g) , int(b)) #255 , 224 , 0

        dark_screen_color = (int(round(float(r)/1.13,0)) , int(round(float(g)/1.13,0)) , int(round(float(b)/1.13,0))) #225, 200, 0

        light_effet = (light_color(r), light_color(g), light_color(b)) #252, 244, 164
        darker_color = ( max( int(r) - 50 , 0),max( int(g) - 50 , 0),max( int(b) - 50 , 0))

        # -----------

        if click:
            var_red = not var_red
            var_green = not var_green
            var_blue = not var_blue

        click = False
        for event in pygame.event.get():
            exit_sys(event)
            if event.type == pygame.MOUSEBUTTONDOWN and event.button == 1:
                click = True
        pygame.display.flip()

def sound_menu():

    global volume

    Header = pygame.Rect(0,0,SIZE_X, 150)
    underHeader = pygame.Rect(0,150,SIZE_X, 100)
    #-----Title
    font = switch_font(110, False, False)
    #---LAnguage

    title = font.render(langues["option"].get(LANG), True, white)
    rect_title = title.get_rect(center=(SIZE_X/2,75))

    screen.fill(light_effet)
    pygame.draw.rect(screen, dark_screen_color, Header)
    pygame.draw.rect(screen, screen_color, underHeader)
    screen.blit(title, rect_title)

    back_font = switch_font(50, False, True)
    vol_text = back_font.render( str(volume) + "%", True, black)
    vol_rect = vol_text.get_rect(center=(SIZE_X/2,SIZE_Y/1.75 +100))
    screen.blit(vol_text, vol_rect)

    sound_font = switch_font(70, False, False)
    sound_text = sound_font.render(langues["vol_music"].get(LANG), True, black)
    sound_rect = sound_text.get_rect(center=(SIZE_X/2, SIZE_Y/1.75 -100))

    screen.blit(sound_text, sound_rect)

    change_volume_background = pygame.Rect(100, SIZE_Y/1.75 -50, SIZE_X - 200, 100 )
    change_volume_frame = pygame.Rect(95, SIZE_Y/1.75 -55, SIZE_X - 190, 110 )

    pygame.draw.rect(screen, black, change_volume_frame)
    pygame.draw.rect(screen, screen_color, change_volume_background)

    click = False
    click_slider = False
    while 1:

        mouse_x, mouse_y = pygame.mouse.get_pos()

        triangle_back(mouse_x,mouse_y,click)

        if change_volume_background.collidepoint((mouse_x, mouse_y)) and click_slider:
            volume = round((((mouse_x -100 )/( SIZE_X -100)) * 100) * (10/8.97), 1)
            vol_text = back_font.render( str(volume) + "%", True, black)
            vol_rect = vol_text.get_rect(center=(SIZE_X/2,SIZE_Y/1.75 +100))
            vol_rect2 = pygame.Rect(100,SIZE_Y/1.75 + 55,SIZE_X - 190, 110)
            change_volume = pygame.Rect(100, SIZE_Y/1.75 -50, mouse_x-100, 100 )
            pygame.draw.rect(screen, gray, change_volume_background)
            pygame.draw.rect(screen, screen_color, change_volume)
            pygame.draw.rect(screen, light_effet, vol_rect2)
            screen.blit(vol_text, vol_rect)
            music.set_volume(volume/100)
            a_file = open("info.txt", "r")
            list_of_lines = a_file.readlines()
            list_of_lines[5] = str(int(volume)) + "\n"

            with open("info.txt", "w") as a_file:
                a_file.writelines(list_of_lines)

        if not change_volume_background.collidepoint((mouse_x, mouse_y)):
            click_slider = False

        underHeaderButton(mouse_x,mouse_y,0,"languages",click)
        underHeaderButton(mouse_x,mouse_y,1,"background-color",click)
        underHeaderButton(mouse_x,mouse_y,2,"music",click)

        click = False
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                running = False
                sys.exit()
            if event.type == pygame.MOUSEBUTTONDOWN and event.button == 1:
                click_slider = True
                click = True
        pygame.display.flip()

def choosing_lenght():
    """ The Menu to change the lenght of the tray """

    screen.fill(screen_color)
    title_font = switch_font(75, False, False)

    #TITLE
    title = title_font.render(langues["local"].get(LANG), True, (0 , 0 ,0))
    title_rect =title.get_rect(center=(SIZE_X/2, 50))
    screen.blit(title,title_rect)

    K=0

    #Back Button
    button_return = pygame.Rect(10, 10 , 200, 75)
    click_button = pygame.draw.rect(screen, screen_color, button_return)
    back_font = switch_font(50, False, True)
    back_text = back_font.render(" << "+langues["back"].get(LANG), True, black)

    back_center = back_text.get_rect(center=(105, 43))
    pygame.draw.rect(screen, black, button_return, 5)
    screen.blit(back_text, back_center)

    change_lenght_background = pygame.Rect(100, SIZE_Y/2 -50, SIZE_X - 200, 100 )
    change_lenght_frame = pygame.Rect(95, SIZE_Y/2 -55, SIZE_X - 190, 110 )

    pygame.draw.rect(screen, black, change_lenght_frame)
    pygame.draw.rect(screen, gray, change_lenght_background)

    _extracted_from_choosing_lenght_29(70, "tray_lenght", 100)
    # ctc <=> Click to change
    ctc_font = switch_font(20, False, False)
    ctc_text = ctc_font.render(langues["clic_to_change"].get(LANG), True, black)
    ctc_rect = ctc_text.get_rect(bottomright=(SIZE_X - 150, SIZE_Y/2 - 60))
    screen.blit(ctc_text, ctc_rect)

    arrow_file = pygame.image.load("Icon/arrow.png")
    arrow = pygame.transform.scale(arrow_file, (100, 100))
    #---Showing Images
    screen.blit(arrow, [SIZE_X - 150, SIZE_Y/2 - 100])

    #-------Let's GO Button

    WIDTH_BUTTON2 = 300
    HEIGHT_BUTTON2 = 100
    MARGIN_TOP2 = -200 # MARGIN_TOP > HEIGHT_BUTTON

    letsgo_button = pygame.Rect((SIZE_X - WIDTH_BUTTON2)/2, (SIZE_Y - HEIGHT_BUTTON2)/2 - MARGIN_TOP2, WIDTH_BUTTON2, HEIGHT_BUTTON2)
    letsgo_button_2 = pygame.Rect((SIZE_X - WIDTH_BUTTON2)/2, (SIZE_Y - HEIGHT_BUTTON2)/2 - MARGIN_TOP2, WIDTH_BUTTON2 , HEIGHT_BUTTON2/2)
    letsgo_button_4 = pygame.Rect((SIZE_X - WIDTH_BUTTON2)/2 + 50, (SIZE_Y - HEIGHT_BUTTON2)/2 - MARGIN_TOP2, WIDTH_BUTTON2-100 , HEIGHT_BUTTON2/4)

    pygame.draw.rect(screen, dark_screen_color, letsgo_button, border_radius= 5)
    pygame.draw.rect(screen, screen_color, letsgo_button_2, border_radius= 5)
    pygame.draw.rect(screen, light_effet, letsgo_button_4, border_radius= 5)
    pygame.draw.rect(screen, black, letsgo_button, 5 ,border_radius= 5)
    pygame.display.flip()

    _extracted_from_choosing_lenght_29(50, "letsgo", MARGIN_TOP2)
    running = True
    click = False
    while running:
        mouse_x , mouse_y = pygame.mouse.get_pos()

        if click_button.collidepoint((mouse_x, mouse_y)) and click:
            main()

        if change_lenght_background.collidepoint((mouse_x, mouse_y)) and click:
            lenght_plate = int(round((((mouse_x -100 )/( SIZE_X -100)) * 45) * (10/8.97)+5, 0))
            vol_text = back_font.render( str(lenght_plate) + "x" + str(lenght_plate), True, black)
            vol_rect = vol_text.get_rect(center=(SIZE_X/2,SIZE_Y/2 +100))
            change_volume = pygame.Rect(100, SIZE_Y/2 -50, mouse_x-100, 100 )
            pygame.draw.rect(screen, gray, change_lenght_background)
            pygame.draw.rect(screen, white, change_volume)
            pygame.draw.rect(screen, screen_color, vol_rect)
            screen.blit(vol_text, vol_rect)

        if not change_lenght_background.collidepoint((mouse_x, mouse_y)):
            click = False

        if K==8:
            lenght_plate = 100
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                running = False
                sys.exit()
            if event.type == pygame.MOUSEBUTTONDOWN and event.button == 1:
                click = True
            if event.type == pygame.MOUSEBUTTONDOWN and letsgo_button.collidepoint((mouse_x, mouse_y)):
                try:
                    game(lenght_plate)
                except UnboundLocalError:
                    game(11)
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_UP and K in {0, 1}:
                    K+=1
                elif event.key == pygame.K_DOWN and K in {2, 3}:
                    K+=1
                elif event.key == pygame.K_LEFT and K in {4, 6}:
                    K+=1
                elif event.key == pygame.K_RIGHT and K in {5, 7}:
                    K+=1
                else:
                    K=0

        pygame.display.flip()

def _extracted_from_choosing_lenght_29(arg0, arg1, arg2):
    lenght_font = switch_font(arg0, False, False)
    lenght_text = lenght_font.render(langues[arg1].get(LANG), True, black)
    lenght_rect = lenght_text.get_rect(center=(SIZE_X/2, SIZE_Y/2 - arg2))
    screen.blit(lenght_text, lenght_rect)

def game(x):

    """ The Game """

    POSITION_FOUND2 = False
    screen.fill(screen_color)
    title_font = switch_font(75, False, False)
    title = title_font.render(langues["local"].get(LANG), True, (0 , 0 ,0))
    title_rect =title.get_rect(center=(SIZE_X/2, 50))
    screen.blit(title,title_rect)

    #Back Button
    button_return = pygame.Rect(10, 10 , 200, 75)
    click_button = pygame.draw.rect(screen, screen_color, button_return)
    back_font = switch_font(50, False, True)
    back_text = back_font.render(" << "+langues["back"].get(LANG), True, black)

    back_center = back_text.get_rect(center=(105, 43))

    pygame.draw.rect(screen, black, button_return, 5)
    screen.blit(back_text, back_center)

    #-----Plateau
    #---------------Fond
    box  = [(LEFT_BOX, TOP_BOX),(RIGHT_BOX,TOP_BOX),(RIGHT_BOX,BOTTOM_BOX),(LEFT_BOX, BOTTOM_BOX)]
    bordures = [(SIZE_X/2, TOP_BOX),(RIGHT_BOX,MIDY_BOX),(SIZE_X/2,BOTTOM_BOX),(LEFT_BOX, MIDY_BOX)]
    phase_blanche  = [(SIZE_X/2, TOP_BOX),(SIZE_X/2,BOTTOM_BOX),(RIGHT_BOX,MIDY_BOX),(LEFT_BOX, MIDY_BOX)]

    pygame.draw.polygon(screen, screen_color, box)
    pygame.draw.polygon(screen, black, bordures)
    pygame.draw.polygon(screen, white, phase_blanche)
    #---------------Hexagones
    lenght_plate = x
    border_plate_size = sqrt((BOTTOM_BOX-MIDY_BOX)**2+(RIGHT_BOX-BOX_X/2)**2)
    hex_border = ((border_plate_size)/2)/lenght_plate
    marge = 72.5
    Hexa_color = []
    #print(f"BotBox = {BOTTOM_BOX} / Mid Box = {MIDY_BOX} / border plate size = {border_plate_size}")
    for i in range(lenght_plate):
        for j in range(lenght_plate):
            hexagone = [(LEFT_BOX + marge + hex_border/2 + j*(3/2)*hex_border +i*(3/2)*hex_border , MIDY_BOX + sqrt(3)*hex_border/2 - (sqrt(3)*j/2)*hex_border + (sqrt(3)*i/2)*hex_border),
            (LEFT_BOX + marge + j*(3/2)*hex_border +i*(3/2)*hex_border,MIDY_BOX - (sqrt(3)*j/2)*hex_border+ (sqrt(3)*i/2)*hex_border),
            (LEFT_BOX + marge + hex_border/2 + j*(3/2)*hex_border+i*(3/2)*hex_border, MIDY_BOX - sqrt(3)*hex_border/2 - (sqrt(3)*j/2)*hex_border+ (sqrt(3)*i/2)*hex_border),
            (LEFT_BOX + marge + (3 * hex_border)/2 + j*(3/2)*hex_border+i*(3/2)*hex_border, MIDY_BOX - sqrt(3)*hex_border/2 - (sqrt(3)*j/2)*hex_border+ (sqrt(3)*i/2)*hex_border),
            (LEFT_BOX + marge + 2 * hex_border + j*(3/2)*hex_border+i*(3/2)*hex_border,MIDY_BOX - (sqrt(3)*j/2)*hex_border+ (sqrt(3)*i/2)*hex_border),
            (LEFT_BOX + marge + (3 * hex_border)/2+ j*(3/2)*hex_border+i*(3/2)*hex_border, MIDY_BOX + sqrt(3)*hex_border/2 - (sqrt(3)*j/2)*hex_border+ (sqrt(3)*i/2)*hex_border)]
            Hexa_color+=[beige]
            bounding_rect = pygame.draw.polygon(screen, Hexa_color[(lenght_plate*i)+j], hexagone)
            pygame.draw.polygon(screen, black, hexagone, round(50/lenght_plate))

    pygame.display.flip()
    running = True
    TURN = 'white'
    once_variable = False
    while running:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                running = False
                sys.exit()
            elif event.type == pygame.MOUSEBUTTONUP and once_variable and click_button.collidepoint(pygame.mouse.get_pos()):
                game_menu()
            elif event.type == pygame.MOUSEBUTTONUP and once_variable:
                click = True
                FOUND = False
                for i in range(lenght_plate):
                    for j in range(lenght_plate):
                        hexagone = [(LEFT_BOX + marge + hex_border/2 + j*(3/2)*hex_border +i*(3/2)*hex_border , MIDY_BOX + sqrt(3)*hex_border/2 - (sqrt(3)*j/2)*hex_border + (sqrt(3)*i/2)*hex_border),
                        (LEFT_BOX + marge + j*(3/2)*hex_border +i*(3/2)*hex_border,MIDY_BOX - (sqrt(3)*j/2)*hex_border+ (sqrt(3)*i/2)*hex_border),
                        (LEFT_BOX + marge + hex_border/2 + j*(3/2)*hex_border+i*(3/2)*hex_border, MIDY_BOX - sqrt(3)*hex_border/2 - (sqrt(3)*j/2)*hex_border+ (sqrt(3)*i/2)*hex_border),
                        (LEFT_BOX + marge + (3 * hex_border)/2 + j*(3/2)*hex_border+i*(3/2)*hex_border, MIDY_BOX - sqrt(3)*hex_border/2 - (sqrt(3)*j/2)*hex_border+ (sqrt(3)*i/2)*hex_border),
                        (LEFT_BOX + marge + 2 * hex_border + j*(3/2)*hex_border+i*(3/2)*hex_border,MIDY_BOX - (sqrt(3)*j/2)*hex_border+ (sqrt(3)*i/2)*hex_border),
                        (LEFT_BOX + marge + (3 * hex_border)/2+ j*(3/2)*hex_border+i*(3/2)*hex_border, MIDY_BOX + sqrt(3)*hex_border/2 - (sqrt(3)*j/2)*hex_border+ (sqrt(3)*i/2)*hex_border)]
                        bounding_rect = pygame.draw.polygon(screen, Hexa_color[(lenght_plate*i)+j], hexagone)
                        if x < 64:
                            pygame.draw.polygon(screen, d_gray, hexagone, round(50/lenght_plate))
                        else:
                            pass
                        if bounding_rect.collidepoint(pygame.mouse.get_pos()) and not FOUND:
                            if Hexa_color[(lenght_plate * i) + j] != beige:
                                continue
                            if TURN == 'white':
                                Hexa_color[(lenght_plate*i)+j]=white
                                pygame.draw.polygon(screen, white , hexagone)
                                TURN = "black"
                            else:
                                Hexa_color[(lenght_plate*i)+j]=black
                                pygame.draw.polygon(screen, black , hexagone)
                                TURN = "white"
                            pygame.draw.polygon(screen, d_gray, hexagone, round(50/lenght_plate))
                            pygame.display.flip()
                            FOUND = True
                pygame.display.flip()
            else:
                once_variable = True
                continue

            once_variable = True
        #========GAME

        turn_font = switch_font(50, False, False)
        white_text = turn_font.render(langues["white"].get(LANG), True, black)
        black_text = turn_font.render(langues["black"].get(LANG), True, black)
        screen.blit(white_text,[10, 100])
        black_rect = black_text.get_rect(topright=(SIZE_X-10,100))
        screen.blit(black_text, black_rect)

        if TURN == "white":
            arrow_left = turn_font.render("<", True, black)
            arrow_right = turn_font.render(">", True, screen_color)
        elif TURN == "black":
            arrow_left = turn_font.render("<", True, screen_color)
            arrow_right = turn_font.render(">", True, black)
        screen.blit(arrow_left,[120, 100])
        if LANG in {'jp', 'gr'}:
            screen.blit(arrow_right,[SIZE_X-200, 100])
        else:
            screen.blit(arrow_right,[SIZE_X-127, 100])
        pygame.display.flip()
        Z = 1
        WIN = True
        WHITE_WON = False
        for i in range(lenght_plate):
            if Z==0:
                WIN=False
            else:
                Z = 0
            for j in range(lenght_plate):
                if Hexa_color[(lenght_plate*i)+j]==white:
                    Z = 1
                else:
                    continue
        if Z == 0:
            WIN = False
        elif Z == 1 and WIN:
            solution = []
            next_solution = []
            for j in range(lenght_plate):
                if Hexa_color[j]==white:
                    solution.append(j)
                else:
                    continue
            passed = []
            solutionLoop = []
            CanWin = True
            SOL_AND_PASSE = False
            POSITION_FOUND2 = False
            def solw(x):
                if Hexa_color[VALUE_SOLUTION+x]==white:
                    next_solution.append(VALUE_SOLUTION  + x)

            while CanWin and not WHITE_WON:
                if next_solution != []:
                    solution = next_solution
                for sol in solution:
                    for passe in passed:
                        if sol == passe:
                            SOL_AND_PASSE = True
                        else:
                            x=0
                    if not SOL_AND_PASSE:
                        solutionLoop.append(sol)
                    else:
                        x=0
                    SOL_AND_PASSE = False
                solution = []
                next_solution = []
                solution = solutionLoop
                solutionLoop = []
                #print(f"WHITE \ \n Solution = {solution} \n \n Passed = {passed} \n \n \n")
                if solution == []:
                    CanWin = False
                else:
                    for k in solution:
                        VALUE_SOLUTION = k
                        POSITION_FOUND2 = False
                        if VALUE_SOLUTION >= lenght_plate ** 2 - lenght_plate:
                            WHITE_WON = True
                        elif not WHITE_WON:
                            #print(VALUE_SOLUTION)
                            solw(lenght_plate)
                            for x in range(lenght_plate):
                                if VALUE_SOLUTION >= lenght_plate and VALUE_SOLUTION == x * lenght_plate - 1: #Black Border-Right
                                    solw(-lenght_plate)
                                    solw(-1)
                                    solw(-lenght_plate-1)
                                    POSITION_FOUND2 = True
                                elif VALUE_SOLUTION >= lenght_plate and VALUE_SOLUTION == x * lenght_plate: #Black Border-Left
                                    solw(-lenght_plate)
                                    solw(-lenght_plate+1)
                                    solw(1)
                                    POSITION_FOUND2 = True
                            if VALUE_SOLUTION == lenght_plate - 1: #White Border and Black Border-Right
                                solw(-1)
                                solw(lenght_plate -1)
                                POSITION_FOUND2 = True

                            elif VALUE_SOLUTION == "0": #White Border and Black Border-Left
                                solw(1)
                                POSITION_FOUND2 = True
                            elif VALUE_SOLUTION < lenght_plate:#White Border
                                if Hexa_color[VALUE_SOLUTION-1]==white:
                                    next_solution.append(VALUE_SOLUTION  - 1)
                                if Hexa_color[VALUE_SOLUTION+1]==white:
                                    next_solution.append(VALUE_SOLUTION + 1 )
                                if Hexa_color[VALUE_SOLUTION+lenght_plate-1]==white:
                                    next_solution.append(VALUE_SOLUTION  + lenght_plate - 1)
                                POSITION_FOUND2 = True

                            elif not POSITION_FOUND2:
                                if Hexa_color[VALUE_SOLUTION-lenght_plate]==white:
                                    next_solution.append(VALUE_SOLUTION  -lenght_plate)
                                if Hexa_color[VALUE_SOLUTION-lenght_plate+1]==white:
                                    next_solution.append(VALUE_SOLUTION  - lenght_plate + 1)
                                if Hexa_color[VALUE_SOLUTION-1]==white:
                                    next_solution.append(VALUE_SOLUTION  - 1)
                                if Hexa_color[VALUE_SOLUTION+1]==white:
                                    next_solution.append(VALUE_SOLUTION + 1 )
                                if Hexa_color[VALUE_SOLUTION+lenght_plate-1]==white:
                                    next_solution.append(VALUE_SOLUTION  + lenght_plate - 1)
                            passed.append(VALUE_SOLUTION)
                            #print("next solution of",k,":",next_solution)

        # BLACK
        if not WHITE_WON:
            Z=1
            WIN = True
            BLACK_WON = False
            for i in range(lenght_plate):
                if Z==0:
                    WIN=False
                else:
                    Z = 0
                for j in range(lenght_plate):
                    if Hexa_color[(lenght_plate*j)+i]==black:
                        Z = 1
                    else:
                        continue
            if Z == 0:
                WIN = False
            elif Z == 1 and WIN:
                solution = []
                next_solution = []
                for j in range(lenght_plate):
                    if Hexa_color[j*lenght_plate]==black:
                        solution.append(j*lenght_plate)
                    else:
                        continue
                passed = []
                solutionLoop = []
                CanWin = True
                SOL_AND_PASSE = False
                POSITION_FOUND = False
                def solb(x):
                    global POSITION_FOUND
                    if Hexa_color[VALUE_SOLUTION+x]==black:
                        next_solution.append(VALUE_SOLUTION  + x)
                        POSITION_FOUND = True
                while CanWin and not BLACK_WON:
                    if next_solution != []:
                        solution = next_solution
                    for sol in solution:
                        for passe in passed:
                            if sol == passe:
                                SOL_AND_PASSE = True
                            else:
                                x=0
                        if not SOL_AND_PASSE:
                            solutionLoop.append(sol)
                        else:
                            x=0
                        SOL_AND_PASSE = False
                    solution = []
                    solution = solutionLoop
                    solutionLoop = []
                    #print(f"BLACK/ \nSolution = {solution} \n \nPassed = {passed} \n \n \n")
                    if solution == []:
                        CanWin = False
                    else:
                        for k in solution:
                            VALUE_SOLUTION = k
                            POSITION_FOUND = False
                            for x in range(lenght_plate):
                                if VALUE_SOLUTION== x * (lenght_plate) - 1 :
                                    BLACK_WON = True

                            if not BLACK_WON:
                                if Hexa_color[VALUE_SOLUTION+1]==black:
                                    next_solution.append(VALUE_SOLUTION +1)
                                for x in range(lenght_plate):
                                    if VALUE_SOLUTION == x*lenght_plate and VALUE_SOLUTION!=0 and VALUE_SOLUTION != lenght_plate**2 - lenght_plate : #Black Border
                                        solb(lenght_plate)
                                        solb(-lenght_plate+1)
                                        solb(-lenght_plate)
                                        POSITION_FOUND =True

                                if VALUE_SOLUTION == lenght_plate**2 - lenght_plate: #Black Border and white Border-Bottom
                                    solb(-lenght_plate+1)
                                    solb(-lenght_plate)
                                elif VALUE_SOLUTION == 0: #Black Border and white Border-Top
                                    solb(lenght_plate)
                                elif VALUE_SOLUTION > lenght_plate**2 - lenght_plate: #White Border-Bottom
                                    solb(-1)
                                    solb(-lenght_plate +1)
                                    solb(-lenght_plate)
                                elif VALUE_SOLUTION <= (lenght_plate-1) : #WHite Border-Top
                                    solb(lenght_plate)
                                    solb(lenght_plate-1)
                                    solb(-1)

                                elif not POSITION_FOUND:
                                    if Hexa_color[VALUE_SOLUTION-lenght_plate]==black:
                                        next_solution.append(VALUE_SOLUTION - lenght_plate)
                                    if Hexa_color[VALUE_SOLUTION-lenght_plate+1]==black:
                                        next_solution.append(VALUE_SOLUTION - lenght_plate+1)
                                    if Hexa_color[VALUE_SOLUTION-1]==black:
                                        next_solution.append(VALUE_SOLUTION - 1)
                                    if Hexa_color[VALUE_SOLUTION+lenght_plate-1]==black:
                                        next_solution.append(VALUE_SOLUTION + lenght_plate-1)
                                    if Hexa_color[VALUE_SOLUTION+lenght_plate]==black:
                                        next_solution.append(VALUE_SOLUTION + lenght_plate )
                                passed.append(VALUE_SOLUTION)

        else:
            X=0
        X=0
        title_font = switch_font(50, False, False)
        win_rect = pygame.Rect(325, 110, SIZE_X - 650, 75)
        if WHITE_WON:
            winmessage = title_font.render(langues["white_won"].get(LANG), True, (0 , 0 ,0))
            pygame.draw.rect(screen,white,win_rect)
        elif BLACK_WON:
            winmessage = title_font.render(langues["black_won"].get(LANG), True, (255 , 255 ,255))
            pygame.draw.rect(screen,black,win_rect)
        else:
            continue
        l = 50
        restart = [(SIZE_X - 100, SIZE_Y-10),
        (SIZE_X - 100 - l*(sqrt(3)/2), SIZE_Y-10-l/2 ),
        (SIZE_X - 100 - l*(sqrt(3)/2), SIZE_Y-10-(3*l)/2 ),
        (SIZE_X - 100, SIZE_Y - 20 - (sqrt(3)*l)),
        (SIZE_X - 100 + l*(sqrt(3)/2), SIZE_Y-10-(3*l)/2 ),
        (SIZE_X - 100 + l*(sqrt(3)/2), SIZE_Y-10-l/2 )
         ]

         #---------ARRORW
        res_polygon = pygame.draw.polygon(screen, dark_screen_color,restart)
        pygame.draw.polygon(screen, black,restart, 5)
        pygame.draw.line(screen, black,(SIZE_X - 100, SIZE_Y-30),(SIZE_X - 100 - l*(sqrt(3)/2)+20, SIZE_Y-10-l/2 -10),5)
        pygame.draw.line(screen, black,(SIZE_X - 100 - l*(sqrt(3)/2)+20, SIZE_Y-10-l/2 -10),(SIZE_X - 100 - l*(sqrt(3)/2)+20, SIZE_Y-10-(3*l)/2 +10),5)
        pygame.draw.line(screen,black,(SIZE_X - 100 - l*(sqrt(3)/2)+20, SIZE_Y-10-(3*l)/2 +10), (SIZE_X - 100, SIZE_Y - (sqrt(3)*l)),5)
        pygame.draw.line(screen, black, (SIZE_X - 100, SIZE_Y - (sqrt(3)*l)),(SIZE_X - 100 + l*(sqrt(3)/2) - 20, SIZE_Y-10-(3*l)/2 +10),5)
        pygame.draw.line(screen, black, (SIZE_X - 100 + l*(sqrt(3)/2) - 20, SIZE_Y-10-(3*l)/2 +10),(SIZE_X - 100 + l*(sqrt(3)/2)-20, SIZE_Y-10-l/2 -10),5)
        pygame.draw.line(screen, black, (SIZE_X - 100 + l*(sqrt(3)/2)-20, SIZE_Y-10-l/2 -10),(SIZE_X - 95+ (sqrt(3)/4) * 12 , SIZE_Y-25 - l/4),5)
        pygame.draw.line(screen, black,(SIZE_X - 95+ (sqrt(3)/4) * 12 , SIZE_Y-25 - l/4),(SIZE_X - 95+ (sqrt(3)/4) * 12 , SIZE_Y-25 - l/4 -20),5)
        pygame.draw.line(screen, black,(SIZE_X - 95+ (sqrt(3)/4) * 12 , SIZE_Y-25 - l/4),(SIZE_X - 95+ (sqrt(3)/4) * 12 +20 , SIZE_Y-25 - l/4),5)
        #-------------

        if res_polygon.collidepoint(pygame.mouse.get_pos()) and click:
            choosing_lenght()

        middle = winmessage.get_rect(center=(SIZE_X/2,147))
        screen.blit(winmessage,middle)
        pygame.display.flip()
        click = False

menu()


# -*- coding: utf-8 -*-
from __future__ import unicode_literals

import json

from django.urls import re_path as url
from django.contrib.sessions.middleware import SessionMiddleware
from django.http import response
from django.test import RequestFactory
from django.test.utils import override_settings
import six
from six.moves.urllib.parse import parse_qsl, urlparse

from ..models import WeChatUser
from ..oauth import (WeChatAuthenticated, wechat_auth, WeChatSNSScope,
                     WeChatOAuthClient, WeChatOAuthView)
from .base import mock, WeChatTestCase
from .interceptors import common_interceptor

def oauth_api(openid, callback=None):
    kwargs = dict(
        netloc=r"(.*\.)?api\.weixin\.qq\.com$",
        path="/sns/oauth2/access_token"
    )

    def mock(url, request):
        headers = {
            "Content-Type": "application/json"
        }
        data = dict(
            access_token="123",
            refresh_token="123",
            expires_in=7200,
            openid=openid
        )
        from httmock import response
        resp = response(200, data, headers)
        if callback:
            callback(url, request, resp)
        return resp

    return common_interceptor(mock, **kwargs)

def snsinfo_api(openid, callback=None, **data):
    kwargs = dict(
        netloc=r"(.*\.)?api\.weixin\.qq\.com$",
        path="/sns/userinfo"
    )

    def mock(url, request):
        headers = {
            "Content-Type": "application/json"
        }
        from httmock import response
        resp = response(200, data, headers)
        if callback:
            callback(url, request, resp)
        return resp

    return common_interceptor(mock, **kwargs)

@wechat_auth("test", state="state")
def test_oauth_view(request, *args):
    user = request.wechat.user
    return dict(
        openid=user.openid,
        id=user.id,
        args=args
    )

urlpatterns = [
    url(r"^test/(.+)$", test_oauth_view)
]

@override_settings(ROOT_URLCONF=__name__)
class OAuthTestCase(WeChatTestCase):
    def test_oauth_api(self):
        """测试oauth接口请求"""
        pass

    def test_redirect_uri(self):
        """测试redirect_uri生成"""
        host = "example.com"
        rf = self.rf(HTTP_HOST=host)
        api = "/app"
        absolute_uri = lambda uri: "http://" + host + uri

        # 测试写入redirect_uri时
        redirect_uri = "https://mp.weixin.qq.com/wiki"
        view_cls = WeChatOAuthView(
            appname=self.app.name, redirect_uri=redirect_uri)
        request = rf.get(api)
        SessionMiddleware().process_request(request)
        view_cls.setup(request)
        request = view_cls.initialize_request(request)
        self.assertEqual(request.wechat.redirect_uri, redirect_uri)

        redirect_uri = "/app"
        view_cls = WeChatOAuthView(
            appname=self.app.name, redirect_uri=redirect_uri)
        request = rf.get(api)
        SessionMiddleware().process_request(request)
        view_cls.setup(request)
        request = view_cls.initialize_request(request)
        self.assertEqual(request.wechat.redirect_uri,
                         absolute_uri(redirect_uri))

        # 测试模板请求redirect_uri
        view_cls = WeChatOAuthView(appname=self.app.name)
        request = rf.get(redirect_uri)
        SessionMiddleware().process_request(request)
        view_cls.setup(request)
        request = view_cls.initialize_request(request)
        self.assertEqual(request.wechat.redirect_uri,
                         absolute_uri(redirect_uri))

        # 测试ajax请求redirect_uri
        view_cls = WeChatOAuthView(appname=self.app.name)
        request = rf.post(api, dict(a=1),
            HTTP_X_REQUESTED_WITH="XMLHttpRequest",
            HTTP_REFERRER=absolute_uri(redirect_uri))
        SessionMiddleware().process_request(request)
        view_cls.setup(request)
        request = view_cls.initialize_request(request)
        self.assertEqual(request.wechat.redirect_uri,
                         absolute_uri(redirect_uri))

        # 测试callable redirect_uri
        callable_redirect = lambda request, *args, **kwargs: redirect_uri
        view_cls = WeChatOAuthView(appname=self.app.name,
                                   redirect_uri=callable_redirect)
        request = rf.get(redirect_uri)
        SessionMiddleware().process_request(request)
        view_cls.setup(request)
        request = view_cls.initialize_request(request)
        self.assertEqual(request.wechat.redirect_uri,
                         absolute_uri(redirect_uri))

    def test_unauthorization(self):
        rf = RequestFactory()
        path = "/test"
        redirect_uri = "https://mp.weixin.qq.com/wiki"

        # 默认response
        state = "abc"
        request = rf.get(path)
        handler = self._make_handler(
            request, redirect_uri=redirect_uri,
            scope=WeChatSNSScope.USERINFO, state=state)
        request = handler.initialize_request(request)
        resp = handler.unauthorization_response(request)
        self.assertIsInstance(resp, response.HttpResponseRedirect)
        client = WeChatOAuthClient(self.app)
        self.assertEqual(resp.url, client.authorize_url(
            redirect_uri, WeChatSNSScope.USERINFO, state))

        # 传入callable state
        state = lambda request: request.path
        request = rf.get(path)
        handler = self._make_handler(
            request, redirect_uri=redirect_uri,
            scope=WeChatSNSScope.USERINFO, state=state)
        request = handler.initialize_request(request)
        resp = handler.unauthorization_response(request)
        self.assertIsInstance(resp, response.HttpResponseRedirect)
        client = WeChatOAuthClient(self.app)
        self.assertEqual(resp.url, client.authorize_url(
            redirect_uri, WeChatSNSScope.USERINFO, path))

        # 传入callback response
        resp = response.HttpResponseForbidden()
        request = rf.get(path)
        handler = self._make_handler(request, response=resp)
        request = handler.initialize_request(request)
        self.assertIs(
            resp,
            handler.unauthorization_response(request)
        )

        # 传入普通response
        resp_func = lambda request: response.HttpResponseForbidden(request.path)
        request = rf.get(path)
        handler = self._make_handler(request, response=resp_func)
        request = handler.initialize_request(request)
        resp = handler.unauthorization_response(request)
        self.assertIsInstance(resp, response.HttpResponseForbidden)
        self.assertEqual(resp.content, path.encode())

    def test_user_update(self):
        "测试更新授权数据"
        pass

    def test_request(self):
        "测试请求"
        redirect_uri = "https://mp.weixin.qq.com/wiki"
        url = "/test"
        request = self._create_request(url)

        # 设置了response
        resp = response.HttpResponseForbidden()
        handler = self._make_handler(
            request, redirect_uri=redirect_uri, response=resp)
        self.assertIs(handler.dispatch(request), resp)

        # 未授权
        handler = self._make_handler(request, redirect_uri=redirect_uri)
        resp = handler.dispatch(request)
        self.assertIsInstance(resp, response.HttpResponseRedirect)
        self.assertEqual(resp.url, request.wechat.oauth_uri)

        # 授权
        request = self._create_request(url + "?code=123")
        openid = "456"
        view = lambda request, *args, **kwargs: request.wechat.openid
        handler = self._make_handler(request, view=view)
        with oauth_api(openid):
            resp = handler.dispatch(request)
            self.assertEqual(resp.content, openid.encode())

        # 已授权
        session_key = "sessionid"
        resp = SessionMiddleware().process_response(request, resp)
        request = self._create_request(url + "?code=123")
        request.COOKIES[session_key] = resp.cookies[session_key].value
        resp = handler.dispatch(request)
        self.assertEqual(resp.content, openid.encode())

    def test_decorator(self):
        """测试class based view与decorator是否一致"""
        openid = "test_decorator"
        user = WeChatUser.objects.upsert_by_dict(
            dict(openid=openid), app=self.app)
        session_key = "wechat_{0}_user".format(self.app.name)

        view = lambda request: request
        # 测试appname
        wrapped_view = wechat_auth(self.app.name)(view)
        request = self._create_request("/")
        request.session[session_key] = openid
        self.assertEqual(wrapped_view(request).wechat.appname, self.app.name)

        # 测试scope
        wrapped_view = wechat_auth(
            self.app.name, scope=WeChatSNSScope.USERINFO)(view)
        request = self._create_request("/")
        request.session[session_key] = openid
        self.assertIn(WeChatSNSScope.USERINFO, wrapped_view(request).wechat.scope)

        # 测试redirect_uri
        redirect_uri = "https://www.baidu.com/"
        wrapped_view = wechat_auth(
            self.app.name, redirect_uri=redirect_uri)(view)
        request = self._create_request("/")
        request.session[session_key] = openid
        self.assertEqual(wrapped_view(request).wechat.redirect_uri, redirect_uri)

        # 测试required
        wrapped_view = wechat_auth(self.app.name, required=False)(view)
        request = self._create_request("/")
        self.assertEqual(wrapped_view(request), request)

        # 测试默认required及response
        resp = response.HttpResponse()
        wrapped_view = wechat_auth(self.app.name, response=resp)(view)
        request = self._create_request("/")
        self.assertEqual(wrapped_view(request), resp)

        # 测试state
        state = "abc"
        wrapped_view = wechat_auth(
            self.app.name, state=state)(view)
        request = self._create_request("/")
        request.session[session_key] = openid
        self.assertEqual(wrapped_view(request).wechat.state, state)

        # 测试methods
        request_get = self._create_request("/")
        request_get.session[session_key] = openid
        request_post = self._create_request("/", "post")
        request_post.session[session_key] = openid

        # 测试仅get
        view = lambda request: resp
        wrapped_view = wechat_auth(self.app.name)(view)
        self.assertEqual(wrapped_view(request_get), resp)
        self.assertIsInstance(wrapped_view(request_post),
                              response.HttpResponseNotAllowed)

        # 测试仅post
        wrapped_view = wechat_auth(self.app.name, methods=["POST"])(view)
        self.assertIsInstance(wrapped_view(request_get),
                              response.HttpResponseNotAllowed)
        self.assertEqual(wrapped_view(request_post), resp)

    def test_view(self):
        """测试view是否正常"""
        args = "t"
        openid = "666"
        host = "example.com"
        path = "/test/" + args

        resp = self.client.get(path, HTTP_HOST="example.com")
        self.assertEqual(resp.status_code, 302)
        parsed_url = urlparse(resp.url)
        self.assertEqual(parsed_url.netloc, "open.weixin.qq.com")
        query = dict(parse_qsl(parsed_url.query))
        self.assertEqual(query["appid"], self.app.appid)
        self.assertEqual(query["response_type"], "code")
        self.assertEqual(query["scope"], WeChatSNSScope.BASE)
        self.assertEqual(query["state"], "state")
        self.assertEqual(parsed_url.fragment, "wechat_redirect")
        self.assertEqual(query["redirect_uri"], "http://" + host + path)

        with oauth_api(openid):
            resp = self.client.get(path + "?code=123", follow=True,
                HTTP_HOST=host)
        self.assertEqual(resp.status_code, 200)
        data = json.loads(resp.content.decode())
        self.assertEqual(data["openid"], openid)
        self.assertEqual(data["args"], [args])
        id = data["id"]
        user = WeChatUser.objects.get(id=id)
        self.assertEqual(user.openid, openid)

    def test_custom_oauth_url(self):
        """测试设置了OAUTH_URL url后 不再向微信请求授权,转向第三方请求授权"""
        with mock.patch.object(WeChatOAuthClient, "authorize_url"):
            new_url = "new_url"
            self.app.configurations["OAUTH_URL"] = new_url
            hasattr(self.app, "_oauth") and delattr(self.app, "_oauth")
            url = self.app.oauth.authorize_url("redirect_url")
            self.assertTrue(url.startswith(new_url))
            delattr(self.app, "_oauth")
            del self.app.configurations["OAUTH_URL"]

    def _make_handler(self, request, appname="", **kwargs):
        view = kwargs.pop("view", lambda request, *args, **kwargs: "")
        appname = appname or self.app.name
        scope = kwargs.get("scope")
        if scope and isinstance(scope, six.text_type):
            kwargs["scope"] = (scope,)
        cls = type(str("WeChatOAuthView"), (WeChatOAuthView,), dict())
        kwargs = cls.prepare_init_kwargs(appname=appname, **kwargs)
        rv = cls(**kwargs)
        rv.setup(request)
        rv.get = view
        return rv

    def _create_request(self, path, method="get"):
        request = getattr(self.rf(), method)(path)
        SessionMiddleware().process_request(request)
        return request


from wand.image import Image

def mono_array_from_img_obj(img, threshold=200, inverse=False):
    blob = img.make_blob(format='RGB')
    pixels = list()
    if inverse:
        on = 1
        off = 0
    else:
        on = 0
        off = 1
    for y in range(0, img.height):
        current_row = list()
        pixels.append(current_row)
        for x in range(0, img.width * 3, 3):
            loc = y * img.width * 3 + x
            if (ord(blob[loc]) + ord(blob[loc + 1]) + ord(blob[loc + 2])) / 3 >= threshold:
                current_row.append(on)
            else:
                current_row.append(off)
    return pixels

def gen_bitmap_string(rows, width=8, reverse_lr_order=False):
    out_lines = list()
    out_str_fmt = '    .byte #%{0}'
    for row in rows:
        this_line = ''.join([str(x) for x in row])
        if reverse_lr_order:
            this_line = this_line[::-1]
        if width == 4:
            this_line += '0000'
        out_lines.append(this_line)
    out_lines = out_lines[::-1]
    return '\n'.join([out_str_fmt.format(l) for l in out_lines])

def gen_sprite_asm_from_bit_array(bit_array, prefix=''):
    pf0pos1_bytes = [row[0:4] for row in bit_array]
    pf1pos1_bytes = [row[4:12] for row in bit_array]
    pf2pos1_bytes = [row[12:20] for row in bit_array]
    pf0pos2_bytes = [row[20:24] for row in bit_array]
    pf1pos2_bytes = [row[24:32] for row in bit_array]
    pf2pos2_bytes = [row[32:40] for row in bit_array]
    pf0pos1_strings = gen_bitmap_string(pf0pos1_bytes, width=4, reverse_lr_order=True)
    pf1pos1_strings = gen_bitmap_string(pf1pos1_bytes)
    pf2pos1_strings = gen_bitmap_string(pf2pos1_bytes, reverse_lr_order=True)
    pf0pos2_strings = gen_bitmap_string(pf0pos2_bytes, width=4, reverse_lr_order=True)
    pf1pos2_strings = gen_bitmap_string(pf1pos2_bytes)
    pf2pos2_strings = gen_bitmap_string(pf2pos2_bytes, reverse_lr_order=True)
    out = '{0}PF0SpriteA\n{1}\n'.format(prefix, pf0pos1_strings)
    out += '{0}PF0SpriteB\n{1}\n'.format(prefix, pf0pos2_strings)
    out += '{0}PF1SpriteA\n{1}\n'.format(prefix, pf1pos1_strings)
    out += '{0}PF1SpriteB\n{1}\n'.format(prefix, pf1pos2_strings)
    out += '{0}PF2SpriteA\n{1}\n'.format(prefix, pf2pos1_strings)
    out += '{0}PF2SpriteB\n{1}\n'.format(prefix, pf2pos2_strings)
    return out

def bit_array_from_file(filename, r_width=40, r_height=192):
    with Image(filename=filename) as img:
        img.resize(r_width, r_height)
        pixels = mono_array_from_img_obj(img)
    return pixels

def gen_asm_from_image_file(filename, prefix=''):
    bits = bit_array_from_file(filename)
    asm_text = gen_sprite_asm_from_bit_array(bits, prefix=prefix)
    return asm_text


from django.urls import path

from.views import ContactListApiView, ContactDetailApiView, ContactCreateApiView

urlpatterns = [
    path('contact-list/', ContactListApiView.as_view(), name='contact_list'),
    path('contact-detail/<int:pk>/', ContactDetailApiView.as_view(), name='contact-detail'),
    path('create-contact/', ContactCreateApiView.as_view(), name='create-contact')
]


from Bio import pairwise2
from Bio.Seq import Seq
from Bio.pairwise2 import format_alignment

seq1 = Seq("AGCGGTTT")
seq2 = Seq("ACGT")

print("--- LOCAL ---")
for a in pairwise2.align.localxx(seq1, seq2):
    print(format_alignment(*a))

print("--- GLOBAL ---")
alignments = pairwise2.align.globalxx(seq1, seq2)

for g in alignments:
    print(format_alignment(*g))


# 11_ws_movecells.py
# - Post 9. 데이터 잘라내 붙이기

from openpyxl import load_workbook
from openpyxl.styles import Alignment

# 5_functions.py 파일의 결과 파일 경로 입력 후 파일 load
path = "../Post04"
wb = load_workbook(f'{path}/wb_multiple_func.xlsx')
ws = wb['Sheet']

# move_range 수행
ws.move_range("A2:F15", rows=3, cols=1)
wb.save('wb_moving.xlsx')

wb = load_workbook(f'{path}/wb_multiple_func.xlsx')
ws = wb['Sheet']
ws.move_range("A2:F15", rows=3, cols=1, translate=True)
wb.save('wb_moving2.xlsx')


#!/usr/bin/python3
# $Id$
# $Date$

# NOTE: script need to call with root privileges or via "sudo"

# TODO: cannot receive incremental stream: most recent snapshot of backup/test does not match incremental source

import argparse
import configparser

from zbackup_lib import *
from tables import print_table_as_is, reform_table_fix_columns_sizes
# ############# constant values #################
config_file = 'zbackup.ini'
atempts_to_mount = 3

# ################ command line arguments ###########################
help_info = 'snapshots sending direction to \'usb\' or \'os\''
parser = argparse.ArgumentParser(description='Arguments from command line')
parser.add_argument('direction', action='store', type=str, choices=['usb', 'os'],
                    help=help_info)

arg_group_v_q = parser.add_mutually_exclusive_group()
arg_group_v_q.add_argument('-v', '--verbosity', action='count',
                           # it always set 2, if -v == 3, -vv == 4
                           default=2,
                           help='DEBUG on')
arg_group_v_q.add_argument("-q", "--quiet", action='store_true',
                           help='be quiet, only CRITICAL logs')

parser.add_argument('-s', '--save-last-snapshots', type=int, default=0,
                    help='Delete old snapshots from all devices, it override values in all BLOCKs .INI file')
arg = parser.parse_args()

# print(arg.verbosity)
debug_flag = False
if arg.quiet:
    logging_level = 40
    # logging.ERROR
    # CRITICAL = 50
elif arg.verbosity >= 3:
    logging_level = 10
    debug_flag = True
    # logging.DEBUG
    # NOTSET = 0
else:
    logging_level = 20
    # logging.INFO
    # logging.WARNING = 30
# #################### logging block ##################
formatter = '%(asctime)s - %(name)s - %(levelname)s - %(message)s'
logging.basicConfig(level=logging_level,
                    # filename='zbackup.log',
                    format=formatter,
                    handlers=[logging.FileHandler("zbackup.log"),
                              logging.StreamHandler()])

logger = logging.getLogger(__name__)

logger.info("----------- start working ------------")

# ############## read config file ################
config = configparser.ConfigParser()
config.read(config_file)

partuuid = config.get('USB device', 'partuuid', fallback=None)
pool = config.get('USB device', 'backup_pool', fallback='backup')
truecrypt = config.getboolean('USB device', 'truecrypt', fallback=False)

# config.BOOLEAN_STATES = {'yes': True, 'Yes': True, 'YES': True}

logger.debug('------ read config file {0} --------'.format(config_file))
logger.debug('dev_disk (partuuid) = {0}'.format(partuuid))
logger.debug('disk_pool = {0}'.format(pool))

# ## search zpool guid in config file and implement appropriate config section
zpool_get_guid = subprocess.getoutput('zpool get guid').split()
logger.debug('zpool_get_guid = {0}'.format(str(zpool_get_guid)))

for i in config.sections():
    if not i.startswith('host'):
        continue
    logger.debug('check config file section= {0}, guid= {1}'.format(i, config.get(i, 'guid')))
    if config.get(i, 'guid') in zpool_get_guid:
        # get pool name from 'zpool get guid' output
        root_pool_index = zpool_get_guid.index(config.get(i, 'guid')) - 2
        root_pool = zpool_get_guid[root_pool_index]
        host_config = i
        # root_pool = config.get(i, 'root_pool', fallback=None)
        break
else:
    logger.critical('there is CRITICAL error in config file\n'
                    'there are no any guid or host section in config file, in \'zpool get guid\' output\n'
                    'exit...')
    exit(202)

usb_disk = Pool(pool, partuuid)  # init USB disk
usb_disk.altroot = config.get('USB device', 'mount-point', fallback='/backup')
usb_disk.mount(atempts_to_mount)

# ############## set direction according command line options ###########
if arg.direction == 'usb':
    # noinspection PyUnboundLocalVariable
    current_volume = ToUSB(root_pool, usb_disk.pool, debug_flag)
    current_volume.save_n_old_snapshots_dst = config.get('USB device', 'save-last-snapshots', fallback=0)
    # noinspection PyUnboundLocalVariable
    current_volume.save_n_old_snapshots_src = config.get(host_config, 'save-last-snapshots', fallback=0)
elif arg.direction == 'os':
    # noinspection PyUnboundLocalVariable
    current_volume = ToOS(usb_disk.pool, root_pool, debug_flag)
    current_volume.save_n_old_snapshots_src = config.get('USB device', 'save-last-snapshots', fallback=0)
    # noinspection PyUnboundLocalVariable
    current_volume.save_n_old_snapshots_dst = config.get(host_config, 'save-last-snapshots', fallback=0)
else:
    logger.error('wrong direction exit ... ')
    exit(201)

# noinspection PyUnboundLocalVariable
current_volume.save_n_old_snapshots_src = int(current_volume.save_n_old_snapshots_src)
current_volume.save_n_old_snapshots_dst = int(current_volume.save_n_old_snapshots_dst)

if arg.save_last_snapshots != 0:
    # noinspection PyUnboundLocalVariable
    current_volume.save_n_old_snapshots_src = arg.save_last_snapshots
    current_volume.save_n_old_snapshots_dst = arg.save_last_snapshots

# #################### main block #######################
# noinspection PyUnboundLocalVariable
work_table = [('previous snapshot', 'prev. snap. date', 'snapshot to send', 'recv. destination', 'size')]
result_table = [('previous snap', 'send snap', 'est. size', 'trans. snap', 'received', 'time', 'speed')]
delete_snaps_table = [('del. snapshot', 'create date')]
# create snaps and tables, in work_table - snaps which to send and where
umount_tmp = False
for volume in config.get(host_config, 'volume').split():
    # noinspection PyUnboundLocalVariable
    logger.debug('INIT==> {0}'.format(current_volume))
    current_volume.generate_dicts(volume)
    if volume == '/tmp' and usb_disk.OS_type == 'Linux':
#        current_volume.linux_workarount = True
        umount_tmp = True

    logger.debug('UPDATE==> {0}'.format(current_volume))
    work_table.append(current_volume.send_snap(True))
    # current_volume.delete_old_snapshots()
    if current_volume.snaps_to_remove_src is not None:
        delete_snaps_table += current_volume.snaps_to_remove_src
    if current_volume.snaps_to_remove_dst is not None:
        delete_snaps_table += current_volume.snaps_to_remove_dst

logger.debug('<work_table> {0}'.format(work_table))
print_table_as_is(reform_table_fix_columns_sizes(work_table, [18, 18, 18, 12, 5]))
continue_or_exit('start send snapshots', True)
linux_workaround_umount(umount_tmp)
result_table += list(map(lambda lst: send_snap(lst[0], lst[2], lst[3], debug_flag, False), work_table[1:]))
logger.debug('<result_table> {0}'.format(result_table))
logger.info('result work table below:')
print_table_as_is(reform_table_fix_columns_sizes(result_table, [12, 12, 5, 12, 7, 5, 12]))
if len(delete_snaps_table) > 1:
    logger.info('list to delete snap according config below:')
    logger.debug('<delete_snaps_table>'.format(delete_snaps_table))
    print_table_as_is(reform_table_fix_columns_sizes(delete_snaps_table, 25))
    continue_or_exit('delete snaps?', True)
    tuple(map(lambda lst: destroy_snaps(lst[0]), delete_snaps_table[1:]))
else:
    logger.info('no snaps to delete according config')

usb_disk.umount()
linux_workaround_mount(umount_tmp)
logger.info("----------- END ------------")


__version__ = "0.1.1"

import sqlite3

import TFIDFEngine

def main():
    #Load engine
    engine = TFIDFEngine.BasicTFIDFEngine()
    engine.load(args.vsm_pickle)

    conn = sqlite3.connect(args.out_db)
    conn.row_factory = sqlite3.Row
    cursor = conn.cursor()

    cursor.execute("CREATE TABLE doc_statistics (doc_name TEXT UNIQUE, doc_len INTEGER);")

    for doc_name in sorted(engine.corpus):
        doc_len = 0
        #Don't fail on empty signatures.
        if not doc_name in engine.tf:
            continue
        #Define length of document as number of terms that appear >0 times.
        for term in engine.tf[doc_name]:
            if engine.tf[doc_name].get(term, 0) > 0:
                doc_len += 1
        cursor.execute("INSERT INTO doc_statistics (doc_name, doc_len) VALUES (?,?);", (doc_name, doc_len))
    conn.commit()

if __name__ == "__main__":
    import argparse
    parser = argparse.ArgumentParser()
    parser.add_argument("vsm_pickle")
    parser.add_argument("out_db")
    args = parser.parse_args()

    main()


#! /u/sgupta45/conda/bin/python3
import itertools
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
import numpy as np
import sys

hatch = {'FCFS': '*', 'LEDF': '.', 'GLAX': 'xx', 'APRX3': '/'}

def geo_mean(iterable):
    a = np.array(iterable)
    return a.prod()**(1.0/len(a))

def add_plot(offset, policy, label):
    if policy in hatch:
        plt.bar([i+offset for i in x], total_mem_time[policy], edgecolor='k',
                width=width, label=label, fc='w', hatch=hatch[policy])
    else:
        plt.bar([i+offset for i in x], total_mem_time[policy], edgecolor='k',
                width=width, label=label, fc='k')

policies = ['FCFS', 'LEDF', 'GEDF', 'GLAX', 'APRX3', 'xbar']
applications = ['canny', 'deblur', 'gru', 'harris', 'lstm']

num_acc_types = 7
num_instances = [1, 2, 1, 4, 1, 1, 1]
acc_id_to_name = ['canny_non_max', 'convolution', 'edge_tracking',
        'elem_matrix', 'grayscale', 'harris_non_max', 'isp']
app_mixes = sorted([c for c in itertools.combinations(applications, 3)])

total_mem_time = {p:[] for p in policies}

for policy in policies:
    for app_mix in app_mixes:
        critical_path = [[[] for j in range(num_instances[i])]
                for i in range(num_acc_types)]
        mem_time = [[[] for j in range(num_instances[i])]
                for i in range(num_acc_types)]

        # load the critical path
        out_file = '/u/sgupta45/scheduler/critical_paths/'
        if policy == 'xbar': out_file += 'APRX3/' + '_'.join(app_mix)
        else:                out_file += policy + '/' + '_'.join(app_mix)

        for line in open(out_file):
            tokens = line.split()
            if len(tokens) == 0: continue

            acc_type = int(tokens[0])
            acc_inst = int(tokens[1])
            node_id = int(tokens[2])

            critical_path[acc_type][acc_inst].append(node_id)

        # load all memory access times
        app_mix_str = ''
        for app in applications:
            app_mix_str += app + '_'
            app_mix_str += '4_' if app in app_mix else '0_'

        out_file = '/u/sgupta45/gem5-SALAM/BM_ARM_OUT/'
        if policy == 'xbar':
            out_file += 'image_4_parallel_dma_xbar/' + app_mix_str + \
                    'APRX3_pipeline/debug-trace.txt'
        else:
            out_file += 'image_4_parallel_dma_bus/' + app_mix_str + policy + \
                    '_pipeline/debug-trace.txt'

        for acc_type in range(num_acc_types):
            for acc_inst in range(num_instances[acc_type]):
                acc_name = acc_id_to_name[acc_type] + str(acc_inst)

                curr_mem_time = 0
                is_compute_valid = False
                dma_op = ''

                for line in open(out_file):
                    if (acc_name in line) or ('Runtime' in line):
                        if 'Transfer completed' in line:
                            dma_time = float(line.split()[5])
                            if 'DST:0x000000008' in dma_op:
                                mem_time[acc_type][acc_inst][-1] += dma_time
                            else:
                                curr_mem_time += dma_time
                        elif is_compute_valid and ('Runtime' in line) and \
                             ('us' in line):
                            mem_time[acc_type][acc_inst].append(curr_mem_time)

                            curr_mem_time = 0
                            is_compute_valid = False

                        if 'SRC:' in line:
                            dma_op = line
                        if '.compute' in line:
                            is_compute_valid = True

        # accumulate compute and mem time on the critical path
        mem_critical = 0

        for acc_type in range(num_acc_types):
            for acc_inst in range(num_instances[acc_type]):
                for i in range(len(mem_time[acc_type][acc_inst])):
                    if i in critical_path[acc_type][acc_inst]:
                        mem_critical += mem_time[acc_type][acc_inst][i]

        total_mem_time[policy].append(mem_critical)

# calculate geo-mean for each policy
for policy in policies:
    if policy == 'GEDF': continue

    for i in range(len(total_mem_time['GEDF'])):
        total_mem_time[policy][i] /= total_mem_time['GEDF'][i]

    total_mem_time[policy].append(geo_mean(total_mem_time[policy]))

x = [i for i in range(len(app_mixes)+1)]
x_labels = ['Mix ' + str(i) for i in range(len(app_mixes))] + ['Gmean']

plt.figure(figsize=(24, 8), dpi=600)
plt.rc('axes', axisbelow=True)

width = 0.16
add_plot(-(width*2), 'FCFS',  'FCFS')
add_plot(-width,     'LEDF',  'GEDF-D')
add_plot(0,          'GLAX',  'LAX')
add_plot(width,      'APRX3', 'ELF')
add_plot((width*2),  'xbar',  'ELF-xbar')

plt.xlabel('Application mix', fontsize=35)
plt.xticks(x, x_labels, fontsize=35, rotation='vertical')

plt.ylabel('Time spent on DMA\n(norm. to GEDF-N)', fontsize=35)
plt.yticks(fontsize=35)
plt.ylim([0, 1.7])
plt.gca().yaxis.set_major_locator(plt.MultipleLocator(0.2))

plt.legend(loc="upper left", ncol=5, fontsize=35)
plt.grid(color='silver', linestyle='-', linewidth=1)
plt.savefig('plots/mem_time_critical.pdf', bbox_inches='tight')


# -*- coding: utf-8 -*-
"""
Created on Thu May 21 13:09:23 2020

@author:maregul

to me, you are my perfect
"""
import os
import time
import openpyxl

def setdate(x):
     a=str(int(time.strftime("%Y")))
     b=str(int(time.strftime("%m")))
     c=str(int(time.strftime("%d"))+x)

     monthday=0
     biglist=[1,3,5,7,8,10,12]
     smalllist=[4,6,9,11]
     if int(time.strftime("%m"))==4:
          monthday=28
     if int(time.strftime("%m")) in biglist:
          monthday=31
     if int(time.strftime("%m")) in smalllist:
          monthday=30

     if int(c)>monthday:
          c=str(int(c)-monthday)
          b=str(int(b)+1)

     day=a+'年'+b+'月'+c+'日'
     return day

reviewList=openpyxl.load_workbook("复习清单.xlsx")
sheet=reviewList['Sheet1']

sign=2
signCell='B'+str(sign)
test=sheet[signCell].value
while(test):
     sign+=1
     signCell='B'+str(sign)
     test=sheet[signCell].value

today=str(int(time.strftime("%Y")))+'年'+str(int(time.strftime("%m")))+'月'+str(int(time.strftime("%d")))+'日'

order=str(input())

if order=='1':#检索需要复习的内容并输出

     sign-=1
     signCell='H'+str(sign)
     j=1

     for a in sheet['C3':signCell]:
          for b in a:
               if b.value==today:
                    rownum=int(b.row)
                    contextcell='B'+str(rownum)
                    print(str(j)+'、'+str(sheet[contextcell].value))
                    j+=1
                    break

if order=='2':
     context=str(input())
     sheet[signCell]=(context)
     time0='C'+str(sign)
     sheet[time0]=today

     time1='D'+str(sign)
     time2='E'+str(sign)
     time3='F'+str(sign)
     time4='G'+str(sign)
     time5='H'+str(sign)

     sheet[time1]=setdate(1)
     sheet[time2]=setdate(2)
     sheet[time3]=setdate(4)
     sheet[time4]=setdate(7)
     sheet[time5]=setdate(15)

     reviewList.save("复习清单.xlsx")

print("加油哦!!会当凌绝顶一览众山小")

os.system("pause")


"""
.. module:: HierarchicalAuthors

HierarchicalAuthors
*************

:Description: HierarchicalAuthors

:Authors: bejar

:Version:

:Created on: 18/09/2015 9:35

"""

__author__ = 'bejar'

from os import listdir
from os.path import join
from sklearn.feature_extraction.text import CountVectorizer, TfidfVectorizer
from scipy.cluster.hierarchy import linkage, dendrogram, fcluster
from sklearn.metrics import adjusted_mutual_info_score
import argparse

path = '/home/bejar/Data/authors/'

def authors_data(method=1, nfeatures=100):
    """
    Returns a data matrix representing the documents using the indicated method for generating the features and the
    specified number of features and the labels for the documents

    :param method:
    :param nfeatures:
    :return:
    """

    docs = sorted(listdir(docpath))[1:]

    # use v[:2] for dataset labels, use [2:-2] for individual authors
    labs = [v[:2] for v in docs]
    ulabs = sorted(list(set(labs)))
    dlabs = {}
    for ul, v in zip(ulabs, range(len(ulabs))):
        dlabs[ul] = v
    labels = [dlabs[v] for v in labs]

    pdocs = [join(docpath, f) for f in docs]

    if method == 1:  # Features are word counts
        cvec = CountVectorizer(input='filename', stop_words='english', max_features=nfeatures)
    elif method == 2:  # Features are TF-IDF
        cvec = TfidfVectorizer(input='filename', stop_words='english', max_features=nfeatures)
    elif method == 3:  # Features are word occurence
        cvec = TfidfVectorizer(input='filename', stop_words='english', max_features=nfeatures, binary=True,
                               use_idf=False, norm=False)

    return cvec.fit_transform(pdocs).toarray(), labels

if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument('--data', default=1, choices = [1,2], help='Dataset to use (1 or 2)', type=int)
    parser.add_argument('--nfeatures', help="Number of features to generate", default=100, type=int)
    parser.add_argument('--fmethod', help="Method for generating features", default=1, choices=[1,2,3], type=int)
    args = parser.parse_args()

    if args.data == 1:
        docpath = path + 'Auth1/'
    else:
        docpath = path + 'Auth2/'

    nfeatures = args.nfeatures
    method = args.fmethod

    authors, alabels = authors_data(method, nfeatures)

    ### Ward
    clust = linkage(authors, method='ward')
    fig = plt.figure(figsize=(8, 8))
    fig.suptitle('Ward', fontsize=32)
    dendrogram(clust)
    plt.show()
    labels = fcluster(clust, 2, criterion='maxclust')
    print(adjusted_mutual_info_score(alabels, labels))

    ### Single
    clust = linkage(authors, method='single')
    fig = plt.figure(figsize=(8, 8))
    fig.suptitle('Single Link', fontsize=32)
    dendrogram(clust)
    plt.show()
    labels = fcluster(clust, 2, criterion='maxclust')
    print(adjusted_mutual_info_score(alabels, labels))

    ### Complete
    clust = linkage(authors, method='complete')
    fig = plt.figure(figsize=(8, 8))
    fig.suptitle('Complete Link', fontsize=32)
    dendrogram(clust)
    plt.show()
    labels = fcluster(clust, 2, criterion='maxclust')
    print(adjusted_mutual_info_score(alabels, labels))

    ### Average
    clust = linkage(authors, method='average')
    fig = plt.figure(figsize=(8, 8))
    fig.suptitle('Average', fontsize=32)
    dendrogram(clust)
    plt.show()
    labels = fcluster(clust, 2, criterion='maxclust')
    print(adjusted_mutual_info_score(alabels, labels))

    ### Centroid
    clust = linkage(authors, method='centroid')
    fig = plt.figure(figsize=(8, 8))
    fig.suptitle('Centroid', fontsize=32)
    dendrogram(clust)
    plt.show()
    labels = fcluster(clust, 2, criterion='maxclust')
    print(adjusted_mutual_info_score(alabels, labels))


import logging

# Third-party modules
import orjson
from typing import Optional, Dict

# NOC modules
from noc.core.http.client import fetch_sync
from noc.config import config
from noc.core.perf import metrics
from noc.core.comp import smart_text
from noc.core.liftbridge.base import LiftBridgeClient
from noc.core.ioloop.util import run_sync

logger = logging.getLogger(__name__)

def pub(topic, data, raw=False):
    logger.debug("Publish to topic %s", topic)
    url = "http://%s:%s/pub" % (
        config.nsqd.http_addresses[0].host,
        config.nsqd.http_addresses[0].port,
    )
    code, headers, body = fetch_sync(
        "%s?topic=%s" % (url, topic),
        method="POST",
        body=data if raw else smart_text(orjson.dumps(data)),
        connect_timeout=config.nsqd.connect_timeout,
        request_timeout=config.nsqd.request_timeout,
    )
    if code != 200:
        metrics["error", ("type", "nsq_pub_error_code %s" % code)] += 1
        raise Exception("Cannot publish: %s %s" % (code, body))

def publish(
    value: bytes,
    stream: str,
    partition: Optional[int] = None,
    key: Optional[bytes] = None,
    headers: Optional[Dict[str, bytes]] = None,
):
    async def wrap():
        async with LiftBridgeClient() as client:
            await client.publish(
                value=value, stream=stream, partition=partition, key=key, headers=headers
            )

    run_sync(wrap)


import logging
from typing import Any, List, Dict, Optional

from abcckpt import ckpt_constants
from abccore.checkpoint_service import CheckpointService
from abcnet.handlers import AbstractItemHandler
from abcnet.services import ChannelService
from abcnet.structures import Message
from abcnet.timer import SimpleTimer
from abcckpt.ckptItems import CkptItemType, ValidatorVote, CkptHash, CkptData
from abcckpt.ckptParser import CkptItemsParser
from abcckpt.ckpt_creation_state import CkptCreationState, StateTransitionObserver
from abcckpt.ckpt_creation_state import PreCkptStatus as ps, PreCkptStatus
from abcckpt.ckpt_syncronizer import CkptSync
from abcckpt.ckptproposal import PostCheckpoint
from abcckpt.pre_checkpoint import PreCheckpoint, PreCkptItemProcessor, AgentService
from abcckpt.vote_cr_handler import VoteCrHandler

logger = logging.getLogger(__name__)

class ContentHandler(AbstractItemHandler, StateTransitionObserver, PreCkptItemProcessor):
    """
    Class for processing checkpoint proposal content in step AGREE_CONTENT in checkpoint creation. OK or PASS votes are
    created after verifying the proposal received.
    """
    ckpt_hash: CkptHash
    vote_creator: VoteCrHandler
    ckpt_sync: CkptSync

    def __init__(self, pre_ckpt: PreCheckpoint, agent_service: AgentService, ckpt_service: CheckpointService):
        super(ContentHandler, self).__init__([CkptItemType.CKPT_DATA], CkptItemsParser())
        self.pc: PreCheckpoint = pre_ckpt
        self.agent_service = agent_service
        self.ckpt_service = ckpt_service

        self.ckpt_hash: Optional[CkptHash] = None
        self.content_timer: Optional[SimpleTimer] = None
        self.vote_sent = False

        self.pending_content_timer: Optional[SimpleTimer] = None
        self.finalzd_content: Dict[str, CkptData] = {}

        self.queued_content: List[CkptData] = []
        self.queued_votes: Dict[bytes, List[ValidatorVote]] = {}
        self.verified_content: Dict[str, CkptData] = {}
        self.rejected_content: List[bytes] = []
        self.fetch_list = set()
        self.timeout_timers = [
            (self.try_vote, SimpleTimer(4.0)),
            (self.send_request_for_missing, SimpleTimer(1.0)),
            (self.send_content_of_requested, SimpleTimer(1.0))

        ]

    def transition(self, votes: List, voted_content_hash_id):
        if voted_content_hash_id is None:
            # PASS majority
            new_state = CkptCreationState.copy(self.pc.state, next_round=True)
            new_state.voted_chosen_val(None)
            new_state.voted_content_hash(None)
            new_state.step_status = PreCkptStatus.AGREE_VALIDATOR
            logger.warning(f"PASS case: State transition to AGREE_VALIDATOR")
            self.pc.state_transition(new_state, votes)

        # If ok is reached:
        else:
            if not isinstance(voted_content_hash_id, str) and voted_content_hash_id not in self.finalzd_content:
                raise Exception(f"Transition is invoked with an invalid content item: {voted_content_hash_id}")

            ckpt = self.finalzd_content[voted_content_hash_id]
            # Inject the new checkpoint into the agent:
            # self.agent_service.inject_checkpoint(ckpt.checkpoint_data)
            # TODO add votes check to ckpt sync handler
            self.ckpt_sync.update_ckpt(ckpt.checkpoint_data, external=True)
            voted_content_hash = ckpt.get_ckpt_hash()

            self.reset_queues()
            logger.info(f"AGREE CONTENT round completed. AGREE_VALIDATOR state set ")
            logger.info(f"Voted content message ID is:{voted_content_hash_id}")
            logger.info(f"Voted checkpoint hash:{voted_content_hash.hex()[:6]}")

    def reset_queues(self):
        logger.info(f"Clearing content handler queues")
        self.ckpt_hash: Optional[CkptHash] = None
        self.queued_content = []
        self.queued_votes: Dict[bytes, List[ValidatorVote]] = {}
        self.verified_content: Dict[str, CkptData] = {}
        self.finalzd_content: Dict[str, CkptData] = {}
        self.fetch_list.clear()
        self.vote_sent = False

    def set_handlers(self, vote_creator: VoteCrHandler, ckpt_sync: CkptSync):
        self.vote_creator: VoteCrHandler = vote_creator
        self.ckpt_sync = ckpt_sync

    def process_content(self, content: CkptData):
        if content.item_qualifier() in self.verified_content:
            return
        auth_result = content.verify_signature()
        item_id = content.item_qualifier()
        if not auth_result:
            logger.warning(f"Invalid signature for hash msg:{item_id}")
            return

        if self.pc.state != content.state:
            logger.warning("Rejected content because of wrong state %s != %s", self.pc.state, content.state)
            return

        if self.pc.state.content_hash != content.ckpt_hash:
            logger.warning("Rejected content because its hash %s is not the same as the chosen hash: %s",
                           content.ckpt_hash.hex(), self.pc.state.content_hash.hex())
            return

        sign_pk = content.signature[0]
        if sign_pk != self.pc.state.chosen_validator:
            logger.warning("Rejected content because it is not signed by the chosen validator: %s"
                           " but it is instead signed by %s.",
                           self.pc.state.chosen_validator.hex(), sign_pk.hex())
            return

        self.verified_content[content.item_qualifier()] = content
        self.pending_content_timer = SimpleTimer(ckpt_constants.PROPOSAL_TXNS_RCV_TIME, start=True)
        logger.info("Received checkpoint content with the expected hash: %s", content.ckpt_hash.hex()[:6])
        return

    def has_timer_run_out(self):
        if self.content_timer is None:
            return False
        return self.content_timer.check()

    def create_pass_vote(self):
        self.vote_creator.create_vote(None, CkptItemType.CKPT_DATA)
        self.vote_sent = True

    def try_vote(self, cs):
        self.process_verified_content()
        self.check_content_timeout()

    def process_verified_content(self):
        if len(self.verified_content) == 1 and not self.vote_sent:
            content: CkptData = next(iter(self.verified_content.values()))
            if not self.pending_content_timer.check():
                content_check, status = self.__verify_content(content)
                if status == 'PENDING':
                    logger.info("Checkpoint content verification is pending, hash: %s", content.ckpt_hash.hex()[:6])
                    return
                if content_check:
                    self.finalzd_content[content.item_qualifier()] = content
                    logger.info("Finalized checkpoint content with the expected hash: %s, content ID:%s", content.ckpt_hash.hex()[:6], content.item_qualifier()[:6])
                elif not content_check:
                    logger.warning("Invalid content, rejecting content ID : %s", content.item_qualifier())
                    # PASS vote if content from chosen validator is invalid
                    self.create_pass_vote()
            else:
                logger.warning("Pending txns check timedout, rejecting content ID: %s",content.item_qualifier())
                #PASS vote if content from chosen validator could not be validated within timer for checking pending txns
                self.create_pass_vote()

    def __verify_content(self, content):
        local_dag = self.agent_service.get_DAG()
        ckpt_data = content.checkpoint_data
        content_check, status = PostCheckpoint.checkpoint_verify(local_dag, ckpt_data, self.ckpt_service,
                                                                 self.agent_service)
        return content_check, status

    def check_content_timeout(self):
        if not self.vote_sent and len(self.finalzd_content) == 1:
            # create vote for hash of content received and verified
            content: CkptData = next(iter(self.verified_content.values()))
            self.vote_creator.create_vote(content.item_qualifier(), CkptItemType.CKPT_DATA)
            self.vote_sent = True
        # if not self.vote_sent and (self.has_timer_run_out() or len(self.verified_content) > 1):
        if not self.vote_sent:
            # create PASS vote if no content received within timeout or multiple contents received from chosen validator
            if self.has_timer_run_out():
                logger.info(f"PASS vote created as no content received within timeout")
                self.create_pass_vote()
            elif len(self.verified_content) > 1:
                logger.info(f"PASS vote creates as multiple contents received from chosen validator")
                self.create_pass_vote()

    def handle_state_transition(self, state: CkptCreationState):
        self.reset_queues()
        if state.step_status == PreCkptStatus.AGREE_CONTENT:
            self.content_timer = SimpleTimer(ckpt_constants.CKPT_PROPOSAL_RCV_TIMEOUT, start=True)

    def perform_maintenance(self, cs: ChannelService, force_maintenance=False):
        self.check_state_transition()
        if self.pc.state.step_status == PreCkptStatus.AGREE_CONTENT:
            # self.send_request_for_missing(cs)
            for maintenance_method, timer in self.timeout_timers:
                if timer():
                    maintenance_method(cs)

    def handle_item_content(self, cs: "ChannelService", msg: Message, item_type: int, item_content: Any):  # items()
        if item_type == CkptItemType.CKPT_DATA and item_content is not None and isinstance(item_content, CkptData) \
                and not self.has_content(item_content.item_qualifier()):
            self.process_content(item_content)

    def handle_item_checklist(self, cs: "ChannelService", msg: Message, item_type: int,
                              item_qualifier: str):  # checklist()
        if not self.has_content(item_qualifier):
            self.fetch_list.add((item_type, item_qualifier))

    def send_request_for_missing(self, cs: ChannelService):
        if self.fetch_list:
            cs.broadcast_channel().fetch_items(list(self.fetch_list))
            self.fetch_list.clear()

    def has_content(self, item_qualifier):
        if item_qualifier in self.verified_content or item_qualifier in self.rejected_content or item_qualifier in self.finalzd_content:
            return True
        return False

    def check_item_exists(self, item_qualifier) -> bool:
        if item_qualifier in self.finalzd_content:
            return True
        elif item_qualifier in self.rejected_content or item_qualifier in self.verified_content:
            logger.error("Checking content item in invalid queues, trying to initiate transition an invalid content item")
            return True
        self.fetch_list.add((CkptItemType.CKPT_DATA, item_qualifier))
        return False

    def send_content_of_requested(self, cs: ChannelService):
        for type, item_qualifier in self.fetch_list:
            if item_qualifier in self.verified_content:
                cs.broadcast_channel().items([self.verified_content[item_qualifier]])