hex view control separated, using the new hexview control in binaryDataTag preview, binary preview limit removed (not necessary anymore)

This commit is contained in:
honfika
2014-06-23 23:36:16 +02:00
parent b93518e462
commit e644452636
10 changed files with 288 additions and 266 deletions
@@ -1,83 +1,74 @@
/*
* Copyright (C) 2010-2014 JPEXS
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.jpexs.decompiler.flash.gui;
import com.jpexs.decompiler.flash.configuration.Configuration;
import com.jpexs.decompiler.flash.gui.abc.LineMarkedEditorPane;
import com.jpexs.helpers.Helper;
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
/**
*
* @author JPEXS
*/
public final class BinaryPanel extends JPanel implements ComponentListener {
public LineMarkedEditorPane hexEditor = new LineMarkedEditorPane();
private byte[] data;
public BinaryPanel() {
super(new BorderLayout());
add(new JScrollPane(hexEditor), BorderLayout.CENTER);
JPanel bottomPanel = new JPanel(new BorderLayout());
JPanel buttonsPanel = new JPanel(new FlowLayout());
bottomPanel.add(buttonsPanel, BorderLayout.EAST);
add(bottomPanel, BorderLayout.SOUTH);
addComponentListener(this);
}
public void setBinaryData(byte[] data) {
this.data = data;
hexEditor.setEditable(false);
if (data != null) {
int widthInChars = getWidth() / 7 - 3 - 11; // -3: scrollbar, -11: address in hex format
int blockCount = widthInChars / 34;
hexEditor.setFont(new Font("Monospaced", Font.PLAIN, hexEditor.getFont().getSize()));
hexEditor.setContentType("text/plain");
int limit = Configuration.binaryDataDisplayLimit.get();
hexEditor.setText(Helper.byteArrayToHex(data, blockCount * 8, limit));
hexEditor.setCaretPosition(0);
} else {
hexEditor.setText("");
}
}
@Override
public void componentResized(ComponentEvent e) {
setBinaryData(data);
}
@Override
public void componentMoved(ComponentEvent ce) {
}
@Override
public void componentShown(ComponentEvent ce) {
}
@Override
public void componentHidden(ComponentEvent ce) {
}
}
/*
* Copyright (C) 2010-2014 JPEXS
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.jpexs.decompiler.flash.gui;
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
/**
*
* @author JPEXS
*/
public final class BinaryPanel extends JPanel implements ComponentListener {
public HexView hexEditor = new HexView();
private byte[] data;
public BinaryPanel() {
super(new BorderLayout());
add(new JScrollPane(hexEditor), BorderLayout.CENTER);
JPanel bottomPanel = new JPanel(new BorderLayout());
JPanel buttonsPanel = new JPanel(new FlowLayout());
bottomPanel.add(buttonsPanel, BorderLayout.EAST);
add(bottomPanel, BorderLayout.SOUTH);
addComponentListener(this);
}
public void setBinaryData(byte[] data) {
this.data = data;
if (data != null) {
int widthInChars = getWidth() / 7 - 3 - 11; // -3: scrollbar, -11: address in hex format
//int blockCount = widthInChars / 34;
hexEditor.setData(data, null, null);
} else {
hexEditor.setData(new byte[0], null, null);
}
}
@Override
public void componentResized(ComponentEvent e) {
setBinaryData(data);
}
@Override
public void componentMoved(ComponentEvent ce) {
}
@Override
public void componentShown(ComponentEvent ce) {
}
@Override
public void componentHidden(ComponentEvent ce) {
}
}
@@ -18,24 +18,12 @@ package com.jpexs.decompiler.flash.gui;
import com.jpexs.decompiler.flash.dumpview.DumpInfo;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Point;
import java.awt.Rectangle;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JViewport;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.JTableHeader;
import javax.swing.table.TableColumn;
import javax.swing.table.TableColumnModel;
/**
*
@@ -43,123 +31,17 @@ import javax.swing.table.TableColumnModel;
*/
public class DumpViewPanel extends JPanel {
private final int bytesInRow = 16;
private final JLabel dumpViewLabel;
private final JTable dumpViewHexTable;
private byte[] data;
private DumpInfo[] dumpInfos;
private final String[] highlightColorsStr = new String[]{/*"EEEEEE", */"29AEC2", "9AC88C", "DF5F80", "EEA32E", "FFD200", "5E9B4C", "D3E976", "A3AEC2"};
private final Color[] highlightColors;
private final HexView dumpViewHexTable;
public class HighlightCellRenderer extends DefaultTableCellRenderer {
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int col) {
JLabel l = (JLabel) super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, col);
int idx = row * bytesInRow + col - 1;
int level = -1;
for (int i = 0; i < dumpInfos.length; i++) {
DumpInfo di = dumpInfos[i];
if (di.startByte <= idx && getEndIndex(di) >= idx) {
level++;
} else {
break;
}
}
if (level > -1) {
l.setBackground(highlightColors[level % highlightColors.length]);
} else {
l.setBackground(Color.white);
}
return l;
}
}
public DumpViewPanel() {
super(new BorderLayout());
highlightColors = new Color[highlightColorsStr.length];
for (int i = 0; i < highlightColors.length; i++) {
highlightColors[i] = Color.decode("#" + highlightColorsStr[i]);
}
dumpViewLabel = new JLabel();
dumpViewLabel.setMinimumSize(new Dimension(100, 20));
add(dumpViewLabel, BorderLayout.SOUTH);
dumpViewHexTable = new JTable();
dumpViewHexTable.setModel(new AbstractTableModel() {
@Override
public int getRowCount() {
if (data == null) {
return 0;
}
int byteCount = data.length;
int rowCount = byteCount / bytesInRow;
if (byteCount % bytesInRow != 0) {
rowCount++;
}
return rowCount;
}
@Override
public int getColumnCount() {
return 2 * bytesInRow + 1;
}
@Override
public String getColumnName(int column) {
if (column == 0) {
return "Address";
} else if (column <= bytesInRow) {
return String.format("%01X", column - 1);
}
return "";
}
@Override
public Object getValueAt(int row, int column) {
if (column == 0) {
return String.format("%08X", (long) row * bytesInRow);
} else if (column <= bytesInRow) {
int pos = row * bytesInRow + column - 1;
if (pos < data.length) {
return String.format("%02X", data[pos]);
}
return null;
} else {
int pos = row * bytesInRow + column - bytesInRow - 1;
if (pos < data.length) {
return (char) data[pos];
}
return null;
}
}
});
dumpViewHexTable.setBackground(Color.white);
dumpViewHexTable.setFont(new Font("Monospaced", Font.PLAIN, 12));
dumpViewHexTable.setTableHeader(new JTableHeader());
dumpViewHexTable.setMaximumSize(new Dimension(200, 200));
dumpViewHexTable.setShowHorizontalLines(false);
dumpViewHexTable.setShowVerticalLines(false);
HighlightCellRenderer cellRenderer = new HighlightCellRenderer();
TableColumnModel columnModel = dumpViewHexTable.getColumnModel();
columnModel.getColumn(0).setMaxWidth(80);
for (int i = 0; i < bytesInRow; i++) {
TableColumn column = columnModel.getColumn(i + 1);
column.setMaxWidth(25);
column.setCellRenderer(cellRenderer);
}
for (int i = 0; i < bytesInRow; i++) {
TableColumn column = columnModel.getColumn(i + bytesInRow + 1);
column.setMaxWidth(10);
}
dumpViewHexTable = new HexView();
add(new JScrollPane(dumpViewHexTable), BorderLayout.CENTER);
}
@@ -178,42 +60,27 @@ public class DumpViewPanel extends JPanel {
}
public void setData(byte[] data, DumpInfo dumpInfo) {
this.data = data;
List<DumpInfo> dumpInfos = new ArrayList<>();
DumpInfo di = dumpInfo;
while (di.parent != null) {
dumpInfos.add(di);
di = di.parent;
}
DumpInfo[] dumpInfos1 = new DumpInfo[dumpInfos.size()];
for (int i = 0; i < dumpInfos1.length; i++) {
dumpInfos1[i] = dumpInfos.get(dumpInfos1.length - i - 1);
long[] highlightStarts = new long[dumpInfos.size()];
long[] highlightEnds = new long[dumpInfos.size()];
for (int i = 0; i < dumpInfos.size(); i++) {
DumpInfo di2 = dumpInfos.get(highlightStarts.length - i - 1);
highlightStarts[i] = di2.startByte;
highlightEnds[i] = getEndIndex(di2);
}
this.dumpInfos = dumpInfos1;
dumpViewHexTable.setData(data, highlightStarts, highlightEnds);
if (dumpInfo.lengthBytes != 0 || dumpInfo.lengthBits != 0) {
int selectionStart = (int) dumpInfo.startByte;
int selectionEnd = getEndIndex(dumpInfo);
// HACK to scroll current selection to visible
int row = (int) (dumpInfo.startByte / bytesInRow);
dumpViewHexTable.scrollToByte(dumpInfo.startByte);
final int pageSize = (int) (dumpViewHexTable.getParent().getSize().getHeight() / dumpViewHexTable.getRowHeight());
int byteCount = data.length;
int rowCount = byteCount / bytesInRow;
if (byteCount % bytesInRow != 0) {
rowCount++;
}
int row2 = Math.min(row + pageSize - 2, rowCount - 1);
dumpViewHexTable.getSelectionModel().setSelectionInterval(row2, row2);
dumpViewHexTable.scrollRectToVisible(new Rectangle(dumpViewHexTable.getCellRect(row2, 0, true)));
dumpViewHexTable.getSelectionModel().setSelectionInterval(row, row);
dumpViewHexTable.scrollRectToVisible(new Rectangle(dumpViewHexTable.getCellRect(row, 0, true)));
// END HACK
setLabelText("startByte: " + dumpInfo.startByte
+ " startBit: " + dumpInfo.startBit
+ " lengthBytes: " + dumpInfo.lengthBytes
@@ -0,0 +1,186 @@
/*
* Copyright (C) 2010-2014 JPEXS
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.jpexs.decompiler.flash.gui;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Rectangle;
import javax.swing.JLabel;
import javax.swing.JTable;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.JTableHeader;
import javax.swing.table.TableColumn;
import javax.swing.table.TableColumnModel;
/**
*
* @author JPEXS
*/
public class HexView extends JTable {
private final int bytesInRow = 16;
private long[] highlightStarts;
private long[] highlightEnds;
private byte[] data;
private final String[] highlightColorsStr = new String[]{/*"EEEEEE", */"29AEC2", "9AC88C", "DF5F80", "EEA32E", "FFD200", "5E9B4C", "D3E976", "A3AEC2"};
private final Color[] highlightColors;
public class HighlightCellRenderer extends DefaultTableCellRenderer {
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int col) {
JLabel l = (JLabel) super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, col);
if (highlightStarts != null) {
int idx = row * bytesInRow + ((col > bytesInRow) ? (col - bytesInRow - 1) : (col - 1));
int level = -1;
for (int i = 0; i < highlightStarts.length; i++) {
if (highlightStarts[i] <= idx && highlightEnds[i] >= idx) {
level++;
} else {
break;
}
}
if (level > -1) {
l.setBackground(highlightColors[level % highlightColors.length]);
} else {
l.setBackground(Color.white);
}
}
return l;
}
}
public HexView() {
highlightColors = new Color[highlightColorsStr.length];
for (int i = 0; i < highlightColors.length; i++) {
highlightColors[i] = Color.decode("#" + highlightColorsStr[i]);
}
setModel(new AbstractTableModel() {
@Override
public int getRowCount() {
if (data == null) {
return 0;
}
int byteCount = data.length;
int rowCount = byteCount / bytesInRow;
if (byteCount % bytesInRow != 0) {
rowCount++;
}
return rowCount;
}
@Override
public int getColumnCount() {
return 2 * bytesInRow + 1;
}
@Override
public String getColumnName(int column) {
if (column == 0) {
return "Address";
} else if (column <= bytesInRow) {
return String.format("%01X", column - 1);
}
return "";
}
@Override
public Object getValueAt(int row, int column) {
if (column == 0) {
return String.format("%08X", (long) row * bytesInRow);
} else if (column <= bytesInRow) {
int pos = row * bytesInRow + column - 1;
if (pos < data.length) {
return String.format("%02X", data[pos]);
}
return null;
} else {
int pos = row * bytesInRow + column - bytesInRow - 1;
if (pos < data.length) {
return (char) data[pos];
}
return null;
}
}
});
setBackground(Color.white);
setFont(new Font("Monospaced", Font.PLAIN, 12));
setTableHeader(new JTableHeader());
setMaximumSize(new Dimension(200, 200));
setShowHorizontalLines(false);
setShowVerticalLines(false);
HighlightCellRenderer cellRenderer = new HighlightCellRenderer();
TableColumnModel columnModel = getColumnModel();
columnModel.getColumn(0).setMaxWidth(80);
for (int i = 0; i < bytesInRow; i++) {
TableColumn column = columnModel.getColumn(i + 1);
column.setMaxWidth(25);
column.setCellRenderer(cellRenderer);
}
for (int i = 0; i < bytesInRow; i++) {
TableColumn column = columnModel.getColumn(i + bytesInRow + 1);
column.setMaxWidth(10);
column.setCellRenderer(cellRenderer);
}
}
public void setData(byte[] data, long[] highlightStarts, long[] highlightEnds) {
if ((highlightStarts == null) ^ (highlightEnds == null)) {
throw new Error("highlightStarts and highlightEnds should be both null or not null.");
}
if (highlightStarts != null && highlightStarts.length != highlightEnds.length) {
throw new Error("highlightStarts and highlightEnds should have the same number of elements.");
}
this.data = data;
this.highlightStarts = highlightStarts;
this.highlightEnds = highlightEnds;
}
public void scrollToByte(long byteNum) {
// HACK to scroll current selection to visible
int row = (int) (byteNum / bytesInRow);
final int pageSize = (int) (getParent().getSize().getHeight() / getRowHeight());
int byteCount = data.length;
int rowCount = byteCount / bytesInRow;
if (byteCount % bytesInRow != 0) {
rowCount++;
}
int row2 = Math.min(row + pageSize - 2, rowCount - 1);
getSelectionModel().setSelectionInterval(row2, row2);
scrollRectToVisible(new Rectangle(getCellRect(row2, 0, true)));
getSelectionModel().setSelectionInterval(row, row);
scrollRectToVisible(new Rectangle(getCellRect(row, 0, true)));
// END HACK
}
}
@@ -99,9 +99,6 @@ config.description.openFolderAfterFlaExport = Display output directory after exp
config.name.useDetailedLogging = Detailed Logging
config.description.useDetailedLogging = Log detailed error messages and info for debugging purposes
config.name.binaryDataDisplayLimit = Binary data display limit
config.description.binaryDataDisplayLimit = Maximum number of bytes to display from BinaryData tags
config.name.debugMode = Debug mode
config.description.debugMode = Mode for debugging. Turns on debug menu.
@@ -99,9 +99,6 @@ config.description.openFolderAfterFlaExport = Mostra el directori de sortida des
config.name.useDetailedLogging = Registre Detallat
config.description.useDetailedLogging = Registra missatges d'error detallats i la informaci\u00f3 de depuraci\u00f3
config.name.binaryDataDisplayLimit = L\u00edmit de mostra de dades bin\u00e0ries
config.description.binaryDataDisplayLimit = Nombre m\u00e0xim de bytes a mostrar de les etiquetes BinaryData
config.name.debugMode = Mode de depuraci\u00f3
config.description.debugMode = Mode de depuraci\u00f3. Activa el men\u00fa de depuraci\u00f3.
@@ -100,9 +100,6 @@ config.description.openFolderAfterFlaExport = Zobraz\u00ed v\u00fdstupn\u00ed ad
config.name.useDetailedLogging = Detailn\u00ed logov\u00e1n\u00ed
config.description.useDetailedLogging = Logovat detailn\u00ed chybov\u00e9 zpr\u00e1vy a informace pro \u00fa\u010dely lad\u011bn\u00ed
config.name.binaryDataDisplayLimit = Limit zobrazen\u00fdch bin\u00e1rn\u00edch dat
config.description.binaryDataDisplayLimit = Maxim\u00e1ln\u00ed po\u010det bajt\u016f zobrazen\u00fdch z BinaryData tag\u016f
config.name.debugMode = Lad\u00edc\u00ed m\u00f3d
config.description.debugMode = M\u00f3d pro lad\u011bn\u00ed. Zap\u00edn\u00e1 lad\u00edc\u00ed menu.
@@ -99,9 +99,6 @@ config.description.openFolderAfterFlaExport = A kimeneti k\u00f6nyvt\u00e1r megn
config.name.useDetailedLogging = R\u00e9szletes napl\u00f3z\u00e1s
config.description.useDetailedLogging = R\u00e9szletes hiba\u00fczenetek \u00e9s inform\u00e1ci\u00f3k napl\u00f3z\u00e1sa hibakeres\u00e9ssi c\u00e9lb\u00f3l
config.name.binaryDataDisplayLimit = Bin\u00e1ris adat megjelen\u00edt\u00e9si korl\u00e1t
config.description.binaryDataDisplayLimit = A megjelen\u00edtett b\u00e1jtok maxim\u00e1lis sz\u00e1ma BinaryData tag eset\u00e9n
config.name.debugMode = Hibakeres\u00e9si m\u00f3d
config.description.debugMode = M\u00f3d a hibakeres\u00e9shez. Bekapcsolja a hibakeres\u00e9si men\u00fct.
@@ -13,54 +13,54 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
advancedSettings.dialog.title = Opções Avançadas
advancedSettings.restartConfirmation = Tens que reiniciar o programa para tudo ter efeito. Fazer isso já?
advancedSettings.dialog.title = Op\u00c3\u00a7\u00c3\u00b5es Avan\u00c3\u00a7adas
advancedSettings.restartConfirmation = Tens que reiniciar o programa para tudo ter efeito. Fazer isso j\u00c3\u00a1?
advancedSettings.columns.name = Nome
advancedSettings.columns.value = Valor
advancedSettings.columns.description = Descrição
advancedSettings.columns.description = Descri\u00c3\u00a7\u00c3\u00a3o
default = default
config.group.name.export = Exportar
config.group.description.export = Configurações de Exportação
config.group.description.export = Configura\u00c3\u00a7\u00c3\u00b5es de Exporta\u00c3\u00a7\u00c3\u00a3o
config.group.name.script = Scripts
config.group.description.script = Relatado com decompililão de ActionScript
config.group.description.script = Relatado com decompilil\u00c3\u00a3o de ActionScript
config.group.name.update = Atualizações
config.group.description.update = A pesquisar atualizações...
config.group.name.update = Atualiza\u00c3\u00a7\u00c3\u00b5es
config.group.description.update = A pesquisar atualiza\u00c3\u00a7\u00c3\u00b5es...
config.group.name.format = A Formatar
config.group.description.format = Formatação de ActionScript
config.group.description.format = Formata\u00c3\u00a7\u00c3\u00a3o de ActionScript
config.group.name.limit = Limites
config.group.description.limit = Limites para desobufucação, ficheiros, etc.
config.group.description.limit = Limites para desobufuca\u00c3\u00a7\u00c3\u00a3o, ficheiros, etc.
config.group.name.ui = Menu
config.group.description.ui = Configuração do Menu
config.group.description.ui = Configura\u00c3\u00a7\u00c3\u00a3o do Menu
config.group.name.debug = Correr
config.group.description.debug = Opções de Correr o programa
config.group.description.debug = Op\u00c3\u00a7\u00c3\u00b5es de Correr o programa
config.group.name.display = Mostrar
config.group.description.display = Mostrar objectos flash, etc.
config.group.name.decompilation = Decompilação
config.group.description.decompilation = Funções de decompilação.
config.group.name.decompilation = Decompila\u00c3\u00a7\u00c3\u00a3o
config.group.description.decompilation = Fun\u00c3\u00a7\u00c3\u00b5es de decompila\u00c3\u00a7\u00c3\u00a3o.
config.group.name.other = Outros
config.group.description.other = Outras coisas.
config.name.openMultipleFiles = Abrir ficheiros múltiplos
config.description.openMultipleFiles = Permite abrir vários ficheiros de uma só vez na janela.
config.name.openMultipleFiles = Abrir ficheiros m\u00c3\u00baltiplos
config.description.openMultipleFiles = Permite abrir v\u00c3\u00a1rios ficheiros de uma s\u00c3\u00b3 vez na janela.
config.name.decompile = Mostrar Decompilação de ActionScript
config.description.decompile = Podes desativar a Decompilação tal como para o P-Code.
config.name.decompile = Mostrar Decompila\u00c3\u00a7\u00c3\u00a3o de ActionScript
config.description.decompile = Podes desativar a Decompila\u00c3\u00a7\u00c3\u00a3o tal como para o P-Code.
config.name.parallelSpeedUp = Parallel SpeedUp
config.description.parallelSpeedUp = Parallelism can speed up decompilation
config.name.parallelThreadCount = Número de Threads
config.name.parallelThreadCount = N\u00c3\u00bamero de Threads
config.description.parallelThreadCount = Number of threads for parallel speedup
config.name.autoDeobfuscate = Automatic deobfuscation
@@ -99,9 +99,6 @@ config.description.openFolderAfterFlaExport = Display output directory after exp
config.name.useDetailedLogging = Detailed Logging
config.description.useDetailedLogging = Log detailed error messages and info for debugging purposes
config.name.binaryDataDisplayLimit = Binary data display limit
config.description.binaryDataDisplayLimit = Maximum number of bytes to display from BinaryData tags
config.name.debugMode = Debug mode
config.description.debugMode = Mode for debugging. Turns on debug menu.
@@ -99,9 +99,6 @@ config.description.openFolderAfterFlaExport = \u041e\u0442\u043a\u0440\u044b\u04
config.name.useDetailedLogging = \u041f\u043e\u0434\u0440\u043e\u0431\u043d\u044b\u0439 \u043b\u043e\u0433
config.description.useDetailedLogging = \u041f\u0438\u0441\u0430\u0442\u044c \u0432 \u043b\u043e\u0433 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u043e \u043f\u0440\u0435\u0434\u0443\u043f\u0440\u0435\u0436\u0434\u0435\u043d\u0438\u044f\u0445 \u0438 \u043e\u0448\u0438\u0431\u043a\u0430\u0445, \u0434\u043b\u044f \u043e\u0442\u043b\u0430\u0434\u043e\u0447\u043d\u044b\u0445 \u0446\u0435\u043b\u0435\u0439
config.name.binaryDataDisplayLimit = \u041f\u0440\u0435\u0434\u0435\u043b \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f Binary data
config.description.binaryDataDisplayLimit = \u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0431\u0430\u0439\u0442 \u0434\u043b\u044f \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0438\u0437 \u0442\u044d\u0433\u043e\u0432 BinaryData
config.name.debugMode = \u0420\u0435\u0436\u0438\u043c \u043e\u0442\u043b\u0430\u0434\u043a\u0438
config.description.debugMode = \u0420\u0435\u0436\u0438\u043c \u043e\u0442\u043b\u0430\u0434\u043a\u0438, \u0432\u043a\u043b\u044e\u0447\u0430\u0442 \u043e\u0442\u043b\u0430\u0434\u043e\u0447\u043d\u043e\u0435 \u043c\u0435\u043d\u044e