import { ParseOptions , parseTsvBuffer } from './ImportUtils' ; const browserBytes = 'browser ' . split ( '' ) . map ( c => c . charCodeAt ( 0 ) ) ; const trackBytes = 'track ' . split ( '' ) . map ( c => c . charCodeAt ( 0 ) ) ; const commentBytes = '#' . split ( '' ) . map ( c => c . charCodeAt ( 0 ) ) ; function bytesAreFoundAt ( position , buffer , bytes ) { let i = 0 ; for ( ; i < bytes . length ; i += 1 ) { if ( buffer [ position + i ] !== bytes [ i ] ) { return false ; } } return true ; } export function removeBedHeaders ( buffer ) { let i = 0 ; for ( ; i < buffer . length ; i += 1 ) { if ( bytesAreFoundAt ( i , buffer , browserBytes ) || bytesAreFoundAt ( i , buffer , trackBytes ) || bytesAreFoundAt ( i , buffer , commentBytes ) ) { do { i += 1 ; } while ( buffer [ i ] !== 10 ) ; } else { break ; } } if ( i ) { return buffer . slice ( i ) ; } return buffer ; } export async function parseBedBuffer ( buffer , options ) { const b = removeBedHeaders ( buffer ) ; const data = await parseTsvBuffer ( b ) ; const bedColumns = [ { name : 'chrom' , dataType : { type : 'LocRef' } } , { name : 'chromStart' , dataType : { type : 'LocStart' } } , { name : 'chromEnd' , dataType : { type : 'LocEnd' } } , { name : 'name' , dataType : { type : 'Text' } } , { name : 'score' , dataType : { type : 'Number' } } , { name : 'strand' , dataType : { type : 'Text' } } , ] ; data . columns . forEach ( ( col , colNumber ) => { const bedColumn = bedColumns [ colNumber ] ; if ( bedColumn ) { col . name = bedColumn . name ; col . dataType = bedColumn . dataType ; } } ) ; data . hasColumnNames = true ; data . assemblyName = options . selectedAssemblyName ; data . columnDisplayOrder . push ( data . columnDisplayOrder . length ) ; data . columns . unshift ( { name : 'Location' , dataType : { type : 'LocString' } , isDerived : true , derivationFunctionText : `jexl:{text:row.cells[0].text+':'+row.cells[1].text+'..'+row.cells[2].text,\n
    extendedData: {refName: row.cells.ref.text, start: parseInt(row.cells.start.text,10), end: parseInt(row.cells.end.text,10)}}` , } ) ; return data ; } export async function parseBedPEBuffer ( buffer , options ) { const b = removeBedHeaders ( buffer ) ; const data = await parseTsvBuffer ( b ) ; interface BedColumn { name : string ; dataType : { type : string ; } ; featureField : string [ ] ; } const bedColumns = [ { name : 'chrom1' , dataType : { type : 'Text' } , featureField : [ 'refName' ] } , { name : 'start1' , dataType : { type : 'Number' } , featureField : [ 'start' ] } , { name : 'end1' , dataType : { type : 'Number' } , featureField : [ 'end' ] } , { name : 'chrom2' , dataType : { type : 'Text' } , featureField : [ 'mate' , 'refName' ] , } , { name : 'start2' , dataType : { type : 'Number' } , featureField : [ 'mate' , 'start' ] , } , { name : 'end2' , dataType : { type : 'Number' } , featureField : [ 'mate' , 'end' ] , } , { name : 'name' , dataType : { type : 'Text' } , featureField : [ 'name' ] } , { name : 'score' , dataType : { type : 'Number' } , featureField : [ 'score' ] } , { name : 'strand1' , dataType : { type : 'Text' } , featureField : [ 'strand' ] } , { name : 'strand2' , dataType : { type : 'Text' } , featureField : [ 'mate' , 'strand' ] , } , ] ; data . columns . forEach ( ( col , colNumber ) => { const bedColumn = bedColumns [ colNumber ] ; if ( bedColumn ) { col . name = bedColumn . name ; col . dataType = bedColumn . dataType ; } } ) ; data . hasColumnNames = true ; data . rowSet . rows . forEach ( ( row , rowNumber ) => { const featureData = { } ; row . cells . forEach ( ( { text } , columnNumber ) => { const bedColumn = bedColumns [ columnNumber ] ; const val = bedColumn && bedColumn . dataType . type === 'Number' && text ? parseFloat ( text ) : text ; if ( bedColumn ) { if ( bedColumn . featureField . length === 2 ) { if ( ! featureData [ bedColumn . featureField [ 0 ] ] ) { featureData [ bedColumn . featureField [ 0 ] ] = { } ; } featureData [ bedColumn . featureField [ 0 ] ] [ bedColumn . featureField [ 1 ] ] = val ; } else { featureData [ bedColumn . featureField [ 0 ] ] = val ; } } else { featureData [ `column${ columnNumber + 1 }` ] = val ; } } ) ; featureData . uniqueId = `bedpe-${ rowNumber }` ; row . extendedData = { feature : featureData , } ; } ) ; data . assemblyName = options . selectedAssemblyName ; return data ; }