export function mergeSort < T > ( source , compare ) { let s = 1 , n = source . length ; let buff = new Array ( n ) ; while ( s < n ) { mergeAll ( source , buff , s , n , compare ) ; s += s ; mergeAll ( buff , source , s , n , compare ) ; s += s ; } } function merge < T > ( source , target , l , m , r , compare ) { let i = l , j = m + 1 , k = l ; while ( ( i <= m ) && ( j <= r ) ) if ( compare ( source [ i ] , source [ j ] ) ) target [ k ++ ] = source [ i ++ ] ; else target [ k ++ ] = source [ j ++ ] ; if ( i > m ) for ( let q = j ; q <= r ; ++ q ) target [ k ++ ] = source [ q ] ; else for ( let q = i ; q <= m ; ++ q ) target [ k ++ ] = source [ q ] ; } function mergeAll < T > ( source , target , s , n , compare ) { let i = 0 ; while ( i <= n - 2 * s ) { merge ( source , target , i , i + s - 1 , i + 2 * s - 1 , compare ) ; i = i + 2 * s ; } if ( i + s < n ) merge ( source , target , i , i + s - 1 , n - 1 , compare ) ; else for ( let j = i ; j <= n - 1 ; ++ j ) target [ j ] = source [ j ] ; }