OLD | NEW |
1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 // TODO(terry): Need to be consistent with tokens either they're ASCII tokens | 5 // TODO(terry): Need to be consistent with tokens either they're ASCII tokens |
6 // e.g., ASTERISK or they're CSS e.g., PSEUDO, COMBINATOR_*. | 6 // e.g., ASTERISK or they're CSS e.g., PSEUDO, COMBINATOR_*. |
7 class TokenKind { | 7 class TokenKind { |
8 // Common shared tokens used in TokenizerBase. | 8 // Common shared tokens used in TokenizerBase. |
9 static final int UNUSED = 0; // Unused place holder... | 9 static const int UNUSED = 0; // Unused place holder... |
10 static final int END_OF_FILE = 1; | 10 static const int END_OF_FILE = 1; |
11 static final int LPAREN = 2; // ( | 11 static const int LPAREN = 2; // ( |
12 static final int RPAREN = 3; // ) | 12 static const int RPAREN = 3; // ) |
13 static final int LBRACK = 4; // [ | 13 static const int LBRACK = 4; // [ |
14 static final int RBRACK = 5; // ] | 14 static const int RBRACK = 5; // ] |
15 static final int LBRACE = 6; // { | 15 static const int LBRACE = 6; // { |
16 static final int RBRACE = 7; // } | 16 static const int RBRACE = 7; // } |
17 static final int DOT = 8; // . | 17 static const int DOT = 8; // . |
18 static final int SEMICOLON = 9; // ; | 18 static const int SEMICOLON = 9; // ; |
19 static final int SPACE = 10; // space character | 19 static const int SPACE = 10; // space character |
20 static final int TAB = 11; // \t | 20 static const int TAB = 11; // \t |
21 static final int NEWLINE = 12; // \n | 21 static const int NEWLINE = 12; // \n |
22 static final int RETURN = 13; // \r | 22 static const int RETURN = 13; // \r |
23 static final int COMMA = 14; // , | 23 static const int COMMA = 14; // , |
24 | 24 |
25 // Unique tokens. | 25 // Unique tokens. |
26 static final int LESS_THAN = 15; // < | 26 static const int LESS_THAN = 15; // < |
27 static final int GREATER_THAN = 16; // > | 27 static const int GREATER_THAN = 16; // > |
28 static final int SLASH = 17; // / | 28 static const int SLASH = 17; // / |
29 static final int DOLLAR = 18; // $ | 29 static const int DOLLAR = 18; // $ |
30 static final int HASH = 19; // # | 30 static const int HASH = 19; // # |
31 static final int MINUS = 20; // - | 31 static const int MINUS = 20; // - |
32 static final int EQUAL = 21; // = | 32 static const int EQUAL = 21; // = |
33 static final int DOUBLE_QUOTE = 22; // " | 33 static const int DOUBLE_QUOTE = 22; // " |
34 static final int SINGLE_QUOTE = 23; // ' | 34 static const int SINGLE_QUOTE = 23; // ' |
35 static final int ASTERISK = 24; // * | 35 static const int ASTERISK = 24; // * |
36 | 36 |
37 // WARNING: END_TOKENS must be 1 greater than the last token above (last | 37 // WARNING: END_TOKENS must be 1 greater than the last token above (last |
38 // character in our list). Also add to kindToString function and the | 38 // character in our list). Also add to kindToString function and the |
39 // constructor for TokenKind. | 39 // constructor for TokenKind. |
40 | 40 |
41 static final int END_TOKENS = 25; // Marker for last token in list | 41 static const int END_TOKENS = 25; // Marker for last token in list |
42 | 42 |
43 // Synthesized tokens: | 43 // Synthesized tokens: |
44 | 44 |
45 static final int END_NO_SCOPE_TAG = 50; // /> | 45 static const int END_NO_SCOPE_TAG = 50; // /> |
46 static final int START_EXPRESSION = 51; // ${ | 46 static const int START_EXPRESSION = 51; // ${ |
47 static final int START_COMMAND = 52; // ${# | 47 static const int START_COMMAND = 52; // ${# |
48 static final int END_COMMAND = 53; // ${/ | 48 static const int END_COMMAND = 53; // ${/ |
49 static final int EACH_COMMAND = 53; // ${#each list} | 49 static const int EACH_COMMAND = 53; // ${#each list} |
50 static final int WITH_COMMAND = 54; // ${#with object} | 50 static const int WITH_COMMAND = 54; // ${#with object} |
51 static final int IF_COMMAND = 55; // ${#if (expression)} | 51 static const int IF_COMMAND = 55; // ${#if (expression)} |
52 static final int ELSE_COMMAND = 56; // ${#else} | 52 static const int ELSE_COMMAND = 56; // ${#else} |
53 | 53 |
54 /** [TokenKind] representing integer tokens. */ | 54 /** [TokenKind] representing integer tokens. */ |
55 static final int INTEGER = 60; // TODO(terry): must match base | 55 static const int INTEGER = 60; // TODO(terry): must match base |
56 | 56 |
57 /** [TokenKind] representing hex integer tokens. */ | 57 /** [TokenKind] representing hex integer tokens. */ |
58 // static final int HEX_INTEGER = 61; // TODO(terry): must match base | 58 // static const int HEX_INTEGER = 61; // TODO(terry): must match base |
59 | 59 |
60 /** [TokenKind] representing double tokens. */ | 60 /** [TokenKind] representing double tokens. */ |
61 static final int DOUBLE = 62; // TODO(terry): must match base | 61 static const int DOUBLE = 62; // TODO(terry): must match base |
62 | 62 |
63 /** [TokenKind] representing whitespace tokens. */ | 63 /** [TokenKind] representing whitespace tokens. */ |
64 static final int WHITESPACE = 63; // TODO(terry): must match base | 64 static const int WHITESPACE = 63; // TODO(terry): must match base |
65 | 65 |
66 /** [TokenKind] representing comment tokens. */ | 66 /** [TokenKind] representing comment tokens. */ |
67 static final int COMMENT = 64; // TODO(terry): must match base | 67 static const int COMMENT = 64; // TODO(terry): must match base |
68 | 68 |
69 /** [TokenKind] representing error tokens. */ | 69 /** [TokenKind] representing error tokens. */ |
70 static final int ERROR = 65; // TODO(terry): must match base | 70 static const int ERROR = 65; // TODO(terry): must match base |
71 | 71 |
72 /** [TokenKind] representing incomplete string tokens. */ | 72 /** [TokenKind] representing incomplete string tokens. */ |
73 static final int INCOMPLETE_STRING = 66; // TODO(terry): must match base | 73 static const int INCOMPLETE_STRING = 66; // TODO(terry): must match base |
74 | 74 |
75 /** [TokenKind] representing incomplete comment tokens. */ | 75 /** [TokenKind] representing incomplete comment tokens. */ |
76 static final int INCOMPLETE_COMMENT = 67; // TODO(terry): must match base | 76 static const int INCOMPLETE_COMMENT = 67; // TODO(terry): must match base |
77 | 77 |
78 // Synthesized Tokens (no character associated with TOKEN). | 78 // Synthesized Tokens (no character associated with TOKEN). |
79 // TODO(terry): Possible common names used by both Dart and CSS tokenizers. | 79 // TODO(terry): Possible common names used by both Dart and CSS tokenizers. |
80 static final int ATTR_VALUE = 500; | 80 static const int ATTR_VALUE = 500; |
81 static final int NUMBER = 502; | 81 static const int NUMBER = 502; |
82 static final int HEX_NUMBER = 503; | 82 static const int HEX_NUMBER = 503; |
83 static final int HTML_COMMENT = 504; // <!-- | 83 static const int HTML_COMMENT = 504; // <!-- |
84 static final int IDENTIFIER = 511; | 84 static const int IDENTIFIER = 511; |
85 static final int STRING = 512; | 85 static const int STRING = 512; |
86 static final int STRING_PART = 513; | 86 static const int STRING_PART = 513; |
87 | 87 |
88 static final int TEMPLATE_KEYWORD = 595; // template keyword | 88 static const int TEMPLATE_KEYWORD = 595; // template keyword |
89 | 89 |
90 // Elements | 90 // Elements |
91 /* START_HTML_ELEMENT is first valid element tag name | 91 /* START_HTML_ELEMENT is first valid element tag name |
92 * END_HTML_ELEMENT is the last valid element tag name | 92 * END_HTML_ELEMENT is the last valid element tag name |
93 * | 93 * |
94 */ | 94 */ |
95 static final int START_HTML_ELEMENT = 600; // First valid tag name. | 95 static const int START_HTML_ELEMENT = 600; // First valid tag name. |
96 static final int A_ELEMENT = 600; | 96 static const int A_ELEMENT = 600; |
97 static final int ABBR_ELEMENT = 601; | 97 static const int ABBR_ELEMENT = 601; |
98 static final int ACRONYM_ELEMENT = 602; | 98 static const int ACRONYM_ELEMENT = 602; |
99 static final int ADDRESS_ELEMENT = 603; | 99 static const int ADDRESS_ELEMENT = 603; |
100 static final int APPLET_ELEMENT = 604; | 100 static const int APPLET_ELEMENT = 604; |
101 static final int AREA_ELEMENT = 605; | 101 static const int AREA_ELEMENT = 605; |
102 static final int B_ELEMENT = 606; | 102 static const int B_ELEMENT = 606; |
103 static final int BASE_ELEMENT = 607; | 103 static const int BASE_ELEMENT = 607; |
104 static final int BASEFONT_ELEMENT = 608; | 104 static const int BASEFONT_ELEMENT = 608; |
105 static final int BDO_ELEMENT = 609; | 105 static const int BDO_ELEMENT = 609; |
106 static final int BIG_ELEMENT = 610; | 106 static const int BIG_ELEMENT = 610; |
107 static final int BLOCKQUOTE_ELEMENT = 611; | 107 static const int BLOCKQUOTE_ELEMENT = 611; |
108 static final int BODY_ELEMENT = 612; | 108 static const int BODY_ELEMENT = 612; |
109 static final int BR_ELEMENT = 613; | 109 static const int BR_ELEMENT = 613; |
110 static final int BUTTON_ELEMENT = 614; | 110 static const int BUTTON_ELEMENT = 614; |
111 static final int CAPTION_ELEMENT = 615; | 111 static const int CAPTION_ELEMENT = 615; |
112 static final int CENTER_ELEMENT = 616; | 112 static const int CENTER_ELEMENT = 616; |
113 static final int CITE_ELEMENT = 617; | 113 static const int CITE_ELEMENT = 617; |
114 static final int CODE_ELEMENT = 618; | 114 static const int CODE_ELEMENT = 618; |
115 static final int COL_ELEMENT = 619; | 115 static const int COL_ELEMENT = 619; |
116 static final int COLGROUP_ELEMENT = 620; | 116 static const int COLGROUP_ELEMENT = 620; |
117 static final int DD_ELEMENT = 621; | 117 static const int DD_ELEMENT = 621; |
118 static final int DEL_ELEMENT = 622; | 118 static const int DEL_ELEMENT = 622; |
119 static final int DFN_ELEMENT = 623; | 119 static const int DFN_ELEMENT = 623; |
120 static final int DIR_ELEMENT = 624; | 120 static const int DIR_ELEMENT = 624; |
121 static final int DIV_ELEMENT = 625; | 121 static const int DIV_ELEMENT = 625; |
122 static final int DL_ELEMENT = 626; | 122 static const int DL_ELEMENT = 626; |
123 static final int DT_ELEMENT = 627; | 123 static const int DT_ELEMENT = 627; |
124 static final int EM_ELEMENT = 628; | 124 static const int EM_ELEMENT = 628; |
125 static final int FIELDSET_ELEMENT = 629; | 125 static const int FIELDSET_ELEMENT = 629; |
126 static final int FONT_ELEMENT = 630; | 126 static const int FONT_ELEMENT = 630; |
127 static final int FORM_ELEMENT = 631; | 127 static const int FORM_ELEMENT = 631; |
128 static final int FRAME_ELEMENT = 632; | 128 static const int FRAME_ELEMENT = 632; |
129 static final int FRAMESET_ELEMENT = 633; | 129 static const int FRAMESET_ELEMENT = 633; |
130 static final int H1_ELEMENT = 634; | 130 static const int H1_ELEMENT = 634; |
131 static final int H2_ELEMENT = 635; | 131 static const int H2_ELEMENT = 635; |
132 static final int H3_ELEMENT = 636; | 132 static const int H3_ELEMENT = 636; |
133 static final int H4_ELEMENT = 637; | 133 static const int H4_ELEMENT = 637; |
134 static final int H5_ELEMENT = 638; | 134 static const int H5_ELEMENT = 638; |
135 static final int H6_ELEMENT = 639; | 135 static const int H6_ELEMENT = 639; |
136 static final int HEAD_ELEMENT = 640; | 136 static const int HEAD_ELEMENT = 640; |
137 static final int HR_ELEMENT = 641; | 137 static const int HR_ELEMENT = 641; |
138 static final int HTML_ELEMENT = 642; | 138 static const int HTML_ELEMENT = 642; |
139 static final int I_ELEMENT = 643; | 139 static const int I_ELEMENT = 643; |
140 static final int IFRAME_ELEMENT = 644; | 140 static const int IFRAME_ELEMENT = 644; |
141 static final int IMG_ELEMENT = 645; | 141 static const int IMG_ELEMENT = 645; |
142 static final int INPUT_ELEMENT = 646; | 142 static const int INPUT_ELEMENT = 646; |
143 static final int INS_ELEMENT = 647; | 143 static const int INS_ELEMENT = 647; |
144 static final int ISINDEX_ELEMENT = 648; | 144 static const int ISINDEX_ELEMENT = 648; |
145 static final int KBD_ELEMENT = 649; | 145 static const int KBD_ELEMENT = 649; |
146 static final int LABEL_ELEMENT = 650; | 146 static const int LABEL_ELEMENT = 650; |
147 static final int LEGEND_ELEMENT = 651; | 147 static const int LEGEND_ELEMENT = 651; |
148 static final int LI_ELEMENT = 652; | 148 static const int LI_ELEMENT = 652; |
149 static final int LINK_ELEMENT = 653; | 149 static const int LINK_ELEMENT = 653; |
150 static final int MAP_ELEMENT = 654; | 150 static const int MAP_ELEMENT = 654; |
151 static final int MENU_ELEMENT = 645; | 151 static const int MENU_ELEMENT = 645; |
152 static final int META_ELEMENT = 656; | 152 static const int META_ELEMENT = 656; |
153 static final int NOFRAMES_ELEMENT = 657; | 153 static const int NOFRAMES_ELEMENT = 657; |
154 static final int NOSCRIPT_ELEMENT = 658; | 154 static const int NOSCRIPT_ELEMENT = 658; |
155 static final int OBJECT_ELEMENT = 659; | 155 static const int OBJECT_ELEMENT = 659; |
156 static final int OL_ELEMENT = 660; | 156 static const int OL_ELEMENT = 660; |
157 static final int OPTGROUP_ELEMENT = 661; | 157 static const int OPTGROUP_ELEMENT = 661; |
158 static final int OPTION_ELEMENT = 662; | 158 static const int OPTION_ELEMENT = 662; |
159 static final int P_ELEMENT = 663; | 159 static const int P_ELEMENT = 663; |
160 static final int PARAM_ELEMENT = 664; | 160 static const int PARAM_ELEMENT = 664; |
161 static final int PRE_ELEMENT = 665; | 161 static const int PRE_ELEMENT = 665; |
162 static final int Q_ELEMENT = 666; | 162 static const int Q_ELEMENT = 666; |
163 static final int S_ELEMENT = 667; | 163 static const int S_ELEMENT = 667; |
164 static final int SAMP_ELEMENT = 668; | 164 static const int SAMP_ELEMENT = 668; |
165 static final int SCRIPT_ELEMENT = 669; | 165 static const int SCRIPT_ELEMENT = 669; |
166 static final int SELECT_ELEMENT = 670; | 166 static const int SELECT_ELEMENT = 670; |
167 static final int SMALL_ELEMENT = 671; | 167 static const int SMALL_ELEMENT = 671; |
168 static final int SPAN_ELEMENT = 672; | 168 static const int SPAN_ELEMENT = 672; |
169 static final int STRIKE_ELEMENT = 673; | 169 static const int STRIKE_ELEMENT = 673; |
170 static final int STRONG_ELEMENT = 674; | 170 static const int STRONG_ELEMENT = 674; |
171 static final int STYLE_ELEMENT = 675; | 171 static const int STYLE_ELEMENT = 675; |
172 static final int SUB_ELEMENT = 676; | 172 static const int SUB_ELEMENT = 676; |
173 static final int SUP_ELEMENT = 677; | 173 static const int SUP_ELEMENT = 677; |
174 static final int TABLE_ELEMENT = 678; | 174 static const int TABLE_ELEMENT = 678; |
175 static final int TBODY_ELEMENT = 679; | 175 static const int TBODY_ELEMENT = 679; |
176 static final int TD_ELEMENT = 680; | 176 static const int TD_ELEMENT = 680; |
177 static final int TEXTAREA_ELEMENT = 681; | 177 static const int TEXTAREA_ELEMENT = 681; |
178 static final int TFOOT_ELEMENT = 682; | 178 static const int TFOOT_ELEMENT = 682; |
179 static final int TH_ELEMENT = 683; | 179 static const int TH_ELEMENT = 683; |
180 static final int THEAD_ELEMENT = 684; | 180 static const int THEAD_ELEMENT = 684; |
181 static final int TITLE_ELEMENT = 685; | 181 static const int TITLE_ELEMENT = 685; |
182 static final int TR_ELEMENT = 686; | 182 static const int TR_ELEMENT = 686; |
183 static final int TT_ELEMENT = 687; | 183 static const int TT_ELEMENT = 687; |
184 static final int U_ELEMENT = 688; | 184 static const int U_ELEMENT = 688; |
185 static final int UL_ELEMENT = 689; | 185 static const int UL_ELEMENT = 689; |
186 static final int VAR_ELEMENT = 690; | 186 static const int VAR_ELEMENT = 690; |
187 static final int END_HTML_ELEMENT = VAR_ELEMENT; // Last valid tag name. | 187 static const int END_HTML_ELEMENT = VAR_ELEMENT; // Last valid tag name. |
188 | 188 |
189 static bool validTagName(int tokId) { | 189 static bool validTagName(int tokId) { |
190 return tokId >= TokenKind.START_HTML_ELEMENT && | 190 return tokId >= TokenKind.START_HTML_ELEMENT && |
191 tokId <= TokenKind.END_HTML_ELEMENT; | 191 tokId <= TokenKind.END_HTML_ELEMENT; |
192 } | 192 } |
193 | 193 |
194 static final List<Map<int, String>> _KEYWORDS = const [ | 194 static const List<Map<int, String>> _KEYWORDS = const [ |
195 const {'type': TokenKind.TEMPLATE_KEYWORD, 'value' : 'template'}, | 195 const {'type': TokenKind.TEMPLATE_KEYWORD, 'value' : 'template'}, |
196 ]; | 196 ]; |
197 | 197 |
198 static final List<int> _NON_SCOPED_ELEMENTS = const [ | 198 static const List<int> _NON_SCOPED_ELEMENTS = const [ |
199 BR_ELEMENT, | 199 BR_ELEMENT, |
200 ]; | 200 ]; |
201 | 201 |
202 // tag values starting with a minus sign implies tag can be unscoped e.g., | 202 // tag values starting with a minus sign implies tag can be unscoped e.g., |
203 // <br> is valid without <br></br> or <br/> | 203 // <br> is valid without <br></br> or <br/> |
204 static final List<Map<int, String>> _ELEMENTS = const [ | 204 static const List<Map<int, String>> _ELEMENTS = const [ |
205 const {'type': TokenKind.A_ELEMENT, 'value' : 'a'}, | 205 const {'type': TokenKind.A_ELEMENT, 'value' : 'a'}, |
206 const {'type': TokenKind.ABBR_ELEMENT, 'value' : 'abbr'}, | 206 const {'type': TokenKind.ABBR_ELEMENT, 'value' : 'abbr'}, |
207 const {'type': TokenKind.ACRONYM_ELEMENT, 'value' : 'acronym'}, | 207 const {'type': TokenKind.ACRONYM_ELEMENT, 'value' : 'acronym'}, |
208 const {'type': TokenKind.ADDRESS_ELEMENT, 'value' : 'address'}, | 208 const {'type': TokenKind.ADDRESS_ELEMENT, 'value' : 'address'}, |
209 const {'type': TokenKind.APPLET_ELEMENT, 'value' : 'applet'}, | 209 const {'type': TokenKind.APPLET_ELEMENT, 'value' : 'applet'}, |
210 const {'type': TokenKind.AREA_ELEMENT, 'value' : 'area'}, | 210 const {'type': TokenKind.AREA_ELEMENT, 'value' : 'area'}, |
211 const {'type': TokenKind.B_ELEMENT, 'value' : 'b'}, | 211 const {'type': TokenKind.B_ELEMENT, 'value' : 'b'}, |
212 const {'type': TokenKind.BASE_ELEMENT, 'value' : 'base'}, | 212 const {'type': TokenKind.BASE_ELEMENT, 'value' : 'base'}, |
213 const {'type': TokenKind.BASEFONT_ELEMENT, 'value' : 'basefont'}, | 213 const {'type': TokenKind.BASEFONT_ELEMENT, 'value' : 'basefont'}, |
214 const {'type': TokenKind.BDO_ELEMENT, 'value' : 'bdo'}, | 214 const {'type': TokenKind.BDO_ELEMENT, 'value' : 'bdo'}, |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
289 const {'type': TokenKind.THEAD_ELEMENT, 'value' : 'thead'}, | 289 const {'type': TokenKind.THEAD_ELEMENT, 'value' : 'thead'}, |
290 const {'type': TokenKind.TITLE_ELEMENT, 'value' : 'title'}, | 290 const {'type': TokenKind.TITLE_ELEMENT, 'value' : 'title'}, |
291 const {'type': TokenKind.TR_ELEMENT, 'value' : 'tr'}, | 291 const {'type': TokenKind.TR_ELEMENT, 'value' : 'tr'}, |
292 const {'type': TokenKind.TT_ELEMENT, 'value' : 'tt'}, | 292 const {'type': TokenKind.TT_ELEMENT, 'value' : 'tt'}, |
293 const {'type': TokenKind.U_ELEMENT, 'value' : 'u'}, | 293 const {'type': TokenKind.U_ELEMENT, 'value' : 'u'}, |
294 const {'type': TokenKind.UL_ELEMENT, 'value' : 'ul'}, | 294 const {'type': TokenKind.UL_ELEMENT, 'value' : 'ul'}, |
295 const {'type': TokenKind.VAR_ELEMENT, 'value' : 'var'}, | 295 const {'type': TokenKind.VAR_ELEMENT, 'value' : 'var'}, |
296 ]; | 296 ]; |
297 | 297 |
298 // Some more constants: | 298 // Some more constants: |
299 static final int ASCII_UPPER_A = 65; // ASCII value for uppercase A | 299 static const int ASCII_UPPER_A = 65; // ASCII value for uppercase A |
300 static final int ASCII_UPPER_Z = 90; // ASCII value for uppercase Z | 300 static const int ASCII_UPPER_Z = 90; // ASCII value for uppercase Z |
301 | 301 |
302 List<int> tokens; | 302 List<int> tokens; |
303 | 303 |
304 /* | 304 /* |
305 * Return the token that matches the unit ident found. | 305 * Return the token that matches the unit ident found. |
306 */ | 306 */ |
307 static int matchList(var identList, String tokenField, String text, | 307 static int matchList(var identList, String tokenField, String text, |
308 int offset, int length) { | 308 int offset, int length) { |
309 for (final entry in identList) { | 309 for (final entry in identList) { |
310 String ident = entry['value']; | 310 String ident = entry['value']; |
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
456 return kind == IDENTIFIER; | 456 return kind == IDENTIFIER; |
457 } | 457 } |
458 } | 458 } |
459 | 459 |
460 class NoElementMatchException implements Exception { | 460 class NoElementMatchException implements Exception { |
461 String _tagName; | 461 String _tagName; |
462 NoElementMatchException(this._tagName); | 462 NoElementMatchException(this._tagName); |
463 | 463 |
464 String get name() => _tagName; | 464 String get name() => _tagName; |
465 } | 465 } |
OLD | NEW |