| var createCustomError = require('../utils/createCustomError'); | 
| var MAX_LINE_LENGTH = 100; | 
| var OFFSET_CORRECTION = 60; | 
| var TAB_REPLACEMENT = '    '; | 
|   | 
| function sourceFragment(error, extraLines) { | 
|     function processLines(start, end) { | 
|         return lines.slice(start, end).map(function(line, idx) { | 
|             var num = String(start + idx + 1); | 
|   | 
|             while (num.length < maxNumLength) { | 
|                 num = ' ' + num; | 
|             } | 
|   | 
|             return num + ' |' + line; | 
|         }).join('\n'); | 
|     } | 
|   | 
|     var lines = error.source.split(/\r\n?|\n|\f/); | 
|     var line = error.line; | 
|     var column = error.column; | 
|     var startLine = Math.max(1, line - extraLines) - 1; | 
|     var endLine = Math.min(line + extraLines, lines.length + 1); | 
|     var maxNumLength = Math.max(4, String(endLine).length) + 1; | 
|     var cutLeft = 0; | 
|   | 
|     // column correction according to replaced tab before column | 
|     column += (TAB_REPLACEMENT.length - 1) * (lines[line - 1].substr(0, column - 1).match(/\t/g) || []).length; | 
|   | 
|     if (column > MAX_LINE_LENGTH) { | 
|         cutLeft = column - OFFSET_CORRECTION + 3; | 
|         column = OFFSET_CORRECTION - 2; | 
|     } | 
|   | 
|     for (var i = startLine; i <= endLine; i++) { | 
|         if (i >= 0 && i < lines.length) { | 
|             lines[i] = lines[i].replace(/\t/g, TAB_REPLACEMENT); | 
|             lines[i] = | 
|                 (cutLeft > 0 && lines[i].length > cutLeft ? '\u2026' : '') + | 
|                 lines[i].substr(cutLeft, MAX_LINE_LENGTH - 2) + | 
|                 (lines[i].length > cutLeft + MAX_LINE_LENGTH - 1 ? '\u2026' : ''); | 
|         } | 
|     } | 
|   | 
|     return [ | 
|         processLines(startLine, line), | 
|         new Array(column + maxNumLength + 2).join('-') + '^', | 
|         processLines(line, endLine) | 
|     ].filter(Boolean).join('\n'); | 
| } | 
|   | 
| var SyntaxError = function(message, source, offset, line, column) { | 
|     var error = createCustomError('SyntaxError', message); | 
|   | 
|     error.source = source; | 
|     error.offset = offset; | 
|     error.line = line; | 
|     error.column = column; | 
|   | 
|     error.sourceFragment = function(extraLines) { | 
|         return sourceFragment(error, isNaN(extraLines) ? 0 : extraLines); | 
|     }; | 
|     Object.defineProperty(error, 'formattedMessage', { | 
|         get: function() { | 
|             return ( | 
|                 'Parse error: ' + error.message + '\n' + | 
|                 sourceFragment(error, 2) | 
|             ); | 
|         } | 
|     }); | 
|   | 
|     // for backward capability | 
|     error.parseError = { | 
|         offset: offset, | 
|         line: line, | 
|         column: column | 
|     }; | 
|   | 
|     return error; | 
| }; | 
|   | 
| module.exports = SyntaxError; |