Applied patch files

This commit is contained in:
Your Name 2025-05-16 23:20:04 +01:00
parent ff6826b0d9
commit 2b52907e05
240 changed files with 201 additions and 250 deletions

View file

@ -1,6 +1,6 @@
from PyQt6.QtWidgets import QComboBox,QButtonGroup, QLineEdit,QMainWindow, QLabel, QWidget, QVBoxLayout, QStackedWidget, QApplication, QPushButton, QTextEdit, QFrame, QHBoxLayout, QVBoxLayout, QScrollArea, QSystemTrayIcon, QMessageBox, QGridLayout, QCheckBox, QStackedLayout, QGroupBox, QDialog
from PyQt6.QtGui import QIcon, QPixmap,QIcon, QPixmap, QTransform, QPainter, QColor, QFont, QFontDatabase
from PyQt6 import QtGui
from PyQt6 import QtGui
from PyQt6 import QtCore
from PyQt6.QtCore import Qt,QSize,QThread,pyqtSignal, QTimer, QPointF, QRect, QMutex, QMutexLocker, QObject
import os
@ -9,7 +9,7 @@ import functools
import threading
import logging
import traceback
import random
import random
import subprocess
from typing import Union
from core.Errors import UnknownConnectionTypeError, CommandNotFoundError, MissingSubscriptionError, InvalidSubscriptionError, ProfileActivationError, UnsupportedApplicationVersionError, FileIntegrityError, ProfileModificationError, ProfileStateConflictError
@ -35,6 +35,7 @@ from datetime import datetime, timezone, timedelta
from core.Constants import Constants
import atexit
import json
import shlex
@ -119,7 +120,7 @@ class WorkerThread(QThread):
self.text_output.emit("Checking for updates...")
ClientController.sync(client_observer=client_observer, connection_observer=connection_observer)
update_available = ClientController.can_be_updated()
if update_available:
if update_available:
self.text_output.emit("An update is available. Downloading...")
self.finished.emit(True)
else:
@ -130,7 +131,7 @@ class WorkerThread(QThread):
def install_package(self):
try:
self.text_output.emit(f"Installing {self.package_name}...")
subprocess.run(self.package_command.split(), check=True)
subprocess.run(shlex.split(self.package_command), check=True)
self.text_output.emit(f"{self.package_name} installed!")
self.finished.emit(True)
except subprocess.CalledProcessError:
@ -227,7 +228,7 @@ class WorkerThread(QThread):
ConfigurationController.set_connection('tor')
else:
ConfigurationController.set_connection('system')
ClientController.sync(client_observer=client_observer, connection_observer=connection_observer)
self.check_for_update()
locations = LocationController.get_all()
all_location_codes = [f"{location.country_code}_{location.code}" for location in locations]
self.sync_output.emit(all_location_codes, True, False, locations, False)
@ -317,12 +318,15 @@ class CustomWindow(QMainWindow):
self.setAttribute(Qt.WidgetAttribute.WA_TranslucentBackground)
self.setAttribute(Qt.WidgetAttribute.WA_NoSystemBackground)
self.setWindowTitle("HydraVeil VPN")
self.setWindowTitle('HydraVeil')
self._data = {"Profile_1": {}}
self.gui_dir = os.path.join(Constants.HV_DATA_HOME, "gui")
self.gui_config_file = os.path.join(self.gui_dir, "config.json")
self.gui_log_file = os.path.join(self.gui_dir, "gui.log")
self.gui_config_home = os.path.join(Constants.HV_CONFIG_HOME, 'gui')
self.gui_config_file = os.path.join(self.gui_config_home, 'config.json')
self.gui_cache_home = os.path.join(Constants.HV_CACHE_HOME, 'gui')
self.gui_log_file = os.path.join(self.gui_cache_home, 'gui.log')
self._setup_gui_directory()
current_dir = os.path.dirname(os.path.abspath(__file__))
@ -330,10 +334,8 @@ class CustomWindow(QMainWindow):
self.btn_path = os.getenv('BTN_PATH', os.path.join(current_dir, 'resources', 'images'))
self.css_path = os.getenv('CSS_PATH', os.path.join(current_dir, 'resources', 'styles'))
icon_base = os.getenv('SYSTEM_TRAY_ICON', '')
self.tray = None
self.init_system_tray(icon_base)
self.init_system_tray(self.btn_path)
self.is_downloading = False
self.current_profile_id = None
@ -351,6 +353,12 @@ class CustomWindow(QMainWindow):
profile_observer.subscribe('created', lambda event: self.update_status('Profile Created'))
profile_observer.subscribe('destroyed', lambda event: self.update_status('Profile destroyed'))
client_observer.subscribe('synchronizing', lambda event: self.update_status('Sync in progress...'))
client_observer.subscribe('synchronized', lambda event: self.update_status('Sync complete'))
client_observer.subscribe('updating', lambda event: self.update_status('Updating client...'))
client_observer.subscribe('update_progressing', lambda event: self.update_status(f'Current progress: {event.meta.get('progress'):.2f}%'))
client_observer.subscribe('updated', lambda event: self.update_status('Restart client to apply update.'))
application_version_observer.subscribe('downloading', lambda event: self.update_status(f'Downloading {ApplicationController.get(event.subject.application_code).name}'))
application_version_observer.subscribe('download_progressing', lambda event: self.update_status(f'Downloading {ApplicationController.get(event.subject.application_code).name} {event.meta.get('progress'):.2f}%'))
@ -389,7 +397,7 @@ class CustomWindow(QMainWindow):
self.scroll_speed = 1
self.tor_text = QLabel("Billing & Browsers", self)
self.tor_text.setGeometry(515, 542, 150, 20)
self.tor_text.setGeometry(532, 541, 150, 20)
self.tor_text.setStyleSheet("""
QLabel {
color: cyan;
@ -401,31 +409,56 @@ class CustomWindow(QMainWindow):
self.set_scroll_speed(7)
self.tor_icon = QLabel(self)
self.tor_icon.setGeometry(705, 537, 25, 25)
self.set_tor_icon()
self.toggle_button = QPushButton(self)
self.toggle_button.setGeometry(645, 541, 50, 22)
self.toggle_button.setGeometry(670, 541, 50, 22)
self.toggle_button.setCheckable(True)
self.toggle_button.clicked.connect(self.toggle_mode)
self.tor_icon = QLabel(self)
self.tor_icon.setGeometry(730, 537, 25, 25)
self.set_tor_icon()
self.create_toggle(self.is_tor_mode)
self.animation_timer = QTimer()
self.animation_timer.timeout.connect(self.animate_toggle)
self.check_logging()
self.sync_button = QPushButton(self)
self.sync_button.setGeometry(771, 541, 22, 22)
self.sync_button.setObjectName('sync_button')
if CustomWindow.should_be_synchronized():
sync_icon = QtGui.QIcon(os.path.join(self.btn_path, 'icon_sync_urgent.png'))
else:
sync_icon = QtGui.QIcon(os.path.join(self.btn_path, 'icon_sync.png'))
self.sync_button.setToolTip('Sync')
self.sync_button.setIcon(sync_icon)
self.sync_button.setIconSize(self.sync_button.size())
self.sync_button.clicked.connect(self.sync)
self.init_ui()
current_connection = self.get_current_connection()
self.is_tor_mode = current_connection == 'tor'
self.set_toggle_state(self.is_tor_mode)
def perform_update_check(self):
update_available = ClientController.can_be_updated()
if update_available:
menu_page = self.page_stack.findChild(MenuPage)
menu_page.on_update_check_finished()
def sync(self):
if ConfigurationController.get_connection() == 'tor':
self.worker_thread = WorkerThread('SYNC_TOR')
else:
self.worker_thread = WorkerThread('SYNC')
self.sync_button.setIcon(QtGui.QIcon(os.path.join(self.btn_path, 'icon_sync.png')))
self.worker_thread.finished.connect(lambda: self.perform_update_check())
self.worker_thread.start()
def _handle_exception(self, identifier, message, trace):
if issubclass(identifier, UnknownConnectionTypeError):
@ -515,7 +548,8 @@ class CustomWindow(QMainWindow):
return ConfigurationController.get_connection()
def _setup_gui_directory(self):
os.makedirs(self.gui_dir, exist_ok=True)
os.makedirs(self.gui_cache_home, exist_ok=True)
os.makedirs(self.gui_config_home, exist_ok=True)
if not os.path.exists(self.gui_config_file):
default_config = {
@ -562,7 +596,7 @@ class CustomWindow(QMainWindow):
def _setup_gui_logging(self):
os.makedirs(self.gui_dir, exist_ok=True)
os.makedirs(self.gui_cache_home, exist_ok=True)
formatter = logging.Formatter(
'%(asctime)s - %(levelname)s - %(message)s',
@ -734,24 +768,25 @@ class CustomWindow(QMainWindow):
def init_system_tray(self, icon_base):
def init_system_tray(self, icon_base_path):
if QSystemTrayIcon.isSystemTrayAvailable():
tray_icon = QIcon()
window_icon = QIcon()
tray_sizes = [22, 24]
for size in tray_sizes:
icon_path = os.path.join(icon_base, f"{size}x{size}/apps/simplified-privacy.png")
icon_path = os.path.join(icon_base_path, f"hv-icon-{size}x{size}.png")
if os.path.exists(icon_path):
tray_icon.addFile(icon_path, QSize(size, size))
window_sizes = [32, 48, 64, 128]
for size in window_sizes:
icon_path = os.path.join(icon_base, f"{size}x{size}/apps/simplified-privacy.png")
icon_path = os.path.join(icon_base_path, f"hv-icon-{size}x{size}.png")
if os.path.exists(icon_path):
window_icon.addFile(icon_path, QSize(size, size))
self.tray = QSystemTrayIcon(self)
self.tray.setToolTip('HydraVeil')
self.tray.setIcon(tray_icon)
self.tray.setVisible(True)
self.setWindowIcon(window_icon)
@ -828,13 +863,13 @@ class CustomWindow(QMainWindow):
self.editor_page = EditorPage(self.page_stack, self)
self.pages = [MenuPage(self.page_stack, self),
ProtocolPage(self.page_stack, self),
WireGuardPage(self.page_stack, self),
HidetorPage(self.page_stack, self),
LocationPage(self.page_stack, self),
BrowserPage(self.page_stack, self),
ScreenPage(self.page_stack, self),
ResumePage(self.page_stack, self),
WireGuardPage(self.page_stack, self),
ResidentialPage(self.page_stack, self),
HidetorPage(self.page_stack, self),
InstallSystemPackage(self.page_stack, self),
WelcomePage(self.page_stack, self),
PaymentPage(self.page_stack, self),
@ -878,8 +913,8 @@ class CustomWindow(QMainWindow):
self.disable_marquee()
def check_first_launch(self):
config_file = os.path.join(self.gui_dir, "first_launch.txt")
config_file = os.path.join(self.gui_config_home, '.first-run')
os.makedirs(Constants.HV_CONFIG_HOME, exist_ok=True)
is_first_launch = not os.path.exists(config_file)
@ -936,7 +971,23 @@ class CustomWindow(QMainWindow):
def set_scroll_speed(self, speed):
self.scroll_speed = speed
@staticmethod
def should_be_synchronized():
current_datetime = datetime.today().astimezone(timezone.utc)
last_synced_at = ConfigurationController.get_last_synced_at()
return last_synced_at is None or (current_datetime - last_synced_at) >= timedelta(days=30)
def page_changed(self, index):
if CustomWindow.should_be_synchronized():
sync_icon = QtGui.QIcon(os.path.join(self.btn_path, 'icon_sync_urgent.png'))
else:
sync_icon = QtGui.QIcon(os.path.join(self.btn_path, 'icon_sync.png'))
self.sync_button.setIcon(sync_icon)
current_page = self.page_stack.widget(index)
if self.page_history:
previous_page = self.page_history[-1]
@ -958,15 +1009,17 @@ class CustomWindow(QMainWindow):
elif isinstance(current_page, LocationPage):
self.update_status(None, clear=True)
elif isinstance(current_page, InstallSystemPackage):
self.update_status("Required tools are not installed. Please install them.")
self.update_status('Please check package availability.')
else:
self.update_status(None)
if isinstance(current_page, MenuPage):
self.sync_button.setVisible(True)
self.tor_text.setVisible(True)
self.toggle_button.setGeometry(645, 541, 50, 22)
self.tor_icon.setGeometry(705, 537, 25, 25)
self.toggle_button.setGeometry(670, 541, 50, 22)
self.tor_icon.setGeometry(730, 537, 25, 25)
else:
self.sync_button.setVisible(False)
self.tor_text.setVisible(False)
self.toggle_button.setGeometry(540, 541, 50, 22)
self.tor_icon.setGeometry(600, 537, 25, 25)
@ -1104,7 +1157,7 @@ class Worker(QObject):
except ProfileStateConflictError:
self.update_signal.emit("The profile is already being enabled...", False, None, None, None)
except CommandNotFoundError as e :
self.update_signal.emit(str(e), False, -1, None, None)
self.update_signal.emit(str(e.subject), False, -1, None, None)
except Exception as e:
print(e)
self.update_signal.emit("An unknown error occurred", False, None, None, None)
@ -1198,7 +1251,7 @@ class MenuPage(Page):
self.worker = WorkerThread('DOWNLOAD_UPDATE')
self.worker.start()
else:
self.update_status.update_status("Update cancelled by user.")
self.update_status.update_status('Update canceled')
@ -1328,6 +1381,9 @@ class MenuPage(Page):
return new_dict
def create(self):
self.boton_just.setEnabled(False)
self.boton_just_session.setEnabled(False)
self.boton_edit.setEnabled(False)
self.profiles_data = self.match_core_profiles(ProfileController.get_all())
self.number_of_profiles = len(self.profiles_data)
self.profile_info.update(self.profiles_data)
@ -1933,7 +1989,7 @@ class ConnectionManager:
def get_is_profile_being_enabled(self, profile_id: int) -> bool:
return self._is_profile_being_enabled.get(profile_id, False)
class InstallSystemPackage(Page):
def __init__(self, page_stack, main_window=None, parent=None):
super().__init__("InstallPackage", page_stack, main_window, parent)
@ -1953,110 +2009,104 @@ class InstallSystemPackage(Page):
self.auto_install_package_commands = {
'all': {
'debian': 'pkexec apt install -y bubblewrap iproute2 microsocks proxychains4 ratpoison tor wireguard xserver-xephyr resolvconf',
'arch': 'pkexec pacman -S bubblewrap iproute2 microsocks proxychains-ng tor wireguard-tools xorg-server-xephyr resolvconf',
'fedora': 'pkexec dnf -y install bubblewrap iproute-doc proxychains4 ratpoison tor wireguard xorg-x11-server-Xephyr resolvconf'
'debian': 'pkexec apt install -y bubblewrap iproute2 microsocks proxychains4 ratpoison tor wireguard xserver-xephyr',
'arch': 'pkexec pacman -S bubblewrap iproute2 microsocks proxychains-ng tor wireguard-tools xorg-server-xephyr',
'fedora': 'pkexec dnf -y install bubblewrap iproute proxychains4 ratpoison tor wireguard-tools xorg-x11-server-Xephyr'
},
'wireguard': {
'debian': 'pkexec apt -y install wireguard resolvconf',
'arch': 'pkexec pacman -S wireguard-tools resolvconf',
'fedora': 'pkexec dnf -y install wireguard-tools resolvconf'
'bwrap': {
'debian': 'pkexec apt -y install bubblewrap',
'arch': 'pkexec pacman -S bubblewrap',
'fedora': 'pkexec dnf -y install bubblewrap'
},
'resolvconf': {
'debian': 'pkexec apt -y install resolvconf',
'arch': 'pkexec pacman -S resolvconf',
'fedora': 'pkexec dnf -y install resolvconf'
},
'tor': {
'debian': 'pkexec apt -y install tor proxychains4 microsocks',
'arch': 'pkexec pacman -S tor proxychains4 microsocks',
'fedora': 'pkexec dnf -y install tor proxychains4'
},
'tor_sync': {
'debian': 'pkexec apt -y install tor',
'arch': 'pkexec pacman -S tor',
'fedora': 'pkexec dnf -y install tor'
},
'proxychains4': {
'debian': 'pkexec apt -y install proxychains4',
'arch': 'pkexec pacman -S proxychains-ng',
'fedora': 'pkexec dnf -y install proxychains4'
'ip': {
'debian': 'pkexec apt -y install iproute2',
'arch': 'pkexec pacman -S iproute2',
'fedora': 'pkexec dnf -y install iproute'
},
'microsocks': {
'debian': 'pkexec apt -y install microsocks',
'arch': 'pkexec pacman -S microsocks',
'fedora': 'pkexec dnf -y install microsocks'
'fedora': 'zenity --warning --text="An essential dependency (microsocks) is not included in your distribution\'s default repository. Please build it from source or contact support."'
},
'xserver-xephyr': {
'debian': 'pkexec apt -y install xserver-xephyr bubblewrap ratpoison',
'arch': 'pkexec pacman -S xorg-server-xephyr bubblewrap ratpoison',
'fedora': 'pkexec dnf -y install xorg-x11-server-Xephyr bubblewrap ratpoison'
'proxychains4': {
'debian': 'pkexec apt -y install proxychains4',
'arch': 'pkexec pacman -S proxychains-ng',
'fedora': 'pkexec dnf -y install proxychains4'
},
'bubblewrap': {
'debian': 'pkexec apt -y install bubblewrap',
'arch': 'pkexec pacman -S bubblewrap',
'fedora': 'pkexec dnf -y install bubblewrap'
'ratpoison': {
'debian': 'pkexec apt -y install ratpoison',
'arch': 'zenity --warning --text="An essential dependency (ratpoison) is not included in your distribution\'s default repository. Please build it from source or contact support."',
'fedora': 'pkexec dnf -y install ratpoison'
},
'tor': {
'debian': 'pkexec apt -y install tor',
'arch': 'pkexec pacman -S tor',
'fedora': 'pkexec dnf -y install tor'
},
'wg-quick': {
'debian': 'pkexec apt -y install wireguard',
'arch': 'pkexec pacman -S wireguard-tools',
'fedora': 'pkexec dnf -y install wireguard-tools'
},
'Xephyr': {
'debian': 'pkexec apt -y install xserver-xephyr',
'arch': 'pkexec pacman -S xorg-server-xephyr',
'fedora': 'pkexec dnf -y install xorg-x11-server-Xephyr'
}
}
self.manual_install_package_commands = {
'all': {
'debian': 'sudo apt install -y bubblewrap iproute2 microsocks proxychains4 ratpoison tor wireguard xserver-xephyr resolvconf',
'arch': 'sudo pacman -S bubblewrap iproute2 microsocks proxychains-ng tor wireguard-tools xorg-server-xephyr resolvconf',
'fedora': 'sudo dnf -y install bubblewrap iproute-doc proxychains4 ratpoison tor wireguard xorg-x11-server-Xephyr resolvconf'
'debian': 'sudo apt install -y bubblewrap iproute2 microsocks proxychains4 ratpoison tor wireguard xserver-xephyr',
'arch': 'sudo pacman -S bubblewrap iproute2 microsocks proxychains-ng tor wireguard-tools xorg-server-xephyr',
'fedora': 'sudo dnf -y install bubblewrap iproute proxychains4 ratpoison tor wireguard-tools xorg-x11-server-Xephyr'
},
'polkit': {
'debian': 'sudo apt -y install policykit-1',
'arch': 'sudo pacman -S polkit',
'fedora': 'sudo dnf -y install polkit'
'bwrap': {
'debian': 'sudo apt -y install bubblewrap',
'arch': 'sudo pacman -S bubblewrap',
'fedora': 'sudo dnf -y install bubblewrap'
},
'wireguard': {
'debian': 'sudo apt -y install wireguard resolvconf',
'arch': 'sudo pacman -S wireguard-tools resolvconf',
'fedora': 'sudo dnf -y install wireguard-tools resolvconf'
},
'resolvconf': {
'debian': 'sudo apt -y install resolvconf',
'arch': 'sudo pacman -S resolvconf',
'fedora': 'sudo dnf -y install resolvconf'
},
'tor': {
'debian': 'sudo apt -y install tor proxychains4 microsocks',
'arch': 'sudo pacman -S tor proxychains-ng microsocks',
'fedora': 'sudo dnf -y install tor proxychains4'
},
'tor_sync': {
'debian': 'sudo apt -y install tor',
'arch': 'sudo pacman -S tor',
'fedora': 'sudo dnf -y install tor'
},
'proxychains4': {
'debian': 'sudo apt -y install proxychains4',
'arch': 'sudo pacman -S proxychains-ng',
'fedora': 'sudo dnf -y install proxychains4'
'ip': {
'debian': 'sudo apt -y install iproute2',
'arch': 'sudo pacman -S iproute2',
'fedora': 'sudo dnf -y install iproute'
},
'microsocks': {
'debian': 'sudo apt -y install microsocks',
'arch': 'sudo pacman -S microsocks',
'fedora': 'sudo dnf -y install microsocks'
'fedora': '# Package not available.'
},
'xserver-xephyr': {
'debian': 'sudo apt -y install xserver-xephyr bubblewrap ratpoison',
'arch': 'sudo pacman -S xorg-server-xephyr bubblewrap ratpoison',
'fedora': 'sudo dnf -y install xorg-x11-server-Xephyr bubblewrap ratpoison'
'proxychains4': {
'debian': 'sudo apt -y install proxychains4',
'arch': 'sudo pacman -S proxychains-ng',
'fedora': 'sudo dnf -y install proxychains4'
},
'bubblewrap': {
'debian': 'sudo apt -y install bubblewrap',
'arch': 'sudo pacman -S bubblewrap',
'fedora': 'sudo dnf -y install bubblewrap'
'ratpoison': {
'debian': 'sudo apt -y install ratpoison',
'arch': '# Package not available.',
'fedora': 'sudo dnf -y install ratpoison'
},
'tor': {
'debian': 'sudo apt -y install tor',
'arch': 'sudo pacman -S tor',
'fedora': 'sudo dnf -y install tor'
},
'wg-quick': {
'debian': 'sudo apt -y install wireguard',
'arch': 'sudo pacman -S wireguard-tools',
'fedora': 'sudo dnf -y install wireguard-tools'
},
'Xephyr': {
'debian': 'sudo apt -y install xserver-xephyr',
'arch': 'sudo pacman -S xorg-server-xephyr',
'fedora': 'sudo dnf -y install xorg-x11-server-Xephyr'
}
}
def _setup_permanent_ui(self):
self.title.setGeometry(20, 50, 300, 60)
self.title.setText("Package Installation")
self.title.setStyleSheet("font-size: 24px; font-weight: bold;")
self.title.setStyleSheet("font-size: 22px; font-weight: bold;")
self.permanent_elements.append(self.title)
self.display.setGeometry(QtCore.QRect(100, 160, 580, 435))
@ -2147,6 +2197,7 @@ class InstallSystemPackage(Page):
self.ui_elements.append(auto_install_label)
auto_install_desc = QLabel("Click the button below to automatically install the missing packages:", self)
auto_install_desc.setStyleSheet("font-size: 14px; font-weight: bold;")
auto_install_desc.setGeometry(80, 170, 650, 30)
auto_install_desc.setVisible(True)
self.ui_elements.append(auto_install_desc)
@ -2182,6 +2233,7 @@ class InstallSystemPackage(Page):
self.ui_elements.append(manual_install_label)
manual_install_desc = QLabel("Run this command in your terminal:", self)
manual_install_desc.setStyleSheet("font-size: 14px; font-weight: bold;")
manual_install_desc.setGeometry(80, 330, 380, 30)
manual_install_desc.setVisible(True)
@ -2368,7 +2420,7 @@ class InstallSystemPackage(Page):
def check_package(self):
try:
if self.package_name.lower() == 'all':
packages = ['bwrap', 'ip', 'microsocks', 'proxychains4', 'ratpoison', 'tor', 'Xephyr', 'wg', 'resolvconf']
packages = ['bwrap', 'ip', 'microsocks', 'proxychains4', 'ratpoison', 'tor', 'Xephyr', 'wg']
for package in packages:
if subprocess.getstatusoutput(f'{package} --help')[0] == 127:
self.status_label.setText(f"{package} is not installed")
@ -2397,120 +2449,6 @@ class InstallSystemPackage(Page):
def go_next(self):
self.page_stack.setCurrentIndex(self.page_stack.indexOf(self.page_stack.findChild(MenuPage)))
class WelcomePage(Page):
def __init__(self, page_stack, main_window=None, parent=None):
super().__init__("Welcome", page_stack, main_window, parent)
self.btn_path = main_window.btn_path
self.update_status = main_window
self.ui_elements = []
self.button_next.clicked.connect(self.go_to_install)
self.button_next.setVisible(True)
self._setup_welcome_ui()
self._setup_stats_display()
def _setup_welcome_ui(self):
welcome_title = QLabel("Welcome to HydraVeilVPN", self)
welcome_title.setGeometry(20, 45, 760, 60)
welcome_title.setStyleSheet("""
font-size: 32px;
font-weight: bold;
color: cyan;
""")
welcome_title.setAlignment(Qt.AlignmentFlag.AlignCenter)
welcome_msg = QLabel(
"Before we begin your journey, we need to set up a few essential components. "
"Click 'Next' to take you to the installation page.", self)
welcome_msg.setGeometry(40, 100, 720, 80)
welcome_msg.setWordWrap(True)
welcome_msg.setStyleSheet("""
font-size: 16px;
color: cyan;
""")
welcome_msg.setAlignment(Qt.AlignmentFlag.AlignCenter)
def _setup_stats_display(self):
stats_container = QWidget(self)
stats_container.setGeometry(70, 200, 730, 240)
stats_title = QLabel(stats_container)
stats_title.setText("Features & Services")
stats_title.setGeometry(190, 10, 300, 30)
stats_title.setStyleSheet("""
font-size: 22px;
font-weight: bold;
color: cyan;
""")
grid_widget = QWidget(stats_container)
grid_widget.setGeometry(0, 70, 700, 190)
grid_layout = QGridLayout(grid_widget)
grid_layout.setSpacing(30)
stats = [
("Browsers", "browsers_mini.png", "10 Supported Browsers", True),
("WireGuard", "wireguard_mini.png", "6 Global Locations", True),
("Proxy", "just proxy_mini.png", "5 Proxy Locations", True),
("Tor", "toricon_mini.png", "Tor Network Access", True)
]
for i, (title, icon_name, count, available) in enumerate(stats):
row = i // 2
col = i % 2
stat_widget = QWidget()
stat_layout = QHBoxLayout(stat_widget)
stat_layout.setContentsMargins(20, 10, 2, 10)
stat_layout.setSpacing(15)
icon_label = QLabel()
icon_path = os.path.join(self.btn_path, icon_name)
icon_label.setPixmap(QPixmap(icon_path).scaled(30, 30, Qt.AspectRatioMode.KeepAspectRatio, Qt.TransformationMode.SmoothTransformation))
icon_label.setFixedSize(30, 30)
stat_layout.addWidget(icon_label)
text_widget = QWidget()
text_layout = QVBoxLayout(text_widget)
text_layout.setSpacing(5)
text_layout.setContentsMargins(0, 0, 30, 0)
title_widget = QWidget()
title_layout = QHBoxLayout(title_widget)
title_layout.setContentsMargins(0, 0, 0, 0)
title_layout.setSpacing(10)
title_label = QLabel(title)
title_label.setStyleSheet("font-size: 16px; font-weight: bold; color: #2c3e50;")
title_layout.addWidget(title_label)
status_indicator = QLabel("")
status_indicator.setStyleSheet("color: #2ecc71; font-size: 16px;")
title_layout.addWidget(status_indicator)
title_layout.addStretch()
text_layout.addWidget(title_widget)
count_label = QLabel(count)
count_label.setStyleSheet("color: #34495e;")
text_layout.addWidget(count_label)
stat_layout.addWidget(text_widget, stretch=1)
stat_widget.setStyleSheet("""
QWidget {
background-color: transparent;
border-radius: 10px;
}
""")
grid_layout.addWidget(stat_widget, row, col)
def go_to_install(self):
install_page = self.page_stack.findChild(InstallSystemPackage)
install_page.configure(package_name='all', distro='debian')
self.page_stack.setCurrentIndex(self.page_stack.indexOf(install_page))
class ProtocolPage(Page):
def __init__(self, page_stack, main_window=None, parent=None):
super().__init__("Protocol", page_stack,main_window, parent)
@ -2538,8 +2476,7 @@ class ProtocolPage(Page):
for j, (object_type,icon_name, page_class, geometry) in enumerate([
(QPushButton,"wireguard", WireGuardPage, (585, 90,185,75)),
(QPushButton,"residential", ResidentialPage, (585, 90+30+75,185,75)),
(QPushButton,"hidetor", HidetorPage, (585, 90+30+75+30+75,185,75)),
(QPushButton,"open", LocationPage, (585, 90+30+75+30+75+30+75,185,75))
(QPushButton,"hidetor", HidetorPage, (585, 90+30+75+30+75,185,75))
]):
boton = object_type(self)
boton.setGeometry(*geometry)
@ -2559,6 +2496,7 @@ class ProtocolPage(Page):
self.update_status.write_data({"protocol": self.selected_protocol_icon})
def show_protocol(self, page_class, protocol):
self.update_status.clear_data()
self.display.setPixmap(QPixmap(os.path.join(self.btn_path, f"{protocol}.png")).scaled(self.display.size(), Qt.AspectRatioMode.KeepAspectRatio))
self.selected_protocol_icon = protocol
self.selected_page_class = page_class
@ -2767,7 +2705,7 @@ class HidetorPage(Page):
boton.setVisible(False)
boton.setIcon(QIcon(os.path.join(self.btn_path, f"button_{icon_name}.png")))
if boton.icon().isNull():
boton.setPixmap(QPixmap(os.path.join(self.btn_path, "default_location_button.png")))
boton.setIcon(QIcon(os.path.join(self.btn_path, "default_location_button.png")))
self.buttons.append(boton)
self.buttonGroup.addButton(boton, j)
boton.clicked.connect(lambda _, location=icon_name: self.show_location(location))
@ -3075,7 +3013,7 @@ class LocationPage(Page):
def show_location(self, location):
self.initial_display.hide()
self.initial_display.hide()
self.display.setPixmap(QPixmap(os.path.join(self.btn_path, f"icon_{location}.png")).scaled(self.display.size(), Qt.AspectRatioMode.KeepAspectRatio))
self.selected_location_icon = location
self.button_next.setVisible(True)
@ -3356,7 +3294,7 @@ class ResumePage(Page):
def create_interface_elements(self):
for j, (object_type, icon_name, geometry) in enumerate([
(QLineEdit, None, (130, 70, 300, 30)),
(QLineEdit, None, (130, 73, 300, 24)),
(QLabel, None, (0,0,0,0))
]):
@ -3373,8 +3311,8 @@ class ResumePage(Page):
self.line_edit.setGeometry(*geometry)
self.line_edit.setMaxLength(13)
self.line_edit.textChanged.connect(self.toggle_button_visibility)
self.line_edit.setStyleSheet("background-color: rgba(22, 10, 30, 0.5);")
self.line_edit.setPlaceholderText("Type a name here")
self.line_edit.setStyleSheet("background-color: transparent; border: none; color: cyan;")
self.line_edit.setPlaceholderText("Enter profile name")
self.line_edit.setAlignment(Qt.AlignmentFlag.AlignCenter)
self.create()
@ -3644,13 +3582,14 @@ class EditorPage(Page):
self.button_back.clicked.connect(self.go_back)
self.name_handle = QLabel(self)
self.name_handle.setGeometry(125, 70, 400, 30)
self.name_handle.setGeometry(134, 70, 400, 30)
self.name_handle.setStyleSheet('color: #cacbcb;')
self.name_handle.setText("Profile Name:")
self.name = QLineEdit(self)
self.name.setGeometry(275, 70, 400, 30)
self.name.setGeometry(288, 70, 190, 30)
self.name.setStyleSheet("border: transparent;")
self.name.setStyleSheet("color: cyan; border: transparent;")
self.temp_changes = {}
self.original_values = {}
@ -4144,7 +4083,7 @@ class Settings(Page):
border: none;
background: transparent;
color: #808080;
font-size: 15px;
font-size: 14px;
{self.font_style}
}}
QPushButton:checked {{
@ -4477,7 +4416,7 @@ class Settings(Page):
value_label = ClickableValueLabel("N/A", stat_widget)
value_label.setObjectName("value_label")
value_label.setStyleSheet(f"color: #00ffff; font-size: 13px; font-weight: bold; {self.font_style}")
value_label.setStyleSheet(f"color: #00ffff; font-size: 12px; font-family: 'Retro Gaming', sans-serif;")
value_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
stat_widget.layout().insertWidget(0, value_label)
@ -4639,15 +4578,21 @@ class Settings(Page):
layout.setSpacing(10)
config_path = Constants.HV_CONFIG_HOME
current_connection = self.update_status.get_current_connection();
if current_connection is not None:
current_connection = current_connection.capitalize()
stats = [
("Config Path", config_path),
("Client Version", Constants.HV_CLIENT_VERSION_NUMBER),
("Connection", self.update_status.get_current_connection()),
("Connection", current_connection),
]
for i, (label, value) in enumerate(stats):
info_widget = QLabel(f"{label}: {value}")
info_widget.setStyleSheet(f"color: white; padding: 5px; {self.font_style}")
info_widget.setStyleSheet(f"font-size: 14px; color: white; padding: 5px; {self.font_style}")
info_widget.setWordWrap(True)
layout.addWidget(info_widget, i, 0)
@ -4667,7 +4612,7 @@ class Settings(Page):
value_label = QLabel(str(value))
value_label.setObjectName("value_label")
value_label.setStyleSheet("color: #00ffff; font-size: 24px; font-weight: bold")
value_label.setStyleSheet("font-family: 'Retro Gaming', sans-serif; color: #00ffff; font-size: 22px; font-weight: bold")
value_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
desc_label = QLabel(label)
@ -4744,7 +4689,7 @@ class Settings(Page):
title.setStyleSheet(f"color: #808080; font-size: 12px; font-weight: bold; {self.font_style}")
layout.addWidget(title)
log_text = QLabel(f"If enabled, these Error Logs would be stored locally on your computer\nat {Constants.HV_DATA_HOME}/gui")
log_text = QLabel(f"Enabling this feature means error logs will be stored on your local\nmachine at: '{Constants.HV_CACHE_HOME}/gui'.")
log_text.setStyleSheet(f"color: white; font-size: 14px; {self.font_style}")
layout.addWidget(log_text)
@ -4818,7 +4763,7 @@ class IdPage(Page):
self.btn_path = main_window.btn_path
self.buttonGroup = QButtonGroup(self)
self.display.setGeometry(QtCore.QRect(-10, 50, 550, 460))
self.display.setPixmap(QPixmap(os.path.join(self.btn_path, "wireguardx.png")).scaled(self.display.size(), Qt.AspectRatioMode.KeepAspectRatio))
# self.display.setPixmap(QPixmap(os.path.join(self.btn_path, "wireguardx.png")).scaled(self.display.size(), Qt.AspectRatioMode.KeepAspectRatio))
self.create_interface_elements()
@ -5336,7 +5281,7 @@ class PaymentConfirmed(Page):
self.update_status = main_window
self.buttonGroup = QButtonGroup(self)
self.display.setGeometry(QRect(-10, 50, 550, 460))
self.display.setPixmap(QPixmap(os.path.join(self.btn_path, f"wireguardx.png")).scaled(self.display.size(), Qt.AspectRatioMode.KeepAspectRatio))
# self.display.setPixmap(QPixmap(os.path.join(self.btn_path, f"wireguardx.png")).scaled(self.display.size(), Qt.AspectRatioMode.KeepAspectRatio))
self.button_reverse.setVisible(False)
@ -5652,7 +5597,7 @@ class SyncScreen(Page):
def perform_sync(self):
self.button_go.setEnabled(False)
self.button_back.setEnabled(False)
self.update_status.update_status('Syncing in progress...')
self.update_status.update_status('Sync in progress...')
if self.main_window.get_current_connection() == 'tor':
self.worker_thread = WorkerThread('SYNC_TOR')
else:
@ -5754,7 +5699,7 @@ class WelcomePage(Page):
self._setup_stats_display()
def _setup_welcome_ui(self):
welcome_title = QLabel("Welcome to HydraVeilVPN", self)
welcome_title = QLabel('Welcome to HydraVeil', self)
welcome_title.setGeometry(20, 45, 760, 60)
welcome_title.setStyleSheet("""
font-size: 32px;
@ -5836,7 +5781,7 @@ class WelcomePage(Page):
text_layout.addWidget(title_widget)
count_label = QLabel(count)
count_label.setStyleSheet("color: #34495e;")
count_label.setStyleSheet("font-size: 16px; color: #34495e;")
text_layout.addWidget(count_label)
stat_layout.addWidget(text_widget, stretch=1)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 985 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 41 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2 KiB

After

Width:  |  Height:  |  Size: 1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 41 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 1,012 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 40 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 40 KiB

After

Width:  |  Height:  |  Size: 7.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2 KiB

After

Width:  |  Height:  |  Size: 1,000 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 831 B

After

Width:  |  Height:  |  Size: 429 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.4 KiB

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 41 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 999 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.4 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7 KiB

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 242 KiB

After

Width:  |  Height:  |  Size: 194 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.9 KiB

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 96 KiB

After

Width:  |  Height:  |  Size: 75 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.4 KiB

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.5 KiB

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.2 KiB

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 474 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 624 B

After

Width:  |  Height:  |  Size: 339 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.1 KiB

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 60 KiB

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 9.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 510 B

After

Width:  |  Height:  |  Size: 351 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 7.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.6 KiB

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 172 KiB

After

Width:  |  Height:  |  Size: 124 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 632 KiB

After

Width:  |  Height:  |  Size: 517 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 429 KiB

After

Width:  |  Height:  |  Size: 325 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 453 B

After

Width:  |  Height:  |  Size: 254 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.9 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.4 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 822 B

After

Width:  |  Height:  |  Size: 434 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.3 KiB

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.8 KiB

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.1 KiB

After

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 962 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 962 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.6 KiB

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 622 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.1 KiB

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.6 KiB

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.6 KiB

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.3 KiB

After

Width:  |  Height:  |  Size: 8.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.5 KiB

After

Width:  |  Height:  |  Size: 7.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.8 KiB

After

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 547 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 821 B

After

Width:  |  Height:  |  Size: 433 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 797 B

After

Width:  |  Height:  |  Size: 433 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 826 B

After

Width:  |  Height:  |  Size: 433 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.8 KiB

After

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.6 KiB

After

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.6 KiB

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 9.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 48 KiB

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 841 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 717 B

After

Width:  |  Height:  |  Size: 375 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 831 B

After

Width:  |  Height:  |  Size: 429 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.7 KiB

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.6 KiB

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.9 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.5 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.5 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 774 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 802 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 808 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.2 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.7 KiB

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.9 KiB

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.4 KiB

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 74 KiB

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 996 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 158 KiB

After

Width:  |  Height:  |  Size: 117 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 165 KiB

After

Width:  |  Height:  |  Size: 140 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.4 KiB

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.4 KiB

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.4 KiB

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 188 KiB

After

Width:  |  Height:  |  Size: 162 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 160 KiB

After

Width:  |  Height:  |  Size: 134 KiB

Some files were not shown because too many files have changed in this diff Show more