From 193908f28dfde5ec156f84bfa7bb8ea4021c8b3a Mon Sep 17 00:00:00 2001 From: aschumann-virtualcable Date: Wed, 24 Sep 2025 12:13:30 +0200 Subject: [PATCH 1/2] init dev --- actor | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/actor b/actor index 3c40cb45f..04ce3fc2d 160000 --- a/actor +++ b/actor @@ -1 +1 @@ -Subproject commit 3c40cb45f078d27a7673527f42961f1e65135fa5 +Subproject commit 04ce3fc2d1528fc9e6b01c50809f02239e6bb431 From af7f5d9608668fefff3e3db76ea3e0bd9a6055e5 Mon Sep 17 00:00:00 2001 From: aschumann-virtualcable Date: Thu, 12 Mar 2026 22:39:19 +0100 Subject: [PATCH 2/2] Refactor logging statements and improve error handling in RDP scripts for better clarity and debugging --- .../src/uds/transports/RDP/scripts/linux/direct.py | 13 ++++++++----- .../RDP/scripts/linux/direct.py.signature | 2 +- .../src/uds/transports/RDP/scripts/linux/tunnel.py | 10 ++++------ .../RDP/scripts/linux/tunnel.py.signature | 2 +- .../src/uds/transports/RDP/scripts/macosx/direct.py | 5 ----- .../RDP/scripts/macosx/direct.py.signature | 2 +- .../src/uds/transports/RDP/scripts/macosx/tunnel.py | 9 +-------- .../RDP/scripts/macosx/tunnel.py.signature | 2 +- 8 files changed, 17 insertions(+), 28 deletions(-) diff --git a/server/src/uds/transports/RDP/scripts/linux/direct.py b/server/src/uds/transports/RDP/scripts/linux/direct.py index 2fe6edde5..597c20f0b 100644 --- a/server/src/uds/transports/RDP/scripts/linux/direct.py +++ b/server/src/uds/transports/RDP/scripts/linux/direct.py @@ -17,7 +17,7 @@ except ImportError: logger = logging.getLogger(__name__) # For UDS Clients 4.0 -# TambiƩn asegura logger en globales +# Also ensures logger in globals globals()['logger'] = logger # Avoid type checking annoing errors @@ -42,15 +42,11 @@ def _prepare_rdp_file(theFile: str, extension: str = '.rdp') -> str: base_name = os.path.basename(filename) dest_filename = os.path.join(home_dir, base_name + extension) temp_rdp_filename = filename + extension - logger.debug(f'Renaming temp file {filename} to {temp_rdp_filename}') os.rename(filename, temp_rdp_filename) - logger.debug(f'Moving temp file {temp_rdp_filename} to {dest_filename}') shutil.move(temp_rdp_filename, dest_filename) - logger.debug(f'RDP file content (forced): {theFile}') return dest_filename def _exec_client_with_params(executable: str, params: typing.List[str], unlink_file: typing.Optional[str] = None) -> None: - logger.info(f'Executing {executable} with params: {params}') tools.addTaskToWait(subprocess.Popen(params)) if unlink_file: tools.addFileToUnlink(unlink_file) @@ -102,20 +98,27 @@ def exec_thincast(thincast: str) -> None: if os.path.isfile(thincast) and os.access(thincast, os.X_OK): executable = thincast kind = 'thincast' + logger.debug('Found Thincast executable: %s', thincast) break # If you don't find Thincast, search UDSRDP and XFREERDP if not executable: + logger.debug('Thincast not found. Searching for UDSRDP and XFREERDP.') udsrdp: typing.Optional[str] = tools.findApp('udsrdp') xfreerdp: typing.Optional[str] = tools.findApp('xfreerdp3') or tools.findApp('xfreerdp') or tools.findApp('xfreerdp2') + logger.debug('UDSRDP found: %s', udsrdp) + logger.debug('XFREERDP found: %s', xfreerdp) if udsrdp: executable = udsrdp kind = 'udsrdp' + logger.debug('Selected UDSRDP as executable.') elif xfreerdp: executable = xfreerdp kind = 'xfreerdp' + logger.debug('Selected XFREERDP as executable.') if not executable: + logger.error('No suitable RDP client found. Thincast, UDSRDP, or XFREERDP are required.') raise Exception( '''

You need to have Thincast Remote Desktop Client or xfreerdp (>= 2.0) installed on your system, and have it in your PATH in order to connect to this UDS service.

Please, install the proper package for your system.

diff --git a/server/src/uds/transports/RDP/scripts/linux/direct.py.signature b/server/src/uds/transports/RDP/scripts/linux/direct.py.signature index 3662a9236..e539364bc 100644 --- a/server/src/uds/transports/RDP/scripts/linux/direct.py.signature +++ b/server/src/uds/transports/RDP/scripts/linux/direct.py.signature @@ -1 +1 @@ -QvtwKeb/U+eyrCDzuaYDwqzgP0zSbKOo49gNPDs4h9w12D6NJsn4F8fsyaUQ7H8PQaIID+lThQGPGTKKYN0wNrhFHYx+PchgeyWOJkfvjlPDxu4JKkwmdlkvHAkfHjW7rJbzh90UkhJmRev3fX7mMAqNBUSbXEcL0/mB31iELzhMYY+RHrMrMpcIO86R0XAxNcaEnJhSW4gQuXonhRf6vrRfWbexqce9+XtftqxbOINlSgRFaFWdZu0Mtdm2kQ2FWq9XGxebha2+5PC1PRBhoxCRip2fEcTn9PzEy8gOjhm9masK8UJ/isVcfiM/ISJPbyDz3jSPV9Z+xtYkcrVQKV+GwvPuj3GCdMInxzAkUEPPNVTnqupHKfXXjAhi+sYZHO+TC0F79FiydxZmxMrJjcZbt+e1rCSDSzKdXn/WTHAuwTtwUj8cbrkrEwHrZWtQzgSGHSK/PlunZD7ASYg6QP7Dq8HRaYT1RmRmjH0tVzs/7y/HYMwdg0MI17zJcEyG7Q67PPa/RcUeSZ4eOMetnTnwPv29u9KpuAZm2P8mn+y4dMaRTC2uAARIHg77khWbVElhoO8JpVb31yHeLENvBmRxZv3Gli404cmzrH66N38xWHadZXYP6fiErptLGPdsL0sGKZRHbAZUjqppx5qwHmHWaNuBY2XOfIrlFvOr5UQ= \ No newline at end of file +CsuVtrIJIIJGSbLocIul1Q+uFlddT0bYIuFpfnEbeDbtabcn0S8lPl23/Br+L4aQi5Rua0jw2c0wo4RAZCrMNYSM8+jyIZ0oE+9Jw1CGCB+2uW2aM/Ksus9R7RHwkzqbRv24cBGQn9vQpYcldoYSN/l8JvCsbOcIVEZ1yol/P5xqQU6ED24R2fTvDJ5WXks6HS1S6HGm/pIQoUCIRK8iXJUTeOrmWJnRcAfgUqp6paMZDU9iCvFl7xkyxV7kUnbqBzN2eVujZaMnQReVopscoMdnO9ckPWL+mXBuJXnH2VmC4QvQDFVPk9j5oRPYqc22WXlcGwrMXMZOGLI9ncXNc4cSCiwiFP01twNYb8+TioxEmIPXkpP9w4fArlteCbA24sKKvU0p8UNoCG5nj4XFgnXz3O7n3wkudmnAethWC3VofT+naRXpElhWlbOrM214VQy/rr8G3Aav8MfxEE1GBqPim7K5lQwbSGnUr8AgLF+hv4gzfkUv1o5jkI3bk7ltjyMNv5BrX2JTywHbMJN3j8E7A5LRXrvClqH+fiDaeGsqbW0SthqUgklCHbtu602v2hO+FQ5SnUvWRiif7LE5HBEDIfZYuJk9t+SHrR4lWIjsJu8d4OOqwBmmII5R4tc76+/46+Re6ghRqiB9IqcXMka3u+/lAHrCTH0mWmpHyVc= \ No newline at end of file diff --git a/server/src/uds/transports/RDP/scripts/linux/tunnel.py b/server/src/uds/transports/RDP/scripts/linux/tunnel.py index 2b9b0842e..40a8a3805 100644 --- a/server/src/uds/transports/RDP/scripts/linux/tunnel.py +++ b/server/src/uds/transports/RDP/scripts/linux/tunnel.py @@ -44,22 +44,16 @@ def _prepare_rdp_file(theFile: str, port: int, extension: str = '.rdp') -> str: theFile = theFile.format( address='127.0.0.1:{}'.format(port) ) - logger.info(f'Preparing RDP file with address 127.0.0.1:{port}') - logger.debug(f'RDP file content (forced): {theFile}') filename = tools.saveTempFile(theFile) home_dir = os.path.expanduser("~") base_name = os.path.basename(filename) dest_filename = os.path.join(home_dir, base_name + extension) temp_rdp_filename = filename + extension - logger.debug(f'Renaming temp file {filename} to {temp_rdp_filename}') os.rename(filename, temp_rdp_filename) - logger.debug(f'Moving temp file {temp_rdp_filename} to {dest_filename}') shutil.move(temp_rdp_filename, dest_filename) - logger.debug(f'RDP file content (forced): {theFile}') return dest_filename def _exec_client_with_params(executable: str, params: typing.List[str], unlink_file: typing.Optional[str] = None) -> None: - logger.info(f'Executing {executable} with params: {params}') tools.addTaskToWait(subprocess.Popen(params)) if unlink_file: tools.addFileToUnlink(unlink_file) @@ -121,14 +115,18 @@ def exec_thincast(thincast: str, port: int) -> None: logger.debug('Thincast client found, using it') fnc, app = exec_thincast, thincast_executable else: + logger.debug('Thincast not found, searching for xfreerdp and udsrdp') xfreerdp: typing.Optional[str] = tools.findApp('xfreerdp3') or tools.findApp('xfreerdp') or tools.findApp('xfreerdp2') udsrdp = tools.findApp('udsrdp') fnc, app = None, None if xfreerdp: + logger.debug('xfreerdp found: %s', xfreerdp) fnc, app = exec_new_xfreerdp, xfreerdp if udsrdp: + logger.debug('udsrdp found: %s', udsrdp) fnc, app = exec_udsrdp, udsrdp if app is None or fnc is None: + logger.error('No suitable RDP client found (Thincast, xfreerdp, udsrdp)') raise Exception( '''

You need to have Thincast Remote Desktop Client o xfreerdp (>= 2.0) installed on your system, y tenerlo en tu PATH para conectar con este servicio UDS.

Please install the right package for your system.

diff --git a/server/src/uds/transports/RDP/scripts/linux/tunnel.py.signature b/server/src/uds/transports/RDP/scripts/linux/tunnel.py.signature index 6143ed235..567e3c5ef 100644 --- a/server/src/uds/transports/RDP/scripts/linux/tunnel.py.signature +++ b/server/src/uds/transports/RDP/scripts/linux/tunnel.py.signature @@ -1 +1 @@ -PwNGSn1G1RSI6m56VoamK3c3DASZhca6H9ejQ8gzX3Izny7c/JjKAd6vU9/BL7vyM9a/46UaOPDH+R9kD7j6rbtvwo/32ULDqGU9Dt+9taRyzediIdfwg/XkI5A2H7pxamXiFWAwLW24FFSBEa5/DBPSSjBwFaEeJbGm6IqSuDfJQdR4C/6uy0wbwakMUhMsY6ZcUYB7QOKa4sKF6jQorjZ+RUHkkPiEtTCZvjP56c743B0nZ5qqBlA6sOV4vUPDntG8RSwdo6ds73foz8+Q/13qlTCh5IA7E+S2HoxRuF3nPDUL6ML1wHfWLlUnAQjrmYtD59YDh1PCBVuqasHZ6Qe4ShXepSwIzJUp4bmd3gQh6U7FMfbv0T9e9gx7WYQ1LUNJtpLXM0c84cLGAO0a6sPBJZ6S6R5Pxc9OCRxwykkBIm9FEjE8+8bcDyRGiTRtw/t7HUHP4gUM06sp/wnx63COKGzk9GBb+vMcx9VHH5sAZKs3Ghs8DB/7z4C8iIsIqBxVesWYAJQlngIXwxTAw9llrFnSTDPEmB9e2HgsWejezE35s1bICF5r0L9LxxCcqna+YkGFrgAjo9to9BW3WjRMmcRqvEQmucwCEcqaVJXBw2ffvGZEozrJ6HSOCpKKd4Hz2SxWS8MaQQHYMlysPo4I6pyPXGPHT4SCGL+XoNg= \ No newline at end of file +uEvdJ3lABkcawKogomSXhPcE+pf7MCruSxn01YVm02P1OXjseKk2gq7WuhuA2oKeNKX3g7zYRLSB8xmRXDo0JfI3v0CML11RgqjvDcb1hzX5tkymO+F8bkoRU2qpFT4oV+zx52b+FH5aFSzbkGqXsIoLm5fuwl89L7CmA6/qQse+GwOuLRt1NeJvBqOEsMeSdf/oX1J3DZAmyoAuOBbtsHzgx1aznDrcU336vOHAJiAAovbYHLflY7lk+5hJix/xF8kXkn6Ejjamo3wZd+Urft0bAXZorSOICgRm+VdRqKQQG7zPVt55kmp03XKAwQTfTp4DxJSvrVZfuljPQ/zFt5IP4fMu4AKCXnYXsUuue4Df2VNad//qpvjVct6pkUwiP1PsV5QNHyMx91Va+HN7sBWSeQhHJJKTdizgOCQS2IZJ07VbpT6b0k7A+oK4DqXJA3tSYTOBwYjaRA/HYCrQDjN3GptlRSmomLhiAI4yK1gAICzIDtzFJhu0gXFYGBSVOVVnUwZnLCbWuQwRTZlYvBYigOqx/kKrXjf5pDFjzvR43uC4uHuO84GNgV0iCCIoFROQLgifLDAC4UIdf2Eo20FqT4JjG9DU5r53O4n2RwiwnAPulSOGGevqykOkbHTSFtj0LaCerHDllDMph+mUw6clyN2D6zCxmwb3WnEa7/I= \ No newline at end of file diff --git a/server/src/uds/transports/RDP/scripts/macosx/direct.py b/server/src/uds/transports/RDP/scripts/macosx/direct.py index 178befcd1..bbe2f6aaa 100644 --- a/server/src/uds/transports/RDP/scripts/macosx/direct.py +++ b/server/src/uds/transports/RDP/scripts/macosx/direct.py @@ -146,7 +146,6 @@ def fix_resolution() -> typing.List[str]: if kind == 'thincast': if sp['as_file']: # type: ignore - logger.debug('Opening Thincast with RDP file %s', sp['as_file']) # type: ignore theFile = sp['as_file'] # type: ignore filename = tools.saveTempFile(theFile) # type: ignore @@ -186,12 +185,9 @@ def fix_resolution() -> typing.List[str]: if sp.get('password', ''): # type: ignore params.append('--args') # type: ignore params.append('/p:{}'.format(sp['password'])) # type: ignore - else: - logger.debug('No password provided for Thincast RDP file') params.append(filename + '.rdp') # type: ignore - # logger.debug('Opening Thincast with RDP file with params: %s', ' '.join(params)) # type: ignore tools.addTaskToWait( # type: ignore subprocess.Popen(params) # type: ignore ) @@ -225,5 +221,4 @@ def fix_resolution() -> typing.List[str]: xfparms = list(map(lambda x: x.replace('#WIDTH#', '1400').replace('#HEIGHT#', '800'), sp['as_new_xfreerdp_params'])) # type: ignore params = [os.path.expandvars(i) for i in [executable] + xfparms + ['/v:{}'.format(sp['address'])]] # type: ignore - logger.debug('Executing: %s', ' '.join(params)) # type: ignore subprocess.Popen(params) # type: ignore diff --git a/server/src/uds/transports/RDP/scripts/macosx/direct.py.signature b/server/src/uds/transports/RDP/scripts/macosx/direct.py.signature index ff084df1f..3068b0a24 100644 --- a/server/src/uds/transports/RDP/scripts/macosx/direct.py.signature +++ b/server/src/uds/transports/RDP/scripts/macosx/direct.py.signature @@ -1 +1 @@ -s37W+aeOwsd7FJGBWiP+7h1L16108PhPWYTuEFq5pn3EtN9hBp1yD/Yrnz0HB1WNCS5URA3ev+fx2ojLHFdR4dABUmXMB0+yBKnql/5FoAgme5DsmEsZzV8BE1Z1BhluC6E9WiJSdIRDPkEmITyRB0H7d9n11tzRzCxX5/o2m2Bx4dYBdjfsE2NeMwk+MXw5/Y4MZfoVgCnCpmMBKB0MzGRBkFeqYaGpsf9ow9cM4pwb22J2w095KHCebCMojKO5+sD8rrQuL+coDPw+anb9a/RRPMI2oZsKrZJiYeoZY57cuO2uJIg/eeBYy1TttdHFK/kqi6ngs8bNXI79qTWdTkfKtC3aUCmd55XiZx/PbgOliVmF9jiT377AGGrSI/A2uW+8yuc/eOl0ALEtnKxQgFPHbY1FXSsvAiybsadQPStncAWc/c8rt4ficqQZdF3yfhN6Jp4npw/4Ge1GEXrJOkXDu/EtBLSi7lolqt0iNWNKHXjqwZTWaRJ6NuWnR8goTgR0CAfVLfom/+7E1iDf7JpIhnAwIIIPbGh41pd2SpL7ysy0vjQhhwjCmnW8HGJ1oF0qAf3LZy0LVV9r61pCEFNCQBDtHNvZLr3lwX7x614lifm+ZkNAY56ishUmYT8jNpcBIloAEfkbRQO3Pju4EhHL8Ch5gnUOmQ+S9D04P8o= \ No newline at end of file +gw1uAbG83EPUvALrY/DhDL9dy7xn0HvkfkpAvTDXScOFWwkkq86yQuEySal833G2mQgSS1sVcTJkx2k1Sp9d/zIM5VkeEOIRl5L0/Ca4qkSN9aKV1tuD+B8f5Vu/+Tc75myrzGn9RZ8WQovaUgfJ4Y/STy9eOKTCjwa1i1ZEd77uSBqfoDl7IghYq5FgG/wg/AKk5EV7CHRbTDV9vlCZDKfsdnaKnWuiPc9LGpTH3iIbeOpSYlVc3xb3fU0tokkgN7CYz+I4lz1rnbGrWdlnnNueVPodA431hmnOiqSdmh9ocITZY7sNtjRaA4qS555TJPrrSwF8vYerXJFzVN8539+sHqa+SE+XwUPDjZrpQZXFm3rZgAo4wuKYytAxvC0+UukVVxpq32xKdNU0D3LsO3IcJKCnKi3H6zlDDHTuZRgItGnJbKY68pMQoAv1Vw5ORZCKdjaYcPduRBGb5BTSqEk0Aa26IA5LpsD1lKxnLx+szROIRvaeR1u1McBkuPPwTHkTRDxYrcgr5Y+mCRjxiXJvZZg7WSFmdSHqwnh5/Cq+8Y06QzdgKhKgQFYflngXiw6OswqXB8hnjs8L+YdWMsOyRyFVKZ/JRoGDrCbMFE5TQUua3NaadfF3kQZT0nUW1X5I6q3ellRGhbx55GdmFN/DjtfiEc7AYJnLirMYyOU= \ No newline at end of file diff --git a/server/src/uds/transports/RDP/scripts/macosx/tunnel.py b/server/src/uds/transports/RDP/scripts/macosx/tunnel.py index 03196b25e..e0236ece0 100644 --- a/server/src/uds/transports/RDP/scripts/macosx/tunnel.py +++ b/server/src/uds/transports/RDP/scripts/macosx/tunnel.py @@ -163,7 +163,6 @@ def fix_resolution() -> typing.List[str]: if kind == 'thincast': if sp['as_file']: # type: ignore - logger.debug('Opening Thincast with RDP file %s', sp['as_file']) # type: ignore theFile = sp['as_file'] # type: ignore theFile = theFile.format( # type: ignore address='{}'.format(address) @@ -177,9 +176,7 @@ def fix_resolution() -> typing.List[str]: # Rename as .rdp, so open recognizes it shutil.move(filename, filename + '.rdp') # type: ignore - # show filename content in log for debug - with open(filename + '.rdp', 'r') as f: # type: ignore - logger.debug('RDP file content:\n%s', f.read()) # type: ignore + params = [ # type: ignore 'open', '-a', @@ -189,12 +186,9 @@ def fix_resolution() -> typing.List[str]: if sp.get('password', ''): # type: ignore params.append('--args') # type: ignore params.append('/p:{}'.format(sp['password'])) # type: ignore - else: - logger.debug('No password provided for Thincast RDP file') params.append(filename + '.rdp') # type: ignore - #logger.debug('Opening Thincast with RDP file with params: %s', ' '.join(params)) # type: ignore tools.addTaskToWait( # type: ignore subprocess.Popen(params) # type: ignore ) @@ -213,7 +207,6 @@ def fix_resolution() -> typing.List[str]: executable, '--args', ] + [os.path.expandvars(i) for i in xfparms + ['/v:{}'.format(address)]] # type: ignore - #logger.debug('Executing: %s', ' '.join(params)) subprocess.Popen(params) # type: ignore else: # freerdp or udsrdp # Fix resolution... diff --git a/server/src/uds/transports/RDP/scripts/macosx/tunnel.py.signature b/server/src/uds/transports/RDP/scripts/macosx/tunnel.py.signature index 25f7aa15d..42f4c5457 100644 --- a/server/src/uds/transports/RDP/scripts/macosx/tunnel.py.signature +++ b/server/src/uds/transports/RDP/scripts/macosx/tunnel.py.signature @@ -1 +1 @@ -hFkzy2kQewVgPgamVcsimwQxyaVESVj9qZsZWUNLcXX8tjaSGpacSB24ZxC8EaICbIz0NBGu7x/6wVIIQCCcOcIdAyzS8I6kTZZMPMisPT1dI8SOkq/NgqHwXwFxGxE/LMW6V7F1yPZK55o1z94nqz3unGmFv9FD25SXYqZedSdOLiHuWoUwkb84mqbR8qbTnFlsghBBKuhnWC0eAuoSatgpaNceR7scQ5yB3NzXdGnU8CMWU5IpJ4E96mhAugHEIioxXAunOmBLvsvWPEjGc9RLQPli9nX2yX2UpIvVeIRtYh1KAG1DQF0M00L76RBJOEvfkgziSkQMelRiC+CxpnrOY3TXZNQwObwMZy+7n2a4pQdOq+YCHFOReGmCZaswtupYL+so2pnI9D5ZBztFt/ORaPn8G+krV94HFAOTMY/7MTJLYtZabKyUdaneLxApKjCBYvP2qilhpEwJINuO1RvOJqYh/++M59hkiu0FQHuvU68s7t9Flj9l5eNb6wEpC0imslaKYisHPwjLlNpVSchixvIouyiw5XUFeRRU545I6wYiFKDC9Vx84o20iVQ94KF97Xm+Eze++M2f9/qFUS5dACQUIqBTpZe9EF3UGc3tMBf3td/k3J8sP3p+eVKMBird0h1cr9kCDjYPv7BXGDdusszAOucR2ew7RVSdKnc= \ No newline at end of file +mU3j2K4iUFRPjJRErH6D480ZgWrf1TQP3OWL6sBQhkP1jXfUFwjeWUsXh3oIREur/9jy2xm8EzLoxOZt/OwhL7pIO7fJqOMQzqTfw2Gwwyu+naMNTys181rThpJqz8sEeW+Fos1wGuDxg0TDYp8CZTFKdCQyW/CqB5emOn2YQf0bJG/c4yrlDRBJmSXhH4+6Cr7hexAi8bGR4gD2dAEd8GpchlsqIX+2AALYQNho0Owl7z2AwpIf0epy/QNvMuOLpFMAEmUxGWVz0FsJBasXKZNgEbhmty5fVECGTHgK9Xd6ie4QSDgUHMFzD1NLGcWEihM04/vLorpkztFmsM2QGo8E/+cwE7P65urGu+M9xSZe0byJlHWNPe7Hf86kPv1eZBBoh8xrv13Mj0jB0vtv0VBMidOsUmjMdlFvYzuf6U/IVSAWiC23kWkO2dEjseYhWYG4p6NJnlmjEQfYljqBZXDRaLwF/b/biJdqj9Jc7glJQ+MpoGYjnqI+2wsQefME/mhRnq4DCDilWCEp13Mwl6MYVhYlC5A3yfLaRoIe8/2ZB727gtH79VybWAaMsod8f3OFThuxLWucYlCVjLgJnLUd4z1/pnrh4dxKZML1aivLh3p3F4QalxL0IKFOmxOS39qZZchpoNv2JHrJw187AAG6fzoUeIeoc2hHlo7BFyA= \ No newline at end of file