| 'use strict'; | 
| var uncurryThis = require('../internals/function-uncurry-this'); | 
| var hasOwn = require('../internals/has-own-property'); | 
|   | 
| var $SyntaxError = SyntaxError; | 
| var $parseInt = parseInt; | 
| var fromCharCode = String.fromCharCode; | 
| var at = uncurryThis(''.charAt); | 
| var slice = uncurryThis(''.slice); | 
| var exec = uncurryThis(/./.exec); | 
|   | 
| var codePoints = { | 
|   '\\"': '"', | 
|   '\\\\': '\\', | 
|   '\\/': '/', | 
|   '\\b': '\b', | 
|   '\\f': '\f', | 
|   '\\n': '\n', | 
|   '\\r': '\r', | 
|   '\\t': '\t' | 
| }; | 
|   | 
| var IS_4_HEX_DIGITS = /^[\da-f]{4}$/i; | 
| // eslint-disable-next-line regexp/no-control-character -- safe | 
| var IS_C0_CONTROL_CODE = /^[\u0000-\u001F]$/; | 
|   | 
| module.exports = function (source, i) { | 
|   var unterminated = true; | 
|   var value = ''; | 
|   while (i < source.length) { | 
|     var chr = at(source, i); | 
|     if (chr === '\\') { | 
|       var twoChars = slice(source, i, i + 2); | 
|       if (hasOwn(codePoints, twoChars)) { | 
|         value += codePoints[twoChars]; | 
|         i += 2; | 
|       } else if (twoChars === '\\u') { | 
|         i += 2; | 
|         var fourHexDigits = slice(source, i, i + 4); | 
|         if (!exec(IS_4_HEX_DIGITS, fourHexDigits)) throw new $SyntaxError('Bad Unicode escape at: ' + i); | 
|         value += fromCharCode($parseInt(fourHexDigits, 16)); | 
|         i += 4; | 
|       } else throw new $SyntaxError('Unknown escape sequence: "' + twoChars + '"'); | 
|     } else if (chr === '"') { | 
|       unterminated = false; | 
|       i++; | 
|       break; | 
|     } else { | 
|       if (exec(IS_C0_CONTROL_CODE, chr)) throw new $SyntaxError('Bad control character in string literal at: ' + i); | 
|       value += chr; | 
|       i++; | 
|     } | 
|   } | 
|   if (unterminated) throw new $SyntaxError('Unterminated string at: ' + i); | 
|   return { value: value, end: i }; | 
| }; |