/**
 * Throw an error with start/end pos like the Svelte compiler does
 */ export function throwError ( start , end , message , code ) { const error = new Error ( message ) ; ( error as any ) . start = positionAt ( start , code ) ; ( error as any ) . end = positionAt ( end , code ) ; throw error ; } param offset param text function positionAt ( offset , text ) { offset = clamp ( offset , 0 , text . length ) ; const lineOffsets = getLineOffsets ( text ) ; let low = 0 ; let high = lineOffsets . length ; if ( high === 0 ) { return { line : 1 , column : offset } ; } while ( low < high ) { const mid = Math . floor ( ( low + high ) / 2 ) ; if ( lineOffsets [ mid ] > offset ) { high = mid ; } else { low = mid + 1 ; } } return { line : low , column : offset - lineOffsets [ low - 1 ] } ; } export function clamp ( num , min , max ) { return Math . max ( min , Math . min ( max , num ) ) ; } function getLineOffsets ( text ) { const lineOffsets = [ ] ; let isLineStart = true ; for ( let i = 0 ; i < text . length ; i ++ ) { if ( isLineStart ) { lineOffsets . push ( i ) ; isLineStart = false ; } const ch = text . charAt ( i ) ; isLineStart = ch === '\r' || ch === '\n' ; if ( ch === '\r' && i + 1 < text . length && text . charAt ( i + 1 ) === '\n' ) { i ++ ; } } if ( isLineStart && text . length > 0 ) { lineOffsets . push ( text . length ) ; } return lineOffsets ; }