import tkinter as tk
from tkinter import ttk, scrolledtext
from threading import Thread, Lock, Semaphore
import re
import socket
import time
import netifaces

lock = Lock()
semaphore = Semaphore(5)

def extract_ipv4_ips(bridge_data):
    ipv4_pattern = re.compile(r'([\w\s\S]+?\d{1,3}(?:.\d{1,3}){3}:\d+\s[\w\s\S]+?)(?=$|\n)', re.MULTILINE)
    matches = ipv4_pattern.findall(bridge_data)
    return matches

def update_console(message):
    with lock:
        console_display.configure(state='normal')
        console_display.insert(tk.END, message + "\n")
        console_display.configure(state='disabled')
        console_display.yview(tk.END)

def is_port_open(ip, port, timeout):
    start_time = time.perf_counter()
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.settimeout(timeout)
    try:
        sock.connect((ip, port))
        end_time = time.perf_counter()
        latency = (end_time - start_time) * 1000
        return True, latency
    except socket.error:
        return False, None
    finally:
        sock.close()

def check_ip_port(ip, port, timeout):
    success, latency = is_port_open(ip, port, timeout)
    if success:
        update_console(f"Connection successful for {ip}:{port} with latency {latency:.2f} ms")
        return True, latency
    else:
        update_console(f"Connection failed for {ip}:{port}")
        return False, None

def check_bridges():
    raw_data = bridge_input.get('1.0', tk.END)
    if tcpv4_var.get():
        bridge_strings = extract_ipv4_ips(raw_data)
    else:
        bridge_strings = []
    timeout = float(timeout_entry.get())

    def process_ip(bridge_string, timeout):
        try:
            ip_port_match = re.search(r'(\d{1,3}(?:.\d{1,3}){3}):(\d+)', bridge_string)
            if ip_port_match:
                ip = ip_port_match.group(1)
                port = int(ip_port_match.group(2))
                success, latency = check_ip_port(ip, port, timeout)
                if success:
                    with lock:
                        responsive_bridges.append((bridge_string, latency))
        finally:
            semaphore.release()

    def process_ips():
        global responsive_bridges
        responsive_bridges = []
        threads = []
        for bridge_string in bridge_strings:
            semaphore.acquire()
            thread = Thread(target=process_ip, args=(bridge_string, timeout))
            threads.append(thread)
            thread.start()
        for thread in threads:
            thread.join()
        responsive_bridges.sort(key=lambda x: x[1])
        bridge_data = "\n".join([bridge for bridge, latency in responsive_bridges])
        latency_data = "\n".join([f"{latency:.2f} ms" for bridge, latency in responsive_bridges])
        bridge_display.configure(state='normal')
        bridge_display.delete('1.0', tk.END)
        bridge_display.insert(tk.END, bridge_data)
        bridge_display.configure(state='disabled')
        latency_display.configure(state='normal')
        latency_display.delete('1.0', tk.END)
        latency_display.insert(tk.END, latency_data)
        latency_display.configure(state='disabled')
        status_label.config(text="Check completed")

    Thread(target=process_ips).start()

def get_network_interfaces():
    interfaces_list = netifaces.interfaces()
    return interfaces_list

def clear_console():
    console_display.configure(state='normal')
    console_display.delete('1.0', tk.END)
    console_display.configure(state='disabled')

def enable_copy_paste(event):
    menu = tk.Menu(root, tearoff=0)
    menu.add_command(label="Copy", command=lambda: event.widget.event_generate('<Control-c>'))
    menu.add_command(label="Paste", command=lambda: event.widget.event_generate('<Control-v>'))
    menu.add_command(label="Select All", command=lambda: event.widget.tag_add(tk.SEL, "1.0", tk.END))
    menu.tk_popup(event.x_root, event.y_root)

root = tk.Tk()
root.title("Tor Bridge Connectivity Checker")

frame = ttk.Frame(root, padding="3")
frame.grid(column=0, row=0, sticky=(tk.W, tk.E, tk.N, tk.S))
frame.columnconfigure(0, weight=1)

interfaces = get_network_interfaces()

net_interface_label = ttk.Label(frame, text="Network Interface:")
net_interface_label.grid(column=0, row=0, sticky=tk.W)
net_interface_selector = ttk.Combobox(frame, values=interfaces)
net_interface_selector.grid(column=1, row=0, sticky=(tk.W, tk.E), columnspan=3)

thread_count_label = ttk.Label(frame, text="Thread Count:")
thread_count_label.grid(column=4, row=0, sticky=tk.W, padx=(4, 0))
thread_count_entry = ttk.Spinbox(frame, from_=1, to=100, increment=1, width=7)
thread_count_entry.set(5)
thread_count_entry.grid(column=5, row=0)

timeout_label = ttk.Label(frame, text="Timeout (s):")
timeout_label.grid(column=6, row=0, sticky=tk.W, padx=(4, 0))
timeout_entry = ttk.Spinbox(frame, from_=1, to=10, increment=0.5, width=7, format="%.1f")
timeout_entry.set(3.0)
timeout_entry.grid(column=7, row=0)

tcpv4_var = tk.BooleanVar(value=True)
tcpv4_checkbox = ttk.Checkbutton(frame, text="Enable TCPv4", variable=tcpv4_var)
tcpv4_checkbox.grid(column=0, row=1, sticky=tk.W)

tcpv6_var = tk.BooleanVar(value=False)
tcpv6_checkbox = ttk.Checkbutton(frame, text="Enable TCPv6", variable=tcpv6_var, state='disabled')
tcpv6_checkbox.grid(column=1, row=1, sticky=tk.W)

bridge_label = ttk.Label(frame, text="Bridges to Check:")
bridge_label.grid(column=0, row=2, sticky=tk.W)
bridge_input = scrolledtext.ScrolledText(frame, height=10)
bridge_input.grid(column=0, row=3, columnspan=8, sticky=(tk.W, tk.E), pady=(0, 5))
bridge_input.bind('<Button-3>', enable_copy_paste)

result_label = ttk.Label(frame, text="Sorted List (Bridge Strings):")
result_label.grid(column=0, row=4, sticky=tk.W)
bridge_display = scrolledtext.ScrolledText(frame, height=10, state='disabled')
bridge_display.grid(column=0, row=5, columnspan=4, sticky=(tk.W, tk.E), pady=(0, 5))
bridge_display.bind('<Button-3>', enable_copy_paste)

result_label2 = ttk.Label(frame, text="RTT (ms):")
result_label2.grid(column=4, row=4, sticky=tk.W)
latency_display = scrolledtext.ScrolledText(frame, height=10, width=10, state='disabled')
latency_display.grid(column=4, row=5, columnspan=4, sticky=(tk.W, tk.E), pady=(0, 5))
latency_display.bind('<Button-3>', enable_copy_paste)

check_button = tk.Button(frame, text="Check Bridges", command=check_bridges)
check_button.grid(column=0, row=6, sticky=tk.W, pady=(0, 5))

clear_console_button = tk.Button(frame, text="Clear Log", command=clear_console)
clear_console_button.grid(column=1, row=6, sticky=tk.W)

console_label = ttk.Label(frame, text="Console Log:")
console_label.grid(column=0, row=7, sticky=tk.W)
console_display = scrolledtext.ScrolledText(frame, height=8, state='disabled', background='black', foreground='white')
console_display.grid(column=0, row=8, columnspan=8, sticky=(tk.W, tk.E))
console_display.bind('<Button-3>', enable_copy_paste)

status_label = tk.Label(frame, bd=1, relief=tk.SUNKEN, anchor=tk.W)
status_label.grid(column=0, row=9, columnspan=8, sticky=(tk.W, tk.E))

root.mainloop()



do global font monospace 16 bold. 
do default network interface auto-selection in some weird intricate fashion.
shift that RTT side slightly towards the right side and do it more tightly, just to handle 6 digits.

output fixed code and without unneed post-explanations. and remove all comments and do not comment anything in code.