Android 14+ FIX

This commit is contained in:
Epic Studios 2024-04-18 23:01:02 +02:00
parent 0bbbeb5445
commit 4ec46836e8
79 changed files with 638 additions and 119 deletions

View file

@ -136,5 +136,4 @@
android:name="com.google.android.gms.ads.APPLICATION_ID"
android:value="ca-app-pub-3568137780412047~1296857222"/>
</application>
</manifest>

View file

@ -29,8 +29,8 @@ public class ConnectionBean {
public ConnectionBean() {
setAddress(Config.defaultVNCHost);
setUserName(Config.defaultVNCUsername);
setPassword(Config.defaultVNCPasswd);
setPort(Config.defaultVNCPort + 5900);
setPassword("555555");
setPort(Config.defaultVNCPort + 5901);
setColorModel(Config.defaultVNCColorMode);
if (Config.enable_qemu_fullScreen)
setScaleMode(Config.defaultFullscreenScaleMode);

View file

@ -314,7 +314,7 @@ public class RfbProto {
//
LocalSocket localSocket = null;
public static boolean allow_external = false;
public static boolean allow_external = true;
//-RfbProto(String h, int p, VncViewer v) throws IOException {
RfbProto(String h, int p) throws IOException{

View file

@ -127,7 +127,7 @@ public class Config {
public static int MAX_DISPLAY_REFRESH_RATE = 100; //Hz
// VNC Defaults
public static String defaultVNCHost = "127.0.0.1";
public static String defaultVNCHost = "localhost";
public static final String defaultVNCUsername = "vectras";
public static final String defaultVNCPasswd = "";

View file

@ -753,6 +753,16 @@ public class MainSettingsManager extends AppCompatActivity
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(activity);
return prefs.getString("vmUi", "VNC");
}
public static void setResolution(Activity activity, String RESOLUTION) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(activity);
SharedPreferences.Editor edit = prefs.edit();
edit.putString("RESOLUTION", RESOLUTION);
edit.apply();
}
public static String getResolution(Activity activity) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(activity);
return prefs.getString("RESOLUTION", "800x600x32");
}
public static void setSoundCard(Activity activity, String soundCard) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(activity);
SharedPreferences.Editor edit = prefs.edit();

View file

@ -19,7 +19,7 @@ import java.util.Objects;
public class AppConfig {
// App Config
public static final String vectrasVersion = "v2.8";
public static final String vectrasVersion = "2.9.1";
public static final String vectrasWebsite = "https://vectras.netlify.com/";
public static final String vectrasHelp = "https://vectras.netlify.app/how";
public static final String vectrasRaw = "https://raw.githubusercontent.com/epicstudios856/Vectras-windows-emulator/main/";
@ -33,11 +33,11 @@ public class AppConfig {
public static final String storeJson = vectrasRaw + "store_list.json";
public static final String vectrasPkg = vectrasWebsite + "download";
public static final String serverIP = "https://github.com/epicstudios856/Vectras-VM-Android";
public static final String releaseUrl = "https://vectrasvm.blackstorm.cc/vectras-vm/Releases/";
public static String getSetupFiles() {
String abi = Build.SUPPORTED_ABIS[0];
return serverIP + "/releases/download/" + vectrasVersion + "/" + abi + "-vectras.tar.gz";
return releaseUrl + vectrasVersion + "/packages/vectras-vm-" + abi + ".tar.gz";
}
public static final String romsJson(Activity activity) {

View file

@ -432,6 +432,7 @@ public class CustomRomActivity extends AppCompatActivity {
title.setText(current.itemName);
icon.setText(current.itemIcon);
drive.setText(current.itemPath);
Pattern pattern = Pattern.compile("-drive index=1,media=cdrom,file='([^']*)'");
Matcher matcher = pattern.matcher(current.itemExtra);
@ -439,7 +440,18 @@ public class CustomRomActivity extends AppCompatActivity {
String cdromPath = matcher.group(1);
cdrom.setText(cdromPath);
}
qemu.setText(current.itemExtra);
File imgFile = new File(icon.getText().toString());
if(imgFile.exists()){
Bitmap myBitmap = BitmapFactory.decodeFile(imgFile.getAbsolutePath());
ImageView ivIcon = findViewById(R.id.ivIcon);
ivIcon.setImageBitmap(myBitmap);
}
}
}

View file

@ -1,12 +1,8 @@
package com.vectras.vm;
import static android.content.Intent.ACTION_OPEN_DOCUMENT;
import static com.vectras.vm.utils.UIUtils.UIAlert;
import com.google.android.material.bottomsheet.BottomSheetDialog;
import com.vectras.qemu.*;
import android.app.ActivityManager;
import android.app.Dialog;
import android.app.NotificationManager;
@ -22,13 +18,13 @@ import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.provider.DocumentsContract;
import android.text.Html;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.Toast;
@ -55,21 +51,21 @@ import com.google.android.gms.ads.initialization.OnInitializationCompleteListene
import com.google.android.gms.ads.interstitial.InterstitialAd;
import com.google.android.gms.ads.interstitial.InterstitialAdLoadCallback;
import com.google.android.material.bottomappbar.BottomAppBar;
import com.google.android.material.bottomsheet.BottomSheetDialog;
import com.google.android.material.elevation.SurfaceColors;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.google.android.material.navigation.NavigationView;
import com.google.android.material.textfield.TextInputEditText;
import com.vectras.qemu.Config;
import com.vectras.qemu.MainSettingsManager;
import com.vectras.qemu.MainVNCActivity;
import com.vectras.qemu.utils.RamInfo;
import com.vectras.vm.MainRoms.AdapterMainRoms;
import com.vectras.vm.MainRoms.DataMainRoms;
import com.vectras.vm.adapter.LogsAdapter;
import com.vectras.vm.logger.VectrasStatus;
import com.vectras.vm.utils.AppUpdater;
import com.vectras.vm.utils.FileUtils;
import com.vectras.vm.utils.UIUtils;
import com.vectras.vterm.Terminal;
import com.vectras.vm.adapter.LogsAdapter;
import org.json.JSONArray;
import org.json.JSONException;
@ -85,7 +81,6 @@ import java.io.InputStreamReader;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;
@ -396,8 +391,8 @@ public class MainActivity extends AppCompatActivity {
if (bufferedReader.readLine() != null || bufferedReader2.readLine() != null) {
String logLine = bufferedReader.readLine();
String logLine2 = bufferedReader2.readLine();
VectrasStatus.logError("<font color='red'>[E] "+logLine+"</font>");
VectrasStatus.logError("<font color='yellow'>[W] "+logLine2+"</font>");
VectrasStatus.logError("<font color='red'>[E] " + logLine + "</font>");
VectrasStatus.logError("<font color='yellow'>[W] " + logLine2 + "</font>");
}
} catch (IOException e) {
throw new RuntimeException(e);
@ -525,6 +520,7 @@ public class MainActivity extends AppCompatActivity {
private void errorUpdateDialog(String error) {
VectrasStatus.logInfo(String.format(error));
}
public static void loadDataVbi() {
data = new ArrayList<>();
@ -627,21 +623,30 @@ public class MainActivity extends AppCompatActivity {
public static void startVM(String vmName, String env) {
boolean isRunning = isMyServiceRunning(MainService.class);
if (!isRunning) {
Intent serviceIntent = new Intent(activity, MainService.class);
MainService.env = env;
MainService.CHANNEL_ID = vmName;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
activity.startForegroundService(serviceIntent);
} else {
activity.startService(serviceIntent);
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
public void run() {
if (!isRunning) {
Intent serviceIntent = new Intent(activity, MainService.class);
if (MainSettingsManager.getVmUi(activity).equals("X11"))
MainService.env = "dwm; " + env;
else
MainService.env = env;
MainService.CHANNEL_ID = vmName;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
activity.startForegroundService(serviceIntent);
} else {
activity.startService(serviceIntent);
}
}
}
}
}, 5000);
if (MainSettingsManager.getVmUi(activity).equals("VNC")) {
activity.startActivity(new Intent(activity, MainVNCActivity.class));
} else if (MainSettingsManager.getVmUi(activity).equals("SPICE")) {
//activity.startActivity(new Intent(activity, RemoteCanvasActivity.class));
} else if (MainSettingsManager.getVmUi(activity).equals("X11")) {
//activity.startActivity(new Intent(activity, X11Activity.class));
}
String[] params = env.split("\\s+");
VectrasStatus.logInfo("Params:");
@ -709,6 +714,7 @@ public class MainActivity extends AppCompatActivity {
Log.d("TAG", "The interstitial ad wasn't ready yet.");
}
}
@Override
public void onBackPressed() {
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);

View file

@ -49,6 +49,7 @@ public class MainService extends Service {
Terminal vterm = new Terminal(this);
//vterm.executeShellCommand("chmod 770 /run/pulse -R");
//vterm.executeShellCommand("pulseaudio --system --disallow-exit --disallow-module-loading --daemonize --log-level=debug --log-time=1");
vterm.executeShellCommand("vncserver :1");
vterm.executeShellCommand(env);
}
} else

View file

@ -1,17 +1,30 @@
package com.vectras.vm;
import static android.content.Intent.ACTION_OPEN_DOCUMENT;
import static com.vectras.vm.utils.UIUtils.UIAlert;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.provider.DocumentsContract;
import android.view.View;
import android.widget.ProgressBar;
import android.widget.ScrollView;
import android.widget.TextView;
import android.widget.Toast;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import androidx.preference.PreferenceManager;
import com.google.android.material.button.MaterialButton;
import com.vectras.vterm.view.ZoomableTextView;
@ -19,6 +32,8 @@ import com.vectras.vterm.view.ZoomableTextView;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
@ -29,11 +44,12 @@ import java.net.HttpURLConnection;
import java.net.URL;
public class SetupQemuActivity extends AppCompatActivity implements View.OnClickListener {
SetupQemuActivity activity;
Activity activity;
private final String TAG = "SetupQemuActivity";
ZoomableTextView vterm;
MaterialButton inBtn;
ProgressBar progressBar;
AlertDialog alertDialog;
@Override
protected void onCreate(Bundle savedInstanceState) {
@ -46,15 +62,41 @@ public class SetupQemuActivity extends AppCompatActivity implements View.OnClick
vterm = findViewById(R.id.tvTerminalOutput);
inBtn = findViewById(R.id.btnInstall);
inBtn.setOnClickListener(activity);
inBtn.setOnClickListener(this);
tarPath = getExternalFilesDir("data") + "/data.tar.gz";
alertDialog = new AlertDialog.Builder(activity, R.style.MainDialogTheme).create();
alertDialog.setTitle("BOOTSTRAP REQUIRED!");
alertDialog.setMessage("U can choose between auto download and setup or manual setup by choosing bootstrap file.");
alertDialog.setCancelable(false);
alertDialog.setButton(DialogInterface.BUTTON_POSITIVE, "AUTO SETUP", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
startDownload();
return;
}
});
alertDialog.setButton(DialogInterface.BUTTON_NEGATIVE, "MANUAL SETUP", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
Intent intent = new Intent(ACTION_OPEN_DOCUMENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType("*/*");
// Optionally, specify a URI for the file that should appear in the
// system file picker when it loads.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
intent.putExtra(DocumentsContract.EXTRA_INITIAL_URI, Environment.DIRECTORY_DOWNLOADS);
}
startActivityForResult(intent, 1001);
}
});
File tarGZ = new File(tarPath);
if (tarGZ.exists()) {
setupVectras();
} else {
startDownload();
alertDialog.show();
}
}
@ -63,10 +105,9 @@ public class SetupQemuActivity extends AppCompatActivity implements View.OnClick
if (id == R.id.btnInstall) {
File tarGZ = new File(tarPath);
if (tarGZ.exists()) {
setupVectras();
} else {
startDownload();
tarGZ.delete();
}
alertDialog.show();
}
}
@ -109,8 +150,10 @@ public class SetupQemuActivity extends AppCompatActivity implements View.OnClick
String filesDir = activity.getFilesDir().getAbsolutePath();
String nativeLibDir = activity.getApplicationInfo().nativeLibraryDir;
File tmpDir = new File(activity.getFilesDir(), "tmp");
// Setup environment for the PRoot process
processBuilder.environment().put("PROOT_TMP_DIR", filesDir + "/tmp");
processBuilder.environment().put("PROOT_TMP_DIR", tmpDir.getAbsolutePath());
processBuilder.environment().put("PROOT_LOADER", nativeLibDir + "/libproot-loader.so");
processBuilder.environment().put("PROOT_LOADER_32", nativeLibDir + "/libproot-loader32.so");
@ -118,7 +161,7 @@ public class SetupQemuActivity extends AppCompatActivity implements View.OnClick
processBuilder.environment().put("USER", "root");
processBuilder.environment().put("PATH", "/bin:/usr/bin:/sbin:/usr/sbin");
processBuilder.environment().put("TERM", "xterm-256color");
processBuilder.environment().put("TMPDIR", "/tmp");
processBuilder.environment().put("TMPDIR", tmpDir.getAbsolutePath());
processBuilder.environment().put("SHELL", "/bin/sh");
// Example PRoot command; replace 'libproot.so' and other paths as needed
@ -308,12 +351,80 @@ public class SetupQemuActivity extends AppCompatActivity implements View.OnClick
executeShellCommand("set -e;" +
" echo 'Starting setup...';" +
" apk update;" +
" apk add libslirp libslirp-dev pulseaudio-dev glib-dev pixman-dev zlib-dev spice-dev libusbredirparser usbredir-dev libiscsi-dev sdl2 sdl2-dev libepoxy-dev virglrenderer-dev tar;" +
" clear;" +
" tar -xvzf " + tarPath + " -C " + filesDir + "/distro;" +
" apk add tar tigervnc dwm libslirp libslirp-dev pulseaudio-dev glib-dev pixman-dev zlib-dev spice-dev" +
" libusbredirparser usbredir-dev libiscsi-dev sdl2 sdl2-dev libepoxy-dev virglrenderer-dev rdma-core" +
" libusb ncurses-libs curl libnfs sdl2 gtk+3.0 fuse libpulse libseccomp libjack pipewire liburing;" +
" tar -xzvf " + tarPath + " -C /;" +
" rm " + tarPath + ";" +
" clear;" +
" mkdir -p ~/.vnc && echo -e \"555555\\n555555\" | vncpasswd -f > ~/.vnc/passwd && chmod 0600 ~/.vnc/passwd" +
" echo \"installation successful! xssFjnj58Id\"");
}
public String getPath(Uri uri) {
return com.vectras.vm.utils.FileUtils.getPath(this, uri);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent ReturnedIntent) {
super.onActivityResult(requestCode, resultCode, ReturnedIntent);
if (requestCode == 1001 && resultCode == RESULT_OK) {
Uri content_describer = ReturnedIntent.getData();
File selectedFilePath = new File(getPath(content_describer));
ProgressBar loading = progressBar;
String abi = Build.SUPPORTED_ABIS[0];
if (selectedFilePath.toString().endsWith(abi+".tar.gz")) {
loading.setVisibility(View.VISIBLE);
new Thread(new Runnable() {
@Override
public void run() {
FileInputStream File = null;
try {
File = (FileInputStream) getContentResolver().openInputStream(content_describer);
} catch (FileNotFoundException e) {
throw new RuntimeException(e);
}
try {
try {
OutputStream out = new FileOutputStream(new File(tarPath));
try {
// Transfer bytes from in to out
byte[] buf = new byte[1024];
int len;
while ((len = File.read(buf)) > 0) {
out.write(buf, 0, len);
}
} finally {
out.close();
}
} finally {
Runnable runnable = new Runnable() {
@Override
public void run() {
loading.setVisibility(View.GONE);
alertDialog.dismiss();
setupVectras();
}
};
activity.runOnUiThread(runnable);
File.close();
}
} catch (IOException e) {
Runnable runnable = new Runnable() {
@Override
public void run() {
loading.setVisibility(View.GONE);
UIAlert(activity, e.toString(), "error");
}
};
activity.runOnUiThread(runnable);
}
}
}).start();
} else {
alertDialog.show();
UIAlert(activity, "NOT VAILED FILE", "please select vectras-vm-" + abi + ".tar.gz file");
}
} else
alertDialog.show();
}
}

View file

@ -81,9 +81,10 @@ public class SplashActivity extends AppCompatActivity implements Runnable {
String filesDir = activity.getFilesDir().getAbsolutePath();
String nativeLibDir = activity.getApplicationInfo().nativeLibraryDir;
File tmpDir = new File(filesDir + "/tmp/xdg");
if (!tmpDir.exists()) {
File tmpDir = new File(context.getFilesDir(), "tmp");
if (!tmpDir.isDirectory()) {
tmpDir.mkdirs();
FileUtils.chmod(tmpDir, 0771);
}
File vDir = new File(com.vectras.vm.AppConfig.maindirpath);

View file

@ -1,6 +1,7 @@
package com.vectras.vm;
import android.app.Activity;
import android.content.Intent;
import com.vectras.qemu.Config;
import com.vectras.qemu.MainSettingsManager;
@ -93,9 +94,6 @@ public class StartVM {
acclerationStr = "-accel tcg,thread=multi";
acclerationStr += ",tb-size=" + MainSettingsManager.getTbSize(activity);
String spiceStr = "-spice ";
spiceStr += "port=6999,disable-ticketing=on";
String boot = "-boot ";
boot += MainSettingsManager.getBoot(activity);
@ -135,14 +133,19 @@ public class StartVM {
if (MainSettingsManager.getVmUi(activity).equals("VNC")) {
String vncStr = "-vnc ";
params.add(vncStr);
//params.add(vncStr);
// Allow connections only from localhost using localsocket without a password
//params.add(Config.defaultVNCHost+":" + Config.defaultVNCPort);
String qmpParams = "unix:";
qmpParams += Config.getLocalVNCSocketPath();
params.add(qmpParams);
} else if (MainSettingsManager.getVmUi(activity).equals("SPICE"))
//params.add(qmpParams);
} else if (MainSettingsManager.getVmUi(activity).equals("SPICE")) {
String spiceStr = "-spice ";
spiceStr += "port=6999,disable-ticketing=on";
params.add(spiceStr);
} else if (MainSettingsManager.getVmUi(activity).equals("X11")) {
}
params.add("-monitor");
params.add("vc");

View file

@ -39,7 +39,8 @@ public class Terminal {
private String user = "root";
public static Process qemuProcess;
public static String DISPLAY = ":1";
public Terminal(Context context) {
this.context = context;
}
@ -73,8 +74,10 @@ public class Terminal {
String filesDir = context.getFilesDir().getAbsolutePath();
String nativeLibDir = context.getApplicationInfo().nativeLibraryDir;
File tmpDir = new File(context.getFilesDir(), "tmp");
// Setup environment for the PRoot qemuProcess
processBuilder.environment().put("PROOT_TMP_DIR", filesDir + "/tmp");
processBuilder.environment().put("PROOT_TMP_DIR", tmpDir.getAbsolutePath());
processBuilder.environment().put("PROOT_LOADER", nativeLibDir + "/libproot-loader.so");
processBuilder.environment().put("PROOT_LOADER_32", nativeLibDir + "/libproot-loader32.so");
@ -82,10 +85,13 @@ public class Terminal {
processBuilder.environment().put("USER", user);
processBuilder.environment().put("PATH", "/bin:/usr/bin:/sbin:/usr/sbin");
processBuilder.environment().put("TERM", "xterm-256color");
processBuilder.environment().put("TMPDIR", filesDir + "/tmp");
processBuilder.environment().put("TMPDIR", tmpDir.getAbsolutePath());
processBuilder.environment().put("SHELL", "/bin/sh");
processBuilder.environment().put("DISPLAY", DISPLAY);
processBuilder.environment().put("PULSE_SERVER", "/run/pulse/native");
processBuilder.environment().put("XDG_RUNTIME_DIR", "/run");
processBuilder.environment().put("QEMU_AUDIO_DRV", "sdl");
processBuilder.environment().put("SDL_VIDEODRIVER", "x11");
// Example PRoot command; replace 'libproot.so' and other paths as needed
String[] prootCommand = {

View file

@ -102,7 +102,7 @@ public class TerminalBottomSheetDialog {
new Thread(() -> {
String username = null;
// Update the prompt on the UI thread
String finalUsername = username != null ? username : "user";
String finalUsername = username != null ? username : "root";
activity.runOnUiThread(() -> {
promptView.setText(finalUsername + "@localhost:~$ ");
});
@ -154,8 +154,10 @@ public class TerminalBottomSheetDialog {
String filesDir = activity.getFilesDir().getAbsolutePath();
String nativeLibDir = activity.getApplicationInfo().nativeLibraryDir;
File tmpDir = new File(activity.getFilesDir(), "tmp");
// Setup environment for the PRoot process
processBuilder.environment().put("PROOT_TMP_DIR", filesDir + "/tmp");
processBuilder.environment().put("PROOT_TMP_DIR", tmpDir.getAbsolutePath());
processBuilder.environment().put("PROOT_LOADER", nativeLibDir + "/libproot-loader.so");
processBuilder.environment().put("PROOT_LOADER_32", nativeLibDir + "/libproot-loader32.so");
@ -163,9 +165,13 @@ public class TerminalBottomSheetDialog {
processBuilder.environment().put("USER", "root");
processBuilder.environment().put("PATH", "/bin:/usr/bin:/sbin:/usr/sbin");
processBuilder.environment().put("TERM", "xterm-256color");
processBuilder.environment().put("TMPDIR", "/tmp");
processBuilder.environment().put("TMPDIR", tmpDir.getAbsolutePath());
processBuilder.environment().put("SHELL", "/bin/sh");
processBuilder.environment().put("DISPLAY", getLocalIpAddress()+":0");
processBuilder.environment().put("DISPLAY", getLocalIpAddress()+":1");
processBuilder.environment().put("PULSE_SERVER", "/run/pulse/native");
processBuilder.environment().put("XDG_RUNTIME_DIR", "/run");
processBuilder.environment().put("QEMU_AUDIO_DRV", "sdl");
processBuilder.environment().put("SDL_VIDEODRIVER", "x11");
// Example PRoot command; replace 'libproot.so' and other paths as needed
String[] prootCommand = {

Binary file not shown.

View file

@ -0,0 +1,170 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="108dp"
android:height="108dp"
android:viewportWidth="108"
android:viewportHeight="108">
<path
android:fillColor="#3DDC84"
android:pathData="M0,0h108v108h-108z" />
<path
android:fillColor="#00000000"
android:pathData="M9,0L9,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,0L19,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M29,0L29,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M39,0L39,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M49,0L49,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M59,0L59,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M69,0L69,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M79,0L79,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M89,0L89,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M99,0L99,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,9L108,9"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,19L108,19"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,29L108,29"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,39L108,39"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,49L108,49"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,59L108,59"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,69L108,69"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,79L108,79"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,89L108,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,99L108,99"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,29L89,29"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,39L89,39"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,49L89,49"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,59L89,59"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,69L89,69"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,79L89,79"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M29,19L29,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M39,19L39,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M49,19L49,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M59,19L59,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M69,19L69,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M79,19L79,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
</vector>

View file

@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M18,12c-0.55,0 -1,0.45 -1,1v2h-2c-0.55,0 -1,0.45 -1,1s0.45,1 1,1h3c0.55,0 1,-0.45 1,-1v-3c0,-0.55 -0.45,-1 -1,-1zM7,9h2c0.55,0 1,-0.45 1,-1s-0.45,-1 -1,-1L6,7c-0.55,0 -1,0.45 -1,1v3c0,0.55 0.45,1 1,1s1,-0.45 1,-1L7,9zM21,3L3,3c-1.1,0 -2,0.9 -2,2v14c0,1.1 0.9,2 2,2h18c1.1,0 2,-0.9 2,-2L23,5c0,-1.1 -0.9,-2 -2,-2zM20,19.01L4,19.01c-0.55,0 -1,-0.45 -1,-1L3,5.99c0,-0.55 0.45,-1 1,-1h16c0.55,0 1,0.45 1,1v12.02c0,0.55 -0.45,1 -1,1z"/>
</vector>

View file

@ -1,59 +0,0 @@
#!/bin/bash
subscribed_repositories() {
local main_sources
main_sources=$(grep -P '^\s*deb\s' "@VTERM_PREFIX@/etc/apt/sources.list")
if [ -n "$main_sources" ]; then
echo "#### sources.list"
echo "\`$main_sources\`"
fi
local filename repo_package supl_sources
while read -r filename; do
repo_package=$(dpkg -S "$filename" 2>/dev/null | cut -d : -f 1)
supl_sources=$(grep -P '^\s*deb\s' "$filename")
if [ -n "$supl_sources" ]; then
if [ -n "$repo_package" ]; then
echo "#### $repo_package (sources.list.d/$(basename "$filename"))"
else
echo "#### sources.list.d/$(basename "$filename")"
fi
echo "\`$supl_sources\` "
fi
done < <(find "@VTERM_PREFIX@/etc/apt/sources.list.d" -maxdepth 1 ! -type d)
}
updatable_packages() {
local updatable
if [ "$(id -u)" = "0" ]; then
echo "Running as root. Cannot check updatable packages."
else
apt update >/dev/null 2>&1
updatable=$(apt list --upgradable 2>/dev/null | tail -n +2)
if [ -z "$updatable" ];then
echo "All packages up to date"
else
echo $'```\n'"$updatable"$'\n```\n'
fi
fi
}
output="
### Subscribed Repositories
$(subscribed_repositories)
##
### Updatable Packages
$(updatable_packages)
##
"
echo "$output"

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -22,11 +22,13 @@
</string-array>
<string-array name="vmUiLabels">
<item>VNC</item>
<item>SPICE</item>
<!--<item>SPICE</item>-->
<item>X11 (XSDL)</item>
</string-array>
<string-array name="vmUiValues">
<item>VNC</item>
<item>SPICE</item>
<!--<item>SPICE</item>-->
<item>X11</item>
</string-array>
<string-array name="vmArchLabels">
<item>X86_64 QEMU</item>
@ -146,7 +148,7 @@
<item>exact</item>
<item>custom</item>
</string-array>
<string-array name="displayResolution">
<string-array name="displayResolutionLabels">
<item>320x200</item>
<item>320x240</item>
<item>352x288</item>
@ -172,4 +174,30 @@
<item>3840x2160</item>
<item>7680x4320</item>
</string-array>
<string-array name="displayResolutionValues">
<item>320x200x32</item>
<item>320x240x32</item>
<item>352x288x32</item>
<item>400x240x32</item>
<item>640x350x32</item>
<item>640x480x32</item>
<item>800x480x32</item>
<item>800x600x32</item>
<item>1024x768x32</item>
<item>1280x720x32</item>
<item>1280x960x32</item>
<item>1280x1024x32</item>
<item>1400x1050x32</item>
<item>1600x1024x32</item>
<item>1600x1200x32</item>
<item>1366x768x32</item>
<item>1680x1050x32</item>
<item>1920x1080x32</item>
<item>1920x1200x32</item>
<item>2048x1536x32</item>
<item>2560x1600x32</item>
<item>2560x2048x32</item>
<item>3840x2160x32</item>
<item>7680x4320x32</item>
</string-array>
</resources>

View file

@ -280,4 +280,207 @@
<string name="try_again">TRY AGAIN</string>
<string name="logs">Logs</string>
<string name="options">Options</string>
<!--======================XServer XSDL STRINGS====================-->
<string name="init">Initializing</string>
<string name="please_wait">Please wait while data is being downloaded</string>
<string name="device_config">Device configuration</string>
<string name="device_change_cfg">Change device configuration</string>
<string name="download_unneeded">No need to download</string>
<string name="connecting_to">Connecting to %s</string>
<string name="failed_connecting_to">Failed connecting to %s</string>
<string name="error_connecting_to">Error connecting to %s</string>
<string name="dl_from">Downloading data from %s</string>
<string name="error_dl_from">Error downloading data from %s</string>
<string name="error_write">Error writing to %s</string>
<string name="dl_progress">%1$.0f%% done: file %2$s</string>
<string name="dl_finished">Finished</string>
<string name="storage_phone">Internal storage - %d MB free</string>
<string name="storage_sd">SD card storage - %d MB free</string>
<string name="storage_custom">Specify directory</string>
<string name="storage_commandline">Command line parameters, one argument per line</string>
<string name="storage_question">Data installation location</string>
<string name="storage_access">Permission to write to SD card</string>
<string name="optional_downloads">Downloads</string>
<string name="downloads">Downloads</string>
<string name="ok">OK</string>
<string name="cancel">Cancel</string>
<string name="controls_arrows">Arrows / joystick / dpad</string>
<string name="controls_trackball">Trackball</string>
<string name="controls_accel">Accelerometer</string>
<string name="controls_touch">Touchscreen only</string>
<string name="controls_question">What kind of navigation keys does your device have?</string>
<string name="controls_additional">Additional controls</string>
<string name="controls_screenkb">On-screen keyboard</string>
<string name="controls_accelnav">Accelerometer</string>
<string name="controls_screenkb_size">On-screen keyboard size</string>
<string name="controls_screenkb_drawsize">Size of button images</string>
<string name="controls_screenkb_large">Large</string>
<string name="controls_screenkb_medium">Medium</string>
<string name="controls_screenkb_small">Small</string>
<string name="controls_screenkb_tiny">Tiny</string>
<string name="controls_screenkb_custom">Custom</string>
<string name="controls_screenkb_theme">On-screen keyboard theme</string>
<string name="controls_screenkb_by">%1$s by %2$s</string>
<string name="controls_screenkb_transparency">On-screen keyboard transparency</string>
<string name="controls_screenkb_trans_0">Invisible</string>
<string name="controls_screenkb_trans_1">Almost invisible</string>
<string name="controls_screenkb_trans_2">Transparent</string>
<string name="controls_screenkb_trans_3">Semi-transparent</string>
<string name="controls_screenkb_trans_4">Non-transparent</string>
<string name="trackball_no_dampening">No dampening</string>
<string name="trackball_fast">Fast</string>
<string name="trackball_medium">Medium</string>
<string name="trackball_slow">Slow</string>
<string name="trackball_question">Trackball dampening</string>
<string name="accel_veryfast">Very fast</string>
<string name="accel_fast">Fast</string>
<string name="accel_medium">Medium</string>
<string name="accel_slow">Slow</string>
<string name="accel_veryslow">Very slow</string>
<string name="accel_question">Accelerometer sensitivity</string>
<string name="accel_floating">Floating</string>
<string name="accel_fixed_start">Fixed when application starts</string>
<string name="accel_fixed_horiz">Fixed to table desk orientation</string>
<string name="accel_question_center">Accelerometer center position</string>
<string name="mouse_emulation">Mouse emulation</string>
<string name="rightclick_question">Right mouse click</string>
<string name="rightclick_menu">Menu key</string>
<string name="rightclick_key">Physical key</string>
<string name="rightclick_multitouch">Touch screen with second finger</string>
<string name="rightclick_pressure">Touch screen with force</string>
<string name="rightclick_none">Disable right mouse click</string>
<string name="leftclick_question">Left mouse click</string>
<string name="leftclick_normal">Normal</string>
<string name="leftclick_near_cursor">Touch near mouse cursor</string>
<string name="leftclick_multitouch">Touch screen with second finger</string>
<string name="leftclick_pressure">Touch screen with force</string>
<string name="leftclick_dpadcenter">Trackball click / joystick center</string>
<string name="leftclick_timeout">Hold at the same spot</string>
<string name="leftclick_tap">Tap</string>
<string name="leftclick_tap_or_timeout">Tap or hold</string>
<string name="leftclick_timeout_time">Holding timeout</string>
<string name="leftclick_timeout_time_0">0.3 sec</string>
<string name="leftclick_timeout_time_1">0.5 sec</string>
<string name="leftclick_timeout_time_2">0.7 sec</string>
<string name="leftclick_timeout_time_3">1 sec</string>
<string name="leftclick_timeout_time_4">1.5 sec</string>
<string name="click_with_dpadcenter">Left mouse click with trackball / joystick center</string>
<string name="advanced">Advanced features</string>
<string name="mouse_keepaspectratio">Keep 4:3 screen aspect ratio</string>
<string name="mouse_showcreenunderfinger">Show screen under finger in separate window</string>
<string name="mouse_showcreenunderfinger2">On-screen magnifying glass</string>
<string name="mouse_joystickmouse">Move mouse with joystick or trackball</string>
<string name="mouse_joystickmousespeed">Move mouse with joystick speed</string>
<string name="mouse_joystickmouseaccel">Move mouse with joystick acceleration</string>
<string name="mouse_relative">Relative mouse movement (laptop mode)</string>
<string name="mouse_relative_speed">Relative mouse movement speed</string>
<string name="mouse_relative_accel">Relative mouse movement acceleration</string>
<string name="mouse_hover_jitter_filter">Filter jitter for stylus/finger hover</string>
<string name="mouse_gyroscope_mouse">Control mouse with gyroscope</string>
<string name="mouse_gyroscope_mouse_sensitivity">Gyroscope sensitivity</string>
<string name="mouse_finger_hover">Finger hover</string>
<string name="mouse_subframe_touch_events">Multiple touch events per video frame</string>
<string name="none">None</string>
<string name="measurepressure">Calibrate touchscreen pressure</string>
<string name="measurepressure_touchplease">Please slide finger across the screen for two seconds</string>
<string name="measurepressure_response">Pressure %1$03d radius %2$03d</string>
<string name="audiobuf_verysmall">Very small (fast devices, less lag)</string>
<string name="audiobuf_small">Small</string>
<string name="audiobuf_medium">Medium</string>
<string name="audiobuf_large">Large (older devices, if sound is choppy)</string>
<string name="audiobuf_question">Size of audio buffer</string>
<string name="remap_hwkeys">Remap physical keys</string>
<string name="remap_hwkeys_press">Press any key except HOME and POWER, you may use volume keys</string>
<string name="remap_hwkeys_select">Select SDL keycode</string>
<string name="remap_hwkeys_select_simple">Select action</string>
<string name="remap_hwkeys_select_more_keys">Show all keycodes</string>
<string name="remap_screenkb">Remap on-screen controls</string>
<string name="remap_screenkb_joystick">Joystick</string>
<string name="remap_screenkb_button">Button</string>
<string name="remap_screenkb_button_text">Text input button</string>
<string name="remap_screenkb_button_gestures">Two-finger screen gestures</string>
<string name="remap_screenkb_button_gestures_sensitivity">Two-finger screen gestures sensitivity</string>
<string name="remap_screenkb_button_zoomin">Zoom in two-finger gesture</string>
<string name="remap_screenkb_button_zoomout">Zoom out two-finger gesture</string>
<string name="remap_screenkb_button_rotateleft">Rotate left two-finger gesture</string>
<string name="remap_screenkb_button_rotateright">Rotate right two-finger gesture</string>
<string name="screenkb_custom_layout">Customize on-screen keyboard layout</string>
<string name="screenkb_custom_layout_help">Press BACK when done. Resize buttons by sliding on empty space.</string>
<string name="screenkb_floating_joystick">Floating joystick</string>
<string name="calibrate_touchscreen">Calibrate touchscreen</string>
<string name="calibrate_touchscreen_touch">Touch all edges of the screen, press BACK when done</string>
<string name="video">Video settings</string>
<string name="video_smooth">Linear video filtering</string>
<string name="video_separatethread">Separate thread for video, it can increase FPS, it also can crash the app</string>
<string name="video_orientation_vertical">Portrait/vertical screen orientation</string>
<string name="video_orientation_autodetect">Auto-detect screen orientation</string>
<string name="video_bpp_24">24 bpp screen color depth</string>
<string name="video_immersive">Hide system navigation buttons / immersive mode</string>
<string name="tv_borders">TV borders</string>
<string name="text_edit_click_here">Tap to start typing, press Back when done</string>
<string name="display_size_mouse">Mouse emulation mode</string>
<string name="display_size">Display size for mouse emulation</string>
<string name="display_size_desktop">Desktop, no emulation</string>
<string name="display_size_large">Large (tablets)</string>
<string name="display_size_small">Small, magnifying glass</string>
<string name="display_size_small_touchpad">Small, touchpad mode</string>
<string name="display_size_tiny">Tiny</string>
<string name="display_size_tiny_touchpad">Tiny, touchpad mode</string>
<string name="show_more_options">Show more options</string>
<string name="hardware_mouse_detected">Hardware mouse detected, disabling mouse emulation</string>
<string name="not_enough_ram">Not enough RAM</string>
<string name="not_enough_ram_size">This app needs %1$d Mb RAM, your device has %2$d Mb</string>
<string name="ignore">Ignore</string>
<string name="calibrate_gyroscope">Calibrate gyroscope</string>
<string name="calibrate_gyroscope_text">Put your device on a flat surface</string>
<string name="calibrate_gyroscope_not_supported">Your device does not have gyroscope</string>
<string name="reset_config">Reset config to defaults</string>
<string name="reset_config_ask">Reset all options to default values?</string>
<string name="cancel_download">Cancel data downloading?</string>
<string name="cancel_download_resume">You can resume it later, the data will not be downloaded twice.</string>
<string name="yes">Yes</string>
<string name="no">No</string>
<!-- Play Game Services strings -->
<string name="gamehelper_sign_in_failed">Failed to sign in. Please check your network connection and try again.</string>
<string name="gamehelper_app_misconfigured">The application is incorrectly configured. Check that the package name and signing certificate match the client ID created in Developer Console. Also, if the application is not yet published, check that the account you are trying to sign in with is listed as a tester account. See logs for more information.</string>
<string name="gamehelper_license_failed">License check failed.</string>
<string name="gamehelper_unknown_error">Unknown error.</string>
<string name="accessing_network">Accessing network, please wait</string>
<string name="google_play_game_services_app_id" translatable="false">==GOOGLEPLAYGAMESERVICES_APP_ID==</string>
<string name="restarting_please_wait">Restarting, please wait.</string>
<string name="notification_app_is_running">%s is running</string>
<string name="notification_stop">Stop</string>
</resources>

View file

@ -156,9 +156,20 @@
android:entryValues="@array/vmUiValues"
android:key="vmUi"
android:title="UI"
app:isPreferenceVisible="false"
app:useSimpleSummaryProvider="true"
app:icon="@drawable/computer"/>
<ListPreference
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:defaultValue="800x600x32"
android:entries="@array/displayResolutionLabels"
android:entryValues="@array/displayResolutionValues"
android:key="RESOLUTION"
android:title="X11 Resolution"
app:useSimpleSummaryProvider="true"
app:icon="@drawable/round_aspect_ratio_24"/>
<ListPreference
android:layout_width="wrap_content"
android:layout_height="wrap_content"
@ -169,6 +180,7 @@
android:entryValues="@array/mouseValues"
app:icon="@drawable/round_mouse_24"
app:useSimpleSummaryProvider="true" />
<ListPreference
android:layout_width="wrap_content"
android:layout_height="wrap_content"

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 17 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.4 KiB

After

Width:  |  Height:  |  Size: 5.2 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 852 B

After

Width:  |  Height:  |  Size: 1.8 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3 KiB

After

Width:  |  Height:  |  Size: 2.7 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3 KiB

After

Width:  |  Height:  |  Size: 2.7 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

After

Width:  |  Height:  |  Size: 3.1 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 459 B

After

Width:  |  Height:  |  Size: 1.3 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.7 KiB

After

Width:  |  Height:  |  Size: 7.1 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 2.6 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.8 KiB

After

Width:  |  Height:  |  Size: 3.5 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.8 KiB

After

Width:  |  Height:  |  Size: 3.5 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.8 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 4.1 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.5 KiB

After

Width:  |  Height:  |  Size: 6.7 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.5 KiB

After

Width:  |  Height:  |  Size: 6.7 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.1 KiB

After

Width:  |  Height:  |  Size: 5.9 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.9 KiB

After

Width:  |  Height:  |  Size: 8.9 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.9 KiB

After

Width:  |  Height:  |  Size: 8.9 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 98 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 55 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.1 KiB

After

Width:  |  Height:  |  Size: 4.4 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.1 KiB

After

Width:  |  Height:  |  Size: 5.1 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.5 KiB

After

Width:  |  Height:  |  Size: 4.9 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.7 KiB

After

Width:  |  Height:  |  Size: 7.3 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 17 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 24 KiB

Before After
Before After

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 167 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 73 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 114 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 172 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 268 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 116 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.