diff --git a/pom.xml b/pom.xml index ab8abe32af..66d9fdb8ed 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.ghostchu.peerbanhelper peerbanhelper - 7.1.2 + 7.1.3 jar PeerBanHelper @@ -485,7 +485,11 @@ xz 1.10 - + + com.formdev + flatlaf-extras + 3.0 + diff --git a/src/main/java/com/ghostchu/peerbanhelper/downloader/impl/qbittorrent/AbstractQbittorrent.java b/src/main/java/com/ghostchu/peerbanhelper/downloader/impl/qbittorrent/AbstractQbittorrent.java index 352b8afa6e..ac03d964d7 100644 --- a/src/main/java/com/ghostchu/peerbanhelper/downloader/impl/qbittorrent/AbstractQbittorrent.java +++ b/src/main/java/com/ghostchu/peerbanhelper/downloader/impl/qbittorrent/AbstractQbittorrent.java @@ -161,7 +161,7 @@ public List getTorrents() { fillTorrentPrivateField(qbTorrent); } return qbTorrent.stream().map(t -> (Torrent) t) - .filter(t-> !config.isIgnorePrivate() || !t.isPrivate()) + .filter(t -> !config.isIgnorePrivate() || !t.isPrivate()) .collect(Collectors.toList()); } @@ -247,6 +247,9 @@ public List getPeers(Torrent torrent) { for (String s : peers.keySet()) { JsonObject singlePeerObject = peers.getAsJsonObject(s); QBittorrentPeer qbPeer = JsonUtil.getGson().fromJson(singlePeerObject.toString(), QBittorrentPeer.class); + if ("HTTP".equalsIgnoreCase(qbPeer.getConnection()) || "HTTPS".equalsIgnoreCase(qbPeer.getConnection()) || "Web".equalsIgnoreCase(qbPeer.getConnection())) { + continue; + } if (qbPeer.getPeerAddress().getIp() == null || qbPeer.getPeerAddress().getIp().isBlank()) { continue; } diff --git a/src/main/java/com/ghostchu/peerbanhelper/downloader/impl/qbittorrent/impl/QBittorrentPeer.java b/src/main/java/com/ghostchu/peerbanhelper/downloader/impl/qbittorrent/impl/QBittorrentPeer.java index 1e400655f6..74f6ddb319 100644 --- a/src/main/java/com/ghostchu/peerbanhelper/downloader/impl/qbittorrent/impl/QBittorrentPeer.java +++ b/src/main/java/com/ghostchu/peerbanhelper/downloader/impl/qbittorrent/impl/QBittorrentPeer.java @@ -18,8 +18,8 @@ public final class QBittorrentPeer implements Peer { @SerializedName("client") private String client; -// @SerializedName("connection") -// private String connection; + @SerializedName("connection") + private String connection; // @SerializedName("country") // private String country; // @SerializedName("country_code") @@ -114,4 +114,7 @@ public String getRawIp() { return rawIp == null ? ip : rawIp; } + public String getConnection() { + return connection; + } } diff --git a/src/main/java/com/ghostchu/peerbanhelper/gui/impl/swing/MainWindow.java b/src/main/java/com/ghostchu/peerbanhelper/gui/impl/swing/MainWindow.java index 5cf7a06458..5d46c67209 100644 --- a/src/main/java/com/ghostchu/peerbanhelper/gui/impl/swing/MainWindow.java +++ b/src/main/java/com/ghostchu/peerbanhelper/gui/impl/swing/MainWindow.java @@ -1,7 +1,9 @@ package com.ghostchu.peerbanhelper.gui.impl.swing; +import com.formdev.flatlaf.extras.FlatSVGIcon; import com.formdev.flatlaf.util.SystemInfo; import com.ghostchu.peerbanhelper.Main; +import com.ghostchu.peerbanhelper.downloader.DownloaderLastStatus; import com.ghostchu.peerbanhelper.text.Lang; import com.ghostchu.peerbanhelper.util.logger.LogEntry; import lombok.Getter; @@ -19,6 +21,8 @@ import java.awt.event.WindowEvent; import java.io.IOException; import java.net.URI; +import java.util.ArrayList; +import java.util.List; import java.util.Locale; import java.util.logging.Level; @@ -36,7 +40,7 @@ public class MainWindow extends JFrame { private JScrollPane loggerScrollPane; @Nullable @Getter - private TrayIcon trayIcon; + private SwingTray swingTrayDialog; private boolean persistFlagTrayMessageSent; public MainWindow(SwingGuiImpl swingGUI) { @@ -87,7 +91,7 @@ public static void copyText(String content) { } private void minimizeToTray() { - if (trayIcon != null) { + if (swingTrayDialog != null) { setVisible(false); if (!persistFlagTrayMessageSent) { persistFlagTrayMessageSent = true; @@ -104,25 +108,64 @@ private void setupSystemTray() { if (SystemTray.isSupported()) { TrayIcon icon = new TrayIcon(Toolkit.getDefaultToolkit().getImage(Main.class.getResource("/assets/icon.png"))); icon.setImageAutoSize(true); - //创建弹出菜单 - PopupMenu menu = new PopupMenu(); - //添加一个用于退出的按钮 - MenuItem item = new MenuItem("Exit"); - item.addActionListener(e -> System.exit(0)); - menu.add(item); - //添加弹出菜单到托盘图标 - icon.setPopupMenu(menu); - SystemTray tray = SystemTray.getSystemTray();//获取系统托盘 - icon.addActionListener(e -> setVisible(true)); + SystemTray sysTray = SystemTray.getSystemTray();//获取系统托盘 try { - tray.add(icon);//将托盘图表添加到系统托盘 - this.trayIcon = icon; + var tray = new SwingTray(icon, mouseEvent -> setVisible(true), mouseEvent -> updateTrayMenus()); + sysTray.add(icon);//将托盘图表添加到系统托盘 + updateTrayMenus(); + this.swingTrayDialog = tray; } catch (AWTException e) { throw new RuntimeException(e); } } } + private void updateTrayMenus() { + if (this.swingTrayDialog == null) return; + List items = new ArrayList<>(); + JMenuItem openMainWindow = new JMenuItem(tlUI(Lang.GUI_MENU_SHOW_WINDOW), new FlatSVGIcon(Main.class.getResource("/assets/icon/tray/open.svg"))); + JMenuItem openWebUI = new JMenuItem(tlUI(Lang.GUI_MENU_WEBUI_OPEN), new FlatSVGIcon(Main.class.getResource("/assets/icon/tray/browser.svg"))); + JMenuItem quit = new JMenuItem(tlUI(Lang.GUI_MENU_QUIT), new FlatSVGIcon(Main.class.getResource("/assets/icon/tray/close.svg"))); + openMainWindow.addActionListener(e -> setVisible(true)); + openWebUI.addActionListener(e -> openWebUI()); + quit.addActionListener(e -> System.exit(0)); + items.add(menuDisplayItem(new JMenuItem(tlUI(Lang.GUI_MENU_STATS)))); + items.add(menuBanStats()); + items.add(menuDownloaderStats()); + items.add(menuDisplayItem(new JMenuItem(tlUI(Lang.GUI_MENU_QUICK_OPERATIONS)))); + items.add(openMainWindow); + items.add(openWebUI); + items.add(null); + items.add(quit); + this.swingTrayDialog.set(items); + } + + private JMenuItem menuDownloaderStats() { + var totalDownloaders = 0L; + var healthDownloaders = 0L; + if (Main.getServer() != null) { + totalDownloaders = Main.getServer().getDownloaders().size(); + healthDownloaders = Main.getServer().getDownloaders().stream().filter(m -> m.getLastStatus() == DownloaderLastStatus.HEALTHY).count(); + } + return new JMenuItem(tlUI(Lang.GUI_MENU_STATS_DOWNLOADER, healthDownloaders, totalDownloaders), new FlatSVGIcon(Main.class.getResource("/assets/icon/tray/connection.svg"))); + } + + private JMenuItem menuBanStats() { + var bannedPeers = 0L; + var bannedIps = 0L; + var server = Main.getServer(); + if (server != null) { + bannedIps = Main.getServer().getBannedPeers().values().stream().map(m -> m.getPeer().getAddress().getIp()).distinct().count(); + bannedPeers = Main.getServer().getBannedPeers().values().size(); + } + return new JMenuItem(tlUI(Lang.GUI_MENU_STATS_BANNED, bannedPeers, bannedIps), new FlatSVGIcon(Main.class.getResource("/assets/icon/tray/banned.svg"))); + } + + private JMenuItem menuDisplayItem(JMenuItem jMenuItem) { + jMenuItem.setEnabled(false); + return jMenuItem; + } + private JMenuBar setupMenuBar() { JMenuBar menuBar = new JMenuBar(); menuBar.add(generateProgramMenu()); @@ -156,9 +199,7 @@ private JMenu generateWebUIMenu() { JMenu webUIMenu = new JMenu(tlUI(Lang.GUI_MENU_WEBUI)); JMenuItem openWebUIMenuItem = new JMenuItem(tlUI(Lang.GUI_MENU_WEBUI_OPEN)); openWebUIMenuItem.addActionListener(e -> { - if (Main.getServer() != null && Main.getServer().getWebContainer() != null) { - swingGUI.openWebpage(URI.create("http://localhost:" + Main.getServer().getWebContainer().javalin().port() + "?token=" + Main.getServer().getWebContainer().getToken())); - } + this.openWebUI(); }); webUIMenu.add(openWebUIMenuItem); JMenuItem copyWebUIToken = new JMenuItem(tlUI(Lang.GUI_COPY_WEBUI_TOKEN)); @@ -173,6 +214,12 @@ private JMenu generateWebUIMenu() { return webUIMenu; } + private void openWebUI() { + if (Main.getServer() != null && Main.getServer().getWebContainer() != null) { + swingGUI.openWebpage(URI.create("http://localhost:" + Main.getServer().getWebContainer().javalin().port() + "?token=" + Main.getServer().getWebContainer().getToken())); + } + } + public void sync() { } diff --git a/src/main/java/com/ghostchu/peerbanhelper/gui/impl/swing/SwingGuiImpl.java b/src/main/java/com/ghostchu/peerbanhelper/gui/impl/swing/SwingGuiImpl.java index ee35d00fed..c6ffe00eb0 100644 --- a/src/main/java/com/ghostchu/peerbanhelper/gui/impl/swing/SwingGuiImpl.java +++ b/src/main/java/com/ghostchu/peerbanhelper/gui/impl/swing/SwingGuiImpl.java @@ -2,7 +2,6 @@ import com.formdev.flatlaf.FlatDarculaLaf; import com.formdev.flatlaf.FlatIntelliJLaf; -import com.formdev.flatlaf.util.SystemInfo; import com.ghostchu.peerbanhelper.Main; import com.ghostchu.peerbanhelper.PeerBanHelperServer; import com.ghostchu.peerbanhelper.exchange.ExchangeMap; @@ -196,32 +195,39 @@ public void createDialog(Level level, String title, String description) { @Override public void createNotification(Level level, String title, String description) { - TrayIcon icon = mainWindow.getTrayIcon(); - if (icon != null) { - if (level.equals(Level.WARNING)) { - icon.displayMessage(title, description, TrayIcon.MessageType.WARNING); - } else if (level.equals(Level.SEVERE)) { - icon.displayMessage(title, description, TrayIcon.MessageType.ERROR); - } else { - icon.displayMessage(title, description, TrayIcon.MessageType.INFO); - } - if (System.getProperty("os.name").contains("Windows")) { - CommonUtil.getScheduler().schedule(this::refreshTrayIcon, 5, TimeUnit.SECONDS); + + var swingTray = mainWindow.getSwingTrayDialog(); + if (swingTray != null) { + var icon = swingTray.getTrayIcon(); + if (swingTray.getTrayIcon() != null) { + if (level.equals(Level.WARNING)) { + icon.displayMessage(title, description, TrayIcon.MessageType.WARNING); + } else if (level.equals(Level.SEVERE)) { + icon.displayMessage(title, description, TrayIcon.MessageType.ERROR); + } else { + icon.displayMessage(title, description, TrayIcon.MessageType.INFO); + } + if (System.getProperty("os.name").contains("Windows")) { + CommonUtil.getScheduler().schedule(this::refreshTrayIcon, 5, TimeUnit.SECONDS); + } + return; } - } else { - super.createNotification(level, title, description); } + super.createNotification(level, title, description); } private synchronized void refreshTrayIcon() { - TrayIcon icon = mainWindow.getTrayIcon(); - if (icon != null) { - try { - SystemTray tray = SystemTray.getSystemTray(); - tray.remove(icon); // fix https://github.com/PBH-BTN/PeerBanHelper/issues/515 - tray.add(icon); - } catch (AWTException e) { - throw new RuntimeException(e); + var swingTray = mainWindow.getSwingTrayDialog(); + if (swingTray != null) { + var icon = swingTray.getTrayIcon(); + if (icon != null) { + try { + SystemTray tray = SystemTray.getSystemTray(); + tray.remove(icon); // fix https://github.com/PBH-BTN/PeerBanHelper/issues/515 + tray.add(icon); + } catch (AWTException e) { + throw new RuntimeException(e); + } } } } diff --git a/src/main/java/com/ghostchu/peerbanhelper/gui/impl/swing/SwingTray.java b/src/main/java/com/ghostchu/peerbanhelper/gui/impl/swing/SwingTray.java new file mode 100644 index 0000000000..11469bfcbd --- /dev/null +++ b/src/main/java/com/ghostchu/peerbanhelper/gui/impl/swing/SwingTray.java @@ -0,0 +1,74 @@ +package com.ghostchu.peerbanhelper.gui.impl.swing; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.util.List; +import java.util.function.Consumer; + +public class SwingTray { + + private final JDialog jDialog; + private final JPopupMenu jPopupMenu; + private final TrayIcon trayIcon; + + public SwingTray(TrayIcon trayIcon, Consumer clickCallback, Consumer rightClickCallback) { + this.trayIcon = trayIcon; + this.jDialog = new JDialog(); + jDialog.setUndecorated(true); + jDialog.setSize(1, 1); + this.jPopupMenu = new JPopupMenu() { + @Override + public void firePopupMenuWillBecomeInvisible() { + jDialog.setVisible(false); + } + }; + trayIcon.addMouseListener(new MouseAdapter() { + @Override + public void mouseReleased(MouseEvent e) { + // 左键单击 + if (e.getButton() == 1) { + clickCallback.accept(e); + return; + } + if (e.getButton() == 3 && e.isPopupTrigger()) { + rightClickCallback.accept(e); + // 获取屏幕相对位置 + Point point = MouseInfo.getPointerInfo().getLocation(); + // 将jDialog设置为鼠标位置 + jDialog.setLocation(point.x, point.y); + // 显示载体 + jDialog.setVisible(true); + var dimension = jPopupMenu.getPreferredSize(); + jPopupMenu.setSize((int) dimension.getWidth() + 1, (int) dimension.getHeight() + 1); + // 在载体的0,0处显示对话框 + jPopupMenu.show(jDialog, 0, 0); + } + } + }); + } + + public void set(List items) { + jPopupMenu.removeAll(); + items.forEach(ele->{ + if(ele == null) { + jPopupMenu.addSeparator(); + }else{ + jPopupMenu.add(ele); + } + }); + } + + public TrayIcon getTrayIcon() { + return trayIcon; + } + + public JDialog getjDialog() { + return jDialog; + } + + public JPopupMenu getjPopupMenu() { + return jPopupMenu; + } +} diff --git a/src/main/java/com/ghostchu/peerbanhelper/text/Lang.java b/src/main/java/com/ghostchu/peerbanhelper/text/Lang.java index e6fd324ccb..64248f103d 100644 --- a/src/main/java/com/ghostchu/peerbanhelper/text/Lang.java +++ b/src/main/java/com/ghostchu/peerbanhelper/text/Lang.java @@ -433,7 +433,7 @@ public enum Lang { BTN_RULES_SCRIPT_COMPILING, BTN_RULES_SCRIPT_COMPILED, BTN_SERVICES_NEED_RESTART, - EXPRESS_RULE_ENGINE_SAVED; + EXPRESS_RULE_ENGINE_SAVED, GUI_MENU_SHOW_WINDOW, GUI_MENU_STATS_BANNED, GUI_MENU_STATS_DOWNLOADER, GUI_MENU_QUICK_OPERATIONS, GUI_MENU_STATS; public String getKey() { return name(); diff --git a/src/main/java/com/ghostchu/peerbanhelper/text/TextManager.java b/src/main/java/com/ghostchu/peerbanhelper/text/TextManager.java index affb38483e..b62d4aecc6 100644 --- a/src/main/java/com/ghostchu/peerbanhelper/text/TextManager.java +++ b/src/main/java/com/ghostchu/peerbanhelper/text/TextManager.java @@ -127,7 +127,7 @@ public static String[] convert(String locale, @Nullable Object... args) { * Loading Crowdin OTA module and i18n system */ public void load() { - log.info("Loading up translations, this may need a while..."); + log.info("Loading up translations, this may take a while..."); //TODO: This will break the message processing system in-game until loading finished, need to fix it. this.reset(); // first, we need load built-in fallback translation. diff --git a/src/main/java/com/ghostchu/peerbanhelper/util/collection/CircularArrayList.java b/src/main/java/com/ghostchu/peerbanhelper/util/collection/CircularArrayList.java deleted file mode 100644 index 866face139..0000000000 --- a/src/main/java/com/ghostchu/peerbanhelper/util/collection/CircularArrayList.java +++ /dev/null @@ -1,351 +0,0 @@ -package com.ghostchu.peerbanhelper.util.collection; - -import org.jetbrains.annotations.Contract; - -import java.util.AbstractList; -import java.util.Arrays; -import java.util.NoSuchElementException; -import java.util.RandomAccess; - -/** - * @author Glavo - */ -@SuppressWarnings("unchecked") -public final class CircularArrayList extends AbstractList implements RandomAccess { - - private static final int DEFAULT_CAPACITY = 10; - private static final Object[] EMPTY_ARRAY = new Object[0]; - - private Object[] elements; - private int begin = -1; - private int end = 0; - - public CircularArrayList() { - this.elements = EMPTY_ARRAY; - } - - public CircularArrayList(int initialCapacity) { - if (initialCapacity < 0) { - throw new IllegalArgumentException("illegal initialCapacity: " + initialCapacity); - } - - this.elements = initialCapacity == 0 ? EMPTY_ARRAY : new Object[initialCapacity]; - } - - private static int inc(int i, int capacity) { - return i + 1 >= capacity ? 0 : i + 1; - } - - private static int inc(int i, int distance, int capacity) { - if ((i += distance) - capacity >= 0) { - i -= capacity; - } - - return i; - } - - private static int dec(int i, int capacity) { - return i - 1 < 0 ? capacity - 1 : i - 1; - } - - private static int sub(int i, int distance, int capacity) { - if ((i -= distance) < 0) { - i += capacity; - } - return i; - } - - private static int newCapacity(int oldCapacity, int minCapacity) { - return oldCapacity == 0 - ? Math.max(DEFAULT_CAPACITY, minCapacity) - : Math.max(Math.max(oldCapacity, minCapacity), oldCapacity + (oldCapacity >> 1)); - } - - private static void checkElementIndex(int index, int size) throws IndexOutOfBoundsException { - if (index < 0 || index >= size) { - // Optimized for execution by hotspot - checkElementIndexFailed(index, size); - } - } - - @Contract("_, _ -> fail") - private static void checkElementIndexFailed(int index, int size) { - if (size < 0) { - throw new IllegalArgumentException("size(" + size + ") < 0"); - } - if (index < 0) { - throw new IndexOutOfBoundsException("index(" + index + ") < 0"); - } - if (index >= size) { - throw new IndexOutOfBoundsException("index(" + index + ") >= size(" + size + ")"); - } - throw new AssertionError(); - } - - private static void checkPositionIndex(int index, int size) throws IndexOutOfBoundsException { - if (index < 0 || index > size) { - // Optimized for execution by hotspot - checkPositionIndexFailed(index, size); - } - } - - @Contract("_, _ -> fail") - private static void checkPositionIndexFailed(int index, int size) { - if (size < 0) { - throw new IllegalArgumentException("size(" + size + ") < 0"); - } - if (index < 0) { - throw new IndexOutOfBoundsException("index(" + index + ") < 0"); - } - if (index > size) { - throw new IndexOutOfBoundsException("index(" + index + ") > size(" + size + ")"); - } - throw new AssertionError(); - } - - private void grow() { - grow(elements.length + 1); - } - - private void grow(int minCapacity) { - final int oldCapacity = elements.length; - final int size = size(); - final int newCapacity = newCapacity(oldCapacity, minCapacity); - - final Object[] newElements; - if (size == 0) { - newElements = new Object[newCapacity]; - } else if (begin < end) { - newElements = Arrays.copyOf(elements, newCapacity, Object[].class); - } else { - newElements = new Object[newCapacity]; - System.arraycopy(elements, begin, newElements, 0, elements.length - begin); - System.arraycopy(elements, 0, newElements, elements.length - begin, end); - begin = 0; - end = size; - } - this.elements = newElements; - } - - @Override - public boolean isEmpty() { - return begin == -1; - } - - @Override - public int size() { - if (isEmpty()) { - return 0; - } else if (begin < end) { - return end - begin; - } else { - return elements.length - begin + end; - } - } - - @Override - public E get(int index) { - if (isEmpty()) { - throw new IndexOutOfBoundsException("Index out of range: " + index); - } else if (begin < end) { - checkElementIndex(index, end - begin); - return (E) elements[begin + index]; - } else { - checkElementIndex(index, elements.length - begin + end); - return (E) elements[inc(begin, index, elements.length)]; - } - } - - @Override - public E set(int index, E element) { - int arrayIndex; - if (isEmpty()) { - throw new IndexOutOfBoundsException(); - } else if (begin < end) { - checkElementIndex(index, end - begin); - arrayIndex = begin + index; - } else { - final int size = elements.length - begin + end; - checkElementIndex(index, size); - arrayIndex = inc(begin, index, elements.length); - } - - E oldValue = (E) elements[arrayIndex]; - elements[arrayIndex] = element; - return oldValue; - } - - @Override - public void add(int index, E element) { - if (index == 0) { - addFirst(element); - return; - } - - final int oldSize = size(); - if (index == oldSize) { - addLast(element); - return; - } - - checkPositionIndex(index, oldSize); - - if (oldSize == elements.length) { - grow(); - } - - if (begin < end) { - final int targetIndex = begin + index; - if (end < elements.length) { - System.arraycopy(elements, targetIndex, elements, targetIndex + 1, end - targetIndex); - end++; - } else { - System.arraycopy(elements, begin, elements, begin - 1, targetIndex - begin + 1); - begin--; - } - elements[targetIndex] = element; - } else { - int targetIndex = inc(begin, index, elements.length); - if (targetIndex <= end) { - System.arraycopy(elements, targetIndex, elements, targetIndex + 1, end - targetIndex); - elements[targetIndex] = element; - end++; - } else { - System.arraycopy(elements, begin, elements, begin - 1, targetIndex - begin); - elements[targetIndex - 1] = element; - begin--; - } - } - } - - @Override - public E remove(int index) { - final int oldSize = size(); - checkElementIndex(index, oldSize); - - if (index == 0) { - return removeFirst(); - } - - if (index == oldSize - 1) { - return removeLast(); - } - - final Object res; - - if (begin < end) { - final int targetIndex = begin + index; - res = elements[targetIndex]; - System.arraycopy(elements, targetIndex + 1, elements, targetIndex, end - targetIndex - 1); - end--; - } else { - final int targetIndex = inc(begin, index, elements.length); - res = elements[targetIndex]; - if (targetIndex < end) { - System.arraycopy(elements, targetIndex + 1, elements, targetIndex, end - targetIndex - 1); - end--; - } else { - System.arraycopy(elements, begin, elements, begin + 1, targetIndex - begin); - begin = inc(begin, elements.length); - } - } - - return (E) res; - } - - @Override - public void clear() { - if (isEmpty()) { - return; - } - - if (begin < end) { - Arrays.fill(elements, begin, end, null); - } else { - Arrays.fill(elements, 0, end, null); - Arrays.fill(elements, begin, elements.length, null); - } - - begin = -1; - end = 0; - } - - // Deque - - public void addFirst(E e) { - final int oldSize = size(); - if (oldSize == elements.length) { - grow(); - } - - if (oldSize == 0) { - begin = elements.length - 1; - } else { - begin = dec(begin, elements.length); - } - elements[begin] = e; - } - - public void addLast(E e) { - final int oldSize = size(); - if (oldSize == elements.length) { - grow(); - } - elements[end] = e; - end = inc(end, elements.length); - - if (oldSize == 0) { - begin = 0; - } - } - - public E removeFirst() { - final int oldSize = size(); - if (oldSize == 0) { - throw new NoSuchElementException(); - } - - Object res = elements[begin]; - elements[begin] = null; - - if (oldSize == 1) { - begin = -1; - end = 0; - } else { - begin = inc(begin, elements.length); - } - return (E) res; - } - - public E removeLast() { - final int oldSize = size(); - if (oldSize == 0) { - throw new NoSuchElementException(); - } - final int lastIdx = dec(end, elements.length); - E res = (E) elements[lastIdx]; - elements[lastIdx] = null; - - if (oldSize == 1) { - begin = -1; - end = 0; - } else { - end = lastIdx; - } - return res; - } - - public E getFirst() { - if (isEmpty()) - throw new NoSuchElementException(); - - return get(0); - } - - public E getLast() { - if (isEmpty()) - throw new NoSuchElementException(); - - return get(size() - 1); - } -} \ No newline at end of file diff --git a/src/main/java/com/ghostchu/peerbanhelper/util/logger/JListAppender.java b/src/main/java/com/ghostchu/peerbanhelper/util/logger/JListAppender.java index 3e4a48bbcb..5d2829dbde 100644 --- a/src/main/java/com/ghostchu/peerbanhelper/util/logger/JListAppender.java +++ b/src/main/java/com/ghostchu/peerbanhelper/util/logger/JListAppender.java @@ -5,7 +5,7 @@ import ch.qos.logback.core.AppenderBase; import com.ghostchu.peerbanhelper.Main; import com.ghostchu.peerbanhelper.event.NewLogEntryCreatedEvent; -import com.ghostchu.peerbanhelper.util.collection.CircularArrayList; +import com.google.common.collect.EvictingQueue; import org.slf4j.event.Level; import javax.swing.*; @@ -15,7 +15,7 @@ public class JListAppender extends AppenderBase { public static final LinkedBlockingDeque logEntryDeque = new LinkedBlockingDeque<>(); - public static final CircularArrayList ringDeque = new CircularArrayList<>(300); + public static final EvictingQueue ringDeque = EvictingQueue.create(300); private static final AtomicInteger seq = new AtomicInteger(0); private PatternLayout layout; diff --git a/src/main/java/com/ghostchu/peerbanhelper/web/JavalinWebContainer.java b/src/main/java/com/ghostchu/peerbanhelper/web/JavalinWebContainer.java index e52f8d07bc..4f1091ebf5 100644 --- a/src/main/java/com/ghostchu/peerbanhelper/web/JavalinWebContainer.java +++ b/src/main/java/com/ghostchu/peerbanhelper/web/JavalinWebContainer.java @@ -41,7 +41,7 @@ public class JavalinWebContainer { @Setter @Getter private String token; - private Cache FAIL2BAN = CacheBuilder.newBuilder() + private final Cache FAIL2BAN = CacheBuilder.newBuilder() .expireAfterWrite(15, TimeUnit.MINUTES) .build(); diff --git a/src/main/resources/assets/icon/tray/banned.svg b/src/main/resources/assets/icon/tray/banned.svg new file mode 100644 index 0000000000..8879079d1a --- /dev/null +++ b/src/main/resources/assets/icon/tray/banned.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/main/resources/assets/icon/tray/browser.svg b/src/main/resources/assets/icon/tray/browser.svg new file mode 100644 index 0000000000..2c2062f6ff --- /dev/null +++ b/src/main/resources/assets/icon/tray/browser.svg @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/src/main/resources/assets/icon/tray/close.svg b/src/main/resources/assets/icon/tray/close.svg new file mode 100644 index 0000000000..e1b613e5d0 --- /dev/null +++ b/src/main/resources/assets/icon/tray/close.svg @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/src/main/resources/assets/icon/tray/connection.svg b/src/main/resources/assets/icon/tray/connection.svg new file mode 100644 index 0000000000..a0b2fb9e95 --- /dev/null +++ b/src/main/resources/assets/icon/tray/connection.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/main/resources/assets/icon/tray/open.svg b/src/main/resources/assets/icon/tray/open.svg new file mode 100644 index 0000000000..be55c35687 --- /dev/null +++ b/src/main/resources/assets/icon/tray/open.svg @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/src/main/resources/lang/en_us/messages.yml b/src/main/resources/lang/en_us/messages.yml index 7b2d30a0b8..e116ff446b 100644 --- a/src/main/resources/lang/en_us/messages.yml +++ b/src/main/resources/lang/en_us/messages.yml @@ -317,7 +317,7 @@ ARB_BANNED_REASON: "IP address {} is in the same ban range as another banned IP TOO_MANY_FAILED_ATTEMPT: "Too many failed login attempts. We paused attempt until {}." AMM_SHUTTING_DOWN: "Please wait ActiveMonitoring flush its data from memory to disk... (up to 5 seconds)" -AMM_CLEANING_TABLES: "[Data Cleanup] ActiveMonitoring deleting expired data, this may need a while..." +AMM_CLEANING_TABLES: "[Data Cleanup] ActiveMonitoring deleting expired data, this may take a while..." AMM_CLEANED_UP: "[Data Cleanup] ActiveMonitoring deleted {} expired data" OOBE_DISALLOW_REINIT: "This PeerBanHelper instance already initialized,OOBE interface no-longer available" @@ -492,4 +492,9 @@ EXPRESS_RULE_ENGINE_DISALLOW_UNSAFE_SOURCE_ACCESS: "For security reason, create EXPRESS_RULE_ENGINE_SAVED: "Script saved" BTN_RULES_SCRIPT_COMPILING: "Compiling the scripts from BTN server, this may take a while..." BTN_RULES_SCRIPT_COMPILED: "Compiled {} scripts, took {}ms" -BTN_SERVICES_NEED_RESTART: "BTN Service Unavailable: Restart PeerBanHelper is required for loading BTN module and apply changes." \ No newline at end of file +BTN_SERVICES_NEED_RESTART: "BTN Service Unavailable: Restart PeerBanHelper is required for loading BTN module and apply changes." +GUI_MENU_QUICK_OPERATIONS: "Quick Actions" +GUI_MENU_SHOW_WINDOW: "Open Window" +GUI_MENU_STATS: "Statistics" +GUI_MENU_STATS_BANNED: "Banned {} peers ({} IP addresses)" +GUI_MENU_STATS_DOWNLOADER: "Connected {}/{} downloader" \ No newline at end of file diff --git a/src/main/resources/lang/messages_fallback.yml b/src/main/resources/lang/messages_fallback.yml index e15c8df5ca..0ae4975f67 100644 --- a/src/main/resources/lang/messages_fallback.yml +++ b/src/main/resources/lang/messages_fallback.yml @@ -490,4 +490,9 @@ EXPRESS_RULE_ENGINE_DISALLOW_UNSAFE_SOURCE_ACCESS: "因安全原因,不允许 EXPRESS_RULE_ENGINE_SAVED: "脚本已保存" BTN_RULES_SCRIPT_COMPILING: "正在编译来自 BTN 服务器的可编程脚本,请稍等,这可能需要一点时间……" BTN_RULES_SCRIPT_COMPILED: "已成功编译 {} 个脚本,用时 {}ms" -BTN_SERVICES_NEED_RESTART: "BTN 服务不可用:需要重启 PeerBanHelper 以加载 BTN 模块并应用更改" \ No newline at end of file +BTN_SERVICES_NEED_RESTART: "BTN 服务不可用:需要重启 PeerBanHelper 以加载 BTN 模块并应用更改" +GUI_MENU_QUICK_OPERATIONS: "快速操作" +GUI_MENU_SHOW_WINDOW: "打开主窗口" +GUI_MENU_STATS: "统计数据" +GUI_MENU_STATS_BANNED: "已封禁 {} 个 Peer ({} 个 IP 地址)" +GUI_MENU_STATS_DOWNLOADER: "已连接 {}/{} 个下载器" \ No newline at end of file diff --git a/src/main/resources/lang/zh_cn/messages.yml b/src/main/resources/lang/zh_cn/messages.yml index 8cb666507c..ad580d6e73 100644 --- a/src/main/resources/lang/zh_cn/messages.yml +++ b/src/main/resources/lang/zh_cn/messages.yml @@ -490,4 +490,9 @@ EXPRESS_RULE_ENGINE_DISALLOW_UNSAFE_SOURCE_ACCESS: "因安全原因,不允许 EXPRESS_RULE_ENGINE_SAVED: "脚本已保存" BTN_RULES_SCRIPT_COMPILING: "正在编译来自 BTN 服务器的可编程脚本,请稍等,这可能需要一点时间……" BTN_RULES_SCRIPT_COMPILED: "已成功编译 {} 个脚本,用时 {}ms" -BTN_SERVICES_NEED_RESTART: "BTN 服务不可用:需要重启 PeerBanHelper 以加载 BTN 模块并应用更改" \ No newline at end of file +BTN_SERVICES_NEED_RESTART: "BTN 服务不可用:需要重启 PeerBanHelper 以加载 BTN 模块并应用更改" +GUI_MENU_QUICK_OPERATIONS: "快速操作" +GUI_MENU_SHOW_WINDOW: "打开主窗口" +GUI_MENU_STATS: "统计数据" +GUI_MENU_STATS_BANNED: "已封禁 {} 个 Peer ({} 个 IP 地址)" +GUI_MENU_STATS_DOWNLOADER: "已连接 {}/{} 个下载器" \ No newline at end of file diff --git a/webui/package.json b/webui/package.json index 6da811ddb7..8c79b42faa 100644 --- a/webui/package.json +++ b/webui/package.json @@ -66,7 +66,7 @@ "typescript": "~5.6.3", "typescript-eslint": "^8.13.0", "vite": "^5.4.10", - "vite-bundle-analyzer": "^0.12.1", + "vite-bundle-analyzer": "^0.13.0", "vite-plugin-node-polyfills": "^0.22.0", "vite-plugin-remove-console": "^2.2.0", "vite-plugin-vue-devtools": "^7.6.2", diff --git a/webui/pnpm-lock.yaml b/webui/pnpm-lock.yaml index 8300939c5f..6bcebc08c1 100644 --- a/webui/pnpm-lock.yaml +++ b/webui/pnpm-lock.yaml @@ -162,8 +162,8 @@ importers: specifier: ^5.4.10 version: 5.4.10(@types/node@22.9.0)(less@4.2.0)(sass@1.77.8) vite-bundle-analyzer: - specifier: ^0.12.1 - version: 0.12.1 + specifier: ^0.13.0 + version: 0.13.0 vite-plugin-node-polyfills: specifier: ^0.22.0 version: 0.22.0(rollup@4.24.0)(vite@5.4.10(@types/node@22.9.0)(less@4.2.0)(sass@1.77.8)) @@ -172,7 +172,7 @@ importers: version: 2.2.0 vite-plugin-vue-devtools: specifier: ^7.6.2 - version: 7.6.2(rollup@4.24.0)(vite@5.4.10(@types/node@22.9.0)(less@4.2.0)(sass@1.77.8))(vue@3.5.12(typescript@5.6.3)) + version: 7.6.3(rollup@4.24.0)(vite@5.4.10(@types/node@22.9.0)(less@4.2.0)(sass@1.77.8))(vue@3.5.12(typescript@5.6.3)) vue-eslint-parser: specifier: ^9.4.3 version: 9.4.3(eslint@9.14.0) @@ -414,139 +414,139 @@ packages: resolution: {integrity: sha512-XqVAi0O/KITtznpMK5TP4D+rWfwst5lrsbPbes5c5SPMGjwK7fuvlTdEmG2XUrxzYqDTIPshywyzdVYKooGdGA==} '@esbuild/aix-ppc64@0.21.5': - resolution: {integrity: sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==, tarball: https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz} + resolution: {integrity: sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==} engines: {node: '>=12'} cpu: [ppc64] os: [aix] '@esbuild/android-arm64@0.21.5': - resolution: {integrity: sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==, tarball: https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz} + resolution: {integrity: sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==} engines: {node: '>=12'} cpu: [arm64] os: [android] '@esbuild/android-arm@0.21.5': - resolution: {integrity: sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==, tarball: https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz} + resolution: {integrity: sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==} engines: {node: '>=12'} cpu: [arm] os: [android] '@esbuild/android-x64@0.21.5': - resolution: {integrity: sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==, tarball: https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz} + resolution: {integrity: sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==} engines: {node: '>=12'} cpu: [x64] os: [android] '@esbuild/darwin-arm64@0.21.5': - resolution: {integrity: sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==, tarball: https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz} + resolution: {integrity: sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==} engines: {node: '>=12'} cpu: [arm64] os: [darwin] '@esbuild/darwin-x64@0.21.5': - resolution: {integrity: sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==, tarball: https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz} + resolution: {integrity: sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==} engines: {node: '>=12'} cpu: [x64] os: [darwin] '@esbuild/freebsd-arm64@0.21.5': - resolution: {integrity: sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==, tarball: https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz} + resolution: {integrity: sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==} engines: {node: '>=12'} cpu: [arm64] os: [freebsd] '@esbuild/freebsd-x64@0.21.5': - resolution: {integrity: sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==, tarball: https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz} + resolution: {integrity: sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==} engines: {node: '>=12'} cpu: [x64] os: [freebsd] '@esbuild/linux-arm64@0.21.5': - resolution: {integrity: sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==, tarball: https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz} + resolution: {integrity: sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==} engines: {node: '>=12'} cpu: [arm64] os: [linux] '@esbuild/linux-arm@0.21.5': - resolution: {integrity: sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==, tarball: https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz} + resolution: {integrity: sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==} engines: {node: '>=12'} cpu: [arm] os: [linux] '@esbuild/linux-ia32@0.21.5': - resolution: {integrity: sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==, tarball: https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz} + resolution: {integrity: sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==} engines: {node: '>=12'} cpu: [ia32] os: [linux] '@esbuild/linux-loong64@0.21.5': - resolution: {integrity: sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==, tarball: https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz} + resolution: {integrity: sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==} engines: {node: '>=12'} cpu: [loong64] os: [linux] '@esbuild/linux-mips64el@0.21.5': - resolution: {integrity: sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==, tarball: https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz} + resolution: {integrity: sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==} engines: {node: '>=12'} cpu: [mips64el] os: [linux] '@esbuild/linux-ppc64@0.21.5': - resolution: {integrity: sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==, tarball: https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz} + resolution: {integrity: sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==} engines: {node: '>=12'} cpu: [ppc64] os: [linux] '@esbuild/linux-riscv64@0.21.5': - resolution: {integrity: sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==, tarball: https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz} + resolution: {integrity: sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==} engines: {node: '>=12'} cpu: [riscv64] os: [linux] '@esbuild/linux-s390x@0.21.5': - resolution: {integrity: sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==, tarball: https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz} + resolution: {integrity: sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==} engines: {node: '>=12'} cpu: [s390x] os: [linux] '@esbuild/linux-x64@0.21.5': - resolution: {integrity: sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==, tarball: https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz} + resolution: {integrity: sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==} engines: {node: '>=12'} cpu: [x64] os: [linux] '@esbuild/netbsd-x64@0.21.5': - resolution: {integrity: sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==, tarball: https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz} + resolution: {integrity: sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==} engines: {node: '>=12'} cpu: [x64] os: [netbsd] '@esbuild/openbsd-x64@0.21.5': - resolution: {integrity: sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==, tarball: https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz} + resolution: {integrity: sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==} engines: {node: '>=12'} cpu: [x64] os: [openbsd] '@esbuild/sunos-x64@0.21.5': - resolution: {integrity: sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==, tarball: https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz} + resolution: {integrity: sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==} engines: {node: '>=12'} cpu: [x64] os: [sunos] '@esbuild/win32-arm64@0.21.5': - resolution: {integrity: sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==, tarball: https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz} + resolution: {integrity: sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==} engines: {node: '>=12'} cpu: [arm64] os: [win32] '@esbuild/win32-ia32@0.21.5': - resolution: {integrity: sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==, tarball: https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz} + resolution: {integrity: sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==} engines: {node: '>=12'} cpu: [ia32] os: [win32] '@esbuild/win32-x64@0.21.5': - resolution: {integrity: sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==, tarball: https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz} + resolution: {integrity: sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==} engines: {node: '>=12'} cpu: [x64] os: [win32] @@ -586,16 +586,16 @@ packages: engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@formatjs/ecma402-abstract@2.2.3': - resolution: {integrity: sha512-aElGmleuReGnk2wtYOzYFmNWYoiWWmf1pPPCYg0oiIQSJj0mjc4eUfzUXaSOJ4S8WzI/cLqnCTWjqz904FT2OQ==, tarball: https://registry.npmjs.org/@formatjs/ecma402-abstract/-/ecma402-abstract-2.2.3.tgz} + resolution: {integrity: sha512-aElGmleuReGnk2wtYOzYFmNWYoiWWmf1pPPCYg0oiIQSJj0mjc4eUfzUXaSOJ4S8WzI/cLqnCTWjqz904FT2OQ==} '@formatjs/fast-memoize@2.2.3': - resolution: {integrity: sha512-3jeJ+HyOfu8osl3GNSL4vVHUuWFXR03Iz9jjgI7RwjG6ysu/Ymdr0JRCPHfF5yGbTE6JCrd63EpvX1/WybYRbA==, tarball: https://registry.npmjs.org/@formatjs/fast-memoize/-/fast-memoize-2.2.3.tgz} + resolution: {integrity: sha512-3jeJ+HyOfu8osl3GNSL4vVHUuWFXR03Iz9jjgI7RwjG6ysu/Ymdr0JRCPHfF5yGbTE6JCrd63EpvX1/WybYRbA==} '@formatjs/intl-durationformat@0.6.3': - resolution: {integrity: sha512-sI+ssVZpL9ymdF7j4/qzwSwPHdCYVb2jQqQV71tCVEjDRgTz5jj8JqZTymYcV563v1rHKI2nNwNlp2L8D+zJQw==, tarball: https://registry.npmjs.org/@formatjs/intl-durationformat/-/intl-durationformat-0.6.3.tgz} + resolution: {integrity: sha512-sI+ssVZpL9ymdF7j4/qzwSwPHdCYVb2jQqQV71tCVEjDRgTz5jj8JqZTymYcV563v1rHKI2nNwNlp2L8D+zJQw==} '@formatjs/intl-localematcher@0.5.7': - resolution: {integrity: sha512-GGFtfHGQVFe/niOZp24Kal5b2i36eE2bNL0xi9Sg/yd0TR8aLjcteApZdHmismP5QQax1cMnZM9yWySUUjJteA==, tarball: https://registry.npmjs.org/@formatjs/intl-localematcher/-/intl-localematcher-0.5.7.tgz} + resolution: {integrity: sha512-GGFtfHGQVFe/niOZp24Kal5b2i36eE2bNL0xi9Sg/yd0TR8aLjcteApZdHmismP5QQax1cMnZM9yWySUUjJteA==} '@guolao/vue-monaco-editor@1.5.4': resolution: {integrity: sha512-eyBAqxJeDpV4mZYZSpNvh3xUgKCld5eEe0dBtjJhsy2+L0MB6PYFZ/FbPHNwskgp2RoIpfn1DLrIhXXE3lVbwQ==} @@ -666,15 +666,15 @@ packages: monaco-editor: '>= 0.21.0 < 1' '@nodelib/fs.scandir@2.1.5': - resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==, tarball: https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz} + resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} engines: {node: '>= 8'} '@nodelib/fs.stat@2.0.5': - resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==, tarball: https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz} + resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} engines: {node: '>= 8'} '@nodelib/fs.walk@1.2.8': - resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==, tarball: https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz} + resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} engines: {node: '>= 8'} '@octokit/auth-token@5.1.1': @@ -738,82 +738,82 @@ packages: optional: true '@rollup/rollup-android-arm-eabi@4.24.0': - resolution: {integrity: sha512-Q6HJd7Y6xdB48x8ZNVDOqsbh2uByBhgK8PiQgPhwkIw/HC/YX5Ghq2mQY5sRMZWHb3VsFkWooUVOZHKr7DmDIA==, tarball: https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.24.0.tgz} + resolution: {integrity: sha512-Q6HJd7Y6xdB48x8ZNVDOqsbh2uByBhgK8PiQgPhwkIw/HC/YX5Ghq2mQY5sRMZWHb3VsFkWooUVOZHKr7DmDIA==} cpu: [arm] os: [android] '@rollup/rollup-android-arm64@4.24.0': - resolution: {integrity: sha512-ijLnS1qFId8xhKjT81uBHuuJp2lU4x2yxa4ctFPtG+MqEE6+C5f/+X/bStmxapgmwLwiL3ih122xv8kVARNAZA==, tarball: https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.24.0.tgz} + resolution: {integrity: sha512-ijLnS1qFId8xhKjT81uBHuuJp2lU4x2yxa4ctFPtG+MqEE6+C5f/+X/bStmxapgmwLwiL3ih122xv8kVARNAZA==} cpu: [arm64] os: [android] '@rollup/rollup-darwin-arm64@4.24.0': - resolution: {integrity: sha512-bIv+X9xeSs1XCk6DVvkO+S/z8/2AMt/2lMqdQbMrmVpgFvXlmde9mLcbQpztXm1tajC3raFDqegsH18HQPMYtA==, tarball: https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.24.0.tgz} + resolution: {integrity: sha512-bIv+X9xeSs1XCk6DVvkO+S/z8/2AMt/2lMqdQbMrmVpgFvXlmde9mLcbQpztXm1tajC3raFDqegsH18HQPMYtA==} cpu: [arm64] os: [darwin] '@rollup/rollup-darwin-x64@4.24.0': - resolution: {integrity: sha512-X6/nOwoFN7RT2svEQWUsW/5C/fYMBe4fnLK9DQk4SX4mgVBiTA9h64kjUYPvGQ0F/9xwJ5U5UfTbl6BEjaQdBQ==, tarball: https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.24.0.tgz} + resolution: {integrity: sha512-X6/nOwoFN7RT2svEQWUsW/5C/fYMBe4fnLK9DQk4SX4mgVBiTA9h64kjUYPvGQ0F/9xwJ5U5UfTbl6BEjaQdBQ==} cpu: [x64] os: [darwin] '@rollup/rollup-linux-arm-gnueabihf@4.24.0': - resolution: {integrity: sha512-0KXvIJQMOImLCVCz9uvvdPgfyWo93aHHp8ui3FrtOP57svqrF/roSSR5pjqL2hcMp0ljeGlU4q9o/rQaAQ3AYA==, tarball: https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.24.0.tgz} + resolution: {integrity: sha512-0KXvIJQMOImLCVCz9uvvdPgfyWo93aHHp8ui3FrtOP57svqrF/roSSR5pjqL2hcMp0ljeGlU4q9o/rQaAQ3AYA==} cpu: [arm] os: [linux] '@rollup/rollup-linux-arm-musleabihf@4.24.0': - resolution: {integrity: sha512-it2BW6kKFVh8xk/BnHfakEeoLPv8STIISekpoF+nBgWM4d55CZKc7T4Dx1pEbTnYm/xEKMgy1MNtYuoA8RFIWw==, tarball: https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.24.0.tgz} + resolution: {integrity: sha512-it2BW6kKFVh8xk/BnHfakEeoLPv8STIISekpoF+nBgWM4d55CZKc7T4Dx1pEbTnYm/xEKMgy1MNtYuoA8RFIWw==} cpu: [arm] os: [linux] '@rollup/rollup-linux-arm64-gnu@4.24.0': - resolution: {integrity: sha512-i0xTLXjqap2eRfulFVlSnM5dEbTVque/3Pi4g2y7cxrs7+a9De42z4XxKLYJ7+OhE3IgxvfQM7vQc43bwTgPwA==, tarball: https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.24.0.tgz} + resolution: {integrity: sha512-i0xTLXjqap2eRfulFVlSnM5dEbTVque/3Pi4g2y7cxrs7+a9De42z4XxKLYJ7+OhE3IgxvfQM7vQc43bwTgPwA==} cpu: [arm64] os: [linux] '@rollup/rollup-linux-arm64-musl@4.24.0': - resolution: {integrity: sha512-9E6MKUJhDuDh604Qco5yP/3qn3y7SLXYuiC0Rpr89aMScS2UAmK1wHP2b7KAa1nSjWJc/f/Lc0Wl1L47qjiyQw==, tarball: https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.24.0.tgz} + resolution: {integrity: sha512-9E6MKUJhDuDh604Qco5yP/3qn3y7SLXYuiC0Rpr89aMScS2UAmK1wHP2b7KAa1nSjWJc/f/Lc0Wl1L47qjiyQw==} cpu: [arm64] os: [linux] '@rollup/rollup-linux-powerpc64le-gnu@4.24.0': - resolution: {integrity: sha512-2XFFPJ2XMEiF5Zi2EBf4h73oR1V/lycirxZxHZNc93SqDN/IWhYYSYj8I9381ikUFXZrz2v7r2tOVk2NBwxrWw==, tarball: https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.24.0.tgz} + resolution: {integrity: sha512-2XFFPJ2XMEiF5Zi2EBf4h73oR1V/lycirxZxHZNc93SqDN/IWhYYSYj8I9381ikUFXZrz2v7r2tOVk2NBwxrWw==} cpu: [ppc64] os: [linux] '@rollup/rollup-linux-riscv64-gnu@4.24.0': - resolution: {integrity: sha512-M3Dg4hlwuntUCdzU7KjYqbbd+BLq3JMAOhCKdBE3TcMGMZbKkDdJ5ivNdehOssMCIokNHFOsv7DO4rlEOfyKpg==, tarball: https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.24.0.tgz} + resolution: {integrity: sha512-M3Dg4hlwuntUCdzU7KjYqbbd+BLq3JMAOhCKdBE3TcMGMZbKkDdJ5ivNdehOssMCIokNHFOsv7DO4rlEOfyKpg==} cpu: [riscv64] os: [linux] '@rollup/rollup-linux-s390x-gnu@4.24.0': - resolution: {integrity: sha512-mjBaoo4ocxJppTorZVKWFpy1bfFj9FeCMJqzlMQGjpNPY9JwQi7OuS1axzNIk0nMX6jSgy6ZURDZ2w0QW6D56g==, tarball: https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.24.0.tgz} + resolution: {integrity: sha512-mjBaoo4ocxJppTorZVKWFpy1bfFj9FeCMJqzlMQGjpNPY9JwQi7OuS1axzNIk0nMX6jSgy6ZURDZ2w0QW6D56g==} cpu: [s390x] os: [linux] '@rollup/rollup-linux-x64-gnu@4.24.0': - resolution: {integrity: sha512-ZXFk7M72R0YYFN5q13niV0B7G8/5dcQ9JDp8keJSfr3GoZeXEoMHP/HlvqROA3OMbMdfr19IjCeNAnPUG93b6A==, tarball: https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.24.0.tgz} + resolution: {integrity: sha512-ZXFk7M72R0YYFN5q13niV0B7G8/5dcQ9JDp8keJSfr3GoZeXEoMHP/HlvqROA3OMbMdfr19IjCeNAnPUG93b6A==} cpu: [x64] os: [linux] '@rollup/rollup-linux-x64-musl@4.24.0': - resolution: {integrity: sha512-w1i+L7kAXZNdYl+vFvzSZy8Y1arS7vMgIy8wusXJzRrPyof5LAb02KGr1PD2EkRcl73kHulIID0M501lN+vobQ==, tarball: https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.24.0.tgz} + resolution: {integrity: sha512-w1i+L7kAXZNdYl+vFvzSZy8Y1arS7vMgIy8wusXJzRrPyof5LAb02KGr1PD2EkRcl73kHulIID0M501lN+vobQ==} cpu: [x64] os: [linux] '@rollup/rollup-win32-arm64-msvc@4.24.0': - resolution: {integrity: sha512-VXBrnPWgBpVDCVY6XF3LEW0pOU51KbaHhccHw6AS6vBWIC60eqsH19DAeeObl+g8nKAz04QFdl/Cefta0xQtUQ==, tarball: https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.24.0.tgz} + resolution: {integrity: sha512-VXBrnPWgBpVDCVY6XF3LEW0pOU51KbaHhccHw6AS6vBWIC60eqsH19DAeeObl+g8nKAz04QFdl/Cefta0xQtUQ==} cpu: [arm64] os: [win32] '@rollup/rollup-win32-ia32-msvc@4.24.0': - resolution: {integrity: sha512-xrNcGDU0OxVcPTH/8n/ShH4UevZxKIO6HJFK0e15XItZP2UcaiLFd5kiX7hJnqCbSztUF8Qot+JWBC/QXRPYWQ==, tarball: https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.24.0.tgz} + resolution: {integrity: sha512-xrNcGDU0OxVcPTH/8n/ShH4UevZxKIO6HJFK0e15XItZP2UcaiLFd5kiX7hJnqCbSztUF8Qot+JWBC/QXRPYWQ==} cpu: [ia32] os: [win32] '@rollup/rollup-win32-x64-msvc@4.24.0': - resolution: {integrity: sha512-fbMkAF7fufku0N2dE5TBXcNlg0pt0cJue4xBRE2Qc5Vqikxr4VCgKj/ht6SMdFcOacVA9rqF70APJ8RN/4vMJw==, tarball: https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.24.0.tgz} + resolution: {integrity: sha512-fbMkAF7fufku0N2dE5TBXcNlg0pt0cJue4xBRE2Qc5Vqikxr4VCgKj/ht6SMdFcOacVA9rqF70APJ8RN/4vMJw==} cpu: [x64] os: [win32] @@ -848,10 +848,10 @@ packages: resolution: {integrity: sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg==} '@types/node@16.18.119': - resolution: {integrity: sha512-ia7V9a2FnhUFfetng4/sRPBMTwHZUkPFY736rb1cg9AgG7MZdR97q7/nLR9om+sq5f1la9C857E0l/nrI0RiFQ==, tarball: https://registry.npmjs.org/@types/node/-/node-16.18.119.tgz} + resolution: {integrity: sha512-ia7V9a2FnhUFfetng4/sRPBMTwHZUkPFY736rb1cg9AgG7MZdR97q7/nLR9om+sq5f1la9C857E0l/nrI0RiFQ==} '@types/node@22.9.0': - resolution: {integrity: sha512-vuyHg81vvWA1Z1ELfvLko2c8f34gyA0zaic0+Rllc5lbCnbSyuvb2Oxpm6TAUAC/2xZN3QGqxBNggD1nNR2AfQ==, tarball: https://registry.npmjs.org/@types/node/-/node-22.9.0.tgz} + resolution: {integrity: sha512-vuyHg81vvWA1Z1ELfvLko2c8f34gyA0zaic0+Rllc5lbCnbSyuvb2Oxpm6TAUAC/2xZN3QGqxBNggD1nNR2AfQ==} '@types/uuid@10.0.0': resolution: {integrity: sha512-7gqG38EyHgyP1S+7+xomFtL+ZNHcKv6DwNaCZmJmo1vgMugyF3TCnXVg4t1uk89mLNwnLtnY3TpOpCOyp1/xHQ==} @@ -860,7 +860,7 @@ packages: resolution: {integrity: sha512-g9gZnnXVq7gM7v3tJCWV/qw7w+KeOlSHAhgF9RytFyifW6AF61hdT2ucrYhPq9hLs5JIryeupHV3qGk95dH9ow==} '@typescript-eslint/eslint-plugin@8.13.0': - resolution: {integrity: sha512-nQtBLiZYMUPkclSeC3id+x4uVd1SGtHuElTxL++SfP47jR0zfkZBJHc+gL4qPsgTuypz0k8Y2GheaDYn6Gy3rg==, tarball: https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.13.0.tgz} + resolution: {integrity: sha512-nQtBLiZYMUPkclSeC3id+x4uVd1SGtHuElTxL++SfP47jR0zfkZBJHc+gL4qPsgTuypz0k8Y2GheaDYn6Gy3rg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: '@typescript-eslint/parser': ^8.0.0 || ^8.0.0-alpha.0 @@ -871,7 +871,7 @@ packages: optional: true '@typescript-eslint/parser@8.13.0': - resolution: {integrity: sha512-w0xp+xGg8u/nONcGw1UXAr6cjCPU1w0XVyBs6Zqaj5eLmxkKQAByTdV/uGgNN5tVvN/kKpoQlP2cL7R+ajZZIQ==, tarball: https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.13.0.tgz} + resolution: {integrity: sha512-w0xp+xGg8u/nONcGw1UXAr6cjCPU1w0XVyBs6Zqaj5eLmxkKQAByTdV/uGgNN5tVvN/kKpoQlP2cL7R+ajZZIQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 @@ -881,11 +881,11 @@ packages: optional: true '@typescript-eslint/scope-manager@8.13.0': - resolution: {integrity: sha512-XsGWww0odcUT0gJoBZ1DeulY1+jkaHUciUq4jKNv4cpInbvvrtDoyBH9rE/n2V29wQJPk8iCH1wipra9BhmiMA==, tarball: https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.13.0.tgz} + resolution: {integrity: sha512-XsGWww0odcUT0gJoBZ1DeulY1+jkaHUciUq4jKNv4cpInbvvrtDoyBH9rE/n2V29wQJPk8iCH1wipra9BhmiMA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@typescript-eslint/type-utils@8.13.0': - resolution: {integrity: sha512-Rqnn6xXTR316fP4D2pohZenJnp+NwQ1mo7/JM+J1LWZENSLkJI8ID8QNtlvFeb0HnFSK94D6q0cnMX6SbE5/vA==, tarball: https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.13.0.tgz} + resolution: {integrity: sha512-Rqnn6xXTR316fP4D2pohZenJnp+NwQ1mo7/JM+J1LWZENSLkJI8ID8QNtlvFeb0HnFSK94D6q0cnMX6SbE5/vA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '*' @@ -894,11 +894,11 @@ packages: optional: true '@typescript-eslint/types@8.13.0': - resolution: {integrity: sha512-4cyFErJetFLckcThRUFdReWJjVsPCqyBlJTi6IDEpc1GWCIIZRFxVppjWLIMcQhNGhdWJJRYFHpHoDWvMlDzng==, tarball: https://registry.npmjs.org/@typescript-eslint/types/-/types-8.13.0.tgz} + resolution: {integrity: sha512-4cyFErJetFLckcThRUFdReWJjVsPCqyBlJTi6IDEpc1GWCIIZRFxVppjWLIMcQhNGhdWJJRYFHpHoDWvMlDzng==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@typescript-eslint/typescript-estree@8.13.0': - resolution: {integrity: sha512-v7SCIGmVsRK2Cy/LTLGN22uea6SaUIlpBcO/gnMGT/7zPtxp90bphcGf4fyrCQl3ZtiBKqVTG32hb668oIYy1g==, tarball: https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.13.0.tgz} + resolution: {integrity: sha512-v7SCIGmVsRK2Cy/LTLGN22uea6SaUIlpBcO/gnMGT/7zPtxp90bphcGf4fyrCQl3ZtiBKqVTG32hb668oIYy1g==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '*' @@ -907,13 +907,13 @@ packages: optional: true '@typescript-eslint/utils@8.13.0': - resolution: {integrity: sha512-A1EeYOND6Uv250nybnLZapeXpYMl8tkzYUxqmoKAWnI4sei3ihf2XdZVd+vVOmHGcp3t+P7yRrNsyyiXTvShFQ==, tarball: https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.13.0.tgz} + resolution: {integrity: sha512-A1EeYOND6Uv250nybnLZapeXpYMl8tkzYUxqmoKAWnI4sei3ihf2XdZVd+vVOmHGcp3t+P7yRrNsyyiXTvShFQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 '@typescript-eslint/visitor-keys@8.13.0': - resolution: {integrity: sha512-7N/+lztJqH4Mrf0lb10R/CbI1EaAMMGyF5y0oJvFoAhafwgiRA7TXyd8TFn8FC8k5y2dTsYogg238qavRGNnlw==, tarball: https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.13.0.tgz} + resolution: {integrity: sha512-7N/+lztJqH4Mrf0lb10R/CbI1EaAMMGyF5y0oJvFoAhafwgiRA7TXyd8TFn8FC8k5y2dTsYogg238qavRGNnlw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@vitejs/plugin-vue@5.1.4': @@ -966,16 +966,16 @@ packages: '@vue/devtools-api@6.6.4': resolution: {integrity: sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g==} - '@vue/devtools-core@7.6.2': - resolution: {integrity: sha512-hJfjNR3ai94Mb6i0PB42kxUPkPreS6Dl07FUaHAcw+umtkUX55jTXe7+mhsHx9NI6NFT+1WMFREIy8O81KLYyA==} + '@vue/devtools-core@7.6.3': + resolution: {integrity: sha512-C7FOuh3Z+EmXXzDU9eRjHQL7zW7/CFovM6yCNNpUb+zXxhrn4fiqTum+a3gNau9DuzYfEtQXwZ9F7MeK0JKYVw==} peerDependencies: vue: ^3.0.0 - '@vue/devtools-kit@7.6.2': - resolution: {integrity: sha512-k61BxHRmcTtIQZFouF9QWt9nCCNtSdw12lhg8VNtHq5/XOBGD+ewiK27a40UJ8UPYoCJvi80hbvbYr5E/Zeu1g==} + '@vue/devtools-kit@7.6.3': + resolution: {integrity: sha512-ETsFc8GlOp04rSFN79tB2TpVloWfsSx9BoCSElV3w3CaJTSBfz42KsIi5Ka+dNTJs1jY7QVLTDeoBmUGgA9h2A==} - '@vue/devtools-shared@7.6.2': - resolution: {integrity: sha512-lcjyJ7hCC0W0kNwnCGMLVTMvDLoZgjcq9BvboPgS+6jQyDul7fpzRSKTGtGhCHoxrDox7qBAKGbAl2Rcf7GE1A==} + '@vue/devtools-shared@7.6.3': + resolution: {integrity: sha512-wJW5QF27i16+sNQIaes8QoEZg1eqEgF83GkiPUlEQe9k7ZoHXHV7PRrnrxOKem42sIHPU813J2V/ZK1uqTJe6g==} '@vue/language-core@2.1.10': resolution: {integrity: sha512-DAI289d0K3AB5TUG3xDp9OuQ71CnrujQwJrQnfuZDwo6eGNf0UoRlPuaVNO+Zrn65PC3j0oB2i7mNmVPggeGeQ==} @@ -1052,7 +1052,7 @@ packages: engines: {node: '>=16'} anymatch@3.1.3: - resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==, tarball: https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz} + resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} engines: {node: '>= 8'} argparse@2.0.1: @@ -1084,7 +1084,7 @@ packages: resolution: {integrity: sha512-Nik3Sc0ncrMK4UUdXQmAnRtzmNQTAAXmXIopizwZ1W1t8QmfJj+zL4OA2I7XPTPW5z5TDqv4hRo/JzouDJnX3A==} binary-extensions@2.3.0: - resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==, tarball: https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz} + resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} engines: {node: '>=8'} birpc@0.2.19: @@ -1106,7 +1106,7 @@ packages: resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} braces@3.0.3: - resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==, tarball: https://registry.npmjs.org/braces/-/braces-3.0.3.tgz} + resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} engines: {node: '>=8'} brorand@1.1.0: @@ -1160,8 +1160,8 @@ packages: resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} engines: {node: '>=6'} - caniuse-lite@1.0.30001676: - resolution: {integrity: sha512-Qz6zwGCiPghQXGJvgQAem79esjitvJ+CxSbSQkW9H/UX5hg8XM88d4lp2W+MEQ81j+Hip58Il+jGVdazk1z9cw==} + caniuse-lite@1.0.30001678: + resolution: {integrity: sha512-RR+4U/05gNtps58PEBDZcPWTgEO2MBeoPZ96aQcjmfkBWRIDfN451fW2qyDA9/+HohLLIL5GqiMwA+IB1pWarw==} chalk@2.4.2: resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} @@ -1172,7 +1172,7 @@ packages: engines: {node: '>=10'} chokidar@3.6.0: - resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==, tarball: https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz} + resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} engines: {node: '>= 8.10.0'} cipher-base@1.0.4: @@ -1252,6 +1252,10 @@ packages: resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} engines: {node: '>= 8'} + cross-spawn@7.0.5: + resolution: {integrity: sha512-ZVJrKKYunU38/76t0RMOulHOnUcbU9GbpWKAOZ0mhjr7CX6FVrH+4FrAapSOekrgFQ3f/8gwMEuIft0aKq6Hug==} + engines: {node: '>= 8'} + crypto-browserify@3.12.0: resolution: {integrity: sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==} @@ -1323,8 +1327,8 @@ packages: echarts@5.5.1: resolution: {integrity: sha512-Fce8upazaAXUVUVsjgV6mBnGuqgO+JNDlcgF79Dksy4+wgGpQB2lmYoO4TSweFg/mZITdpGHomw/cNBJZj1icA==} - electron-to-chromium@1.5.50: - resolution: {integrity: sha512-eMVObiUQ2LdgeO1F/ySTXsvqvxb6ZH2zPGaMYsWzRDdOddUa77tdmI0ltg+L16UpbWdhPmuF3wIQYyQq65WfZw==} + electron-to-chromium@1.5.55: + resolution: {integrity: sha512-6maZ2ASDOTBtjt9FhqYPRnbvKU5tjG0IN9SztUOWYw2AzNDNpKJYLJmlK0/En4Hs/aiWnB+JZ+gW19PIGszgKg==} elliptic@6.6.0: resolution: {integrity: sha512-dpwoQcLc/2WLQvJvLRHKZ+f9FgOdjnq11rurqwekGQygGPsYSK29OMMD2WalatiqQ+XGFDglTNixpPfI+lpaAA==} @@ -1334,7 +1338,7 @@ packages: engines: {node: '>=0.12'} errno@0.1.8: - resolution: {integrity: sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==, tarball: https://registry.npmjs.org/errno/-/errno-0.1.8.tgz} + resolution: {integrity: sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==} hasBin: true error-stack-parser-es@0.1.5: @@ -1445,7 +1449,7 @@ packages: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} fast-glob@3.3.2: - resolution: {integrity: sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==, tarball: https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz} + resolution: {integrity: sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==} engines: {node: '>=8.6.0'} fast-json-stable-stringify@2.1.0: @@ -1455,14 +1459,14 @@ packages: resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} fastq@1.17.1: - resolution: {integrity: sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==, tarball: https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz} + resolution: {integrity: sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==} file-entry-cache@8.0.0: resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==} engines: {node: '>=16.0.0'} fill-range@7.1.1: - resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==, tarball: https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz} + resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} engines: {node: '>=8'} find-up@5.0.0: @@ -1484,7 +1488,7 @@ packages: engines: {node: '>=14.14'} fsevents@2.3.3: - resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==, tarball: https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz} + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} os: [darwin] @@ -1508,7 +1512,7 @@ packages: engines: {node: '>=16'} glob-parent@5.1.2: - resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==, tarball: https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz} + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} engines: {node: '>= 6'} glob-parent@6.0.2: @@ -1531,10 +1535,10 @@ packages: resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==} graceful-fs@4.2.11: - resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==, tarball: https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz} + resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} graphemer@1.4.0: - resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==, tarball: https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz} + resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} has-flag@3.0.0: resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} @@ -1612,12 +1616,12 @@ packages: engines: {node: '>= 4'} image-size@0.5.5: - resolution: {integrity: sha512-6TDAlDPZxUFCv+fuOkIoXT/V/f3Qbq8e37p+YOiYrUv3v9cc3/6x78VdfPgFVaB9dZYeLUfKgHRebpkm/oP2VQ==, tarball: https://registry.npmjs.org/image-size/-/image-size-0.5.5.tgz} + resolution: {integrity: sha512-6TDAlDPZxUFCv+fuOkIoXT/V/f3Qbq8e37p+YOiYrUv3v9cc3/6x78VdfPgFVaB9dZYeLUfKgHRebpkm/oP2VQ==} engines: {node: '>=0.10.0'} hasBin: true immutable@4.3.7: - resolution: {integrity: sha512-1hqclzwYwjRDFLjcFxOM5AYkkG0rpFPpr1RLPMEuGczoS7YA8gLhy8SWXYRAA/XwfEHpfo3cw5JGioS32fnMRw==, tarball: https://registry.npmjs.org/immutable/-/immutable-4.3.7.tgz} + resolution: {integrity: sha512-1hqclzwYwjRDFLjcFxOM5AYkkG0rpFPpr1RLPMEuGczoS7YA8gLhy8SWXYRAA/XwfEHpfo3cw5JGioS32fnMRw==} import-fresh@3.3.0: resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==} @@ -1642,7 +1646,7 @@ packages: resolution: {integrity: sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==} is-binary-path@2.1.0: - resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==, tarball: https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz} + resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} engines: {node: '>=8'} is-callable@1.2.7: @@ -1687,7 +1691,7 @@ packages: engines: {node: '>= 0.4'} is-number@7.0.0: - resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==, tarball: https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz} + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} engines: {node: '>=0.12.0'} is-regexp@3.1.0: @@ -1807,7 +1811,7 @@ packages: engines: {node: '>=12'} make-dir@2.1.0: - resolution: {integrity: sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==, tarball: https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz} + resolution: {integrity: sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==} engines: {node: '>=6'} markdown-it@14.1.0: @@ -1828,11 +1832,11 @@ packages: resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} merge2@1.4.1: - resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==, tarball: https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz} + resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} engines: {node: '>= 8'} micromatch@4.0.8: - resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==, tarball: https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz} + resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} engines: {node: '>=8.6'} miller-rabin@4.0.1: @@ -1840,7 +1844,7 @@ packages: hasBin: true mime@1.6.0: - resolution: {integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==, tarball: https://registry.npmjs.org/mime/-/mime-1.6.0.tgz} + resolution: {integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==} engines: {node: '>=4'} hasBin: true @@ -1889,7 +1893,7 @@ packages: resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} needle@3.3.1: - resolution: {integrity: sha512-6k0YULvhpw+RoLNiQCRKOl09Rv1dPLr8hHnVjHqdolKwDrdNyk+Hmrthi4lIGPPz3r39dLx0hsF5s40sZ3Us4Q==, tarball: https://registry.npmjs.org/needle/-/needle-3.3.1.tgz} + resolution: {integrity: sha512-6k0YULvhpw+RoLNiQCRKOl09Rv1dPLr8hHnVjHqdolKwDrdNyk+Hmrthi4lIGPPz3r39dLx0hsF5s40sZ3Us4Q==} engines: {node: '>= 4.4.x'} hasBin: true @@ -1901,7 +1905,7 @@ packages: engines: {node: '>=10'} normalize-path@3.0.0: - resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==, tarball: https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz} + resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} engines: {node: '>=0.10.0'} normalize.css@8.0.1: @@ -2031,7 +2035,7 @@ packages: engines: {node: '>=6'} pinia@2.2.6: - resolution: {integrity: sha512-vIsR8JkDN5Ga2vAxqOE2cJj4VtsHnzpR1Fz30kClxlh0yCHfec6uoMeM3e/ddqmwFUejK3NlrcQa/shnpyT4hA==, tarball: https://registry.npmjs.org/pinia/-/pinia-2.2.6.tgz} + resolution: {integrity: sha512-vIsR8JkDN5Ga2vAxqOE2cJj4VtsHnzpR1Fz30kClxlh0yCHfec6uoMeM3e/ddqmwFUejK3NlrcQa/shnpyT4hA==} peerDependencies: '@vue/composition-api': ^1.4.0 typescript: '>=4.4.4' @@ -2100,7 +2104,7 @@ packages: engines: {node: '>=0.4.x'} queue-microtask@1.2.3: - resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==, tarball: https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz} + resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} randombytes@2.1.0: resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==} @@ -2120,7 +2124,7 @@ packages: engines: {node: '>= 6'} readdirp@3.6.0: - resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==, tarball: https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz} + resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} engines: {node: '>=8.10.0'} resize-observer-polyfill@1.5.1: @@ -2135,7 +2139,7 @@ packages: hasBin: true reusify@1.0.4: - resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==, tarball: https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz} + resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} engines: {iojs: '>=1.0.0', node: '>=0.10.0'} rfdc@1.4.1: @@ -2154,7 +2158,7 @@ packages: engines: {node: '>=18'} run-parallel@1.2.0: - resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==, tarball: https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz} + resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} safe-buffer@5.1.2: resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} @@ -2166,7 +2170,7 @@ packages: resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} sass@1.77.8: - resolution: {integrity: sha512-4UHg6prsrycW20fqLGPShtEvo/WyHRVRHwOP4DzkUrObWoWI05QBSfzU71TVB7PFaL104TwNaHpjlWXAZbQiNQ==, tarball: https://registry.npmjs.org/sass/-/sass-1.77.8.tgz} + resolution: {integrity: sha512-4UHg6prsrycW20fqLGPShtEvo/WyHRVRHwOP4DzkUrObWoWI05QBSfzU71TVB7PFaL104TwNaHpjlWXAZbQiNQ==} engines: {node: '>=14.0.0'} hasBin: true @@ -2240,7 +2244,7 @@ packages: engines: {node: '>=0.10.0'} source-map@0.6.1: - resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==, tarball: https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz} + resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} engines: {node: '>=0.10.0'} speakingurl@14.0.1: @@ -2309,7 +2313,7 @@ packages: engines: {node: '>=4'} to-regex-range@5.0.1: - resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==, tarball: https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz} + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} engines: {node: '>=8.0'} toggle-selection@1.0.6: @@ -2320,7 +2324,7 @@ packages: engines: {node: '>=6'} ts-api-utils@1.4.0: - resolution: {integrity: sha512-032cPxaEKwM+GT3vA5JXNzIaizx388rhsSW79vGRNGXfRRAdEAn2mvk36PvK5HnOchyWZ7afLEXqYCvPCrzuzQ==, tarball: https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.4.0.tgz} + resolution: {integrity: sha512-032cPxaEKwM+GT3vA5JXNzIaizx388rhsSW79vGRNGXfRRAdEAn2mvk36PvK5HnOchyWZ7afLEXqYCvPCrzuzQ==} engines: {node: '>=16'} peerDependencies: typescript: '>=4.2.0' @@ -2343,7 +2347,7 @@ packages: engines: {node: '>=10'} typescript-eslint@8.13.0: - resolution: {integrity: sha512-vIMpDRJrQd70au2G8w34mPps0ezFSPMEX4pXkTzUkrNbRX+36ais2ksGWN0esZL+ZMaFJEneOBHzCgSqle7DHw==, tarball: https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.13.0.tgz} + resolution: {integrity: sha512-vIMpDRJrQd70au2G8w34mPps0ezFSPMEX4pXkTzUkrNbRX+36ais2ksGWN0esZL+ZMaFJEneOBHzCgSqle7DHw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '*' @@ -2360,7 +2364,7 @@ packages: resolution: {integrity: sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==} undici-types@6.19.8: - resolution: {integrity: sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==, tarball: https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz} + resolution: {integrity: sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==} universal-user-agent@7.0.2: resolution: {integrity: sha512-0JCqzSKnStlRRQfCdowvqy3cy0Dvtlb8xecj/H8JFZuCze4rwjPZQOgvFvn0Ws/usCHQFGpyr+pB9adaGwXn4Q==} @@ -2395,8 +2399,8 @@ packages: resolution: {integrity: sha512-14FfcOJmqdjbBPdDjFQyk/SdT4NySW4eM0zcG+HqbHP5jzuH56xO3J1DGhgs/cEMCfwYi3HQI1gnTO62iaG+tQ==} hasBin: true - vite-bundle-analyzer@0.12.1: - resolution: {integrity: sha512-mIYwsDvTYCqXAUtOZIL3f7NdwWUeL/MlNFhOJzlTdcZE4pye6h06IEnOvWhnc/e+HM4oVVNxuRHZt0Rz6VO7EA==} + vite-bundle-analyzer@0.13.0: + resolution: {integrity: sha512-59ScOf+dCf6EmPpBiQawHf2vGVm8+kaiEwDQkMoMWMNweD4VWtxpU+voPe78z74YrIuP19RCaNCAfjP+0NOJ+A==} vite-hot-client@0.2.3: resolution: {integrity: sha512-rOGAV7rUlUHX89fP2p2v0A2WWvV3QMX2UYq0fRqsWSvFvev4atHWqjwGoKaZT1VTKyLGk533ecu3eyd0o59CAg==} @@ -2421,8 +2425,8 @@ packages: vite-plugin-remove-console@2.2.0: resolution: {integrity: sha512-qgjh5pz75MdE9Kzs8J0kBwaCfifHV0ezRbB9rpGsIOxam+ilcGV7WOk91vFJXquzRmiKrFh3Hxlh0JJWAmXTbQ==} - vite-plugin-vue-devtools@7.6.2: - resolution: {integrity: sha512-YPE/8AIBsomvHadZ02Kkp8yZo2FR0SFNjbC2lcMgW+hNA1ZoXu9b5oi18gTMzJcLLFRNNSMNjShA4RLqXlIR/A==} + vite-plugin-vue-devtools@7.6.3: + resolution: {integrity: sha512-p1rZMKzreWqxj9U05RaxY1vDoOhGYhA6iX8vKfo4nD6jqTmVoGjjk+U1g5HYwwTCdr/eck3kzO2f4gnPCjqVKA==} engines: {node: '>=v14.21.3'} peerDependencies: vite: ^3.1.0 || ^4.0.0-0 || ^5.0.0-0 @@ -3405,10 +3409,10 @@ snapshots: '@vue/devtools-api@6.6.4': {} - '@vue/devtools-core@7.6.2(vite@5.4.10(@types/node@22.9.0)(less@4.2.0)(sass@1.77.8))(vue@3.5.12(typescript@5.6.3))': + '@vue/devtools-core@7.6.3(vite@5.4.10(@types/node@22.9.0)(less@4.2.0)(sass@1.77.8))(vue@3.5.12(typescript@5.6.3))': dependencies: - '@vue/devtools-kit': 7.6.2 - '@vue/devtools-shared': 7.6.2 + '@vue/devtools-kit': 7.6.3 + '@vue/devtools-shared': 7.6.3 mitt: 3.0.1 nanoid: 3.3.7 pathe: 1.1.2 @@ -3417,9 +3421,9 @@ snapshots: transitivePeerDependencies: - vite - '@vue/devtools-kit@7.6.2': + '@vue/devtools-kit@7.6.3': dependencies: - '@vue/devtools-shared': 7.6.2 + '@vue/devtools-shared': 7.6.3 birpc: 0.2.19 hookable: 5.5.3 mitt: 3.0.1 @@ -3427,7 +3431,7 @@ snapshots: speakingurl: 14.0.1 superjson: 2.2.1 - '@vue/devtools-shared@7.6.2': + '@vue/devtools-shared@7.6.3': dependencies: rfdc: 1.4.1 @@ -3634,8 +3638,8 @@ snapshots: browserslist@4.24.2: dependencies: - caniuse-lite: 1.0.30001676 - electron-to-chromium: 1.5.50 + caniuse-lite: 1.0.30001678 + electron-to-chromium: 1.5.55 node-releases: 2.0.18 update-browserslist-db: 1.1.1(browserslist@4.24.2) @@ -3662,7 +3666,7 @@ snapshots: callsites@3.1.0: {} - caniuse-lite@1.0.30001676: {} + caniuse-lite@1.0.30001678: {} chalk@2.4.2: dependencies: @@ -3777,6 +3781,12 @@ snapshots: shebang-command: 2.0.0 which: 2.0.2 + cross-spawn@7.0.5: + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + crypto-browserify@3.12.0: dependencies: browserify-cipher: 1.0.1 @@ -3848,7 +3858,7 @@ snapshots: tslib: 2.3.0 zrender: 5.6.0 - electron-to-chromium@1.5.50: {} + electron-to-chromium@1.5.55: {} elliptic@6.6.0: dependencies: @@ -4014,7 +4024,7 @@ snapshots: execa@8.0.1: dependencies: - cross-spawn: 7.0.3 + cross-spawn: 7.0.5 get-stream: 8.0.1 human-signals: 5.0.0 is-stream: 3.0.0 @@ -4943,7 +4953,7 @@ snapshots: uuid@11.0.2: {} - vite-bundle-analyzer@0.12.1: {} + vite-bundle-analyzer@0.13.0: {} vite-hot-client@0.2.3(vite@5.4.10(@types/node@22.9.0)(less@4.2.0)(sass@1.77.8)): dependencies: @@ -4975,11 +4985,11 @@ snapshots: vite-plugin-remove-console@2.2.0: {} - vite-plugin-vue-devtools@7.6.2(rollup@4.24.0)(vite@5.4.10(@types/node@22.9.0)(less@4.2.0)(sass@1.77.8))(vue@3.5.12(typescript@5.6.3)): + vite-plugin-vue-devtools@7.6.3(rollup@4.24.0)(vite@5.4.10(@types/node@22.9.0)(less@4.2.0)(sass@1.77.8))(vue@3.5.12(typescript@5.6.3)): dependencies: - '@vue/devtools-core': 7.6.2(vite@5.4.10(@types/node@22.9.0)(less@4.2.0)(sass@1.77.8))(vue@3.5.12(typescript@5.6.3)) - '@vue/devtools-kit': 7.6.2 - '@vue/devtools-shared': 7.6.2 + '@vue/devtools-core': 7.6.3(vite@5.4.10(@types/node@22.9.0)(less@4.2.0)(sass@1.77.8))(vue@3.5.12(typescript@5.6.3)) + '@vue/devtools-kit': 7.6.3 + '@vue/devtools-shared': 7.6.3 execa: 8.0.1 sirv: 3.0.0 vite: 5.4.10(@types/node@22.9.0)(less@4.2.0)(sass@1.77.8) diff --git a/webui/src/components/copier.vue b/webui/src/components/copier.vue new file mode 100644 index 0000000000..ef86fbd03b --- /dev/null +++ b/webui/src/components/copier.vue @@ -0,0 +1,26 @@ + + diff --git a/webui/src/locale/en-US.ts b/webui/src/locale/en-US.ts index 1a59ef4048..101cca6e4b 100644 --- a/webui/src/locale/en-US.ts +++ b/webui/src/locale/en-US.ts @@ -9,6 +9,7 @@ import topBanPageLocale from '@/views/ranks/locale/en-US' import ruleManageMentLocale from '@/views/rule-management/locale/en-US' import configLocale from '@/views/settings/locale/en-US' import alertLocale from './en-US/alert' +import copierLocale from './en-US/copier' import plusLocale from './en-US/plus' import settingsLocale from './en-US/settings' export default { @@ -60,5 +61,6 @@ export default { ...ruleManageMentLocale, ...chartsLocale, ...configLocale, - ...alertLocale + ...alertLocale, + ...copierLocale } diff --git a/webui/src/locale/en-US/copier.ts b/webui/src/locale/en-US/copier.ts new file mode 100644 index 0000000000..cfed7f8ca2 --- /dev/null +++ b/webui/src/locale/en-US/copier.ts @@ -0,0 +1,4 @@ +export default { + 'copier.copy': 'Copy', + 'copier.copied': 'Copied' +} diff --git a/webui/src/locale/zh-CN.ts b/webui/src/locale/zh-CN.ts index 0d798a83e2..4ef6215347 100644 --- a/webui/src/locale/zh-CN.ts +++ b/webui/src/locale/zh-CN.ts @@ -9,6 +9,7 @@ import topBanPageLocale from '@/views/ranks/locale/zh-CN' import ruleManageMentLocale from '@/views/rule-management/locale/zh-CN' import configLocale from '@/views/settings/locale/zh-CN' import alertLocale from './zh-CN/alert' +import copierLocale from './zh-CN/copier' import plusLocale from './zh-CN/plus' import settingsLocale from './zh-CN/settings' @@ -60,5 +61,6 @@ export default { ...ruleManageMentLocale, ...chartsLocale, ...configLocale, - ...alertLocale + ...alertLocale, + ...copierLocale } diff --git a/webui/src/locale/zh-CN/copier.ts b/webui/src/locale/zh-CN/copier.ts new file mode 100644 index 0000000000..b103b00694 --- /dev/null +++ b/webui/src/locale/zh-CN/copier.ts @@ -0,0 +1,4 @@ +export default { + 'copier.copy': '复制', + 'copier.copied': '已复制' +} diff --git a/webui/src/views/charts/components/banTrends.vue b/webui/src/views/charts/components/banTrends.vue index dc6e03afcd..14996ea618 100644 --- a/webui/src/views/charts/components/banTrends.vue +++ b/webui/src/views/charts/components/banTrends.vue @@ -57,10 +57,10 @@ @@ -99,6 +99,8 @@ const option = reactive({ range: [dayjs().startOf('day').add(-7, 'day').toDate(), new Date()] }) +const usedOption = computed(() => chartOptions.value) + const chartOptions = ref({ xAxis: { type: 'time', @@ -108,7 +110,12 @@ const chartOptions = ref({ type: 'value' }, tooltip: { - trigger: 'axis' + trigger: 'axis', + backgroundColor: darkStore.isDark ? '#333335' : '', + borderColor: darkStore.isDark ? '#333335' : '', + textStyle: { + color: darkStore.isDark ? 'rgba(255, 255, 255, 0.7)' : '' + } }, grid: { left: '15%' @@ -119,7 +126,8 @@ const chartOptions = ref({ type: 'line', name: t('page.charts.line.options.field') } - ] + ], + backgroundColor: darkStore.isDark ? 'rgba(0, 0, 0, 0.0)' : undefined }) watch(option, (v) => { diff --git a/webui/src/views/charts/components/fieldPie.vue b/webui/src/views/charts/components/fieldPie.vue index 90f2d9b27f..9dfd10df50 100644 --- a/webui/src/views/charts/components/fieldPie.vue +++ b/webui/src/views/charts/components/fieldPie.vue @@ -23,7 +23,7 @@ ({ })) const err = ref() +const usedOption = computed(() => chartOption.value) + const chartOption = ref({ tooltip: { trigger: 'item', appendToBody: true, - formatter: '

{b}

{c} ({d}%)' + formatter: '

{b}

{c} ({d}%)', + backgroundColor: darkStore.isDark ? '#333335' : '', + borderColor: darkStore.isDark ? '#333335' : '', + textStyle: { + color: darkStore.isDark ? 'rgba(255, 255, 255, 0.7)' : '' + } }, legend: { orient: 'vertical', diff --git a/webui/src/views/charts/components/ispPie.vue b/webui/src/views/charts/components/ispPie.vue index 2cc867aeaf..ae50f05839 100644 --- a/webui/src/views/charts/components/ispPie.vue +++ b/webui/src/views/charts/components/ispPie.vue @@ -28,7 +28,7 @@ ({ maskColor: darkStore.isDark ? 'rgba(0, 0, 0, 0.4)' : 'rgba(255, 255, 255, 0.4)' })) +const usedOption = computed(() => chartOption.value) + const chartOption = ref({ tooltip: { trigger: 'item', appendToBody: true, - formatter: '

{b}

{c} ({d}%)' + formatter: '

{b}

{c} ({d}%)', + backgroundColor: darkStore.isDark ? '#333335' : '', + borderColor: darkStore.isDark ? '#333335' : '', + textStyle: { + color: darkStore.isDark ? 'rgba(255, 255, 255, 0.7)' : '' + } }, legend: { orient: 'vertical', diff --git a/webui/src/views/charts/components/traffic.vue b/webui/src/views/charts/components/traffic.vue index 9b7850eb27..5e10b41352 100644 --- a/webui/src/views/charts/components/traffic.vue +++ b/webui/src/views/charts/components/traffic.vue @@ -65,10 +65,10 @@ @@ -111,6 +111,7 @@ const loadingOptions = computed(() => ({ const { t, d } = useI18n() const err = ref() +const usedOption = computed(() => chartOptions.value) const chartOptions = ref({ tooltip: { @@ -118,6 +119,11 @@ const chartOptions = ref({ axisPointer: { type: 'shadow' }, + backgroundColor: darkStore.isDark ? '#333335' : '', + borderColor: darkStore.isDark ? '#333335' : '', + textStyle: { + color: darkStore.isDark ? 'rgba(255, 255, 255, 0.7)' : '' + }, formatter: function (value: CallbackDataParams[]) { return ( d((value[0].data as OptionDataValue[])[0] as Date, 'short') + @@ -130,6 +136,7 @@ const chartOptions = ref({ ) } }, + backgroundColor: darkStore.isDark ? 'rgba(0, 0, 0, 0.0)' : undefined, legend: { data: [t('page.charts.traffic.options.download'), t('page.charts.traffic.options.upload')] }, diff --git a/webui/src/views/charts/components/trends.vue b/webui/src/views/charts/components/trends.vue index b502413d78..83e567b66f 100644 --- a/webui/src/views/charts/components/trends.vue +++ b/webui/src/views/charts/components/trends.vue @@ -48,10 +48,10 @@ @@ -88,6 +88,7 @@ const loadingOptions = computed(() => ({ textColor: darkStore.isDark ? 'rgba(255, 255, 255, 0.9)' : 'rgb(29, 33, 41)', maskColor: darkStore.isDark ? 'rgba(0, 0, 0, 0.4)' : 'rgba(255, 255, 255, 0.4)' })) +const usedOption = computed(() => chartOptions.value) const chartOptions = ref({ xAxis: { @@ -98,8 +99,14 @@ const chartOptions = ref({ type: 'value' }, tooltip: { - trigger: 'axis' + trigger: 'axis', + backgroundColor: darkStore.isDark ? '#333335' : '', + borderColor: darkStore.isDark ? '#333335' : '', + textStyle: { + color: darkStore.isDark ? 'rgba(255, 255, 255, 0.7)' : '' + } }, + backgroundColor: darkStore.isDark ? 'rgba(0, 0, 0, 0.0)' : undefined, series: [ { data: [] as [Date, number][], diff --git a/webui/src/views/settings/components/info/components/logViewer.vue b/webui/src/views/settings/components/info/components/logViewer.vue index 1e8dc31e6f..bf1326db2c 100644 --- a/webui/src/views/settings/components/info/components/logViewer.vue +++ b/webui/src/views/settings/components/info/components/logViewer.vue @@ -1,49 +1,84 @@