import invariant from 'invariant' ; import stripDiacritics from './stripDiacritics' ; const CASE_INSENSITIVE = 'i' ; const COMBINING_MARKS = /[\u0300-\u036F]/ ; interface MatchBounds { end : number ; start : number ; } export function escapeStringRegexp ( str ) { invariant ( typeof str === 'string' , '`escapeStringRegexp` expected a string.' ) ; return str . replace ( /[|\\{}()[\]^$+*?.]/g , '\\$&' ) . replace ( /-/g , '\\x2d' ) ; } export default function getMatchBounds ( subject , str ) { const search = new RegExp ( escapeStringRegexp ( stripDiacritics ( str ) ) , CASE_INSENSITIVE ) ; const matches = search . exec ( stripDiacritics ( subject ) ) ; if ( ! matches ) { return null ; } let start = matches . index ; let matchLength = matches [ 0 ] . length ; if ( COMBINING_MARKS . test ( subject ) ) { for ( let ii = 0 ; ii <= start ; ii ++ ) { if ( COMBINING_MARKS . test ( subject [ ii ] ) ) { start += 1 ; } } for ( let ii = start ; ii <= start + matchLength ; ii ++ ) { if ( COMBINING_MARKS . test ( subject [ ii ] ) ) { matchLength += 1 ; } } } return { end : start + matchLength , start , } ; }