diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 000000000..13566b81b --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/Robots_kroki.iml b/.idea/Robots_kroki.iml new file mode 100644 index 000000000..d6ebd4805 --- /dev/null +++ b/.idea/Robots_kroki.iml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 000000000..919ce1f1f --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,7 @@ + + + + + + \ No newline at end of file diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml new file mode 100644 index 000000000..a55e7a179 --- /dev/null +++ b/.idea/codeStyles/codeStyleConfig.xml @@ -0,0 +1,5 @@ + + + + \ No newline at end of file diff --git a/.idea/compiler.xml b/.idea/compiler.xml new file mode 100644 index 000000000..6834da5ca --- /dev/null +++ b/.idea/compiler.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/encodings.xml b/.idea/encodings.xml new file mode 100644 index 000000000..03a3f688a --- /dev/null +++ b/.idea/encodings.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/jarRepositories.xml b/.idea/jarRepositories.xml new file mode 100644 index 000000000..712ab9d98 --- /dev/null +++ b/.idea/jarRepositories.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 000000000..c31bbf317 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,14 @@ + + + + + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 000000000..f913d90b3 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 000000000..35eb1ddfb --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/Robots.iml b/Robots.iml new file mode 100644 index 000000000..aec4429cf --- /dev/null +++ b/Robots.iml @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/pom.xml b/pom.xml new file mode 100644 index 000000000..0b1d3c70e --- /dev/null +++ b/pom.xml @@ -0,0 +1,46 @@ + + 4.0.0 + com.example + Robots + 1.0.0 + Robots + jar + + + 17 + 17 + UTF-8 + + + + + org.jetbrains + annotations + 13.0 + compile + + + com.thoughtworks.xstream + xstream + 1.4.3 + + + + + robots/src + ../Robots/bin + + + org.apache.maven.plugins + maven-compiler-plugin + 3.8.1 + + 10 + 10 + + + + + \ No newline at end of file diff --git a/robots/src/gui/MainApplicationFrame.java b/robots/src/gui/MainApplicationFrame.java deleted file mode 100644 index 62e943ee1..000000000 --- a/robots/src/gui/MainApplicationFrame.java +++ /dev/null @@ -1,156 +0,0 @@ -package gui; - -import java.awt.Dimension; -import java.awt.Toolkit; -import java.awt.event.KeyEvent; - -import javax.swing.JDesktopPane; -import javax.swing.JFrame; -import javax.swing.JInternalFrame; -import javax.swing.JMenu; -import javax.swing.JMenuBar; -import javax.swing.JMenuItem; -import javax.swing.SwingUtilities; -import javax.swing.UIManager; -import javax.swing.UnsupportedLookAndFeelException; - -import log.Logger; - -/** - * Что требуется сделать: - * 1. Метод создания меню перегружен функционалом и трудно читается. - * Следует разделить его на серию более простых методов (или вообще выделить отдельный класс). - * - */ -public class MainApplicationFrame extends JFrame -{ - private final JDesktopPane desktopPane = new JDesktopPane(); - - public MainApplicationFrame() { - //Make the big window be indented 50 pixels from each edge - //of the screen. - int inset = 50; - Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); - setBounds(inset, inset, - screenSize.width - inset*2, - screenSize.height - inset*2); - - setContentPane(desktopPane); - - - LogWindow logWindow = createLogWindow(); - addWindow(logWindow); - - GameWindow gameWindow = new GameWindow(); - gameWindow.setSize(400, 400); - addWindow(gameWindow); - - setJMenuBar(generateMenuBar()); - setDefaultCloseOperation(EXIT_ON_CLOSE); - } - - protected LogWindow createLogWindow() - { - LogWindow logWindow = new LogWindow(Logger.getDefaultLogSource()); - logWindow.setLocation(10,10); - logWindow.setSize(300, 800); - setMinimumSize(logWindow.getSize()); - logWindow.pack(); - Logger.debug("Протокол работает"); - return logWindow; - } - - protected void addWindow(JInternalFrame frame) - { - desktopPane.add(frame); - frame.setVisible(true); - } - -// protected JMenuBar createMenuBar() { -// JMenuBar menuBar = new JMenuBar(); -// -// //Set up the lone menu. -// JMenu menu = new JMenu("Document"); -// menu.setMnemonic(KeyEvent.VK_D); -// menuBar.add(menu); -// -// //Set up the first menu item. -// JMenuItem menuItem = new JMenuItem("New"); -// menuItem.setMnemonic(KeyEvent.VK_N); -// menuItem.setAccelerator(KeyStroke.getKeyStroke( -// KeyEvent.VK_N, ActionEvent.ALT_MASK)); -// menuItem.setActionCommand("new"); -//// menuItem.addActionListener(this); -// menu.add(menuItem); -// -// //Set up the second menu item. -// menuItem = new JMenuItem("Quit"); -// menuItem.setMnemonic(KeyEvent.VK_Q); -// menuItem.setAccelerator(KeyStroke.getKeyStroke( -// KeyEvent.VK_Q, ActionEvent.ALT_MASK)); -// menuItem.setActionCommand("quit"); -//// menuItem.addActionListener(this); -// menu.add(menuItem); -// -// return menuBar; -// } - - private JMenuBar generateMenuBar() - { - JMenuBar menuBar = new JMenuBar(); - - JMenu lookAndFeelMenu = new JMenu("Режим отображения"); - lookAndFeelMenu.setMnemonic(KeyEvent.VK_V); - lookAndFeelMenu.getAccessibleContext().setAccessibleDescription( - "Управление режимом отображения приложения"); - - { - JMenuItem systemLookAndFeel = new JMenuItem("Системная схема", KeyEvent.VK_S); - systemLookAndFeel.addActionListener((event) -> { - setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); - this.invalidate(); - }); - lookAndFeelMenu.add(systemLookAndFeel); - } - - { - JMenuItem crossplatformLookAndFeel = new JMenuItem("Универсальная схема", KeyEvent.VK_S); - crossplatformLookAndFeel.addActionListener((event) -> { - setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName()); - this.invalidate(); - }); - lookAndFeelMenu.add(crossplatformLookAndFeel); - } - - JMenu testMenu = new JMenu("Тесты"); - testMenu.setMnemonic(KeyEvent.VK_T); - testMenu.getAccessibleContext().setAccessibleDescription( - "Тестовые команды"); - - { - JMenuItem addLogMessageItem = new JMenuItem("Сообщение в лог", KeyEvent.VK_S); - addLogMessageItem.addActionListener((event) -> { - Logger.debug("Новая строка"); - }); - testMenu.add(addLogMessageItem); - } - - menuBar.add(lookAndFeelMenu); - menuBar.add(testMenu); - return menuBar; - } - - private void setLookAndFeel(String className) - { - try - { - UIManager.setLookAndFeel(className); - SwingUtilities.updateComponentTreeUI(this); - } - catch (ClassNotFoundException | InstantiationException - | IllegalAccessException | UnsupportedLookAndFeelException e) - { - // just ignore - } - } -} diff --git a/robots/src/main/java/gui/AbstarctWindowState.java b/robots/src/main/java/gui/AbstarctWindowState.java new file mode 100644 index 000000000..7da39ff91 --- /dev/null +++ b/robots/src/main/java/gui/AbstarctWindowState.java @@ -0,0 +1,64 @@ +package gui; + +import java.beans.PropertyVetoException; +import java.util.prefs.Preferences; +import javax.swing.JInternalFrame; + +public abstract class AbstarctWindowState extends JInternalFrame implements FrameState { + private static final String prefixWindowPreferences = formatTitle("window preferences"); + private static final String prefixWindowPositionX = formatTitle("position x"); + private static final String prefixWindowPositionY = formatTitle("position y"); + private static final String prefixWindowSizeWidth = formatTitle("size width"); + private static final String prefixWindowSizeHeight = formatTitle("size height"); + private static final String prefixWindowIsMinimised = formatTitle("is minimised"); + private final JInternalFrame frame = this; + + public AbstarctWindowState(String string, boolean b, boolean b1, boolean b2, boolean b3) { + super(string, b, b1, b2, b3); + } + + + private static Preferences getPreferences() { + return Preferences.userRoot().node(prefixWindowPreferences); + } + private static String formatTitle(String title) { + String cased = title.toUpperCase(); + + return cased.replaceAll(" +", "_"); + } + + public void saveWindow() { + Preferences preferences = getPreferences(); + + String title = formatTitle(frame.getTitle()); + + preferences.putInt(prefixWindowPositionX + title, frame.getX()); + preferences.putInt(prefixWindowPositionY + title, frame.getY()); + preferences.putInt(prefixWindowSizeWidth + title, frame.getWidth()); + preferences.putInt(prefixWindowSizeHeight + title, frame.getHeight()); + preferences.putBoolean(prefixWindowIsMinimised + title, frame.isIcon()); + } + + public void restoreWindow() { + Preferences preferences = getPreferences(); + final int missing = -1; + + String title = formatTitle(frame.getTitle()); + + int x = preferences.getInt(prefixWindowPositionX + title, missing); + int y = preferences.getInt(prefixWindowPositionY + title, missing); + int width = preferences.getInt(prefixWindowSizeWidth + title, missing); + int height = preferences.getInt(prefixWindowSizeHeight + title, missing); + boolean isMinimised = preferences.getBoolean(prefixWindowIsMinimised + title, false); + + if (x == -1 || y == -1 || width == -1 || height == -1) + return; + + frame.setBounds(x, y, width, height); + try { + frame.setIcon(isMinimised); + } catch (PropertyVetoException e) { + e.printStackTrace(System.out); + } + } +} diff --git a/robots/src/main/java/gui/FrameState.java b/robots/src/main/java/gui/FrameState.java new file mode 100644 index 000000000..5b6444a51 --- /dev/null +++ b/robots/src/main/java/gui/FrameState.java @@ -0,0 +1,6 @@ +package gui; + +public interface FrameState { + void saveWindow(); + void restoreWindow(); +} diff --git a/robots/src/gui/GameVisualizer.java b/robots/src/main/java/gui/GameVisualizer.java similarity index 88% rename from robots/src/gui/GameVisualizer.java rename to robots/src/main/java/gui/GameVisualizer.java index f82cfd8f8..9304a82c8 100644 --- a/robots/src/gui/GameVisualizer.java +++ b/robots/src/main/java/gui/GameVisualizer.java @@ -11,7 +11,7 @@ import java.util.Timer; import java.util.TimerTask; -import javax.swing.JPanel; +import javax.swing.*; public class GameVisualizer extends JPanel { @@ -207,4 +207,21 @@ private void drawTarget(Graphics2D g, int x, int y) g.setColor(Color.BLACK); drawOval(g, x, y, 5, 5); } + + public void showRobotCoordinatesDialog() { + JFrame dialog = new JFrame("Координаты робота"); + dialog.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); // Закрытие при нажатии X + + JLabel positionLabel = new JLabel("Позиция: (" + round(m_robotPositionX) + ", " + round(m_robotPositionY) + ")"); + JLabel directionLabel = new JLabel("Направление: " + Math.toDegrees(m_robotDirection) + " градусов"); + + JPanel contentPanel = new JPanel(); + contentPanel.add(positionLabel); + contentPanel.add(directionLabel); + + dialog.getContentPane().add(contentPanel); + dialog.pack(); + dialog.setLocationRelativeTo(null); // Центрирование диалога + dialog.setVisible(true); + } } diff --git a/robots/src/gui/GameWindow.java b/robots/src/main/java/gui/GameWindow.java similarity index 90% rename from robots/src/gui/GameWindow.java rename to robots/src/main/java/gui/GameWindow.java index ecb63c00f..aa793cc58 100644 --- a/robots/src/gui/GameWindow.java +++ b/robots/src/main/java/gui/GameWindow.java @@ -5,7 +5,7 @@ import javax.swing.JInternalFrame; import javax.swing.JPanel; -public class GameWindow extends JInternalFrame +public class GameWindow extends AbstarctWindowState { private final GameVisualizer m_visualizer; public GameWindow() diff --git a/robots/src/gui/LogWindow.java b/robots/src/main/java/gui/LogWindow.java similarity index 93% rename from robots/src/gui/LogWindow.java rename to robots/src/main/java/gui/LogWindow.java index 723d3e2fc..2d235b003 100644 --- a/robots/src/gui/LogWindow.java +++ b/robots/src/main/java/gui/LogWindow.java @@ -3,7 +3,6 @@ import java.awt.BorderLayout; import java.awt.EventQueue; import java.awt.TextArea; - import javax.swing.JInternalFrame; import javax.swing.JPanel; @@ -11,7 +10,7 @@ import log.LogEntry; import log.LogWindowSource; -public class LogWindow extends JInternalFrame implements LogChangeListener +public class LogWindow extends AbstarctWindowState implements LogChangeListener { private LogWindowSource m_logSource; private TextArea m_logContent; diff --git a/robots/src/main/java/gui/MainApplicationFrame.java b/robots/src/main/java/gui/MainApplicationFrame.java new file mode 100644 index 000000000..dea96793c --- /dev/null +++ b/robots/src/main/java/gui/MainApplicationFrame.java @@ -0,0 +1,169 @@ +package gui; + +import java.awt.*; +import java.awt.event.ActionListener; +import java.awt.event.InputEvent; +import java.awt.event.KeyEvent; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import java.util.Arrays; +import java.util.Locale; +import java.util.ResourceBundle; +import javax.swing.*; + +import log.Logger; + +public class MainApplicationFrame extends JFrame { + private final JDesktopPane desktopPane = new JDesktopPane(); + Locale locale = new Locale("ru", "RU"); + ResourceBundle bundle = ResourceBundle.getBundle("recources", locale); + + @Override + public void dispose() { + super.dispose(); + saveWindows(); + } + + private void saveWindows() { + for (var frame : desktopPane.getAllFrames()) { + if (frame instanceof FrameState) { + ((FrameState) frame).saveWindow(); + } + } + } + + private void restoreState() { + for (var frame : desktopPane.getAllFrames()) + if (frame instanceof FrameState) + ((FrameState) frame).restoreWindow(); + } + + public MainApplicationFrame() { + int inset = 50; + Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); + setBounds(inset, inset, + screenSize.width - inset*2, + screenSize.height - inset*2); + + setContentPane(desktopPane); + + addWindow(new LogWindow(Logger.getDefaultLogSource())); + addWindow(createGameWindow()); + for (var frame : desktopPane.getAllFrames()) + if (frame instanceof FrameState) + ((FrameState) frame).restoreWindow(); + setJMenuBar(generateMenuBar()); + setDefaultCloseOperation(DO_NOTHING_ON_CLOSE); + } +// public static void initializeUI() { +// try { +// UIManager.setLookAndFeel("javax.swing.plaf.nimbus.NimbusLookAndFeel"); +// } catch (Exception e) { +// e.printStackTrace(); +// } +// MainApplicationFrame frame = new MainApplicationFrame(); +// int inset = 50; +// Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); +// frame.setBounds(inset, inset, screenSize.width - inset * 2, screenSize.height - inset * 2); +// frame.setContentPane(frame.desktopPane); +// frame.setJMenuBar(frame.generateMenuBar()); +// frame.setDefaultCloseOperation(EXIT_ON_CLOSE); +// frame.restoreState(); +// frame.setVisible(true); +// frame.pack(); +// frame.setExtendedState(Frame.MAXIMIZED_BOTH); +// } + + private GameWindow createGameWindow() { + int gameWindowWidth = 400; + int gameWindowHeight = 400; + + GameWindow gameWindow = new GameWindow(); + gameWindow.setSize(gameWindowWidth, gameWindowHeight); + return gameWindow; + } + + private void addWindow(JInternalFrame frame) { + desktopPane.add(frame); + frame.setVisible(true); + } + + private JMenuItem createMenuItem(String label, int mnemonic, String acceleratorKey, ActionListener actionListener) { + JMenuItem menuItem = new JMenuItem(label, mnemonic); + if (acceleratorKey != null && !acceleratorKey.isEmpty()) { + menuItem.setAccelerator(KeyStroke.getKeyStroke(acceleratorKey)); + } + menuItem.addActionListener(actionListener); + return menuItem; + } + + private JMenu createMenu(String label, int mnemonic) { + JMenu menu = new JMenu(label); + menu.setMnemonic(mnemonic); + return menu; + } + + private JMenuBar generateMenuBar() { + JMenuBar menuBar = new JMenuBar(); + + JMenu documentMenu = createMenu(bundle.getString("menu"), KeyEvent.VK_D); + + documentMenu.add(createMenuItem(bundle.getString("new_game_field"), KeyEvent.VK_N, "alt N", (event) -> addWindow(createGameWindow()))); + documentMenu.add(createMenuItem(bundle.getString("log_window"), KeyEvent.VK_L, "alt L", (event) -> addWindow(new LogWindow(Logger.getDefaultLogSource())))); + documentMenu.add(createMenuItem(bundle.getString("exit"), KeyEvent.VK_Q, "alt Q", (event) -> confirmExit())); + menuBar.add(documentMenu); + + JMenu viewMenu = createMenu(bundle.getString("display_mode"), KeyEvent.VK_V); + viewMenu.add(createMenuItem(bundle.getString("system_diagram"), KeyEvent.VK_S, "ctrl S", (event) -> setLookAndFeel(UIManager.getSystemLookAndFeelClassName()))); + viewMenu.add(createMenuItem(bundle.getString("universal_scheme"), KeyEvent.VK_U, "ctrl U", (event) -> setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName()))); + menuBar.add(viewMenu); + + JMenu testMenu = createMenu(bundle.getString("tests"), KeyEvent.VK_T); + testMenu.add(createMenuItem(bundle.getString("message_in_the_log"), KeyEvent.VK_M, "alt M", (event) -> Logger.debug(bundle.getString("new_str")))); + menuBar.add(testMenu); + + return menuBar; + } + + + private void setLookAndFeel(String className) { + try { + UIManager.setLookAndFeel(className); + SwingUtilities.updateComponentTreeUI(this); + } catch (Exception e) { + e.printStackTrace(); + } + } + + private void confirmExit() { + int confirm = JOptionPane.showConfirmDialog(this, + bundle.getString("exit?"), bundle.getString("exit-yes"), + JOptionPane.YES_NO_OPTION); + if (confirm == JOptionPane.YES_OPTION) { + int confirm2 = JOptionPane.showConfirmDialog(this, + bundle.getString("exit-save"), bundle.getString("exit-save_q"), + JOptionPane.YES_NO_OPTION); + if (confirm2 == JOptionPane.YES_OPTION) { + saveWindows(); + }else if (confirm2 == JOptionPane.NO_OPTION) { + // Создаем панель с изображением и текстом + JPanel panel = new JPanel(new BorderLayout()); + ImageIcon icon = new ImageIcon("./robots/src/resources/photos/chechen.jpg"); // Укажите путь к вашей картинке + JLabel label = new JLabel(bundle.getString("ramzan_1"), icon, JLabel.CENTER); + panel.add(label, BorderLayout.CENTER); + + // Добавляем панель в диалоговое окно + int confirm3 = JOptionPane.showConfirmDialog(this, + panel, bundle.getString("ramzan"), + JOptionPane.YES_NO_OPTION); + if (confirm3 == JOptionPane.YES_OPTION) saveWindows(); + setVisible(false); + Arrays.asList(desktopPane.getAllFrames()).forEach(JInternalFrame::dispose); + dispose(); + } + setVisible(false); + Arrays.asList(desktopPane.getAllFrames()).forEach(JInternalFrame::dispose); + dispose(); + } + } +} \ No newline at end of file diff --git a/robots/src/gui/RobotsProgram.java b/robots/src/main/java/gui/RobotsProgram.java similarity index 70% rename from robots/src/gui/RobotsProgram.java rename to robots/src/main/java/gui/RobotsProgram.java index ae0930a8b..ac87b9f48 100644 --- a/robots/src/gui/RobotsProgram.java +++ b/robots/src/main/java/gui/RobotsProgram.java @@ -16,10 +16,10 @@ public static void main(String[] args) { } catch (Exception e) { e.printStackTrace(); } - SwingUtilities.invokeLater(() -> { - MainApplicationFrame frame = new MainApplicationFrame(); - frame.pack(); - frame.setVisible(true); - frame.setExtendedState(Frame.MAXIMIZED_BOTH); - }); + SwingUtilities.invokeLater(() -> { + MainApplicationFrame frame = new MainApplicationFrame(); + frame.pack(); + frame.setVisible(true); + frame.setExtendedState(Frame.MAXIMIZED_BOTH); + }); }} diff --git a/robots/src/log/LogChangeListener.java b/robots/src/main/java/log/LogChangeListener.java similarity index 100% rename from robots/src/log/LogChangeListener.java rename to robots/src/main/java/log/LogChangeListener.java diff --git a/robots/src/log/LogEntry.java b/robots/src/main/java/log/LogEntry.java similarity index 100% rename from robots/src/log/LogEntry.java rename to robots/src/main/java/log/LogEntry.java diff --git a/robots/src/log/LogLevel.java b/robots/src/main/java/log/LogLevel.java similarity index 100% rename from robots/src/log/LogLevel.java rename to robots/src/main/java/log/LogLevel.java diff --git a/robots/src/log/LogWindowSource.java b/robots/src/main/java/log/LogWindowSource.java similarity index 100% rename from robots/src/log/LogWindowSource.java rename to robots/src/main/java/log/LogWindowSource.java diff --git a/robots/src/log/Logger.java b/robots/src/main/java/log/Logger.java similarity index 100% rename from robots/src/log/Logger.java rename to robots/src/main/java/log/Logger.java diff --git a/robots/src/resources/recources.properties b/robots/src/resources/recources.properties new file mode 100644 index 000000000..673c2b12a --- /dev/null +++ b/robots/src/resources/recources.properties @@ -0,0 +1,19 @@ +menu=menu +protocol = Protocol +new_game_field = new_game_field +log_window = log_window +exit = exit +display_mode = display_mode +system_diagram = system_diagram +universal_scheme = universal_scheme +tests = tests +message_in_the_log = message_in_the_log +new_str = new_str +exit? = exit? +exit-yes = exit-yes +exit-save = exit-save +exit-save_q = exit-save_q +yes_button_text = yes_button_text +no_button_text = no_button_text +ramzan= ramzan +ramzan_1=ramzan_1 \ No newline at end of file diff --git a/robots/src/resources/recources_ru_RU.properties b/robots/src/resources/recources_ru_RU.properties new file mode 100644 index 000000000..df7cbb9eb --- /dev/null +++ b/robots/src/resources/recources_ru_RU.properties @@ -0,0 +1,20 @@ +menu=\u041c\u0435\u043d\u044e +protocol = \u041f\u0440\u043e\u0442\u043e\u043a\u043e\u043b\u0020\u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 +new_game_field = \u041d\u043e\u0432\u043e\u0435\u0020\u0438\u0433\u0440\u043e\u0432\u043e\u0435\u0020\u043f\u043e\u043b\u0435 +log_window = \u043e\u043a\u043d\u043e\u0020\u043b\u043e\u0433\u043e\u0432 +exit = \u0412\u044b\u0445\u043e\u0434 +display_mode = \u0420\u0435\u0436\u0438\u043c\u0020\u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f +system_diagram = \u0421\u0438\u0441\u0442\u0435\u043c\u043d\u0430\u044f\u0020\u0441\u0445\u0435\u043c\u0430 +universal_scheme = \u0423\u043d\u0438\u0432\u0435\u0440\u0441\u0430\u043b\u044c\u043d\u0430\u044f\u0020\u0441\u0445\u0435\u043c\u0430 +tests = \u0422\u0435\u0441\u0442\u044b +message_in_the_log = \u0421\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435\u0020\u0432\u0020\u043b\u043e\u0433 +new_str = \u041d\u043e\u0432\u0430\u044f\u0020\u0441\u0442\u0440\u043e\u043a\u0430 +exit? = \u0412\u044b\u0020\u0443\u0432\u0435\u0440\u0435\u043d\u044b\u002c\u0447\u0442\u043e\u0020\u0445\u043e\u0442\u0438\u0442\u0435\u0020\u0432\u044b\u0439\u0442\u0438\u003f +exit-yes = \u041f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u0435\u0020\u0432\u044b\u0445\u043e\u0434\u0430 +yes_button_text = \u0414\u0430 +no_button_text = \u041d\u0435\u0442 +save_button = \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0435 +exit-save = \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0442\u044c\u003f +exit-save_q =\u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0435 +ramzan = \u0420\u0430\u043c\u0437\u0430\u043d\u0020\u041a\u0430\u0434\u044b\u0440\u043e\u0432\u0020\u043d\u0435\u0020\u043b\u044e\u0431\u0438\u0442\u0020\u043a\u043e\u0433\u0434\u0430\u0020\u0435\u043c\u0443\u0020\u0433\u043e\u0432\u043e\u0440\u044f\u0442\u0020\u041d\u0415\u0422\u0021 +ramzan_1 = \u0418\u0437\u0432\u0438\u043d\u0438\u0442\u044c\u0441\u044f\u003f \ No newline at end of file