From 4bb76274885fb9e7054de26c036702f03aa7cbb5 Mon Sep 17 00:00:00 2001 From: crschnick Date: Sun, 19 Mar 2023 19:38:29 +0000 Subject: [PATCH] More shell rework --- app/build.gradle | 2 +- .../io/xpipe/app/browser/FileBrowserComp.java | 2 +- .../io/xpipe/app/browser/FileListComp.java | 6 +- .../xpipe/app/browser/FileSystemHelper.java | 27 ++++++- .../app/browser/OpenFileSystemModel.java | 22 +++--- .../source/store/DataStoreSelectorComp.java | 2 +- .../store/DsStoreProviderChoiceComp.java | 2 +- .../source/store/NamedStoreChoiceComp.java | 2 +- .../comp/storage/store/StoreEntryComp.java | 2 +- .../store/StoreEntryFlatMiniSection.java | 4 +- .../io/xpipe/app/ext/DataStoreProvider.java | 2 +- .../impl/FileSystemStoreChoiceComp.java | 4 +- .../fxcomps/impl/ShellStoreChoiceComp.java | 2 +- .../xpipe/core/charsetter/StreamCharset.java | 14 ++++ .../io/xpipe/core/process/ProcessControl.java | 2 + .../io/xpipe/core/process/ShellDialect.java | 11 +++ .../io/xpipe/ext/base/LocalStoreProvider.java | 71 ------------------ ext/base/src/main/java/module-info.java | 1 - .../io/xpipe/ext/base/resources/img/cmd.png | Bin 1653 -> 0 bytes .../ext/base/resources/img/local_icon.png | Bin 14068 -> 0 bytes .../ext/base/resources/img/powershell.png | Bin 19994 -> 0 bytes 21 files changed, 79 insertions(+), 99 deletions(-) delete mode 100644 ext/base/src/main/java/io/xpipe/ext/base/LocalStoreProvider.java delete mode 100644 ext/base/src/main/resources/io/xpipe/ext/base/resources/img/cmd.png delete mode 100644 ext/base/src/main/resources/io/xpipe/ext/base/resources/img/local_icon.png delete mode 100644 ext/base/src/main/resources/io/xpipe/ext/base/resources/img/powershell.png diff --git a/app/build.gradle b/app/build.gradle index f475d74a..ed3fc133 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -136,7 +136,7 @@ run { systemProperty 'io.xpipe.app.writeLogs', "true" systemProperty 'io.xpipe.app.writeSysOut', "true" systemProperty 'io.xpipe.app.developerMode', "true" - systemProperty 'io.xpipe.app.logLevel', "debug" + systemProperty 'io.xpipe.app.logLevel', "trace" systemProperty 'io.xpipe.app.fullVersion', rootProject.fullVersion // systemProperty "io.xpipe.beacon.port", "21724" // systemProperty "io.xpipe.beacon.printMessages", "true" diff --git a/app/src/main/java/io/xpipe/app/browser/FileBrowserComp.java b/app/src/main/java/io/xpipe/app/browser/FileBrowserComp.java index 1cc14216..767d9ad8 100644 --- a/app/src/main/java/io/xpipe/app/browser/FileBrowserComp.java +++ b/app/src/main/java/io/xpipe/app/browser/FileBrowserComp.java @@ -209,7 +209,7 @@ public class FileBrowserComp extends SimpleComp { ? DataStorage.get() .getStoreEntry(model.getStore().getValue()) .getProvider() - .getDisplayIconFileName() + .getDisplayIconFileName(model.getStore().getValue()) : null; }, model.getStore()); diff --git a/app/src/main/java/io/xpipe/app/browser/FileListComp.java b/app/src/main/java/io/xpipe/app/browser/FileListComp.java index aa77e162..b05be15e 100644 --- a/app/src/main/java/io/xpipe/app/browser/FileListComp.java +++ b/app/src/main/java/io/xpipe/app/browser/FileListComp.java @@ -204,9 +204,9 @@ final class FileListComp extends AnchorPane { } newItems.addAll(newValue); table.getItems().setAll(newItems); - if (newValue.size() > 0) { - table.scrollTo(0); - } +// if (newValue.size() > 0) { +// table.scrollTo(0); +// } }); }); diff --git a/app/src/main/java/io/xpipe/app/browser/FileSystemHelper.java b/app/src/main/java/io/xpipe/app/browser/FileSystemHelper.java index 45072151..ea2bc111 100644 --- a/app/src/main/java/io/xpipe/app/browser/FileSystemHelper.java +++ b/app/src/main/java/io/xpipe/app/browser/FileSystemHelper.java @@ -4,6 +4,7 @@ import io.xpipe.app.issue.ErrorEvent; import io.xpipe.core.impl.FileNames; import io.xpipe.core.impl.LocalStore; import io.xpipe.core.process.OsType; +import io.xpipe.core.store.ConnectionFileSystem; import io.xpipe.core.store.FileSystem; import java.nio.file.Files; @@ -13,7 +14,25 @@ import java.util.List; public class FileSystemHelper { - public static String normalizeDirectoryPath(OpenFileSystemModel model, String path) { + public static String getStartDirectory(OpenFileSystemModel model) throws Exception { + // Handle special case when file system creation has failed + if (model.getFileSystem() == null) { + return null; + } + + ConnectionFileSystem fileSystem = (ConnectionFileSystem) model.getFileSystem(); + var current = !(model.getStore().getValue() instanceof LocalStore) + ? fileSystem + .getShellControl() + .executeStringSimpleCommand(fileSystem + .getShellControl() + .getShellDialect() + .getPrintWorkingDirectoryCommand()) + : fileSystem.getShell().get().getOsType().getHomeDirectory(fileSystem.getShell().get()); + return FileSystemHelper.normalizeDirectoryPath(model, current); + } + + public static String normalizeDirectoryPath(OpenFileSystemModel model, String path) throws Exception { if (path == null) { return null; } @@ -37,7 +56,11 @@ public class FileSystemHelper { return path + "\\"; } - return FileNames.toDirectory(path); + var normalized = shell.get() + .getShellDialect() + .normalizeDirectory(shell.get(), path) + .readOrThrow(); + return FileNames.toDirectory(normalized); } public static FileSystem.FileEntry getLocal(Path file) throws Exception { diff --git a/app/src/main/java/io/xpipe/app/browser/OpenFileSystemModel.java b/app/src/main/java/io/xpipe/app/browser/OpenFileSystemModel.java index 1f44c499..57165a92 100644 --- a/app/src/main/java/io/xpipe/app/browser/OpenFileSystemModel.java +++ b/app/src/main/java/io/xpipe/app/browser/OpenFileSystemModel.java @@ -7,7 +7,6 @@ import io.xpipe.app.util.BusyProperty; import io.xpipe.app.util.TerminalHelper; import io.xpipe.app.util.ThreadHelper; import io.xpipe.core.impl.FileNames; -import io.xpipe.core.impl.LocalStore; import io.xpipe.core.store.ConnectionFileSystem; import io.xpipe.core.store.FileSystem; import io.xpipe.core.store.FileSystemStore; @@ -76,7 +75,14 @@ final class OpenFileSystemModel { } public Optional cd(String path) { - var newPath = FileSystemHelper.normalizeDirectoryPath(this, path); + String newPath = null; + try { + newPath = FileSystemHelper.normalizeDirectoryPath(this, path); + } catch (Exception ex) { + ErrorEvent.fromThrowable(ex).handle(); + return Optional.of(currentPath.get()); + } + if (!Objects.equals(path, newPath)) { return Optional.of(newPath); } @@ -96,7 +102,8 @@ final class OpenFileSystemModel { this.fileSystem = fs; } - path = FileSystemHelper.normalizeDirectoryPath(this, path); + // Assumed that the path is normalized to improve performance! + // path = FileSystemHelper.normalizeDirectoryPath(this, path); navigateToSync(path); filter.setValue(null); @@ -218,14 +225,7 @@ final class OpenFileSystemModel { fs.open(); this.fileSystem = fs; - var current = !(fileSystem instanceof LocalStore) && fs instanceof ConnectionFileSystem connectionFileSystem - ? connectionFileSystem - .getShellControl() - .executeStringSimpleCommand(connectionFileSystem - .getShellControl() - .getShellDialect() - .getPrintWorkingDirectoryCommand()) - : null; + var current = FileSystemHelper.getStartDirectory(this); cdSync(current); } diff --git a/app/src/main/java/io/xpipe/app/comp/source/store/DataStoreSelectorComp.java b/app/src/main/java/io/xpipe/app/comp/source/store/DataStoreSelectorComp.java index af4f27dd..9dc99db3 100644 --- a/app/src/main/java/io/xpipe/app/comp/source/store/DataStoreSelectorComp.java +++ b/app/src/main/java/io/xpipe/app/comp/source/store/DataStoreSelectorComp.java @@ -56,7 +56,7 @@ public class DataStoreSelectorComp extends Comp> { ? DataStoreProviders.byStoreClass(chosenStore.getValue().getClass()) .orElse(null) : null; - var graphic = provider != null ? provider.getDisplayIconFileName() : "file_icon.png"; + var graphic = provider != null ? provider.getDisplayIconFileName(chosenStore.getValue()) : "file_icon.png"; if (chosenStore.getValue() == null || !(chosenStore.getValue() instanceof FileStore f)) { return JfxHelper.createNamedEntry( AppI18n.get("selectStreamStore"), AppI18n.get("openStreamStoreWizard"), graphic); diff --git a/app/src/main/java/io/xpipe/app/comp/source/store/DsStoreProviderChoiceComp.java b/app/src/main/java/io/xpipe/app/comp/source/store/DsStoreProviderChoiceComp.java index 6ac44d45..033f628a 100644 --- a/app/src/main/java/io/xpipe/app/comp/source/store/DsStoreProviderChoiceComp.java +++ b/app/src/main/java/io/xpipe/app/comp/source/store/DsStoreProviderChoiceComp.java @@ -43,7 +43,7 @@ public class DsStoreProviderChoiceComp extends Comp return createDefaultNode(); } - var graphic = provider.getDisplayIconFileName(); + var graphic = provider.getDisplayIconFileName(null); return JfxHelper.createNamedEntry(provider.getDisplayName(), provider.getDisplayDescription(), graphic); } diff --git a/app/src/main/java/io/xpipe/app/comp/source/store/NamedStoreChoiceComp.java b/app/src/main/java/io/xpipe/app/comp/source/store/NamedStoreChoiceComp.java index 1f03672f..0b6c08cc 100644 --- a/app/src/main/java/io/xpipe/app/comp/source/store/NamedStoreChoiceComp.java +++ b/app/src/main/java/io/xpipe/app/comp/source/store/NamedStoreChoiceComp.java @@ -125,7 +125,7 @@ public class NamedStoreChoiceComp extends SimpleComp implements Validatable { var view = new ListViewComp<>(shown, list, prop, (DataStoreEntry e) -> { var provider = e.getProvider(); - var graphic = provider.getDisplayIconFileName(); + var graphic = provider.getDisplayIconFileName(e.getStore()); var top = String.format("%s (%s)", e.getName(), provider.getDisplayName()); var bottom = provider.toSummaryString(e.getStore(), 50); var el = JfxHelper.createNamedEntry(top, bottom, graphic); diff --git a/app/src/main/java/io/xpipe/app/comp/storage/store/StoreEntryComp.java b/app/src/main/java/io/xpipe/app/comp/storage/store/StoreEntryComp.java index 1a54cdce..28ea1250 100644 --- a/app/src/main/java/io/xpipe/app/comp/storage/store/StoreEntryComp.java +++ b/app/src/main/java/io/xpipe/app/comp/storage/store/StoreEntryComp.java @@ -98,7 +98,7 @@ public class StoreEntryComp extends SimpleComp { private Node createIcon() { var img = entry.isDisabled() ? "disabled_icon.png" - : entry.getEntry().getProvider().getDisplayIconFileName(); + : entry.getEntry().getProvider().getDisplayIconFileName(entry.getEntry().getStore()); var imageComp = new PrettyImageComp(new SimpleStringProperty(img), 55, 45); var storeIcon = imageComp.createRegion(); storeIcon.getStyleClass().add("icon"); diff --git a/app/src/main/java/io/xpipe/app/comp/storage/store/StoreEntryFlatMiniSection.java b/app/src/main/java/io/xpipe/app/comp/storage/store/StoreEntryFlatMiniSection.java index 9a2e721d..f7e5a4ca 100644 --- a/app/src/main/java/io/xpipe/app/comp/storage/store/StoreEntryFlatMiniSection.java +++ b/app/src/main/java/io/xpipe/app/comp/storage/store/StoreEntryFlatMiniSection.java @@ -41,7 +41,9 @@ public class StoreEntryFlatMiniSection extends SimpleComp { @Override protected Region createSimple() { - var image = entry.getState() == DataStoreEntry.State.LOAD_FAILED ? "disabled_icon.png" : entry.getProvider().getDisplayIconFileName(); + var image = entry.getState() == DataStoreEntry.State.LOAD_FAILED + ? "disabled_icon.png" + : entry.getProvider().getDisplayIconFileName(entry.getStore()); var label = new Label(entry.getName(), new PrettyImageComp(new SimpleStringProperty(image), 20, 20).createRegion()); var spacer = new Spacer(depth * 10, Orientation.HORIZONTAL); var box = new HBox(spacer, label); diff --git a/app/src/main/java/io/xpipe/app/ext/DataStoreProvider.java b/app/src/main/java/io/xpipe/app/ext/DataStoreProvider.java index 08a5b665..f62cbd08 100644 --- a/app/src/main/java/io/xpipe/app/ext/DataStoreProvider.java +++ b/app/src/main/java/io/xpipe/app/ext/DataStoreProvider.java @@ -100,7 +100,7 @@ public interface DataStoreProvider { return i != -1 ? n.substring(i + 1) : n; } - default String getDisplayIconFileName() { + default String getDisplayIconFileName(DataStore store) { return getModuleName() + ":" + getId() + "_icon.png"; } diff --git a/app/src/main/java/io/xpipe/app/fxcomps/impl/FileSystemStoreChoiceComp.java b/app/src/main/java/io/xpipe/app/fxcomps/impl/FileSystemStoreChoiceComp.java index 7a86644a..88c6f95f 100644 --- a/app/src/main/java/io/xpipe/app/fxcomps/impl/FileSystemStoreChoiceComp.java +++ b/app/src/main/java/io/xpipe/app/fxcomps/impl/FileSystemStoreChoiceComp.java @@ -34,13 +34,13 @@ public class FileSystemStoreChoiceComp extends SimpleComp { private Region createGraphic(FileSystemStore s) { var provider = DataStoreProviders.byStore(s); - var img = new PrettyImageComp(new SimpleStringProperty(provider.getDisplayIconFileName()), 16, 16); + var img = new PrettyImageComp(new SimpleStringProperty(provider.getDisplayIconFileName(s)), 16, 16); return new Label(getName(s), img.createRegion()); } private Region createDisplayGraphic(FileSystemStore s) { var provider = DataStoreProviders.byStore(s); - var img = new PrettyImageComp(new SimpleStringProperty(provider.getDisplayIconFileName()), 16, 16); + var img = new PrettyImageComp(new SimpleStringProperty(provider.getDisplayIconFileName(s)), 16, 16); return new Label(null, img.createRegion()); } diff --git a/app/src/main/java/io/xpipe/app/fxcomps/impl/ShellStoreChoiceComp.java b/app/src/main/java/io/xpipe/app/fxcomps/impl/ShellStoreChoiceComp.java index d2934630..e5ad6380 100644 --- a/app/src/main/java/io/xpipe/app/fxcomps/impl/ShellStoreChoiceComp.java +++ b/app/src/main/java/io/xpipe/app/fxcomps/impl/ShellStoreChoiceComp.java @@ -54,7 +54,7 @@ public class ShellStoreChoiceComp extends SimpleComp { protected Region createGraphic(T s) { var provider = DataStoreProviders.byStore(s); var imgView = - new PrettyImageComp(new SimpleStringProperty(provider.getDisplayIconFileName()), 16, 16).createRegion(); + new PrettyImageComp(new SimpleStringProperty(provider.getDisplayIconFileName(s)), 16, 16).createRegion(); var name = DataStorage.get().getUsableStores().stream() .filter(e -> e.equals(s)) diff --git a/core/src/main/java/io/xpipe/core/charsetter/StreamCharset.java b/core/src/main/java/io/xpipe/core/charsetter/StreamCharset.java index 26d43e00..828b9013 100644 --- a/core/src/main/java/io/xpipe/core/charsetter/StreamCharset.java +++ b/core/src/main/java/io/xpipe/core/charsetter/StreamCharset.java @@ -3,6 +3,9 @@ package io.xpipe.core.charsetter; import io.xpipe.core.util.Identifiers; import lombok.Value; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.Reader; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; import java.util.Arrays; @@ -117,6 +120,17 @@ public class StreamCharset { byte[] byteOrderMark; List names; + public Reader reader(InputStream stream) throws Exception { + if (hasByteOrderMark()) { + var bom = stream.readNBytes(getByteOrderMark().length); + if (bom.length != 0 && !Arrays.equals(bom, getByteOrderMark())) { + throw new IllegalStateException("Charset does not match: " + charset.toString()); + } + } + + return new InputStreamReader(stream, charset); + } + public static StreamCharset get(Charset charset, boolean byteOrderMark) { return ALL.stream() .filter(streamCharset -> diff --git a/core/src/main/java/io/xpipe/core/process/ProcessControl.java b/core/src/main/java/io/xpipe/core/process/ProcessControl.java index ec23cd66..4fa3ad73 100644 --- a/core/src/main/java/io/xpipe/core/process/ProcessControl.java +++ b/core/src/main/java/io/xpipe/core/process/ProcessControl.java @@ -9,6 +9,8 @@ import java.util.concurrent.ExecutorService; public interface ProcessControl extends Closeable, AutoCloseable { + void resetData(); + ExecutorService getStdoutReader(); ExecutorService getStderrReader(); diff --git a/core/src/main/java/io/xpipe/core/process/ShellDialect.java b/core/src/main/java/io/xpipe/core/process/ShellDialect.java index d055ffaa..5bca7da1 100644 --- a/core/src/main/java/io/xpipe/core/process/ShellDialect.java +++ b/core/src/main/java/io/xpipe/core/process/ShellDialect.java @@ -2,6 +2,7 @@ package io.xpipe.core.process; import com.fasterxml.jackson.annotation.JsonTypeInfo; import io.xpipe.core.charsetter.NewLine; +import io.xpipe.core.charsetter.StreamCharset; import io.xpipe.core.store.FileSystem; import java.nio.charset.Charset; @@ -13,6 +14,12 @@ import java.util.stream.Stream; @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type") public interface ShellDialect { + default StreamCharset getTextFileCharset(ShellControl sc) { + return StreamCharset.get(sc.getCharset(), false); + } + + CommandControl normalizeDirectory(ShellControl shellControl, String directory); + String fileArgument(String s); default String applyRcFileCommand() { @@ -91,6 +98,10 @@ public interface ShellDialect { String prepareInitFileOpenCommand(ShellControl parent, String file); + String runScript(String file); + + String sourceScript(String file); + String executeCommandWithShell(String cmd); String getMkdirsCommand(String dirs); diff --git a/ext/base/src/main/java/io/xpipe/ext/base/LocalStoreProvider.java b/ext/base/src/main/java/io/xpipe/ext/base/LocalStoreProvider.java deleted file mode 100644 index 3dc4a861..00000000 --- a/ext/base/src/main/java/io/xpipe/ext/base/LocalStoreProvider.java +++ /dev/null @@ -1,71 +0,0 @@ -package io.xpipe.ext.base; - -import io.xpipe.app.ext.DataStoreProvider; -import io.xpipe.app.storage.DataStorage; -import io.xpipe.app.storage.DataStoreEntry; -import io.xpipe.app.storage.StorageElement; -import io.xpipe.core.impl.LocalStore; -import io.xpipe.core.process.OsType; -import io.xpipe.core.store.DataStore; - -import java.util.List; -import java.util.UUID; - -public class LocalStoreProvider implements DataStoreProvider { - - @Override - public String queryInformationString(DataStore store, int length) throws Exception { - try (var pc = LocalStore.getShell().start()) { - return OsType.getLocal().determineOperatingSystemName(pc); - } - } - - @Override - public String toSummaryString(DataStore store, int length) { - return "localhost"; - } - - @Override - public boolean shouldShow() { - return false; - } - - @Override - public void storageInit() throws Exception { - var hasLocal = DataStorage.get().getUsableStores().stream() - .anyMatch(dataStore -> dataStore instanceof LocalStore); - if (hasLocal) { - return; - } - - var e = DataStoreEntry.createNew(UUID.randomUUID(), "Local Machine", new LocalStore()); - DataStorage.get().addStoreEntry(e); - e.setConfiguration(StorageElement.Configuration.builder() - .deletable(false) - .editable(false) - .refreshable(true) - .renameable(false) - .build()); - e.refresh(true); - } - - @Override - public DataStore defaultStore() { - return new LocalStore(); - } - - @Override - public String getDisplayName() { - return null; - } - - @Override - public List getPossibleNames() { - return List.of("local", "localhost"); - } - - @Override - public List> getStoreClasses() { - return List.of(LocalStore.class); - } -} diff --git a/ext/base/src/main/java/module-info.java b/ext/base/src/main/java/module-info.java index e93d2492..0cd23a0f 100644 --- a/ext/base/src/main/java/module-info.java +++ b/ext/base/src/main/java/module-info.java @@ -44,7 +44,6 @@ open module io.xpipe.ext.base { provides DataStoreProvider with SinkDrainStoreProvider, HttpStoreProvider, - LocalStoreProvider, InternalStreamProvider, FileStoreProvider, InMemoryStoreProvider; diff --git a/ext/base/src/main/resources/io/xpipe/ext/base/resources/img/cmd.png b/ext/base/src/main/resources/io/xpipe/ext/base/resources/img/cmd.png deleted file mode 100644 index cc7a2bd8193a382932cde445a1ad1d5cdd5c4923..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1653 zcmb7_|3A}-1ILvw3A@E=)o^M~avx#L#BTYLjcvZpXdA;VU)$%hg=CX0%P7s=rEIME zM0TvO@+HKzT<1%ac$e?Wm$D{4j+;7C=llns$LH~QzFyB?UcbLCg#`J5j9^AOIyxY{ zzb|Rat6S+e)ZOZ1yQX$*i5n6?#%_6YbCbv8$>s93wKYRS!=9d=<>h4tgTZ7n)oOJ? zLBZ(gXklR?7K_zrG;M8d=H}*9DiwplNFKwe zC+q9$!^6W-D3nYlgFqkxfk2^9yng+f#bRY zQ;VV44*JJ`eSvbE|2~>U^gC1PInN__=9cBfECmD4%M)j$LwT#|8vI&E`5tM7B67|2GjvB0v^YWpLtSnn$2rB0j)o{+(DGoRY!gC=E7VROdB^T0(xgnUnT+ zGMB=6WS^1P9Lss|OrH7|!m3@oW@3DctQ>wa!LY~JjaM^Qk7N(vRvJ;)ACCO+66!u~ zdWB>$H6sKtNw32g-lrsr{^-~;XVaIX5S6pWWzhu>H zXwd4x3C-a-VyA`6ygqq7Rw;tL0o)!&T|pG#Jb~%sqU=id>}rg^cH{QhOzr}3JnQ8h zxBX#HD_4;GY%b}l(VGk|vdzO8;%Dvkl-^yWdWX}Q1kS;CzacU8F8cCdxQal zZWs58PDzfj4xoDUjqo5#j6b=P?4gT7zfD@cbTXuw59)gU;!`R#tIGp1gj)#!m-q$Y za!sac-kwW7ILhCQ&k3_}YS~y{pZT$8dU1yP5~7;88hksK-|#AOGkZ)I3}A8HK|B^^ zC2%|8ZcJt575{>?0@Hb`3VT%xCb~&t9i0RL!7YvdCv^a^Mj${J0)6%4A;T^B{}fb3 zU;1ShY&);aL9}<|A{+ou?3uuZvp@CkG58He8XhI?y?pRqH0B|N$ke}S^NRZ2z3T>8 zWgu;_m&7q4dcYcsrSes%q7dtGxrDLtG1_{#t_&&Fi^TF;aTw z@r+up!C~GzPT2Q@rd=@{1hz=6EH|sU*s-hGkGL2mZiJ@(hREm37I;XPJEkM7!LRRq z9hFU`+|U(B((%pi=7tsJ`L5a_e>C)~|Kb_9=~Y>D$4yDsH{tg^#4^A`v;?XTZAP96qs+34BI2s!Jws z1@^lAUfN=|jg}g)6e^DKVhW#N{w#$gJ#%dJi%HV09kcoCRJFq_uWsS6f{{WeTJCSR zo{OgkuUK3;aF6hI7!DFEX48KpS7AT>{+z4oC|+fK z1PvC)KrQwrKP`#h8q3-G?1v$S=pN2RO4a2>`MZ3r+-oOLtKokb(MxurZ2|?o8EZ`) zpRylCz?jqv()RbrC>R@McnujjUO#tt3~;)gviorIePsTERG$EIsKsW1bZr8~4iu>Y z0p=)cKz(%$8S^Qz!A$FgH?CB{ReQe8OOk(?5|&ZPpNH~J6S})RcE8)_PCX!{{n_n` zyB|B58e!DdYh{(6X8->Z)m{DTiHU)*<>$VxvBo=32``USu%dg&0KeFsHhgKe$*c?< zVFeh_QMDCCH!53Gq~3kW<%LDasd$RU-ECW$ylAjf-FnvPTwu1m=o^^`eI)U_jnlRp Y;7=HewnT|`-ue$6JT}O;&L=kKAM!2>5&!@I diff --git a/ext/base/src/main/resources/io/xpipe/ext/base/resources/img/local_icon.png b/ext/base/src/main/resources/io/xpipe/ext/base/resources/img/local_icon.png deleted file mode 100644 index 6682cd80a2aa696fb3a0ab73b71c82761587f67c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 14068 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 R-e#k^cIEozqDzSA{{yY3pacK_ diff --git a/ext/base/src/main/resources/io/xpipe/ext/base/resources/img/powershell.png b/ext/base/src/main/resources/io/xpipe/ext/base/resources/img/powershell.png deleted file mode 100644 index e7d5081119e029a2689e79c711c3e937e936e9f9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 19994 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 I^}A313wRVEr2qf`