From 6920774e64e4012b087eca595af86839bb515c61 Mon Sep 17 00:00:00 2001 From: gewuyou <1063891901@qq.com> Date: Tue, 10 Oct 2023 14:07:44 +0800 Subject: [PATCH] =?UTF-8?q?=F0=9F=9A=A9=20=E5=AE=8C=E5=96=84=E6=96=87?= =?UTF-8?q?=E4=BB=B6=E5=9B=BE=E6=A0=87=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- .../jnotepad/app/i18n/UiResourceBundle.java | 2 +- .../app/manager/ApplicationManager.java | 2 +- .../common/constants/AppConstants.java | 2 +- .../component/module/TextCodeArea.java | 2 +- .../jnotepad/model/entity/DirFileModel.java | 17 ++- .../java/org/jcnc/jnotepad/util/FileUtil.java | 20 ++-- .../org/jcnc/jnotepad/util/ResourceUtil.java | 70 +++++++++++++ .../java/org/jcnc/jnotepad/util/UiUtil.java | 97 ++++++++++++++++++ .../views/manager/SidebarToolBarManager.java | 9 +- .../{ => jcnc/app}/css/java_code_styles.css | 0 .../resources/{ => jcnc/app}/css/styles.css | 0 .../{ => jcnc/app}/i18n/i18n.properties | 0 .../{ => jcnc/app}/i18n/i18n_en.properties | 0 .../{ => jcnc/app}/i18n/i18n_zh_CN.properties | 0 .../app/images/appIcons}/JCNC.png | Bin .../app/images/appIcons}/icon.icns | 0 .../app/images/appIcons}/icon.ico | Bin .../app/images/appIcons}/icon.png | Bin .../jcnc/app/images/fileIcons/bat.png | Bin 0 -> 424 bytes .../resources/jcnc/app/images/fileIcons/c.png | Bin 0 -> 309 bytes .../jcnc/app/images/fileIcons/cplusplus.png | Bin 0 -> 694 bytes .../jcnc/app/images/fileIcons/csharp.png | Bin 0 -> 498 bytes .../jcnc/app/images/fileIcons/css.png | Bin 0 -> 598 bytes .../jcnc/app/images/fileIcons/database.png | Bin 0 -> 494 bytes .../jcnc/app/images/fileIcons/dll.png | Bin 0 -> 256 bytes .../jcnc/app/images/fileIcons/doc.png | Bin 0 -> 513 bytes .../jcnc/app/images/fileIcons/exe.png | Bin 0 -> 361 bytes .../jcnc/app/images/fileIcons/gif.png | Bin 0 -> 300 bytes .../jcnc/app/images/fileIcons/git.png | Bin 0 -> 369 bytes .../jcnc/app/images/fileIcons/golang.png | Bin 0 -> 246 bytes .../jcnc/app/images/fileIcons/html.png | Bin 0 -> 596 bytes .../jcnc/app/images/fileIcons/java.png | Bin 0 -> 442 bytes .../jcnc/app/images/fileIcons/js.png | Bin 0 -> 398 bytes .../jcnc/app/images/fileIcons/json.png | Bin 0 -> 229 bytes .../jcnc/app/images/fileIcons/kotlin.png | Bin 0 -> 625 bytes .../jcnc/app/images/fileIcons/lua.png | Bin 0 -> 369 bytes .../jcnc/app/images/fileIcons/markdown.png | Bin 0 -> 382 bytes .../jcnc/app/images/fileIcons/php.png | Bin 0 -> 384 bytes .../jcnc/app/images/fileIcons/png.png | Bin 0 -> 326 bytes .../jcnc/app/images/fileIcons/python.png | Bin 0 -> 610 bytes .../jcnc/app/images/fileIcons/ruby.png | Bin 0 -> 407 bytes .../jcnc/app/images/fileIcons/sh.png | Bin 0 -> 334 bytes .../jcnc/app/images/fileIcons/svg.png | Bin 0 -> 302 bytes .../jcnc/app/images/fileIcons/txt.png | Bin 0 -> 274 bytes .../jcnc/app/images/fileIcons/xml.png | Bin 0 -> 540 bytes .../app/images/sidebarIcons}/cmd.png | Bin .../app/images/sidebarIcons}/directory.png | Bin .../app/images/sidebarIcons}/tools.gif | Bin .../app/images/sidebarIcons}/tools.png | Bin .../resources/{img => jcnc/app/svg}/icon.svg | 0 tool/jpackage.sh | 2 +- tool/jpackage.txt | 2 +- 53 files changed, 197 insertions(+), 30 deletions(-) create mode 100644 src/main/java/org/jcnc/jnotepad/util/ResourceUtil.java rename src/main/resources/{ => jcnc/app}/css/java_code_styles.css (100%) rename src/main/resources/{ => jcnc/app}/css/styles.css (100%) rename src/main/resources/{ => jcnc/app}/i18n/i18n.properties (100%) rename src/main/resources/{ => jcnc/app}/i18n/i18n_en.properties (100%) rename src/main/resources/{ => jcnc/app}/i18n/i18n_zh_CN.properties (100%) rename src/main/resources/{img => jcnc/app/images/appIcons}/JCNC.png (100%) rename src/main/resources/{img => jcnc/app/images/appIcons}/icon.icns (100%) rename src/main/resources/{img => jcnc/app/images/appIcons}/icon.ico (100%) rename src/main/resources/{img => jcnc/app/images/appIcons}/icon.png (100%) create mode 100644 src/main/resources/jcnc/app/images/fileIcons/bat.png create mode 100644 src/main/resources/jcnc/app/images/fileIcons/c.png create mode 100644 src/main/resources/jcnc/app/images/fileIcons/cplusplus.png create mode 100644 src/main/resources/jcnc/app/images/fileIcons/csharp.png create mode 100644 src/main/resources/jcnc/app/images/fileIcons/css.png create mode 100644 src/main/resources/jcnc/app/images/fileIcons/database.png create mode 100644 src/main/resources/jcnc/app/images/fileIcons/dll.png create mode 100644 src/main/resources/jcnc/app/images/fileIcons/doc.png create mode 100644 src/main/resources/jcnc/app/images/fileIcons/exe.png create mode 100644 src/main/resources/jcnc/app/images/fileIcons/gif.png create mode 100644 src/main/resources/jcnc/app/images/fileIcons/git.png create mode 100644 src/main/resources/jcnc/app/images/fileIcons/golang.png create mode 100644 src/main/resources/jcnc/app/images/fileIcons/html.png create mode 100644 src/main/resources/jcnc/app/images/fileIcons/java.png create mode 100644 src/main/resources/jcnc/app/images/fileIcons/js.png create mode 100644 src/main/resources/jcnc/app/images/fileIcons/json.png create mode 100644 src/main/resources/jcnc/app/images/fileIcons/kotlin.png create mode 100644 src/main/resources/jcnc/app/images/fileIcons/lua.png create mode 100644 src/main/resources/jcnc/app/images/fileIcons/markdown.png create mode 100644 src/main/resources/jcnc/app/images/fileIcons/php.png create mode 100644 src/main/resources/jcnc/app/images/fileIcons/png.png create mode 100644 src/main/resources/jcnc/app/images/fileIcons/python.png create mode 100644 src/main/resources/jcnc/app/images/fileIcons/ruby.png create mode 100644 src/main/resources/jcnc/app/images/fileIcons/sh.png create mode 100644 src/main/resources/jcnc/app/images/fileIcons/svg.png create mode 100644 src/main/resources/jcnc/app/images/fileIcons/txt.png create mode 100644 src/main/resources/jcnc/app/images/fileIcons/xml.png rename src/main/resources/{ => jcnc/app/images/sidebarIcons}/cmd.png (100%) rename src/main/resources/{ => jcnc/app/images/sidebarIcons}/directory.png (100%) rename src/main/resources/{ => jcnc/app/images/sidebarIcons}/tools.gif (100%) rename src/main/resources/{ => jcnc/app/images/sidebarIcons}/tools.png (100%) rename src/main/resources/{img => jcnc/app/svg}/icon.svg (100%) diff --git a/README.md b/README.md index 78c11e8..752e774 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@

- JNotepad Icon + JNotepad Icon

JNotepad

JavaFX开发,插件驱动,创造无限可能

diff --git a/src/main/java/org/jcnc/jnotepad/app/i18n/UiResourceBundle.java b/src/main/java/org/jcnc/jnotepad/app/i18n/UiResourceBundle.java index 945f872..bf6245b 100644 --- a/src/main/java/org/jcnc/jnotepad/app/i18n/UiResourceBundle.java +++ b/src/main/java/org/jcnc/jnotepad/app/i18n/UiResourceBundle.java @@ -21,7 +21,7 @@ public class UiResourceBundle { /** * resource目录下的i18n/i18nXXX.properties */ - private static final String BASENAME = "i18n/i18n"; + private static final String BASENAME = "jcnc/app/i18n/i18n"; /** * 资源文件的观察者绑定。 */ diff --git a/src/main/java/org/jcnc/jnotepad/app/manager/ApplicationManager.java b/src/main/java/org/jcnc/jnotepad/app/manager/ApplicationManager.java index 1a43139..c3238b1 100644 --- a/src/main/java/org/jcnc/jnotepad/app/manager/ApplicationManager.java +++ b/src/main/java/org/jcnc/jnotepad/app/manager/ApplicationManager.java @@ -106,7 +106,7 @@ public class ApplicationManager { double width = AppConstants.SCREEN_WIDTH; double length = AppConstants.SCREEN_LENGTH; scene = new Scene(root, width, length); - scene.getStylesheets().add(Objects.requireNonNull(application.getClass().getResource("/css/styles.css")).toExternalForm()); + scene.getStylesheets().add(Objects.requireNonNull(application.getClass().getResource("/jcnc/app/css/styles.css")).toExternalForm()); } private void initPrimaryStage() { diff --git a/src/main/java/org/jcnc/jnotepad/common/constants/AppConstants.java b/src/main/java/org/jcnc/jnotepad/common/constants/AppConstants.java index 69a7a19..6419719 100644 --- a/src/main/java/org/jcnc/jnotepad/common/constants/AppConstants.java +++ b/src/main/java/org/jcnc/jnotepad/common/constants/AppConstants.java @@ -33,7 +33,7 @@ public class AppConstants { /** * logo地址 */ - public static final String APP_ICON = "/img/icon.png"; + public static final String APP_ICON = "/jcnc/app/images/appIcons/icon.png"; /** * 默认标签页的正则 diff --git a/src/main/java/org/jcnc/jnotepad/component/module/TextCodeArea.java b/src/main/java/org/jcnc/jnotepad/component/module/TextCodeArea.java index 451958f..3a36ae3 100644 --- a/src/main/java/org/jcnc/jnotepad/component/module/TextCodeArea.java +++ b/src/main/java/org/jcnc/jnotepad/component/module/TextCodeArea.java @@ -107,7 +107,7 @@ public class TextCodeArea extends CodeArea { } } }); - this.getStylesheets().add(Objects.requireNonNull(getClass().getResource("/css/java_code_styles.css")).toString()); + this.getStylesheets().add(Objects.requireNonNull(getClass().getResource("/jcnc/app/css/java_code_styles.css")).toString()); } diff --git a/src/main/java/org/jcnc/jnotepad/model/entity/DirFileModel.java b/src/main/java/org/jcnc/jnotepad/model/entity/DirFileModel.java index 0d65f28..f7c11b4 100644 --- a/src/main/java/org/jcnc/jnotepad/model/entity/DirFileModel.java +++ b/src/main/java/org/jcnc/jnotepad/model/entity/DirFileModel.java @@ -1,5 +1,6 @@ package org.jcnc.jnotepad.model.entity; +import javafx.scene.Node; import org.kordamp.ikonli.javafx.FontIcon; import java.util.List; @@ -16,9 +17,9 @@ public class DirFileModel { private String path; private String name; - private FontIcon iconIsNotSelected; + private Node iconIsNotSelected; - private FontIcon iconIsSelected; + private Node iconIsSelected; private List childFile; @@ -31,6 +32,14 @@ public class DirFileModel { this.iconIsSelected = iconIsSelected; } + public DirFileModel(String path, String name, List childFile, Node iconIsNotSelected, Node iconIsSelected) { + this.path = path; + this.name = name; + this.childFile = childFile; + this.iconIsNotSelected = iconIsNotSelected; + this.iconIsSelected = iconIsSelected; + } + public List getChildFile() { return childFile; @@ -57,7 +66,7 @@ public class DirFileModel { return name; } - public FontIcon getIconIsNotSelected() { + public Node getIconIsNotSelected() { return iconIsNotSelected; } @@ -65,7 +74,7 @@ public class DirFileModel { this.iconIsNotSelected = iconIsNotSelected; } - public FontIcon getIconIsSelected() { + public Node getIconIsSelected() { return iconIsSelected; } diff --git a/src/main/java/org/jcnc/jnotepad/util/FileUtil.java b/src/main/java/org/jcnc/jnotepad/util/FileUtil.java index ba0709a..5df4111 100644 --- a/src/main/java/org/jcnc/jnotepad/util/FileUtil.java +++ b/src/main/java/org/jcnc/jnotepad/util/FileUtil.java @@ -158,7 +158,7 @@ public class FileUtil { dirFileModel.getChildFile().add(childDirFileModel); } else { // todo 在此监测文件后缀,设置对应的图标 - dirFileModel.getChildFile().add(new DirFileModel(f.getAbsolutePath(), f.getName(), null, new FontIcon(FILE), new FontIcon(FILE))); + dirFileModel.getChildFile().add(new DirFileModel(f.getAbsolutePath(), f.getName(), null, getIconCorrespondingToFileName(f.getName()), new FontIcon(FILE))); } } } @@ -293,21 +293,13 @@ public class FileUtil { /** * Retrieves the icon corresponding to the given file name. * - * @param tabTitle the title of the tab - * @return the icon node corresponding to the file name + * @param fileName the file name + * @return the corresponding icon for the file extension */ - public static Node getIconCorrespondingToFileName(String tabTitle) { + public static Node getIconCorrespondingToFileName(String fileName) { // todo 在此根据文件缀名获取对应的图标 - String fileExtension = tabTitle.substring(tabTitle.lastIndexOf(".") + 1); - return switch (fileExtension.toLowerCase()) { - case "txt" -> FontIcon.of(FILE_TEXT); - case "doc" -> FontIcon.of(FILE_WORD); - case "pdf" -> FontIcon.of(FILE_PDF); - case "ppt" -> FontIcon.of(FILE_PPT); - case "xls" -> FontIcon.of(FILE_EXCEL); - case "md" -> FontIcon.of(FILE_MARKDOWN); - default -> FontIcon.of(FILE_UNKNOWN); - }; + String fileExtension = fileName.substring(fileName.lastIndexOf(".") + 1); + return UiUtil.getIconMap().getOrDefault(fileExtension, FontIcon.of(FILE_UNKNOWN)); } } diff --git a/src/main/java/org/jcnc/jnotepad/util/ResourceUtil.java b/src/main/java/org/jcnc/jnotepad/util/ResourceUtil.java new file mode 100644 index 0000000..ee7f7c0 --- /dev/null +++ b/src/main/java/org/jcnc/jnotepad/util/ResourceUtil.java @@ -0,0 +1,70 @@ +package org.jcnc.jnotepad.util; + +import org.jcnc.jnotepad.JnotepadApp; + +import java.io.InputStream; +import java.net.URI; +import java.net.URL; +import java.util.Objects; + +/** + * 资源工具 + * + * @author gewuyou + */ +public class ResourceUtil { + public static final String MODULE_DIR = "/jcnc/app/"; + + private ResourceUtil() { + } + + /** + * Retrieves an input stream for the specified resource. + * + * @param resource the path to the resource + * @return the input stream for the resource + */ + public static InputStream getResourceAsStream(String resource) { + String path = resolve(resource); + return Objects.requireNonNull( + JnotepadApp.class.getResourceAsStream(resolve(path)), + "Resource not found: " + path + ); + } + + /** + * Retrieves the resource with the specified path. + * + * @param resource the path of the resource to retrieve + * @return the URI of the retrieved resource + */ + public static URI getResource(String resource) { + String path = resolve(resource); + URL url = Objects.requireNonNull(JnotepadApp.class.getResource(resolve(path)), "Resource not found: " + path); + return URI.create(url.toExternalForm()); + } + + /** + * Resolves a resource path by checking if it starts with a "/". If it does, + * the resource path is returned as is. If it doesn't, the resource path is + * concatenated with the module directory path. + * + * @param resource the resource path to be resolved + * @param moduleDir the module directory path + * @return the resolved resource path + */ + public static String resolve(String resource, String moduleDir) { + Objects.requireNonNull(resource); + return resource.startsWith("/") ? resource : moduleDir + resource; + } + + /** + * Resolve the given resource using the default module directory. + * + * @param resource the resource to resolve + * @return the resolved resource + */ + public static String resolve(String resource) { + return resolve(resource, MODULE_DIR); + } +} diff --git a/src/main/java/org/jcnc/jnotepad/util/UiUtil.java b/src/main/java/org/jcnc/jnotepad/util/UiUtil.java index 6935d2c..7cfe1c0 100644 --- a/src/main/java/org/jcnc/jnotepad/util/UiUtil.java +++ b/src/main/java/org/jcnc/jnotepad/util/UiUtil.java @@ -1,12 +1,16 @@ package org.jcnc.jnotepad.util; import atlantafx.base.theme.Styles; +import javafx.scene.Node; import javafx.scene.image.Image; +import javafx.scene.image.ImageView; import javafx.stage.Window; import org.jcnc.jnotepad.app.manager.ApplicationManager; import org.jcnc.jnotepad.common.constants.AppConstants; import org.kordamp.ikonli.javafx.FontIcon; +import java.util.HashMap; +import java.util.Map; import java.util.Objects; import static org.kordamp.ikonli.antdesignicons.AntDesignIconsFilled.*; @@ -43,6 +47,10 @@ public class UiUtil { private static final FontIcon QUESTION_ICON = FontIcon.of(QUESTION_CIRCLE); private static final FontIcon SUCCESS_ICON = FontIcon.of(CHECK_CIRCLE); + /** + * 图标集合 + */ + private static final Map ICON_MAP = new HashMap<>(32); static { // 暂时设置颜色 @@ -51,6 +59,39 @@ public class UiUtil { QUESTION_ICON.getStyleClass().addAll(Styles.ACCENT); WARNING_ICON.getStyleClass().addAll(Styles.WARNING); SUCCESS_ICON.getStyleClass().addAll(Styles.SUCCESS); + ICON_MAP.put("css", fileIconByPng("css")); + ICON_MAP.put("doc", fileIconByPng("doc")); + ICON_MAP.put("dll", fileIconByPng("dll")); + ICON_MAP.put("exe", fileIconByPng("exe")); + ICON_MAP.put("gif", fileIconByPng("gif")); + ICON_MAP.put("gitignore", fileIconByPng("git")); + ICON_MAP.put("html", fileIconByPng("html")); + ICON_MAP.put("json", fileIconByPng("json")); + ICON_MAP.put("md", fileIconByPng("markdown")); + ICON_MAP.put("pdf", FontIcon.of(FILE_PDF)); + ICON_MAP.put("ppt", FontIcon.of(FILE_PPT)); + ICON_MAP.put("png", fileIconByPng("png")); + ICON_MAP.put("sql", fileIconByPng("database")); + ICON_MAP.put("svg", fileIconByPng("svg")); + ICON_MAP.put("txt", FontIcon.of(FILE_TEXT)); + ICON_MAP.put("xls", FontIcon.of(FILE_EXCEL)); + ICON_MAP.put("xml", fileIconByPng("xml")); + // 编程语言 + ICON_MAP.put("bat", fileIconByPng("bat")); + ICON_MAP.put("c", fileIconByPng("c")); + ICON_MAP.put("cs", fileIconByPng("csharp")); + ICON_MAP.put("cpp", fileIconByPng("cplusplus")); + ICON_MAP.put("go", fileIconByPng("golang")); + ICON_MAP.put("js", fileIconByPng("js")); + ICON_MAP.put("java", fileIconByPng("java")); + ICON_MAP.put("kt", fileIconByPng("kotlin")); + ICON_MAP.put("lua", fileIconByPng("lua")); + ICON_MAP.put("py", fileIconByPng("python")); + ICON_MAP.put("php", fileIconByPng("php")); + ICON_MAP.put("rb", fileIconByPng("ruby")); + ICON_MAP.put("sh", fileIconByPng("sh")); + + } private UiUtil() { @@ -121,5 +162,61 @@ public class UiUtil { return ApplicationManager.getInstance().getWindow(); } + /** + * Generates an ImageView with the specified module directory, name, and format. + * + * @param moduleDir the directory where the module is located + * @param name the name of the icon + * @param format the format of the icon + * @return the generated ImageView + */ + public static ImageView icon(String moduleDir, String name, String format) { + return icon(moduleDir + name + format); + } + /** + * Generates an ImageView object with the image specified by the given path. + * + * @param path the path to the image file + * @return the ImageView object with the specified image + */ + public static ImageView icon(String path) { + var img = new Image(ResourceUtil.getResourceAsStream(path)); + return new ImageView(img); + } + + /** + * Generates an ImageView based on a PNG file. + * + * @param moduleDir the directory of the module + * @param name the name of the PNG file + * @return the generated ImageView + */ + public static ImageView iconByPng(String moduleDir, String name) { + return icon(moduleDir + name + ".png"); + } + + /** + * Generates an ImageView object for a file icon based on the given PNG name. + * + * @param name the name of the PNG file for the file icon + * @return the ImageView object representing the file icon + */ + public static ImageView fileIconByPng(String name) { + return iconByPng("images/fileIcons/", name); + } + + /** + * Generates an ImageView object for a file icon based on the given PNG name. + * + * @param name the name of the PNG file for the file icon + * @return the ImageView object representing the file icon + */ + public static ImageView sidebarIconByPng(String name) { + return iconByPng("images/sidebarIcons/", name); + } + + public static Map getIconMap() { + return ICON_MAP; + } } diff --git a/src/main/java/org/jcnc/jnotepad/views/manager/SidebarToolBarManager.java b/src/main/java/org/jcnc/jnotepad/views/manager/SidebarToolBarManager.java index 010c100..cad62de 100644 --- a/src/main/java/org/jcnc/jnotepad/views/manager/SidebarToolBarManager.java +++ b/src/main/java/org/jcnc/jnotepad/views/manager/SidebarToolBarManager.java @@ -1,13 +1,12 @@ package org.jcnc.jnotepad.views.manager; import javafx.scene.Node; -import javafx.scene.image.Image; -import javafx.scene.image.ImageView; import org.jcnc.jnotepad.api.core.views.manager.AbstractManager; import org.jcnc.jnotepad.api.core.views.manager.builder.SideBarButtonBuilder; import org.jcnc.jnotepad.controller.event.handler.toolbar.DirTreeBtn; import org.jcnc.jnotepad.controller.event.handler.toolbar.RunBtn; import org.jcnc.jnotepad.controller.event.handler.toolbar.SetBtn; +import org.jcnc.jnotepad.util.UiUtil; import org.jcnc.jnotepad.views.root.left.sidebar.tools.SidebarToolBar; import java.util.ArrayList; @@ -42,7 +41,7 @@ public class SidebarToolBarManager extends AbstractManager { registerNode( new SideBarButtonBuilder() .setButton(sidebarToolBar.getSetButton()) - .setImageView(new ImageView(new Image("tools.png"))) + .setImageView(UiUtil.sidebarIconByPng("tools")) .setImageViewEssentialAttribute(10D, 10D, true, 2.5D, 2.5D) .setButtonEssentialAttribute(20D, 20D) .setEventHandler(new SetBtn()).build()); @@ -50,7 +49,7 @@ public class SidebarToolBarManager extends AbstractManager { registerNode( new SideBarButtonBuilder() .setButton(sidebarToolBar.getDirTreeButton()) - .setImageView(new ImageView(new Image("directory.png"))) + .setImageView(UiUtil.sidebarIconByPng("directory")) .setImageViewEssentialAttribute(10D, 10D, true, 2.5D, 2.5D) .setButtonEssentialAttribute(20D, 20D) .setEventHandler(new DirTreeBtn()).build()); @@ -60,7 +59,7 @@ public class SidebarToolBarManager extends AbstractManager { registerNode( new SideBarButtonBuilder() .setButton(sidebarToolBar.getRunButton()) - .setImageView(new ImageView(new Image("cmd.png"))) + .setImageView(UiUtil.sidebarIconByPng("cmd")) .setImageViewEssentialAttribute(10D, 10D, true, 2.5D, 2.5D) .setButtonEssentialAttribute(20D, 20D) .setEventHandler(new RunBtn()).build()); diff --git a/src/main/resources/css/java_code_styles.css b/src/main/resources/jcnc/app/css/java_code_styles.css similarity index 100% rename from src/main/resources/css/java_code_styles.css rename to src/main/resources/jcnc/app/css/java_code_styles.css diff --git a/src/main/resources/css/styles.css b/src/main/resources/jcnc/app/css/styles.css similarity index 100% rename from src/main/resources/css/styles.css rename to src/main/resources/jcnc/app/css/styles.css diff --git a/src/main/resources/i18n/i18n.properties b/src/main/resources/jcnc/app/i18n/i18n.properties similarity index 100% rename from src/main/resources/i18n/i18n.properties rename to src/main/resources/jcnc/app/i18n/i18n.properties diff --git a/src/main/resources/i18n/i18n_en.properties b/src/main/resources/jcnc/app/i18n/i18n_en.properties similarity index 100% rename from src/main/resources/i18n/i18n_en.properties rename to src/main/resources/jcnc/app/i18n/i18n_en.properties diff --git a/src/main/resources/i18n/i18n_zh_CN.properties b/src/main/resources/jcnc/app/i18n/i18n_zh_CN.properties similarity index 100% rename from src/main/resources/i18n/i18n_zh_CN.properties rename to src/main/resources/jcnc/app/i18n/i18n_zh_CN.properties diff --git a/src/main/resources/img/JCNC.png b/src/main/resources/jcnc/app/images/appIcons/JCNC.png similarity index 100% rename from src/main/resources/img/JCNC.png rename to src/main/resources/jcnc/app/images/appIcons/JCNC.png diff --git a/src/main/resources/img/icon.icns b/src/main/resources/jcnc/app/images/appIcons/icon.icns similarity index 100% rename from src/main/resources/img/icon.icns rename to src/main/resources/jcnc/app/images/appIcons/icon.icns diff --git a/src/main/resources/img/icon.ico b/src/main/resources/jcnc/app/images/appIcons/icon.ico similarity index 100% rename from src/main/resources/img/icon.ico rename to src/main/resources/jcnc/app/images/appIcons/icon.ico diff --git a/src/main/resources/img/icon.png b/src/main/resources/jcnc/app/images/appIcons/icon.png similarity index 100% rename from src/main/resources/img/icon.png rename to src/main/resources/jcnc/app/images/appIcons/icon.png diff --git a/src/main/resources/jcnc/app/images/fileIcons/bat.png b/src/main/resources/jcnc/app/images/fileIcons/bat.png new file mode 100644 index 0000000000000000000000000000000000000000..8bdf3ee4003b777de0d0072340ae1484b266be72 GIT binary patch literal 424 zcmV;Z0ayNsP)Px$Vo5|nR5(wq)4xi?P!tC6?@NLXZQK-faqk;cP}C<-t4%vN3C`*RSSocA{Idzp zVq04u!|mvinV#2**`m`5j2{!CcvYbYw} zX6;G`V3r!!fFz>=%8AnlP8%bpE7fLLwB!js!oX1v>_R#584oavwMCHS-@pfnIZcjH z%Rx6pL~=S~Z+d`Ls_zJ}7ASrp^n!+wB(NPusP&|q9k}v4=rTVc4~AmerOeY{E{HVe zZ$1Zrx`e*+N`)l@QdK4j0B8O8yirbU+ykuR_X#nKOTR!4m1D1%<;F5Z3IK+KIDuW) ziLZNrQLJr{%maJ^v8o`qrbYoo3dEfk7EHDFB59SePdvaZ)z1M;gQ!5bPv|WH69o34 z<*bz<2HUr!ERG@-dkzBO`FmWyKY!p1YCo+-SgzUkhIIdZyY!!brU)H`OTGc@KztF$ SQ;ZM*0000Px#?@2^KR5(w~)2}baQ547V*Ax5`iY_Xc@<=90Ok_+`Y-|+m@ncMp2q=Oen64;_ znP5y2Ou!%TOtQP(uU&Wd8$3^Ow$sje-}CvLa~ryhMwk8mCtwd#=uPBpV;${WaxUQv z{kXy%J}``FykQQHDI^7i=5Y+-A$w^CM_9u~3DAR2++wt5GnY7x`BPF&FoJ7rV)ZYp ztpH2d#RM)o0nFnNvpDVq(2UOSV7Ue`fcKbRRZY5uC%j;+2JnjK+~gFnf-UT0F@pqS zTP2C5Lz=`5&f~b@kQSmh!J}VM`b^>4LemiXaE}ull%#zFef=yEq|1!200000NkvXX Hu0mjf?%9J@ literal 0 HcmV?d00001 diff --git a/src/main/resources/jcnc/app/images/fileIcons/cplusplus.png b/src/main/resources/jcnc/app/images/fileIcons/cplusplus.png new file mode 100644 index 0000000000000000000000000000000000000000..9a8686add01d5005ceaf4e049635b42c00fe6389 GIT binary patch literal 694 zcmV;n0!jUeP) zTm{9@pEQbSk&7T|f}%~@t|wSggrz;qw1<&cWX@PVn$c_?IexcA(=d~Ici-ilbI-Z= z6K1Hc>XX?TnK&YXWs5nn>XP$gI-LC9P{*-4zuE^xsS{xVfWnBN&PcvFzr}H4GYWL= ztKX<-gFx|g)70?JvQ2G~_t?D@fj3q4`6_w_VJ9GS3m1`FUdrr(JOIL<{R}lfBh=G} zDvIhYD@|&PE_ixf0LIeu0y_Y5x2xZiNydRvt$_=#f5yk{(#};HVFmCD}1j% z+CYUXZetF>+`>gHtSrMsf8)D)htZea0A#IRN#36A%r7t1&W1+yJ%2AKZU9$u#@zB! zMC32|*}FtP(E3LETRQbq^K*#|1+8RG%42px9wruJ^hI}~H#RV0-ri`@fPcg)@$8j( zh52l{;vs8!0aF|#-zGX9GJP*TXyD6t3y>@T)%Z0u0ZkDIfA*7EvJA5z$8=r3D>`Ws z4kyM#v^!pY2Y&Lns(xw&Rn^|hwo~} ztSg=~+~3h-#s>rTggc!zrw+0Cs>25FQ4p}x(@>*y)SV+T9Q->F4FT8y8+v#W{S{dZ zEFWxpD+7;S;m*m#ot?pCIEw#aJ5Q=l^QrNEoJ$kN)ZD~3mhzP^y4G*S=vfgdns&L$ zYbPx$tVu*cR5(wqlRsz_VGzaNn~fj=J6j>C{0CwXM6kKrO+*_lM6r+9c!dhtTd_%{ zyC;ZnHcDb4q!6(bh1~9?NEHw(gPkW>3KljBxASE0Fu5c)nta{&nC~}lX1*bIdAQ5> z*n2>bVjv9{^2x7FDrB z2SMDK6}bTDxo6X}+Z$`m{4;=wQC;LarQwAEz~atRkT*zNEz{`Lj>#m;HIsD#-2(U+ za0ANzQrF5Rs^|Cd+xCJoZ-H)IBGZny{H8ZU^ebB%SfF*ewLIdJUZ-v*k z0OI1XQJ=QEa@r))dT%&|yPad^{0QJXh$V-=2F7|of1=6~#KlEXEdp}_9(ooX`2*bi zNW(hc02m+1*7Gcyv}XQ5;8D`oL;wH)07*qoM6N<$f=JBbz5oCK literal 0 HcmV?d00001 diff --git a/src/main/resources/jcnc/app/images/fileIcons/css.png b/src/main/resources/jcnc/app/images/fileIcons/css.png new file mode 100644 index 0000000000000000000000000000000000000000..0aaf7de8bc14285654d2a954a8d755c3428627e0 GIT binary patch literal 598 zcmV-c0;&CpP)Px%5J^NqR5(wS(M@O*K@?$Q?WV42y+ z%&BN?&RT;PfsP+iuRwWeTC`Yj^mA1h(8N)H!qbCFY6drH`;TMw5O?`e;KWJOCsl*dRP^c#XuH7w0XUPVwo{( z14SE{Ewda`CqtN-15P}YK+e>|F+cDYz@8iJL9}jEaP)o&-|{Rwh=hRGoi#8rE)uD- zNWC-l@LnHaJp#DB|4;xOJ5^kHZsX~9R{{dO*b>0KX$Sq!Y|;2*Q`e69fczvtXOjCW zfT+4S#M4cEbTITr0DRljBb|O=0H9ux+@KM}n;(o;uIOcs@ha!yhgCTez=Nh9>GJ}k zRxgMLymgoPW9l<|v_TILo5-#Xm9;ifs11Plw)(bz24JwuMk#0+*{)d81NdvzPvp0g kBQdbbMy4w=y;MK{0McQ<5&X;3R{#J207*qoM6N<$f{82(kN^Mx literal 0 HcmV?d00001 diff --git a/src/main/resources/jcnc/app/images/fileIcons/database.png b/src/main/resources/jcnc/app/images/fileIcons/database.png new file mode 100644 index 0000000000000000000000000000000000000000..4a82096ad7775f40867f1b5f39a067d98bc302e1 GIT binary patch literal 494 zcmVjKtFVz4t-~sps@)hh8Vkf+Ob0&AE8_m23vkbwYz%U#;LU*Y6 zuPB7o1*|fGiAU9;2&x03_4=VXXa=DJMGML{5kT?OBA!@={Fd_P)$=Z? zj2y!KPD105#r1b%ZxJPFjXZnAcR$end@-Kd&k^O-6@0Y~U-rp+9ef<4+Cvr8tWT7v zA1(oxLS+*C48+re8!$~g{|bull-=9sU1mqV@sAtK@36RfFy0D4lvFbEkm8Fg+SfPZ zsf#9Z{o30oAJms>|GN*;*qT`>bN}Q6I1)2l>us_ddTa-!p=ML6q-r=dr2awxI=~N* kd(7@YE-^WgwWs&L0JXon8+axv4*&oF07*qoM6N<$f{RDZO8@`> literal 0 HcmV?d00001 diff --git a/src/main/resources/jcnc/app/images/fileIcons/dll.png b/src/main/resources/jcnc/app/images/fileIcons/dll.png new file mode 100644 index 0000000000000000000000000000000000000000..c331337f3cd1ec692bd003bd59a949e224b5303b GIT binary patch literal 256 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|c6quuhFJLD z4YuZMHW1l-|G+gqSlcYbA2ZaCS#sbXR_b}?* zXkYUEo_9-1HO88jQtoC)&eR{O~#)WTwC^K5Zvs8Y!*pf4CaUHx3vIVCg! E0P*Ky&;S4c literal 0 HcmV?d00001 diff --git a/src/main/resources/jcnc/app/images/fileIcons/doc.png b/src/main/resources/jcnc/app/images/fileIcons/doc.png new file mode 100644 index 0000000000000000000000000000000000000000..d4323abb9408142f510f7b366a22b7f9412d5661 GIT binary patch literal 513 zcmV+c0{;DpP)Px$yGcYrR5(v#WWWjjGYWVvGWh%NzrlY7Mwu@=aZt)(Fh5&_E?@&c3? zGJO?MyuiZ3f^Y#S5D!iEX6RdWg`qvogyH??Ukr^4&NKAom@{a{tz{r83?}ATFx-0l zi6Puck>TX^*9>33|6x#&;9*E;Kg5vaD$Wq+C<=FhkdP1qCnqPW3lhE57(j-sK5(Dm z;+=O4-j=cq8;?9>n6~~paV{`W6=nc=qkYLmhMSK*GAyXFV{k6m&T#t1Yli$lWri$2 zC6q8=Vq!vd0kW)-nh3-GiCzr+o{PZ31f!8qN+c=}$xg~(jh3r8dHKH^{Qu9W&-nkp z0Rtl_BY`p$BRj#&gwJMfuO+(7fBzZ$WB9LtD>niF+?&3mKckh^00000NkvXXu0mjf DaR=i{ literal 0 HcmV?d00001 diff --git a/src/main/resources/jcnc/app/images/fileIcons/exe.png b/src/main/resources/jcnc/app/images/fileIcons/exe.png new file mode 100644 index 0000000000000000000000000000000000000000..5ebb8551a696fd4283b6a11bdb4bf7e9ae85e67c GIT binary patch literal 361 zcmV-v0ha!WP)Px$BS}O-R5(wild(#~KoExie~@19U>I!o9R(AH{1NatNm=!D% zur!s}ixENaItxo1g(xb5O<~nA(QOxKT~+Q9g0BJz%DdsR4wjN{yC!fJrRxf~7_F*mXBlUAdj6m$U|&{V z>mhrWJ*9X!NdUm5h=gQ5u$9oncN)U*m!w9w02?%MdILdcj6eeL1rR;Pf6an0r2jLZ zgw+7|E1ahV#Pc|P6v136LZbtJyWXMHcBfmyW3(0cYwiNhUvP)$+Q!dWw`F-SGif2c-zXm748JU8xw^DPx#=1D|BR5(wik}(d#FbqZga|v1`B)9?L7960=3@j|PY}|km+8wbXx-qhF1IiIt zP}@tyD3w};f?6OMW54Iv4#@Jrk|(5_VV?xe!RQg_pcr@~?2Ql`NF}4_M71i{!;hU;`H|*b1Iv^jvl~_xR%g0000Px$D@jB_R5(wSlfN%RQ545N=i-SlT0MhEsz!s@G?DlZI@)X&N%z)lvDn3EwJ|X1 zKY&(Pv8so2Z>PLIYR}W%2_krtJik-Z1q)#L<(& zk`I!8@QIyWt*sfG+}g=#PoU{5M?&Hh00&=D?WJJ06k0`ybmQm-*zir`7eG^0wpaRt zi%uN1a@n*?11z#%?G27Pi_;BJJ^T*XE?Gia{|oS1oXFTF0(G_aO^i7Q=DbbJj3dod zy{`1%YtG+Yn7Tq_GdRW&MBv22bJjH9HhNb%e+U0s=n(6CS?E=PMS01)36RT@(NS literal 0 HcmV?d00001 diff --git a/src/main/resources/jcnc/app/images/fileIcons/html.png b/src/main/resources/jcnc/app/images/fileIcons/html.png new file mode 100644 index 0000000000000000000000000000000000000000..069bf406c7c8f2f21b792138703d57dd0060ec1d GIT binary patch literal 596 zcmV-a0;~OrP)Px%4oO5oR5(wSlD}&dK@`WoZ)P{@?V2Bg1`C5lRFEW%S1CdYJ+qhCsc4}fs7d~V zXdxnK1PR)RLK+o<;x7cb+cR361g&CWVj=O;L@fM)$tAZZ=G=KQvx;|N4RM-z^WMDA zd+$3#08r_2I|0?H?UgT)w{xXDMF3}j2!kt62AFZ$&IOkYAWSFvnCbfe0EoC>X3IAW z;AfY67{qsIa~r7d^0FKr9sp0j0ho?hxzgPT;3YhOvS@0C9GM1BjQta$29E;8uK+l0 z`DNb#xO?r+P^p)YHsq68;L{Akf78?Ej!2rJPX=CJMXSN^c{ZBXXHF;lss}jo7 iQK5uSPv;A9H-7=*QneBMIK{>Q0000Px$bV)=(R5(walD$h?VHm}K=cc#`iWEPnn8AWnba3fVoZZ}tAc6{d6a523T>QYr z)#aK5ZE;jwx_4-CaOqG4KTyP}5OuRdk>(z`K|$KYs4u+RIX}+xoJTz28NLVxD@pYP zKL!gbYHI=vTfoN`0UnwS!$48+^e@A`{V4w>)sun+iJqk#S zhErf!@cCIS7J;^7nGtc7b>g_h&-l%c_4k4P>#S-E*~sZw{6uWZL~+3DLa1*wcaX{Zlg*q(v&@i9r^FxNhs=KR z*QRvw-z83OxV`k3CC7{)0^k=h>*a{z(4qrq2kJ^@D+p*PgxaY(!bHJuf|ya@8mO1( kwRsQa7Pj*lE#9ZN1%2Fq5pLwu7ytkO07*qoM6N<$g6b2%AOHXW literal 0 HcmV?d00001 diff --git a/src/main/resources/jcnc/app/images/fileIcons/js.png b/src/main/resources/jcnc/app/images/fileIcons/js.png new file mode 100644 index 0000000000000000000000000000000000000000..e1d007f5f535ecc013f1034950d2962f25a4a9b4 GIT binary patch literal 398 zcmV;90df9`P)Px$NJ&INR5(wS)4fYvQ4q%A$0ChjBP1X;7FwmyB7#_HCAOLbf{OkFMl2LTK`j&; zQIJ$=LP$c0v9QoW@B=>z(Nq;s3f%Tv#cyQqn^E123ABd;|2Z}9F;(L@ s)|X&o(RseyW6H)GFcb$n*e_-C7gUx}5%!6JwEzGB07*qoM6N<$g7}T49smFU literal 0 HcmV?d00001 diff --git a/src/main/resources/jcnc/app/images/fileIcons/json.png b/src/main/resources/jcnc/app/images/fileIcons/json.png new file mode 100644 index 0000000000000000000000000000000000000000..bcd7bac37bcff1985f00ef72b7fbfed71f5d7303 GIT binary patch literal 229 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|=6kw0hFJKo zy}Xh4kONQaLw#1;%?fM{U9&tT7$q7#SFB86IHL1KM8SPiiHnQN&K=)=|Gjtf`ieEn zg4VOhY&g#QTJD3Wwv6E4_=a*to)hc23PT!hJzUz%@}*N)V!}&C&)zrAvRn2FD!$SA za6s(5{p^{K=gjhCFx;T!WOYt=Pr;#0!cY5T)10>n^zG{3d2ngL?P_+ziYtnt^FOVq d5B)1`zxxmqCdfit;xdcJoKkyJziNI+-< z!FP%=5CDTTB|;kKA8r*JN>{B50Irok>DB5w!E`l$)zFZD7~=fo&n8^202JZo_J$7s z{Vc&m>>zZG{q;!+WAm%iwY-(SVsT-F`{mFC^5#)pd=dtd-Jy7@hflztd* zqZZs20sExy>Ds<9fEnKWWxUT3d=Bp;f{(H@M69Rhbmq^!({ViC`CmZ;*a7>9_c9nh z$e>iMT=837vvK^^?JH={-uPCcfv^${n6fjJouO*wy5HJN~tn1k*h2`FY zU(NU1$SbV@f)Z|>>g%d1dPfj#R-o#dWxqaDNSBVBuoWvLR!FQNaYEt@Nmj||qw%Gg z`iL?C2&#^keMf5x$B((hG~kw`?1Zv2B-T)~a(8lU@p+p77W(s*xk7J8#R!e;m0gmg zE-5=h&6)A3u~*Lk+(MxznLT+RGOF1gw5@{fINO&RKpsrpUrhc1xK#ZFoCSAX00000 LNkvXXu0mjf6W|<> literal 0 HcmV?d00001 diff --git a/src/main/resources/jcnc/app/images/fileIcons/lua.png b/src/main/resources/jcnc/app/images/fileIcons/lua.png new file mode 100644 index 0000000000000000000000000000000000000000..7118da180ee9361de0182deefd8907f9960c7d0e GIT binary patch literal 369 zcmV-%0gnEOP)Px$D@jB_R5(wali^VUK@5dII*Px$I7vi7R5(wylrc^NF%U)nYz{!Qp`ri@tsBaeR3JJU4uFtAfP}1UZh+tpyV*z} z1Vt`DMM*k10Ro%`iim>U?>C-5V-q|t5?(zqD?Yg6SoJCF4$i^6 z?E?s+3koyCUSOY)Z$Jk65+~rx0>V8rUfj6VO=;z^3G#`D84Gq(h!xmLY0$!~#@Rk~GA?-s_brKd(} zHu9Fb{1Y&!(ORLS!sE0qofXl|U=74RA}Ay*EOWn0E*iS2pFRv8fsn1_lH~lQaAegYEn2dH)=I czGGp%0}=|NZAmHS6#xJL07*qoM6N<$f_A`{sQ>@~ literal 0 HcmV?d00001 diff --git a/src/main/resources/jcnc/app/images/fileIcons/php.png b/src/main/resources/jcnc/app/images/fileIcons/php.png new file mode 100644 index 0000000000000000000000000000000000000000..d559dfe1f1fc0685dc93e5f45837df43b88d32ce GIT binary patch literal 384 zcmV-`0e}99P)Px$I!Q!9R5(w~Q$0%qQ4pMYcW4S58yhQ&{D53iS*fK~f**}-E`nfVliXRD!Y9~? zV7$}H!a_@bKvD)`E-03MG!|lI8@ardgdk}y3TZOU!ZI^3!!9u*IHDe7Y~Tg06)5C% zK2shRGciIbXnIuK(RpX~PXjNA8X$5#B5^xm(`|ptIf>1_xXwwnCT+71V7t$|gOP~E zv&U&=#~+3=PvI1S8o&%8*8)_u>zsOFB#K-#B8Lz@=|ZMZ3Zp8)FBU6}1!Y-P?K<>> z*1Aw`OowyIk~aX$hVrR|_hMs)F<(iuXN)|M>I%Xd{UF*E;^a4{NSP_?LfYotC`ns_ zB?#S4+}TjJ^)k@Mvv!>{{V=*TkkpZz-5OSwA2wG7Jno7HdGvzjL3g1G+1^Y-5^szz e@xMPx$07*naR5(walg*U@K@>)BuPkh2z}Ci*0Wx4`$3!qfAOkXJ5s(2gFd0k+WMIyn z^UC!2>C@Dvs;l0+_1@QCW&DjP&@6nHEx&=a0a-+uJOj2B0YhL3cuz)ek3_L#gxSK5DSYybcN literal 0 HcmV?d00001 diff --git a/src/main/resources/jcnc/app/images/fileIcons/python.png b/src/main/resources/jcnc/app/images/fileIcons/python.png new file mode 100644 index 0000000000000000000000000000000000000000..58595f41426cd7f08d6d78edb8bb5557ab50ae62 GIT binary patch literal 610 zcmV-o0-gPdP)lw{P>;>l4_cp1dEr{+or%mVwMR{1BJjfM zG+?Iy$F|}#^#YBnl>Ib8oV+0vXJ+$z|4gSz{rJ$eULZ{jR1xK6E}6B8qbglilA{%_@aqFDp3`s|P>U@)IXYJw2fpsW w?kcdj2pL{I`Jttyi_@%07*qoM6N<$f~R&97ytkO literal 0 HcmV?d00001 diff --git a/src/main/resources/jcnc/app/images/fileIcons/ruby.png b/src/main/resources/jcnc/app/images/fileIcons/ruby.png new file mode 100644 index 0000000000000000000000000000000000000000..3f59bfb118779f76daa0272e5f22e8c87c151b9b GIT binary patch literal 407 zcmV;I0cie-P)Px$QAtEWR5(wK)4xkrVHn2o&pU$iN;*Uid+`_^750pEe1Bb(VUOjMg4$pO8-{*cVo>Ni(8NxGM zV=1-H;xoQsx>DkwLR5QBAHW=Xb8DY!0p4T22KX&D@Bx!aKPm#s%+db>)ntrG7UDY( zsAt~7U}374Sj+%1()T)fj-Ue#c#OuZGQd9iO8^sC$8R(hda40iN65ilPVW&fE<2AZ-+He4Z9=rA=VKtrqp5NrZ+!ug@biX6v82L{c_aT7R z0Ax3C4a;fNhnSG$?j2?cM6X)MR7U^+002ovPDHLkV1k|O BuS);` literal 0 HcmV?d00001 diff --git a/src/main/resources/jcnc/app/images/fileIcons/sh.png b/src/main/resources/jcnc/app/images/fileIcons/sh.png new file mode 100644 index 0000000000000000000000000000000000000000..f3faf4ec5026f7ef9c23a5f9c00f09a9919921b0 GIT binary patch literal 334 zcmV-U0kQsxP)Px$2uVaiR5(wq(>*K2Q5XR5-`&hoN($30%3?EMwi&z>21?3gkQFnFMe1giyk_zN zB(riy27?%Ugd3eYr;dOBOV@SAbDrmSp69$&v^gqm=F5R;oVE()zzJp}u!A{Ne*x<` z@Qi_&FoX_VqxT1-mVjYAWPx?epbJ;%Y=SH$U=@djpoH|}B34v%stGv4a>*_U8N^v( z{RMpqctq$s9}O%Z9B$bSorn1VbmOg%e2+yuVHX=E)oq5g08HUB3)sgxCa{N*CI>i% z+W_P{%;Ol_*ou80WWZW%=Ob3$2*4di@g8qtJnkOyUQx?{74+Z+lVLsppRGP$gqIqs g{Pq|A;QRyd1$VD51gnF+egFUf07*qoM6N<$f}QnPx#=t)FDR5(wi(>+Q3eyYhwzn6coIIdILd3VwWQ4NbChI zJcBugGO$nfE$e&4Otm{7|DBng8EDH9&TwAno9jL9a@(MA3}ZlAPRZvACul)Rz&9pX zRWbDOHUV5NJ= Ai2wiq literal 0 HcmV?d00001 diff --git a/src/main/resources/jcnc/app/images/fileIcons/txt.png b/src/main/resources/jcnc/app/images/fileIcons/txt.png new file mode 100644 index 0000000000000000000000000000000000000000..51731c20941cc5ed9b9ad4ddd577bee3317e6efb GIT binary patch literal 274 zcmV+t0qy>YP)Px#%t=H+R5(wilf4c>K@f$%`zC}^=>g~zN<4`kiFc8x_2{*9;=YAOLXPanX576$ zYl6U;4e@ih;)0eJyn0GxrDhj_pf7y<_e(f1WF@sK8fWq?kB zo(a?i>?22t^XZELQdj_{l-iH#iu1k~1EeB)oue6PR)qjlkeefL2S!2F9F_tE?f_R{ z4LpKfxwGw50%T8-y20fJm^T4b&7shN<@Px$)=5M`R5(wilRs!wK@i5jS?;hC6cokALc~9%D0XsiJM#iDh(fSYL=db*Bx0FM zDW(t`3n2k5ghY&}oNwoyJZu$96|6)MMM1H?V@KX`FRT~!3b)+(<~O_Z%@F?c(4>4- zy$;|AGq?Vv-2ez7bVQ_6i$e&Hi0A_|UoMJb-h020f_?+2>J>BFoB~w!otfPbk);X_ z;Jb+2sv+wDRlNw{HW78|DtVsobk2P;v%@0tx&jcwvUKrNL5P!KgN?sFS`R^FEbxY!DU(Q84Lz1X7;lNY;(@dw%hHusZdp40C>;L z7t;G)uXiBExB}oC6-9B>%pL>yIu23QFJ`tVB8xR3N#0^+Gs7l^5T=Rf34k{>q%6xu zzu)i27^ku<%PU=yd=NmJnV+XNo&j*z%oeIS2q7FIqE|7-U0IfW9u*qeNJOW+_Yc=? zOgelCz}6AqJP}=G=KV>$