| OLD | NEW |
| 1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 17 matching lines...) Expand all Loading... |
| 28 // This file contains support for URI manipulations written in | 28 // This file contains support for URI manipulations written in |
| 29 // JavaScript. | 29 // JavaScript. |
| 30 | 30 |
| 31 // Expect $String = global.String; | 31 // Expect $String = global.String; |
| 32 | 32 |
| 33 function URIAddEncodedOctetToBuffer(octet, result, index) { | 33 function URIAddEncodedOctetToBuffer(octet, result, index) { |
| 34 result[index++] = 37; // Char code of '%'. | 34 result[index++] = 37; // Char code of '%'. |
| 35 result[index++] = hexCharCodeArray[octet >> 4]; | 35 result[index++] = hexCharCodeArray[octet >> 4]; |
| 36 result[index++] = hexCharCodeArray[octet & 0x0F]; | 36 result[index++] = hexCharCodeArray[octet & 0x0F]; |
| 37 return index; | 37 return index; |
| 38 }; | 38 } |
| 39 | 39 |
| 40 | 40 |
| 41 function URIEncodeOctets(octets, result, index) { | 41 function URIEncodeOctets(octets, result, index) { |
| 42 index = URIAddEncodedOctetToBuffer(octets[0], result, index); | 42 index = URIAddEncodedOctetToBuffer(octets[0], result, index); |
| 43 if (octets[1]) index = URIAddEncodedOctetToBuffer(octets[1], result, index); | 43 if (octets[1]) index = URIAddEncodedOctetToBuffer(octets[1], result, index); |
| 44 if (octets[2]) index = URIAddEncodedOctetToBuffer(octets[2], result, index); | 44 if (octets[2]) index = URIAddEncodedOctetToBuffer(octets[2], result, index); |
| 45 if (octets[3]) index = URIAddEncodedOctetToBuffer(octets[3], result, index); | 45 if (octets[3]) index = URIAddEncodedOctetToBuffer(octets[3], result, index); |
| 46 return index; | 46 return index; |
| 47 }; | 47 } |
| 48 | 48 |
| 49 | 49 |
| 50 function URIEncodeSingle(cc, result, index) { | 50 function URIEncodeSingle(cc, result, index) { |
| 51 var x = (cc >> 12) & 0xF; | 51 var x = (cc >> 12) & 0xF; |
| 52 var y = (cc >> 6) & 63; | 52 var y = (cc >> 6) & 63; |
| 53 var z = cc & 63; | 53 var z = cc & 63; |
| 54 var octets = new $Array(3); | 54 var octets = new $Array(3); |
| 55 if (cc <= 0x007F) { | 55 if (cc <= 0x007F) { |
| 56 octets[0] = cc; | 56 octets[0] = cc; |
| 57 } else if (cc <= 0x07FF) { | 57 } else if (cc <= 0x07FF) { |
| 58 octets[0] = y + 192; | 58 octets[0] = y + 192; |
| 59 octets[1] = z + 128; | 59 octets[1] = z + 128; |
| 60 } else { | 60 } else { |
| 61 octets[0] = x + 224; | 61 octets[0] = x + 224; |
| 62 octets[1] = y + 128; | 62 octets[1] = y + 128; |
| 63 octets[2] = z + 128; | 63 octets[2] = z + 128; |
| 64 } | 64 } |
| 65 return URIEncodeOctets(octets, result, index); | 65 return URIEncodeOctets(octets, result, index); |
| 66 }; | 66 } |
| 67 | 67 |
| 68 | 68 |
| 69 function URIEncodePair(cc1 , cc2, result, index) { | 69 function URIEncodePair(cc1 , cc2, result, index) { |
| 70 var u = ((cc1 >> 6) & 0xF) + 1; | 70 var u = ((cc1 >> 6) & 0xF) + 1; |
| 71 var w = (cc1 >> 2) & 0xF; | 71 var w = (cc1 >> 2) & 0xF; |
| 72 var x = cc1 & 3; | 72 var x = cc1 & 3; |
| 73 var y = (cc2 >> 6) & 0xF; | 73 var y = (cc2 >> 6) & 0xF; |
| 74 var z = cc2 & 63; | 74 var z = cc2 & 63; |
| 75 var octets = new $Array(4); | 75 var octets = new $Array(4); |
| 76 octets[0] = (u >> 2) + 240; | 76 octets[0] = (u >> 2) + 240; |
| 77 octets[1] = (((u & 3) << 4) | w) + 128; | 77 octets[1] = (((u & 3) << 4) | w) + 128; |
| 78 octets[2] = ((x << 4) | y) + 128; | 78 octets[2] = ((x << 4) | y) + 128; |
| 79 octets[3] = z + 128; | 79 octets[3] = z + 128; |
| 80 return URIEncodeOctets(octets, result, index); | 80 return URIEncodeOctets(octets, result, index); |
| 81 }; | 81 } |
| 82 | 82 |
| 83 | 83 |
| 84 function URIHexCharsToCharCode(ch1, ch2) { | 84 function URIHexCharsToCharCode(ch1, ch2) { |
| 85 if (HexValueOf(ch1) == -1 || HexValueOf(ch2) == -1) { | 85 if (HexValueOf(ch1) == -1 || HexValueOf(ch2) == -1) { |
| 86 throw new $URIError("URI malformed"); | 86 throw new $URIError("URI malformed"); |
| 87 } | 87 } |
| 88 return HexStrToCharCode(ch1 + ch2); | 88 return HexStrToCharCode(ch1 + ch2); |
| 89 }; | 89 } |
| 90 | 90 |
| 91 | 91 |
| 92 function URIDecodeOctets(octets, result, index) { | 92 function URIDecodeOctets(octets, result, index) { |
| 93 if (octets[3]) { | 93 if (octets[3]) { |
| 94 var x = (octets[2] >> 4) & 3; | 94 var x = (octets[2] >> 4) & 3; |
| 95 var y = octets[2] & 0xF; | 95 var y = octets[2] & 0xF; |
| 96 var z = octets[3] & 63; | 96 var z = octets[3] & 63; |
| 97 var v = (((octets[0] & 7) << 2) | ((octets[1] >> 4) & 3)) - 1; | 97 var v = (((octets[0] & 7) << 2) | ((octets[1] >> 4) & 3)) - 1; |
| 98 var w = octets[1] & 0xF; | 98 var w = octets[1] & 0xF; |
| 99 result[index++] = 55296 | (v << 6) | (w << 2) | x; | 99 result[index++] = 55296 | (v << 6) | (w << 2) | x; |
| 100 result[index++] = 56320 | (y << 6) | z; | 100 result[index++] = 56320 | (y << 6) | z; |
| 101 return index; | 101 return index; |
| 102 } | 102 } |
| 103 if (octets[2]) { | 103 if (octets[2]) { |
| 104 var x = octets[0] & 0xF; | 104 var x = octets[0] & 0xF; |
| 105 var y = octets[1] & 63; | 105 var y = octets[1] & 63; |
| 106 var z = octets[2] & 63; | 106 var z = octets[2] & 63; |
| 107 result[index++] = (x << 12) | (y << 6) | z; | 107 result[index++] = (x << 12) | (y << 6) | z; |
| 108 return index; | 108 return index; |
| 109 } | 109 } |
| 110 var z = octets[1] & 63; | 110 var z = octets[1] & 63; |
| 111 var y = octets[0] & 31; | 111 var y = octets[0] & 31; |
| 112 result[index++] = (y << 6) | z; | 112 result[index++] = (y << 6) | z; |
| 113 return index; | 113 return index; |
| 114 }; | 114 } |
| 115 | 115 |
| 116 | 116 |
| 117 // ECMA-262, section 15.1.3 | 117 // ECMA-262, section 15.1.3 |
| 118 function Encode(uri, unescape) { | 118 function Encode(uri, unescape) { |
| 119 var uriLength = uri.length; | 119 var uriLength = uri.length; |
| 120 var result = new $Array(uriLength); | 120 var result = new $Array(uriLength); |
| 121 var index = 0; | 121 var index = 0; |
| 122 for (var k = 0; k < uriLength; k++) { | 122 for (var k = 0; k < uriLength; k++) { |
| 123 var cc1 = uri.charCodeAt(k); | 123 var cc1 = uri.charCodeAt(k); |
| 124 if (unescape(cc1)) { | 124 if (unescape(cc1)) { |
| 125 result[index++] = cc1; | 125 result[index++] = cc1; |
| 126 } else { | 126 } else { |
| 127 if (cc1 >= 0xDC00 && cc1 <= 0xDFFF) throw new $URIError("URI malformed"); | 127 if (cc1 >= 0xDC00 && cc1 <= 0xDFFF) throw new $URIError("URI malformed"); |
| 128 if (cc1 < 0xD800 || cc1 > 0xDBFF) { | 128 if (cc1 < 0xD800 || cc1 > 0xDBFF) { |
| 129 index = URIEncodeSingle(cc1, result, index); | 129 index = URIEncodeSingle(cc1, result, index); |
| 130 } else { | 130 } else { |
| 131 k++; | 131 k++; |
| 132 if (k == uriLength) throw new $URIError("URI malformed"); | 132 if (k == uriLength) throw new $URIError("URI malformed"); |
| 133 var cc2 = uri.charCodeAt(k); | 133 var cc2 = uri.charCodeAt(k); |
| 134 if (cc2 < 0xDC00 || cc2 > 0xDFFF) throw new $URIError("URI malformed"); | 134 if (cc2 < 0xDC00 || cc2 > 0xDFFF) throw new $URIError("URI malformed"); |
| 135 index = URIEncodePair(cc1, cc2, result, index); | 135 index = URIEncodePair(cc1, cc2, result, index); |
| 136 } | 136 } |
| 137 } | 137 } |
| 138 } | 138 } |
| 139 return %StringFromCharCodeArray(result); | 139 return %StringFromCharCodeArray(result); |
| 140 }; | 140 } |
| 141 | 141 |
| 142 | 142 |
| 143 // ECMA-262, section 15.1.3 | 143 // ECMA-262, section 15.1.3 |
| 144 function Decode(uri, reserved) { | 144 function Decode(uri, reserved) { |
| 145 var uriLength = uri.length; | 145 var uriLength = uri.length; |
| 146 var result = new $Array(uriLength); | 146 var result = new $Array(uriLength); |
| 147 var index = 0; | 147 var index = 0; |
| 148 for (var k = 0; k < uriLength; k++) { | 148 for (var k = 0; k < uriLength; k++) { |
| 149 var ch = uri.charAt(k); | 149 var ch = uri.charAt(k); |
| 150 if (ch == '%') { | 150 if (ch == '%') { |
| (...skipping 19 matching lines...) Expand all Loading... |
| 170 } else { | 170 } else { |
| 171 result[index++] = cc; | 171 result[index++] = cc; |
| 172 } | 172 } |
| 173 } | 173 } |
| 174 } else { | 174 } else { |
| 175 result[index++] = ch.charCodeAt(0); | 175 result[index++] = ch.charCodeAt(0); |
| 176 } | 176 } |
| 177 } | 177 } |
| 178 result.length = index; | 178 result.length = index; |
| 179 return %StringFromCharCodeArray(result); | 179 return %StringFromCharCodeArray(result); |
| 180 }; | 180 } |
| 181 | 181 |
| 182 | 182 |
| 183 // ECMA-262 - 15.1.3.1. | 183 // ECMA-262 - 15.1.3.1. |
| 184 function URIDecode(uri) { | 184 function URIDecode(uri) { |
| 185 function reservedPredicate(cc) { | 185 function reservedPredicate(cc) { |
| 186 // #$ | 186 // #$ |
| 187 if (35 <= cc && cc <= 36) return true; | 187 if (35 <= cc && cc <= 36) return true; |
| 188 // & | 188 // & |
| 189 if (cc == 38) return true; | 189 if (cc == 38) return true; |
| 190 // +, | 190 // +, |
| 191 if (43 <= cc && cc <= 44) return true; | 191 if (43 <= cc && cc <= 44) return true; |
| 192 // / | 192 // / |
| 193 if (cc == 47) return true; | 193 if (cc == 47) return true; |
| 194 // :; | 194 // :; |
| 195 if (58 <= cc && cc <= 59) return true; | 195 if (58 <= cc && cc <= 59) return true; |
| 196 // = | 196 // = |
| 197 if (cc == 61) return true; | 197 if (cc == 61) return true; |
| 198 // ?@ | 198 // ?@ |
| 199 if (63 <= cc && cc <= 64) return true; | 199 if (63 <= cc && cc <= 64) return true; |
| 200 | 200 |
| 201 return false; | 201 return false; |
| 202 }; | 202 }; |
| 203 var string = ToString(uri); | 203 var string = ToString(uri); |
| 204 return Decode(string, reservedPredicate); | 204 return Decode(string, reservedPredicate); |
| 205 }; | 205 } |
| 206 | 206 |
| 207 | 207 |
| 208 // ECMA-262 - 15.1.3.2. | 208 // ECMA-262 - 15.1.3.2. |
| 209 function URIDecodeComponent(component) { | 209 function URIDecodeComponent(component) { |
| 210 function reservedPredicate(cc) { return false; }; | 210 function reservedPredicate(cc) { return false; }; |
| 211 var string = ToString(component); | 211 var string = ToString(component); |
| 212 return Decode(string, reservedPredicate); | 212 return Decode(string, reservedPredicate); |
| 213 }; | 213 } |
| 214 | 214 |
| 215 | 215 |
| 216 // Does the char code correspond to an alpha-numeric char. | 216 // Does the char code correspond to an alpha-numeric char. |
| 217 function isAlphaNumeric(cc) { | 217 function isAlphaNumeric(cc) { |
| 218 // a - z | 218 // a - z |
| 219 if (97 <= cc && cc <= 122) return true; | 219 if (97 <= cc && cc <= 122) return true; |
| 220 // A - Z | 220 // A - Z |
| 221 if (65 <= cc && cc <= 90) return true; | 221 if (65 <= cc && cc <= 90) return true; |
| 222 // 0 - 9 | 222 // 0 - 9 |
| 223 if (48 <= cc && cc <= 57) return true; | 223 if (48 <= cc && cc <= 57) return true; |
| 224 | 224 |
| 225 return false; | 225 return false; |
| 226 }; | 226 } |
| 227 | 227 |
| 228 | 228 |
| 229 // ECMA-262 - 15.1.3.3. | 229 // ECMA-262 - 15.1.3.3. |
| 230 function URIEncode(uri) { | 230 function URIEncode(uri) { |
| 231 function unescapePredicate(cc) { | 231 function unescapePredicate(cc) { |
| 232 if (isAlphaNumeric(cc)) return true; | 232 if (isAlphaNumeric(cc)) return true; |
| 233 // ! | 233 // ! |
| 234 if (cc == 33) return true; | 234 if (cc == 33) return true; |
| 235 // #$ | 235 // #$ |
| 236 if (35 <= cc && cc <= 36) return true; | 236 if (35 <= cc && cc <= 36) return true; |
| 237 // &'()*+,-./ | 237 // &'()*+,-./ |
| 238 if (38 <= cc && cc <= 47) return true; | 238 if (38 <= cc && cc <= 47) return true; |
| 239 // :; | 239 // :; |
| 240 if (58 <= cc && cc <= 59) return true; | 240 if (58 <= cc && cc <= 59) return true; |
| 241 // = | 241 // = |
| 242 if (cc == 61) return true; | 242 if (cc == 61) return true; |
| 243 // ?@ | 243 // ?@ |
| 244 if (63 <= cc && cc <= 64) return true; | 244 if (63 <= cc && cc <= 64) return true; |
| 245 // _ | 245 // _ |
| 246 if (cc == 95) return true; | 246 if (cc == 95) return true; |
| 247 // ~ | 247 // ~ |
| 248 if (cc == 126) return true; | 248 if (cc == 126) return true; |
| 249 | 249 |
| 250 return false; | 250 return false; |
| 251 }; | 251 }; |
| 252 | 252 |
| 253 var string = ToString(uri); | 253 var string = ToString(uri); |
| 254 return Encode(string, unescapePredicate); | 254 return Encode(string, unescapePredicate); |
| 255 }; | 255 } |
| 256 | 256 |
| 257 | 257 |
| 258 // ECMA-262 - 15.1.3.4 | 258 // ECMA-262 - 15.1.3.4 |
| 259 function URIEncodeComponent(component) { | 259 function URIEncodeComponent(component) { |
| 260 function unescapePredicate(cc) { | 260 function unescapePredicate(cc) { |
| 261 if (isAlphaNumeric(cc)) return true; | 261 if (isAlphaNumeric(cc)) return true; |
| 262 // ! | 262 // ! |
| 263 if (cc == 33) return true; | 263 if (cc == 33) return true; |
| 264 // '()* | 264 // '()* |
| 265 if (39 <= cc && cc <= 42) return true; | 265 if (39 <= cc && cc <= 42) return true; |
| 266 // -. | 266 // -. |
| 267 if (45 <= cc && cc <= 46) return true; | 267 if (45 <= cc && cc <= 46) return true; |
| 268 // _ | 268 // _ |
| 269 if (cc == 95) return true; | 269 if (cc == 95) return true; |
| 270 // ~ | 270 // ~ |
| 271 if (cc == 126) return true; | 271 if (cc == 126) return true; |
| 272 | 272 |
| 273 return false; | 273 return false; |
| 274 }; | 274 }; |
| 275 | 275 |
| 276 var string = ToString(component); | 276 var string = ToString(component); |
| 277 return Encode(string, unescapePredicate); | 277 return Encode(string, unescapePredicate); |
| 278 }; | 278 } |
| 279 | 279 |
| 280 | 280 |
| 281 const hexCharArray = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", | 281 const hexCharArray = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", |
| 282 "A", "B", "C", "D", "E", "F"]; | 282 "A", "B", "C", "D", "E", "F"]; |
| 283 | 283 |
| 284 const hexCharCodeArray = [48, 49, 50, 51, 52, 53, 54, 55, 56, 57, | 284 const hexCharCodeArray = [48, 49, 50, 51, 52, 53, 54, 55, 56, 57, |
| 285 65, 66, 67, 68, 69, 70]; | 285 65, 66, 67, 68, 69, 70]; |
| 286 | 286 |
| 287 | 287 |
| 288 function HexValueOf(c) { | 288 function HexValueOf(c) { |
| 289 var code = c.charCodeAt(0); | 289 var code = c.charCodeAt(0); |
| 290 | 290 |
| 291 // 0-9 | 291 // 0-9 |
| 292 if (code >= 48 && code <= 57) return code - 48; | 292 if (code >= 48 && code <= 57) return code - 48; |
| 293 // A-F | 293 // A-F |
| 294 if (code >= 65 && code <= 70) return code - 55; | 294 if (code >= 65 && code <= 70) return code - 55; |
| 295 // a-f | 295 // a-f |
| 296 if (code >= 97 && code <= 102) return code - 87; | 296 if (code >= 97 && code <= 102) return code - 87; |
| 297 | 297 |
| 298 return -1; | 298 return -1; |
| 299 }; | 299 } |
| 300 | 300 |
| 301 | 301 |
| 302 // Convert a character code to 4-digit hex string representation | 302 // Convert a character code to 4-digit hex string representation |
| 303 // 64 -> 0040, 62234 -> F31A. | 303 // 64 -> 0040, 62234 -> F31A. |
| 304 function CharCodeToHex4Str(cc) { | 304 function CharCodeToHex4Str(cc) { |
| 305 var r = ""; | 305 var r = ""; |
| 306 for (var i = 0; i < 4; ++i) { | 306 for (var i = 0; i < 4; ++i) { |
| 307 var c = hexCharArray[cc & 0x0F]; | 307 var c = hexCharArray[cc & 0x0F]; |
| 308 r = c + r; | 308 r = c + r; |
| 309 cc = cc >>> 4; | 309 cc = cc >>> 4; |
| 310 } | 310 } |
| 311 return r; | 311 return r; |
| 312 }; | 312 } |
| 313 | 313 |
| 314 | 314 |
| 315 // Converts hex string to char code. Not efficient. | 315 // Converts hex string to char code. Not efficient. |
| 316 function HexStrToCharCode(s) { | 316 function HexStrToCharCode(s) { |
| 317 var m = 0; | 317 var m = 0; |
| 318 var r = 0; | 318 var r = 0; |
| 319 for (var i = s.length - 1; i >= 0; --i) { | 319 for (var i = s.length - 1; i >= 0; --i) { |
| 320 r = r + (HexValueOf(s.charAt(i)) << m); | 320 r = r + (HexValueOf(s.charAt(i)) << m); |
| 321 m = m + 4; | 321 m = m + 4; |
| 322 } | 322 } |
| 323 return r; | 323 return r; |
| 324 }; | 324 } |
| 325 | 325 |
| 326 | 326 |
| 327 // Returns true if all digits in string s are valid hex numbers | 327 // Returns true if all digits in string s are valid hex numbers |
| 328 function IsValidHex(s) { | 328 function IsValidHex(s) { |
| 329 for (var i = 0; i < s.length; ++i) { | 329 for (var i = 0; i < s.length; ++i) { |
| 330 var cc = s.charCodeAt(i); | 330 var cc = s.charCodeAt(i); |
| 331 if ((48 <= cc && cc <= 57) || (65 <= cc && cc <= 70) || (97 <= cc && cc <= 1
02)) { | 331 if ((48 <= cc && cc <= 57) || (65 <= cc && cc <= 70) || (97 <= cc && cc <= 1
02)) { |
| 332 // '0'..'9', 'A'..'F' and 'a' .. 'f'. | 332 // '0'..'9', 'A'..'F' and 'a' .. 'f'. |
| 333 } else { | 333 } else { |
| 334 return false; | 334 return false; |
| 335 } | 335 } |
| 336 } | 336 } |
| 337 return true; | 337 return true; |
| 338 }; | 338 } |
| 339 | 339 |
| 340 | 340 |
| 341 // ECMA-262 - B.2.1. | 341 // ECMA-262 - B.2.1. |
| 342 function URIEscape(str) { | 342 function URIEscape(str) { |
| 343 var s = ToString(str); | 343 var s = ToString(str); |
| 344 return %URIEscape(s); | 344 return %URIEscape(s); |
| 345 }; | 345 } |
| 346 | 346 |
| 347 | 347 |
| 348 // ECMA-262 - B.2.2. | 348 // ECMA-262 - B.2.2. |
| 349 function URIUnescape(str) { | 349 function URIUnescape(str) { |
| 350 var s = ToString(str); | 350 var s = ToString(str); |
| 351 return %URIUnescape(s); | 351 return %URIUnescape(s); |
| 352 } | 352 } |
| 353 | 353 |
| 354 | 354 |
| 355 // ------------------------------------------------------------------- | 355 // ------------------------------------------------------------------- |
| 356 | 356 |
| 357 function SetupURI() { | 357 function SetupURI() { |
| 358 // Setup non-enumerable URI properties of the global object. | 358 // Setup non-enumerable URI functions on the global object and set |
| 359 InstallProperties(global, DONT_ENUM, { | 359 // their names. |
| 360 escape: URIEscape, | 360 InstallFunctions(global, DONT_ENUM, $Array( |
| 361 unescape: URIUnescape, | 361 "escape", URIEscape, |
| 362 decodeURI: URIDecode, | 362 "unescape", URIUnescape, |
| 363 decodeURIComponent: URIDecodeComponent, | 363 "decodeURI", URIDecode, |
| 364 encodeURI: URIEncode, | 364 "decodeURIComponent", URIDecodeComponent, |
| 365 encodeURIComponent: URIEncodeComponent | 365 "encodeURI", URIEncode, |
| 366 }); | 366 "encodeURIComponent", URIEncodeComponent |
| 367 }; | 367 )); |
| 368 } |
| 368 | 369 |
| 369 SetupURI(); | 370 SetupURI(); |
| 370 | 371 |
| OLD | NEW |