| 1 | package com.jsql.view.swing.table; | |
| 2 | ||
| 3 | import javax.swing.*; | |
| 4 | import javax.swing.event.TableModelEvent; | |
| 5 | import javax.swing.event.TableModelListener; | |
| 6 | import javax.swing.table.TableCellRenderer; | |
| 7 | import javax.swing.table.TableColumn; | |
| 8 | import javax.swing.table.TableColumnModel; | |
| 9 | import javax.swing.table.TableModel; | |
| 10 | import java.awt.*; | |
| 11 | import java.awt.event.ActionEvent; | |
| 12 | import java.beans.PropertyChangeEvent; | |
| 13 | import java.beans.PropertyChangeListener; | |
| 14 | import java.util.HashMap; | |
| 15 | import java.util.Map; | |
| 16 | ||
| 17 | /** | |
| 18 | * Class to manage the widths of columns in a table. | |
| 19 | * | |
| 20 | * Various properties control how the width of the column is calculated. | |
| 21 | * Another property controls whether column width calculation should be dynamic. | |
| 22 | * Finally, various Actions will be added to the table to allow the user | |
| 23 | * to customize the functionality. | |
| 24 | * | |
| 25 | * This class was designed to be used with tables that use an auto resize mode | |
| 26 | * of AUTO_RESIZE_OFF. With all other modes you are constrained as the width | |
| 27 | * of the columns must fit inside the table. So if you increase one column, one | |
| 28 | * or more of the other columns must decrease. Because of this the resize mode | |
| 29 | * of RESIZE_ALL_COLUMNS will work the best. | |
| 30 | */ | |
| 31 | public class AdjusterTableColumn implements PropertyChangeListener, TableModelListener { | |
| 32 | | |
| 33 | private final JTable tableAdjust; | |
| 34 | private final int spacing; | |
| 35 | private boolean isColumnHeaderIncluded; | |
| 36 | private boolean isColumnDataIncluded; | |
| 37 | private boolean isOnlyAdjustLarger; | |
| 38 | private boolean isDynamicAdjustment; | |
| 39 | private final Map<TableColumn, Integer> columnSizes = new HashMap<>(); | |
| 40 | ||
| 41 | /** | |
| 42 | * Specify the table and use default spacing | |
| 43 | */ | |
| 44 | public AdjusterTableColumn(JTable table) { | |
| 45 | this(table, 6); | |
| 46 | } | |
| 47 | ||
| 48 | /** | |
| 49 | * Specify the table and spacing | |
| 50 | */ | |
| 51 | public AdjusterTableColumn(JTable tableAdjust, int spacing) { | |
| 52 | this.tableAdjust = tableAdjust; | |
| 53 | this.spacing = spacing; | |
| 54 |
1
1. <init> : removed call to com/jsql/view/swing/table/AdjusterTableColumn::setColumnHeaderIncluded → NO_COVERAGE |
this.setColumnHeaderIncluded(true); |
| 55 |
1
1. <init> : removed call to com/jsql/view/swing/table/AdjusterTableColumn::setColumnDataIncluded → NO_COVERAGE |
this.setColumnDataIncluded(true); |
| 56 |
1
1. <init> : removed call to com/jsql/view/swing/table/AdjusterTableColumn::setOnlyAdjustLarger → NO_COVERAGE |
this.setOnlyAdjustLarger(true); |
| 57 |
1
1. <init> : removed call to com/jsql/view/swing/table/AdjusterTableColumn::setDynamicAdjustment → NO_COVERAGE |
this.setDynamicAdjustment(false); |
| 58 |
1
1. <init> : removed call to com/jsql/view/swing/table/AdjusterTableColumn::installActions → NO_COVERAGE |
this.installActions(); |
| 59 | } | |
| 60 | ||
| 61 | /** | |
| 62 | * Adjust the widths of all the columns in the table | |
| 63 | */ | |
| 64 | public void adjustColumns() { | |
| 65 | TableColumnModel tcm = this.tableAdjust.getColumnModel(); | |
| 66 |
2
1. adjustColumns : changed conditional boundary → NO_COVERAGE 2. adjustColumns : negated conditional → NO_COVERAGE |
for (var i = 0 ; i < tcm.getColumnCount() ; i++) { |
| 67 |
1
1. adjustColumns : removed call to com/jsql/view/swing/table/AdjusterTableColumn::adjustColumn → NO_COVERAGE |
this.adjustColumn(i); |
| 68 | } | |
| 69 | } | |
| 70 | ||
| 71 | /** | |
| 72 | * Adjust the width of the specified column in the table | |
| 73 | */ | |
| 74 | public void adjustColumn(final int column) { | |
| 75 | var tableColumn = this.tableAdjust.getColumnModel().getColumn(column); | |
| 76 |
1
1. adjustColumn : negated conditional → NO_COVERAGE |
if (!tableColumn.getResizable()) { |
| 77 | return; | |
| 78 | } | |
| 79 | ||
| 80 | int columnHeaderWidth = this.getColumnHeaderWidth(column); | |
| 81 | int columnDataWidth = this.getColumnDataWidth(column); | |
| 82 | int preferredWidth = Math.max(columnHeaderWidth, columnDataWidth); | |
| 83 |
1
1. adjustColumn : removed call to com/jsql/view/swing/table/AdjusterTableColumn::updateTableColumn → NO_COVERAGE |
this.updateTableColumn(column, preferredWidth); |
| 84 | } | |
| 85 | ||
| 86 | /** | |
| 87 | * Calculated the width based on the column name | |
| 88 | */ | |
| 89 | private int getColumnHeaderWidth(int column) { | |
| 90 |
1
1. getColumnHeaderWidth : negated conditional → NO_COVERAGE |
if (!this.isColumnHeaderIncluded) { |
| 91 | return 0; | |
| 92 | } | |
| 93 | ||
| 94 | var tableColumn = this.tableAdjust.getColumnModel().getColumn(column); | |
| 95 | Object value = tableColumn.getHeaderValue(); | |
| 96 | TableCellRenderer renderer = tableColumn.getHeaderRenderer(); | |
| 97 |
1
1. getColumnHeaderWidth : negated conditional → NO_COVERAGE |
if (renderer == null) { |
| 98 | renderer = this.tableAdjust.getTableHeader().getDefaultRenderer(); | |
| 99 | } | |
| 100 | ||
| 101 | var c = renderer.getTableCellRendererComponent(this.tableAdjust, value, false, false, -1, column); | |
| 102 |
1
1. getColumnHeaderWidth : replaced int return with 0 for com/jsql/view/swing/table/AdjusterTableColumn::getColumnHeaderWidth → NO_COVERAGE |
return c.getPreferredSize().width; |
| 103 | } | |
| 104 | ||
| 105 | /** | |
| 106 | * Calculate the width based on the widest cell renderer for the | |
| 107 | * given column. | |
| 108 | */ | |
| 109 | private int getColumnDataWidth(int column) { | |
| 110 |
1
1. getColumnDataWidth : negated conditional → NO_COVERAGE |
if (!this.isColumnDataIncluded) { |
| 111 | return 0; | |
| 112 | } | |
| 113 | ||
| 114 | var preferredWidth = 0; | |
| 115 | int maxWidth = this.tableAdjust.getColumnModel().getColumn(column).getMaxWidth(); | |
| 116 | ||
| 117 |
2
1. getColumnDataWidth : changed conditional boundary → NO_COVERAGE 2. getColumnDataWidth : negated conditional → NO_COVERAGE |
for (var row = 0 ; row < this.tableAdjust.getRowCount() ; row++) { |
| 118 | preferredWidth = Math.max(preferredWidth, this.getCellDataWidth(row, column)); | |
| 119 | // We've exceeded the maximum width, no need to check other rows | |
| 120 |
2
1. getColumnDataWidth : changed conditional boundary → NO_COVERAGE 2. getColumnDataWidth : negated conditional → NO_COVERAGE |
if (preferredWidth >= maxWidth) { |
| 121 | break; | |
| 122 | } | |
| 123 | } | |
| 124 |
1
1. getColumnDataWidth : replaced int return with 0 for com/jsql/view/swing/table/AdjusterTableColumn::getColumnDataWidth → NO_COVERAGE |
return preferredWidth; |
| 125 | } | |
| 126 | ||
| 127 | /** | |
| 128 | * Get the preferred width for the specified cell | |
| 129 | */ | |
| 130 | private int getCellDataWidth(int row, int column) { | |
| 131 | // Invoke the renderer for the cell to calculate the preferred width | |
| 132 | TableCellRenderer cellRenderer = this.tableAdjust.getCellRenderer(row, column); | |
| 133 | Component c = this.tableAdjust.prepareRenderer(cellRenderer, row, column); | |
| 134 |
2
1. getCellDataWidth : Replaced integer addition with subtraction → NO_COVERAGE 2. getCellDataWidth : replaced int return with 0 for com/jsql/view/swing/table/AdjusterTableColumn::getCellDataWidth → NO_COVERAGE |
return c.getPreferredSize().width + this.tableAdjust.getIntercellSpacing().width; |
| 135 | } | |
| 136 | ||
| 137 | /** | |
| 138 | * Update the TableColumn with the newly calculated width | |
| 139 | */ | |
| 140 | private void updateTableColumn(int column, int width) { | |
| 141 | final var tableColumn = this.tableAdjust.getColumnModel().getColumn(column); | |
| 142 |
1
1. updateTableColumn : negated conditional → NO_COVERAGE |
if (!tableColumn.getResizable()) { |
| 143 | return; | |
| 144 | } | |
| 145 | ||
| 146 | int calculatedWidth = width; | |
| 147 |
1
1. updateTableColumn : Replaced integer addition with subtraction → NO_COVERAGE |
calculatedWidth += this.spacing; |
| 148 | // Don't shrink the column width | |
| 149 |
1
1. updateTableColumn : negated conditional → NO_COVERAGE |
if (this.isOnlyAdjustLarger) { |
| 150 | calculatedWidth = Math.max(calculatedWidth, tableColumn.getPreferredWidth()); | |
| 151 | } | |
| 152 | ||
| 153 | this.columnSizes.put(tableColumn, tableColumn.getWidth()); | |
| 154 |
1
1. updateTableColumn : removed call to javax/swing/table/JTableHeader::setResizingColumn → NO_COVERAGE |
this.tableAdjust.getTableHeader().setResizingColumn(tableColumn); |
| 155 |
1
1. updateTableColumn : removed call to javax/swing/table/TableColumn::setWidth → NO_COVERAGE |
tableColumn.setWidth(calculatedWidth); |
| 156 | } | |
| 157 | ||
| 158 | /** | |
| 159 | * Restore the widths of the columns in the table to its previous width | |
| 160 | */ | |
| 161 | public void restoreColumns() { | |
| 162 | TableColumnModel tableColumnModel = this.tableAdjust.getColumnModel(); | |
| 163 |
2
1. restoreColumns : changed conditional boundary → NO_COVERAGE 2. restoreColumns : negated conditional → NO_COVERAGE |
for (var i = 0 ; i < tableColumnModel.getColumnCount() ; i++) { |
| 164 |
1
1. restoreColumns : removed call to com/jsql/view/swing/table/AdjusterTableColumn::restoreColumn → NO_COVERAGE |
this.restoreColumn(i); |
| 165 | } | |
| 166 | } | |
| 167 | ||
| 168 | /** | |
| 169 | * Restore the width of the specified column to its previous width | |
| 170 | */ | |
| 171 | private void restoreColumn(int column) { | |
| 172 | var tableColumn = this.tableAdjust.getColumnModel().getColumn(column); | |
| 173 | Integer width = this.columnSizes.get(tableColumn); | |
| 174 |
1
1. restoreColumn : negated conditional → NO_COVERAGE |
if (width != null) { |
| 175 |
1
1. restoreColumn : removed call to javax/swing/table/JTableHeader::setResizingColumn → NO_COVERAGE |
this.tableAdjust.getTableHeader().setResizingColumn(tableColumn); |
| 176 |
1
1. restoreColumn : removed call to javax/swing/table/TableColumn::setWidth → NO_COVERAGE |
tableColumn.setWidth(width); |
| 177 | } | |
| 178 | } | |
| 179 | ||
| 180 | /** | |
| 181 | * Indicates whether to include the header in the width calculation | |
| 182 | */ | |
| 183 | public void setColumnHeaderIncluded(boolean isColumnHeaderIncluded) { | |
| 184 | this.isColumnHeaderIncluded = isColumnHeaderIncluded; | |
| 185 | } | |
| 186 | ||
| 187 | /** | |
| 188 | * Indicates whether to include the model data in the width calculation | |
| 189 | */ | |
| 190 | public void setColumnDataIncluded(boolean isColumnDataIncluded) { | |
| 191 | this.isColumnDataIncluded = isColumnDataIncluded; | |
| 192 | } | |
| 193 | ||
| 194 | /** | |
| 195 | * Indicates whether columns can only be increased in size | |
| 196 | */ | |
| 197 | public void setOnlyAdjustLarger(boolean isOnlyAdjustLarger) { | |
| 198 | this.isOnlyAdjustLarger = isOnlyAdjustLarger; | |
| 199 | } | |
| 200 | ||
| 201 | /** | |
| 202 | * Indicate whether changes to the model should cause the width to be | |
| 203 | * dynamically recalculated. | |
| 204 | */ | |
| 205 | public void setDynamicAdjustment(boolean isDynamicAdjustment) { | |
| 206 | // May need to add or remove the TableModelListener when changed | |
| 207 |
1
1. setDynamicAdjustment : negated conditional → NO_COVERAGE |
if (this.isDynamicAdjustment != isDynamicAdjustment) { |
| 208 |
1
1. setDynamicAdjustment : negated conditional → NO_COVERAGE |
if (isDynamicAdjustment) { |
| 209 |
1
1. setDynamicAdjustment : removed call to javax/swing/JTable::addPropertyChangeListener → NO_COVERAGE |
this.tableAdjust.addPropertyChangeListener(this); |
| 210 |
1
1. setDynamicAdjustment : removed call to javax/swing/table/TableModel::addTableModelListener → NO_COVERAGE |
this.tableAdjust.getModel().addTableModelListener(this); |
| 211 | } else { | |
| 212 |
1
1. setDynamicAdjustment : removed call to javax/swing/JTable::removePropertyChangeListener → NO_COVERAGE |
this.tableAdjust.removePropertyChangeListener(this); |
| 213 |
1
1. setDynamicAdjustment : removed call to javax/swing/table/TableModel::removeTableModelListener → NO_COVERAGE |
this.tableAdjust.getModel().removeTableModelListener(this); |
| 214 | } | |
| 215 | } | |
| 216 | this.isDynamicAdjustment = isDynamicAdjustment; | |
| 217 | } | |
| 218 | | |
| 219 | /** | |
| 220 | * Implement the PropertyChangeListener | |
| 221 | */ | |
| 222 | @Override | |
| 223 | public void propertyChange(PropertyChangeEvent e) { | |
| 224 | // When the TableModel changes we need to update the listeners | |
| 225 | // and column widths | |
| 226 |
1
1. propertyChange : negated conditional → NO_COVERAGE |
if ("model".equals(e.getPropertyName())) { |
| 227 | TableModel model = (TableModel) e.getOldValue(); | |
| 228 |
1
1. propertyChange : removed call to javax/swing/table/TableModel::removeTableModelListener → NO_COVERAGE |
model.removeTableModelListener(this); |
| 229 | ||
| 230 | model = (TableModel) e.getNewValue(); | |
| 231 |
1
1. propertyChange : removed call to javax/swing/table/TableModel::addTableModelListener → NO_COVERAGE |
model.addTableModelListener(this); |
| 232 |
1
1. propertyChange : removed call to com/jsql/view/swing/table/AdjusterTableColumn::adjustColumns → NO_COVERAGE |
this.adjustColumns(); |
| 233 | } | |
| 234 | } | |
| 235 | | |
| 236 | /** | |
| 237 | * Implement the TableModelListener | |
| 238 | */ | |
| 239 | @Override | |
| 240 | public void tableChanged(TableModelEvent e) { | |
| 241 |
1
1. tableChanged : negated conditional → NO_COVERAGE |
if (!this.isColumnDataIncluded) { |
| 242 | return; | |
| 243 | } | |
| 244 | ||
| 245 | // A cell has been updated | |
| 246 |
1
1. tableChanged : negated conditional → NO_COVERAGE |
if (e.getType() == TableModelEvent.UPDATE) { |
| 247 | int column = this.tableAdjust.convertColumnIndexToView(e.getColumn()); | |
| 248 | ||
| 249 | // Only need to worry about an increase in width for this cell | |
| 250 |
1
1. tableChanged : negated conditional → NO_COVERAGE |
if (this.isOnlyAdjustLarger) { |
| 251 | int row = e.getFirstRow(); | |
| 252 | var tableColumn = this.tableAdjust.getColumnModel().getColumn(column); | |
| 253 |
1
1. tableChanged : negated conditional → NO_COVERAGE |
if (tableColumn.getResizable()) { |
| 254 | int width = this.getCellDataWidth(row, column); | |
| 255 |
1
1. tableChanged : removed call to com/jsql/view/swing/table/AdjusterTableColumn::updateTableColumn → NO_COVERAGE |
this.updateTableColumn(column, width); |
| 256 | } | |
| 257 | } else { | |
| 258 |
1
1. tableChanged : removed call to com/jsql/view/swing/table/AdjusterTableColumn::adjustColumn → NO_COVERAGE |
this.adjustColumn(column); // Could be an increase of decrease so check all rows |
| 259 | } | |
| 260 | } else { | |
| 261 |
1
1. tableChanged : removed call to com/jsql/view/swing/table/AdjusterTableColumn::adjustColumns → NO_COVERAGE |
this.adjustColumns(); // The update affected more than one column so adjust all columns |
| 262 | } | |
| 263 | } | |
| 264 | ||
| 265 | /** | |
| 266 | * Install Actions to give user control of certain functionality. | |
| 267 | */ | |
| 268 | private void installActions() { | |
| 269 |
1
1. installActions : removed call to com/jsql/view/swing/table/AdjusterTableColumn::installColumnAction → NO_COVERAGE |
this.installColumnAction(true, true, "adjustColumn", "control ADD"); |
| 270 |
1
1. installActions : removed call to com/jsql/view/swing/table/AdjusterTableColumn::installColumnAction → NO_COVERAGE |
this.installColumnAction(false, true, "adjustColumns", "control shift ADD"); |
| 271 |
1
1. installActions : removed call to com/jsql/view/swing/table/AdjusterTableColumn::installColumnAction → NO_COVERAGE |
this.installColumnAction(true, false, "restoreColumn", "control SUBTRACT"); |
| 272 |
1
1. installActions : removed call to com/jsql/view/swing/table/AdjusterTableColumn::installColumnAction → NO_COVERAGE |
this.installColumnAction(false, false, "restoreColumns", "control shift SUBTRACT"); |
| 273 | ||
| 274 |
1
1. installActions : removed call to com/jsql/view/swing/table/AdjusterTableColumn::installToggleAction → NO_COVERAGE |
this.installToggleAction(true, false, "toggleDynamic", "control MULTIPLY"); |
| 275 |
1
1. installActions : removed call to com/jsql/view/swing/table/AdjusterTableColumn::installToggleAction → NO_COVERAGE |
this.installToggleAction(false, true, "toggleLarger", "control DIVIDE"); |
| 276 | } | |
| 277 | ||
| 278 | /** | |
| 279 | * Update the input and action maps with a new ColumnAction | |
| 280 | */ | |
| 281 | private void installColumnAction(boolean isSelectedColumn, boolean isAdjust, String key, String keyStroke) { | |
| 282 | Action action = new ColumnAction(isSelectedColumn, isAdjust); | |
| 283 | var ks = KeyStroke.getKeyStroke(keyStroke); | |
| 284 | | |
| 285 |
1
1. installColumnAction : removed call to javax/swing/InputMap::put → NO_COVERAGE |
this.tableAdjust.getInputMap().put(ks, key); |
| 286 |
1
1. installColumnAction : removed call to javax/swing/ActionMap::put → NO_COVERAGE |
this.tableAdjust.getActionMap().put(key, action); |
| 287 | } | |
| 288 | ||
| 289 | /** | |
| 290 | * Update the input and action maps with new ToggleAction | |
| 291 | */ | |
| 292 | private void installToggleAction(boolean isToggleDynamic, boolean isToggleLarger, String key, String keyStroke) { | |
| 293 | Action action = new ToggleAction(isToggleDynamic, isToggleLarger); | |
| 294 | var ks = KeyStroke.getKeyStroke(keyStroke); | |
| 295 | | |
| 296 |
1
1. installToggleAction : removed call to javax/swing/InputMap::put → NO_COVERAGE |
this.tableAdjust.getInputMap().put(ks, key); |
| 297 |
1
1. installToggleAction : removed call to javax/swing/ActionMap::put → NO_COVERAGE |
this.tableAdjust.getActionMap().put(key, action); |
| 298 | } | |
| 299 | ||
| 300 | /** | |
| 301 | * Action to adjust or restore the width of a single column or all columns | |
| 302 | */ | |
| 303 | class ColumnAction extends AbstractAction { | |
| 304 | | |
| 305 | private final boolean isSelectedColumn; | |
| 306 | private final boolean isAdjust; | |
| 307 | ||
| 308 | public ColumnAction(boolean isSelectedColumn, boolean isAdjust) { | |
| 309 | this.isSelectedColumn = isSelectedColumn; | |
| 310 | this.isAdjust = isAdjust; | |
| 311 | } | |
| 312 | ||
| 313 | @Override | |
| 314 | public void actionPerformed(ActionEvent e) { | |
| 315 | // Handle selected column(s) width change actions | |
| 316 |
1
1. actionPerformed : negated conditional → NO_COVERAGE |
if (this.isSelectedColumn) { |
| 317 | int[] columns = AdjusterTableColumn.this.tableAdjust.getSelectedColumns(); | |
| 318 | ||
| 319 | for (int column: columns) { | |
| 320 |
1
1. actionPerformed : negated conditional → NO_COVERAGE |
if (this.isAdjust) { |
| 321 |
1
1. actionPerformed : removed call to com/jsql/view/swing/table/AdjusterTableColumn::adjustColumn → NO_COVERAGE |
AdjusterTableColumn.this.adjustColumn(column); |
| 322 | } else { | |
| 323 |
1
1. actionPerformed : removed call to com/jsql/view/swing/table/AdjusterTableColumn::restoreColumn → NO_COVERAGE |
AdjusterTableColumn.this.restoreColumn(column); |
| 324 | } | |
| 325 | } | |
| 326 | } else { | |
| 327 |
1
1. actionPerformed : negated conditional → NO_COVERAGE |
if (this.isAdjust) { |
| 328 |
1
1. actionPerformed : removed call to com/jsql/view/swing/table/AdjusterTableColumn::adjustColumns → NO_COVERAGE |
AdjusterTableColumn.this.adjustColumns(); |
| 329 | } else { | |
| 330 |
1
1. actionPerformed : removed call to com/jsql/view/swing/table/AdjusterTableColumn::restoreColumns → NO_COVERAGE |
AdjusterTableColumn.this.restoreColumns(); |
| 331 | } | |
| 332 | } | |
| 333 | } | |
| 334 | } | |
| 335 | ||
| 336 | /** | |
| 337 | * Toggle properties of the TableColumnAdjuster so the user can | |
| 338 | * customize the functionality to their preferences | |
| 339 | */ | |
| 340 | class ToggleAction extends AbstractAction { | |
| 341 | | |
| 342 | private final boolean isToggleDynamic; | |
| 343 | private final boolean isToggleLarger; | |
| 344 | ||
| 345 | public ToggleAction(boolean isToggleDynamic, boolean isToggleLarger) { | |
| 346 | this.isToggleDynamic = isToggleDynamic; | |
| 347 | this.isToggleLarger = isToggleLarger; | |
| 348 | } | |
| 349 | ||
| 350 | @Override | |
| 351 | public void actionPerformed(ActionEvent e) { | |
| 352 |
1
1. actionPerformed : negated conditional → NO_COVERAGE |
if (this.isToggleDynamic) { |
| 353 |
2
1. actionPerformed : removed call to com/jsql/view/swing/table/AdjusterTableColumn::setDynamicAdjustment → NO_COVERAGE 2. actionPerformed : negated conditional → NO_COVERAGE |
AdjusterTableColumn.this.setDynamicAdjustment(!AdjusterTableColumn.this.isDynamicAdjustment); |
| 354 |
1
1. actionPerformed : negated conditional → NO_COVERAGE |
} else if (this.isToggleLarger) { |
| 355 |
2
1. actionPerformed : negated conditional → NO_COVERAGE 2. actionPerformed : removed call to com/jsql/view/swing/table/AdjusterTableColumn::setOnlyAdjustLarger → NO_COVERAGE |
AdjusterTableColumn.this.setOnlyAdjustLarger(!AdjusterTableColumn.this.isOnlyAdjustLarger); |
| 356 | } | |
| 357 | } | |
| 358 | } | |
| 359 | } | |
Mutations | ||
| 54 |
1.1 |
|
| 55 |
1.1 |
|
| 56 |
1.1 |
|
| 57 |
1.1 |
|
| 58 |
1.1 |
|
| 66 |
1.1 2.2 |
|
| 67 |
1.1 |
|
| 76 |
1.1 |
|
| 83 |
1.1 |
|
| 90 |
1.1 |
|
| 97 |
1.1 |
|
| 102 |
1.1 |
|
| 110 |
1.1 |
|
| 117 |
1.1 2.2 |
|
| 120 |
1.1 2.2 |
|
| 124 |
1.1 |
|
| 134 |
1.1 2.2 |
|
| 142 |
1.1 |
|
| 147 |
1.1 |
|
| 149 |
1.1 |
|
| 154 |
1.1 |
|
| 155 |
1.1 |
|
| 163 |
1.1 2.2 |
|
| 164 |
1.1 |
|
| 174 |
1.1 |
|
| 175 |
1.1 |
|
| 176 |
1.1 |
|
| 207 |
1.1 |
|
| 208 |
1.1 |
|
| 209 |
1.1 |
|
| 210 |
1.1 |
|
| 212 |
1.1 |
|
| 213 |
1.1 |
|
| 226 |
1.1 |
|
| 228 |
1.1 |
|
| 231 |
1.1 |
|
| 232 |
1.1 |
|
| 241 |
1.1 |
|
| 246 |
1.1 |
|
| 250 |
1.1 |
|
| 253 |
1.1 |
|
| 255 |
1.1 |
|
| 258 |
1.1 |
|
| 261 |
1.1 |
|
| 269 |
1.1 |
|
| 270 |
1.1 |
|
| 271 |
1.1 |
|
| 272 |
1.1 |
|
| 274 |
1.1 |
|
| 275 |
1.1 |
|
| 285 |
1.1 |
|
| 286 |
1.1 |
|
| 296 |
1.1 |
|
| 297 |
1.1 |
|
| 316 |
1.1 |
|
| 320 |
1.1 |
|
| 321 |
1.1 |
|
| 323 |
1.1 |
|
| 327 |
1.1 |
|
| 328 |
1.1 |
|
| 330 |
1.1 |
|
| 352 |
1.1 |
|
| 353 |
1.1 2.2 |
|
| 354 |
1.1 |
|
| 355 |
1.1 2.2 |