[447] | 1 | // Module : $RCSfile: Key.java,v $ |
---|
| 2 | // Version : $Revision: 0.0 $ $Author: patrick $ $Date: 01.04.2012 $ |
---|
| 3 | // Project : TaskTreeCreator |
---|
| 4 | // Creation : 2012 by patrick |
---|
| 5 | // Copyright : Patrick Harms, 2012 |
---|
[558] | 6 | |
---|
| 7 | |
---|
[447] | 8 | package de.ugoe.cs.tasktree.keyboardmaps; |
---|
| 9 | |
---|
| 10 | import java.awt.event.KeyEvent; |
---|
| 11 | |
---|
| 12 | /** |
---|
| 13 | * TODO comment |
---|
[558] | 14 | * |
---|
[447] | 15 | * @version $Revision: $ $Date: 01.04.2012$ |
---|
| 16 | * @author 2012, last modified by $Author: patrick$ |
---|
| 17 | */ |
---|
[558] | 18 | public enum VirtualKey { |
---|
| 19 | |
---|
[447] | 20 | ENTER(KeyEvent.VK_ENTER), |
---|
| 21 | BACK_SPACE(KeyEvent.VK_BACK_SPACE), |
---|
| 22 | TAB(KeyEvent.VK_TAB), |
---|
| 23 | CANCEL(KeyEvent.VK_CANCEL), |
---|
| 24 | CLEAR(KeyEvent.VK_CLEAR), |
---|
| 25 | SHIFT(KeyEvent.VK_SHIFT), |
---|
| 26 | CONTROL(KeyEvent.VK_CONTROL), |
---|
| 27 | ALT(KeyEvent.VK_ALT), |
---|
| 28 | PAUSE(KeyEvent.VK_PAUSE), |
---|
| 29 | CAPS_LOCK(KeyEvent.VK_CAPS_LOCK), |
---|
| 30 | ESCAPE(KeyEvent.VK_ESCAPE), |
---|
| 31 | SPACE(KeyEvent.VK_SPACE), |
---|
| 32 | PAGE_UP(KeyEvent.VK_PAGE_UP), |
---|
| 33 | PAGE_DOWN(KeyEvent.VK_PAGE_DOWN), |
---|
| 34 | END(KeyEvent.VK_END), |
---|
| 35 | HOME(KeyEvent.VK_HOME), |
---|
| 36 | |
---|
| 37 | LEFT(KeyEvent.VK_LEFT), |
---|
| 38 | UP(KeyEvent.VK_UP), |
---|
| 39 | RIGHT(KeyEvent.VK_RIGHT), |
---|
| 40 | DOWN(KeyEvent.VK_DOWN), |
---|
| 41 | |
---|
| 42 | COMMA(KeyEvent.VK_COMMA), |
---|
| 43 | MINUS(KeyEvent.VK_MINUS), |
---|
| 44 | PERIOD(KeyEvent.VK_PERIOD), |
---|
| 45 | SLASH(KeyEvent.VK_SLASH), |
---|
| 46 | |
---|
| 47 | DIGIT_0(KeyEvent.VK_0), |
---|
| 48 | DIGIT_1(KeyEvent.VK_1), |
---|
| 49 | DIGIT_2(KeyEvent.VK_2), |
---|
| 50 | DIGIT_3(KeyEvent.VK_3), |
---|
| 51 | DIGIT_4(KeyEvent.VK_4), |
---|
| 52 | DIGIT_5(KeyEvent.VK_5), |
---|
| 53 | DIGIT_6(KeyEvent.VK_6), |
---|
| 54 | DIGIT_7(KeyEvent.VK_7), |
---|
| 55 | DIGIT_8(KeyEvent.VK_8), |
---|
| 56 | DIGIT_9(KeyEvent.VK_9), |
---|
| 57 | |
---|
| 58 | SEMICOLON(KeyEvent.VK_SEMICOLON), |
---|
| 59 | EQUALS(KeyEvent.VK_EQUALS), |
---|
| 60 | |
---|
| 61 | LETTER_A(KeyEvent.VK_A), |
---|
| 62 | LETTER_B(KeyEvent.VK_B), |
---|
| 63 | LETTER_C(KeyEvent.VK_C), |
---|
| 64 | LETTER_D(KeyEvent.VK_D), |
---|
| 65 | LETTER_E(KeyEvent.VK_E), |
---|
| 66 | LETTER_F(KeyEvent.VK_F), |
---|
| 67 | LETTER_G(KeyEvent.VK_G), |
---|
| 68 | LETTER_H(KeyEvent.VK_H), |
---|
| 69 | LETTER_I(KeyEvent.VK_I), |
---|
| 70 | LETTER_J(KeyEvent.VK_J), |
---|
| 71 | LETTER_K(KeyEvent.VK_K), |
---|
| 72 | LETTER_L(KeyEvent.VK_L), |
---|
| 73 | LETTER_M(KeyEvent.VK_M), |
---|
| 74 | LETTER_N(KeyEvent.VK_N), |
---|
| 75 | LETTER_O(KeyEvent.VK_O), |
---|
| 76 | LETTER_P(KeyEvent.VK_P), |
---|
| 77 | LETTER_Q(KeyEvent.VK_Q), |
---|
| 78 | LETTER_R(KeyEvent.VK_R), |
---|
| 79 | LETTER_S(KeyEvent.VK_S), |
---|
| 80 | LETTER_T(KeyEvent.VK_T), |
---|
| 81 | LETTER_U(KeyEvent.VK_U), |
---|
| 82 | LETTER_V(KeyEvent.VK_V), |
---|
| 83 | LETTER_W(KeyEvent.VK_W), |
---|
| 84 | LETTER_X(KeyEvent.VK_X), |
---|
| 85 | LETTER_Y(KeyEvent.VK_Y), |
---|
| 86 | LETTER_Z(KeyEvent.VK_Z), |
---|
| 87 | |
---|
| 88 | OPEN_BRACKET(KeyEvent.VK_OPEN_BRACKET), |
---|
| 89 | BACK_SLASH(KeyEvent.VK_BACK_SLASH), |
---|
| 90 | CLOSE_BRACKET(KeyEvent.VK_CLOSE_BRACKET), |
---|
| 91 | |
---|
| 92 | NUMPAD_0(KeyEvent.VK_NUMPAD0), |
---|
| 93 | NUMPAD_1(KeyEvent.VK_NUMPAD1), |
---|
| 94 | NUMPAD_2(KeyEvent.VK_NUMPAD2), |
---|
| 95 | NUMPAD_3(KeyEvent.VK_NUMPAD3), |
---|
| 96 | NUMPAD_4(KeyEvent.VK_NUMPAD4), |
---|
| 97 | NUMPAD_5(KeyEvent.VK_NUMPAD5), |
---|
| 98 | NUMPAD_6(KeyEvent.VK_NUMPAD6), |
---|
| 99 | NUMPAD_7(KeyEvent.VK_NUMPAD7), |
---|
| 100 | NUMPAD_8(KeyEvent.VK_NUMPAD8), |
---|
| 101 | NUMPAD_9(KeyEvent.VK_NUMPAD9), |
---|
| 102 | MULTIPLY(KeyEvent.VK_MULTIPLY), |
---|
| 103 | ADD(KeyEvent.VK_ADD), |
---|
| 104 | |
---|
| 105 | SEPARATOR(KeyEvent.VK_SEPARATOR), |
---|
| 106 | |
---|
| 107 | SUBTRACT(KeyEvent.VK_SUBTRACT), |
---|
| 108 | DECIMAL(KeyEvent.VK_DECIMAL), |
---|
| 109 | DIVIDE(KeyEvent.VK_DIVIDE), |
---|
| 110 | DELETE(KeyEvent.VK_DELETE), |
---|
| 111 | NUM_LOCK(KeyEvent.VK_NUM_LOCK), |
---|
| 112 | SCROLL_LOCK(KeyEvent.VK_SCROLL_LOCK), |
---|
| 113 | |
---|
| 114 | F1(KeyEvent.VK_F1), |
---|
| 115 | F2(KeyEvent.VK_F2), |
---|
| 116 | F3(KeyEvent.VK_F3), |
---|
| 117 | F4(KeyEvent.VK_F4), |
---|
| 118 | F5(KeyEvent.VK_F5), |
---|
| 119 | F6(KeyEvent.VK_F6), |
---|
| 120 | F7(KeyEvent.VK_F7), |
---|
| 121 | F8(KeyEvent.VK_F8), |
---|
| 122 | F9(KeyEvent.VK_F9), |
---|
| 123 | F10(KeyEvent.VK_F10), |
---|
| 124 | F11(KeyEvent.VK_F11), |
---|
| 125 | F12(KeyEvent.VK_F12), |
---|
| 126 | F13(KeyEvent.VK_F13), |
---|
| 127 | F14(KeyEvent.VK_F14), |
---|
| 128 | F15(KeyEvent.VK_F15), |
---|
| 129 | F16(KeyEvent.VK_F16), |
---|
| 130 | F17(KeyEvent.VK_F17), |
---|
| 131 | F18(KeyEvent.VK_F18), |
---|
| 132 | F19(KeyEvent.VK_F19), |
---|
| 133 | F20(KeyEvent.VK_F20), |
---|
| 134 | F21(KeyEvent.VK_F21), |
---|
| 135 | F22(KeyEvent.VK_F22), |
---|
| 136 | F23(KeyEvent.VK_F23), |
---|
| 137 | F24(KeyEvent.VK_F24), |
---|
| 138 | |
---|
| 139 | PRINTSCREEN(KeyEvent.VK_PRINTSCREEN), |
---|
| 140 | INSERT(KeyEvent.VK_INSERT), |
---|
| 141 | HELP(KeyEvent.VK_HELP), |
---|
| 142 | META(KeyEvent.VK_META), |
---|
| 143 | |
---|
| 144 | BACK_QUOTE(KeyEvent.VK_BACK_QUOTE), |
---|
| 145 | QUOTE(KeyEvent.VK_QUOTE), |
---|
| 146 | |
---|
| 147 | KP_UP(KeyEvent.VK_KP_UP), |
---|
| 148 | KP_DOWN(KeyEvent.VK_KP_DOWN), |
---|
| 149 | KP_LEFT(KeyEvent.VK_KP_LEFT), |
---|
| 150 | KP_RIGHT(KeyEvent.VK_KP_RIGHT), |
---|
| 151 | |
---|
| 152 | DEAD_GRAVE(KeyEvent.VK_DEAD_GRAVE), |
---|
| 153 | DEAD_ACUTE(KeyEvent.VK_DEAD_ACUTE), |
---|
| 154 | DEAD_CIRCUMFLEX(KeyEvent.VK_DEAD_CIRCUMFLEX), |
---|
| 155 | DEAD_TILDE(KeyEvent.VK_DEAD_TILDE), |
---|
| 156 | DEAD_MACRON(KeyEvent.VK_DEAD_MACRON), |
---|
| 157 | DEAD_BREVE(KeyEvent.VK_DEAD_BREVE), |
---|
| 158 | DEAD_ABOVEDOT(KeyEvent.VK_DEAD_ABOVEDOT), |
---|
| 159 | DEAD_DIAERESIS(KeyEvent.VK_DEAD_DIAERESIS), |
---|
| 160 | DEAD_ABOVERING(KeyEvent.VK_DEAD_ABOVERING), |
---|
| 161 | DEAD_DOUBLEACUTE(KeyEvent.VK_DEAD_DOUBLEACUTE), |
---|
| 162 | DEAD_CARON(KeyEvent.VK_DEAD_CARON), |
---|
| 163 | DEAD_CEDILLA(KeyEvent.VK_DEAD_CEDILLA), |
---|
| 164 | DEAD_OGONEK(KeyEvent.VK_DEAD_OGONEK), |
---|
| 165 | DEAD_IOTA(KeyEvent.VK_DEAD_IOTA), |
---|
| 166 | DEAD_VOICED_SOUND(KeyEvent.VK_DEAD_VOICED_SOUND), |
---|
| 167 | DEAD_SEMIVOICED_SOUND(KeyEvent.VK_DEAD_SEMIVOICED_SOUND), |
---|
| 168 | |
---|
| 169 | AMPERSAND(KeyEvent.VK_AMPERSAND), |
---|
| 170 | ASTERISK(KeyEvent.VK_ASTERISK), |
---|
| 171 | QUOTEDBL(KeyEvent.VK_QUOTEDBL), |
---|
| 172 | LESS(KeyEvent.VK_LESS), |
---|
| 173 | GREATER(KeyEvent.VK_GREATER), |
---|
| 174 | BRACELEFT(KeyEvent.VK_BRACELEFT), |
---|
| 175 | BRACERIGHT(KeyEvent.VK_BRACERIGHT), |
---|
| 176 | |
---|
| 177 | AT(KeyEvent.VK_AT), |
---|
| 178 | COLON(KeyEvent.VK_COLON), |
---|
| 179 | CIRCUMFLEX(KeyEvent.VK_CIRCUMFLEX), |
---|
| 180 | DOLLAR(KeyEvent.VK_DOLLAR), |
---|
| 181 | EURO_SIGN(KeyEvent.VK_EURO_SIGN), |
---|
| 182 | EXCLAMATION_MARK(KeyEvent.VK_EXCLAMATION_MARK), |
---|
| 183 | INVERTED_EXCLAMATION_MARK(KeyEvent.VK_INVERTED_EXCLAMATION_MARK), |
---|
| 184 | LEFT_PARENTHESIS(KeyEvent.VK_LEFT_PARENTHESIS), |
---|
| 185 | NUMBER_SIGN(KeyEvent.VK_NUMBER_SIGN), |
---|
| 186 | PLUS(KeyEvent.VK_PLUS), |
---|
| 187 | RIGHT_PARENTHESIS(KeyEvent.VK_RIGHT_PARENTHESIS), |
---|
| 188 | UNDERSCORE(KeyEvent.VK_UNDERSCORE), |
---|
| 189 | |
---|
| 190 | WINDOWS(KeyEvent.VK_WINDOWS), |
---|
| 191 | CONTEXT_MENU(KeyEvent.VK_CONTEXT_MENU), |
---|
| 192 | |
---|
| 193 | FINAL(KeyEvent.VK_FINAL), |
---|
| 194 | CONVERT(KeyEvent.VK_CONVERT), |
---|
| 195 | NONCONVERT(KeyEvent.VK_NONCONVERT), |
---|
| 196 | ACCEPT(KeyEvent.VK_ACCEPT), |
---|
| 197 | MODECHANGE(KeyEvent.VK_MODECHANGE), |
---|
| 198 | KANA(KeyEvent.VK_KANA), |
---|
| 199 | KANJI(KeyEvent.VK_KANJI), |
---|
| 200 | ALPHANUMERIC(KeyEvent.VK_ALPHANUMERIC), |
---|
| 201 | KATAKANA(KeyEvent.VK_KATAKANA), |
---|
| 202 | HIRAGANA(KeyEvent.VK_HIRAGANA), |
---|
| 203 | FULL_WIDTH(KeyEvent.VK_FULL_WIDTH), |
---|
| 204 | HALF_WIDTH(KeyEvent.VK_HALF_WIDTH), |
---|
| 205 | ROMAN_CHARACTERS(KeyEvent.VK_ROMAN_CHARACTERS), |
---|
| 206 | ALL_CANDIDATES(KeyEvent.VK_ALL_CANDIDATES), |
---|
| 207 | PREVIOUS_CANDIDATE(KeyEvent.VK_PREVIOUS_CANDIDATE), |
---|
| 208 | CODE_INPUT(KeyEvent.VK_CODE_INPUT), |
---|
| 209 | JAPANESE_KATAKANA(KeyEvent.VK_JAPANESE_KATAKANA), |
---|
| 210 | JAPANESE_HIRAGANA(KeyEvent.VK_JAPANESE_HIRAGANA), |
---|
| 211 | JAPANESE_ROMAN(KeyEvent.VK_JAPANESE_ROMAN), |
---|
| 212 | KANA_LOCK(KeyEvent.VK_KANA_LOCK), |
---|
| 213 | INPUT_METHOD_ON_OFF(KeyEvent.VK_INPUT_METHOD_ON_OFF), |
---|
| 214 | |
---|
| 215 | CUT(KeyEvent.VK_CUT), |
---|
| 216 | COPY(KeyEvent.VK_COPY), |
---|
| 217 | PASTE(KeyEvent.VK_PASTE), |
---|
| 218 | UNDO(KeyEvent.VK_UNDO), |
---|
| 219 | AGAIN(KeyEvent.VK_AGAIN), |
---|
| 220 | FIND(KeyEvent.VK_FIND), |
---|
| 221 | PROPS(KeyEvent.VK_PROPS), |
---|
| 222 | STOP(KeyEvent.VK_STOP), |
---|
| 223 | COMPOSE(KeyEvent.VK_COMPOSE), |
---|
| 224 | ALT_GRAPH(KeyEvent.VK_ALT_GRAPH), |
---|
| 225 | BEGIN(KeyEvent.VK_BEGIN), |
---|
| 226 | |
---|
| 227 | UNDEFINED(KeyEvent.VK_UNDEFINED); |
---|
| 228 | |
---|
[558] | 229 | /* |
---|
| 230 | * BAR(KeyEvent.VK_UNDEFINED), |
---|
| 231 | * APOSTROPHE(KeyEvent.VK_UNDEFINED), |
---|
| 232 | * QUESTIONMARK(KeyEvent.VK_UNDEFINED), |
---|
| 233 | * DEGREE(KeyEvent.VK_UNDEFINED), |
---|
| 234 | * HENKAN_MODE(KeyEvent.VK_UNDEFINED), |
---|
| 235 | * MUHENKAN(KeyEvent.VK_UNDEFINED), |
---|
| 236 | * EISU_TOGGLE(KeyEvent.VK_UNDEFINED), |
---|
| 237 | * HANGUL(KeyEvent.VK_UNDEFINED), |
---|
| 238 | * HANGUL_HANJA(KeyEvent.VK_UNDEFINED), |
---|
| 239 | * EXECUTE(KeyEvent.VK_UNDEFINED); |
---|
| 240 | */ |
---|
[447] | 241 | |
---|
[558] | 242 | /** the virtual key code of the virtual key. */ |
---|
| 243 | private int virtualKeyCode = -1; |
---|
[447] | 244 | |
---|
[558] | 245 | /** the description of the virtual key */ |
---|
| 246 | private String description; |
---|
| 247 | |
---|
| 248 | /** |
---|
[447] | 249 | * |
---|
| 250 | */ |
---|
[558] | 251 | private VirtualKey(int virtualKeyCode) { |
---|
| 252 | this.virtualKeyCode = virtualKeyCode; |
---|
| 253 | this.description = KeyEvent.getKeyText(this.virtualKeyCode); |
---|
| 254 | } |
---|
[447] | 255 | |
---|
[558] | 256 | /** |
---|
| 257 | * @return Returns the description. |
---|
| 258 | */ |
---|
| 259 | String getDescription() { |
---|
| 260 | return description; |
---|
| 261 | } |
---|
[447] | 262 | |
---|
[558] | 263 | /** |
---|
[447] | 264 | * |
---|
| 265 | */ |
---|
[558] | 266 | public boolean isCombinationKey() { |
---|
| 267 | switch (this) |
---|
| 268 | { |
---|
| 269 | case SHIFT: |
---|
| 270 | case CONTROL: |
---|
| 271 | case ALT: |
---|
| 272 | case ALT_GRAPH: |
---|
| 273 | case WINDOWS: |
---|
| 274 | return true; |
---|
[447] | 275 | |
---|
[558] | 276 | default: |
---|
| 277 | return false; |
---|
| 278 | } |
---|
[447] | 279 | } |
---|
| 280 | |
---|
[558] | 281 | /** |
---|
[447] | 282 | * |
---|
| 283 | */ |
---|
[558] | 284 | public boolean isLockKey() { |
---|
| 285 | switch (this) |
---|
| 286 | { |
---|
| 287 | case CAPS_LOCK: |
---|
| 288 | case NUM_LOCK: |
---|
| 289 | case SCROLL_LOCK: |
---|
| 290 | return true; |
---|
[447] | 291 | |
---|
[558] | 292 | default: |
---|
| 293 | return false; |
---|
| 294 | } |
---|
[447] | 295 | } |
---|
| 296 | |
---|
[558] | 297 | /** |
---|
[447] | 298 | * |
---|
| 299 | */ |
---|
[558] | 300 | public boolean isShiftKey() { |
---|
| 301 | switch (this) |
---|
| 302 | { |
---|
| 303 | case SHIFT: |
---|
| 304 | return true; |
---|
[447] | 305 | |
---|
[558] | 306 | default: |
---|
| 307 | return false; |
---|
| 308 | } |
---|
[447] | 309 | } |
---|
| 310 | |
---|
[558] | 311 | /** |
---|
[447] | 312 | * |
---|
| 313 | */ |
---|
[558] | 314 | public boolean isAltKey() { |
---|
| 315 | switch (this) |
---|
| 316 | { |
---|
| 317 | case ALT: |
---|
| 318 | case ALT_GRAPH: |
---|
| 319 | return true; |
---|
[447] | 320 | |
---|
[558] | 321 | default: |
---|
| 322 | return false; |
---|
| 323 | } |
---|
[447] | 324 | } |
---|
| 325 | |
---|
[558] | 326 | /** |
---|
[447] | 327 | * |
---|
| 328 | */ |
---|
[558] | 329 | public boolean isControlKey() { |
---|
| 330 | switch (this) |
---|
| 331 | { |
---|
| 332 | case CONTROL: |
---|
| 333 | return true; |
---|
[447] | 334 | |
---|
[558] | 335 | default: |
---|
| 336 | return false; |
---|
| 337 | } |
---|
[447] | 338 | } |
---|
| 339 | |
---|
[558] | 340 | /** |
---|
[447] | 341 | * |
---|
| 342 | */ |
---|
[558] | 343 | public boolean isWindowsKey() { |
---|
| 344 | switch (this) |
---|
| 345 | { |
---|
| 346 | case WINDOWS: |
---|
| 347 | return true; |
---|
[447] | 348 | |
---|
[558] | 349 | default: |
---|
| 350 | return false; |
---|
| 351 | } |
---|
[447] | 352 | } |
---|
| 353 | |
---|
[558] | 354 | /** |
---|
[447] | 355 | * |
---|
| 356 | */ |
---|
[558] | 357 | public boolean isMetaKey() { |
---|
| 358 | switch (this) |
---|
| 359 | { |
---|
| 360 | case META: |
---|
| 361 | return true; |
---|
[447] | 362 | |
---|
[558] | 363 | default: |
---|
| 364 | return false; |
---|
| 365 | } |
---|
[447] | 366 | } |
---|
| 367 | |
---|
[558] | 368 | /** |
---|
[447] | 369 | * |
---|
| 370 | */ |
---|
[558] | 371 | public boolean isLetter() { |
---|
| 372 | if (virtualKeyCode > -1) { |
---|
| 373 | return Character.isLetter((char) virtualKeyCode); |
---|
| 374 | } |
---|
| 375 | else { |
---|
| 376 | return false; |
---|
| 377 | } |
---|
[447] | 378 | } |
---|
| 379 | |
---|
[558] | 380 | /** |
---|
[447] | 381 | * |
---|
| 382 | */ |
---|
[558] | 383 | public boolean isDigit() { |
---|
| 384 | if (virtualKeyCode > -1) { |
---|
| 385 | return Character.isDigit(virtualKeyCode); |
---|
| 386 | } |
---|
| 387 | else { |
---|
| 388 | return false; |
---|
| 389 | } |
---|
[447] | 390 | } |
---|
[558] | 391 | |
---|
| 392 | /** |
---|
| 393 | * TODO: comment |
---|
| 394 | * |
---|
| 395 | * @param parameter |
---|
| 396 | * @return |
---|
| 397 | */ |
---|
| 398 | public static VirtualKey parseVirtualKey(String string) { |
---|
| 399 | int virtualKeyCode = Integer.parseInt(string); |
---|
| 400 | for (VirtualKey key1 : VirtualKey.values()) { |
---|
| 401 | if (key1.virtualKeyCode == virtualKeyCode) { |
---|
| 402 | return key1; |
---|
| 403 | } |
---|
| 404 | } |
---|
| 405 | |
---|
| 406 | throw new IllegalArgumentException("there is no virtual key with id " + string); |
---|
[447] | 407 | } |
---|
| 408 | |
---|
[558] | 409 | /** |
---|
[447] | 410 | * |
---|
| 411 | */ |
---|
[558] | 412 | public static VirtualKey valueOf(int number) { |
---|
| 413 | for (VirtualKey virtualKey : VirtualKey.values()) { |
---|
| 414 | if (virtualKey.virtualKeyCode == number) { |
---|
| 415 | return virtualKey; |
---|
| 416 | } |
---|
| 417 | } |
---|
[447] | 418 | |
---|
[558] | 419 | throw new IllegalArgumentException("there is no virtual key with number " + number); |
---|
[447] | 420 | } |
---|
| 421 | |
---|
| 422 | } |
---|