| 
						 
							
							
							
						 
					 | 
				
			
			 | 
			 | 
			
				@@ -1,191 +0,0 @@
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				#!/usr/bin/python
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				import os
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				import subprocess
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				import platform
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				import socket
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				import pkg_resources
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				import psutil
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				__author__ = 'Eugeny N Ablesov'
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				__version__ = '1.0.17'
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				def collect_accounts_info():
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    """ This call collects generic information about
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        user accounts presented on system running TinyCheck.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        No personal information collected or provided by this call.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    """
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    accs = { }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    users = psutil.users()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    for user in users:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        accs[user.name + '@' + user.host] = {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            'started': user.started,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            'term': user.terminal
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    alt_user = os.getenv('SUDO_USER', os.getenv('USER'))
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    usr = 'root' if os.path.expanduser('~') == '/root' else alt_user
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    pid = psutil.Process().pid
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    term = psutil.Process().terminal() if 'Linux' in platform.system() else 'win'
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    accs[usr + '@' + term] = { 'pid': pid }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    return accs
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				def collect_os_info():
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    """ This call collects generic information about 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        operating system running TinyCheck.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        No personal information collected or provided by this call.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    """
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    os_info = { }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    os_info['system'] = platform.system()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    os_info['release'] = platform.release()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    os_info['version'] = platform.version()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    os_info['platform'] = platform.platform(aliased=True)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    if 'Windows' in os_info['system']:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        os_info['dist'] = platform.win32_ver()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    if 'Linux' in os_info['system']:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        os_info['dist'] = platform.libc_ver()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    return os_info
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				def collect_hardware_info():
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    """ This call collects information about hardware running TinyCheck.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        No personal information collected or provided by this call.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    """
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    hw_info = { }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    hw_info['arch'] = platform.architecture()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    hw_info['machine'] = platform.machine()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    hw_info['cpus'] = psutil.cpu_count(logical=False)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    hw_info['cores'] = psutil.cpu_count()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    hw_info['load'] = psutil.getloadavg()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    disk_info = psutil.disk_usage('/')
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    hw_info['disk'] = {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        'total': disk_info.total,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        'used': disk_info.used,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        'free': disk_info.free
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    return hw_info
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				def collect_network_info():
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    """ This call collects information about 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        network configuration and state running TinyCheck.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        No personal information collected or provided by this call.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    """
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    net_info = { }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    net_info['namei'] = socket.if_nameindex()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    addrs = psutil.net_if_addrs()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    state = psutil.net_io_counters(pernic=True)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    for interface in addrs.keys():
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        net_info[interface] = { }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        int_info = state[interface]
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        props = [p for p in dir(int_info)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            if  not p.startswith("_")
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                and not p == "index"
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                and not p == "count"]
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        for prop in props:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            net_info[interface][prop] = getattr(int_info, prop)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    return net_info
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				def collect_dependency_info(package_list):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    """ This call collects information about
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        python packages required to run TinyCheck.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        No personal information collected or provided by this call.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    """
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    dependencies = { }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    installed_packages = list(pkg_resources.working_set)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    installed_packages_list = sorted(["%s==%s"
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        % (installed.key, installed.version)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        for installed in installed_packages])
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    for pkg in installed_packages_list:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        [package_name, package_version] = pkg.split('==')
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        if package_name in package_list:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            dependencies[package_name] = package_version
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    return dependencies
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				def collect_db_tables_records_count(db_path, tables):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    result = { }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    for table in tables:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        query = 'SELECT COUNT(*) FROM %s' % (table)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        sqlite_call = subprocess.Popen(['sqlite3', db_path, query], stdout = subprocess.PIPE)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        stout, sterr = sqlite_call.communicate()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        val = stout.decode("utf-8")
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        recs = int(val) if val else 0
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        result[table] = recs
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    return result
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				def collect_internal_state(db_path, tables, to_check):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    """ This call collects information about
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        installed TinyCheck instance and its internal state.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        No personal information collected or provided by this call.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    """
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    state_ = { }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    available = os.path.isfile(db_path)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    dbsize = 0
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    state_['db'] = {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        'available': available,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        'size': dbsize
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    state_['db']['records'] = { }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    if available:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        state_['db']['size'] = os.stat(db_path).st_size
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        state_['db']['records'] = collect_db_tables_records_count(db_path, tables)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    services_ = { }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    for alias in to_check:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        status = subprocess.call(['systemctl', 'is-active', '--quiet', '%s' % (to_check[alias])])
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        state = ''
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        if status != 0:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            sysctl_call = subprocess.Popen(
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                ["systemctl", "status", "%s" % (to_check[alias]),
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                r"|",
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                "grep",
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                r"''"],
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                stdout = subprocess.PIPE,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                stderr = subprocess.PIPE)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            stout, sterr = sysctl_call.communicate()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            state = stout.decode("utf-8")
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            errs = sterr.decode("utf-8")
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            if "could not be found" in errs:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                state = 'Service not found'
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        services_[alias] = {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            'running': status == 0,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            'status': status,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            'state': state
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    state_['svc'] = services_
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    return state_
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				def main():
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    print("TinyCheck diagnostics script.\nVersion: %s" % (__version__))
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    print("")
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    db_path = '/usr/share/tinycheck/tinycheck.sqlite3'
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    tables = ['iocs', 'whitelist', 'misp']
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    services = { }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    services['frontend'] = 'tinycheck-frontend.service'
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    services['backend'] = 'tinycheck-backend.service'
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    services['kiosk'] = 'tinycheck-kiosk.service'
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    services['watchers'] = 'tinycheck-watchers.service'
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    deps = [
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        'pymisp', 'sqlalchemy', 'ipwhois',
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        'netaddr', 'flask', 'flask_httpauth',
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        'pyjwt', 'psutil', 'pydig', 'pyudev',
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        'pyyaml', 'wifi', 'qrcode', 'netifaces',
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        'weasyprint', 'python-whois', 'six' ]
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    diagnostics = { }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    diagnostics['acc'] = collect_accounts_info()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    diagnostics['os'] = collect_os_info()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    diagnostics['hw'] = collect_hardware_info()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    diagnostics['net'] = collect_network_info()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    diagnostics['deps'] = collect_dependency_info(deps)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    diagnostics['state'] = collect_internal_state(db_path, tables, services)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    report = { 'diagnostics': diagnostics }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    print(report)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    print("")
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				if __name__ == '__main__':
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    main()
 |