import { BigNumber , BlockRange , bufferUtils , ONE , Range , } from '@pigi/core-utils' ; param start1 param end1 param start2 param end2 returns export const intersects = ( start1 , end1 , start2 , end2 ) : boolean => { const maxStart = bufferUtils . max ( start1 , start2 ) ; const minEnd = bufferUtils . min ( end1 , end2 ) ; return bufferUtils . lt ( maxStart , minEnd ) ; } ; param range1 param range2 returns export const getOverlappingRange = ( range1 , range2 ) : Range | undefined => { const start = BigNumber . max ( range1 . start , range2 . start ) ; const end = BigNumber . min ( range1 . end , range2 . end ) ; return start . lt ( end ) ? { start , end } : undefined ; } ; param range1 param range2 returns export const rangesIntersect = ( range1 , range2 ) : boolean => { return ! ! getOverlappingRange ( range1 , range2 ) ; } ; param subset param superset returns export const isRangeSubset = ( subset , superset ) : boolean => { return ( subset !== undefined && superset !== undefined && subset . start . gte ( superset . start ) && subset . end . lte ( superset . end ) ) ; } ; param ranges param rangeToSpan returns export const doRangesSpanRange = ( ranges , rangeToSpan ) : boolean => { const sortedRanges = ranges . sort ( ( a , b ) => { return a . start . lt ( b . start ) ? - 1 : a . start . eq ( b . start ) ? 0 : 1 ; } ) ; let lowestNotSpanned = rangeToSpan . start ; for ( const rangeElem of sortedRanges ) { if ( rangeElem . start . gt ( lowestNotSpanned ) ) { return false ; } lowestNotSpanned = rangeElem . end ; if ( lowestNotSpanned . gte ( rangeToSpan . end ) ) { return true ; } } return false ; } ; /**
 * RangeStore makes it easy to store ranges.
 * When ranges are added, only the sections with
 * a higher block number than existing ranges
 * that they overlap with will be inserted.
 */ export class DefaultBlockRange < T extends BlockRange > { public ranges : T [ ] ; param ranges constructor ( ranges = [ ] ) { this . ranges = ranges ; } param other public merge ( other ) { for ( const range of other . ranges ) { this . addRange ( range ) ; } } param range returns public getOverlapping ( range ) { return this . ranges . reduce ( ( overlap , existing ) => { const overlapping = getOverlappingRange ( existing , range ) ; if ( ! ! overlapping ) { overlap . push ( { ... existing , start : overlapping . start , end : overlapping . end , } ) ; } return overlap ; } , [ ] ) ; } param range public addRange ( range ) { if ( range . start . gte ( range . end ) ) { throw new Error ( 'Invalid range' ) ; } const toAdd = new DefaultBlockRange ( [ range ] ) ; for ( const overlap of this . getOverlapping ( range ) ) { if ( overlap . block . gt ( range . block ) ) { toAdd . removeRange ( overlap ) ; } else { this . removeRange ( overlap ) ; } } this . ranges = this . ranges . concat ( toAdd . ranges ) ; this . sortRanges ( ) ; } param range public removeRange ( range ) { for ( const overlap of this . getOverlapping ( range ) ) { let removed ; this . ranges = this . ranges . filter ( ( r ) => { if ( r . start . lte ( overlap . start ) && r . end . gte ( overlap . end ) ) { removed = r ; return false ; } return true ; } ) ; if ( removed . start . lt ( overlap . start ) ) { this . ranges . push ( { ... removed , end : overlap . start , } ) ; } if ( removed . end . gt ( overlap . end ) ) { this . ranges . push ( { ... removed , start : overlap . end , } ) ; } } this . sortRanges ( ) ; } param range public incrementBlocks ( range ) { if ( range . start . gte ( range . end ) ) { throw new Error ( 'Invalid range' ) ; } for ( const existing of this . ranges ) { const overlap = { start : BigNumber . max ( existing . start , range . start ) , end : BigNumber . min ( existing . end , range . end ) , } ; if ( overlap . start . gte ( overlap . end ) ) { continue ; } this . addRange ( { ... existing , ... overlap , ... { block : existing . block . add ( ONE ) , } , } ) ; } } /**
     * Sorts ranges by start.
     */ private sortRanges ( ) { this . ranges = this . ranges . sort ( ( a , b ) => { return a . start . sub ( b . start ) . toNumber ( ) ; } ) ; } }