diff --git a/.gitignore b/.gitignore index c82690f590..8a78c38776 100644 --- a/.gitignore +++ b/.gitignore @@ -3,19 +3,21 @@ .#* \#*\# *.index -bin/wig2png +/bin/wig2png *.pyc *TODO.txt Makefile /sample_data/json -src/wig2png/config.log -src/wig2png/config.status -src/wig2png/src/config.h -docs/jsdoc/ +/src/wig2png/config.log +/src/wig2png/config.status +/src/wig2png/src/config.h +/docs/jsdoc/ /*-debug.html -jslib/dojo-release-*-src/ /extlib/ autom4te.cache sample_data/raw/tomato -.prove -*.sw* +/.prove +/setup.log +/release-notes.html +samtools/ +setup.log diff --git a/.gitmodules b/.gitmodules index ea5af33492..b990f9d921 100644 --- a/.gitmodules +++ b/.gitmodules @@ -13,3 +13,15 @@ [submodule "src/jszlib"] path = src/jszlib url = git://github.com/rbuels/jszlib.git +[submodule "src/lazyload"] + path = src/lazyload + url = git://github.com/rbuels/lazyload.git +[submodule "src/dgrid"] + path = src/dgrid + url = git://github.com/SitePen/dgrid.git +[submodule "src/xstyle"] + path = src/xstyle + url = git://github.com/kriszyp/xstyle.git +[submodule "src/put-selector"] + path = src/put-selector + url = git://github.com/kriszyp/put-selector.git diff --git a/.htaccess b/.htaccess new file mode 100644 index 0000000000..f7f69764a1 --- /dev/null +++ b/.htaccess @@ -0,0 +1,10 @@ +# This Apache .htaccess file is for +# allowing cross-origin requests as defined by the Cross-Origin +# Resource Sharing working draft from the W3C +# (http://www.w3.org/TR/cors/). In order for Apache to pay attention +# to this, it must have mod_headers enabled, and its AllowOverride +# configuration directive must allow FileInfo overrides. + + Header onsuccess set Access-Control-Allow-Origin * + Header onsuccess set Access-Control-Allow-Headers X-Requested-With + diff --git a/Makefile.PL b/Makefile.PL index 1069e95792..def10847b5 100644 --- a/Makefile.PL +++ b/Makefile.PL @@ -40,12 +40,12 @@ my %WriteMakefileArgs = ( "Bio::Root::Version" => "1.006000", "Bio::SeqFeature::Annotated" => 0, "Carp" => 0, + "Cache::Ref::FIFO" => 0, "Cwd" => 0, "DBI" => 0, "Data::Dumper" => 0, "Devel::Size" => 0, "Digest::Crc32" => 0, - "Digest::MurmurHash" => 0, "Exporter" => 0, "Fcntl" => 0, "File::Basename" => 0, @@ -61,6 +61,7 @@ my %WriteMakefileArgs = ( "Heap::Simple::XS" => 0, "IO::File" => 0, "JSON" => 2, + "JSON::XS" => 0, "List::Util" => 0, "POSIX" => 0, "PerlIO::gzip" => 0, diff --git a/README.md b/README.md index aaff429b7e..80b8d22a5b 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,7 @@ Make sure you have a web server installed on your development machine. Any web cd /my/dev/webserver/root; git clone git@github.com:YOURACCOUNT/jbrowse.git + cd jbrowse git submodule update --init ./setup.sh # and now point your browser to diff --git a/bin/generate-names.pl b/bin/generate-names.pl index 9bfe42b7f2..088fb5c38b 100755 --- a/bin/generate-names.pl +++ b/bin/generate-names.pl @@ -8,7 +8,6 @@ =head1 USAGE generate-names.pl \ [ --out ] \ - [ --thresh ] \ [ --verbose ] =head1 OPTIONS @@ -24,10 +23,20 @@ =head1 OPTIONS Comma-separated list of which tracks to include in the names index. If not passed, all tracks are indexed. -=item --thresh +=item --locationLimit -Optional LazyPatricia chunking threshold, in bytes. Default 100kb. See -L for details. +Maximum number of distinct locations to store for a single name. Default 100. + +=item --completionLimit + +Maximum number of completions to store for a given prefix. Default 20. + +=item --totalNames + +Optional estimate of the total number of names that will go into this +names index. Used to choose some parameters for how the name index is +built. If not passed, tries to estimate this based on the size of the +input names files. =item --verbose @@ -48,33 +57,40 @@ =head1 OPTIONS use lib "$Bin/../src/perl5"; use JBlibs; +use Carp::Always; + use Fcntl ":flock"; use File::Spec::Functions; use Getopt::Long; -use IO::File; use Pod::Usage; +use List::Util qw/ sum min max /; + +use PerlIO::gzip; use JSON 2; +use Bio::JBrowse::HashStore; -use LazyPatricia; use GenomeDB; -use Data::Dumper; -$Data::Dumper::Indent = 1; - -my %trackHash; my @includedTrackNames; -my @tracksWithNames; my $outDir = "data"; -my $thresh = 100 * 2**10; my $verbose = 0; my $help; +my $max_completions = 20; +my $max_locations = 100; +my $thresh; +my $est_total_name_records; +my $hash_bits; GetOptions("dir|out=s" => \$outDir, - "thresh=i" => \$thresh, + "completionLimit=i" => \$max_completions, + "locationLimit=i" => \$max_locations, "verbose+" => \$verbose, + "thresh=i" => \$thresh, + "totalNames=i" => \$est_total_name_records, 'tracks=s' => \@includedTrackNames, + 'hashBits=i' => \$hash_bits, "help|h|?" => \$help) or pod2usage(); my %includedTrackNames = map { $_ => 1 } @@ -93,111 +109,229 @@ =head1 OPTIONS } my $gdb = GenomeDB->new( $outDir ); -my $nameDir = catdir($outDir, "names"); -mkdir($nameDir) unless (-d $nameDir); my @refSeqs = @{ $gdb->refSeqs }; +unless( @refSeqs ) { + die "No reference sequences defined in configuration, nothing to do.\n"; +} my @tracks = grep { !%includedTrackNames || $includedTrackNames{ $_->{label} } } - @{ $gdb->trackList }; + @{ $gdb->trackList || [] }; +unless( @tracks ) { + die "No tracks defined in configuration, nothing to do.\n"; +} if( $verbose ) { print STDERR "Tracks:\n".join('', map " $_->{label}\n", @tracks ); } -# open the root file; we lock this file while we're -# reading the name lists, deleting all the old lazy-* -# files, and writing new ones. -my $rootFile = catfile($nameDir, "root.json"); -my $root = new IO::File $rootFile, O_WRONLY | O_CREAT - or die "couldn't open $rootFile: $!"; -flock $root, LOCK_EX; - # read the name list for each track that has one -my %nameHash; my $trackNum = 0; -my @namearray; -foreach my $ref (@refSeqs) { - push @{$nameHash{lc $ref->{name}}}, [ @{$ref}{ qw/ name length name seqDir start end seqChunkSize/ }]; - foreach my $track (@tracks) { - my $infile = catfile( $outDir, - "tracks", - $track->{label}, - $ref->{name}, - "names.json"); - next unless -e $infile; +# find the names files we will be working with +my @names_files = find_names_files(); +if( ! @names_files ) { + warn "WARNING: No feature names found for indexing, only reference sequence names will be indexed.\n"; +} - my $names = do { - local $/; - open my $j, '<', $infile or die "$! reading $infile"; - JSON::from_json(<$j>); - }; +#print STDERR "Names files:\n", map " $_->{fullpath}\n", @names_files; + +# estimate the total number of name records we probably have based on the input file sizes +$est_total_name_records ||= int( (sum( map { -s $_->{fullpath} } @names_files )||0) / 70 ); +if( $verbose ) { + print STDERR "Estimated $est_total_name_records total name records to index.\n"; +} + +my $nameStore = Bio::JBrowse::HashStore->open( + dir => catdir( $outDir, "names" ), + empty => 1, + + # set the hash size to try to get about 50KB per file, at an + # average of about 500 bytes per name record, for about 100 + # records per file. if the store has existing data in it, this + # will be ignored + hash_bits => $hash_bits || ( + $est_total_name_records + ? sprintf('%0.0f',max( 4, min( 32, 4*int( log( ($est_total_name_records||0) / 100 )/ 4 / log(2)) ))) + : 12 + ), +); + +if( $verbose ) { + print STDERR "Using ".$nameStore->{hash_bits}."-bit hashing.\n"; +} + +# insert a name record for all of the reference sequences + +my $name_records_iterator = sub {}; +my @namerecord_buffer; +for my $ref ( @refSeqs ) { + push @namerecord_buffer, [ @{$ref}{ qw/ name length name seqDir start end seqChunkSize/ }]; +} - foreach my $nameinfo ( @$names) { - foreach my $alias ( @{$nameinfo->[0]} ) { - my $track = $nameinfo->[1]; - unless( defined $trackHash{$track} ) { - $trackHash{$track} = $trackNum++; - push @tracksWithNames, $track; - } - push @{$nameHash{lc $alias}}, [ $alias, - $trackHash{$track}, - @{$nameinfo}[2..$#{$nameinfo}]]; +my %trackHash; +my @tracksWithNames; +my $record_stream = sub { + while( ! @namerecord_buffer ) { + my $nameinfo = $name_records_iterator->() || do { + my $file = shift @names_files; + return unless $file; + #print STDERR "Processing $file->{fullpath}\n"; + $name_records_iterator = make_names_iterator( $file ); + $name_records_iterator->(); + } or return; + foreach my $alias ( @{$nameinfo->[0]} ) { + my $track = $nameinfo->[1]; + unless ( defined $trackHash{$track} ) { + $trackHash{$track} = $trackNum++; + push @tracksWithNames, $track; } + push @namerecord_buffer, [ + lc $alias, + $alias, + $trackHash{$track}, + @{$nameinfo}[2..$#{$nameinfo}] + ]; } } -} + return shift @namerecord_buffer; +}; -# clear out old data -$root->seek(0, SEEK_SET); -$root->truncate(0); -if( my @lazyFiles = glob( catfile( $nameDir, "lazy-*" )) ) { - unlink @lazyFiles - or die "couldn't unlink name files: $!"; -} +# sort the stream by hash key to improve cache locality +my $entry_stream = $nameStore->sort_stream( $record_stream ); -my $trie = LazyPatricia::create( \%nameHash ); -$trie->[0] = \@tracksWithNames; +# now write it to the store +while( my $entry = $entry_stream->() ) { + insert( $nameStore, $entry ); +} -my ($total, $thisChunk) = - LazyPatricia::partition( $trie, "", $thresh, sub { - my ($subtreeRoot, $prefix, $thisChunk, $total) = @_; - # output subtree - writeJSON( catfile($nameDir, "lazy-$prefix.json"), - $subtreeRoot, - {pretty => 0} ); - printf STDERR ( "subtree for %15s has %10d in chunk, %10d total\n", - $prefix, $thisChunk, $total ) - if $verbose; - }); +# store the list of tracks that have names +$nameStore->{meta}{track_names} = \@tracksWithNames; +# record the fact that all the keys are lowercased +$nameStore->{meta}{lowercase_keys} = 1; -print STDERR "${total}b total size, with ${thisChunk}b in the root chunk\n" - if $verbose; -# write the root -$root->print( JSON::to_json($trie, {pretty => 0}) ); +# set up the name store in the trackList.json +$gdb->modifyTrackList( sub { + my ( $data ) = @_; + $data->{names}{type} = 'Hash'; + $data->{names}{url} = 'names/'; + return $data; +}); exit; -############ +################ HELPER SUBROUTINES ############################## -sub writeJSON { - my ( $file, $contents, $opts ) = @_; - open my $f, '>', $file or die "$! writing $file"; - print $f JSON::to_json( $contents, $opts || {} ); +sub find_names_files { + my @files; + for my $track (@tracks) { + for my $ref (@refSeqs) { + my $dir = catdir( $outDir, + "tracks", + $track->{label}, + $ref->{name} + ); + + # read either names.txt or names.json files + my $name_records_iterator; + my $names_txt = catfile( $dir, 'names.txt' ); + if( -f $names_txt ) { + push @files, { fullpath => $names_txt, type => 'txt' }; + } + else { + my $names_json = catfile( $dir, 'names.json' ); + if( -f $names_json ) { + push @files, { fullpath => $names_json, type => 'json', namestxt => $names_txt }; + } + } + } + } + return @files; } +sub insert { + my ( $store, $entry ) = @_; -=head1 AUTHOR + my $record = $entry->data; + my $lc = shift @$record; + my $name = $record->[0]; -Mitchell Skinner Emitch_skinner@berkeley.eduE + { # store the exact name match + my $r = $entry->get || { exact => [], prefix => [] }; + if( $max_locations && @{ $r->{exact} } < $max_locations ) { + push @{ $r->{exact} }, $record; + $entry->set( $r ); + } + elsif( $verbose ) { + #print STDERR "Warning: $name has more than --locationLimit ($max_locations) distinct locations, not all of them will be indexed.\n"; + } + } -Copyright (c) 2007-2009 The Evolutionary Software Foundation + # generate all the prefixes + my @prefixes; + chop $lc; + while( $lc ) { + push @prefixes, $lc; + chop $lc; + } -This package and its accompanying libraries are free software; you can -redistribute it and/or modify it under the terms of the LGPL (either -version 2.1, or at your option, any later version) or the Artistic -License 2.0. Refer to LICENSE for the full license text. + # store the prefixes + for my $prefix ( @prefixes ) { + my $r = $store->get( $prefix ) || { exact => [], prefix => [] }; + my $p = $r->{prefix}; + if( @$p < $max_completions ) { + if( ! grep $name eq $_, @$p ) { + push @{ $r->{prefix} }, $name; + $store->set( $prefix, $r ); + } + } + elsif( @{ $r->{prefix} } == $max_completions ) { + push @{ $r->{prefix} }, { name => 'too many matches', hitLimit => 1 }; + $store->set( $prefix, $r ); + } + } +} -=cut + +# each of these takes an input filename and returns a subroutine that +# returns name records until there are no more, for either names.txt +# files or old-style names.json files +sub make_names_iterator { + my ( $file_record ) = @_; + if( $file_record->{type} eq 'txt' ) { + my $input_fh = open_names_file( $file_record->{fullpath} ); + # read the input json partly with low-level parsing so that we + # can parse incrementally from the filehandle. names list + # files can be very big. + return sub { + my $t = <$input_fh>; + return $t ? eval { JSON::from_json( $t ) } : undef; + }; + } + elsif( $file_record->{type} eq 'json' ) { + # read old-style names.json files all from memory + my $input_fh = open_names_file( $file_record->{fullpath} ); + + my $data = JSON::from_json(do { + local $/; + scalar <$input_fh> + }); + + open my $nt, '>', $file_record->{namestxt} or die; + return sub { + my $rec = shift @$data; + if( $rec ) { + $nt->print(JSON::to_json($rec)."\n"); + } + return $rec; + }; + } +} + +sub open_names_file { + my ( $infile ) = @_; + my $gzip = $infile =~ /\.(txt|json)z$/ ? ':gzip' : ''; + open my $fh, "<$gzip", $infile or die "$! reading $infile"; + return $fh; +} diff --git a/bin/ucsc-to-json.pl b/bin/ucsc-to-json.pl index be78d075cb..89ecae52fa 100755 --- a/bin/ucsc-to-json.pl +++ b/bin/ucsc-to-json.pl @@ -115,7 +115,7 @@ =head1 EXAMPLE use JSON 2; use GenomeDB; use NameHandler; -use ExternalSorter; +use Bio::JBrowse::ExternalSorter; my $trackdb = "trackDb"; my ($indir, $tracks, $arrowheadClass, $subfeatureClasses, $clientConfig, $db, @@ -274,7 +274,7 @@ =head1 EXAMPLE }; my %chromCounts; - my $sorter = ExternalSorter->new($compare, $sortMem); + my $sorter = Bio::JBrowse::ExternalSorter->new($compare, $sortMem); for_columns("$indir/" . $trackMeta->{tableName}, sub { $chromCounts{$_[0]->[$chromCol]} += 1; diff --git a/build/Makefile b/build/Makefile index 27734e6c39..7e4cea7b1f 100644 --- a/build/Makefile +++ b/build/Makefile @@ -59,7 +59,6 @@ release-min-test: release-min cp -r docs tests* sample_data $(RELEASE_MIN_DIR); cd $(RELEASE_MIN_DIR) && ./setup.sh cd $(RELEASE_MIN_DIR) && prove -Isrc/perl5 -r -j3 - cd $(RELEASE_MIN_DIR) && JBROWSE_URL='http://localhost/jbrowse/$(RELEASE_MIN)/index.html' nosetests bin/wig2png: src/wig2png/Makefile $(MAKE) -C src/wig2png; diff --git a/docs/screencasts/demo_script.txt b/docs/screencasts/demo_script.txt index dbe96c590a..3937f36771 100644 --- a/docs/screencasts/demo_script.txt +++ b/docs/screencasts/demo_script.txt @@ -1,37 +1,135 @@ -## This is the script for the JBrowse demo screencast, last updated July 11, 2012 ## +## This is the script for the JBrowse demo screencast, last updated January 15, 2013 ## + +** set up browser to initial state: 1088x784, click + +http://localhost/jbrowse/index.html?loc=ctgA%3A11576..30575&tracks=Transcript%2Cbam_simulated%2Cvolvox_microarray.bw_xyplot&data=sample_data%2Fjson%2Fvolvox + +then close tracks + +** -** set up browser to initial state ** ** hit record ** -I'm Rob Buels, lead developer of the JBrowse genome browser. This short video gives an overview of the primary features of JBrowse. +========================= +SCENE 1 +========================= + +Hi, I'm Rob Buels, lead developer of the JBrowse genome browser. This short video gives an overview of the primary features of JBrowse. Like most genome browsers, JBrowse lets you scroll back and forth through a genome, displaying data in multiple tracks on the screen. For this demo, we are using a set of artificial test data. -Let's turn on some tracks by dragging them from the track list on the left into the main display pane. +Let's turn on a few tracks. We can either drag them from the track list on the left into the main display pane - -** turn on Exonerate predictions, Simulated next-gen reads, volvox_microarray ** +** turn on Exonerate predictions, "Simulated next-gen reads" by dragging ** -We can scroll back and forth a bit by clicking and dragging the mouse in the main pane. +or by double-clicking them -** scroll with the mouse ** +** turn on "BigWig XY - volvox_microarray" with double-click ** -By double-clicking, you can zoom in, and shift-double-clicking zooms out. You can also do these things using the buttons in the bar at the navigation area. +To scroll back and forth, we just click and drag in the main pane. -By typing in the location box in this area, you can jump to the locations of specific features, or to specific reference sequences. Let's jump to test features number 14, called f14. Notice that the track that contains f14 appeared when we jumped to it. +** scroll with the mouse ** + +If we double-click in the main pane, we zoom in, and shift-double-clicking zooms out. We can also do these things using the buttons in the navigation area at the top. -Another great way of navigating is what's called rubber-band zooming, or dynamic zooming, where you can highlight parts of the display that you want to zoom to. You can do this both in the overview +Another way of navigating in JBrowse is what's called rubber-band zooming, or dynamic zooming, where you can highlight parts of the display that you want to zoom to. You can do this either in the overview - ** highlight in the overview to zoom out ** -and in the main view +or in the main view while holding down shift to highlight. + +** shift-zoom in the main view ** + +To find a specific feature or reference sequence by name, just type its name in the location box at the top. Let's type the name of a test feature, f14. + +** Type "f1" slowly in the location box ** + +Notice that as I type, JBrowse suggests names of features that match what I've typed. So far, I've only typed "f1", but JBrowse is already suggesting "f14" as an option, so I'll click it to select it - + +** click "f14" ** + +and then hit "Go" to jump to it. + +** click "Go", MOVE MOUSE OFF SCREEN ** + +** + put + + http://localhost/jbrowse/index.html?data=sample_data/json/modencode + + in the clipboard +** +======================================================== +SCENE 2 +======================================================== + +Notice that "Example Features", the track that contains f14, is automatically brought up to show the feature we're searching for. + +JBrowse is capable of displaying a wide variety of data types, and has support for many popular file formats, including GFF3, BED, BAM, Wiggle, and BigWig. + +One of the best features of JBrowse is its ability to display data directly from BAM and BigWig files, with no pre-processing necessary. This means that if your BigWig or BAM file is accessible on your web server, you can just add a track entry for it in the JBrowse configuration, and it'll be ready to go. + +# BAM alignments + +First, let's have a look at some alignments from a BAM file, in the track labelled 'volvox-sorted.bam'. We'll turn off these tracks to give us some space - + +** turn off all visible tracks ** + +We'll drag it from the side bar to turn it on. + +** turn on volvox-sorted.bam ** + +This is a simulated genomic resequencing dataset, with next-gen reads of 100bp, shown with a JBrowse Alignments track, which is optimized specifically for showing next-generation alignments. As we scroll through, we can see that this data includes both sequencing errors and some SNPs. It's easy to see visually where the reads agree on a sequence that is different from the reference, since it looks like a column of a different color. To see all of the detailed information about a particular read, just click on it - + +** click on one of the reads ** + +and a window showing all of the data for that read will come up. + +** close the dialog ** + +Once again, all of this is being displayed directly from the BAM file itself. As we scroll around, JBrowse is fetching small pieces of the file as they are needed, which works with even the largest BAM files. + +# BigWig files + +Similarly, JBrowse can also display quantitative data directly from BigWig files. Let's turn off that alignment track, and turn on a couple of tracks that demonstrate the BigWig functionality - + +** turn on BigWig Density and BigWig XY - volvox_microarray ** + +These are two different views of data from the same BigWig file, which contains some made-up quantitative test data. + +The upper track is a JBrowse Wiggle/Density track, set up to show the quantitative data as colored regions: blue for values above the data set's global mean, red for values below the mean. More intense blues and reds indicate values that are further above and below the mean, respectively. + +The lower track, labeled 'BigWig XY', is a JBrowse Wiggle/XYPlot track, which shows a bar graph of the quantitative data. This one is configured to show the values as blue bars of varying heights, along with a yellow line showing the data's global mean, and grey shaded regions showing plus or minus one and two variances of the mean. + +And, just as with the BAM track shown earlier, JBrowse fetches small parts of the BigWig file on an as-needed basis, so this works with even with very large BigWig files. + +What's more, beginning in JBrowse 1.7, all of this data can be exported to a variety of file formats. For example, to get the quantitative data for this particular region in a bedGraph file, I can just go to the menu for this track - + +** click the track menu -> save track data ** + +choose to save the visible region, and bedGraph format + +** choose visible region and bedGraph format ** + +and hit 'View'to see the bedGraph dump of the data in the currently visible region. + +** hit View ** + +and there we have our bedGraph file with the data from this region. If we want to save it to disk, we can hit the Save button here, or we could also have hit the save button on the previous screen. + +This data-saving functionality works with all of the major data types supported by JBrowse, and can save files in FASTA, GFF3, BED, bedGraph, and Wiggle format. + +Next, we'll navigate to a different set of test data for 1800 tracks from the modENCODE project, looking at another exciting feature of JBrowse: the optional faceted track selector. -** zoom in the main view ** +** pull up the modencode demo in A NEW TAB -** pull up the modencode demo in A NEW TAB ** +http://localhost/jbrowse/index.html?data=sample_data/json/modencode -One of the most exciting features of JBrowse is the optional faceted track selector, which lets users efficiently find the tracks they want in JBrowse installations with hundreds or even thousands of tracks. +** -Let's pull up another JBrowse demonstration that contains a snapshot of the modENCODE track metadata with 1,805 tracks. +================== +SCENE 3 +================== With the faceted track selector, you can progressively narrow the set of tracks you're interested in by selecting the attributes you want them to have; that is, searching by one or more facets of the track data. In the track selector, click to select an attribute, then click to select one or more values you want to search for. diff --git a/docs/tutorial/conf_files/volvox.json b/docs/tutorial/conf_files/volvox.json index d16cf028d0..df3a1e2543 100644 --- a/docs/tutorial/conf_files/volvox.json +++ b/docs/tutorial/conf_files/volvox.json @@ -153,7 +153,7 @@ "UTR" : "transcript-UTR" }, "subfeatures" : true, - "onClick": "function() { alert('Ran arbitrary JavaScript!'); };" + "onClick": "function() { alert('This is a user-configurable JavaScript action!'); };" }, { "feature" : [ diff --git a/faceted_track_selector.css b/faceted_track_selector.css index 00785235dd..3fe4018b03 100644 --- a/faceted_track_selector.css +++ b/faceted_track_selector.css @@ -105,6 +105,9 @@ .tundra #faceted_tracksel_top { background: #396494; } +.tundra #faceted_tracksel_top .topLink { + color: white; +} #faceted_tracksel_top > * { display: inline-block; @@ -215,7 +218,10 @@ #faceted_tracksel .dijitAccordionContainer .dijitAccordionTitle { padding: 0; } -#faceted_tracksel .facetTitle { +#faceted_tracksel .dijitAccordionTitleFocus { + position: relative; +} +.tundra #faceted_tracksel .dijitAccordionTitleFocus { border-top: 3px solid transparent; padding: 2px 2px 2px 0.6em; color: #1B3047 @@ -237,11 +243,13 @@ } #faceted_tracksel .facetTitle a { - display: none; + position: absolute; + top: 2px; + right: -4px; + visibility: hidden; } #faceted_tracksel .activeFacet a.clearFacet { - display: block; - float: right; + visibility: visible; padding: 1px 6px; } diff --git a/file_dialog.css b/file_dialog.css new file mode 100644 index 0000000000..28d43e3e42 --- /dev/null +++ b/file_dialog.css @@ -0,0 +1,141 @@ +@import url("src/dojox/form/resources/UploaderFileList.css"); +.fileDialog { + color: #333; +} + +.fileDialog label { + font-weight: bold; + padding: 0 0.5em; +} +.fileDialog th { + font-weight: bold; + border-bottom: 2px solid black; +} +.fileDialog .dijitDialogPaneContent > div.intro { + width: 27em; + text-align: justify; + position: relative; + left: 12%; + margin: 1.4em 0 2.4em 0; +} + +.fileDialog .connector { + background: #333; + height: 6px; + width: 12px; + position: absolute; + + bottom: -6px; + left: 50%; + margin-left: -6px; +} + +.fileDialog h2, .fileDialog h3 { + margin: 0; + padding: 0; + font-size: 125%; +} + +.fileDialog .dijitDialogPaneContent > div { + position: relative; + + width: 40em; + padding: 0 0 0.75em 0; + margin: 6px 0; +} +.fileDialog div.aux { + text-align: center; + margin-bottom: 1em; +} +.fileDialog .resourceControls { + height: 10em; + position: relative; +} +.fileDialog .resourceControls > div { + width: 19.5em; + box-sizing: border-box; + height: 100%; +} +.fileDialog .resourceControls > div > h3 { + height: 19%; +} + +.fileDialog .localFilesControl { + position: absolute; + top: 0; + left: 0; +} + +.fileDialog .dijitUploader { + position: absolute; + margin: 0; +} + +.fileDialog .remoteURLsControl textarea, +.fileDialog .localFilesControl .dragArea { + height: 81%; + position: relative; + border: 1px solid #b3b3b3; + width: 100%; + box-sizing: border-box; +} +.fileDialog .localFilesControl .dragArea:hover { + border: 1px dashed green; +} + +.fileDialog .localFilesControl .dragArea .dragMessage { + height: 2em; + position: absolute; + top: 60%; + font-weight: bold; + margin-top: -1em; + text-align: center; + width: 100%; +} +.fileDialog .remoteURLsControl textarea { + font-size: 10px; + background: #f2f2f2; +} +.fileDialog .remoteURLsControl textarea:hover { + background: white; + border-color: #333; +} + +.fileDialog .remoteURLsControl { + position: absolute; + top: 0; + right: 0; +} + +.fileDialog .resourceList { + background: #bcd3ef; +} + +.fileDialog .dijitSelect td.dijitStretch { + width: 6em; +} +.fileDialog .resourceList > h3, .fileDialog .trackList > h3 { + padding: 0 0.6em; + line-height: 2.1; + margin-bottom: 0.5em; +} + +.fileDialog .emptyMessage { + width: 100%; + font-size: 110%; + color: #686868; + font-weight: bold; + text-align: center; + line-height: 4; +} + +.fileDialog .trackList { + background: #8cb1dd; +} + +.fileDialog .resourceList > table, .fileDialog .trackList > table { + width: 95%; + padding: 0 0.75em 0.5em 0.75em; + margin: 0 auto; + border-collapse: collapse; +} \ No newline at end of file diff --git a/genome.css b/genome.css index 831933f755..654fb31d91 100644 --- a/genome.css +++ b/genome.css @@ -3,7 +3,9 @@ @import url("src/dojo/resources/dojo.css"); @import url("main.css"); +@import url("menubar.css"); @import url("icons.css"); +@import url("file_dialog.css"); /* CSS styles for the various types of feature glyphs */ @import url("track_styles.css"); diff --git a/icons.css b/icons.css index 110e4c9527..6765f6e391 100644 --- a/icons.css +++ b/icons.css @@ -1,5 +1,7 @@ .jbrowseIconHelp, -.jbrowseIconBusy { +.jbrowseIconBusy, +.jbrowseIconLink +{ background-image: url('img/commonIconsEnabled.png'); width: 16px; height: 16px; @@ -8,7 +10,10 @@ .jbrowseIconHelp { background-position: 0; } +.jbrowseIconLink { + background-position: -152px; +} .jbrowseIconBusy { background-image: url('img/spinner.gif'); -} \ No newline at end of file +} diff --git a/img/black_20x2.png b/img/black_20x2.png new file mode 100644 index 0000000000..d10f10a465 Binary files /dev/null and b/img/black_20x2.png differ diff --git a/img/commonIconsEnabled.png b/img/commonIconsEnabled.png index b33f2db6e2..319243c48d 100644 Binary files a/img/commonIconsEnabled.png and b/img/commonIconsEnabled.png differ diff --git a/img/glyphs_black.png b/img/glyphs_black.png new file mode 100644 index 0000000000..893112e04d Binary files /dev/null and b/img/glyphs_black.png differ diff --git a/img/glyphs_white.png b/img/glyphs_white.png new file mode 100644 index 0000000000..95f2fa9af2 Binary files /dev/null and b/img/glyphs_white.png differ diff --git a/img/minus-arrowhead.png b/img/minus-arrowhead.png index f562cb79ad..eeb6260f09 100644 Binary files a/img/minus-arrowhead.png and b/img/minus-arrowhead.png differ diff --git a/img/plus-arrowhead.png b/img/plus-arrowhead.png index 4e05f0cd8a..f4daf7e0ed 100644 Binary files a/img/plus-arrowhead.png and b/img/plus-arrowhead.png differ diff --git a/img/red_crosshatch_bg.png b/img/red_crosshatch_bg.png new file mode 100644 index 0000000000..783c4c4561 Binary files /dev/null and b/img/red_crosshatch_bg.png differ diff --git a/index.html b/index.html index 542c6c7c95..9b5419616b 100644 --- a/index.html +++ b/index.html @@ -3,16 +3,19 @@ JBrowse - + diff --git a/jbrowse_conf.json b/jbrowse_conf.json index 4fcfbb09ce..41e8c9877f 100644 --- a/jbrowse_conf.json +++ b/jbrowse_conf.json @@ -11,6 +11,8 @@ // ] // }, + suppressUsageStatistics: true, + // the variable below does nothing placeholder: 1 -} \ No newline at end of file +} diff --git a/main.css b/main.css index ebb254f6fd..5c58faa995 100644 --- a/main.css +++ b/main.css @@ -7,6 +7,14 @@ html, body { font-family: Univers,Trebuchet MS,Helvetica,Arial,sans-serif; } +.tundra input { + outline: none; +} + +.ghosted { + color: #aaa; +} + fieldset { padding-left: 1em; margin: 0.7em 0.5em; @@ -24,10 +32,28 @@ fieldset > legend { font-size: 14px; } -.ghosted { - color: #aaa; +/* styles for the autocomplete menu */ +.dijitComboBoxMenu .locString, .dijitComboBoxMenu .multipleLocations { + margin-left: 1em; +} +.dijitComboBoxMenu .multipleLocations { + color: #333; } +/* location choice dialog */ +.locationChoiceDialog div.prompt { + margin: 0.3em 1em 1em 1em; +} +.locationChoiceDialog .dgrid-row .dijitButton { + margin: 0 0.5em; +} +.locationChoiceDialog .goButtonColumn, +.locationChoiceDialog .showButtonColumn { + text-align: center; + white-space: nowrap; +} + + .tundra .dijitDialogCloseIcon { height: 25px; width: 25px; @@ -86,7 +112,7 @@ div.vertical_scrollbar { border-left: 1px solid #DDD9D9; } div.vertical_scrollbar .vertical_position_marker { - background: #444; + background: #555; opacity: 0.8; border-radius: 5px; width: 100%; @@ -103,17 +129,12 @@ div.vertical_scrollbar .vertical_position_marker { #navbox { padding-top: 3px; position: relative; -} - -.powered_by { - padding: 0 0.5em; - color: black; - text-decoration: none; + text-align: center; } .moreMatches { font-style: italic; - color: #ccc; + color: #aaa; } .moreMatches.dijitMenuItemSelected { background: none; @@ -123,13 +144,14 @@ div.vertical_scrollbar .vertical_position_marker { div.locationTrap { position: absolute; - background-color: #AEC7E3; - border-color: white white #AEC7E3 white; - border-style: solid; - width: 0px; - height: 0px; - line-height: 0px; z-index: -10; + height: 0; + top: 0; + left: 0; + border-color: transparent; + border-style: solid; + border-bottom-color: #A9C6EB; + border-top: 0px dotted transparent; } div.locationThumb { @@ -138,6 +160,7 @@ div.locationThumb { /* if you change this border from 2px, change GenomeView.showTrap */ border: 2px solid red; margin: 0px -2px 0px -2px; + height: 23px; cursor: move; background: rgba(0, 121, 245, 0.1); } @@ -162,10 +185,17 @@ a.topLink { color: blue; } +#location { + font-family: sans-serif; +} + div.overview { + position: relative; width: 100%; - padding: 4px 0; + padding: 4px 0 0 0; z-index: -5; + display: block; + height: 23px; background: #FAFAFA url(src/dijit/themes/tundra/images/titleBar.png) repeat-x top left; @@ -184,6 +214,10 @@ div.block { top: 0px; height: 100%; } +div.block.timed_out { + background: #ddd; + background: rgba( 0,0,0, 0.1 ); +} div.track { position: absolute; @@ -239,6 +273,7 @@ div.pos-label { top: 0px; z-index: 100; margin: 1px; + font-family: sans-serif; } div.overview-pos { @@ -277,12 +312,22 @@ div.sequence .base, div.sequence > div { height: 14px; line-height: 14px; } +div.sequence .base.big { + -moz-box-sizing: border-box; + box-sizing: border-box; + border: 1px solid #ccc; + border-right-color: #333; + border-bottom-color: #333; + height: 16px; +} + div.sequence > div { border-top: 1px solid #4d4d4d; border-bottom: 1px solid black; + background: #C6C6C6; } div.sequence > div:first-child { - border-bottom-width: 0px; + border-bottom-color: #4d4d4d; } span.base { @@ -356,12 +401,14 @@ div.track-label, div.tracklist-label { } .track .loading { - background: rgba( 0,0,0,0.1); + background: #fafafa; color: #777; margin: 0; font-weight: bold; - height: 40px; + height: 100%; width: 100%; + z-index: 15; + position: absolute; } .track .loading .text { display: inline; @@ -382,6 +429,15 @@ div.track-label { z-index: 20; border-color: #eee; opacity: 0.7; + + /* setting white-space to "nowrap" prevents Chrome-specific bug with + label text sometimes disappearing after zoom in Chrome was + wrapping track-label text to next line, which falls outside of + track-label fixed height and therefore not seen. see chromium + bug report for more details on underlying issue: + http://code.google.com/p/chromium/issues/detail?id=138918 + */ + white-space: nowrap; } div.track-label .track-label-text { @@ -530,8 +586,8 @@ a.feature-label { } div.overview .rubber-highlight { font-size: 0; - top: -4px; - height: 23px; + height: 100%; + margin-top: -4px; /* corresponds to padding on div.overview */ border-top: none; border-bottom: none; } @@ -599,12 +655,22 @@ div.error .codecaption { } div.error code { display: block; - padding: 1.2em; + font-size: 10px; + padding: 0.4em 1.2em; margin: 0 0.3em 0.3em 0.3em; + overflow: auto; + max-height: 6em; } div.message { background: #eee; } +div.block > div.message { + margin-top: 1em; + position: absolute; +} +div.block:hover > div.message { + z-index: 30000; +} .tundra .dijitDialogPaneContent { border-top: 1px solid #acacac; @@ -627,35 +693,47 @@ a.dialog-new-window { /* styles for popup feature detail dialogs from tracks */ .feature-detail { - padding-top: 1em; width: 50em; + color: #333; } .feature-detail .subfeature-detail { background: #fafafa; background: rgba( 0, 0, 0, 0.1 ); border: 1px outset #B9B9B9; + padding: 0.6em; } .feature-detail .fasta { clear: both; padding: 1em 1.5em; + margin: 0.2em 0; border: 1px solid #aaa; + background: transparent; +} +.feature-detail div.core { + font-size: 110%; +} +.feature-detail div.additional { +} +.feature-detail div.additional > h2 { + border-bottom: 1px solid rgba(0, 0, 0, 0.1); + margin: 1em 0 0.7em 0; } .detail .value { margin-left: 1em; display: inline-block; vertical-align: top; + font-family: sans-serif; } .detail .field { - margin-top: 0; - margin-bottom: 0.3em; + margin: 0; display: inline-block; - min-width: 9em; + min-width: 90px; vertical-align: top; } .detail .field_container { - padding: 0 4em 0.3em 1em; + padding: 0 4em 0 1em; } .sharePane input { @@ -684,7 +762,7 @@ a.dialog-new-window { display: none; background: #fefefe; padding: 0 0.7em; - z-index: 10; + z-index: 1000; text-align: center; cursor: crosshair; border: 1px solid #888; diff --git a/menubar.css b/menubar.css new file mode 100644 index 0000000000..7016277ed3 --- /dev/null +++ b/menubar.css @@ -0,0 +1,124 @@ +/* styles for the top menu bar */ +div.menuBar { + padding: 1px 0; + height: 25px; +} +.tundra .menuBar { + background: #396494; + text-align: right; +} +.tundra .menuBar a { + color: white; +} +div.topLink { + position: absolute; + right: 0; + top: 0; + z-index: 50; + background: white; + border: 1px solid #888; + border-width: 0 0 1px 1px; +} +div.menuBar a, .topLink a { + padding: 0 0.8ex; + text-decoration: none; +} +.menuBar .powered_by { + float: left; + font-size: 125%; + font-family: 'Helvetica Neue', Arial, Helvetica, 'Nimbus Sans L', sans-serif; + font-weight: bold; + line-height: 25px; /* note this line-height should be the same as the fixed height of the menuBar */ +} + +.share .icon { + height: 8px; + width: 19px; + display: inline; + display: inline-block; + background: url("img/glyphs_white.png") no-repeat -149px -91px; + margin-right: 2px; + margin-top: -2px; +} +a.topLink, a.topLink * { + cursor: pointer; +} +.topLink .powered_by { + padding: 0 0.5em; + color: black; + text-decoration: none; +} +.help .icon { + height: 14px; + width: 8px; + display: inline-block; + margin-top: -4px; + margin-right: 1px; + background: url("img/glyphs_white.png") no-repeat -174px -3px; +} +.menuBar * { + outline: none; +} +.tundra .menuBar .dijitButtonNode { + background: transparent; +} + +.tundra .menuBar .dijitButtonNode { + border: 2px outset rgba( 120, 120, 120, 0.2 ); +} +.tundra .menuBar .dijitButtonHover .dijitButtonNode, +.tundra .menuBar .dijitDropDownButtonHover .dijitButtonNode { + background: rgba( 255, 255, 255, 0.07 ); +} +.tundra .menuBar .dijitButtonActive .dijitButtonNode, +.tundra .menuBar .dijitDropDownButtonActive .dijitButtonNode { + border: 2px inset rgba( 120, 120, 120, 0.2 ); +} + +.menuBar .dijitButtonNode { + padding: 0 1em; +} + +.menuBar .dijitButtonNode * { + color: white; +} +.menuBar .config .icon { + height: 16px; + width: 16px; + margin-right: 2px; + margin-top: -2px; + display: inline; + display: inline-block; + background: url("img/glyphs_white.png") no-repeat -168px -27px; + +} + + +.menuBar > .menu { + float: left; + font-size: 120%; +} +.tundra .globalMenu .dijitMenuItem td { + padding: 0.5em 2px 0.5em 5px; +} + +.tundra .menuBar > .menu .dijitButtonNode { + border: none; +} +.tundra .menuBar > .menu.dijitDropDownButton, +.tundra .menuBar > .menu.dijitDropDownButton * { + margin: 0; + padding: 0; + line-height: 25px; +} +.tundra .menuBar > .menu.dijitDropDownButton .dijitButtonNode { + padding: 0 1em 0 0.7em; + text-align: left; +} + +.tundra .menuBar > .menu .dijitDropDownButtonHover .dijitButtonNode { + background: rgba( 255, 255, 255, 0.07 ); +} +.tundra .menuBar > .menu .dijitDropDownButtonActive .dijitButtonNode { + border: none; +} diff --git a/plugins/WebApollo/bin/flatfile-to-json.pl b/plugins/WebApollo/bin/flatfile-to-json.pl new file mode 100755 index 0000000000..5a458e7ab4 --- /dev/null +++ b/plugins/WebApollo/bin/flatfile-to-json.pl @@ -0,0 +1,166 @@ +#!/usr/bin/env perl +use strict; +use FindBin qw($RealBin); +use lib "$RealBin/../../../src/perl5"; +use JBlibs; + +use Bio::WebApollo::Cmd::FlatFileToJson; + +exit Bio::WebApollo::Cmd::FlatFileToJson->new(@ARGV)->run; + +__END__ + +=head1 NAME + +flatfile-to-json.pl - format data into JBrowse JSON format from an annotation file + +=head1 USAGE + + flatfile-to-json.pl \ + ( --gff | --bed ) \ + --trackLabel \ + [ --out ] \ + [ --key ] \ + [ --className ] \ + [ --getType ] \ + [ --getPhase ] \ + [ --getSubfeatures ] \ + [ --getLabel ] \ + [ --urltemplate "http://example.com/idlookup?id={id}" ] \ + [ --arrowheadClass ] \ + [ --subfeatureClasses '{ JSON-format subfeature class map }' ] \ + [ --clientConfig '{ JSON-format extra configuration for this track }' ] \ + [ --thinType ] \ + [ --thicktype ] \ + [ --type ] \ + [ --nclChunk ] \ + [ --compress ] \ + [ --sortMem ] \ + +=head1 ARGUMENTS + +=head2 Required + +=over 4 + +=item --gff + +=item --bed + +Process a GFF3 or BED-format file containing annotation data. + +NOTE: This script does not support GFF version 2 or GTF (GFF 2.5) input. + +=item --trackLabel + +Unique identifier for this track. Required. + +=back + +=head2 Optional + +=over 4 + +=item --help | -h | -? + +Display an extended help screen. + +=item --key '' + +Human-readable track name. + +=item --out + +Output directory to write to. Defaults to "data/". + +=item --className + +CSS class for features. Defaults to "feature". + +=item --getType + +Include the type of the features in the JSON. + +=item --getPhase + +Include the phase of the features in the JSON. + +=item --getSubfeatures + +Include subfeatures in the JSON. + +=item --getLabel + +Include a label for the features in the JSON. + +=item --urltemplate "http://example.com/idlookup?id={id}" + +Template for a URL to be visited when features are clicked on. + +=item --arrowheadClass + +CSS class for arrowheads. + +=item --subfeatureClasses '{ JSON-format subfeature class map }' + +CSS classes for each subfeature type, in JSON syntax. Example: + + --subfeatureClasses '{"CDS": "transcript-CDS", "exon": "transcript-exon"}' + +=item --clientConfig '{ JSON-format extra configuration for this track }' + +Extra configuration for the client, in JSON syntax. Example: + + --clientConfig '{"featureCss": "background-color: #668; height: 8px;", "histScale": 2}' + +=item --type + +Only process features of the given type. Can take either single type +names, e.g. "mRNA", or type names qualified by "source" name, for +whatever definition of "source" your data file might have. For +example, "mRNA:exonerate" will filter for only mRNA features that have +a source of "exonerate". + +Multiple type names can be specified by separating the type names with +commas, e.g. C<--type mRNA:exonerate,ncRNA>. + +=item --nclChunk + +NCList chunk size; if you get "json text or perl structure exceeds +maximum nesting level" errors, try setting this lower (default: +50,000). + +=item --compress + +Compress the output, making .jsonz (gzipped) JSON files. This can +save a lot of disk space, but note that web servers require some +additional configuration to serve these correctly. + +=item --sortMem + +Bytes of RAM to use for sorting features. Default 512MB. + +=back + +=head2 BED-specific + +=over 4 + +=item --thinType + +=item --thickType + +Correspond to C<<-thin_type>> and C<<-thick_type>> in +L. Do C<> for +details. + +=back + +=head1 MEMORY USAGE + +For efficient memory usage, it is very important that large GFF3 files +have C<###> lines in them periodically. For details of what C<###> is +and how it is used, see the GFF3 specification at +L. + +=cut diff --git a/plugins/WebApollo/css/add_sequence_alteration.css b/plugins/WebApollo/css/add_sequence_alteration.css new file mode 100644 index 0000000000..6aefcac6ca --- /dev/null +++ b/plugins/WebApollo/css/add_sequence_alteration.css @@ -0,0 +1,20 @@ +@CHARSET "UTF-8"; + +.sequence_alteration_button_div { + margin-top: 10px; + margin-left: auto; + margin-right: auto; + width: 25%; +} + +.sequence_alteration_input_label { + margin-left: 3px; + font-size: 1.5em; +} + +.sequence_alteration_input_field { + margin-left: 10px; +} + +.sequence_alteration_button { +} \ No newline at end of file diff --git a/plugins/WebApollo/css/edit_comments.css b/plugins/WebApollo/css/edit_comments.css new file mode 100644 index 0000000000..ead16e6a1c --- /dev/null +++ b/plugins/WebApollo/css/edit_comments.css @@ -0,0 +1,30 @@ +@CHARSET "UTF-8"; + +.comments { + width: 58em; +} + +.comment_header { + font-size: 1.5em; + margin-bottom: 5px; +} + +.comment_area { + width: 40em; + height: 3.5em; +} + +.comment_button { + height: 2.5em; +} + +.comment_add_button_div { + margin-top: 5px; +} + +.parent_comments_div { + margin-bottom: 10px; + border-bottom-style: dotted; + border-bottom-width: 2px; + padding-bottom: 10px; +} \ No newline at end of file diff --git a/plugins/WebApollo/css/edit_dbxrefs.css b/plugins/WebApollo/css/edit_dbxrefs.css new file mode 100644 index 0000000000..a7aa8896c5 --- /dev/null +++ b/plugins/WebApollo/css/edit_dbxrefs.css @@ -0,0 +1,34 @@ +@CHARSET "UTF-8"; + +.dbxrefs { + width: 39em; +} + +.dbxref_header { + font-size: 1.5em; + margin-bottom: 5px; +} + +.dbxref_table_header_field { + margin-right:5em; +} + +.dbxref_field { + margin-right:3px; + margin-top: 0px; + margin-bottom: 0px; +} + +.dbxref_button { +} + +.dbxref_add_button_div { + margin-top: 5px; +} + +.parent_dbxrefs_div { + margin-bottom: 10px; + border-bottom-style: dotted; + border-bottom-width: 2px; + padding-bottom: 10px; +} \ No newline at end of file diff --git a/plugins/WebApollo/css/export.css b/plugins/WebApollo/css/export.css new file mode 100644 index 0000000000..e33354bd97 --- /dev/null +++ b/plugins/WebApollo/css/export.css @@ -0,0 +1,22 @@ +@CHARSET "UTF-8"; + +.export_response { + width: 15em; + text-align: center; +} + +.waiting_image { + display: block; + margin-left: auto; + margin-right: auto; +} + +.export_response_iframe { + border: none; + text-align: center; + font-size: 12px; + max-width: 15em; + max-height: 6em; + overflow-x: auto; + overflow-y: hidden; +} \ No newline at end of file diff --git a/plugins/WebApollo/css/genome.css b/plugins/WebApollo/css/genome.css new file mode 100644 index 0000000000..b4fc7df5ab --- /dev/null +++ b/plugins/WebApollo/css/genome.css @@ -0,0 +1,39 @@ +/** TODO: need to remove all standard JBrowse styles, since they're now in either "main.css" or "feature_style.css", + and keep added / modified styles here (or break out into additional "webapollo.css" ? */ +/* main application CSS styles */ +/* @import url("main.css"); */ + + +/* This is the window around the whole feature map (including the numbers at the top) */ +/* kept diff frrm JBrowse main.css, but commented out +div.dragWindow { + cursor: url("img/openhand.cur"); +} +*/ + +/* kept diff from JBrowse main.css, but commented out +div.locationTrap { + border-bottom-color: #ccc; +} +*/ + +/* This is the red rectangular outline that appears on the top scale bar */ +/* kept diff from JBrowse main.css, but commented out +div.locationThumb { + cursor: url("img/openhand.cur"); +} +*/ + + +/* tweak the style of the powered_by link that has the WA logo in it */ +.menuBar .powered_by { + height: 27px; + background: white; + border-right: 1px solid rgb(156,156,156); + position: relative; + top: -1px; +} +.menuBar .powered_by > img { + position: relative; + top: 1px; +} \ No newline at end of file diff --git a/plugins/WebApollo/css/get_history.css b/plugins/WebApollo/css/get_history.css new file mode 100644 index 0000000000..aac83b2173 --- /dev/null +++ b/plugins/WebApollo/css/get_history.css @@ -0,0 +1,40 @@ +@CHARSET "UTF-8"; + +.history_table { + font-size: 1.5em; + max-width: 47em; +} + +.history_header_column { + font-weight: bold; +} + +.history_column { + width: 15em; + display: inline-block; + background-color: inherit; +} + +.history_row_selected { + background-color: #4169e1; + color: white; +} + +.history_row:hover { + background-color: #000099; + color: white; +} +.history_rows { + max-height: 10em; + overflow-y: auto; +} + +.history_date_column { + max-width: 10em; +} + +.history_preview { + width: 45em; + height: 2em; + padding-top: 3em; +} \ No newline at end of file diff --git a/plugins/WebApollo/css/get_sequence.css b/plugins/WebApollo/css/get_sequence.css new file mode 100644 index 0000000000..099c60d5b4 --- /dev/null +++ b/plugins/WebApollo/css/get_sequence.css @@ -0,0 +1,24 @@ +@CHARSET "UTF-8"; + +.sequence_area { + width: 60em; + height: 20em; + font-family: 'courier'; + font-size: 1.5em; +} + +.first_button_div { + margin-top: 10px; +} + +.button_div { + margin-top: 5px; +} + +.button_label { + margin-left: 3px; +} + +.button_field { + margin-left: 3px; +} \ No newline at end of file diff --git a/plugins/WebApollo/css/main.css b/plugins/WebApollo/css/main.css new file mode 100644 index 0000000000..0e4c3d6743 --- /dev/null +++ b/plugins/WebApollo/css/main.css @@ -0,0 +1,10 @@ +@import url("../jslib/jqueryui/themes/base/jquery.ui.all.css"); +@import url("genome.css"); +@import url("webapollo_track_styles.css"); +@import url("add_sequence_alteration.css"); +@import url("edit_dbxrefs.css"); +@import url("edit_comments.css"); +@import url("get_sequence.css"); +@import url("search_sequence.css"); +@import url("get_history.css"); +@import url("export.css"); diff --git a/plugins/WebApollo/css/search_sequence.css b/plugins/WebApollo/css/search_sequence.css new file mode 100644 index 0000000000..66694d9453 --- /dev/null +++ b/plugins/WebApollo/css/search_sequence.css @@ -0,0 +1,78 @@ +@CHARSET "UTF-8"; + +.search_sequence_label { + font-size: 1.5em; +} + +.search_sequence_input { + width: 50em; + height: 3.5em; +} + +.search_sequence_area { + margin-bottom: 10px; +} + +.search_all_ref_seqs_area { + margin-top: 5px; + margin-bottom: 5px; +} + +.search_all_ref_seqs_checkbox { + margin-right: 3px; +} + +.search_all_ref_seqs_label { + font-size: 1em; +} + +.search_sequence_matches_row:hover { + background-color: #000099; + color: white; +} + +.search_sequence_matches_generic_field { + width: 6.3em; + margin-right: 0.2em; + overflow: hidden; + text-overflow: ellipsis; + font-size: 1.6em; + background-color: inherit; + display: table-cell; +} + +.search_sequence_matches_header { + margin-bottom: 10px; +} + +.search_sequence_matches_field { + margin-top: 0px; + margin-bottom: 0px; + float: left; + overflow: hidden; + width: 6em; +} + +.search_sequence_tools { + margin-bottom: 10px; +} + +.search_sequence_matches { + max-height: 25em; + overflow: auto; +} + +.search_sequence_matches_row { +} + +.search_sequence_matches_row-firefox { + display: table-row; +} + +.search_sequence_message { + font-size: 1.6em; +} + +.search_sequence { + font-size: 9px; +} \ No newline at end of file diff --git a/plugins/WebApollo/css/webapollo_track_styles.css b/plugins/WebApollo/css/webapollo_track_styles.css new file mode 100644 index 0000000000..2471a69c5d --- /dev/null +++ b/plugins/WebApollo/css/webapollo_track_styles.css @@ -0,0 +1,669 @@ +/* +* naming conventions + +*/ + +.webapollo-CDS { + height: 80%; + top: 10%; +/* height: 12px */ +/* margin-top: 2px; */ /* relying on centering code instead */ + background-color: #F58544; + border-style: solid; + border-color: #555; + border-width: 1px; +} + +.webapollo-UTR { + height: 50%; + top: 25%; +/* height: 8px; */ +/* margin-top: 4px; */ /* relying on centering code instead */ +/* z-index: 8; */ + background-color: #AA5626; +} + +.mRNA, +.plus-mRNA, +.minus-mRNA { + height: 14px; + /* outline: 2px dashed green; */ + background-color: transparent; +} + + +div.track_annotations { + background-color: #FFFFDD; +} + +/* + To support WebApollo with sequence alteration features shown on SequenceTrack, + sequence style MUST NOT have a z-index specified +*/ +div.wa-sequence { + position: absolute; + left: 0px; + /* Courier New is preferred by JBrowse, but it looks too light in Firefox, and jagged in Chrome */ + /* font-family: Courier New,monospace; */ + font-family: monospace; + font-size: 10px; + letter-spacing: 2px; + padding-left: 2px; + /* top: 15px; */ + cursor: pointer; + /* z-index: 15; */ + -moz-user-select: none; + -khtml-user-select: none; + -webkit-user-select: none; + user-select: none; +} + +/* + block_seq_container are SequenceTrack divs that are child of .block and parent of .dna-residues + need to break this out from div.sequence because .sequence is also used for determining + font character width and height in GenomeView.calculateSequenceCharacterSize(), + and for that don't want a specified width +*/ +div.block-seq-container { + top: 15px; + width: 100%; + /* outline: 1px solid #00FF00; */ +} + +div.wa-sequence .dna-container { + position: absolute; + width: 100%; +} + +div.wa-sequence .dna-residues.forward-strand { + color: black; + z-index: 5; + /* outline: 1px solid pink; */ +} + +div.wa-sequence .dna-residues.reverse-strand { + color: gray; + border-top: 1px solid lightgray; + z-index: 5; + /* outline: 1px solid pink; */ +} + +div.wa-sequence .aa-residues { + color: black; + z-index: 5; +/* + box-sizing: border-box; + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + -ms-box-sizing: border-box; +*/ +/* outline: 1px solid orange; */ +} + +div.wa-sequence .aa-residues.frame0 { + background-color: #999999; + z-index: 5; +} + +div.wa-sequence .aa-residues.frame1 { + background-color: #BBBBBB; + z-index: 5; +} + +div.wa-sequence .aa-residues.frame2 { + background-color: #DDDDDD; + z-index: 5; +} + +/* highlighting of dna residues in DNA track on mouseover */ +div.wa-sequence .dna-highlighted { + background: #F9BF3A +} + +/* don't think this is currently (April 2012) being used */ +div.wa-sequence .highlighted { + background: #ff0; +} + +div.annot-sequence { + position: absolute; + left: 0px; + font-family: monospace; + font-size: 10px; + letter-spacing: 2px; + padding-left: 2px; + z-index: 15; + /* + need pointer-events:none so that any events pass through annot-sequence overlay + and onto the block or feature div underneath + */ + pointer-events: none; + + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -o-user-select: none; + user-select: none; +} + +/* +div.basic-hist { + position: absolute; + z-index: 10; +} +*/ + +/******************************************************** +* invisible containers, +* for features that also have a renderClass that gets centered, +* and for subfeatures that have rendered children +* (currently only subfeatures like this are exons, which have CDS and UTR child divs) +********************************************************/ +.container-16px, +.plus-container-16px, +.minus-container-16px { + height: 16px; + background-color: transparent; +} + +.container-14px, +.plus-container-14px, +.minus-container-14px { + height: 14px; + background-color: transparent; +} + +.container-12px, +.plus-container-12px, +.minus-container-12px { + height: 12px; + background-color: transparent; +} + +.container-10px, +.plus-container-10px, +.minus-container-10px { + height: 10px; + background-color: transparent; +} + +.container-8px, +.plus-container-8px, +.minus-container-8px { + height: 8px; + background-color: transparent; +} + +/* intended for subfeatures that have rendered children, +* want to size subfeature container to same height as parent feature +* (currently only subfeatures like this are exons, which have CDS and UTR child divs) +*/ +.container-100pct, +.plus-container-100pct, +.minus-container-100pct { + height: 100%; + background-color: transparent; +} + +.feature-render { + position: absolute; + min-width: 1px; + width: 100%; + /* feature render div may be added to feature div _after_ subfeature divs, so + if want subfeature divs in front of feature render div, make sure feature render div has lower + z-index than subfeature divs */ + z-index: 2; +} + +/** + * Basic boxes for subfeatures (and for "render-*" rendering div for features with container divs) + * height is % of parent feature, top % determined based on height to ensure vertically centered + */ +.gray-center-30pct { + background-color: gray; + height: 30%; + top: 35%; +} + + +.gray-center-50pct { + background-color: lightgray; + height: 50%; + top: 25%; +} + + +.gray-center-20pct { + position:absolute; + background-color: gray; + min-width: 1px; + width: 100%; + height: 20%; + top: 40%; + /* annotline div may be added to annot div _after_ child feature divs, so + if want child divs in front of annotline, make sure has lower + z-index than child divs */ + z-index: 2; +} + +.gray-center-10pct { + position:absolute; + background-color: gray; + min-width: 1px; + width: 100%; + height: 10%; + top: 45%; + /* annotline div may be added to annot div _after_ child feature divs, so + if want child divs in front of annotline, make sure has lower + z-index than child divs */ + z-index: 2; +} + + + + +.pink-90pct, +.plus-pink-90pct, +.minus-pink-90pct { + height: 90%; + top: 5%; + background-color: #D8BDEB; + border: 1px solid #01F; +/* border-style: solid; + border-color: #01F; + border-width: 1px; +*/ +} + +.pink-12px, +.plus-pink-12px, +.minus-pink-12px { + background-color: #D8BDEB; + border: 1px solid #01F; + height: 12px; + /* margin-top: 2px; */ /* rely on centering in code instead? */ +} + +.pink-16px, +.plus-pink-16px, +.minus-pink-16px { + background-color: #D8BDEB; + border: 1px solid #01F; + height: 16px; + /* margin-top: 2px; */ /* rely on centering in code instead? */ +} + +.purple-60pct, +.plus-purple-60pct, +.minus-purple-60pct { + background-color: #8F408F; + height: 60%; + top: 20%; +} + +.purple-8px, +.plus-purple-8px, +.minus-purple-8px { + background-color: #8F408F; + height: 8px; + /* margin-top: 4px; */ /* rely on centering in code instead? */ +} + +.darkblue-80pct, +.plus-darkblue-80pct, +.minus-darkblue-80pct { + background-color: #1F3DDE; + height: 80%; + top: 10%; +} + +.bluegreen-80pct, +.plus-bluegreen-80pct, +.minus-bluegreen-80pct { + background-color: #3BA08E; + height: 80%; + top: 10%; +} + + +.brightgreen-80pct, +.plus-brightgreen-80pct, +.minus-brightgreen-80pct { + background-color: #21D61F; + border: 1px solid #555; + height: 80%; + top: 10%; +} + +.darkgreen-60pct, +.plus-darkgreen-60pct, +.minus-darkgreen-60pct { + height: 60%; + top: 20%; + background-color: #8DB890; +} + + +/* defaults for rendering aligned read from BAM files */ +.bam-read, +.plus-bam-read, +.minus-bam-read { + height: 5px; + background-color: #AACDDC; + z-index: 8; +} + +/* testing different coloration of BAM alignments on minus strand +.minus-bam { + height: 5px; + background-color: #AA00AA; + z-index: 8; +} +*/ + +/* render match (M) spans as subfeatures of BAM alignment */ +.cigarM, +.plus-cigarM, +.minus-cigarM { + position: absolute; + height: 100%; + margin-top: 0px; + background-color: #1B8A99; + /* background-color: green; */ + z-index: 8; + min-width: 1px; + cursor: pointer; + box-sizing: border-box; + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + -ms-box-sizing: border-box; +} + +/* don't render skips, just let parent bam show through (similar to not rendering intron but letting transcript show through) +.cigarN, +.plus-cigarN, +.minus-cigarN { + position: absolute; + height: 2px; + margin-top: 0px; + background-color: #AACDDC; + z-index: 8; + min-width: 1px; + cursor: pointer; + box-sizing: border-box; + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + -ms-box-sizing: border-box; +} +*/ + + +/** container */ +.annot, +.plus-annot, +.minus-annot { + height: 16px; + background-color: transparent; + /* disabling standard text selection, so residues overlay doesn't get text selection actions */ + -moz-user-select: none; + -khtml-user-select: none; + -webkit-user-select: none; + user-select: none; +} + +.annot-render { + height: 8px; + margin-top: 4px; + background-color: #A4BBFF; +} + +.annot-CDS, +.plus-annot-CDS, +.minus-annot-CDS { + height: 16px; + /* margin-top: -6px; */ + background-color: #30AAFF; + border: 1px solid #01F; +} + +.annot-UTR, x +.plus-annot-UTR, +.minus-annot-UTR { + height: 12px; + /* margin-top: -4px; */ + margin-top: 2px; + background-color: #2088FF; +} + +.noncanonical-splice-site, +.plus-noncanonical-splice-site, +.minus-noncanonical-splice-site { + margin-left: -8px; + /* margin-top: -11px; */ + /* moved noncanonical icon to bottom of annotation, prefer top of annotation but + need to have a some padding at top of track before that works */ + margin-top: 9px; + padding-left: 8px; + padding-right: 8px; + position: absolute; + height: 16px; + z-index: 100; + background-color: transparent; + background-image: url('../img/exclamation_circle_orange.png'); + pointer-events: none; /* attempting to route around issue with centered non-canon splice sites preventing edge-drag */ +/* background-image: url('img/exclamation_circle_orange.png'); */ +/* background-image: url('img/warning_exclamation_small.png'); */ +/* background-image: url('img/warning_exclamation.png'); */ +/* background-image: url('img/marker_rounded_red.png'); */ +/* background-image: url('img/marker_squared_red.png'); */ +} + + +/* + for styles of features that are on SequenceTrack, + z-index MUST be > z-index of + (div.sequence .dna-residues.forward-strand) and + (div.sequence .dna-residues.reverse-strand) styles +*/ +.deletion, +.plus-deletion, +.minus-deletion { + border-style: solid; + border-color: blue; + border-width: 1px; + height: 100%; + background-color: rgba(150,0,0,0.3); + z-index: 20; +} + +.insertion, +.plus-insertion, +.minus-insertion { + border-style: solid; + border-color: green; + border-width: 1px; + height: 100%; + background-color: rgba(0,150,0,0.3); + z-index: 20; +} + +.substitution, +.plus-substitution, +.minus-substitution { + border-style: solid; + border-color: blue; + border-width: 1px; + height: 100%; + background-color: rgba(250,250,0,0.3); + z-index: 20; +} + +.plus-trellis-arrowhead, +.plus-webapollo-arrowhead, +.plus-annot-arrowhead { + position: absolute; + width: 12px; + height: 100%; + background-image: url('../img/plus-transcript-head.png'); + /* background-image: url('../img/plus-arrowhead-transparent.png'); */ + background-repeat: no-repeat; + background-position: left center; /* center image vertically */ + z-index: 1; +} + +.minus-trellis-arrowhead, +.minus-webapollo-arrowhead, +.minus-annot-arrowhead { + position: absolute; + width: 12px; + height: 100%; + background-image: url('../img/minus-transcript-head.png'); + background-repeat: no-repeat; + background-position: right center; /* center image vertically */ + z-index: 1; +} + +.cds-frame0 { + background-color: #FF8080; +} + +.cds-frame1 { + background-color: #80FF80; +} + +.cds-frame2 { + background-color: #8080FF; +} + +/** +* appearance of resizing box when dragging annotation edges +* if case browser doesn't support transparency via "rgba", fall back on solid background? +*/ +.ui-resizable-helper { + border: 2px dotted red; + background: rgb(100, 150, 255); + background: rgba(100, 150, 255, 0.5); + +} + +/** +* By default, no styling associated with custom multifeature draggable helper +* But leaving here for easing toggling of diagnostic rendering +*/ +.custom-multifeature-draggable-helper { +/* + outline-style: dotted; + outline-color: red; + outline-width: 4px; +*/ +} + +/** +* appearance of annotations (features in AnnoTracks) when they are drop targets and are hovered over +*/ +.annot-drop-hover { + outline-style: solid; + outline-color: green; + outline-width: 4px; +} + +/* +* overriding JQueryUI .ui-resizable style, which changes anything getting resized to "position:absolute" +* for this to work this CSS _must_ come after jquery-ui.css in load order +*/ +.ui-resizable { + position: absolute; +} + +/* style to highlight left feature edges that match selected feature(s) edges +* setting box-sizing to border-box keeps the border _inside_ the element (rather than outside) +* (-moz*, -webkit*, -ms* prefixed versions needed because box-sizing property name currently differs across browsers) +*/ +.left-edge-match { + border-left: solid red 2px; + box-sizing: border-box; + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + -ms-box-sizing: border-box; +} + +/* style to highlight right feature edges that match selected feature(s) edges +* setting box-sizing to border-box keeps the border _inside_ the element (rather than outside) +* (-moz*, -webkit*, -ms* prefixed versions needed because box-sizing property name currently differs across browsers) +*/ +.right-edge-match { + border-right: solid red 2px; + box-sizing: border-box; + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + -ms-box-sizing: border-box; +} + + +/* to make sure selection style overrides any other styles in this stylesheet, make sure to put selection style at end */ +.selected-feature { + outline-style: solid; + outline-color: red; + outline-width: 3px; +} + +.shadow { + -moz-box-shadow: 5px 5px 5px #444; + -webkit-box-shadow: 5px 5px 5px #444; + box-shadow: 5px 5px 5px #444; +} + +/* +* selection of annotations is separate from selection of features +*/ +.selected-annotation { + outline-style: solid; + outline-color: red; + outline-width: 3px; +} + +/* +* diagnostics for blocks +*/ +/* +div.block { + outline-style: solid; + outline-color: gray; + outline-width: 1px; +} +*/ + + +/* experimental canvas graph stuff +div.graph-color-picker { + border: 2px black solid; +} + +div.graph-range-slider { + height: 165px; + width: 10px; +} + +div.canvas-track-control { + left: 0px; + top: 0px; + width: 300px; + height: 250px; + padding: 10px; + z-index: 190; + background-color: white; + border: 2px black solid; +} +*/ + +/* maker background-color: rgb(255,204,204); */ +/* blastn background-color: rgb(102,204,102); */ +/* blastx background-color: rgb(0,200,204); */ +/* tblastx background-color: rgb(0,200,104); */ +/* snap background-color: rgb(153,100,204); */ +/* est2genome background-color: rgb(100,100,210); */ +/* protein2genome background-color: rgb(117,150,255); */ +/* repeatmasker background-color: red; */ +/* repeatrunner background-color: rgb(255,152,255); */ +/* default-alignment-block background-color: #C87C8E; */ +/* nvit-alignment background-color: #848DBF; */ \ No newline at end of file diff --git a/plugins/WebApollo/img/ApolloLogo_100x36.png b/plugins/WebApollo/img/ApolloLogo_100x36.png new file mode 100644 index 0000000000..aa04f4446e Binary files /dev/null and b/plugins/WebApollo/img/ApolloLogo_100x36.png differ diff --git a/plugins/WebApollo/img/exclamation_circle_orange.png b/plugins/WebApollo/img/exclamation_circle_orange.png new file mode 100644 index 0000000000..070685cbd4 Binary files /dev/null and b/plugins/WebApollo/img/exclamation_circle_orange.png differ diff --git a/plugins/WebApollo/img/loading.gif b/plugins/WebApollo/img/loading.gif new file mode 100644 index 0000000000..f2a1bc0c6f Binary files /dev/null and b/plugins/WebApollo/img/loading.gif differ diff --git a/plugins/WebApollo/img/marker_rounded_red.png b/plugins/WebApollo/img/marker_rounded_red.png new file mode 100644 index 0000000000..c8d93da7fd Binary files /dev/null and b/plugins/WebApollo/img/marker_rounded_red.png differ diff --git a/plugins/WebApollo/img/marker_squared_red.png b/plugins/WebApollo/img/marker_squared_red.png new file mode 100644 index 0000000000..ccb44045b1 Binary files /dev/null and b/plugins/WebApollo/img/marker_squared_red.png differ diff --git a/plugins/WebApollo/img/minus-transcript-head.png b/plugins/WebApollo/img/minus-transcript-head.png new file mode 100644 index 0000000000..b53c711675 Binary files /dev/null and b/plugins/WebApollo/img/minus-transcript-head.png differ diff --git a/plugins/WebApollo/img/plus-transcript-head.png b/plugins/WebApollo/img/plus-transcript-head.png new file mode 100644 index 0000000000..e76fa0d25a Binary files /dev/null and b/plugins/WebApollo/img/plus-transcript-head.png differ diff --git a/plugins/WebApollo/img/warning_exclamation.png b/plugins/WebApollo/img/warning_exclamation.png new file mode 100644 index 0000000000..3dd3b55dbe Binary files /dev/null and b/plugins/WebApollo/img/warning_exclamation.png differ diff --git a/plugins/WebApollo/img/warning_exclamation_small.png b/plugins/WebApollo/img/warning_exclamation_small.png new file mode 100644 index 0000000000..5665cd3cb6 Binary files /dev/null and b/plugins/WebApollo/img/warning_exclamation_small.png differ diff --git a/plugins/WebApollo/js/BioFeatureUtils.js b/plugins/WebApollo/js/BioFeatureUtils.js new file mode 100644 index 0000000000..4d5a5ffc1e --- /dev/null +++ b/plugins/WebApollo/js/BioFeatureUtils.js @@ -0,0 +1,59 @@ +define( ['dojo/_base/declare'], + function( declare ) { +return declare( null, { + +// returns modified parent, or null if removal of child would result in parent with empty child list +// if want to go "only creation, no destruction" route, +// could clone parent and return clone instead of original... +// assumes already populated: +// child.track +// child.parent +// child.parent.track +// +removeChild: function(child) { + // console.log("called BioFeatureUtils.removeChild"); + var parent = child.parent(); + var fields = parent.track.fields; + var subfields = parent.track.subFields; + var children = parent[fields["subfeatures"]]; + console.log(children); + var index = children.indexOf(child); + console.log(index); + if (index < 0) { + // console.log("BioFeatureUtils ERROR: child not found in parent!!"); + return parent; + } + children.splice(index, 1); + // console.log(children); + var clength = children.length; + if (children.length === 0) { + // console.log("parent has no more children"); + return null; + } + else { + // console.log("rechecking parent bounds"); + var prevmin = parent[fields["start"]]; + var prevmax = parent[fields["end"]]; + var sibling = children[0]; + var newmin = sibling[subfields["start"]]; + var newmax = sibling[subfields["end"]]; + for (var cindex = 1; cindex= 0) { + this._removeSelectionAt(index); + } + }, + + _removeSelectionAt: function( index ) { + var rec = this.selected[index]; + this.selected.splice(index, 1); + var lislength = this.listeners.length; + for (var lindex = 0; lindex= 0; + }, + + /** + * returns array of currently selected feature records { feature: feature, track: track } + * this is a (shallow) copy of the selected array, therefore a snapshot of what is selected + * as of when getSelection is called + * so if selection changes, previous value returned from getSelection will not change + */ + getSelection: function() { + // return this.selected; + // return this.selected.slice(0); // return shallow copy of array + return this.selected.slice(0, this.selected.length); // return shallow copy of array + }, + + /** + * since getSelection now returns feature records { feature: feature, track: track }, + * also want a method that returns only the feautures (not wrapped in records) + */ + getSelectedFeatures: function() { + var selfeats = new Array(this.selected.length); + for (var i=0; i= 0 ) { // only remove if already in listener list + this.listeners.splice(index, 1); + } + } +}); +}); \ No newline at end of file diff --git a/plugins/WebApollo/js/FileLoader.js b/plugins/WebApollo/js/FileLoader.js new file mode 100644 index 0000000000..c02ad2e135 --- /dev/null +++ b/plugins/WebApollo/js/FileLoader.js @@ -0,0 +1,112 @@ + +function FileLoader(parent_element, brow) { + var floader = this; + this.brow = brow; + this.initLoadDialog(); + $(parent_element).append("
"); + $("#fileLoadB").click(function(event) { FileLoader.prototype.showLoadDialog.call(floader, event); } ); +} + +FileLoader.prototype.initLoadDialog = function() { + this.loadDialog = new dijit.Dialog({title: "Load BAM or GFF3 File"}); + this.loadDialog.startup(); +} + +FileLoader.prototype.showLoadDialog = function(event) { + console.log("called FileLoader.showLoadDialog"); + var mydialog = this.loadDialog; + var floader = this; + var content = document.createElement("div"); + $(content).append("" + + "" + + "" + + "" + + "
"); + $(content).append("
"); + this.loadDialog.set("content", content); + this.loadDialog.show(); + this.loadDialog.placeAt("GenomeBrowser", "first"); + $("#file_load_cancel").click(function() { mydialog.hide() } ); + $("#file_load_ok").click(function() { FileLoader.prototype.handleFileSelect.call(floader, event); } ); +}; + +FileLoader.prototype.handleFileSelect = function(event) { + console.log("called FileLoader.handleFileSelect()"); + var bamfiles = $("#bam_file")[0].files; + var baifiles = $("#bai_file")[0].files; + var gff3files = $("#gff3_file")[0].files; + if (bamfiles && baifiles && bamfiles.length > 0 && baifiles.length > 0) { + console.log("bamfile:"); console.log(bamfiles); + console.log("baifile:"); console.log(baifiles); + var bamfile = bamfiles[0]; + var baifile = baifiles[0]; + this.loadBamFile(bamfile, baifile); + this.loadDialog.hide(); + } + else if (gff3files && gff3files.length > 0) { + console.log("trying to load GFF3 file"); + var gff3file = gff3files[0]; +// var freader = new FileReader(); +// freader.onload = loadGff3File; + + this.loadGff3File(gff3file); + this.loadDialog.hide(); + } + else { + alert("must specify both a BAM file and an BAI index file"); + } + +}; + +FileLoader.prototype.loadGff3File = function(gff3file) { + console.log("called FileLoader.loadGff3File"); + var freader = new FileReader(); + freader.onload = function(event) { + var gfftext = event.target.result; + console.log("gfftext: "); + console.log(gfftext); + var parser = new GFF3toJson(); + var gff3json = parser.parse(gfftext); + console.log("GFF3 parsed to JSON: "); + console.log(gff3json); + var converter = new GFF3toJbrowseJson(); + var gff3_nclist = converter.gff3toJbrowseJson(gff3json); + console.log("GFF3 converted to JBrowse NCList:"); + console.log(gff3_nclist); + }; + freader.readAsText(gff3file); +}; + +FileLoader.prototype.loadBamFile = function(bamfile, baifile) { // bamfile and baifile are HTML5 File objects + console.log("called FileLoader.loadBamFile()"); + var trackName = bamfile.name; + var trackInfoEntry = + { + "type" : "BamFeatureTrack", + "label" : trackName, + "key" : trackName, + "data_file" : bamfile, + "index_file" : baifile, + "autocomplete" : "none", + "style" : { + "className" : "bam", + "subfeatureClasses" : { + "M": "cigarM", + "D": "cigarD", + "N": "cigarN", + "=": "cigarEQ", + "E": "cigarEQ", + "X": "cigarX", + "I": "cigarI" + }, + "arrowheadClass" : null + }, + "compress" : 0, + "subfeatures" : 1 + }; + var gb = $("#GenomeBrowser").get(0).genomeBrowser; + // gb.trackCreate(trackInfoEntry); + gb.viewDndWidget.insertNodes(false, [trackInfoEntry]); + gb.onVisibleTracksChanged(); +}; + diff --git a/plugins/WebApollo/js/GFF3toJbrowseJson.js b/plugins/WebApollo/js/GFF3toJbrowseJson.js new file mode 100644 index 0000000000..58a28b548b --- /dev/null +++ b/plugins/WebApollo/js/GFF3toJbrowseJson.js @@ -0,0 +1,88 @@ +define([ 'dojo/_base/declare', + 'dojo/_base/array', + 'JBrowse/Browser', + 'JBrowse/Util', + 'JBrowse/Model/SimpleFeature', + 'WebApollo/JSONUtils', + 'WebApollo/Store/SeqFeature/ScratchPad' + ], + function( declare, array, Browser, Util, SimpleFeature, JSONUtils, ScratchPad ) { + +// Created by Justin Reese 9/2012 +// justaddcoffee@gmail.com +// +//After +//Alekseyenko, A., and Lee, C. (2007). +//Nested Containment List (NCList): A new algorithm for accelerating +// interval query of genome alignment and interval databases. +//Bioinformatics, doi:10.1093/bioinformatics/btl647 +//http://bioinformatics.oxfordjournals.org/cgi/content/abstract/btl647v1 + +// This code takes a data structure such as that returned by GFF3toJson.js +// and makes it into an jbrowse-style json with a nested containment list +// (NClist) suitable for use in WebApollo and possibly Jbrowse. + +function GFF3toJbrowseJson() { +}; + +GFF3toJbrowseJson.prototype.gff3toJbrowseJson = function(parsedGFF3, params) { + this.params = params; + var trackInfo = {}; + trackInfo["intervals"] = {}; + + trackInfo["histograms"] = {"stats" : [ {"basesPerBin" : "1000000","max" : 1,"mean" : 1} ],"meta" : [ { "basesPerBin" : "1000000", "arrayParams" : { "length" : 1, "chunkSize" : 10000, "urlTemplate" : "hist-1000000-{Chunk}.json"}}]}; + + trackInfo["intervals"]["classes"] = + [ { + "isArrayAttr" : { + "Subfeatures" : 1 + }, + "attributes" : [ "Start", "End", "Strand", "Source", "Phase", "Type", "Score", "Id", "Name", "Subfeatures" ] + }, { + "isArrayAttr" : { + }, + "attributes" : [ "Start", "End", "Strand", "Source", "Phase", "Type", "Score", "Id", "Name", "Subfeatures" ] + }, { + "isArrayAttr" : { + "Sublist" : 1 + }, + "attributes" : [ "Start", "End", "Chunk" ] + } ]; + + trackInfo["intervals"]["lazyClass"] = 2; + trackInfo["intervals"]["urlTemplate"] = "lf-{Chunk}.json"; + trackInfo["formatVersion"] = 1; + + var featureCount = 0; + + // first check if we have only one feature, in which case parsedData is an object not an array + if ( typeof(parsedGFF3.parsedData.length) == 'undefined' ){ + trackInfo["featureCount"] = 1; + } + else { + trackInfo["featureCount"] = parsedGFF3.parsedData.length; + } + + // loop through each top level feature in parsedGFF3 and make array of featureArrays + // jsonUtilObj.convertParsedGFF3JsonToFeatureArray( parsedGFF3 ); + var allGff3Features = new Array; // this is an array of featureArrays containing info for all features in parsedGFF3 + var jsonUtilObj = new JSONUtils; + + // see if there's only one feature, in which case parsedData is an object, not an array with one object (strangely) + if ( !parsedGFF3.parsedData.length ){ + allGff3Features.push( jsonUtilObj.convertParsedGFF3JsonToFeatureArray( parsedGFF3 ) ); + } else { // >1 feature in parsedData, loop through and push each onto allGff3Features + for( var k = 0; k < parsedGFF3.parsedData.length; k++ ){ + var jbrowseFeat = jsonUtilObj.convertParsedGFF3JsonToFeatureArray( parsedGFF3.parsedData[k] ); + if (jbrowseFeat) { + allGff3Features.push( jbrowseFeat ); + } + } + } + + return { trackInfo: trackInfo, featArray: allGff3Features } +}; + +return GFF3toJbrowseJson; + +} ); \ No newline at end of file diff --git a/plugins/WebApollo/js/JSONUtils.js b/plugins/WebApollo/js/JSONUtils.js new file mode 100644 index 0000000000..6005b1e797 --- /dev/null +++ b/plugins/WebApollo/js/JSONUtils.js @@ -0,0 +1,294 @@ +define([ 'dojo/_base/declare', + 'dojo/_base/array', + 'JBrowse/Util', + 'JBrowse/Model/SimpleFeature', + 'WebApollo/SequenceOntologyUtils' + ], + function( declare, array, Util, SimpleFeature, SeqOnto ) { + +function JSONUtils() { +} + +JSONUtils.verbose_conversion = false; + +/** +* creates a feature in JBrowse JSON format +* takes as arguments: +* afeature: feature in ApolloEditorService JSON format, +* arep: ArrayRepr for kind of JBrowse feature to output +* OLD: fields: array specifying order of fields for JBrowse feature +* OLD: subfields: array specifying order of fields for subfeatures of JBrowse feature +* "CDS" type feature in Apollo JSON format is from genomic start of translation to genomic end of translation, +* (+ stop codon), regardless of intons, so one per transcript (usually) +* "CDS" type feature in JBrowse JSON format is a CDS _segment_, which are piecewise and broken up by introns +* therefore commonyly have multiple CDS segments +* +*/ +// JSONUtils.createJBrowseFeature = function(afeature, fields, subfields) { +var JAFeature = declare( SimpleFeature, { + "-chains-": { + constructor: "manual" + }, + constructor: function( afeature, parent ) { + this.afeature = afeature; + if (parent) { this._parent = parent; } + + // get the main data + var loc = afeature.location; + var pfeat = this; + this.data = { + start: loc.fmin, + end: loc.fmax, + strand: loc.strand, + name: afeature.name, + parent_id: afeature.parent_id, + type: afeature.type.name, + properties: afeature.properties + }; + + if (this.data.type === "CDS") { + this.data.type = "wholeCDS"; + } + + this._uniqueID = afeature.uniquename; + + // this doesn't work, since can be multiple properties with same CV term (comments, for example) + // could create arrray for each flattened cv-name for multiple values, but not sure what the point would be over + // just making sure can access via get('properties') via above assignment into data object + // parse the props +/* var props = afeature.properties; + dojo.forEach( props, function( p ) { + var pn = p.type.cv.name+':'+p.type.name; + this.data[pn] = p.value; + }, this); +*/ + + if (afeature.properties) { + for (var i = 0; i < afeature.properties.length; ++i) { + var property = afeature.properties[i]; + if (property.type.name == "comment" && property.value == "Manually set translation start") { + // jfeature.manuallySetTranslationStart = true; + this.data.manuallySetTranslationStart = true; // so can call feat.get('manuallySetTranslationStart') + if (this.parent()) { parent.data.manuallySetTranslationStart = true; } + } + } + } + + // moved subfeature assignment to bottom of feature construction, since subfeatures may need to call method on their parent + // only thing subfeature constructor won't have access to is parent.data.subfeatures + // get the subfeatures + this.data.subfeatures = array.map( afeature.children, function(s) { + return new JAFeature( s, pfeat); + } ); + + } +}); + +JSONUtils.JAFeature = JAFeature; + +JSONUtils.createJBrowseFeature = function( afeature ) { + return new JAFeature( afeature ); +}; + + +/** + * takes any JBrowse feature, returns a SimpleFeature "copy", + * for which all properties returned by tags() are mutable (has set() method) + * needed since JBrowse features no longer necessarily mutable + * feature requirements: + * functions: id, parent, tags, get + * if subfeatures, then returned as array by feature.get('subfeatures') + * + */ +JSONUtils.makeSimpleFeature = function(feature, parent) { + var result = new SimpleFeature({id: feature.id(), parent: (parent ? parent : feature.parent()) }); + var ftags = feature.tags(); + for (var tindex = 0; tindex < ftags.length; tindex++) { + var tag = ftags[tindex]; + // forcing lower case, since still having case issues with NCList features + result.set(tag.toLowerCase(), feature.get(tag.toLowerCase())); + } + var subfeats = feature.get('subfeatures'); + if (subfeats && (subfeats.length > 0)) { + var simple_subfeats = []; + for (var sindex = 0; sindex < subfeats.length; sindex++) { + var simple_subfeat = JSONUtils.makeSimpleFeature(subfeats[sindex], result); + simple_subfeats.push(simple_subfeat); + } + result.set('subfeatures', simple_subfeats); + } + return result; +}; + +/** +* creates a sequence alteration in JBrowse JSON format +* takes as arguments: +* arep: ArrayRepr for kind of JBrowse feature to output +* afeature: sequence alteration in ApolloEditorService JSON format, +*/ +JSONUtils.createJBrowseSequenceAlteration = function( afeature ) { + var loc = afeature.location; + var uid = afeature.uniquename; + + return new SimpleFeature({ + data: { + start: loc.fmin, + end: loc.fmax, + strand: loc.strand, + id: uid, + type: afeature.type.name, + residues: afeature.residues, + seq: afeature.residues + }, + id: uid + }); +}; + + +/** +* creates a feature in ApolloEditorService JSON format +* takes as argument: +* jfeature: a feature in JBrowse JSON format, +* fields: array specifying order of fields in jfeature +* subfields: array specifying order of fields in subfeatures of jfeature +* specified_type (optional): type passed in that overrides type info for jfeature +* ApolloEditorService format: +* { +* "location" : { "fmin": fmin, "fmax": fmax, "strand": strand }, +* "type": { "cv": { "name":, cv }, // typical cv name: "SO" (Sequence Ontology) +* "name": cvterm }, // typical name: "transcript" +* "children": { __recursive ApolloEditorService feature__ } +* } +* +* For ApolloEditorService "add_feature" call to work, need to have "gene" as toplevel feature, +* then "transcript", then ??? +* +* JBrowse JSON fields example: ["start", "end", "strand", "id", "subfeatures"] +* +* type handling +* if specified_type arg present, it determines type name +* else if fields has a "type" field, use that to determine type name +* else don't include type +* +* ignoring JBrowse ID / name fields for now +* currently, for features with lazy-loaded children, ignores children +*/ +JSONUtils.createApolloFeature = function( jfeature, specified_type ) { + + var diagnose = (JSONUtils.verbose_conversion && jfeature.children() && jfeature.children().length > 0); + if (diagnose) { + console.log("converting JBrowse feature to Apollo feture, specified type: " + specified_type); + console.log(jfeature); + } + + var afeature = new Object(); + var astrand; + // Apollo feature strand must be an integer + // either 1 (plus strand), -1 (minus strand), or 0? (not stranded or strand is unknown?) + switch (jfeature.get('strand')) { // strand + case 1: + case '+': + astrand = 1; break; + case -1: + case '-': + astrand = -1; break; + default: + astrand = 0; // either not stranded or strand is uknown + } + + afeature.location = { + "fmin": jfeature.get('start'), + "fmax": jfeature.get('end'), + "strand": astrand + }; + + var typename; + if (specified_type) { + typename = specified_type; + } + else if ( jfeature.get('type') ) { + typename = jfeature.get('type'); + } + + if (typename) { + afeature.type = { + "cv": { + "name": "sequence" + } + }; + afeature.type.name = typename; + } + + if (diagnose) { console.log("converting to Apollo feature: " + typename); } + var subfeats; + // use filteredsubs if present instead of subfeats? + // if (jfeature.filteredsubs) { subfeats = jfeature.filteredsubs; } + // else { subfeats = jfeature.get('subfeatures'); } + subfeats = jfeature.get('subfeatures'); + if( subfeats && subfeats.length ) { + afeature.children = []; + var slength = subfeats.length; + for (var i=0; i"}, content); + var headerDiv = dojo.create("div", { className: "search_sequence_matches_header" }, content); + dojo.create("span", { innerHTML: "ID", className: "search_sequence_matches_header_field search_sequence_matches_generic_field" }, headerDiv); + dojo.create("span", { innerHTML: "Start", className: "search_sequence_matches_header_field search_sequence_matches_generic_field" }, headerDiv); + dojo.create("span", { innerHTML: "End", className: "search_sequence_matches_header_field search_sequence_matches_generic_field" }, headerDiv); + dojo.create("span", { innerHTML: "Score", className: "search_sequence_matches_header_field search_sequence_matches_generic_field" }, headerDiv); + dojo.create("span", { innerHTML: "Significance", className: "search_sequence_matches_header_field search_sequence_matches_generic_field" }, headerDiv); + dojo.create("span", { innerHTML: "Identity", className: "search_sequence_matches_header_field search_sequence_matches_generic_field" }, headerDiv); + var matchDiv = dojo.create("div", { className: "search_sequence_matches" }, content); + var matches = dojo.create("div", { }, matchDiv); + + dojo.style(messageDiv, { display: "none" }); + dojo.style(matchDiv, { display: "none" }); + dojo.style(headerDiv, { display: "none" }); + dojo.style(waitingDiv, { display: "none" }); + if (!refSeqName) { + dojo.style(searchAllRefSeqsDiv, { display: "none" }); + } + + var getSequenceSearchTools = function() { + var ok = false; + var operation = "get_sequence_search_tools"; + dojo.xhrPost( { + postData: '{ "track": "' + trackName + '", "operation": "' + operation + '" }', + url: contextPath + "/AnnotationEditorService", + sync: true, + handleAs: "json", + timeout: 5000 * 1000, // Time in milliseconds + load: function(response, ioArgs) { + if (response.sequence_search_tools.length == 0) { + ok = false; + return; + } + for (var i = 0; i < response.sequence_search_tools.length; ++i) { + dojo.create("option", { innerHTML: response.sequence_search_tools[i] }, sequenceToolsSelect); + } + ok = true; + }, + error: function(response, ioArgs) { + errorCallback(response); + return response; + } + }); + return ok; + }; + + var search = function() { + var residues = dojo.attr(sequenceField, "value").toUpperCase(); + var ok = true; + if (residues.length == 0) { + alert("No sequence entered"); + ok = false; + } + else if (residues.match(/[^ACDEFGHIKLMNPQRSTVWXY\n]/)) { + alert("The sequence should only contain non redundant IUPAC nucleotide or amino acid codes (except for N/X)"); + ok = false; + } + var searchAllRefSeqs = dojo.attr(searchAllRefSeqsCheckbox, "checked"); + if (ok) { + dojo.style(waitingDiv, { display: "block"} ); + dojo.style(matchDiv, { display: "none"} ); + dojo.style(headerDiv, { display: "none" }); + dojo.xhrPost( { + postData: '{ "track": "' + trackName + '", "search": { "key": "' + sequenceToolsSelect.value + '", "residues": "' + residues + (!searchAllRefSeqs && refSeqName != null ? '", "database_id": "' + refSeqName : '') + '"}, "operation": "' + operation + '" }', + url: contextPath + "/AnnotationEditorService", + handleAs: "json", + timeout: 5000 * 1000, // Time in milliseconds + load: function(response, ioArgs) { + dojo.style(waitingDiv, { display: "none"} ); + while (matches.hasChildNodes()) { + matches.removeChild(matches.lastChild); + } + if (response.matches.length == 0) { + dojo.style(messageDiv, { display: "block" }); + dojo.style(matchDiv, { display: "none" }); + dojo.style(headerDiv, { display: "none" }); + return; + } + dojo.style(messageDiv, { display: "none" }); + dojo.style(headerDiv, { display: "block"} ); + dojo.style(matchDiv, { display: "block"} ); + + var returnedMatches = response.matches; + returnedMatches.sort(function(match1, match2) { + return match2.rawscore - match1.rawscore; + }); + var maxNumberOfHits = 100; + + for (var i = 0; i < returnedMatches.length && i < maxNumberOfHits; ++i) { + var match = returnedMatches[i]; + var query = match.query; + var subject = match.subject; + var refSeqStart = starts[subject.feature.uniquename] || 0; + var refSeqEnd = starts[subject.feature.uniquename] || 0; + subject.location.fmin += refSeqStart; + subject.location.fmax += refSeqStart; + var subjectStart = subject.location.fmin + 1; + var subjectEnd = subject.location.fmax + 1; + if (subject.location.strand == -1) { + var tmp = subjectStart; + subjectStart = subjectEnd; + subjectEnd = tmp; + } + var rawscore = match.rawscore; + var significance = match.significance; + var identity = match.identity; + var row = dojo.create("div", { className: "search_sequence_matches_row" + (dojo.isFF ? " search_sequence_matches_row-firefox" : "") }, matches); + var subjectIdColumn = dojo.create("span", { innerHTML: subject.feature.uniquename, className: "search_sequence_matches_field search_sequence_matches_generic_field", title: subject.feature.uniquename }, row); + var subjectStartColumn = dojo.create("span", { innerHTML: subjectStart, className: "search_sequence_matches_field search_sequence_matches_generic_field" }, row); + var subjectEndColumn = dojo.create("span", { innerHTML: subjectEnd, className: "search_sequence_matches_field search_sequence_matches_generic_field" }, row); + var scoreColumn = dojo.create("span", { innerHTML: match.rawscore, className: "search_sequence_matches_field search_sequence_matches_generic_field" }, row); + var significanceColumn = dojo.create("span", { innerHTML: match.significance, className: "search_sequence_matches_field search_sequence_matches_generic_field" }, row); + var identityColumn = dojo.create("span", { innerHTML : match.identity, className: "search_sequence_matches_field search_sequence_matches_generic_field" }, row); + dojo.connect(row, "onclick", function(id, fmin, fmax) { + return function() { + redirectCallback(id, fmin, fmax); + }; + }(subject.feature.uniquename, subject.location.fmin, subject.location.fmax)); + } + }, + // The ERROR function will be called in an error case. + error: function(response, ioArgs) { // + errorCallback(response); + return response; + } + + }); + } + }; + + dojo.connect(sequenceField, "onkeypress", function(event) { + if (event.keyCode == dojo.keys.ENTER) { + event.preventDefault(); + search(); + } + }); + dojo.connect(sequenceButton, "onclick", search); + dojo.connect(searchAllRefSeqsLabel, "onclick", function() { + dojo.attr(searchAllRefSeqsCheckbox, "checked", !searchAllRefSeqsCheckbox.checked); + }); + + if (!getSequenceSearchTools()) { + alert("No search plugins setup"); + return null; + } + + return content; +}; + + /* console.log("at end of SequenceSearch returned function"); + console.log(window); + console.log(SequenceSearch); + console.log(new SequenceSearch(".")); + window.SequenceSearch = SequenceSearch; + */ + return SequenceSearch; + } ); + +console.log("at end of SequenceSearch.js (outside of define)"); \ No newline at end of file diff --git a/plugins/WebApollo/js/Store/SeqFeature/PseudoNCList.js b/plugins/WebApollo/js/Store/SeqFeature/PseudoNCList.js new file mode 100644 index 0000000000..5af85286aa --- /dev/null +++ b/plugins/WebApollo/js/Store/SeqFeature/PseudoNCList.js @@ -0,0 +1,22 @@ +/** +* notes on PseudoNCList needed for porting Trellis data loading to jbrowse_1.7 branch +* mostly need to override ID assignment based on position in NCList, +* and replace with unique IDs already present in feature arrays +* +* inherit from jbrowse Store/NCList, but override: + +_decorate_feature: function(accessors, feature, id, parent) { + feature.get = accessors.get; + if (config.uniqueIdField) { + otherid = feature.get(uniqueIdField) + } + var uid; + if (otherid) { uid = otherid; } + else { uid = id; } + this.inherited( accessors, feature, uid, parent ); +} + + +*/ + + diff --git a/plugins/WebApollo/js/Store/SeqFeature/ScratchPad.js b/plugins/WebApollo/js/Store/SeqFeature/ScratchPad.js new file mode 100644 index 0000000000..0dd5a9c91c --- /dev/null +++ b/plugins/WebApollo/js/Store/SeqFeature/ScratchPad.js @@ -0,0 +1,96 @@ +define( ['dojo/_base/declare', + 'JBrowse/Store/SeqFeature' + ], + function( declare, SeqFeatureStore ) { + +// return declare( "testScratchPadClass", SeqFeatureStore, +return declare( SeqFeatureStore, +{ + constructor: function( args ) { + this.features = {}; + this.sorted_feats = []; + this._calculateStats(); + }, + + insert: function( feature ) { + this.features[ feature.id() ] = feature; +// this._sort(); + this._calculateStats(); + }, + + replace: function( feature ) { + this.features[ feature.id() ] = feature; +// this._sort(); + this._calculateStats(); + }, + +/* _sort: function() { + sorted_feats.sort(function(a, b) { + var astart = a.get('start'); + var bstart = b.get('start'); + if (astart != bstart) { + return astart - bstart; + } + else { + return b.get('end') - a.get('end'); + } + } ); + }, +*/ + +/* + delete: function( feature ) { + this.deleteFeatureById[ feature.id() ]; + }, +*/ + + deleteFeatureById: function( id ) { + delete this.features[ id ]; + this._calculateStats(); + }, + + + /* if feature with given id is present in store, return it. Otherwise return null */ + getFeatureById: function( id ) { + return this.features[ id ]; + }, + + _calculateStats: function() { + var minStart = Infinity; + var maxEnd = -Infinity; + var featureCount = 0; + for( var id in this.features ) { + var f = this.features[id]; + var s = f.get('start'); + var e = f.get('end'); + if( s < minStart ) + minStart = s; + + if( e > maxEnd ) + maxEnd = e; + + featureCount++; + } + + this.globalStats = { + featureDensity: featureCount/(maxEnd-minStart+1), + featureCount: featureCount, + minStart: minStart, + maxEnd: maxEnd, + span: (maxEnd-minStart+1) + }; + }, + + getFeatures: function( query, featCallback, endCallback, errorCallback ) { + var start = query.start; + var end = query.end; + for( var id in this.features ) { + var f = this.features[id]; + if(! ( f.get('end') < start || f.get('start') > end ) ) { + featCallback( f ); + } + } + if (endCallback) { endCallback() } + } +}); +}); \ No newline at end of file diff --git a/plugins/WebApollo/js/View/Track/AnnotSequenceTrack.js b/plugins/WebApollo/js/View/Track/AnnotSequenceTrack.js new file mode 100644 index 0000000000..23120a4240 --- /dev/null +++ b/plugins/WebApollo/js/View/Track/AnnotSequenceTrack.js @@ -0,0 +1,18 @@ +define( [ + 'dojo/_base/declare', + 'WebApollo/View/Track/SequenceTrack', +], + function( declare, SequenceTrack) { + +var AnnotSequenceTrack = declare( SequenceTrack, +{ + // AnnotSequenceTrack is just a stub for now, all functionality is in SequenceTrack superclass + // intent is to eventually move sequence alteration functionality out of SequenceTrack and into AnnotSequenceTrack subclass + constructor: function(args) { } + // , test: function() { console.log("called AnnotSequenceTrack.test"); } +}); + +return AnnotSequenceTrack; + +}); + diff --git a/plugins/WebApollo/js/View/Track/AnnotTrack.js b/plugins/WebApollo/js/View/Track/AnnotTrack.js new file mode 100644 index 0000000000..9842aa1713 --- /dev/null +++ b/plugins/WebApollo/js/View/Track/AnnotTrack.js @@ -0,0 +1,2695 @@ +define( [ + 'dojo/_base/declare', + 'jquery', + 'jqueryui/draggable', + 'jqueryui/droppable', + 'jqueryui/resizable', + 'dijit/Menu', + 'dijit/MenuItem', + 'dijit/MenuSeparator', + 'dijit/PopupMenuItem', + 'dijit/form/DropDownButton', + 'dijit/DropDownMenu', + + 'dijit/Dialog', + 'dojox/grid/DataGrid', + 'dojo/data/ItemFileWriteStore', + 'WebApollo/View/Track/DraggableHTMLFeatures', + 'WebApollo/FeatureSelectionManager', + 'WebApollo/JSONUtils', + 'WebApollo/BioFeatureUtils', + 'WebApollo/Permission', + 'WebApollo/SequenceSearch', + 'JBrowse/Model/SimpleFeature', + 'JBrowse/Util', + 'JBrowse/View/GranularRectLayout', + ], + function( declare, $, draggable, droppable, resizable, + dijitMenu, dijitMenuItem, dijitMenuSeparator , dijitPopupMenuItem, dijitDropDownButton, dijitDropDownMenu, + dijitDialog, dojoxDataGrid, dojoItemFileWriteStore, + DraggableFeatureTrack, FeatureSelectionManager, JSONUtils, BioFeatureUtils, Permission, SequenceSearch, + SimpleFeature, Util, Layout ) { + +//var listeners = []; +//var listener; + +/** + * WARNING + * Requires + * server support for Servlet 3.0 comet-style long-polling, + * AnnotationChangeNotificationService web app properly set up for async + * Otherwise will cause server-breaking errors + */ + +var creation_count = 0; + +var annot_context_menu; +var contextMenuItems; + +var context_path = ".."; + +var non_annot_context_menu; + +var AnnotTrack = declare( DraggableFeatureTrack, +{ + constructor: function( args ) { + //function AnnotTrack(trackMeta, url, refSeq, browserParams) { + this.isWebApolloAnnotTrack = true; + //trackMeta: object with: + // key: display text track name + // label: internal track name (no spaces, odd characters) + // sourceUrl: replaces previous url arg to FetureTrack constructors + //refSeq: object with: + // start: refseq start + // end: refseq end + //browserParams: object with: + // changeCallback: function to call once JSON is loaded + // trackPadding: distance in px between tracks + // baseUrl: base URL for the URL in trackMeta + this.has_custom_context_menu = true; + + this.selectionManager = this.setSelectionManager( this.webapollo.annotSelectionManager ); + + this.selectionClass = "selected-annotation"; + this.annot_under_mouse = null; + + /** + * only show residues overlay if "pointer-events" CSS property is supported + * (otherwise will interfere with passing of events to features beneath the overlay) + */ + this.useResiduesOverlay = 'pointerEvents' in document.body.style; + this.FADEIN_RESIDUES = false; + + /** + * map keeping track of set of y positions for top-level feature divs of selected features + * (for better residue-overlay to be implemented TBD) + */ + // this.selectionYPosition = null; + + var thisObj = this; + /* + this.subfeatureCallback = function(i, val, param) { + thisObj.renderSubfeature(param.feature, param.featDiv, val); + }; + */ + // define fields meta data + // this.fields = AnnotTrack.fields; + this.comet_working = true; + // this.remote_edit_working = false; + + this.annotMouseDown = function(event) { + thisObj.onAnnotMouseDown(event); + }; + + this.verbose_create = false; + this.verbose_add = false; + this.verbose_delete = false; + this.verbose_drop = true; + this.verbose_click = false; + this.verbose_resize = false; + this.verbose_mousedown = false; + this.verbose_mouseenter = false; + this.verbose_mouseleave = false; + this.verbose_render = false; + + var track = this; + + dojo.addOnUnload(this, function() { + /* + var track = this; + if( listeners[track.getUniqueTrackName()] ) { + if( listeners[track.getUniqueTrackName()].fired == -1 ) { + console.log("calling listener.cancel(), via addOnUnload setup"); + listeners[track.getUniqueTrackName()].cancel(); + } + } + */ + }); + + this.gview.browser.subscribe("/jbrowse/v1/n/navigate", dojo.hitch(this, function(currRegion) { + if (currRegion.ref != this.refSeq.name) { + if (this.listener && this.listener.fired == -1 ) { + this.listener.cancel(); + } + } + })); + + }, + + _defaultConfig: function() { + var thisConfig = this.inherited(arguments); + // nulling out menuTemplate to suppress default JBrowse feature contextual menu + thisConfig.menuTemplate = null; + thisConfig.noExport = true; // turn off default "Save track data" " + thisConfig.style.centerChildrenVertically = false; + return thisConfig; + /* start of alternative to nulling out JBrowse feature contextual menu, instead attempt to merge in AnnotTrack-specific menu items + var superConfig = this.inherited(arguments); + var track = this; + var superMenuTemplate = superConfig.menuTemplate; + var thisConfig = Util.deepUpdate( + // dojo.clone( this.inherited(arguments) ), + dojo.clone( superConfig ), + { + menuTemplate: [ + { + label: "Delete", + action: function() { track.deleteSelectedFeatures(); } + } + ] + } + ); + var thisMenuTemplate = thisConfig.menuTemplate; + for (var i=0; i 20) { + // feature.short_id = uniqueId; + // } + var track = this; + var featDiv = this.inherited( arguments ); + + if (featDiv && featDiv != null) { + annot_context_menu.bindDomNode(featDiv); + $(featDiv).droppable( { + accept: ".selected-feature", // only accept draggables that are selected feature divs + tolerance: "pointer", + hoverClass: "annot-drop-hover", + over: function(event, ui) { + track.annot_under_mouse = event.target; + }, + out: function(event, ui) { + track.annot_under_mouse = null; + }, + drop: function(event, ui) { + // ideally in the drop() on annot div is where would handle adding feature(s) to annot, + // but JQueryUI droppable doesn't actually call drop unless draggable helper div is actually + // over the droppable -- even if tolerance is set to pointer + // tolerance=pointer will trigger hover styling when over droppable, + // as well as call to over method (and out when leave droppable) + // BUT location of pointer still does not influence actual dropping and drop() call + // therefore getting around this by handling hover styling here based on pointer over annot, + // but drop-to-add part is handled by whole-track droppable, and uses annot_under_mouse + // tracking variable to determine if drop was actually on top of an annot instead of + // track whitespace + if (track.verbose_drop) { + console.log("dropped feature on annot:"); + console.log(featDiv); + } + } + } ); + } + return featDiv; + }, + + renderSubfeature: function( feature, featDiv, subfeature, + displayStart, displayEnd, block) { + var subdiv = this.inherited( arguments ); + + /** + * setting up annotation resizing via pulling of left/right edges + * but if subfeature is not selectable, do not bind mouse down + */ + if (subdiv && subdiv != null && (! this.selectionManager.unselectableTypes[subfeature.get('type')]) ) { + $(subdiv).bind("mousedown", this.annotMouseDown); + } + return subdiv; + }, + + /** + * get the GenomeView's sequence track -- maybe move this to GenomeView? + * WebApollo assumes there is only one SequenceTrack + * if there are multiple SequenceTracks, getSequenceTrack returns first one found + * iterating through tracks list + */ + getSequenceTrack: function() { + if (this.seqTrack) { + return this.seqTrack; + } + else { + var tracks = this.gview.tracks; + for (var i = 0; i < tracks.length; i++) { +// if (tracks[i] instanceof SequenceTrack) { +// if (tracks[i].config.type == "WebApollo/View/Track/AnnotSequenceTrack") { + if (tracks[i].isWebApolloSequenceTrack) { + this.seqTrack = tracks[i]; + console.log("found WebApollo sequence track: ", this.seqTrack); + // tracks[i].setAnnotTrack(this); + break; + } + } + } + return this.seqTrack; + }, + + onFeatureMouseDown: function(event) { + + // _not_ calling DraggableFeatureTrack.prototyp.onFeatureMouseDown -- + // don't want to allow dragging (at least not yet) + // event.stopPropagation(); + this.last_mousedown_event = event; + var ftrack = this; + if (ftrack.verbose_selection || ftrack.verbose_drag) { + console.log("AnnotTrack.onFeatureMouseDown called, genome coord: " + this.getGenomeCoord(event)); + } + + // checking for whether this is part of drag setup retrigger of mousedown -- + // if so then don't do selection or re-setup draggability) + // this keeps selection from getting confused, + // and keeps trigger(event) in draggable setup from causing infinite recursion + // in event handling calls to featMouseDown + /* if (ftrack.drag_create) { + if (ftrack.verbose_selection || ftrack.verbose_drag) { + console.log("DFT.featMouseDown re-triggered event for drag initiation, drag_create: " + ftrack.drag_create); + console.log(ftrack); + } + ftrack.drag_create = null; + } + else { + this.handleFeatureSelection(event); + // this.handleFeatureDragSetup(event); + } + */ + this.handleFeatureSelection(event); + }, + + /** + * handles mouse down on an annotation subfeature + * to make the annotation resizable by pulling the left/right edges + */ + onAnnotMouseDown: function(event) { + var track = this; + // track.last_mousedown_event = event; + var verbose_resize = track.verbose_resize; + if (verbose_resize || track.verbose_mousedown) { console.log("AnnotTrack.onAnnotMouseDown called"); } + event = event || window.event; + var elem = (event.currentTarget || event.srcElement); + // need to redo getLowestFeatureDiv + // var featdiv = DraggableFeatureTrack.prototype.getLowestFeatureDiv(elem); + var featdiv = track.getLowestFeatureDiv(elem); + + if (featdiv && (featdiv != null)) { + if (dojo.hasClass(featdiv, "ui-resizable")) { + if (verbose_resize) { + console.log("already resizable"); + console.log(featdiv); + } + } + else { + if (verbose_resize) { + console.log("making annotation resizable"); + console.log(featdiv); + } + var scale = track.gview.bpToPx(1); + + // if zoomed int to showing sequence residues, then make edge-dragging snap to interbase pixels + var gridvals; + if (scale === track.gview.charWidth) { gridvals = [track.gview.charWidth, 1]; } + else { gridvals = false; } + + $(featdiv).resizable( { + handles: "e, w", + helper: "ui-resizable-helper", + autohide: false, + grid: gridvals, + + stop: function(event, ui) { + if( verbose_resize ) { + console.log("resizable.stop() called, event:"); + console.dir(event); + console.log("ui:"); + console.dir(ui); + } + var gview = track.gview; + var oldPos = ui.originalPosition; + var newPos = ui.position; + var oldSize = ui.originalSize; + var newSize = ui.size; + var leftDeltaPixels = newPos.left - oldPos.left; + var leftDeltaBases = Math.round(gview.pxToBp(leftDeltaPixels)); + var oldRightEdge = oldPos.left + oldSize.width; + var newRightEdge = newPos.left + newSize.width; + var rightDeltaPixels = newRightEdge - oldRightEdge; + var rightDeltaBases = Math.round(gview.pxToBp(rightDeltaPixels)); + if (verbose_resize) { + console.log("left edge delta pixels: " + leftDeltaPixels); + console.log("left edge delta bases: " + leftDeltaBases); + console.log("right edge delta pixels: " + rightDeltaPixels); + console.log("right edge delta bases: " + rightDeltaBases); + } + var subfeat = ui.originalElement[0].subfeature; + console.log(subfeat); + + var fmin = subfeat.get('start') + leftDeltaBases; + var fmax = subfeat.get('end') + rightDeltaBases; + // var fmin = subfeat[track.subFields["start"]] + leftDeltaBases; + // var fmax = subfeat[track.subFields["end"]] + rightDeltaBases; + var postData = '{ "track": "' + track.getUniqueTrackName() + '", "features": [ { "uniquename": ' + subfeat.id() + ', "location": { "fmin": ' + fmin + ', "fmax": ' + fmax + ' } } ], "operation": "set_exon_boundaries" }'; + track.executeUpdateOperation(postData); + console.log(subfeat); + // track.hideAll(); shouldn't need to call hideAll() before changed() anymore + track.changed(); + } + } ); + } + } + event.stopPropagation(); + }, + + /** + * feature click no-op (to override FeatureTrack.onFeatureClick, which conflicts with mouse-down selection + */ + onFeatureClick: function(event) { + + if (this.verbose_click) { console.log("in AnnotTrack.onFeatureClick"); } + event = event || window.event; + var elem = (event.currentTarget || event.srcElement); + var featdiv = this.getLowestFeatureDiv( elem ); + if (featdiv && (featdiv != null)) { + if (this.verbose_click) { console.log(featdiv); } + } + // do nothing + // event.stopPropagation(); + }, + + /* feature_records ==> { feature: the_feature, track: track_feature_is_from } */ + addToAnnotation: function(annot, feature_records) { + var target_track = this; + + var subfeats = []; + var allSameStrand = 1; + for (var i = 0; i < feature_records.length; ++i) { + var feature_record = feature_records[i]; + var original_feat = feature_record.feature; + var feat = JSONUtils.makeSimpleFeature( original_feat ); + var isSubfeature = !! feat.parent(); // !! is shorthand for returning true if value is defined and non-null + var annotStrand = annot.get('strand'); + if (isSubfeature) { + var featStrand = feat.get('strand'); + var featToAdd = feat; + if (featStrand != annotStrand) { + allSameStrand = 0; + featToAdd.set('strand', annotStrand); + } + subfeats.push(featToAdd); + } + else { // top-level feature + var source_track = feature_record.track; + var subs = feat.get('subfeatures'); + if ( subs && subs.length > 0 ) { // top-level feature with subfeatures + for (var i = 0; i < subs.length; ++i) { + var subfeat = subs[i]; + var featStrand = subfeat.get('strand'); + var featToAdd = subfeat; + if (featStrand != annotStrand) { + allSameStrand = 0; + featToAdd.set('strand', annotStrand); + } + subfeats.push(featToAdd); + } + // $.merge(subfeats, subs); + } + else { // top-level feature without subfeatures + // make exon feature + var featStrand = feat.get('strand'); + var featToAdd = feat; + if (featStrand != annotStrand) { + allSameStrand = 0; + featToAdd.set('strand', annotStrand); + } + featToAdd.set('type', 'exon'); + subfeats.push(featToAdd); + } + } + } + + if (!allSameStrand && !confirm("Adding features of opposite strand. Continue?")) { + return; + } + + var featuresString = ""; + for (var i = 0; i < subfeats.length; ++i) { + var subfeat = subfeats[i]; + // if (subfeat[target_track.subFields["type"]] != "wholeCDS") { + var source_track = subfeat.track; + if ( subfeat.get('type') != "wholeCDS") { + var jsonFeature = JSONUtils.createApolloFeature( subfeats[i], "exon"); + featuresString += ", " + JSON.stringify( jsonFeature ); + } + } +// var parent = JSONUtils.createApolloFeature(annot, target_track.fields, target_track.subfields); +// parent.uniquename = annot[target_track.fields["name"]]; + var postData = '{ "track": "' + target_track.getUniqueTrackName() + '", "features": [ {"uniquename": "' + annot.id() + '"}' + featuresString + '], "operation": "add_exon" }'; + target_track.executeUpdateOperation(postData); + }, + + makeTrackDroppable: function() { + var target_track = this; + var target_trackdiv = target_track.div; + if (target_track.verbose_drop) { + console.log("making track a droppable target: "); + console.log(this); + console.log(target_trackdiv); + } + $(target_trackdiv).droppable( { + // only accept draggables that are selected feature divs + accept: ".selected-feature", + // switched to using deactivate() rather than drop() for drop handling + // this fixes bug where drop targets within track (feature divs) were lighting up as drop target, + // but dropping didn't actually call track.droppable.drop() + // (see explanation in feature droppable for why we catch drop at track div rather than feature div child) + // cause is possible bug in JQuery droppable where droppable over(), drop() and hoverclass + // collision calcs may be off (at least when tolerance=pointer)? + // + // Update 3/2012 + // deactivate behavior changed? Now getting called every time dragged features are release, + // regardless of whether they are over this track or not + // so added another hack to get around drop problem + // combination of deactivate and keeping track via over()/out() of whether drag is above this track when released + // really need to look into actual drop calc fix -- maybe fixed in new JQuery releases? + // + // drop: function(event, ui) { + over: function(event, ui) { + target_track.track_under_mouse_drag = true; + if (target_track.verbose_drop) { console.log("droppable entered AnnotTrack") }; + }, + out: function(event, ui) { + target_track.track_under_mouse_drag = false; + if (target_track.verbose_drop) { console.log("droppable exited AnnotTrack") }; + + }, + deactivate: function(event, ui) { + // console.log("trackdiv droppable detected: draggable deactivated"); + // "this" is the div being dropped on, so same as target_trackdiv + if (target_track.verbose_drop) { console.log("draggable deactivated"); } + + var dropped_feats = target_track.webapollo.featSelectionManager.getSelection(); + // problem with making individual annotations droppable, so checking for "drop" on annotation here, + // and if so re-routing to add to existing annotation + if (target_track.annot_under_mouse != null) { + if (target_track.verbose_drop) { + console.log("draggable dropped onto annot: "); + console.log(target_track.annot_under_mouse.feature); + } + target_track.addToAnnotation(target_track.annot_under_mouse.feature, dropped_feats); + } + else if (target_track.track_under_mouse_drag) { + if (target_track.verbose_drop) { console.log("draggable dropped on AnnotTrack"); } + target_track.createAnnotations(dropped_feats); + } + // making sure annot_under_mouse is cleared + // (should do this in the drop? but need to make sure _not_ null when + target_track.annot_under_mouse = null; + target_track.track_under_mouse_drag = false; + } + } ); + if( target_track.verbose_drop) { console.log("finished making droppable target"); } + }, + + createAnnotations: function(selection_records) { + var target_track = this; + var featuresToAdd = new Array(); + var parentFeatures = new Object(); + for (var i in selection_records) { + var dragfeat = selection_records[i].feature; + + var is_subfeature = !! dragfeat.parent(); // !! is shorthand for returning true if value is defined and non-null + var parentId = is_subfeature ? dragfeat.parent().id() : dragfeat.id(); + + if (parentFeatures[parentId] === undefined) { + parentFeatures[parentId] = new Array(); + parentFeatures[parentId].isSubfeature = is_subfeature; + } + parentFeatures[parentId].push(dragfeat); + } + + for (var i in parentFeatures) { + var featArray = parentFeatures[i]; + if (featArray.isSubfeature) { + var parentFeature = featArray[0].parent(); + var fmin = undefined; + var fmax = undefined; + // var featureToAdd = $.extend({}, parentFeature); + var featureToAdd = JSONUtils.makeSimpleFeature(parentFeature); + featureToAdd.set('subfeatures', new Array()); + for (var k = 0; k < featArray.length; ++k) { + // var dragfeat = featArray[k]; + var dragfeat = JSONUtils.makeSimpleFeature(featArray[k]); + var childFmin = dragfeat.get('start'); + var childFmax = dragfeat.get('end'); + if (fmin === undefined || childFmin < fmin) { + fmin = childFmin; + } + if (fmax === undefined || childFmax > fmax) { + fmax = childFmax; + } + featureToAdd.get("subfeatures").push( dragfeat ); + } + featureToAdd.set( "start", fmin ); + featureToAdd.set( "end", fmax ); + var afeat = JSONUtils.createApolloFeature( featureToAdd, "transcript" ); + featuresToAdd.push(afeat); + } + else { + for (var k = 0; k < featArray.length; ++k) { + var dragfeat = featArray[k]; + var afeat = JSONUtils.createApolloFeature( dragfeat, "transcript"); + featuresToAdd.push(afeat); + } + } + } + var postData = '{ "track": "' + target_track.getUniqueTrackName() + '", "features": ' + JSON.stringify(featuresToAdd) + ', "operation": "add_transcript" }'; + target_track.executeUpdateOperation(postData); + }, + + duplicateSelectedFeatures: function() { + var selected = this.selectionManager.getSelection(); + var selfeats = this.selectionManager.getSelectedFeatures(); + this.selectionManager.clearSelection(); + this.duplicateAnnotations(selfeats); + }, + + duplicateAnnotations: function(feats) { + var track = this; + var featuresToAdd = new Array(); + var subfeaturesToAdd = new Array(); + var parentFeature; + for( var i in feats ) { + var feat = feats[i]; + var is_subfeature = !! feat.parent() ; // !! is shorthand for returning true if value is defined and non-null + if (is_subfeature) { + subfeaturesToAdd.push(feat); + } + else { + featuresToAdd.push( JSONUtils.createApolloFeature( feat, "transcript") ); + } + } + if (subfeaturesToAdd.length > 0) { + var feature = new SimpleFeature(); + var subfeatures = new Array(); + feature.set( 'subfeatures', subfeatures ); + var fmin = undefined; + var fmax = undefined; + var strand = undefined; + for (var i = 0; i < subfeaturesToAdd.length; ++i) { + var subfeature = subfeaturesToAdd[i]; + if (fmin === undefined || subfeature.get('start') < fmin) { + fmin = subfeature.get('start'); + } + if (fmax === undefined || subfeature.get('end') > fmax) { + fmax = subfeature.get('end'); + } + if (strand === undefined) { + strand = subfeature.get('strand'); + } + subfeatures.push(subfeature); + } + feature.set('start', fmin ); + feature.set('end', fmax ); + feature.set('strand', strand ); + featuresToAdd.push( JSONUtils.createApolloFeature( feature, "transcript") ); + } + var postData = '{ "track": "' + track.getUniqueTrackName() + '", "features": ' + JSON.stringify(featuresToAdd) + ', "operation": "add_transcript" }'; + track.executeUpdateOperation(postData); + }, + + /** + * If there are multiple AnnotTracks, each has a separate FeatureSelectionManager + * (contrasted with DraggableFeatureTracks, which all share the same selection and selection manager + */ + deleteSelectedFeatures: function() { + console.log("attempting to delete selected features"); + var selected = this.selectionManager.getSelection(); + this.selectionManager.clearSelection(); + this.deleteAnnotations(selected); + }, + + deleteAnnotations: function(records) { + var track = this; + var features = '"features": ['; + var uniqueNames = []; + for (var i in records) { + var record = records[i]; + var selfeat = record.feature; + var seltrack = record.track; + var uniqueName = selfeat.id(); + // just checking to ensure that all features in selection are from this track -- + // if not, then don't try and delete them + if (seltrack === track) { + var trackdiv = track.div; + var trackName = track.getUniqueTrackName(); + + if (i > 0) { + features += ','; + } + features += ' { "uniquename": "' + uniqueName + '" } '; + uniqueNames.push(uniqueName); + } + } + features += ']'; + if (this.verbose_delete) { + console.log("annotations to delete:"); + console.log(features); + } + var postData = '{ "track": "' + trackName + '", ' + features + ', "operation": "delete_feature" }'; + track.executeUpdateOperation(postData); + }, + + mergeSelectedFeatures: function() { + var selected = this.selectionManager.getSelection(); + this.selectionManager.clearSelection(); + this.mergeAnnotations(selected); + }, + + mergeAnnotations: function(selection) { + var track = this; + var annots = []; + for (var i=0; i rightAnnot[track.fields["end"]]) { + rightAnnot = annot; + } + } + } + */ + + var features; + var operation; + // merge exons + if (leftAnnot.parent() && rightAnnot.parent() && leftAnnot.parent() == rightAnnot.parent()) { + features = '"features": [ { "uniquename": "' + leftAnnot.id() + '" }, { "uniquename": "' + rightAnnot.id() + '" } ]'; + operation = "merge_exons"; + } + // merge transcripts + else { + var leftTranscriptId = leftAnnot.parent() ? leftAnnot.parent().id() : leftAnnot.id(); + var rightTranscriptId = rightAnnot.parent() ? rightAnnot.parent().id() : rightAnnot.id(); + features = '"features": [ { "uniquename": "' + leftTranscriptId + '" }, { "uniquename": "' + rightTranscriptId + '" } ]'; + operation = "merge_transcripts"; + } + var postData = '{ "track": "' + trackName + '", ' + features + ', "operation": "' + operation + '" }'; + track.executeUpdateOperation(postData); + }, + + splitSelectedFeatures: function(event) { + // var selected = this.selectionManager.getSelection(); + var selected = this.selectionManager.getSelectedFeatures(); + this.selectionManager.clearSelection(); + this.splitAnnotations(selected, event); + }, + + splitAnnotations: function(annots, event) { + // can only split on max two elements + if( annots.length > 2 ) { + return; + } + var track = this; + var sortedAnnots = track.sortAnnotationsByLocation(annots); + var leftAnnot = sortedAnnots[0]; + var rightAnnot = sortedAnnots[sortedAnnots.length - 1]; + var trackName = track.getUniqueTrackName(); + + /* + for (var i in annots) { + var annot = annots[i]; + // just checking to ensure that all features in selection are from this track -- + // if not, then don't try and delete them + if (annot.track === track) { + var trackName = track.getUniqueTrackName(); + if (leftAnnot == null || annot[track.fields["start"]] < leftAnnot[track.fields["start"]]) { + leftAnnot = annot; + } + if (rightAnnot == null || annot[track.fields["end"]] > rightAnnot[track.fields["end"]]) { + rightAnnot = annot; + } + } + } + */ + var features; + var operation; + // split exon + if (leftAnnot == rightAnnot) { + var coordinate = this.getGenomeCoord(event); + features = '"features": [ { "uniquename": "' + leftAnnot.id() + '", "location": { "fmax": ' + coordinate + ', "fmin": ' + (coordinate + 1) + ' } } ]'; + operation = "split_exon"; + } + // split transcript + else if (leftAnnot.parent() == rightAnnot.parent()) { + features = '"features": [ { "uniquename": "' + leftAnnot.id() + '" }, { "uniquename": "' + rightAnnot.id() + '" } ]'; + operation = "split_transcript"; + } + else { + return; + } + var postData = '{ "track": "' + trackName + '", ' + features + ', "operation": "' + operation + '" }'; + track.executeUpdateOperation(postData); + }, + + makeIntron: function(event) { + var selected = this.selectionManager.getSelection(); + this.selectionManager.clearSelection(); + this.makeIntronInExon(selected, event); + }, + + makeIntronInExon: function(records, event) { + if (records.length > 1) { + return; + } + var track = this; + var annot = records[0].feature; + var coordinate = this.getGenomeCoord(event); + var features = '"features": [ { "uniquename": "' + annot.id() + '", "location": { "fmin": ' + coordinate + ' } } ]'; + var operation = "make_intron"; + var trackName = track.getUniqueTrackName(); + var postData = '{ "track": "' + trackName + '", ' + features + ', "operation": "' + operation + '" }'; + track.executeUpdateOperation(postData); + }, + + setTranslationStart: function(event) { + // var selected = this.selectionManager.getSelection(); + var selfeats = this.selectionManager.getSelectedFeatures(); + this.selectionManager.clearSelection(); + this.setTranslationStartInCDS(selfeats, event); + }, + + setTranslationStartInCDS: function(annots, event) { + if (annots.length > 1) { + return; + } + var track = this; + var annot = annots[0]; + // var coordinate = this.gview.getGenomeCoord(event); +// var coordinate = Math.floor(this.gview.absXtoBp(event.pageX)); + var coordinate = this.getGenomeCoord(event); + console.log("called setTranslationStartInCDS to: " + coordinate); + + var uid = annot.parent() ? annot.parent().id() : annot.id(); + var features = '"features": [ { "uniquename": "' + uid + '", "location": { "fmin": ' + coordinate + ' } } ]'; + var operation = "set_translation_start"; + var trackName = track.getUniqueTrackName(); + var postData = '{ "track": "' + trackName + '", ' + features + ', "operation": "' + operation + '" }'; + track.executeUpdateOperation(postData); + }, + + flipStrand: function() { + var selected = this.selectionManager.getSelection(); + this.flipStrandForSelectedFeatures(selected); + }, + + flipStrandForSelectedFeatures: function(records) { + var track = this; + var uniqueNames = new Object(); + for (var i in records) { + var record = records[i]; + var selfeat = record.feature; + var seltrack = record.track; + var topfeat = AnnotTrack.getTopLevelAnnotation(selfeat); + var uniqueName = topfeat.id(); + // just checking to ensure that all features in selection are from this track + if (seltrack === track) { + uniqueNames[uniqueName] = 1; + } + } + var features = '"features": ['; + var i = 0; + for (var uniqueName in uniqueNames) { + var trackdiv = track.div; + var trackName = track.getUniqueTrackName(); + + if (i > 0) { + features += ','; + } + features += ' { "uniquename": "' + uniqueName + '" } '; + ++i; + } + features += ']'; + var operation = "flip_strand"; + var trackName = track.getUniqueTrackName(); + var postData = '{ "track": "' + trackName + '", ' + features + ', "operation": "' + operation + '" }'; + track.executeUpdateOperation(postData); + }, + + setLongestORF: function() { + var selected = this.selectionManager.getSelection(); + this.selectionManager.clearSelection(); + this.setLongestORFForSelectedFeatures(selected); + }, + + setLongestORFForSelectedFeatures: function(selection) { + var track = this; + var features = '"features": ['; + for (var i in selection) { + var annot = AnnotTrack.getTopLevelAnnotation(selection[i].feature); + var atrack = selection[i].track; + var uniqueName = annot.id(); + // just checking to ensure that all features in selection are from this track + if (atrack === track) { + var trackdiv = track.div; + var trackName = track.getUniqueTrackName(); + + if (i > 0) { + features += ','; + } + features += ' { "uniquename": "' + uniqueName + '" } '; + } + } + features += ']'; + var operation = "set_longest_orf"; + var trackName = track.getUniqueTrackName(); + var postData = '{ "track": "' + trackName + '", ' + features + ', "operation": "' + operation + '" }'; + track.executeUpdateOperation(postData); + }, + + editComments: function() { + var selected = this.selectionManager.getSelection(); + this.editCommentsForSelectedFeatures(selected); + }, + + editCommentsForSelectedFeatures: function(records) { + var track = this; + var record = records[0]; + var seltrack = record.track; + var annot = AnnotTrack.getTopLevelAnnotation(record.feature); + // just checking to ensure that all features in selection are from this track + if (seltrack !== track) { + return; + } + var content = dojo.create("div"); + // if annotation has parent, get comments for parent + if(annot.afeature.parent_id) { + var parentContent = this.createEditCommentsPanelForFeature( annot.afeature.parent_id, track.getUniqueTrackName()); + dojo.attr(parentContent, "class", "parent_comments_div"); + dojo.place(parentContent, content); + } + var annotContent = this.createEditCommentsPanelForFeature(annot.id(), track.getUniqueTrackName()); + dojo.place(annotContent, content); + track.openDialog("Comments for " + annot.get('name'), content); + }, + + createEditCommentsPanelForFeature: function(uniqueName, trackName) { + var track = this; + var content = dojo.create("div"); + var header = dojo.create("div", { className: "comment_header" }, content); + var table = dojo.create("table", { className: "comments" }, content); + var addButtonDiv = dojo.create("div", { className: "comment_add_button_div" }, content); + var addButton = dojo.create("button", { className: "comment_button", innerHTML: "Add comment" }, addButtonDiv); + var cannedCommentsDiv = dojo.create("div", { }, content); + var cannedCommentsComboBox = dojo.create("select", { }, cannedCommentsDiv); + var comments; + var commentTextFields; + var cannedComments; + var showCannedComments = false; + + var getComments = function() { + var features = '"features": [ { "uniquename": "' + uniqueName + '" } ]'; + var operation = "get_comments"; + var postData = '{ "track": "' + trackName + '", ' + features + ', "operation": "' + operation + '" }'; + dojo.xhrPost( { + postData: postData, + url: context_path + "/AnnotationEditorService", + handleAs: "json", + sync: true, + timeout: 5000 * 1000, // Time in milliseconds + load: function(response, ioArgs) { + var feature = response.features[0]; + comments = feature.comments; + header.innerHTML = "Comments for " + feature.type.name; + }, + // The ERROR function will be called in an error case. + error: function(response, ioArgs) { + track.handleError(response); + console.error("HTTP status code: ", ioArgs.xhr.status); + return response; + } + + }); + }; + + var addComment = function(comment) { + var features = '"features": [ { "uniquename": "' + uniqueName + '", "comments": [ "' + comment + '" ] } ]'; + var operation = "add_comments"; + var postData = '{ "track": "' + trackName + '", ' + features + ', "operation": "' + operation + '" }'; + track.executeUpdateOperation(postData); + }; + + var deleteComment = function(comment) { + var features = '"features": [ { "uniquename": "' + uniqueName + '", "comments": [ "' + comment + '" ] } ]'; + var operation = "delete_comments"; + var postData = '{ "track": "' + trackName + '", ' + features + ', "operation": "' + operation + '" }'; + track.executeUpdateOperation(postData); + }; + + var updateComment = function(oldComment, newComment) { + if (oldComment == newComment) { + return; + } + var features = '"features": [ { "uniquename": "' + uniqueName + '", "old_comments": [ "' + oldComment + '" ], "new_comments": [ "' + newComment + '"] } ]'; + var operation = "update_comments"; + var postData = '{ "track": "' + trackName + '", ' + features + ', "operation": "' + operation + '" }'; + track.executeUpdateOperation(postData); + + }; + + var updateTable = function() { + while (table.hasChildNodes()) { + table.removeChild(table.lastChild); + } + commentTextFields = new Array(); + for (var i = 0; i < comments.length; ++i) { + var row = dojo.create("tr", { }, table); + var col1 = dojo.create("td", { }, row); + var comment = dojo.create("textarea", { rows: 1, innerHTML: comments[i], readonly: true, className: "comment_area" }, col1); + commentTextFields.push(comment); + dojo.connect(comment, "onclick", comment, function() { + if (!showCannedComments) { + dojo.style(cannedCommentsDiv, { display: "none" } ); + } + }); + dojo.connect(comment, "onblur", comment, function(index) { + return function() { + showCannedComments = false; + var newComment = dojo.attr(this, "value"); + var oldComment = comments[index]; + comments[index] = newComment; + dojo.attr(this, "readonly", true); + if (newComment && newComment.length > 0) { + if (oldComment.length == 0) { + addComment(newComment); + } + else { + updateComment(oldComment, newComment); + } + dojo.style(cannedCommentsDiv, { display: "none" } ); + } + }; + }(i)); + dojo.connect(comment, "onkeyup", comment, function() { + var newComment = dojo.attr(this, "value"); + if (newComment && newComment.length > 0) { + dojo.style(cannedCommentsDiv, { display: "none" } ); + } + else if (showCannedComments) { + dojo.style(cannedCommentsDiv, { display: "block" } ); + } + }); + var col2 = dojo.create("td", { }, row); + var delButton = dojo.create("button", { className: "comment_button", innerHTML: "Delete" /* "" */}, col2); + dojo.connect(delButton, "onfocus", delButton, function() { + showCannedComments = false; + dojo.style(cannedCommentsDiv, { display: "none" } ); + }); + dojo.connect(delButton, "onclick", delButton, function(index) { + return function() { + showCannedComments = false; + dojo.style(cannedCommentsDiv, { display: "none" } ); + var oldComment = comments[index]; + comments.splice(index, 1); + updateTable(); + deleteComment(oldComment); + }; + }(i)); + var col3 = dojo.create("td", { }, row); + var editButton = dojo.create("button", { className: "comment_button", innerHTML: "Edit" /*"*/}, col3); + dojo.connect(editButton, "onfocus", editButton, function() { + showCannedComments = false; + dojo.style(cannedCommentsDiv, { display: "none" } ); + }); + dojo.connect(editButton, "onclick", editButton, function(index) { + return function() { + showCannedComments = false; + dojo.style(cannedCommentsDiv, { display: "none" } ); + dojo.attr(commentTextFields[index], "readonly", false); + commentTextFields[index].focus(); + }; + }(i)); + } + }; + + var getCannedComments = function() { + dojo.style(cannedCommentsDiv, { display: "none"} ); + + var features = '"features": [ { "uniquename": "' + uniqueName + '" } ]'; + var operation = "get_canned_comments"; + var postData = '{ "track": "' + trackName + '", ' + features + ', "operation": "' + operation + '" }'; + dojo.xhrPost( { + postData: postData, + url: context_path + "/AnnotationEditorService", + handleAs: "json", + sync: true, + timeout: 5000 * 1000, // Time in milliseconds + load: function(response, ioArgs) { + var feature = response.features[0]; + cannedComments = feature.comments; + cannedComments.unshift("Choose a comment"); + }, + // The ERROR function will be called in an error case. + error: function(response, ioArgs) { + track.handleError(response); + console.error("HTTP status code: ", ioArgs.xhr.status); + return response; + } + }); + + for (var i = 0; i < cannedComments.length; ++i) { + dojo.create("option", { value: cannedComments[i], innerHTML: cannedComments[i] }, cannedCommentsComboBox); + } + dojo.connect(cannedCommentsComboBox, "onchange", cannedCommentsComboBox, function() { + var commentTextField = commentTextFields[commentTextFields.length - 1]; + if (this.selectedIndex > 0) { + dojo.attr(commentTextField, "value", dojo.attr(this, "value")); + commentTextField.focus(); + dojo.style(cannedCommentsDiv, { display : "none" }); + } + }); + }; + + dojo.connect(addButton, "onclick", null, function() { + showCannedComments = true; + comments.push(""); + updateTable(); + var comment = commentTextFields[commentTextFields.length - 1]; + dojo.attr(comment, "readonly", false); + dojo.style(cannedCommentsDiv, { display: "block" }); + cannedCommentsComboBox.selectedIndex = 0; + comment.focus(); + }); + + getComments(); + getCannedComments(); + updateTable(); + return content; + + }, + + editDbxrefs: function() { + var selected = this.selectionManager.getSelection(); + this.editDbxrefsForSelectedFeatures(selected); + }, + + editDbxrefsForSelectedFeatures: function(records) { + var track = this; + var record = records[0]; + var annot = AnnotTrack.getTopLevelAnnotation(record.feature); + var seltrack = record.track; + // just checking to ensure that all features in selection are from this track + if ( seltrack !== track ) { + return; + } + var content = dojo.create("div"); + // if annotation has parent, get comments for parent + if ( annot.afeature.parent_id ) { + var parentContent = this.createEditDbxrefsPanelForFeature( annot.afeature.parent_id, track.getUniqueTrackName()); + dojo.attr(parentContent, "class", "parent_dbxrefs_div"); + dojo.place(parentContent, content); + } + var annotContent = this.createEditDbxrefsPanelForFeature(annot.id(), track.getUniqueTrackName()); + dojo.place(annotContent, content); + track.openDialog("Dbxrefs for " + annot.get("name"), content); + }, + + createEditDbxrefsPanelForFeature: function(uniqueName, trackName) { + var track = this; + var content = dojo.create("div"); + var header = dojo.create("div", { className: "dbxref_header" }, content); + var tableHeader = dojo.create("div", { className: "dbxref_header", innerHTML: "DatabaseAccession" }, content); + var table = dojo.create("div", { className: "dbxrefs" }, content); + var addButtonDiv = dojo.create("div", { className: "dbxref_add_button_div" }, content); + var addButton = dojo.create("button", { className: "dbxref_button", innerHTML: "Add DBXref" }, addButtonDiv); + var dbxrefs; + var dbxrefTextFields; + + var getDbxrefs = function() { + var features = '"features": [ { "uniquename": "' + uniqueName + '" } ]'; + var operation = "get_non_primary_dbxrefs"; + var postData = '{ "track": "' + trackName + '", ' + features + ', "operation": "' + operation + '" }'; + dojo.xhrPost( { + postData: postData, + url: context_path + "/AnnotationEditorService", + handleAs: "json", + sync: true, + timeout: 5000 * 1000, // Time in milliseconds + load: function(response, ioArgs) { + var feature = response.features[0]; + dbxrefs = feature.dbxrefs; + header.innerHTML = "DBXRefs for " + feature.type.name; + }, + // The ERROR function will be called in an error case. + error: function(response, ioArgs) { + track.handleError(response); + console.error("HTTP status code: ", ioArgs.xhr.status); + return response; + } + + }); + + }; + + var addDbxref = function(db, accession) { + var features = '"features": [ { "uniquename": "' + uniqueName + '", "dbxrefs": [ { "db": "' + db + '", "accession": "' + accession + '" } ] } ]'; + var operation = "add_non_primary_dbxrefs"; + var postData = '{ "track": "' + trackName + '", ' + features + ', "operation": "' + operation + '" }'; + track.executeUpdateOperation(postData); + }; + + var deleteDbxref = function(db, accession) { + var features = '"features": [ { "uniquename": "' + uniqueName + '", "dbxrefs": [ { "db": "' + db + '", "accession": "' + accession + '" } ] } ]'; + var operation = "delete_non_primary_dbxrefs"; + var postData = '{ "track": "' + trackName + '", ' + features + ', "operation": "' + operation + '" }'; + track.executeUpdateOperation(postData); + }; + + var updateDbxref = function(oldDb, oldAccession, newDb, newAccession) { + var features = '"features": [ { "uniquename": "' + uniqueName + '", "old_dbxrefs": [ { "db": "' + oldDb + '", "accession": "' + oldAccession + '" } ], "new_dbxrefs": [ { "db": "' + newDb + '", "accession": "' + newAccession + '" } ] } ]'; + var operation = "update_non_primary_dbxrefs"; + var postData = '{ "track": "' + trackName + '", ' + features + ', "operation": "' + operation + '" }'; + track.executeUpdateOperation(postData); + }; + + var handleDbxrefUpdate = function(index) { + var newDb = dojo.attr(dbxrefTextFields[index][0], "value"); + var oldDb = dbxrefs[index].db; + var newAccession = dojo.attr(dbxrefTextFields[index][1], "value"); + var oldAccession = dbxrefs[index].accession; + if (oldDb != newDb || oldAccession != newAccession) { + dbxrefs[index].db = newDb; + dbxrefs[index].accession = newAccession; + if (newDb && newDb.length > 0 && newAccession && newAccession.length > 0) { + if (oldDb.length == 0 || oldAccession.length == 0) { + addDbxref(newDb, newAccession); + } + else { + updateDbxref(oldDb, oldAccession, newDb, newAccession); + } + } + } + }; + + var updateTable = function() { + while (table.hasChildNodes()) { + table.removeChild(table.lastChild); + } + dbxrefTextFields = new Array(); + for (var i = 0; i < dbxrefs.length; ++i) { + var dbxref = dbxrefs[i]; + var row = dojo.create("div", { }, table); + var col1 = dojo.create("span", { }, row); + var db = dojo.create("input", { type: "text", rows: 1, value: dbxref.db, readonly: true, className: "dbxref_field" }, col1); + var col2 = dojo.create("span", { }, row); + var accession = dojo.create("input", { type: "text", rows: 1, value: dbxref.accession, readonly: true, className: "dbxref_field" }, col2); + dbxrefTextFields.push([db, accession]); + dojo.connect(db, "onblur", db, function(index) { + return function() { + handleDbxrefUpdate(index); + }; + }(i)); + dojo.connect(accession, "onblur", accession, function(index) { + return function() { + handleDbxrefUpdate(index); + }; + }(i)); + var col3 = dojo.create("span", { }, row); + var delButton = dojo.create("button", { className: "dbxref_button", innerHTML: "Delete" }, col3); + dojo.connect(delButton, "onclick", delButton, function(index) { + return function() { + var oldDbxref = dbxrefs[index]; + dbxrefs.splice(index, 1); + updateTable(); + deleteDbxref(oldDbxref.db, oldDbxref.accession); + }; + }(i)); + var col4 = dojo.create("span", { }, row); + var editButton = dojo.create("button", { className: "dbxref_button", innerHTML: "Edit" }, col4); + dojo.connect(editButton, "onclick", editButton, function(index) { + return function() { + dojo.attr(dbxrefTextFields[index][0], "readonly", false); + dojo.attr(dbxrefTextFields[index][1], "readonly", false); + dbxrefTextFields[index][0].focus(); + }; + }(i)); + } + }; + dojo.connect(addButton, "onclick", null, function() { + dbxrefs.push( { db: "", accession: "" } ); + updateTable(); + var dbxref = dbxrefTextFields[dbxrefTextFields.length - 1]; + dojo.attr(dbxref[0], "readonly", false); + dojo.attr(dbxref[1], "readonly", false); + dbxref[0].focus(); + }); + + getDbxrefs(); + updateTable(); + return content; + + }, + + undo: function() { + var selected = this.selectionManager.getSelection(); + this.selectionManager.clearSelection(); + this.undoSelectedFeatures(selected); + }, + + undoSelectedFeatures: function(records) { + var track = this; + var features = '"features": ['; + for (var i in records) { + var record = records[i]; + var selfeat = record.feature; + var seltrack = record.track; + var topfeat = AnnotTrack.getTopLevelAnnotation(selfeat); + var uniqueName = topfeat.id(); + // just checking to ensure that all features in selection are from this track + if (seltrack === track) { + var trackdiv = track.div; + var trackName = track.getUniqueTrackName(); + + if (i > 0) { + features += ','; + } + features += ' { "uniquename": "' + uniqueName + '" } '; + } + } + features += ']'; + var operation = "undo"; + var trackName = track.getUniqueTrackName(); + var postData = '{ "track": "' + trackName + '", ' + features + ', "operation": "' + operation + '" }'; + track.executeUpdateOperation(postData, function(response) { + if (response && response.confirm) { + if (track.handleConfirm(response.confirm)) { + postData = '{ "track": "' + trackName + '", ' + features + ', "operation": "' + operation + '", "confirm": true }'; + track.executeUpdateOperation(postData); + } + } + }); + }, + + redo: function() { + var selected = this.selectionManager.getSelection(); + this.selectionManager.clearSelection(); + this.redoSelectedFeatures(selected); + }, + + redoSelectedFeatures: function(records) { + var track = this; + var features = '"features": ['; + for (var i in records) { + var record = records[i]; + var selfeat = record.feature; + var seltrack = record.track; + var topfeat = AnnotTrack.getTopLevelAnnotation(selfeat); + var uniqueName = topfeat.id(); + // just checking to ensure that all features in selection are from this track + if (seltrack === track) { + var trackdiv = track.div; + var trackName = track.getUniqueTrackName(); + + if (i > 0) { + features += ','; + } + features += ' { "uniquename": "' + uniqueName + '" } '; + } + } + features += ']'; + var operation = "redo"; + var trackName = track.getUniqueTrackName(); + var postData = '{ "track": "' + trackName + '", ' + features + ', "operation": "' + operation + '" }'; + track.executeUpdateOperation(postData); + }, + + getHistory: function() { + var selected = this.selectionManager.getSelection(); + this.selectionManager.clearSelection(); + this.getHistoryForSelectedFeatures(selected); + }, + + getHistoryForSelectedFeatures: function(selected) { + var track = this; + var content = dojo.create("div"); + var historyDiv = dojo.create("div", { className: "history_div" }, content); + var historyTable = dojo.create("div", { className: "history_table" }, historyDiv); + var historyHeader = dojo.create("div", { className: "history_header", innerHTML: "OperationEditorDate" }, historyTable); + var historyRows = dojo.create("div", { className: "history_rows" }, historyTable); + var historyPreviewDiv = dojo.create("div", { className: "history_preview" }, historyDiv); + var history; + var selectedIndex = 0; + var minFmin = undefined; + var maxFmax = undefined; + + var cleanupDiv = function(div) { + if (div.style.top) { + div.style.top = null; + } + if (div.style.visibility) { div.style.visibility = null; } + annot_context_menu.unBindDomNode(div); + $(div).unbind(); + for (var i = 0; i < div.childNodes.length; ++i) { + cleanupDiv(div.childNodes[i]); + } + }; + + var displayPreview = function(index) { + var historyItem = history[index]; + var afeature = historyItem.features[0]; + var jfeature = JSONUtils.createJBrowseFeature(afeature); + var fmin = afeature.location.fmin; + var fmax = afeature.location.fmax; + var maxLength = maxFmax - minFmin; +// track.featureStore._add_getters(track.attrs.accessors().get, jfeature); + historyPreviewDiv.featureLayout = new Layout(fmin, fmax); + historyPreviewDiv.featureNodes = new Array(); + historyPreviewDiv.startBase = minFmin - (maxLength * 0.1); + historyPreviewDiv.endBase = maxFmax + (maxLength * 0.1); + var coords = dojo.position(historyPreviewDiv); + // setting labelScale and descriptionScale parameter to 100 px/bp, so neither should get triggered + var featDiv = track.renderFeature(jfeature, jfeature.uid, historyPreviewDiv, coords.w / (maxLength), 100, 100, minFmin, maxFmax); + cleanupDiv(featDiv); + while (historyPreviewDiv.hasChildNodes()) { + historyPreviewDiv.removeChild(historyPreviewDiv.lastChild); + } + historyPreviewDiv.appendChild(featDiv); + dojo.attr(historyRows.childNodes.item(selectedIndex), "class", "history_row"); + dojo.attr(historyRows.childNodes.item(index), "class", "history_row history_row_selected"); + selectedIndex = index; + }; + + var displayHistory = function() { + var current; + for (var i = 0; i < history.length; ++i) { + var historyItem = history[i]; + var rowCssClass = "history_row"; + var row = dojo.create("div", { className: rowCssClass }, historyRows); + var columnCssClass = "history_column"; + dojo.create("span", { className: columnCssClass, innerHTML: historyItem.operation }, row); + dojo.create("span", { className: columnCssClass, innerHTML: historyItem.editor }, row); + dojo.create("span", { className: columnCssClass + " history_date_column", innerHTML: historyItem.date }, row); + var afeature = historyItem.features[0]; + var fmin = afeature.location.fmin; + var fmax = afeature.location.fmax; + if (minFmin == undefined || fmin < minFmin) { + minFmin = fmin; + } + if (maxFmax == undefined || fmax > maxFmax) { + maxFmax = fmax; + } + + if (historyItem.current) { + current = i; + } + + dojo.connect(row, "onclick", row, function(index) { + return function() { + displayPreview(index); + }; + }(i)); + } + displayPreview(current); + var coords = dojo.position(row); + historyRows.scrollTop = selectedIndex * coords.h; + }; + + var fetchHistory = function() { + var features = '"features": ['; + for (var i in selected) { + var record = selected[i]; + var annot = AnnotTrack.getTopLevelAnnotation(record.feature); + var uniqueName = annot.id(); + // just checking to ensure that all features in selection are from this track + if (record.track === track) { + var trackdiv = track.div; + var trackName = track.getUniqueTrackName(); + + if (i > 0) { + features += ','; + } + features += ' { "uniquename": "' + uniqueName + '" } '; + } + } + features += ']'; + var operation = "get_history_for_features"; + var trackName = track.getUniqueTrackName(); + dojo.xhrPost( { + postData: '{ "track": "' + trackName + '", ' + features + ', "operation": "' + operation + '" }', + url: context_path + "/AnnotationEditorService", + handleAs: "json", + timeout: 5000 * 1000, // Time in milliseconds + load: function(response, ioArgs) { + var features = response.features; +// for (var i = 0; i < features.length; ++i) { +// displayHistory(features[i].history); +// } + history = features[i].history; + displayHistory(); + }, + // The ERROR function will be called in an error case. + error: function(response, ioArgs) { // + track.handleError(response); + return response; // + } + + }); + }; + + fetchHistory(); + this.openDialog("History", content); +// this.popupDialog.hide(); +// this.openDialog("History", content); + }, + +getAnnotationInformation: function() { + var selected = this.selectionManager.getSelection(); + this.getInformationForSelectedAnnotations(selected); + }, + + getInformationForSelectedAnnotations: function(records) { + var track = this; + var features = '"features": ['; + for (var i in records) { + var record = records[i]; + var selfeat = record.feature; + var seltrack = record.track; + var topfeat = AnnotTrack.getTopLevelAnnotation(selfeat); + var uniqueName = topfeat.id(); + // just checking to ensure that all features in selection are from this track + if (seltrack === track) { + var trackdiv = track.div; + var trackName = track.getUniqueTrackName(); + + if (i > 0) { + features += ','; + } + features += ' { "uniquename": "' + uniqueName + '" } '; + } + } + features += ']'; + var operation = "get_information"; + var trackName = track.getUniqueTrackName(); + var information = ""; + dojo.xhrPost( { + postData: '{ "track": "' + trackName + '", ' + features + ', "operation": "' + operation + '" }', + url: context_path + "/AnnotationEditorService", + handleAs: "json", + timeout: 5000 * 1000, // Time in milliseconds + load: function(response, ioArgs) { + for (var i = 0; i < response.features.length; ++i) { + var feature = response.features[i]; + if (i > 0) { + information += "
"; + } + information += "Unique id: " + feature.uniquename + "
"; + information += "Date of creation: " + feature.time_accessioned + "
"; + information += "Owner: " + feature.owner + "
"; + information += "Parent ids: " + feature.parent_ids + "
"; + } + track.openDialog("Annotation information", information); + }, + // The ERROR function will be called in an error case. + error: function(response, ioArgs) { + track.handleError(response); + console.log("Annotation server error--maybe you forgot to login to the server?"); + console.error("HTTP status code: ", ioArgs.xhr.status); + // + //dojo.byId("replace").innerHTML = 'Loading the resource from the server did not work'; + return response; + } + }); + }, + + getSequence: function() { + var selected = this.selectionManager.getSelection(); + this.getSequenceForSelectedFeatures(selected); + }, + + getSequenceForSelectedFeatures: function(records) { + var track = this; + + var content = dojo.create("div"); + var textArea = dojo.create("textarea", { className: "sequence_area", readonly: true }, content); + var form = dojo.create("form", { }, content); + var peptideButtonDiv = dojo.create("div", { className: "first_button_div" }, form); + var peptideButton = dojo.create("input", { type: "radio", name: "type", checked: true }, peptideButtonDiv); + var peptideButtonLabel = dojo.create("label", { innerHTML: "Peptide sequence", className: "button_label" }, peptideButtonDiv); + var cdnaButtonDiv = dojo.create("div", { className: "button_div" }, form); + var cdnaButton = dojo.create("input", { type: "radio", name: "type" }, cdnaButtonDiv); + var cdnaButtonLabel = dojo.create("label", { innerHTML: "cDNA sequence", className: "button_label" }, cdnaButtonDiv); + var cdsButtonDiv = dojo.create("div", { className: "button_div" }, form); + var cdsButton = dojo.create("input", { type: "radio", name: "type" }, cdsButtonDiv); + var cdsButtonLabel = dojo.create("label", { innerHTML: "CDS sequence", className: "button_label" }, cdsButtonDiv); + var genomicButtonDiv = dojo.create("div", { className: "button_div" }, form); + var genomicButton = dojo.create("input", { type: "radio", name: "type" }, genomicButtonDiv); + var genomicButtonLabel = dojo.create("label", { innerHTML: "Genomic sequence", className: "button_label" }, genomicButtonDiv); + var genomicWithFlankButtonDiv = dojo.create("div", { className: "button_div" }, form); + var genomicWithFlankButton = dojo.create("input", { type: "radio", name: "type" }, genomicWithFlankButtonDiv); + var genomicWithFlankButtonLabel = dojo.create("label", { innerHTML: "Genomic sequence +/-", className: "button_label" }, genomicWithFlankButtonDiv); + var genomicWithFlankField = dojo.create("input", { type: "text", size: 5, className: "button_field", value: "500" }, genomicWithFlankButtonDiv); + var genomicWithFlankFieldLabel = dojo.create("label", { innerHTML: "bases", className: "button_label" }, genomicWithFlankButtonDiv); + + var fetchSequence = function(type) { + var features = '"features": ['; + for (var i = 0; i < records.length; ++i) { + var record = records[i]; + var annot = record.feature; + var seltrack = record.track; + var uniqueName = annot.id(); + // just checking to ensure that all features in selection are from this track + if (seltrack === track) { + var trackdiv = track.div; + var trackName = track.getUniqueTrackName(); + + if (i > 0) { + features += ','; + } + features += ' { "uniquename": "' + uniqueName + '" } '; + } + } + features += ']'; + var operation = "get_sequence"; + var trackName = track.getUniqueTrackName(); + var postData = '{ "track": "' + trackName + '", ' + features + ', "operation": "' + operation + '"'; + var flank = 0; + if (type == "genomic_with_flank") { + flank = dojo.attr(genomicWithFlankField, "value"); + postData += ', "flank": ' + flank; + type = "genomic"; + } + postData += ', "type": "' + type + '" }'; + dojo.xhrPost( { + postData: postData, + url: context_path + "/AnnotationEditorService", + handleAs: "json", + timeout: 5000 * 1000, // Time in milliseconds + load: function(response, ioArgs) { + var textAreaContent = ""; + for (var i = 0; i < response.features.length; ++i) { + var feature = response.features[i]; + var cvterm = feature.type; + var residues = feature.residues; + textAreaContent += ">" + feature.uniquename + " (" + cvterm.cv.name + ":" + cvterm.name + ") " + residues.length + " residues [" + type + (flank > 0 ? " +/- " + flank + " bases" : "") + "]\n"; + var lineLength = 70; + for (var j = 0; j < residues.length; j += lineLength) { + textAreaContent += residues.substr(j, lineLength) + "\n"; + } + } + dojo.attr(textArea, "innerHTML", textAreaContent); + }, + // The ERROR function will be called in an error case. + error: function(response, ioArgs) { + track.handleError(response); + console.log("Annotation server error--maybe you forgot to login to the server?"); + console.error("HTTP status code: ", ioArgs.xhr.status); + // + //dojo.byId("replace").innerHTML = 'Loading the resource from the server did not work'; + return response; + } + + }); + }; + var callback = function(event) { + var type; + var target = event.target || event.srcElement; + if (target == peptideButton || target == peptideButtonLabel) { + dojo.attr(peptideButton, "checked", true); + type = "peptide"; + } + else if (target == cdnaButton || target == cdnaButtonLabel) { + dojo.attr(cdnaButton, "checked", true); + type = "cdna"; + } + else if (target == cdsButton || target == cdsButtonLabel) { + dojo.attr(cdsButton, "checked", true); + type = "cds"; + } + else if (target == genomicButton || target == genomicButtonLabel) { + dojo.attr(genomicButton, "checked", true); + type = "genomic"; + } + else if (target == genomicWithFlankButton || target == genomicWithFlankButtonLabel) { + dojo.attr(genomicWithFlankButton, "checked", true); + type = "genomic_with_flank"; + } + fetchSequence(type); + }; + + dojo.connect(peptideButton, "onchange", null, callback); + dojo.connect(peptideButtonLabel, "onclick", null, callback); + dojo.connect(cdnaButton, "onchange", null, callback); + dojo.connect(cdnaButtonLabel, "onclick", null, callback); + dojo.connect(cdsButton, "onchange", null, callback); + dojo.connect(cdsButtonLabel, "onclick", null, callback); + dojo.connect(genomicButton, "onchange", null, callback); + dojo.connect(genomicButtonLabel, "onclick", null, callback); + dojo.connect(genomicWithFlankButton, "onchange", null, callback); + dojo.connect(genomicWithFlankButtonLabel, "onclick", null, callback); + + fetchSequence("peptide"); + this.openDialog("Sequence", content); + }, + + searchSequence: function() { + var track = this; + var starts = new Object(); + var browser = track.gview.browser; + for (i in browser.allRefs) { + var refSeq = browser.allRefs[i]; + starts[refSeq.name] = refSeq.start; + } + var search = new SequenceSearch(context_path); + search.setRedirectCallback(function(id, fmin, fmax) { + var loc = id + ":" + fmin + "-" + fmax; + if (id == track.refSeq.name) { + track.gview.browser.navigateTo(loc); + track.popupDialog.hide(); + } + else { + var url = window.location.toString().replace(/loc=.+/, "loc=" + loc); + window.location.replace(url); + } + }); + search.setErrorCallback(function(response) { + track.handleError(response); + }); + var content = search.searchSequence(track.getUniqueTrackName(), track.refSeq.name, starts); + if (content) { + this.openDialog("Search sequence", content); + } + }, + + exportData: function(key, options) { + var track = this; + var adapter = key; + var content = dojo.create("div"); + var waitingDiv = dojo.create("div", { innerHTML: "" }, content); + var responseDiv = dojo.create("div", { className: "export_response" }, content); +// var responseIFrame = dojo.create("iframe", { class: "export_response_iframe" }, responseDiv); + + dojo.xhrGet( { + url: context_path + "/IOService?operation=write&adapter=" + adapter + "&track=" + track.getUniqueTrackName() + "&" + options, + handleAs: "text", + timeout: 5000 * 1000, // Time in milliseconds + load: function(response, ioArgs) { + console.log("/IOService returned, called load()"); + dojo.style(waitingDiv, { display: "none" } ); + response = response.replace("href='", "href='../"); + + /* + var iframeDoc = responseIFrame.contentWindow.document; + iframeDoc.open(); + iframeDoc.write(response); + iframeDoc.close(); + */ + responseDiv.innerHTML = response; + }, + // The ERROR function will be called in an error case. + error: function(response, ioArgs) { + dojo.style(waitingDiv, { display: "none" } ); + responseDiv.innerHTML = "Unable to export data"; + track.handleError(response); + } + }); + track.openDialog("Export " + key, content); + }, + + zoomToBaseLevel: function(event) { + var coordinate = this.getGenomeCoord(event); + this.gview.zoomToBaseLevel(event, coordinate); + }, + + zoomBackOut: function(event) { + this.gview.zoomBackOut(event); + }, + + handleError: function(response) { + console.log("ERROR: "); + console.log(response); // in Firebug, allows retrieval of stack trace, jump to code, etc. + console.log(response.stack); + var error = eval('(' + response.responseText + ')'); + // var error = response.error ? response : eval('(' + response.responseText + ')'); + if (error && error.error) { + alert(error.error); + return false; + } + }, + + handleConfirm: function(response) { + return confirm(response); + }, + + + initAnnotContextMenu: function() { + var thisObj = this; + contextMenuItems = new Array(); + annot_context_menu = new dijit.Menu({}); + var permission = thisObj.permission; + var index = 0; + annot_context_menu.addChild(new dijit.MenuItem( { + label: "Information", + onClick: function(event) { + thisObj.getAnnotationInformation(); + } + } )); + contextMenuItems["information"] = index++; + annot_context_menu.addChild(new dijit.MenuItem( { + label: "Get sequence", + onClick: function(event) { + thisObj.getSequence(); + } + } )); + contextMenuItems["get_sequence"] = index++; + annot_context_menu.addChild(new dijit.MenuItem( { + label: "Zoom to base level", + onClick: function(event) { + if (thisObj.getMenuItem("zoom_to_base_level").get("label") == "Zoom to base level") { + thisObj.zoomToBaseLevel(thisObj.annot_context_mousedown); + } + else { + thisObj.zoomBackOut(thisObj.annot_context_mousedown); + } + } + } )); + contextMenuItems["zoom_to_base_level"] = index++; + if (permission & Permission.WRITE) { + annot_context_menu.addChild(new dijit.MenuSeparator()); + index++; + annot_context_menu.addChild(new dijit.MenuItem( { + label: "Delete", + onClick: function() { + thisObj.deleteSelectedFeatures(); + } + } )); + contextMenuItems["delete"] = index++; + annot_context_menu.addChild(new dijit.MenuItem( { + label: "Merge", + onClick: function() { + thisObj.mergeSelectedFeatures(); + } + } )); + contextMenuItems["merge"] = index++; + annot_context_menu.addChild(new dijit.MenuItem( { + label: "Split", + onClick: function(event) { + // use annot_context_mousedown instead of current event, since want to split + // at mouse position of event that triggered annot_context_menu popup + thisObj.splitSelectedFeatures(thisObj.annot_context_mousedown); + } + } )); + contextMenuItems["split"] = index++; + annot_context_menu.addChild(new dijit.MenuItem( { + label: "Duplicate", + onClick: function(event) { + // use annot_context_mousedown instead of current event, since want to split + // at mouse position of event that triggered annot_context_menu popup + thisObj.duplicateSelectedFeatures(thisObj.annot_context_mousedown); + } + } )); + contextMenuItems["duplicate"] = index++; + annot_context_menu.addChild(new dijit.MenuItem( { + label: "Make intron", + // use annot_context_mousedown instead of current event, since want to split + // at mouse position of event that triggered annot_context_menu popup + onClick: function(event) { + thisObj.makeIntron(thisObj.annot_context_mousedown); + } + } )); + contextMenuItems["make_intron"] = index++; + annot_context_menu.addChild(new dijit.MenuItem( { + label: "Set translation start", + // use annot_context_mousedown instead of current event, since want to split + // at mouse position of event that triggered annot_context_menu popup + onClick: function(event) { + if (thisObj.getMenuItem("set_translation_start").get("label") == "Set translation start") { + thisObj.setTranslationStart(thisObj.annot_context_mousedown); + } + else { + thisObj.setLongestORF(); + } + } + } )); + contextMenuItems["set_translation_start"] = index++; + annot_context_menu.addChild(new dijit.MenuItem( { + label: "Flip strand", + onClick: function(event) { + thisObj.flipStrand(); + } + } )); + contextMenuItems["flip_strand"] = index++; + annot_context_menu.addChild(new dijit.MenuSeparator()); + index++; + annot_context_menu.addChild(new dijit.MenuItem( { + label: "Comments", + onClick: function(event) { + thisObj.editComments(); + } + } )); + contextMenuItems["edit_comments"] = index++; + annot_context_menu.addChild(new dijit.MenuItem( { + label: "DBXRefs", + onClick: function(event) { + thisObj.editDbxrefs(); + } + } )); + contextMenuItems["edit_dbxrefs"] = index++; + annot_context_menu.addChild(new dijit.MenuSeparator()); + index++; + annot_context_menu.addChild(new dijit.MenuItem( { + label: "Undo", + onClick: function(event) { + thisObj.undo(); + } + } )); + contextMenuItems["undo"] = index++; + annot_context_menu.addChild(new dijit.MenuItem( { + label: "Redo", + onClick: function(event) { + thisObj.redo(); + } + } )); + contextMenuItems["redo"] = index++; + annot_context_menu.addChild(new dijit.MenuItem( { + label: "History", + onClick: function(event) { + thisObj.getHistory(); + } + } )); + contextMenuItems["history"] = index++; + } + + annot_context_menu.onOpen = function(event) { + // keeping track of mousedown event that triggered annot_context_menu popup, + // because need mouse position of that event for some actions + thisObj.annot_context_mousedown = thisObj.last_mousedown_event; + if (thisObj.permission & Permission.WRITE) { + thisObj.updateMenu(); + } + dojo.forEach(this.getChildren(), function(item, idx, arr) { + if (item instanceof dijit.MenuItem) { + item._setSelected(false); + item._onUnhover(); + } + }); + }; + + annot_context_menu.startup(); +}, + +/** + * hacking addition of a "tools" menu to standard JBrowse menubar, + * with a "Search Sequence" dropdown + */ +initSearchMenu: function() { + var thisObj = this; + this.browser.addGlobalMenuItem( 'tools', + new dijitMenuItem( + { + label: "Search sequence", + onClick: function() { + thisObj.searchSequence(); + } + }) ); + var toolMenu = this.browser.makeGlobalMenu('tools'); + if( toolMenu ) { + var toolButton = new dijitDropDownButton( + { className: 'file', + innerHTML: 'Tools', + //title: '', + dropDown: toolMenu + }); + dojo.addClass( toolButton.domNode, 'menu' ); + this.browser.menuBar.appendChild( toolButton.domNode ); + } +}, + +/** + * Add AnnotTrack data save option to track label pulldown menu + * Trying to make it a replacement for default JBrowse data save option from ExportMixin + * (turned off JBrowse default via config.noExport = true) + */ +initSaveMenu: function() { + var thisObj = this; + var dataAdaptersMenu = new dijit.Menu(); + dojo.xhrPost( { + sync: true, + postData: '{ "track": "' + thisObj.getUniqueTrackName() + '", "operation": "get_data_adapters" }', + url: context_path + "/AnnotationEditorService", + handleAs: "json", + timeout: 5 * 1000, // Time in milliseconds + // The LOAD function will be called on a successful response. + load: function(response, ioArgs) { // + var dataAdapters = response.data_adapters; + for (var i = 0; i < dataAdapters.length; ++i) { + var dataAdapter = dataAdapters[i]; + if (thisObj.permission & dataAdapter.permission) { + dataAdaptersMenu.addChild(new dijit.MenuItem( { + label: dataAdapter.key, + onClick: function(key, options) { + return function() { + thisObj.exportData(key, options); + }; + }(dataAdapter.key, dataAdapter.options) + })); + } + } + }, + error: function(response, ioArgs) { // +// thisObj.handleError(response); + } + }); + + // if there's a menu separator, add right before first seperator (which is where default save is added), + // otherwise add at end + var mitems = this.trackMenu.getChildren(); + for (var mindex=0; mindex < mitems.length; mindex++) { + if (mitems[mindex].type == "dijit/MenuSeparator") { break; } + } + var savePopup = new dijit.PopupMenuItem({ + label: "Save track data", + iconClass: 'dijitIconSave', + popup: dataAdaptersMenu }); + this.trackMenu.addChild(savePopup, mindex); +}, + + getPermission: function( callback ) { + var thisObj = this; + var loadCallback = callback; + var success = true; + dojo.xhrPost( { + sync: true, + postData: '{ "track": "' + thisObj.getUniqueTrackName() + '", "operation": "get_user_permission" }', + url: context_path + "/AnnotationEditorService", + handleAs: "json", + timeout: 5 * 1000, // Time in milliseconds + // The LOAD function will be called on a successful response. + load: function(response, ioArgs) { // + var permission = response.permission; + thisObj.permission = permission; + if (loadCallback) { loadCallback(permission); }; + }, + error: function(response, ioArgs) { // + thisObj.handleError(response); + success = false; + } + }); + return success; + }, + + initPopupDialog: function() { + var track = this; + var id = "popup_dialog"; + + // deregister widget (needed if changing refseq without reloading page) + var widget = dijit.registry.byId(id); + if (widget) { + widget.destroy(); + } + track.popupDialog = new dijitDialog({ + preventCache: true, + id: id + }); + dojo.connect(track.popupDialog, "onHide", null, function() { + document.activeElement.blur(); + track.selectionManager.clearSelection(); + if (track.getSequenceTrack()) { + track.getSequenceTrack().clearHighlightedBases(); + } + }); + track.popupDialog.startup(); + + }, + + getUniqueTrackName: function() { + return this.name + "-" + this.refSeq.name; + }, + + openDialog: function(title, data) { + this.popupDialog.set("title", title); + this.popupDialog.set("content", data); + this.popupDialog.show(); + this.popupDialog.placeAt("GenomeBrowser", "first"); + }, + + updateMenu: function() { + this.updateSetTranslationStartMenuItem(); + this.updateMergeMenuItem(); + this.updateSplitMenuItem(); + this.updateMakeIntronMenuItem(); + this.updateFlipStrandMenuItem(); + this.updateEditCommentsMenuItem(); + this.updateEditDbxrefsMenuItem(); + this.updateUndoMenuItem(); + this.updateRedoMenuItem(); + this.updateZoomToBaseLevelMenuItem(); + this.updateDuplicateMenuItem(); + }, + + updateSetTranslationStartMenuItem: function() { + var menuItem = this.getMenuItem("set_translation_start"); + var selected = this.selectionManager.getSelection(); + if (selected.length > 1) { + menuItem.set("disabled", true); + return; + } + menuItem.set("disabled", false); + var selectedFeat = selected[0].feature; + if (selectedFeat.parent()) { + selectedFeat = selectedFeat.parent(); + } + if (selectedFeat.get('manuallySetTranslationStart')) { + menuItem.set("label", "Unset translation start"); + } + else { + menuItem.set("label", "Set translation start"); + } + }, + + updateMergeMenuItem: function() { + var menuItem = this.getMenuItem("merge"); + var selected = this.selectionManager.getSelection(); + if (selected.length < 2) { + menuItem.set("disabled", true); + return; + } + var strand = selected[0].feature.get('strand'); + for (var i = 1; i < selected.length; ++i) { + if (selected[i].feature.get('strand') != strand) { + menuItem.set("disabled", true); + return; + } + } + menuItem.set("disabled", false); + }, + + updateSplitMenuItem: function() { + var menuItem = this.getMenuItem("split"); + var selected = this.selectionManager.getSelection(); + if (selected.length > 2) { + menuItem.set("disabled", true); + return; + } + var parent = selected[0].feature.parent(); + for (var i = 1; i < selected.length; ++i) { + if (selected[i].feature.parent() != parent) { + menuItem.set("disabled", true); + return; + } + } + menuItem.set("disabled", false); + }, + + updateMakeIntronMenuItem: function() { + var menuItem = this.getMenuItem("make_intron"); + var selected = this.selectionManager.getSelection(); + if( selected.length > 1) { + menuItem.set("disabled", true); + return; + } + menuItem.set("disabled", false); + }, + + updateFlipStrandMenuItem: function() { + var menuItem = this.getMenuItem("flip_strand"); + }, + + updateEditCommentsMenuItem: function() { + var menuItem = this.getMenuItem("edit_comments"); + var selected = this.selectionManager.getSelection(); + var parent = AnnotTrack.getTopLevelAnnotation(selected[0].feature); + for (var i = 1; i < selected.length; ++i) { + if (AnnotTrack.getTopLevelAnnotation(selected[i].feature) != parent) { + menuItem.set("disabled", true); + return; + } + } + menuItem.set("disabled", false); + }, + + updateEditDbxrefsMenuItem: function() { + var menuItem = this.getMenuItem("edit_dbxrefs"); + var selected = this.selectionManager.getSelection(); + var parent = AnnotTrack.getTopLevelAnnotation(selected[0].feature); + for (var i = 1; i < selected.length; ++i) { + if (AnnotTrack.getTopLevelAnnotation(selected[i].feature) != parent) { + menuItem.set("disabled", true); + return; + } + } + menuItem.set("disabled", false); + }, + + updateUndoMenuItem: function() { + var menuItem = this.getMenuItem("undo"); + var selected = this.selectionManager.getSelection(); + if (selected.length > 1) { + menuItem.set("disabled", true); + return; + } + menuItem.set("disabled", false); + }, + + updateRedoMenuItem: function() { + var menuItem = this.getMenuItem("redo"); + var selected = this.selectionManager.getSelection(); + if (selected.length > 1) { + menuItem.set("disabled", true); + return; + } + menuItem.set("disabled", false); + }, + + + updateHistoryMenuItem: function() { + var menuItem = this.getMenuItem("history"); + var selected = this.selectionManager.getSelection(); + if (selected.length > 1) { + menuItem.set("disabled", true); + return; + } + menuItem.set("disabled", false); + }, + + updateZoomToBaseLevelMenuItem: function() { + var menuItem = this.getMenuItem("zoom_to_base_level"); + if( !this.gview.isZoomedToBase() ) { + menuItem.set("label", "Zoom to base level"); + } + else { + menuItem.set("label", "Zoom back out"); + } + }, + + updateDuplicateMenuItem: function() { + var menuItem = this.getMenuItem("duplicate"); + var selected = this.selectionManager.getSelection(); + var parent = AnnotTrack.getTopLevelAnnotation(selected[0].feature); + for (var i = 1; i < selected.length; ++i) { + if (AnnotTrack.getTopLevelAnnotation(selected[i].feature) != parent) { + menuItem.set("disabled", true); + return; + } + } + menuItem.set("disabled", false); + }, + + getMenuItem: function(operation) { + return annot_context_menu.getChildren()[contextMenuItems[operation]]; + }, + + sortAnnotationsByLocation: function(annots) { + var track = this; + return annots.sort(function(annot1, annot2) { + var start1 = annot1.get("start"); + var end1 = annot1.get("end"); + var start2 = annot2.get("start"); + var end2 = annot2.get('end'); + + if (start1 != start2) { return start1 - start2; } + else if (end1 != end2) { return end1 - end2; } + else { return 0; } + /* + if (annot1[track.fields["start"]] != annot2[track.fields["start"]]) { + return annot1[track.fields["start"]] - annot2[track.fields["start"]]; + } + if (annot1[track.fields["end"]] != annot2[track.fields["end"]]) { + return annot1[track.fields["end"]] - annot2[track.fields["end"]]; + } + return 0; + */ + }); + }, + + showRange: function(first, last, startBase, bpPerBlock, scale, + containerStart, containerEnd) { + // console.log("called AnnotTrack.showRange()"); + this.inherited( arguments ); + + // console.log("after calling annot track.showRange(), block range: " + + // this.firstAttached + "--" + this.lastAttached + ", " + (this.lastAttached - this.firstAttached)); + + // handle showing base residues for selected here? + // selected feats + // ==> selected feat divs + // ==> selected "rows" + // ==> (A) float SequenceTrack-like residues layer (with blocks) on each selected row? + // OR (B) just get all residues needed and float simple div (no blocks) + // but set up so that callback for actual render happens once all needed residues + // are available + // can do this way while still using SequenceTrack.getRange function + // + // update: + // OR (C), hybrid of A and B, block-based AND leveraging SequenceTrack.getRange() + // originally tried (B), but after struggling a bit with SequenceTrack.getRange() etc., now leaning + // trying (C) + /* + var track = this; + if (scale === track.browserParams.charWidth) { + // need to float sequence residues over selected row(s) + var seqTrack = this.getSequenceTrack(); + seqTrack.getRange(containerStart, containerEnd, + // see + // callback, gets called for every block that overlaps with containerStart->containerEnd range + // start = genome coord of first bp of block + // end = genome coord of + function(start, end, seq) { + + } + ); + } + */ + }, + + /** + * handles adding overlay of sequence residues to "row" of selected feature + * (also handled in similar manner in fillBlock()); + * WARNING: + * this _requires_ browser support for pointer-events CSS property, + * (currently supported by Firefox 3.6+, Chrome 4.0+, Safari 4.0+) + * (Exploring possible workarounds for IE, for example see: + * http://www.vinylfox.com/forwarding-mouse-events-through-layers/ + * http://stackoverflow.com/questions/3680429/click-through-a-div-to-underlying-elements + * [ see section on CSS conditional statement workaround for IE ] + * ) + * and must set "pointer-events: none" in CSS rule for div.annot-sequence + * otherwise, since sequence overlay is rendered on top of selected features + * (and is a sibling of feature divs), events intended for feature divs will + * get caught by overlay and not make it to the feature divs + */ + selectionAdded: function( rec, smanager) { + var feat = rec.feature; + this.inherited( arguments ); + + var track = this; + + // switched to only have most recent selected annot have residues overlay if zoomed to base level, + // rather than all selected annots + // therefore want to revove all prior residues overlay divs + if (rec.track === track) { + // remove sequence text nodes + $("div.annot-sequence", track.div).remove(); + } + + // want to get child of block, since want position relative to block + // so get top-level feature div (assumes top level feature is always rendered...) + var topfeat = AnnotTrack.getTopLevelAnnotation(feat); + var featdiv = track.getFeatDiv(topfeat); + if (featdiv) { + var strand = topfeat.get('strand'); + var selectionYPosition = $(featdiv).position().top; + var scale = track.gview.bpToPx(1); + if (scale === track.gview.charWidth && track.useResiduesOverlay) { + var seqTrack = this.getSequenceTrack(); + for (var bindex = this.firstAttached; bindex <= this.lastAttached; bindex++) { + var block = this.blocks[bindex]; + // seqTrack.getRange(block.startBase, block.endBase, + // seqTrack.sequenceStore.getRange(this.refSeq, block.startBase, block.endBase, + seqTrack.sequenceStore.getFeatures({ ref: this.refSeq.name, start: block.startBase, end: block.endBase }, + function(feat) { + var start = feat.get('start'); + var end = feat.get('end'); + var seq = feat.get('seq'); + + // var ypos = $(topfeat).position().top; + // +2 hardwired adjustment to center (should be calc'd based on feature div dims? + var ypos = selectionYPosition + 2; + // checking to see if residues for this "row" of the block are already present + // ( either from another selection in same row, or previous rendering + // of same selection [which often happens when scrolling] ) + // trying to avoid duplication both for efficiency and because re-rendering of text can + // be slighly off from previous rendering, leading to bold / blurry text when overlaid + + var $seqdivs = $("div.annot-sequence", block); + var sindex = $seqdivs.length; + var add_residues = true; + if ($seqdivs && sindex > 0) { + for (var i=0; i 0 ) { + // if selected annotations, then hide residues overlay + // (in case zoomed in to base pair resolution and the residues overlay is being displayed) + $(".annot-sequence", this.div).css('display', 'none'); + } + }, + + // , + // endZoom: function(destScale, destBlockBases) { + // DraggableFeatureTrack.prototype.endZoom.call(this, destScale, destBlockBases); + // }; + + executeUpdateOperation: function(postData, loadCallback) { + if (!this.listener || this.listener.fired != -1 ) { + this.handleError({responseText: '{ error: "Server connection error - try reloading the page" }'}); + return; + } + dojo.xhrPost( { + postData: postData, + url: context_path + "/AnnotationEditorService", + handleAs: "json", + timeout: 1000 * 1000, // Time in milliseconds + load: function(response, ioArgs) { // + if (loadCallback) { + loadCallback(response); + } + }, + error: function(response, ioArgs) { // + track.handleError(response); + return response; + } + }); + } + +}); + +AnnotTrack.getTopLevelAnnotation = function(annotation) { + while( annotation.parent() ) { + annotation = annotation.parent(); + } + return annotation; +}; + +return AnnotTrack; +}); + +/* + Copyright (c) 2010-2011 Berkeley Bioinformatics Open Projects (BBOP) + + This package and its accompanying libraries are free software; you can + redistribute it and/or modify it under the terms of the LGPL (either + version 2.1, or at your option, any later version) or the Artistic + License 2.0. Refer to LICENSE for the full license text. + +*/ diff --git a/plugins/WebApollo/js/View/Track/DraggableAlignments.js b/plugins/WebApollo/js/View/Track/DraggableAlignments.js new file mode 100644 index 0000000000..ab6e1c3f18 --- /dev/null +++ b/plugins/WebApollo/js/View/Track/DraggableAlignments.js @@ -0,0 +1,53 @@ +define([ + 'dojo/_base/declare', + 'JBrowse/View/Track/Alignments', + 'WebApollo/View/Track/DraggableHTMLFeatures', + 'JBrowse/Util', + ], + function( + declare, + AlignmentsTrack, + DraggableTrack, + Util + ) { + +return declare([ DraggableTrack, AlignmentsTrack ], { + + constructor: function( args ) { + // forcing store to create subfeatures, unless config.subfeatures explicitly set to false + // default is set to true in _defaultConfig() + this.store.createSubfeatures = this.config.subfeatures; + }, + + _defaultConfig: function() { + var thisConfig = Util.deepUpdate( +// return Util.deepUpdate( + dojo.clone( this.inherited(arguments) ), + { + layoutPitchY: 2, + subfeatures: true, + style: { + className: "bam-read", + renderClassName: null, + arrowheadClass: "arrowhead", + centerChildrenVertically: false, + showSubfeatures: true, + showMismatches: false, + showLabels: false, + subfeatureClasses: { + M: "cigarM", + D: "cigarD", + N: "cigarN", + E: "cigarEQ", /* "=" converted to "E" in BAM/LazyFeature subfeature construction */ + X: "cigarX", + I: "cigarI" + } + } + } + ); + return thisConfig; + } + +} ); + +}); \ No newline at end of file diff --git a/plugins/WebApollo/js/View/Track/DraggableHTMLFeatures.js b/plugins/WebApollo/js/View/Track/DraggableHTMLFeatures.js new file mode 100644 index 0000000000..882521c869 --- /dev/null +++ b/plugins/WebApollo/js/View/Track/DraggableHTMLFeatures.js @@ -0,0 +1,1178 @@ +define( [ + 'dojo/_base/declare', + 'dojo/_base/array', + 'JBrowse/View/Track/HTMLFeatures', + 'WebApollo/FeatureSelectionManager', + 'dijit/Menu', + 'dijit/MenuItem', + 'dijit/CheckedMenuItem', + 'dijit/Dialog', + 'jquery', + 'jqueryui/draggable', + 'JBrowse/Util', + 'JBrowse/Model/SimpleFeature', + 'WebApollo/SequenceOntologyUtils' + ], + function( declare, array, HTMLFeatureTrack, FeatureSelectionManager, dijitMenu, dijitMenuItem, dijitCheckedMenuItem, dijitDialog, $, draggable, Util, SimpleFeature, SeqOnto ) { + +/* Subclass of FeatureTrack that allows features to be selected, + and dragged and dropped into the annotation track to create annotations. + + WARNING: + for selection to work for features that cross block boundaries, z-index of feature style MUST be set, and must be > 0 + otherwise what happens is: + feature div inherits z-order from parent, so same z-order as block + so feature div pixels may extend into next block, but next block draws ON TOP OF IT (assuming next block added + to parent after current block). So events over part of feature div that isn't within it's parent block will never + reach feature div but instead be triggered on next block + This issue will be more obvious if blocks have background color set since then not only will selection not work but + part of feature div that extends into next block won't even be visible, since next block background will render over it + */ + +var debugFrame = false; + +//var DraggableFeatureTrack = declare( HTMLFeatureTrack, +var draggableTrack = declare( HTMLFeatureTrack, + +{ + // so is dragging + dragging: false, + + _defaultConfig: function() { + return Util.deepUpdate( + dojo.clone( this.inherited(arguments) ), + { + style: { + // className: "{type}", // feature classname gets set to feature.get('type') + className: "container-12px", + renderClassName: "gray-center-30pct", + arrowheadClass: "webapollo-arrowhead", + subfeatureClasses: { + UTR: "webapollo-UTR", + CDS: "webapollo-CDS", + exon: "container-100pct", + wholeCDS: null, + match_part: "darkblue-80pct" + }, + + // renderClassName: 'DraggableFeatureTrack' ??? + // setting minSubfeatureWidth to 1 insures subfeatures will almost always get drawn, + minSubfeatureWidth: 1, + centerChildrenVertically: false + }, + events: { + // need to map click to a null-op, to override default JBrowse click behavior for click on features + // (JBrowse default is feature detail popup) + click: function(event) { + // not quite a null-op, also need to suprress propagation of click recursively up through parent divs, + // in order to stop default JBrowse behavior for click on tracks (which is to recenter view at click point) + event.stopPropagation(); + } + // WebApollo can't set up mousedown --> onFeatureMouseDown() in config.events, + // because dojo.on used by JBrowse config-based event setup doesn't play nice with + // JQuery event retriggering via _mousedown() for feature drag bootstrapping + // also, JBrowse only sets these events for features, and WebApollo needs them to trigger for subfeatures as well + // , mousedown: dojo.hitch( this, 'onFeatureMouseDown' ), + // , dblclick: dojo.hitch( this, 'onFeatureDoubleClick' ) + } + } + ); + }, + + constructor: function( args ) { + + console.log("DragableFeatureTrack constructor called"); + + this.gview = this.browser.view; + // get a handle to on the main WA object + this.browser.getPlugin( 'WebApollo', dojo.hitch( this, function(p) { + this.webapollo = p; + })); + + // DraggableFeatureTracks all share the same FeatureSelectionManager + // if want subclasses to have different selection manager, + // call this.setSelectionManager in subclass (after calling parent constructor) + this.setSelectionManager( this.webapollo.featSelectionManager ); + + // CSS class for selected features + // override if want subclass to have different CSS class for selected features + this.selectionClass = "selected-feature"; + + // DraggableFeatureTrack.selectionManager.addListener(this); + + this.last_whitespace_mousedown_loc = null; + this.last_whitespace_mouseup_time = new Date(); // dummy timestamp + this.prev_selection = null; + + this.verbose = false; + this.verbose_selection = false; + this.verbose_selection_notification = false; + this.verbose_drag = false; + this.drag_enabled = true; + + this.feature_context_menu = null; + + /** hack to determine which tracks to apply edge matching to + would rather do a check for whether track is instance of DraggableHTMLFeatures (or possibly HTMLFeatures), + but use of dojo.declare() for classes means track object's class is actually base Object. + */ + this.edge_matching_enabled = true; + }, + + + loadSuccess: function(trackInfo) { + /* if subclass indicates it has custom context menu, do not initialize default feature context menu */ + if (! this.has_custom_context_menu) { + this.initFeatureContextMenu(); + this.initFeatureDialog(); + } + this.inherited( arguments ); + }, + + setSelectionManager: function(selman) { + if (this.selectionManager) { + this.selectionManager.removeListener(this); + } + this.selectionManager = selman; + // FeatureSelectionManager listeners must implement + // selectionAdded() and selectionRemoved() response methods + this.selectionManager.addListener(this); + return selman; + }, + +/** + * only called once, during track setup ??? + * + * doublclick in track whitespace is used by JBrowse for zoom + * but WebApollo/JBrowse uses single click in whitespace to clear selection + * + * so this sets up mousedown/mouseup/doubleclick + * kludge to restore selection after a double click to whatever selection was before + * initiation of doubleclick (first mousedown/mouseup) + * + */ + setViewInfo: function(genomeView, numBlocks, + trackDiv, labelDiv, + widthPct, widthPx, scale) { + this.inherited( arguments ); + + var $div = $(this.div); + var track = this; + + // this.scale = scale; // scale is in pixels per base + + // setting up mousedown and mouseup handlers to enable click-in-whitespace to clear selection + // (without conflicting with JBrowse drag-in-whitespace to scroll) + $div.bind('mousedown', function(event) { + var target = event.target; + if (! (target.feature || target.subfeature)) { + track.last_whitespace_mousedown_loc = [ event.pageX, event.pageY ]; + } + } ); + $div.bind('mouseup', function(event) { + var target = event.target; + if (! (target.feature || target.subfeature)) { // event not on feature, so must be on whitespace + var xup = event.pageX; + var yup = event.pageY; + // if click in whitespace without dragging (no movement between mouse down and mouse up, + // and no shift modifier, + // then deselect all + if (this.verbose_selection) { console.log("mouse up on track whitespace"); } + var eventModifier = event.shiftKey || event.altKey || event.metaKey || event.ctrlKey; + if (track.last_whitespace_mousedown_loc && + xup === track.last_whitespace_mousedown_loc[0] && + yup === track.last_whitespace_mousedown_loc[1] && + (! eventModifier )) { + var timestamp = new Date(); + var prev_timestamp = track.last_whitespace_mouseup_time; + track.last_whitespace_mouseup_time = timestamp; + // if less than half a second, probably a doubleclick (or triple or more click...) + var probably_doubleclick = ((timestamp.getTime() - prev_timestamp.getTime()) < 500); + if (probably_doubleclick) { + if (this.verbose_selection) { console.log("mouse up probably part of a doubleclick"); } + // don't record selection state, want to keep prev_selection set + // to selection prior to first mouseup of doubleclick + } + else { + track.prev_selection = track.selectionManager.getSelection(); + if (this.verbose_selection) { + console.log("recording prev selection"); + console.log(track.prev_selection); + } + } + if (this.verbose_selection) { console.log("clearing selection"); } + track.selectionManager.clearSelection(); + } + else { + track.prev_selection = null; + } + } + // regardless of what element it's over, mouseup clears out tracking of mouse down + track.last_whitespace_mousedown_loc = null; + } ); + // kludge to restore selection after a double click to whatever selection was before + // initiation of doubleclick (first mousedown/mouseup) + $div.bind('dblclick', function(event) { + var target = event.target; + // because of dblclick bound to features, will only bubble up to here on whitespace, + // but doing feature check just to make sure + if (! (target.feature || target.subfeature)) { + if (this.verbose_selection) { + console.log("double click on track whitespace"); + console.log("restoring selection after double click"); + console.log(track.prev_selection); + } + if (track.prev_selection) { + var plength = track.prev_selection.length; + // restore selection + for (var i = 0; i bs ) { return 1; } + else if ( as < bs ) { return -1; } + else { return 0; /* shouldn't fall through to here */ } + }, + + + /** + * if feature has translated region (CDS, wholeCDS, start_codon, ???), + * reworks feature's subfeatures for more annotation-editing-friendly selection + * + * Assumes: + * if translated, will either have + * CDS-ish term for each coding segment + * wholeCDS from start of translation to end of translation (so already pre-processed) + * mutually exclusive (either have CDS, or wholeCDS, but not both) + * if wholeCDS present, then pre-processed (no UTRs) + * if any exon-ish types present, then _all_ exons are present with exon-ish types + */ + _processTranslation: function( feature ) { + var track = this; + + var feat_type = feature.get('type'); + + // most very dense genomic feature tracks do not have CDS. Trying to minimize overhead for that case -- + // keep list of types that NEVER have CDS children (match, alignment, repeat, etc.) + // (WARNING in this case not sorting, but sorting (currently) only needed for features with CDS (for reading frame calcs)) + if (SeqOnto.neverHasCDS[feat_type]) { + feature.normalized = true; + return; + } + var subfeats = feature.get('subfeatures'); + + // var cds = subfeats.filter( function(feat) { return feat.get('type') === 'CDS'; } ); + var cds = subfeats.filter( function(feat) { + return SeqOnto.cdsTerms[feat.get('type')]; + } ); + var wholeCDS = subfeats.filter( function(feat) { return feat.get('type') === 'wholeCDS'; } ); + + // most very dense genomic feature tracks do not have CDS. Trying to minimize overhead for that case -- + // if no CDS, no wholeCDS, consider normalized + // (WARNING in this case not sorting, but sorting (currently) only needed for features with CDS (for reading frame calcs)) + // + if (cds.length === 0 && wholeCDS.length === 0) { + feature.normalized = true; + return; + } + + var newsubs; + // wholeCDS is specific to WebApollo, if seen can assume no CDS, and UTR/exon already normalized + if (wholeCDS.length > 0) { + // extract wholecds from subfeats, then sort subfeats + feature.wholeCDS = wholeCDS[0]; + newsubs = subfeats.filter( function(feat) { return feat.get('type') !== 'wholeCDS'; } ); + } + + // if has a CDS, remove CDS from subfeats and sort exons + else if (cds.length > 0) { + cds.sort(this._subfeatSorter); + var cdsmin = cds[0].get('start'); + var cdsmax = cds[cds.length-1].get('end'); + feature.wholeCDS = new SimpleFeature({ parent: feature, + data: { start: cdsmin, end: cdsmax, type: 'wholeCDS', + strand: feature.get('strand') } + } ); + var hasExons = false; + for (var i=0; i 0, guaranteed to have at least one CDS + var exonCount = 0; + var prevStart, prevEnd; + // scan through sorted subfeats, joining abutting UTR/CDS regions + for (var i=0; i displayStart) && (subStart < displayEnd)); + var render = subDiv && (subEnd > displayStart) && (subStart < displayEnd); + + // look for UTR and CDS subfeature class mapping from trackData + // if can't find, then default to parent feature class + "-UTR" or "-CDS" + if( render ) { // subfeatureClases defaults set in this._defaultConfig + UTRclass = this.config.style.subfeatureClasses["UTR"]; + CDSclass = this.config.style.subfeatureClasses["CDS"]; + } + + // if ((subEnd <= displayStart) || (subStart >= displayEnd)) { return undefined; } + + var segDiv; + // console.log("render sub frame"); + // whole exon is untranslated (falls outside wholeCDS range, or no CDS info found) + if( (cdsMin === undefined && cdsMax === undefined) || + (cdsMax <= subStart || cdsMin >= subEnd)) { + if( render ) { + segDiv = document.createElement("div"); + // not worrying about appending "plus-"/"minus-" based on strand yet + dojo.addClass(segDiv, "subfeature"); + dojo.addClass(segDiv, UTRclass); + if (Util.is_ie6) segDiv.appendChild(document.createComment()); + segDiv.style.cssText = + "left: " + (100 * ((subStart - subStart) / subLength)) + "%;" + + "width: " + (100 * ((subEnd - subStart) / subLength)) + "%;"; + subDiv.appendChild(segDiv); + } + } + + /* + Frame is calculated as (3 - ((length-frame) mod 3)) mod 3. + (length-frame) is the length of the previous feature starting at the first whole codon (and thus the frame subtracted out). + (length-frame) mod 3 is the number of bases on the 3' end beyond the last whole codon of the previous feature. + 3-((length-frame) mod 3) is the number of bases left in the codon after removing those that are represented at the 3' end of the feature. + (3-((length-frame) mod 3)) mod 3 changes a 3 to a 0, since three bases makes a whole codon, and 1 and 2 are left unchanged. + */ + // whole exon is translated + else if (cdsMin <= subStart && cdsMax >= subEnd) { + var overhang = priorCdsLength % 3; // number of bases overhanging from previous CDS + var relFrame = (3 - (priorCdsLength % 3)) % 3; + var absFrame, cdsFrame, initFrame; + if (reverse) { + initFrame = (cdsMax - 1) % 3; + absFrame = (subEnd - 1) % 3; + cdsFrame = (3 + absFrame - relFrame) % 3; + } + else { + initFrame = cdsMin % 3; + absFrame = (subStart % 3); + cdsFrame = (absFrame + relFrame) % 3; + } + if (debugFrame) { + console.log("whole exon: " + subStart + " -- ", subEnd, " initFrame: ", initFrame, + ", overhang: " + overhang + ", relFrame: ", relFrame, ", absFrame: ", absFrame, + ", cdsFrame: " + cdsFrame); + } + + if (render) { + segDiv = document.createElement("div"); + // not worrying about appending "plus-"/"minus-" based on strand yet + dojo.addClass(segDiv, "subfeature"); + dojo.addClass(segDiv, CDSclass); + if (Util.is_ie6) segDiv.appendChild(document.createComment()); + segDiv.style.cssText = + "left: " + (100 * ((subStart - subStart) / subLength)) + "%;" + + "width: " + (100 * ((subEnd - subStart) / subLength)) + "%;"; + if (this.config.style.colorCdsFrame || this.webapollo.colorCdsByFrame) { + dojo.addClass(segDiv, "cds-frame" + cdsFrame); + } + subDiv.appendChild(segDiv); + } + priorCdsLength += subLength; + } + // partial translation of exon + else { + // calculate 5'UTR, CDS segment, 3'UTR + var cdsSegStart = Math.max(cdsMin, subStart); + var cdsSegEnd = Math.min(cdsMax, subEnd); + var overhang = priorCdsLength % 3; // number of bases overhanging + var absFrame, cdsFrame, initFrame; + if (priorCdsLength > 0) { + var relFrame = (3 - (priorCdsLength % 3)) % 3; + if (reverse) { + // cdsFrame = ((subEnd-1) + ((3 - (priorCdsLength % 3)) % 3)) % 3; } + initFrame = (cdsMax - 1) % 3; + absFrame = (subEnd - 1) % 3; + cdsFrame = (3 + absFrame - relFrame) % 3; + } + else { + // cdsFrame = (subStart + ((3 - (priorCdsLength % 3)) % 3)) % 3; + initFrame = cdsMin % 3; + absFrame = (subStart % 3); + cdsFrame = (absFrame + relFrame) % 3; + } + if (debugFrame) { console.log("partial exon: " + subStart + ", initFrame: " + (cdsMin % 3) + + ", overhang: " + overhang + ", relFrame: " + relFrame + ", subFrame: " + (subStart % 3) + + ", cdsFrame: " + cdsFrame); } + } + else { // actually shouldn't need this? -- if priorCdsLength = 0, then above conditional collapses down to same calc... + if (reverse) { + cdsFrame = (cdsMax-1) % 3; // console.log("rendering reverse frame"); + } + else { + cdsFrame = cdsMin % 3; + } + } + + var utrStart; + var utrEnd; + // make left UTR (if needed) + if (cdsMin > subStart) { + utrStart = subStart; + utrEnd = cdsSegStart; + if (render) { + segDiv = document.createElement("div"); + // not worrying about appending "plus-"/"minus-" based on strand yet + dojo.addClass(segDiv, "subfeature"); + dojo.addClass(segDiv, UTRclass); + if (Util.is_ie6) segDiv.appendChild(document.createComment()); + segDiv.style.cssText = + "left: " + (100 * ((utrStart - subStart) / subLength)) + "%;" + + "width: " + (100 * ((utrEnd - utrStart) / subLength)) + "%;"; + subDiv.appendChild(segDiv); + } + } + if (render) { + // make CDS segment + segDiv = document.createElement("div"); + // not worrying about appending "plus-"/"minus-" based on strand yet + dojo.addClass(segDiv, "subfeature"); + dojo.addClass(segDiv, CDSclass); + if (Util.is_ie6) segDiv.appendChild(document.createComment()); + segDiv.style.cssText = + "left: " + (100 * ((cdsSegStart - subStart) / subLength)) + "%;" + + "width: " + (100 * ((cdsSegEnd - cdsSegStart) / subLength)) + "%;"; + if (this.config.style.colorCdsFrame || this.webapollo.colorCdsByFrame) { + dojo.addClass(segDiv, "cds-frame" + cdsFrame); + } + subDiv.appendChild(segDiv); + } + priorCdsLength += (cdsSegEnd - cdsSegStart); + + // make right UTR (if needed) + if (cdsMax < subEnd) { + utrStart = cdsSegEnd; + utrEnd = subEnd; + if (render) { + segDiv = document.createElement("div"); + // not worrying about appending "plus-"/"minus-" based on strand yet + dojo.addClass(segDiv, "subfeature"); + dojo.addClass(segDiv, UTRclass); + if (Util.is_ie6) segDiv.appendChild(document.createComment()); + segDiv.style.cssText = + "left: " + (100 * ((utrStart - subStart) / subLength)) + "%;" + + "width: " + (100 * ((utrEnd - utrStart) / subLength)) + "%;"; + subDiv.appendChild(segDiv); + } + } + } + return priorCdsLength; + }, + + + /* + * selection occurs on mouse down + * mouse-down on unselected feature -- deselect all & select feature + * mouse-down on selected feature -- no change to selection (but may start drag?) + * mouse-down on "empty" area -- deselect all + * (WARNING: this is preferred behavior, but conflicts with dblclick for zoom -- zoom would also deselect) + * therefore have mouse-click on empty area deselect all (no conflict with dblclick) + * shift-mouse-down on unselected feature -- add feature to selection + * shift-mouse-down on selected feature -- remove feature from selection + * shift-mouse-down on "empty" area -- no change to selection + * + * "this" should be a featdiv or subfeatdiv + */ + onFeatureMouseDown: function(event) { + // event.stopPropagation(); + if( this.verbose_selection || this.verbose_drag ) { console.log("DFT.onFeatureMouseDown called"); } + console.log("genome coord: " + this.gview.absXtoBp(event.pageX)); + + // drag_create conditional needed in older strategy using trigger(event) for feature drag bootstrapping with JQuery 1.5, + // but not with with JQuery 1.7+ strategy using _mouseDown(event), since _mouseDown call doesn't lead to onFeatureMouseDown() call + // if (this.drag_create) { this.drag_create = null; return; } + this.handleFeatureSelection(event); + if (this.drag_enabled) { + this.handleFeatureDragSetup(event); + } + }, + + handleFeatureSelection: function( event ) { + var ftrack = this; + var selman = ftrack.selectionManager; + var featdiv = (event.currentTarget || event.srcElement); + var feat = featdiv.feature || featdiv.subfeature; + + if( selman.unselectableTypes[feat.get('type')] ) { + return; + } + + var already_selected = selman.isSelected( { feature: feat, track: ftrack } ); + var parent_selected = false; + var parent = feat.parent(); + if (parent) { + parent_selected = selman.isSelected( { feature: parent, track: ftrack } ); + } + if (this.verbose_selection) { + console.log("DFT.handleFeatureSelection() called, actual mouse event"); + console.log(featdiv); + console.log(feat); + console.log("already selected: " + already_selected + ", parent selected: " + parent_selected + + ", shift: " + (event.shiftKey)); + } + // if parent is selected, allow propagation of event up to parent, + // in order to ensure parent draggable setup and triggering + // otherwise stop propagation + if (! parent_selected) { + event.stopPropagation(); + } + if (event.shiftKey) { + if (already_selected) { // if shift-mouse-down and this already selected, deselect this + selman.removeFromSelection( { feature: feat, track: this }); + } + else if (parent_selected) { + // if shift-mouse-down and parent selected, do nothing -- + // event will get propagated up to parent, where parent will get deselected... + // selman.removeFromSelection(parent); + } + else { // if shift-mouse-down and neither this or parent selected, select this + // children are auto-deselected by selection manager when parent is selected + selman.addToSelection({ feature: feat, track: this }); + } + } + else if (event.altKey) { + } + else if (event.ctrlKey) { + } + else if (event.metaKey) { + } + else { // no shift modifier + if (already_selected) { // if this selected, do nothing (this remains selected) + if (this.verbose_selection) { console.log("already selected"); } + } + else { + if (parent_selected) { + // if this not selected but parent selected, do nothing (parent remains selected) + // event will propagate up (since parent_selected), so draggable check + // will be done in bubbled parent event + } + else { // if this not selected and parent not selected, select this + selman.clearSelection(); + selman.addToSelection({ track: this, feature: feat}); + } + } + } + }, + + handleFeatureDragSetup: function(event) { + var ftrack = this; + var featdiv = (event.currentTarget || event.srcElement); + if (this.verbose_drag) { console.log("called handleFeatureDragSetup()"); console.log(featdiv); } + var feat = featdiv.feature || featdiv.subfeature; + var selected = this.selectionManager.isSelected( { feature: feat, track: ftrack }); +/* if (selected) { // simple version (no multiselect ghosting, no event retriggering for simultaneous select & drag) + var $featdiv = $(featdiv); + $featdiv.draggable( { + helper: 'clone', + opacity: 0.5, + axis: 'y', + } ); + } +*/ + /** + * ideally would only make $.draggable call once for each selected div + * but having problems with draggability disappearing from selected divs + * that $.draggable was already called on + * therefore whenever mousedown on a previously selected div also want to + * check that draggability and redo if missing + */ + if (selected) { + var $featdiv = $(featdiv); + if (! $featdiv.hasClass("ui-draggable")) { + if (this.verbose_drag) { + console.log("setting up dragability"); + console.log(featdiv); + } + $featdiv.draggable( // draggable() adds "ui-draggable" class to div + { + // custom helper for pseudo-multi-drag ("pseudo" because multidrag is visual only -- + // handling of draggable when dropped is already done through selection) + // strategy for custom helper is to make a "holder" div with same dimensionsas featdiv + // that's (mostly) a clone of the featdiv draggable is being called on + // (since draggable seems to like that), + // then add clones of all selected feature divs (including another clone of featdiv) + // to holder, with dimensions of each clone recalculated as pixels and set relative to + // featdiv that the drag is actually initiated on (and thus relative to the holder's + // dimensions) + + // helper: 'clone', + helper: function() { + var $featdiv_copy = $featdiv.clone(); + var $holder = $featdiv.clone(); + $holder.removeClass(); + $holder.addClass("custom-multifeature-draggable-helper"); + var holder = $holder[0]; + var featdiv_copy = $featdiv_copy[0]; + + var foffset = $featdiv.offset(); + var fheight = $featdiv.height(); + var fwidth = $featdiv.width(); + var ftop = foffset.top; + var fleft = foffset.left; + if (this.verbose_drag) { + console.log("featdiv dimensions: "); + console.log(foffset); console.log("height: " + fheight + ", width: " + fwidth); + } + var selection = ftrack.selectionManager.getSelection(); + var selength = selection.length; + for (var i=0; i 2 levels deep + var subfeat = featdiv.subfeature; + // if (subfeat && (! unselectableTypes[subfeat.get('type')])) { // only allow double-click parent selection for selectable features + if( subfeat && selman.isSelected({ feature: subfeat, track: ftrack }) ) { // only allow double-click of child for parent selection if child is already selected + var parent = subfeat.parent(); + // select parent feature + // children (including subfeat double-clicked one) are auto-deselected in FeatureSelectionManager if parent is selected + if( parent ) { selman.addToSelection({ feature: parent, track: ftrack }); } + } + }, + + + /** + * returns first feature or subfeature div (including itself) + * found when crawling towards root from branch in + * feature/subfeature/descendants div hierachy + */ + getLowestFeatureDiv: function(elem) { + while (!elem.feature && !elem.subfeature) { + elem = elem.parentNode; + if (elem === document) {return null;} + } + return elem; + }, + + + /** + * Near as I can tell, track.showRange is called every time the + * appearance of the track changes in a way that would cause + * feature divs to be added or deleted (or moved? -- not sure, + * feature moves may also happen elsewhere?) So overriding + * showRange here to try and map selected features to selected + * divs and make sure the divs have selection style set + */ + showRange: function( first, last, startBase, bpPerBlock, scale, + containerStart, containerEnd ) { + this.inherited( arguments ); + + // console.log("called DraggableFeatureTrack.showRange(), block range: " + + // this.firstAttached + "--" + this.lastAttached + ", " + (this.lastAttached - this.firstAttached)); + // redo selection styles for divs in case any divs for selected features were changed/added/deleted + var srecs = this.selectionManager.getSelection(); + for (var sin in srecs) { + // only look for selected features in this track -- + // otherwise will be redoing (sfeats.length * tracks.length) times instead of sfeats.length times, + // because showRange is getting called for each track + var srec = srecs[sin]; + if (srec.track === this) { + // some or all feature divs are usually recreated in a showRange call + // therefore calling track.selectionAdded() to retrigger setting of selected-feature CSS style, etc. on new feat divs + this.selectionAdded(srec); + } + } + }, + + /** + * get the GenomeView's sequence track -- maybe move this to GenomeView? + * WebApollo assumes there is only one SequenceTrack + * if there are multiple SequenceTracks, getSequenceTrack returns first one found + * iterating through tracks list + */ + getSequenceTrack: function() { + if( this.seqTrack ) { + return this.seqTrack; + } + else { + var tracks = this.gview.tracks; + for (var i = 0; i < tracks.length; i++) { + if (tracks[i] instanceof SequenceTrack) { + this.seqTrack = tracks[i]; + tracks[i].setAnnotTrack(this); + break; + } + } + return this.seqTrack; + } + }, + + updateStaticElements: function( coords ) { + this.inherited( arguments ); + // this.updateFeatureArrowPositions( coords ); + }, + + + updateFeatureArrowPositions: function( coords ) { + var track = this; + if( ! 'x' in coords ) + return; + + var viewmin = this.gview.minVisible(); + var viewmax = this.gview.maxVisible(); + + dojo.query( '.block', this.div ) + .forEach( function(block) { + + var blockWidth = block.endBase - block.startBase; + + dojo.query('.feature',block) + .forEach( function(featDiv) { + var feature = featDiv.feature; + var fmin = feature.get('start'); + var fmax = feature.get('end'); + + // feature within view bounds, do nothing? + // or probably have to make sure to move back to normal if shifted previously + if (fmin > viewmin && fmax < viewmax) { } + // feature entirely outside view bounds + else if (fmax < viewmin || fmin > viewmax) { } + else { + var strand = feature.get('strand'); + if (strand > 0) { // forward strand + if (fmin < viewmax && fmax > viewmax) { + // extends past visible right, so move arrow leftward so still visible + // calculate percent not showing of feature: + var remainder = ((fmax - viewmax) / (fmax - fmin)) * 100; + var ah = dojo.query(".plus-" + track.config.style.arrowheadClass, featDiv); + ah.style({ "right": remainder + "%", + "left": null, + "z-index": 30 }); + } + } + else if (strand < 0) { // reverse strand + if (fmin < viewmin && fmax > viewmin) { + // extends past visible left, so move arrow rightward so still visible + // calculate percent not showing of feature: + var remainder = ((viewmin - fmin) / (fmax - fmin)) * 100; + var ah = dojo.query(".minus-" + track.config.style.arrowheadClass, featDiv); + ah.style({ "left": remainder + "%", + "right": null, + "z-index": 30 } ); + } + } + } + },this); + },this); + }, + + +/* + * for the input mouse event, returns genome position under mouse IN 1-BASED INTERBASE COORDINATES + * WARNING: returns base position relative to UI coordinate system + * (which is 1-based interbase) + * But for most elements in genome view (features, graphs, etc.) the underlying data structures are + * in 0-base interbase coordinate system + * So if you want data structure coordinates, you need to do (getUiGenomeCoord() - 1) + * or use the convenience function getGenomeCoord() + * + * event can be on GenomeView.elem or any descendant DOM elements (track, block, feature divs, etc.) + * assumes: + * event is a mouse event (plain Javascript event or JQuery event) + * elem is a DOM element OR JQuery wrapped set (in which case result is based on first elem in result set) + * elem is displayed (see JQuery.offset() docs) + * no border/margin/padding set on the doc element (see JQuery.offset() docs) + * if in IE<9, either page is not scrollable (in the HTML page sense) OR event is JQuery event + * (currently JBrowse index.html page is not scrollable (JBrowse internal scrolling is NOT same as HTML page scrolling)) + */ + getUiGenomeCoord: function(mouseEvent) { + return Math.floor(this.gview.absXtoBp(mouseEvent.pageX)); + }, + +/** + * for the input mouse event, returns genome position under mouse IN 0-BASED INTERBASE COORDINATES + * WARNING: + * returns genome coord in 0-based interbase (which is how internal data structure represent coords), + * instead of 1-based interbase (which is how UI displays coordinates) + * if need display coordinates, use getUiGenomeCoord() directly instead + * + * otherwise same capability and assumptions as getUiGenomeCoord(): + * event can be on GenomeView.elem or any descendant DOM elements (track, block, feature divs, etc.) + * assumes: + * event is a mouse event (plain Javascript event or JQuery event) + * elem is a DOM element OR JQuery wrapped set (in which case result is based on first elem in result set) + * elem is displayed (see JQuery.offset() docs) + * no border/margin/padding set on the doc element (see JQuery.offset() docs) + * if in IE<9, either page is not scrollable (in the HTML page sense) OR event is JQuery event + * (currently JBrowse index.html page is not scrollable (JBrowse internal scrolling is NOT same as HTML page scrolling)) + * + */ + getGenomeCoord: function(mouseEvent) { + return this.getUiGenomeCoord(mouseEvent) - 1; + } + +}); + + return draggableTrack; +}); + + /* + Copyright (c) 2010-2011 Berkeley Bioinformatics Open-source Projects & Lawrence Berkeley National Labs + + This package and its accompanying libraries are free software; you can + redistribute it and/or modify it under the terms of the LGPL (either + version 2.1, or at your option, any later version) or the Artistic + License 2.0. Refer to LICENSE for the full license text. +*/ diff --git a/plugins/WebApollo/js/View/Track/SequenceTrack.js b/plugins/WebApollo/js/View/Track/SequenceTrack.js new file mode 100644 index 0000000000..20d1b5a683 --- /dev/null +++ b/plugins/WebApollo/js/View/Track/SequenceTrack.js @@ -0,0 +1,1124 @@ +define( [ + 'dojo/_base/declare', + 'JBrowse/Store/Sequence/StaticChunked', + 'WebApollo/View/Track/DraggableHTMLFeatures', + 'WebApollo/JSONUtils', + 'WebApollo/Permission', + 'JBrowse/CodonTable' + ], +function( declare, StaticChunked, DraggableFeatureTrack, JSONUtils, Permission, CodonTable ) { + + var SequenceTrack = declare( "SequenceTrack", DraggableFeatureTrack, + +{ + +/** + * Track to display the underlying reference sequence, when zoomed in + * far enough. + * @class + * @constructor + */ + constructor: function( args ) { + this.isWebApolloSequenceTrack = true; + var track = this; + + /** + * DraggableFeatureTrack now has its own context menu for divs, + * and adding this flag provides a quick way to short-circuit it's + * initialization + */ + this.has_custom_context_menu = true; + // this.use_standard_context_menu = false; + this.show_reverse_strand = true; + this.show_protein_translation = true; + this.context_path = ".."; + + this.residues_context_menu = new dijit.Menu({}); // placeholder till setAnnotTrack() triggers real menu init + this.annot_context_menu = new dijit.Menu({}); // placeholder till setAnnotTrack() triggers real menu init + + this.residuesMouseDown = function(event) { + track.onResiduesMouseDown(event); + }; + + this.charSize = this.gview.getSequenceCharacterSize(); + this.charWidth = this.charSize.charWidth; + this.seqHeight = this.charSize.seqHeight; + + // splitting seqHeight into residuesHeight and translationHeight, so future iteration may be possible + // for DNA residues and protein translation to be different styles + this.dnaHeight = this.seqHeight; + this.proteinHeight = this.seqHeight; + + // this.refSeq = refSeq; already assigned in BlockBased superclass + + var seqStoreConfig = dojo.clone(this.config); + seqStoreConfig.urlTemplate = this.config.residuesUrlTemplate; + seqStoreConfig.browser = this.browser; + seqStoreConfig.refSeq = this.refSeq; + + this.sequenceStore = new StaticChunked(seqStoreConfig); + + this.trackPadding = 10; + this.SHOW_IF_FEATURES = true; + // this.setLoaded(); + // this.initContextMenu(); + + var atrack = this.getAnnotTrack(); + console.log("in SequenceTrack constructor, annotation track = ", atrack); + if (atrack) { + console.log("in SequenceTrack constructor, found AnnotTrack: ", atrack); + this.setAnnotTrack(atrack); + } + }, + +// annotSelectionManager is class variable (shared by all AnnotTrack instances) +// SequenceTrack.seqSelectionManager = new FeatureSelectionManager(); + +// setting up selection exclusiveOr -- +// if selection is made in annot track, any selection in other tracks is deselected, and vice versa, +// regardless of multi-select mode etc. +// SequenceTrack.seqSelectionManager.addMutualExclusion(DraggableFeatureTrack.selectionManager); +// SequenceTrack.seqSelectionManager.addMutualExclusion(AnnotTrack.annotSelectionManager); +//DraggableFeatureTrack.selectionManager.addMutualExclusion(SequenceTrack.seqSelectionManager); + +// loadSuccess: function(trackInfo) { } // loadSuccess no longer called by track initialization/loading + _defaultConfig: function() { + var thisConfig = this.inherited(arguments); + // nulling out menuTemplate to suppress default JBrowse feature contextual menu + thisConfig.menuTemplate = null; + thisConfig.maxFeatureScreenDensity = 100000; // set rediculously high, ensures will never show "zoomed too far out" placeholder + thisConfig.style.renderClassName = null; + thisConfig.style.arrowheadClass = null; + thisConfig.style.centerChildrenVertically = false; + return thisConfig; + }, + + + /** + * called by AnnotTrack to initiate sequence alterations load + */ + loadSequenceAlterations: function() { + var track = this; + + /** + * now do XHR to WebApollo AnnotationEditorService for "get_sequence_alterations" + */ + dojo.xhrPost( { + postData: '{ "track": "' + track.annotTrack.getUniqueTrackName() + '", "operation": "get_sequence_alterations" }', + url: track.context_path + "/AnnotationEditorService", + handleAs: "json", + timeout: 5 * 1000, // Time in milliseconds + // The LOAD function will be called on a successful response. + load: function(response, ioArgs) { // + console.log("SequenceTrack get_sequence_alterations response: "); + console.log(response); + var responseFeatures = response.features; + for (var i = 0; i < responseFeatures.length; i++) { + var jfeat = JSONUtils.createJBrowseSequenceAlteration(responseFeatures[i]); + track.store.insert(jfeat); + } + track.featureCount = track.storedFeatureCount(); + if (track.SHOW_IF_FEATURES && track.featureCount > 0) { + track.show(); + } + else { + track.hide(); + } + // track.hideAll(); shouldn't need to call hideAll() before changed() anymore + track.changed(); + }, + // The ERROR function will be called in an error case. + error: function(response, ioArgs) { // + + return response; // + } + }); + }, + + startZoom: function(destScale, destStart, destEnd) { + // would prefer to only try and hide dna residues on zoom if previous scale was at base pair resolution + // (otherwise there are no residues to hide), but by time startZoom is called, pxPerBp is already set to destScale, + // so would require keeping prevScale var around, or passing in prevScale as additional parameter to startZoom() + // so for now just always trying to hide residues on a zoom, whether they're present or not + + // if (prevScale == this.charWidth) { + + $(".dna-residues", this.div).css('display', 'none'); + $(".block-seq-container", this.div).css('height', '20px'); + // } + this.heightUpdate(20); + this.gview.trackHeightUpdate(this.name, Math.max(this.labelHeight, 20)); + }, + + endZoom: function(destScale, destBlockBases) { + var charSize = this.getCharacterMeasurements(); + + if( ( destScale == charSize.w ) || + (this.SHOW_IF_FEATURES && this.featureCount > 0) ) { + this.show(); + } + else { + this.hide(); + } + this.clear(); + // this.prevScale = destScale; + }, + + /* + * SequenceTrack.prototype.showRange = function(first, last, startBase, bpPerBlock, scale, + containerStart, containerEnd) { + console.log("called SequenceTrack.showRange():"); + console.log({ first: first, last: last, startBase: startBase, bpPerBloc: bpPerBlock, scale: scale, + containerStart: containerStart, containerEnd: containerEnd }); + DraggableFeatureTrack.prototype.showRange.apply(this, arguments); + }; + */ + + setViewInfo: function( genomeView, numBlocks, + trackDiv, labelDiv, + widthPct, widthPx, scale ) { + + this.inherited( arguments ); + + var charSize = this.getCharacterMeasurements(); + + if ( (scale == charSize.w ) || + (this.SHOW_IF_FEATURES && this.featureCount > 0) ) { + this.show(); + } else { + this.hide(); + this.heightUpdate(0); + } + this.setLabel( this.key ); + }, + + /** + * @returns {Object} containing h and w, + * in pixels, of the characters being used for sequences + */ + getCharacterMeasurements: function() { + if( !this._measurements ) + this._measurements = this._measureSequenceCharacterSize( this.div ); + return this._measurements; + }, + + /** + * Conducts a test with DOM elements to measure sequence text width + * and height. + */ + _measureSequenceCharacterSize: function( containerElement ) { + var widthTest = document.createElement("div"); + widthTest.className = "wa-sequence"; + widthTest.style.visibility = "hidden"; + var widthText = "12345678901234567890123456789012345678901234567890"; + widthTest.appendChild(document.createTextNode(widthText)); + containerElement.appendChild(widthTest); + var result = { + w: widthTest.clientWidth / widthText.length, + h: widthTest.clientHeight + }; + containerElement.removeChild(widthTest); + return result; + }, + + + /** + * GAH + * not entirely sure, but I think this strategy of calling getRange() only works as long as + * seq chunk sizes are a multiple of block sizes + * or in other words for a given block there is only one chunk that overlaps it + * (otherwise in the callback would need to fiddle with horizontal position of seqNode within the block) ??? + */ + fillBlock: function( args ) { + var blockIndex = args.blockIndex; + var block = args.block; + var leftBase = args.leftBase; + var rightBase = args.rightBase; + var scale = args.scale; + var containerStart = args.containerStart; + var containerEnd = args.containerEnd; + + var verbose = false; + // test block for diagnostics + // var verbose = (leftBase === 245524); + + var fillArgs = arguments; + var track = this; + var charSize = this.getCharacterMeasurements(); + if ((scale == charSize.w) || + (this.SHOW_IF_FEATURES && this.featureCount > 0) ) { + this.show(); + } else { + this.hide(); + this.heightUpdate(0); + } + var blockHeight = 0; + + if (this.shown) { + // make a div to contain the sequences + var seqNode = document.createElement("div"); + seqNode.className = "wa-sequence"; + // seq_block_container style sets width = 100%, so seqNode fills the block width + // regardless of whether holding residue divs or not + $(seqNode).addClass("block-seq-container"); + block.appendChild(seqNode); + + var slength = rightBase - leftBase; + + // just always add two base pairs to front and end, + // to make sure can do three-frame translation across for every base position in (leftBase..rightBase), + // both forward (need tw pairs on end) and reverse (need 2 extra bases at start) + var leftExtended = leftBase - 2; + var rightExtended = rightBase + 2; + + var dnaHeight = charSize.h; + var proteinHeight = charSize.h; + + if ( scale == charSize.w ) { + // this.sequenceStore.getRange( this.refSeq, leftBase, rightBase, + // this.sequenceStore.getRange( this.refSeq, leftBase, endBase, + // this.store.getFeatures( + this.sequenceStore.getFeatures( + { ref: this.refSeq.name, start: leftExtended, end: rightExtended }, + function( feat ) { + var start = feat.get('start'); + var end = feat.get('end'); + var seq = feat.get('seq'); + + // fill with leading blanks if the + // sequence does not extend all the way + // across our range + for( ; start < 0; start++ ) { + seq = SequenceTrack.nbsp + seq; //nbsp is an " " entity + } + + var blockStart = start + 2; + var blockEnd = end - 2; + var blockResidues = seq.substring(2, seq.length-2); + var blockLength = blockResidues.length; + var extendedStart = start; + var extendedEnd = end; + var extendedStartResidues = seq.substring(0, seq.length-2); + var extendedEndResidues = seq.substring(2); + + if (verbose) { + console.log("seq: " + seq + ", length: " + seq.length); + console.log("blockResidues: " + blockResidues + ", length: " + blockResidues.length); + console.log("extendedStartResidues: " + extendedStartResidues + ", length: " + extendedStartResidues.length); + console.log("extendedEndResidues: " + extendedEndResidues + ", length: " + extendedEndResidues.length); + } + + if (track.show_protein_translation) { + var framedivs = []; + for (var i=0; i<3; i++) { + // var tstart = start + i; + var tstart = blockStart + i; + var frame = tstart % 3; + if (verbose) { console.log(" forward translating: offset = " + i + ", frame = " + frame); } + var transProtein = track.renderTranslation( extendedEndResidues, i, blockLength); + // if coloring CDS in feature tracks by frame, use same "cds-frame" styling, + // otherwise use more muted "frame" styling + if (track.webapollo.colorCdsByFrame) { + $(transProtein).addClass("cds-frame" + frame); + } + else { + $(transProtein).addClass("frame" + frame); + } + framedivs[frame] = transProtein; + } + for (var i=2; i>=0; i--) { + var transProtein = framedivs[i]; + seqNode.appendChild(transProtein); + $(transProtein).bind("mousedown", track.residuesMouseDown); + blockHeight += proteinHeight; + } + } + + /* + var dnaContainer = document.createElement("div"); + $(dnaContainer).addClass("dna-container"); + seqNode.appendChild(dnaContainer); + */ + + // add a div for the forward strand + var forwardDNA = track.renderResidues( blockResidues ); + $(forwardDNA).addClass("forward-strand"); + seqNode.appendChild( forwardDNA ); + + + /* could force highlighting on mouseenter in additona to mousemove, + but mousemove seems to always be fired anyway when there's a mouseenter + $(forwardDNA).bind("mouseenter", function(event) { + track.removeTextHighlight(element); + } ); + */ + + + // dnaContainer.appendChild(forwardDNA); + track.residues_context_menu.bindDomNode(forwardDNA); + $(forwardDNA).bind("mousedown", track.residuesMouseDown); + blockHeight += dnaHeight; + + if (track.show_reverse_strand) { + // and one for the reverse strand + // var reverseDNA = track.renderResidues( start, end, track.complement(seq) ); + var reverseDNA = track.renderResidues( track.complement(blockResidues) ); + $(reverseDNA).addClass("reverse-strand"); + seqNode.appendChild( reverseDNA ); + // dnaContainer.appendChild(reverseDNA); + track.residues_context_menu.bindDomNode(reverseDNA); + $(reverseDNA).bind("mousedown", track.residuesMouseDown); + blockHeight += dnaHeight; + } + + // set up highlighting of base pair underneath mouse + $(forwardDNA).bind("mouseleave", function(event) { + track.removeTextHighlight(forwardDNA); + if (reverseDNA) { track.removeTextHighlight(reverseDNA); } + track.last_dna_coord = undefined; + } ); + $(forwardDNA).bind("mousemove", function(event) { + var gcoord = track.getGenomeCoord(event); + if ((!track.last_dna_coord) || (gcoord !== track.last_dna_coord)) { + var blockCoord = gcoord - leftBase; + track.last_dna_coord = gcoord; + track.setTextHighlight(forwardDNA, blockCoord, blockCoord, "dna-highlighted"); + if (!track.freezeHighlightedBases) { + track.lastHighlightedForwardDNA = forwardDNA; + } + if (reverseDNA) { + track.setTextHighlight(reverseDNA, blockCoord, blockCoord, "dna-highlighted"); + if (!track.freezeHighlightedBases) { + track.lastHighlightedReverseDNA = reverseDNA; + } + } + } + } ); + if (reverseDNA) { + $(reverseDNA).bind("mouseleave", function(event) { + track.removeTextHighlight(forwardDNA); + track.removeTextHighlight(reverseDNA); + track.last_dna_coord = undefined; + } ); + $(reverseDNA).bind("mousemove", function(event) { + var gcoord = track.getGenomeCoord(event); + if ((!track.last_dna_coord) || (gcoord !== track.last_dna_coord)) { + var blockCoord = gcoord - leftBase; + track.last_dna_coord = gcoord; + track.setTextHighlight(forwardDNA, blockCoord, blockCoord, "dna-highlighted"); + track.setTextHighlight(reverseDNA, blockCoord, blockCoord, "dna-highlighted"); + if (!track.freezeHighlightedBases) { + track.lastHighlightedForwardDNA = forwardDNA; + track.lastHighlightedReverseDNA = reverseDNA; + } + } + } ); + } + + if (track.show_protein_translation && track.show_reverse_strand) { + var extendedReverseComp = track.reverseComplement(extendedStartResidues); + if (verbose) { console.log("extendedReverseComp: " + extendedReverseComp); } + var framedivs = []; + for (var i=0; i<3; i++) { + var tstart = blockStart + i; + // var frame = tstart % 3; + var frame = (track.refSeq.length - blockEnd + i) % 3; + // frame = (frame + (3 - (track.refSeq.length % 3))) % 3; + frame = (Math.abs(frame - 2) + (track.refSeq.length % 3)) % 3; + var transProtein = track.renderTranslation( extendedStartResidues, i, blockLength, true); + if (track.webapollo.colorCdsByFrame) { + $(transProtein).addClass("cds-frame" + frame); + } + else { + $(transProtein).addClass("frame" + frame); + } + framedivs[frame] = transProtein; + } + // for (var i=2; i>=0; i--) { + for (var i=0; i<3; i++) { + var transProtein = framedivs[i]; + seqNode.appendChild(transProtein); + $(transProtein).bind("mousedown", track.residuesMouseDown); + blockHeight += proteinHeight; + } + } +// DraggableFeatureTrack.prototype.fillBlock.apply(track, fillArgs); +// dojo.hitch ??? + track.inherited("fillBlock", fillArgs); + blockHeight += 5; // a little extra padding below (track.trackPadding used for top padding) + // this.blockHeights[blockIndex] = blockHeight; // shouldn't be necessary, done in track.heightUpdate(); + track.heightUpdate(blockHeight, blockIndex); + }, + function() {} + ); + } + else { + blockHeight = 20; // default dna track height if not zoomed to base level + seqNode.style.height = "20px"; + + // DraggableFeatureTrack.prototype.fillBlock.apply(track, arguments); + track.inherited("fillBlock", arguments); + // this.inherited("fillBlock", arguments); + + // this.blockHeights[blockIndex] = blockHeight; // shouldn't be necessary, done in track.heightUpdate(); + track.heightUpdate(blockHeight, blockIndex); + } + } else { + this.heightUpdate(0, blockIndex); + } + }, + + // heightUpdate: function(height, blockIndex) { + // // console.log("SequenceTrack.heightUpdate: height = " + height + ", bindex = " + blockIndex); + // DraggableFeatureTrack.prototype.heightUpdate.call(this, height, blockIndex); + // }; + + addFeatureToBlock: function( feature, uniqueId, block, scale, labelScale, descriptionScale, + containerStart, containerEnd ) { + var featDiv = + this.renderFeature(feature, uniqueId, block, scale, labelScale, descriptionScale, containerStart, containerEnd); + $(featDiv).addClass("sequence-alteration"); + + var charSize = this.getCharacterMeasurements(); + + var seqNode = $("div.wa-sequence", block).get(0); + // var seqNode = $("div.dna-container", block).get(0); + featDiv.style.top = "0px"; + var ftype = feature.get("type"); + if (ftype) { + if (ftype == "deletion") { + + } + else if (ftype == "insertion") { + if ( scale == charSize.w ) { + var container = document.createElement("div"); + var residues = feature.get("residues"); + $(container).addClass("dna-residues"); + container.appendChild( document.createTextNode( residues ) ); + container.style.position = "absolute"; + container.style.top = "-16px"; + container.style.border = "2px solid #00CC00"; + container.style.backgroundColor = "#AAFFAA"; + featDiv.appendChild(container); + } + else { + // + } + } + else if ((ftype == "substitution")) { + if ( scale == charSize.w ) { + var container = document.createElement("div"); + var residues = feature.get("residues"); + $(container).addClass("dna-residues"); + container.appendChild( document.createTextNode( residues ) ); + container.style.position = "absolute"; + container.style.top = "-16px"; + container.style.border = "1px solid black"; + container.style.backgroundColor = "#FFF506"; + featDiv.appendChild(container); + } + else { + + } + } + } + seqNode.appendChild(featDiv); + return featDiv; + }, + + /** + * overriding renderFeature to add event handling right-click context menu + */ + renderFeature: function( feature, uniqueId, block, scale, labelScale, descriptionScale, + containerStart, containerEnd ) { + // var track = this; + // var featDiv = DraggableFeatureTrack.prototype.renderFeature.call(this, feature, uniqueId, block, scale, + + var featDiv = this.inherited( arguments ); + + if (featDiv && featDiv != null) { + this.annot_context_menu.bindDomNode(featDiv); + } + return featDiv; + }, + + reverseComplement: function(seq) { + return this.reverse(this.complement(seq)); + }, + + reverse: function(seq) { + return seq.split("").reverse().join(""); + }, + + complement: (function() { + var compl_rx = /[ACGT]/gi; + + // from bioperl: tr/acgtrymkswhbvdnxACGTRYMKSWHBVDNX/tgcayrkmswdvbhnxTGCAYRKMSWDVBHNX/ + // generated with: + // perl -MJSON -E '@l = split "","acgtrymkswhbvdnxACGTRYMKSWHBVDNX"; print to_json({ map { my $in = $_; tr/acgtrymkswhbvdnxACGTRYMKSWHBVDNX/tgcayrkmswdvbhnxTGCAYRKMSWDVBHNX/; $in => $_ } @l})' + var compl_tbl = {"S":"S","w":"w","T":"A","r":"y","a":"t","N":"N","K":"M","x":"x","d":"h","Y":"R","V":"B","y":"r","M":"K","h":"d","k":"m","C":"G","g":"c","t":"a","A":"T","n":"n","W":"W","X":"X","m":"k","v":"b","B":"V","s":"s","H":"D","c":"g","D":"H","b":"v","R":"Y","G":"C"}; + + var compl_func = function(m) { return compl_tbl[m] || SequenceTrack.nbsp; }; + return function( seq ) { + return seq.replace( compl_rx, compl_func ); + }; + })(), + + //given the start and end coordinates, and the sequence bases, makes a + //div containing the sequence + // SequenceTrack.prototype.renderResidues = function ( start, end, seq ) { + renderResidues: function ( seq ) { + var container = document.createElement("div"); + $(container).addClass("dna-residues"); + container.appendChild( document.createTextNode( seq ) ); + return container; + }, + + /** end is ignored, assume all of seq is translated (except any extra bases at end) */ + renderTranslation: function ( input_seq, offset, blockLength, reverse) { + var verbose = false; + // sequence of diagnostic block + // var verbose = (input_seq === "GTATATTTTGTACGTTAAAAATAAAAA" || input_seq === "GCGTATATTTTGTACGTTAAAAATAAA" ); + var seq; + if (reverse) { + seq = this.reverseComplement(input_seq); + if (verbose) { console.log("revcomped, input: " + input_seq + ", output: " + seq); } + } + else { + seq = input_seq; + } + var container = document.createElement("div"); + $(container).addClass("dna-residues"); + $(container).addClass("aa-residues"); + $(container).addClass("offset" + offset); + var prefix = ""; + var suffix = ""; + for (var i=0; i= 0) { aa = SequenceTrack.nbsp; } + else { aa = "?"; } + } + return prefix + aa + suffix; + // return aa; + } ); + var trimmedAaResidues = aaResidues.substring(0, blockLength); + if (verbose) { console.log("AaLength: " + aaResidues.length + ", trimmedAaLength = " + trimmedAaResidues.length); } + aaResidues = trimmedAaResidues; + if (reverse) { + var revAaResidues = this.reverse(aaResidues); + if (verbose) { console.log("reversing aa string, input: \"" + aaResidues + "\", output: \"" + revAaResidues + "\""); } + aaResidues = revAaResidues; + while (aaResidues.length < blockLength) { + aaResidues = SequenceTrack.nbsp + aaResidues; + } + } + container.appendChild( document.createTextNode( aaResidues ) ); + return container; + }, + + onResiduesMouseDown: function(event) { + this.last_mousedown_event = event; + }, + + onFeatureMouseDown: function(event) { + // _not_ calling DraggableFeatureTrack.prototyp.onFeatureMouseDown -- + // don't want to allow dragging (at least not yet) + // event.stopPropagation(); + this.last_mousedown_event = event; + var ftrack = this; + if (ftrack.verbose_selection || ftrack.verbose_drag) { + console.log("SequenceTrack.onFeatureMouseDown called"); + } + this.handleFeatureSelection(event); + }, + + initContextMenu: function() { + var thisObj = this; + thisObj.contextMenuItems = new Array(); + thisObj.annot_context_menu = new dijit.Menu({}); + + var index = 0; + if (this.annotTrack.permission & Permission.WRITE) { + thisObj.annot_context_menu.addChild(new dijit.MenuItem( { + label: "Delete", + onClick: function() { + thisObj.deleteSelectedFeatures(); + } + } )); + thisObj.contextMenuItems["delete"] = index++; + } + thisObj.annot_context_menu.addChild(new dijit.MenuItem( { + label: "Information", + onClick: function(event) { + thisObj.getInformation(); + } + } )); + + thisObj.contextMenuItems["information"] = index++; + + thisObj.annot_context_menu.onOpen = function(event) { + // keeping track of mousedown event that triggered annot_context_menu popup, + // because need mouse position of that event for some actions + thisObj.annot_context_mousedown = thisObj.last_mousedown_event; + // if (thisObj.permission & Permission.WRITE) { thisObj.updateMenu(); } + dojo.forEach(this.getChildren(), function(item, idx, arr) { + if (item._setSelected) { item._setSelected(false); } // test for function existence first + if (item._onUnhover) { item._onUnhover(); } // test for function existence first + }); + }; + + /** + * context menu for right click on sequence residues + */ + thisObj.residuesMenuItems = new Array(); + thisObj.residues_context_menu = new dijit.Menu({}); + index = 0; + + thisObj.residuesMenuItems["toggle_reverse_strand"] = index++; + thisObj.residues_context_menu.addChild(new dijit.MenuItem( { + label: "Toggle Reverse Strand", + onClick: function(event) { + thisObj.show_reverse_strand = ! thisObj.show_reverse_strand; + thisObj.clearHighlightedBases(); + // thisObj.hideAll(); shouldn't need to call hideAll() before changed() anymore + thisObj.changed(); + // thisObj.toggleReverseStrand(); + } + } )); + + thisObj.residuesMenuItems["toggle_protein_translation"] = index++; + thisObj.residues_context_menu.addChild(new dijit.MenuItem( { + label: "Toggle Protein Translation", + onClick: function(event) { + thisObj.show_protein_translation = ! thisObj.show_protein_translation; + thisObj.clearHighlightedBases(); + // thisObj.hideAll(); shouldn't need to call hideAll() before changed() anymore + thisObj.changed(); + // thisObj.toggleProteinTranslation(); + } + } )); + + + if (this.annotTrack.permission & Permission.WRITE) { + + thisObj.residues_context_menu.addChild(new dijit.MenuSeparator()); + thisObj.residues_context_menu.addChild(new dijit.MenuItem( { + label: "Create Genomic Insertion", + onClick: function() { + thisObj.freezeHighlightedBases = true; + thisObj.createGenomicInsertion(); + } + } )); + thisObj.residuesMenuItems["create_insertion"] = index++; + thisObj.residues_context_menu.addChild(new dijit.MenuItem( { + label: "Create Genomic Deletion", + onClick: function(event) { + thisObj.freezeHighlightedBases = true; + thisObj.createGenomicDeletion(); + } + } )); + thisObj.residuesMenuItems["create_deletion"] = index++; + + thisObj.residues_context_menu.addChild(new dijit.MenuItem( { + label: "Create Genomic Substitution", + onClick: function(event) { + thisObj.freezeHighlightedBases = true; + thisObj.createGenomicSubstitution(); + } + } )); + thisObj.residuesMenuItems["create_substitution"] = index++; + } + /* + thisObj.residues_context_menu.addChild(new dijit.MenuItem( { + label: "..." + } + )); + */ + + thisObj.residues_context_menu.onOpen = function(event) { + // keeping track of mousedown event that triggered residues_context_menu popup, + // because need mouse position of that event for some actions + thisObj.residues_context_mousedown = thisObj.last_mousedown_event; + // if (thisObj.permission & Permission.WRITE) { thisObj.updateMenu() } + dojo.forEach(this.getChildren(), function(item, idx, arr) { + if (item._setSelected) { item._setSelected(false); } + if (item._onUnhover) { item._onUnhover(); } + }); + + thisObj.freezeHighlightedBases = true; + + }; + + thisObj.residues_context_menu.onBlur = function() { + thisObj.freezeHighlightedBases = false; + }; + + thisObj.residues_context_menu.onClose = function(event) { + if (!thisObj.freezeHighlightedBases) { + thisObj.clearHighlightedBases(); + } + }; + + thisObj.annot_context_menu.startup(); + thisObj.residues_context_menu.startup(); + }, + + getUniqueTrackName: function() { + return this.name + "-" + this.refSeq.name; + }, + + createGenomicInsertion: function() { + var gcoord = this.getGenomeCoord(this.residues_context_mousedown); + console.log("SequenceTrack.createGenomicInsertion() called at genome position: " + gcoord); + + var content = this.createAddSequenceAlterationPanel("insertion", gcoord); + this.annotTrack.openDialog("Add Insertion", content); + + /* + var track = this; + var features = '[ { "uniquename": "insertion-' + gcoord + '","location": { "fmin": ' + gcoord + ', "fmax": ' + gcoord + ', "strand": 1 }, "residues": "A", "type": {"name": "insertion", "cv": { "name":"SO" } } } ]'; + dojo.xhrPost( { + postData: '{ "track": "' + track.annotTrack.getUniqueTrackName() + '", "features": ' + features + ', "operation": "add_sequence_alteration" }', + url: context_path + "/AnnotationEditorService", + handleAs: "json", + timeout: 5000, // Time in milliseconds + // The LOAD function will be called on a successful response. + load: function(response, ioArgs) { + }, + // The ERROR function will be called in an error case. + error: function(response, ioArgs) { // + return response; + } + }); + */ + + }, + + createGenomicDeletion: function() { + var gcoord = this.getGenomeCoord(this.residues_context_mousedown); + console.log("SequenceTrack.createGenomicDeletion() called at genome position: " + gcoord); + + var content = this.createAddSequenceAlterationPanel("deletion", gcoord); + this.annotTrack.openDialog("Add Deletion", content); + + }, + + createGenomicSubstitution: function() { + var gcoord = this.getGenomeCoord(this.residues_context_mousedown); + console.log("SequenceTrack.createGenomicSubstitution() called at genome position: " + gcoord); + var content = this.createAddSequenceAlterationPanel("substitution", gcoord); + this.annotTrack.openDialog("Add Substitution", content); + }, + + deleteSelectedFeatures: function() { + console.log("SequenceTrack.deleteSelectedFeatures() called"); + var selected = this.selectionManager.getSelection(); + this.selectionManager.clearSelection(); + this.requestDeletion(selected); + }, + + requestDeletion: function(selected) { + console.log("SequenceTrack.requestDeletion called"); + console.log(selected); + var track = this; + var features = "[ "; + for (var i = 0; i < selected.length; ++i) { + var annot = selected[i].feature; + if (i > 0) { + features += ", "; + } + features += '{ "uniquename": "' + annot.id() + '" }'; + } + features += "]"; + var postData = '{ "track": "' + track.annotTrack.getUniqueTrackName() + '", "features": ' + features + ', "operation": "delete_sequence_alteration" }'; + track.annotTrack.executeUpdateOperation(postData); + }, + + getInformation: function() { + console.log("SequenceTrack.getInformation() called"); + }, + + /** + * sequence alteration annotation ADD command received by a ChangeNotificationListener, + * so telling SequenceTrack to add to it's SeqFeatureStore + */ + annotationsAddedNotification: function(responseFeatures) { + console.log("SequenceTrack.annotationsAddedNotification() called"); + var track = this; + // add to store + for (var i = 0; i < responseFeatures.length; ++i) { + var feat = JSONUtils.createJBrowseSequenceAlteration( responseFeatures[i] ); + var id = responseFeatures[i].uniquename; + if (! this.store.getFeatureById(id)) { + this.store.insert(feat); + } + } + track.featureCount = track.storedFeatureCount(); + if (this.SHOW_IF_FEATURES && this.featureCount > 0) { + this.show(); + } + else { + this.hide(); + } + // track.hideAll(); shouldn't need to call hideAll() before changed() anymore + track.changed(); + }, + + /** + * sequence alteration annotation DELETE command received by a ChangeNotificationListener, + * so telling SequenceTrack to remove from it's SeqFeatureStore + */ + annotationsDeletedNotification: function(annots) { + console.log("SequenceTrack.removeSequenceAlterations() called"); + var track = this; + // remove from SeqFeatureStore + for (var i = 0; i < annots.length; ++i) { + var id_to_delete = annots[i].uniquename; + this.store.deleteFeatureById(id_to_delete); + } + track.featureCount = track.storedFeatureCount(); + if (this.SHOW_IF_FEATURES && this.featureCount > 0) { + this.show(); + } + else { + this.hide(); + } + // track.hideAll(); shouldn't need to call hideAll() before changed() anymore + track.changed(); + }, + + /* + * sequence alteration UPDATE command received by a ChangeNotificationListener + * currently handled as if receiving DELETE followed by ADD command + */ + annotationsUpdatedNotification: function(annots) { + this.annotationsDeletedNotification(annots); + this.annotationAddedNotification(annots); + }, + + storedFeatureCount: function(start, end) { + // get accurate count of features loaded (should do this within the XHR.load() function + var track = this; + if (start == undefined) { + // start = 0; + start = track.refSeq.start; + } + if (end == undefined) { + // end = track.refSeq.length; + end = track.refSeq.end; + } + var count = 0; + track.store.getFeatures({ ref: track.refSeq.name, start: start, end: end}, function() { count++; }); + return count; + }, + + createAddSequenceAlterationPanel: function(type, gcoord) { + var track = this; + var content = dojo.create("div"); + var inputDiv = dojo.create("div", { }, content); + var inputLabel = dojo.create("label", { innerHTML: type == "deletion" ? "Length" : "Sequence", className: "sequence_alteration_input_label" }, inputDiv); + var inputField = dojo.create("input", { type: "text", size: 10, className: "sequence_alteration_input_field" }, inputDiv); + var buttonDiv = dojo.create("div", { className: "sequence_alteration_button_div" }, content); + var addButton = dojo.create("button", { innerHTML: "Add", className: "sequence_alteration_button" }, buttonDiv); + + var addSequenceAlteration = function() { + var ok = true; + if (inputField.value.length == 0) { + alert("Input cannot be empty for " + type); + ok = false; + } + if (ok) { + var input = inputField.value.toUpperCase(); + if (type == "deletion") { + if (input.match(/\D/)) { + alert("The length must be a number"); + ok = false; + } + else { + input = parseInt(input); + if (input <= 0) { + alert("The length must be a positive number"); + ok = false; + } + } + } + else { + if (input.match(/[^ACGT]/)) { + alert("The sequence should only containg A, C, G, T"); + ok = false; + } + } + } + if (ok) { + var fmin = gcoord; + var fmax; + if (type == "insertion") { + fmax = gcoord; + } + else if (type == "deletion") { + fmax = gcoord + parseInt(input); + } + else if (type == "substitution") { + fmax = gcoord + input.length;; + } + if (track.storedFeatureCount(fmin, fmax == fmin ? fmin + 1 : fmax) > 0) { + alert("Cannot create overlapping sequence alterations"); + } + else { + var feature = '"location": { "fmin": ' + fmin + ', "fmax": ' + fmax + ', "strand": 1 }, "type": {"name": "' + type + '", "cv": { "name":"sequence" } }'; + if (type != "deletion") { + feature += ', "residues": "' + input + '"'; + } + var features = '[ { ' + feature + ' } ]'; + var postData = '{ "track": "' + track.annotTrack.getUniqueTrackName() + '", "features": ' + features + ', "operation": "add_sequence_alteration" }'; + track.annotTrack.executeUpdateOperation(postData); + track.annotTrack.popupDialog.hide(); + } + } + }; + + dojo.connect(inputField, "keypress", null, function(e) { + var unicode = e.keyCode ? e.keyCode : e.charCode; + if (unicode == 13) { + addSequenceAlteration(); + } + }); + + dojo.connect(addButton, "onclick", null, function() { + addSequenceAlteration(); + }); + + return content; + }, + + handleError: function(response) { + console.log("ERROR: "); + console.log(response); // in Firebug, allows retrieval of stack trace, jump to code, etc. + console.log(response.stack); + var error = eval('(' + response.responseText + ')'); + if (error && error.error) { + alert(error.error); + return; + } + }, + + setAnnotTrack: function(annotTrack) { + if (this.annotTrack) { console.log("WARNING: SequenceTrack.setAnnotTrack called but annoTrack already set"); } + this.annotTrack = annotTrack; + this.initContextMenu(); + this.loadSequenceAlterations(); + }, + + /* + * Given an element that contains text, highlights a given range of the text + * If called repeatedly, removes highlighting from previous call first + * + * Assumes there is no additional markup within element, just a text node + * (would like to eventually rewrite to remove this restriction? Possibly could use HTML Range manipulation, + * i.e. range.surroundContents() etc. ) + * + * optionally specify what class to use to indicate highlighting (defaults to "text-highlight") + * + * adapted from http://stackoverflow.com/questions/9051369/highlight-substring-in-element + */ + setTextHighlight: function (element, start, end, classname) { + if (this.freezeHighlightedBases) { + return; + } + if (! classname) { classname = "text-highlight"; } + var item = $(element); + var str = item.data("origHTML"); + if (!str) { + str = item.html(); + item.data("origHTML", str); + } + str = str.substr(0, start) + + '' + + str.substr(start, end - start + 1) + + '' + + str.substr(end + 1); + item.html(str); + }, + + /* + * remove highlighting added with setTextHighlight + */ + removeTextHighlight: function(element) { + if (this.freezeHighlightedBases) { + return; + } + var item = $(element); + var str = item.data("origHTML"); + if (str) { + item.html(str); + } + }, + + clearHighlightedBases: function() { + this.freezeHighlightedBases = false; + this.removeTextHighlight(this.lastHighlightedForwardDNA); + if (this.lastHighlightedReverseDNA) { + this.removeTextHighlight(this.lastHighlightedReverseDNA); + } + }, + + getAnnotTrack: function() { + if (this.annotTrack) { + return this.annotTrack; + } + else { + var tracks = this.gview.tracks; + for (var i = 0; i < tracks.length; i++) { + // should be doing instanceof here, but class setup is not being cooperative + if (tracks[i].isWebApolloAnnotTrack) { + this.annotTrack = tracks[i]; + console.log("In SequenceTrack, found WebApollo annotation track: ", this.annotTrack); + this.annotTrack.seqTrack = this; + break; + } + } + } + return this.annotTrack; + } + +}); + + SequenceTrack.nbsp = String.fromCharCode(160); + return SequenceTrack; +}); + +/* + * highlightText is nice, + * what would be _really_ good is a residue highlighter that works in genome coords, and + * does highlights across all blocks that overlap genome coord range + * NOT YET IMPLEMENTED + */ + /*SequenceTrack.prototype.highlightResidues = function(genomeStart, genomeEnd) { +} +*/ + +/* + * More efficient form + * residues_class is CSS class of residues: forward, reverse, frame0, frame1, frame2, frameMinus1, frameMinus2, frameMinus3 + * highlight_class is CSS class for the highlighted span + * ranges is an ordered array (min to max) of ranges, each range is itself an array of form [start, end] in genome coords + * ranges MUST NOT overlap + * + * assumes: + * ranges do not overlap + * any previous highlighting is removed (revert to raw residues before applying new highlighting) + * + * + * In implementation can insert span elements in reverse order, so that indexing into string is always accurate (not tripped up by span elements inserted farther upstream) + * will need to clamp to bounds of each block + */ +/*SequenceTrack.prototype.highlightResidues = function(highlight_class, residues_class, ranges) */ diff --git a/plugins/WebApollo/js/main.js b/plugins/WebApollo/js/main.js new file mode 100644 index 0000000000..2503511dfa --- /dev/null +++ b/plugins/WebApollo/js/main.js @@ -0,0 +1,92 @@ +require({ + packages: [ + { name: 'jqueryui', location: '../plugins/WebApollo/jslib/jqueryui' }, + { name: 'jquery', location: '../plugins/WebApollo/jslib/jquery', main: 'jquery' } + ] + }, + [], + function() { + +define.amd.jQuery = true; + +define( + [ + 'dojo/_base/declare', + 'dijit/CheckedMenuItem', + 'JBrowse/Plugin', + './FeatureEdgeMatchManager', + './FeatureSelectionManager' + ], + function( declare, dijitCheckedMenuItem, JBPlugin, FeatureEdgeMatchManager, FeatureSelectionManager ) { + +return declare( JBPlugin, +{ + + colorCdsByFrame: false, + + constructor: function( args ) { + var thisB = this; + var browser = args.browser; + + // hand the browser object to the feature edge match manager + FeatureEdgeMatchManager.setBrowser( browser ); + + this.featSelectionManager = new FeatureSelectionManager(); + this.annotSelectionManager = new FeatureSelectionManager(); + + // setting up selection exclusiveOr -- + // if selection is made in annot track, any selection in other tracks is deselected, and vice versa, + // regardless of multi-select mode etc. + this.annotSelectionManager.addMutualExclusion(this.featSelectionManager); + this.featSelectionManager.addMutualExclusion(this.annotSelectionManager); + + FeatureEdgeMatchManager.addSelectionManager(this.featSelectionManager); + FeatureEdgeMatchManager.addSelectionManager(this.annotSelectionManager); + + + // add a global menu option for setting CDS color + var cds_frame_toggle = new dijitCheckedMenuItem( + { + label: "Color by CDS frame", + checked: false, + onClick: function(event) { + thisB.colorCdsByFrame = cds_frame_toggle.checked; + browser.view.redrawTracks(); + } + }); + browser.addGlobalMenuItem( 'options', cds_frame_toggle ); + + // register the WebApollo track types with the browser, so + // that the open-file dialog and other things will have them + // as options + browser.registerTrackType({ + type: 'WebApollo/View/Track/DraggableHTMLFeatures', + defaultForStoreTypes: [ 'JBrowse/Store/SeqFeature/NCList', + 'JBrowse/Store/SeqFeature/GFF3' + ], + label: 'WebApollo Features' + }); + browser.registerTrackType({ + type: 'WebApollo/View/Track/DraggableAlignments', + defaultForStoreTypes: [ + 'JBrowse/Store/SeqFeature/BAM', + ], + label: 'WebApollo Alignments' + }); + browser.registerTrackType({ + type: 'WebApollo/View/Track/SequenceTrack', + defaultForStoreTypes: [ 'JBrowse/Store/Sequence/StaticChunked' ], + label: 'WebApollo Sequence' + }); + + // put the WebApollo logo in the powered_by place in the main JBrowse bar + browser.afterMilestone( 'initView', function() { + browser.poweredByLink.innerHTML = ''; + }); + + } +}); + +}); + +}); \ No newline at end of file diff --git a/plugins/WebApollo/jslib/jquery/jquery.js b/plugins/WebApollo/jslib/jquery/jquery.js new file mode 100644 index 0000000000..8ccd0ea786 --- /dev/null +++ b/plugins/WebApollo/jslib/jquery/jquery.js @@ -0,0 +1,9266 @@ +/*! + * jQuery JavaScript Library v1.7.1 + * http://jquery.com/ + * + * Copyright 2011, John Resig + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * Includes Sizzle.js + * http://sizzlejs.com/ + * Copyright 2011, The Dojo Foundation + * Released under the MIT, BSD, and GPL Licenses. + * + * Date: Mon Nov 21 21:11:03 2011 -0500 + */ +(function( window, undefined ) { + +// Use the correct document accordingly with window argument (sandbox) +var document = window.document, + navigator = window.navigator, + location = window.location; +var jQuery = (function() { + +// Define a local copy of jQuery +var jQuery = function( selector, context ) { + // The jQuery object is actually just the init constructor 'enhanced' + return new jQuery.fn.init( selector, context, rootjQuery ); + }, + + // Map over jQuery in case of overwrite + _jQuery = window.jQuery, + + // Map over the $ in case of overwrite + _$ = window.$, + + // A central reference to the root jQuery(document) + rootjQuery, + + // A simple way to check for HTML strings or ID strings + // Prioritize #id over to avoid XSS via location.hash (#9521) + quickExpr = /^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/, + + // Check if a string has a non-whitespace character in it + rnotwhite = /\S/, + + // Used for trimming whitespace + trimLeft = /^\s+/, + trimRight = /\s+$/, + + // Match a standalone tag + rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>)?$/, + + // JSON RegExp + rvalidchars = /^[\],:{}\s]*$/, + rvalidescape = /\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, + rvalidtokens = /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, + rvalidbraces = /(?:^|:|,)(?:\s*\[)+/g, + + // Useragent RegExp + rwebkit = /(webkit)[ \/]([\w.]+)/, + ropera = /(opera)(?:.*version)?[ \/]([\w.]+)/, + rmsie = /(msie) ([\w.]+)/, + rmozilla = /(mozilla)(?:.*? rv:([\w.]+))?/, + + // Matches dashed string for camelizing + rdashAlpha = /-([a-z]|[0-9])/ig, + rmsPrefix = /^-ms-/, + + // Used by jQuery.camelCase as callback to replace() + fcamelCase = function( all, letter ) { + return ( letter + "" ).toUpperCase(); + }, + + // Keep a UserAgent string for use with jQuery.browser + userAgent = navigator.userAgent, + + // For matching the engine and version of the browser + browserMatch, + + // The deferred used on DOM ready + readyList, + + // The ready event handler + DOMContentLoaded, + + // Save a reference to some core methods + toString = Object.prototype.toString, + hasOwn = Object.prototype.hasOwnProperty, + push = Array.prototype.push, + slice = Array.prototype.slice, + trim = String.prototype.trim, + indexOf = Array.prototype.indexOf, + + // [[Class]] -> type pairs + class2type = {}; + +jQuery.fn = jQuery.prototype = { + constructor: jQuery, + init: function( selector, context, rootjQuery ) { + var match, elem, ret, doc; + + // Handle $(""), $(null), or $(undefined) + if ( !selector ) { + return this; + } + + // Handle $(DOMElement) + if ( selector.nodeType ) { + this.context = this[0] = selector; + this.length = 1; + return this; + } + + // The body element only exists once, optimize finding it + if ( selector === "body" && !context && document.body ) { + this.context = document; + this[0] = document.body; + this.selector = selector; + this.length = 1; + return this; + } + + // Handle HTML strings + if ( typeof selector === "string" ) { + // Are we dealing with HTML string or an ID? + if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) { + // Assume that strings that start and end with <> are HTML and skip the regex check + match = [ null, selector, null ]; + + } else { + match = quickExpr.exec( selector ); + } + + // Verify a match, and that no context was specified for #id + if ( match && (match[1] || !context) ) { + + // HANDLE: $(html) -> $(array) + if ( match[1] ) { + context = context instanceof jQuery ? context[0] : context; + doc = ( context ? context.ownerDocument || context : document ); + + // If a single string is passed in and it's a single tag + // just do a createElement and skip the rest + ret = rsingleTag.exec( selector ); + + if ( ret ) { + if ( jQuery.isPlainObject( context ) ) { + selector = [ document.createElement( ret[1] ) ]; + jQuery.fn.attr.call( selector, context, true ); + + } else { + selector = [ doc.createElement( ret[1] ) ]; + } + + } else { + ret = jQuery.buildFragment( [ match[1] ], [ doc ] ); + selector = ( ret.cacheable ? jQuery.clone(ret.fragment) : ret.fragment ).childNodes; + } + + return jQuery.merge( this, selector ); + + // HANDLE: $("#id") + } else { + elem = document.getElementById( match[2] ); + + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document #6963 + if ( elem && elem.parentNode ) { + // Handle the case where IE and Opera return items + // by name instead of ID + if ( elem.id !== match[2] ) { + return rootjQuery.find( selector ); + } + + // Otherwise, we inject the element directly into the jQuery object + this.length = 1; + this[0] = elem; + } + + this.context = document; + this.selector = selector; + return this; + } + + // HANDLE: $(expr, $(...)) + } else if ( !context || context.jquery ) { + return ( context || rootjQuery ).find( selector ); + + // HANDLE: $(expr, context) + // (which is just equivalent to: $(context).find(expr) + } else { + return this.constructor( context ).find( selector ); + } + + // HANDLE: $(function) + // Shortcut for document ready + } else if ( jQuery.isFunction( selector ) ) { + return rootjQuery.ready( selector ); + } + + if ( selector.selector !== undefined ) { + this.selector = selector.selector; + this.context = selector.context; + } + + return jQuery.makeArray( selector, this ); + }, + + // Start with an empty selector + selector: "", + + // The current version of jQuery being used + jquery: "1.7.1", + + // The default length of a jQuery object is 0 + length: 0, + + // The number of elements contained in the matched element set + size: function() { + return this.length; + }, + + toArray: function() { + return slice.call( this, 0 ); + }, + + // Get the Nth element in the matched element set OR + // Get the whole matched element set as a clean array + get: function( num ) { + return num == null ? + + // Return a 'clean' array + this.toArray() : + + // Return just the object + ( num < 0 ? this[ this.length + num ] : this[ num ] ); + }, + + // Take an array of elements and push it onto the stack + // (returning the new matched element set) + pushStack: function( elems, name, selector ) { + // Build a new jQuery matched element set + var ret = this.constructor(); + + if ( jQuery.isArray( elems ) ) { + push.apply( ret, elems ); + + } else { + jQuery.merge( ret, elems ); + } + + // Add the old object onto the stack (as a reference) + ret.prevObject = this; + + ret.context = this.context; + + if ( name === "find" ) { + ret.selector = this.selector + ( this.selector ? " " : "" ) + selector; + } else if ( name ) { + ret.selector = this.selector + "." + name + "(" + selector + ")"; + } + + // Return the newly-formed element set + return ret; + }, + + // Execute a callback for every element in the matched set. + // (You can seed the arguments with an array of args, but this is + // only used internally.) + each: function( callback, args ) { + return jQuery.each( this, callback, args ); + }, + + ready: function( fn ) { + // Attach the listeners + jQuery.bindReady(); + + // Add the callback + readyList.add( fn ); + + return this; + }, + + eq: function( i ) { + i = +i; + return i === -1 ? + this.slice( i ) : + this.slice( i, i + 1 ); + }, + + first: function() { + return this.eq( 0 ); + }, + + last: function() { + return this.eq( -1 ); + }, + + slice: function() { + return this.pushStack( slice.apply( this, arguments ), + "slice", slice.call(arguments).join(",") ); + }, + + map: function( callback ) { + return this.pushStack( jQuery.map(this, function( elem, i ) { + return callback.call( elem, i, elem ); + })); + }, + + end: function() { + return this.prevObject || this.constructor(null); + }, + + // For internal use only. + // Behaves like an Array's method, not like a jQuery method. + push: push, + sort: [].sort, + splice: [].splice +}; + +// Give the init function the jQuery prototype for later instantiation +jQuery.fn.init.prototype = jQuery.fn; + +jQuery.extend = jQuery.fn.extend = function() { + var options, name, src, copy, copyIsArray, clone, + target = arguments[0] || {}, + i = 1, + length = arguments.length, + deep = false; + + // Handle a deep copy situation + if ( typeof target === "boolean" ) { + deep = target; + target = arguments[1] || {}; + // skip the boolean and the target + i = 2; + } + + // Handle case when target is a string or something (possible in deep copy) + if ( typeof target !== "object" && !jQuery.isFunction(target) ) { + target = {}; + } + + // extend jQuery itself if only one argument is passed + if ( length === i ) { + target = this; + --i; + } + + for ( ; i < length; i++ ) { + // Only deal with non-null/undefined values + if ( (options = arguments[ i ]) != null ) { + // Extend the base object + for ( name in options ) { + src = target[ name ]; + copy = options[ name ]; + + // Prevent never-ending loop + if ( target === copy ) { + continue; + } + + // Recurse if we're merging plain objects or arrays + if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) { + if ( copyIsArray ) { + copyIsArray = false; + clone = src && jQuery.isArray(src) ? src : []; + + } else { + clone = src && jQuery.isPlainObject(src) ? src : {}; + } + + // Never move original objects, clone them + target[ name ] = jQuery.extend( deep, clone, copy ); + + // Don't bring in undefined values + } else if ( copy !== undefined ) { + target[ name ] = copy; + } + } + } + } + + // Return the modified object + return target; +}; + +jQuery.extend({ + noConflict: function( deep ) { + if ( window.$ === jQuery ) { + window.$ = _$; + } + + if ( deep && window.jQuery === jQuery ) { + window.jQuery = _jQuery; + } + + return jQuery; + }, + + // Is the DOM ready to be used? Set to true once it occurs. + isReady: false, + + // A counter to track how many items to wait for before + // the ready event fires. See #6781 + readyWait: 1, + + // Hold (or release) the ready event + holdReady: function( hold ) { + if ( hold ) { + jQuery.readyWait++; + } else { + jQuery.ready( true ); + } + }, + + // Handle when the DOM is ready + ready: function( wait ) { + // Either a released hold or an DOMready/load event and not yet ready + if ( (wait === true && !--jQuery.readyWait) || (wait !== true && !jQuery.isReady) ) { + // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443). + if ( !document.body ) { + return setTimeout( jQuery.ready, 1 ); + } + + // Remember that the DOM is ready + jQuery.isReady = true; + + // If a normal DOM Ready event fired, decrement, and wait if need be + if ( wait !== true && --jQuery.readyWait > 0 ) { + return; + } + + // If there are functions bound, to execute + readyList.fireWith( document, [ jQuery ] ); + + // Trigger any bound ready events + if ( jQuery.fn.trigger ) { + jQuery( document ).trigger( "ready" ).off( "ready" ); + } + } + }, + + bindReady: function() { + if ( readyList ) { + return; + } + + readyList = jQuery.Callbacks( "once memory" ); + + // Catch cases where $(document).ready() is called after the + // browser event has already occurred. + if ( document.readyState === "complete" ) { + // Handle it asynchronously to allow scripts the opportunity to delay ready + return setTimeout( jQuery.ready, 1 ); + } + + // Mozilla, Opera and webkit nightlies currently support this event + if ( document.addEventListener ) { + // Use the handy event callback + document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false ); + + // A fallback to window.onload, that will always work + window.addEventListener( "load", jQuery.ready, false ); + + // If IE event model is used + } else if ( document.attachEvent ) { + // ensure firing before onload, + // maybe late but safe also for iframes + document.attachEvent( "onreadystatechange", DOMContentLoaded ); + + // A fallback to window.onload, that will always work + window.attachEvent( "onload", jQuery.ready ); + + // If IE and not a frame + // continually check to see if the document is ready + var toplevel = false; + + try { + toplevel = window.frameElement == null; + } catch(e) {} + + if ( document.documentElement.doScroll && toplevel ) { + doScrollCheck(); + } + } + }, + + // See test/unit/core.js for details concerning isFunction. + // Since version 1.3, DOM methods and functions like alert + // aren't supported. They return false on IE (#2968). + isFunction: function( obj ) { + return jQuery.type(obj) === "function"; + }, + + isArray: Array.isArray || function( obj ) { + return jQuery.type(obj) === "array"; + }, + + // A crude way of determining if an object is a window + isWindow: function( obj ) { + return obj && typeof obj === "object" && "setInterval" in obj; + }, + + isNumeric: function( obj ) { + return !isNaN( parseFloat(obj) ) && isFinite( obj ); + }, + + type: function( obj ) { + return obj == null ? + String( obj ) : + class2type[ toString.call(obj) ] || "object"; + }, + + isPlainObject: function( obj ) { + // Must be an Object. + // Because of IE, we also have to check the presence of the constructor property. + // Make sure that DOM nodes and window objects don't pass through, as well + if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) { + return false; + } + + try { + // Not own constructor property must be Object + if ( obj.constructor && + !hasOwn.call(obj, "constructor") && + !hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) { + return false; + } + } catch ( e ) { + // IE8,9 Will throw exceptions on certain host objects #9897 + return false; + } + + // Own properties are enumerated firstly, so to speed up, + // if last one is own, then all properties are own. + + var key; + for ( key in obj ) {} + + return key === undefined || hasOwn.call( obj, key ); + }, + + isEmptyObject: function( obj ) { + for ( var name in obj ) { + return false; + } + return true; + }, + + error: function( msg ) { + throw new Error( msg ); + }, + + parseJSON: function( data ) { + if ( typeof data !== "string" || !data ) { + return null; + } + + // Make sure leading/trailing whitespace is removed (IE can't handle it) + data = jQuery.trim( data ); + + // Attempt to parse using the native JSON parser first + if ( window.JSON && window.JSON.parse ) { + return window.JSON.parse( data ); + } + + // Make sure the incoming data is actual JSON + // Logic borrowed from http://json.org/json2.js + if ( rvalidchars.test( data.replace( rvalidescape, "@" ) + .replace( rvalidtokens, "]" ) + .replace( rvalidbraces, "")) ) { + + return ( new Function( "return " + data ) )(); + + } + jQuery.error( "Invalid JSON: " + data ); + }, + + // Cross-browser xml parsing + parseXML: function( data ) { + var xml, tmp; + try { + if ( window.DOMParser ) { // Standard + tmp = new DOMParser(); + xml = tmp.parseFromString( data , "text/xml" ); + } else { // IE + xml = new ActiveXObject( "Microsoft.XMLDOM" ); + xml.async = "false"; + xml.loadXML( data ); + } + } catch( e ) { + xml = undefined; + } + if ( !xml || !xml.documentElement || xml.getElementsByTagName( "parsererror" ).length ) { + jQuery.error( "Invalid XML: " + data ); + } + return xml; + }, + + noop: function() {}, + + // Evaluates a script in a global context + // Workarounds based on findings by Jim Driscoll + // http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context + globalEval: function( data ) { + if ( data && rnotwhite.test( data ) ) { + // We use execScript on Internet Explorer + // We use an anonymous function so that context is window + // rather than jQuery in Firefox + ( window.execScript || function( data ) { + window[ "eval" ].call( window, data ); + } )( data ); + } + }, + + // Convert dashed to camelCase; used by the css and data modules + // Microsoft forgot to hump their vendor prefix (#9572) + camelCase: function( string ) { + return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase ); + }, + + nodeName: function( elem, name ) { + return elem.nodeName && elem.nodeName.toUpperCase() === name.toUpperCase(); + }, + + // args is for internal usage only + each: function( object, callback, args ) { + var name, i = 0, + length = object.length, + isObj = length === undefined || jQuery.isFunction( object ); + + if ( args ) { + if ( isObj ) { + for ( name in object ) { + if ( callback.apply( object[ name ], args ) === false ) { + break; + } + } + } else { + for ( ; i < length; ) { + if ( callback.apply( object[ i++ ], args ) === false ) { + break; + } + } + } + + // A special, fast, case for the most common use of each + } else { + if ( isObj ) { + for ( name in object ) { + if ( callback.call( object[ name ], name, object[ name ] ) === false ) { + break; + } + } + } else { + for ( ; i < length; ) { + if ( callback.call( object[ i ], i, object[ i++ ] ) === false ) { + break; + } + } + } + } + + return object; + }, + + // Use native String.trim function wherever possible + trim: trim ? + function( text ) { + return text == null ? + "" : + trim.call( text ); + } : + + // Otherwise use our own trimming functionality + function( text ) { + return text == null ? + "" : + text.toString().replace( trimLeft, "" ).replace( trimRight, "" ); + }, + + // results is for internal usage only + makeArray: function( array, results ) { + var ret = results || []; + + if ( array != null ) { + // The window, strings (and functions) also have 'length' + // Tweaked logic slightly to handle Blackberry 4.7 RegExp issues #6930 + var type = jQuery.type( array ); + + if ( array.length == null || type === "string" || type === "function" || type === "regexp" || jQuery.isWindow( array ) ) { + push.call( ret, array ); + } else { + jQuery.merge( ret, array ); + } + } + + return ret; + }, + + inArray: function( elem, array, i ) { + var len; + + if ( array ) { + if ( indexOf ) { + return indexOf.call( array, elem, i ); + } + + len = array.length; + i = i ? i < 0 ? Math.max( 0, len + i ) : i : 0; + + for ( ; i < len; i++ ) { + // Skip accessing in sparse arrays + if ( i in array && array[ i ] === elem ) { + return i; + } + } + } + + return -1; + }, + + merge: function( first, second ) { + var i = first.length, + j = 0; + + if ( typeof second.length === "number" ) { + for ( var l = second.length; j < l; j++ ) { + first[ i++ ] = second[ j ]; + } + + } else { + while ( second[j] !== undefined ) { + first[ i++ ] = second[ j++ ]; + } + } + + first.length = i; + + return first; + }, + + grep: function( elems, callback, inv ) { + var ret = [], retVal; + inv = !!inv; + + // Go through the array, only saving the items + // that pass the validator function + for ( var i = 0, length = elems.length; i < length; i++ ) { + retVal = !!callback( elems[ i ], i ); + if ( inv !== retVal ) { + ret.push( elems[ i ] ); + } + } + + return ret; + }, + + // arg is for internal usage only + map: function( elems, callback, arg ) { + var value, key, ret = [], + i = 0, + length = elems.length, + // jquery objects are treated as arrays + isArray = elems instanceof jQuery || length !== undefined && typeof length === "number" && ( ( length > 0 && elems[ 0 ] && elems[ length -1 ] ) || length === 0 || jQuery.isArray( elems ) ) ; + + // Go through the array, translating each of the items to their + if ( isArray ) { + for ( ; i < length; i++ ) { + value = callback( elems[ i ], i, arg ); + + if ( value != null ) { + ret[ ret.length ] = value; + } + } + + // Go through every key on the object, + } else { + for ( key in elems ) { + value = callback( elems[ key ], key, arg ); + + if ( value != null ) { + ret[ ret.length ] = value; + } + } + } + + // Flatten any nested arrays + return ret.concat.apply( [], ret ); + }, + + // A global GUID counter for objects + guid: 1, + + // Bind a function to a context, optionally partially applying any + // arguments. + proxy: function( fn, context ) { + if ( typeof context === "string" ) { + var tmp = fn[ context ]; + context = fn; + fn = tmp; + } + + // Quick check to determine if target is callable, in the spec + // this throws a TypeError, but we will just return undefined. + if ( !jQuery.isFunction( fn ) ) { + return undefined; + } + + // Simulated bind + var args = slice.call( arguments, 2 ), + proxy = function() { + return fn.apply( context, args.concat( slice.call( arguments ) ) ); + }; + + // Set the guid of unique handler to the same of original handler, so it can be removed + proxy.guid = fn.guid = fn.guid || proxy.guid || jQuery.guid++; + + return proxy; + }, + + // Mutifunctional method to get and set values to a collection + // The value/s can optionally be executed if it's a function + access: function( elems, key, value, exec, fn, pass ) { + var length = elems.length; + + // Setting many attributes + if ( typeof key === "object" ) { + for ( var k in key ) { + jQuery.access( elems, k, key[k], exec, fn, value ); + } + return elems; + } + + // Setting one attribute + if ( value !== undefined ) { + // Optionally, function values get executed if exec is true + exec = !pass && exec && jQuery.isFunction(value); + + for ( var i = 0; i < length; i++ ) { + fn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass ); + } + + return elems; + } + + // Getting an attribute + return length ? fn( elems[0], key ) : undefined; + }, + + now: function() { + return ( new Date() ).getTime(); + }, + + // Use of jQuery.browser is frowned upon. + // More details: http://docs.jquery.com/Utilities/jQuery.browser + uaMatch: function( ua ) { + ua = ua.toLowerCase(); + + var match = rwebkit.exec( ua ) || + ropera.exec( ua ) || + rmsie.exec( ua ) || + ua.indexOf("compatible") < 0 && rmozilla.exec( ua ) || + []; + + return { browser: match[1] || "", version: match[2] || "0" }; + }, + + sub: function() { + function jQuerySub( selector, context ) { + return new jQuerySub.fn.init( selector, context ); + } + jQuery.extend( true, jQuerySub, this ); + jQuerySub.superclass = this; + jQuerySub.fn = jQuerySub.prototype = this(); + jQuerySub.fn.constructor = jQuerySub; + jQuerySub.sub = this.sub; + jQuerySub.fn.init = function init( selector, context ) { + if ( context && context instanceof jQuery && !(context instanceof jQuerySub) ) { + context = jQuerySub( context ); + } + + return jQuery.fn.init.call( this, selector, context, rootjQuerySub ); + }; + jQuerySub.fn.init.prototype = jQuerySub.fn; + var rootjQuerySub = jQuerySub(document); + return jQuerySub; + }, + + browser: {} +}); + +// Populate the class2type map +jQuery.each("Boolean Number String Function Array Date RegExp Object".split(" "), function(i, name) { + class2type[ "[object " + name + "]" ] = name.toLowerCase(); +}); + +browserMatch = jQuery.uaMatch( userAgent ); +if ( browserMatch.browser ) { + jQuery.browser[ browserMatch.browser ] = true; + jQuery.browser.version = browserMatch.version; +} + +// Deprecated, use jQuery.browser.webkit instead +if ( jQuery.browser.webkit ) { + jQuery.browser.safari = true; +} + +// IE doesn't match non-breaking spaces with \s +if ( rnotwhite.test( "\xA0" ) ) { + trimLeft = /^[\s\xA0]+/; + trimRight = /[\s\xA0]+$/; +} + +// All jQuery objects should point back to these +rootjQuery = jQuery(document); + +// Cleanup functions for the document ready method +if ( document.addEventListener ) { + DOMContentLoaded = function() { + document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false ); + jQuery.ready(); + }; + +} else if ( document.attachEvent ) { + DOMContentLoaded = function() { + // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443). + if ( document.readyState === "complete" ) { + document.detachEvent( "onreadystatechange", DOMContentLoaded ); + jQuery.ready(); + } + }; +} + +// The DOM ready check for Internet Explorer +function doScrollCheck() { + if ( jQuery.isReady ) { + return; + } + + try { + // If IE is used, use the trick by Diego Perini + // http://javascript.nwbox.com/IEContentLoaded/ + document.documentElement.doScroll("left"); + } catch(e) { + setTimeout( doScrollCheck, 1 ); + return; + } + + // and execute any waiting functions + jQuery.ready(); +} + +return jQuery; + +})(); + + +// String to Object flags format cache +var flagsCache = {}; + +// Convert String-formatted flags into Object-formatted ones and store in cache +function createFlags( flags ) { + var object = flagsCache[ flags ] = {}, + i, length; + flags = flags.split( /\s+/ ); + for ( i = 0, length = flags.length; i < length; i++ ) { + object[ flags[i] ] = true; + } + return object; +} + +/* + * Create a callback list using the following parameters: + * + * flags: an optional list of space-separated flags that will change how + * the callback list behaves + * + * By default a callback list will act like an event callback list and can be + * "fired" multiple times. + * + * Possible flags: + * + * once: will ensure the callback list can only be fired once (like a Deferred) + * + * memory: will keep track of previous values and will call any callback added + * after the list has been fired right away with the latest "memorized" + * values (like a Deferred) + * + * unique: will ensure a callback can only be added once (no duplicate in the list) + * + * stopOnFalse: interrupt callings when a callback returns false + * + */ +jQuery.Callbacks = function( flags ) { + + // Convert flags from String-formatted to Object-formatted + // (we check in cache first) + flags = flags ? ( flagsCache[ flags ] || createFlags( flags ) ) : {}; + + var // Actual callback list + list = [], + // Stack of fire calls for repeatable lists + stack = [], + // Last fire value (for non-forgettable lists) + memory, + // Flag to know if list is currently firing + firing, + // First callback to fire (used internally by add and fireWith) + firingStart, + // End of the loop when firing + firingLength, + // Index of currently firing callback (modified by remove if needed) + firingIndex, + // Add one or several callbacks to the list + add = function( args ) { + var i, + length, + elem, + type, + actual; + for ( i = 0, length = args.length; i < length; i++ ) { + elem = args[ i ]; + type = jQuery.type( elem ); + if ( type === "array" ) { + // Inspect recursively + add( elem ); + } else if ( type === "function" ) { + // Add if not in unique mode and callback is not in + if ( !flags.unique || !self.has( elem ) ) { + list.push( elem ); + } + } + } + }, + // Fire callbacks + fire = function( context, args ) { + args = args || []; + memory = !flags.memory || [ context, args ]; + firing = true; + firingIndex = firingStart || 0; + firingStart = 0; + firingLength = list.length; + for ( ; list && firingIndex < firingLength; firingIndex++ ) { + if ( list[ firingIndex ].apply( context, args ) === false && flags.stopOnFalse ) { + memory = true; // Mark as halted + break; + } + } + firing = false; + if ( list ) { + if ( !flags.once ) { + if ( stack && stack.length ) { + memory = stack.shift(); + self.fireWith( memory[ 0 ], memory[ 1 ] ); + } + } else if ( memory === true ) { + self.disable(); + } else { + list = []; + } + } + }, + // Actual Callbacks object + self = { + // Add a callback or a collection of callbacks to the list + add: function() { + if ( list ) { + var length = list.length; + add( arguments ); + // Do we need to add the callbacks to the + // current firing batch? + if ( firing ) { + firingLength = list.length; + // With memory, if we're not firing then + // we should call right away, unless previous + // firing was halted (stopOnFalse) + } else if ( memory && memory !== true ) { + firingStart = length; + fire( memory[ 0 ], memory[ 1 ] ); + } + } + return this; + }, + // Remove a callback from the list + remove: function() { + if ( list ) { + var args = arguments, + argIndex = 0, + argLength = args.length; + for ( ; argIndex < argLength ; argIndex++ ) { + for ( var i = 0; i < list.length; i++ ) { + if ( args[ argIndex ] === list[ i ] ) { + // Handle firingIndex and firingLength + if ( firing ) { + if ( i <= firingLength ) { + firingLength--; + if ( i <= firingIndex ) { + firingIndex--; + } + } + } + // Remove the element + list.splice( i--, 1 ); + // If we have some unicity property then + // we only need to do this once + if ( flags.unique ) { + break; + } + } + } + } + } + return this; + }, + // Control if a given callback is in the list + has: function( fn ) { + if ( list ) { + var i = 0, + length = list.length; + for ( ; i < length; i++ ) { + if ( fn === list[ i ] ) { + return true; + } + } + } + return false; + }, + // Remove all callbacks from the list + empty: function() { + list = []; + return this; + }, + // Have the list do nothing anymore + disable: function() { + list = stack = memory = undefined; + return this; + }, + // Is it disabled? + disabled: function() { + return !list; + }, + // Lock the list in its current state + lock: function() { + stack = undefined; + if ( !memory || memory === true ) { + self.disable(); + } + return this; + }, + // Is it locked? + locked: function() { + return !stack; + }, + // Call all callbacks with the given context and arguments + fireWith: function( context, args ) { + if ( stack ) { + if ( firing ) { + if ( !flags.once ) { + stack.push( [ context, args ] ); + } + } else if ( !( flags.once && memory ) ) { + fire( context, args ); + } + } + return this; + }, + // Call all the callbacks with the given arguments + fire: function() { + self.fireWith( this, arguments ); + return this; + }, + // To know if the callbacks have already been called at least once + fired: function() { + return !!memory; + } + }; + + return self; +}; + + + + +var // Static reference to slice + sliceDeferred = [].slice; + +jQuery.extend({ + + Deferred: function( func ) { + var doneList = jQuery.Callbacks( "once memory" ), + failList = jQuery.Callbacks( "once memory" ), + progressList = jQuery.Callbacks( "memory" ), + state = "pending", + lists = { + resolve: doneList, + reject: failList, + notify: progressList + }, + promise = { + done: doneList.add, + fail: failList.add, + progress: progressList.add, + + state: function() { + return state; + }, + + // Deprecated + isResolved: doneList.fired, + isRejected: failList.fired, + + then: function( doneCallbacks, failCallbacks, progressCallbacks ) { + deferred.done( doneCallbacks ).fail( failCallbacks ).progress( progressCallbacks ); + return this; + }, + always: function() { + deferred.done.apply( deferred, arguments ).fail.apply( deferred, arguments ); + return this; + }, + pipe: function( fnDone, fnFail, fnProgress ) { + return jQuery.Deferred(function( newDefer ) { + jQuery.each( { + done: [ fnDone, "resolve" ], + fail: [ fnFail, "reject" ], + progress: [ fnProgress, "notify" ] + }, function( handler, data ) { + var fn = data[ 0 ], + action = data[ 1 ], + returned; + if ( jQuery.isFunction( fn ) ) { + deferred[ handler ](function() { + returned = fn.apply( this, arguments ); + if ( returned && jQuery.isFunction( returned.promise ) ) { + returned.promise().then( newDefer.resolve, newDefer.reject, newDefer.notify ); + } else { + newDefer[ action + "With" ]( this === deferred ? newDefer : this, [ returned ] ); + } + }); + } else { + deferred[ handler ]( newDefer[ action ] ); + } + }); + }).promise(); + }, + // Get a promise for this deferred + // If obj is provided, the promise aspect is added to the object + promise: function( obj ) { + if ( obj == null ) { + obj = promise; + } else { + for ( var key in promise ) { + obj[ key ] = promise[ key ]; + } + } + return obj; + } + }, + deferred = promise.promise({}), + key; + + for ( key in lists ) { + deferred[ key ] = lists[ key ].fire; + deferred[ key + "With" ] = lists[ key ].fireWith; + } + + // Handle state + deferred.done( function() { + state = "resolved"; + }, failList.disable, progressList.lock ).fail( function() { + state = "rejected"; + }, doneList.disable, progressList.lock ); + + // Call given func if any + if ( func ) { + func.call( deferred, deferred ); + } + + // All done! + return deferred; + }, + + // Deferred helper + when: function( firstParam ) { + var args = sliceDeferred.call( arguments, 0 ), + i = 0, + length = args.length, + pValues = new Array( length ), + count = length, + pCount = length, + deferred = length <= 1 && firstParam && jQuery.isFunction( firstParam.promise ) ? + firstParam : + jQuery.Deferred(), + promise = deferred.promise(); + function resolveFunc( i ) { + return function( value ) { + args[ i ] = arguments.length > 1 ? sliceDeferred.call( arguments, 0 ) : value; + if ( !( --count ) ) { + deferred.resolveWith( deferred, args ); + } + }; + } + function progressFunc( i ) { + return function( value ) { + pValues[ i ] = arguments.length > 1 ? sliceDeferred.call( arguments, 0 ) : value; + deferred.notifyWith( promise, pValues ); + }; + } + if ( length > 1 ) { + for ( ; i < length; i++ ) { + if ( args[ i ] && args[ i ].promise && jQuery.isFunction( args[ i ].promise ) ) { + args[ i ].promise().then( resolveFunc(i), deferred.reject, progressFunc(i) ); + } else { + --count; + } + } + if ( !count ) { + deferred.resolveWith( deferred, args ); + } + } else if ( deferred !== firstParam ) { + deferred.resolveWith( deferred, length ? [ firstParam ] : [] ); + } + return promise; + } +}); + + + + +jQuery.support = (function() { + + var support, + all, + a, + select, + opt, + input, + marginDiv, + fragment, + tds, + events, + eventName, + i, + isSupported, + div = document.createElement( "div" ), + documentElement = document.documentElement; + + // Preliminary tests + div.setAttribute("className", "t"); + div.innerHTML = "
a"; + + all = div.getElementsByTagName( "*" ); + a = div.getElementsByTagName( "a" )[ 0 ]; + + // Can't get basic test support + if ( !all || !all.length || !a ) { + return {}; + } + + // First batch of supports tests + select = document.createElement( "select" ); + opt = select.appendChild( document.createElement("option") ); + input = div.getElementsByTagName( "input" )[ 0 ]; + + support = { + // IE strips leading whitespace when .innerHTML is used + leadingWhitespace: ( div.firstChild.nodeType === 3 ), + + // Make sure that tbody elements aren't automatically inserted + // IE will insert them into empty tables + tbody: !div.getElementsByTagName("tbody").length, + + // Make sure that link elements get serialized correctly by innerHTML + // This requires a wrapper element in IE + htmlSerialize: !!div.getElementsByTagName("link").length, + + // Get the style information from getAttribute + // (IE uses .cssText instead) + style: /top/.test( a.getAttribute("style") ), + + // Make sure that URLs aren't manipulated + // (IE normalizes it by default) + hrefNormalized: ( a.getAttribute("href") === "/a" ), + + // Make sure that element opacity exists + // (IE uses filter instead) + // Use a regex to work around a WebKit issue. See #5145 + opacity: /^0.55/.test( a.style.opacity ), + + // Verify style float existence + // (IE uses styleFloat instead of cssFloat) + cssFloat: !!a.style.cssFloat, + + // Make sure that if no value is specified for a checkbox + // that it defaults to "on". + // (WebKit defaults to "" instead) + checkOn: ( input.value === "on" ), + + // Make sure that a selected-by-default option has a working selected property. + // (WebKit defaults to false instead of true, IE too, if it's in an optgroup) + optSelected: opt.selected, + + // Test setAttribute on camelCase class. If it works, we need attrFixes when doing get/setAttribute (ie6/7) + getSetAttribute: div.className !== "t", + + // Tests for enctype support on a form(#6743) + enctype: !!document.createElement("form").enctype, + + // Makes sure cloning an html5 element does not cause problems + // Where outerHTML is undefined, this still works + html5Clone: document.createElement("nav").cloneNode( true ).outerHTML !== "<:nav>", + + // Will be defined later + submitBubbles: true, + changeBubbles: true, + focusinBubbles: false, + deleteExpando: true, + noCloneEvent: true, + inlineBlockNeedsLayout: false, + shrinkWrapBlocks: false, + reliableMarginRight: true + }; + + // Make sure checked status is properly cloned + input.checked = true; + support.noCloneChecked = input.cloneNode( true ).checked; + + // Make sure that the options inside disabled selects aren't marked as disabled + // (WebKit marks them as disabled) + select.disabled = true; + support.optDisabled = !opt.disabled; + + // Test to see if it's possible to delete an expando from an element + // Fails in Internet Explorer + try { + delete div.test; + } catch( e ) { + support.deleteExpando = false; + } + + if ( !div.addEventListener && div.attachEvent && div.fireEvent ) { + div.attachEvent( "onclick", function() { + // Cloning a node shouldn't copy over any + // bound event handlers (IE does this) + support.noCloneEvent = false; + }); + div.cloneNode( true ).fireEvent( "onclick" ); + } + + // Check if a radio maintains its value + // after being appended to the DOM + input = document.createElement("input"); + input.value = "t"; + input.setAttribute("type", "radio"); + support.radioValue = input.value === "t"; + + input.setAttribute("checked", "checked"); + div.appendChild( input ); + fragment = document.createDocumentFragment(); + fragment.appendChild( div.lastChild ); + + // WebKit doesn't clone checked state correctly in fragments + support.checkClone = fragment.cloneNode( true ).cloneNode( true ).lastChild.checked; + + // Check if a disconnected checkbox will retain its checked + // value of true after appended to the DOM (IE6/7) + support.appendChecked = input.checked; + + fragment.removeChild( input ); + fragment.appendChild( div ); + + div.innerHTML = ""; + + // Check if div with explicit width and no margin-right incorrectly + // gets computed margin-right based on width of container. For more + // info see bug #3333 + // Fails in WebKit before Feb 2011 nightlies + // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right + if ( window.getComputedStyle ) { + marginDiv = document.createElement( "div" ); + marginDiv.style.width = "0"; + marginDiv.style.marginRight = "0"; + div.style.width = "2px"; + div.appendChild( marginDiv ); + support.reliableMarginRight = + ( parseInt( ( window.getComputedStyle( marginDiv, null ) || { marginRight: 0 } ).marginRight, 10 ) || 0 ) === 0; + } + + // Technique from Juriy Zaytsev + // http://perfectionkills.com/detecting-event-support-without-browser-sniffing/ + // We only care about the case where non-standard event systems + // are used, namely in IE. Short-circuiting here helps us to + // avoid an eval call (in setAttribute) which can cause CSP + // to go haywire. See: https://developer.mozilla.org/en/Security/CSP + if ( div.attachEvent ) { + for( i in { + submit: 1, + change: 1, + focusin: 1 + }) { + eventName = "on" + i; + isSupported = ( eventName in div ); + if ( !isSupported ) { + div.setAttribute( eventName, "return;" ); + isSupported = ( typeof div[ eventName ] === "function" ); + } + support[ i + "Bubbles" ] = isSupported; + } + } + + fragment.removeChild( div ); + + // Null elements to avoid leaks in IE + fragment = select = opt = marginDiv = div = input = null; + + // Run tests that need a body at doc ready + jQuery(function() { + var container, outer, inner, table, td, offsetSupport, + conMarginTop, ptlm, vb, style, html, + body = document.getElementsByTagName("body")[0]; + + if ( !body ) { + // Return for frameset docs that don't have a body + return; + } + + conMarginTop = 1; + ptlm = "position:absolute;top:0;left:0;width:1px;height:1px;margin:0;"; + vb = "visibility:hidden;border:0;"; + style = "style='" + ptlm + "border:5px solid #000;padding:0;'"; + html = "
" + + "" + + "
"; + + container = document.createElement("div"); + container.style.cssText = vb + "width:0;height:0;position:static;top:0;margin-top:" + conMarginTop + "px"; + body.insertBefore( container, body.firstChild ); + + // Construct the test element + div = document.createElement("div"); + container.appendChild( div ); + + // Check if table cells still have offsetWidth/Height when they are set + // to display:none and there are still other visible table cells in a + // table row; if so, offsetWidth/Height are not reliable for use when + // determining if an element has been hidden directly using + // display:none (it is still safe to use offsets if a parent element is + // hidden; don safety goggles and see bug #4512 for more information). + // (only IE 8 fails this test) + div.innerHTML = "
t
"; + tds = div.getElementsByTagName( "td" ); + isSupported = ( tds[ 0 ].offsetHeight === 0 ); + + tds[ 0 ].style.display = ""; + tds[ 1 ].style.display = "none"; + + // Check if empty table cells still have offsetWidth/Height + // (IE <= 8 fail this test) + support.reliableHiddenOffsets = isSupported && ( tds[ 0 ].offsetHeight === 0 ); + + // Figure out if the W3C box model works as expected + div.innerHTML = ""; + div.style.width = div.style.paddingLeft = "1px"; + jQuery.boxModel = support.boxModel = div.offsetWidth === 2; + + if ( typeof div.style.zoom !== "undefined" ) { + // Check if natively block-level elements act like inline-block + // elements when setting their display to 'inline' and giving + // them layout + // (IE < 8 does this) + div.style.display = "inline"; + div.style.zoom = 1; + support.inlineBlockNeedsLayout = ( div.offsetWidth === 2 ); + + // Check if elements with layout shrink-wrap their children + // (IE 6 does this) + div.style.display = ""; + div.innerHTML = "
"; + support.shrinkWrapBlocks = ( div.offsetWidth !== 2 ); + } + + div.style.cssText = ptlm + vb; + div.innerHTML = html; + + outer = div.firstChild; + inner = outer.firstChild; + td = outer.nextSibling.firstChild.firstChild; + + offsetSupport = { + doesNotAddBorder: ( inner.offsetTop !== 5 ), + doesAddBorderForTableAndCells: ( td.offsetTop === 5 ) + }; + + inner.style.position = "fixed"; + inner.style.top = "20px"; + + // safari subtracts parent border width here which is 5px + offsetSupport.fixedPosition = ( inner.offsetTop === 20 || inner.offsetTop === 15 ); + inner.style.position = inner.style.top = ""; + + outer.style.overflow = "hidden"; + outer.style.position = "relative"; + + offsetSupport.subtractsBorderForOverflowNotVisible = ( inner.offsetTop === -5 ); + offsetSupport.doesNotIncludeMarginInBodyOffset = ( body.offsetTop !== conMarginTop ); + + body.removeChild( container ); + div = container = null; + + jQuery.extend( support, offsetSupport ); + }); + + return support; +})(); + + + + +var rbrace = /^(?:\{.*\}|\[.*\])$/, + rmultiDash = /([A-Z])/g; + +jQuery.extend({ + cache: {}, + + // Please use with caution + uuid: 0, + + // Unique for each copy of jQuery on the page + // Non-digits removed to match rinlinejQuery + expando: "jQuery" + ( jQuery.fn.jquery + Math.random() ).replace( /\D/g, "" ), + + // The following elements throw uncatchable exceptions if you + // attempt to add expando properties to them. + noData: { + "embed": true, + // Ban all objects except for Flash (which handle expandos) + "object": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000", + "applet": true + }, + + hasData: function( elem ) { + elem = elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ]; + return !!elem && !isEmptyDataObject( elem ); + }, + + data: function( elem, name, data, pvt /* Internal Use Only */ ) { + if ( !jQuery.acceptData( elem ) ) { + return; + } + + var privateCache, thisCache, ret, + internalKey = jQuery.expando, + getByName = typeof name === "string", + + // We have to handle DOM nodes and JS objects differently because IE6-7 + // can't GC object references properly across the DOM-JS boundary + isNode = elem.nodeType, + + // Only DOM nodes need the global jQuery cache; JS object data is + // attached directly to the object so GC can occur automatically + cache = isNode ? jQuery.cache : elem, + + // Only defining an ID for JS objects if its cache already exists allows + // the code to shortcut on the same path as a DOM node with no cache + id = isNode ? elem[ internalKey ] : elem[ internalKey ] && internalKey, + isEvents = name === "events"; + + // Avoid doing any more work than we need to when trying to get data on an + // object that has no data at all + if ( (!id || !cache[id] || (!isEvents && !pvt && !cache[id].data)) && getByName && data === undefined ) { + return; + } + + if ( !id ) { + // Only DOM nodes need a new unique ID for each element since their data + // ends up in the global cache + if ( isNode ) { + elem[ internalKey ] = id = ++jQuery.uuid; + } else { + id = internalKey; + } + } + + if ( !cache[ id ] ) { + cache[ id ] = {}; + + // Avoids exposing jQuery metadata on plain JS objects when the object + // is serialized using JSON.stringify + if ( !isNode ) { + cache[ id ].toJSON = jQuery.noop; + } + } + + // An object can be passed to jQuery.data instead of a key/value pair; this gets + // shallow copied over onto the existing cache + if ( typeof name === "object" || typeof name === "function" ) { + if ( pvt ) { + cache[ id ] = jQuery.extend( cache[ id ], name ); + } else { + cache[ id ].data = jQuery.extend( cache[ id ].data, name ); + } + } + + privateCache = thisCache = cache[ id ]; + + // jQuery data() is stored in a separate object inside the object's internal data + // cache in order to avoid key collisions between internal data and user-defined + // data. + if ( !pvt ) { + if ( !thisCache.data ) { + thisCache.data = {}; + } + + thisCache = thisCache.data; + } + + if ( data !== undefined ) { + thisCache[ jQuery.camelCase( name ) ] = data; + } + + // Users should not attempt to inspect the internal events object using jQuery.data, + // it is undocumented and subject to change. But does anyone listen? No. + if ( isEvents && !thisCache[ name ] ) { + return privateCache.events; + } + + // Check for both converted-to-camel and non-converted data property names + // If a data property was specified + if ( getByName ) { + + // First Try to find as-is property data + ret = thisCache[ name ]; + + // Test for null|undefined property data + if ( ret == null ) { + + // Try to find the camelCased property + ret = thisCache[ jQuery.camelCase( name ) ]; + } + } else { + ret = thisCache; + } + + return ret; + }, + + removeData: function( elem, name, pvt /* Internal Use Only */ ) { + if ( !jQuery.acceptData( elem ) ) { + return; + } + + var thisCache, i, l, + + // Reference to internal data cache key + internalKey = jQuery.expando, + + isNode = elem.nodeType, + + // See jQuery.data for more information + cache = isNode ? jQuery.cache : elem, + + // See jQuery.data for more information + id = isNode ? elem[ internalKey ] : internalKey; + + // If there is already no cache entry for this object, there is no + // purpose in continuing + if ( !cache[ id ] ) { + return; + } + + if ( name ) { + + thisCache = pvt ? cache[ id ] : cache[ id ].data; + + if ( thisCache ) { + + // Support array or space separated string names for data keys + if ( !jQuery.isArray( name ) ) { + + // try the string as a key before any manipulation + if ( name in thisCache ) { + name = [ name ]; + } else { + + // split the camel cased version by spaces unless a key with the spaces exists + name = jQuery.camelCase( name ); + if ( name in thisCache ) { + name = [ name ]; + } else { + name = name.split( " " ); + } + } + } + + for ( i = 0, l = name.length; i < l; i++ ) { + delete thisCache[ name[i] ]; + } + + // If there is no data left in the cache, we want to continue + // and let the cache object itself get destroyed + if ( !( pvt ? isEmptyDataObject : jQuery.isEmptyObject )( thisCache ) ) { + return; + } + } + } + + // See jQuery.data for more information + if ( !pvt ) { + delete cache[ id ].data; + + // Don't destroy the parent cache unless the internal data object + // had been the only thing left in it + if ( !isEmptyDataObject(cache[ id ]) ) { + return; + } + } + + // Browsers that fail expando deletion also refuse to delete expandos on + // the window, but it will allow it on all other JS objects; other browsers + // don't care + // Ensure that `cache` is not a window object #10080 + if ( jQuery.support.deleteExpando || !cache.setInterval ) { + delete cache[ id ]; + } else { + cache[ id ] = null; + } + + // We destroyed the cache and need to eliminate the expando on the node to avoid + // false lookups in the cache for entries that no longer exist + if ( isNode ) { + // IE does not allow us to delete expando properties from nodes, + // nor does it have a removeAttribute function on Document nodes; + // we must handle all of these cases + if ( jQuery.support.deleteExpando ) { + delete elem[ internalKey ]; + } else if ( elem.removeAttribute ) { + elem.removeAttribute( internalKey ); + } else { + elem[ internalKey ] = null; + } + } + }, + + // For internal use only. + _data: function( elem, name, data ) { + return jQuery.data( elem, name, data, true ); + }, + + // A method for determining if a DOM node can handle the data expando + acceptData: function( elem ) { + if ( elem.nodeName ) { + var match = jQuery.noData[ elem.nodeName.toLowerCase() ]; + + if ( match ) { + return !(match === true || elem.getAttribute("classid") !== match); + } + } + + return true; + } +}); + +jQuery.fn.extend({ + data: function( key, value ) { + var parts, attr, name, + data = null; + + if ( typeof key === "undefined" ) { + if ( this.length ) { + data = jQuery.data( this[0] ); + + if ( this[0].nodeType === 1 && !jQuery._data( this[0], "parsedAttrs" ) ) { + attr = this[0].attributes; + for ( var i = 0, l = attr.length; i < l; i++ ) { + name = attr[i].name; + + if ( name.indexOf( "data-" ) === 0 ) { + name = jQuery.camelCase( name.substring(5) ); + + dataAttr( this[0], name, data[ name ] ); + } + } + jQuery._data( this[0], "parsedAttrs", true ); + } + } + + return data; + + } else if ( typeof key === "object" ) { + return this.each(function() { + jQuery.data( this, key ); + }); + } + + parts = key.split("."); + parts[1] = parts[1] ? "." + parts[1] : ""; + + if ( value === undefined ) { + data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]); + + // Try to fetch any internally stored data first + if ( data === undefined && this.length ) { + data = jQuery.data( this[0], key ); + data = dataAttr( this[0], key, data ); + } + + return data === undefined && parts[1] ? + this.data( parts[0] ) : + data; + + } else { + return this.each(function() { + var self = jQuery( this ), + args = [ parts[0], value ]; + + self.triggerHandler( "setData" + parts[1] + "!", args ); + jQuery.data( this, key, value ); + self.triggerHandler( "changeData" + parts[1] + "!", args ); + }); + } + }, + + removeData: function( key ) { + return this.each(function() { + jQuery.removeData( this, key ); + }); + } +}); + +function dataAttr( elem, key, data ) { + // If nothing was found internally, try to fetch any + // data from the HTML5 data-* attribute + if ( data === undefined && elem.nodeType === 1 ) { + + var name = "data-" + key.replace( rmultiDash, "-$1" ).toLowerCase(); + + data = elem.getAttribute( name ); + + if ( typeof data === "string" ) { + try { + data = data === "true" ? true : + data === "false" ? false : + data === "null" ? null : + jQuery.isNumeric( data ) ? parseFloat( data ) : + rbrace.test( data ) ? jQuery.parseJSON( data ) : + data; + } catch( e ) {} + + // Make sure we set the data so it isn't changed later + jQuery.data( elem, key, data ); + + } else { + data = undefined; + } + } + + return data; +} + +// checks a cache object for emptiness +function isEmptyDataObject( obj ) { + for ( var name in obj ) { + + // if the public data object is empty, the private is still empty + if ( name === "data" && jQuery.isEmptyObject( obj[name] ) ) { + continue; + } + if ( name !== "toJSON" ) { + return false; + } + } + + return true; +} + + + + +function handleQueueMarkDefer( elem, type, src ) { + var deferDataKey = type + "defer", + queueDataKey = type + "queue", + markDataKey = type + "mark", + defer = jQuery._data( elem, deferDataKey ); + if ( defer && + ( src === "queue" || !jQuery._data(elem, queueDataKey) ) && + ( src === "mark" || !jQuery._data(elem, markDataKey) ) ) { + // Give room for hard-coded callbacks to fire first + // and eventually mark/queue something else on the element + setTimeout( function() { + if ( !jQuery._data( elem, queueDataKey ) && + !jQuery._data( elem, markDataKey ) ) { + jQuery.removeData( elem, deferDataKey, true ); + defer.fire(); + } + }, 0 ); + } +} + +jQuery.extend({ + + _mark: function( elem, type ) { + if ( elem ) { + type = ( type || "fx" ) + "mark"; + jQuery._data( elem, type, (jQuery._data( elem, type ) || 0) + 1 ); + } + }, + + _unmark: function( force, elem, type ) { + if ( force !== true ) { + type = elem; + elem = force; + force = false; + } + if ( elem ) { + type = type || "fx"; + var key = type + "mark", + count = force ? 0 : ( (jQuery._data( elem, key ) || 1) - 1 ); + if ( count ) { + jQuery._data( elem, key, count ); + } else { + jQuery.removeData( elem, key, true ); + handleQueueMarkDefer( elem, type, "mark" ); + } + } + }, + + queue: function( elem, type, data ) { + var q; + if ( elem ) { + type = ( type || "fx" ) + "queue"; + q = jQuery._data( elem, type ); + + // Speed up dequeue by getting out quickly if this is just a lookup + if ( data ) { + if ( !q || jQuery.isArray(data) ) { + q = jQuery._data( elem, type, jQuery.makeArray(data) ); + } else { + q.push( data ); + } + } + return q || []; + } + }, + + dequeue: function( elem, type ) { + type = type || "fx"; + + var queue = jQuery.queue( elem, type ), + fn = queue.shift(), + hooks = {}; + + // If the fx queue is dequeued, always remove the progress sentinel + if ( fn === "inprogress" ) { + fn = queue.shift(); + } + + if ( fn ) { + // Add a progress sentinel to prevent the fx queue from being + // automatically dequeued + if ( type === "fx" ) { + queue.unshift( "inprogress" ); + } + + jQuery._data( elem, type + ".run", hooks ); + fn.call( elem, function() { + jQuery.dequeue( elem, type ); + }, hooks ); + } + + if ( !queue.length ) { + jQuery.removeData( elem, type + "queue " + type + ".run", true ); + handleQueueMarkDefer( elem, type, "queue" ); + } + } +}); + +jQuery.fn.extend({ + queue: function( type, data ) { + if ( typeof type !== "string" ) { + data = type; + type = "fx"; + } + + if ( data === undefined ) { + return jQuery.queue( this[0], type ); + } + return this.each(function() { + var queue = jQuery.queue( this, type, data ); + + if ( type === "fx" && queue[0] !== "inprogress" ) { + jQuery.dequeue( this, type ); + } + }); + }, + dequeue: function( type ) { + return this.each(function() { + jQuery.dequeue( this, type ); + }); + }, + // Based off of the plugin by Clint Helfers, with permission. + // http://blindsignals.com/index.php/2009/07/jquery-delay/ + delay: function( time, type ) { + time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time; + type = type || "fx"; + + return this.queue( type, function( next, hooks ) { + var timeout = setTimeout( next, time ); + hooks.stop = function() { + clearTimeout( timeout ); + }; + }); + }, + clearQueue: function( type ) { + return this.queue( type || "fx", [] ); + }, + // Get a promise resolved when queues of a certain type + // are emptied (fx is the type by default) + promise: function( type, object ) { + if ( typeof type !== "string" ) { + object = type; + type = undefined; + } + type = type || "fx"; + var defer = jQuery.Deferred(), + elements = this, + i = elements.length, + count = 1, + deferDataKey = type + "defer", + queueDataKey = type + "queue", + markDataKey = type + "mark", + tmp; + function resolve() { + if ( !( --count ) ) { + defer.resolveWith( elements, [ elements ] ); + } + } + while( i-- ) { + if (( tmp = jQuery.data( elements[ i ], deferDataKey, undefined, true ) || + ( jQuery.data( elements[ i ], queueDataKey, undefined, true ) || + jQuery.data( elements[ i ], markDataKey, undefined, true ) ) && + jQuery.data( elements[ i ], deferDataKey, jQuery.Callbacks( "once memory" ), true ) )) { + count++; + tmp.add( resolve ); + } + } + resolve(); + return defer.promise(); + } +}); + + + + +var rclass = /[\n\t\r]/g, + rspace = /\s+/, + rreturn = /\r/g, + rtype = /^(?:button|input)$/i, + rfocusable = /^(?:button|input|object|select|textarea)$/i, + rclickable = /^a(?:rea)?$/i, + rboolean = /^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i, + getSetAttribute = jQuery.support.getSetAttribute, + nodeHook, boolHook, fixSpecified; + +jQuery.fn.extend({ + attr: function( name, value ) { + return jQuery.access( this, name, value, true, jQuery.attr ); + }, + + removeAttr: function( name ) { + return this.each(function() { + jQuery.removeAttr( this, name ); + }); + }, + + prop: function( name, value ) { + return jQuery.access( this, name, value, true, jQuery.prop ); + }, + + removeProp: function( name ) { + name = jQuery.propFix[ name ] || name; + return this.each(function() { + // try/catch handles cases where IE balks (such as removing a property on window) + try { + this[ name ] = undefined; + delete this[ name ]; + } catch( e ) {} + }); + }, + + addClass: function( value ) { + var classNames, i, l, elem, + setClass, c, cl; + + if ( jQuery.isFunction( value ) ) { + return this.each(function( j ) { + jQuery( this ).addClass( value.call(this, j, this.className) ); + }); + } + + if ( value && typeof value === "string" ) { + classNames = value.split( rspace ); + + for ( i = 0, l = this.length; i < l; i++ ) { + elem = this[ i ]; + + if ( elem.nodeType === 1 ) { + if ( !elem.className && classNames.length === 1 ) { + elem.className = value; + + } else { + setClass = " " + elem.className + " "; + + for ( c = 0, cl = classNames.length; c < cl; c++ ) { + if ( !~setClass.indexOf( " " + classNames[ c ] + " " ) ) { + setClass += classNames[ c ] + " "; + } + } + elem.className = jQuery.trim( setClass ); + } + } + } + } + + return this; + }, + + removeClass: function( value ) { + var classNames, i, l, elem, className, c, cl; + + if ( jQuery.isFunction( value ) ) { + return this.each(function( j ) { + jQuery( this ).removeClass( value.call(this, j, this.className) ); + }); + } + + if ( (value && typeof value === "string") || value === undefined ) { + classNames = ( value || "" ).split( rspace ); + + for ( i = 0, l = this.length; i < l; i++ ) { + elem = this[ i ]; + + if ( elem.nodeType === 1 && elem.className ) { + if ( value ) { + className = (" " + elem.className + " ").replace( rclass, " " ); + for ( c = 0, cl = classNames.length; c < cl; c++ ) { + className = className.replace(" " + classNames[ c ] + " ", " "); + } + elem.className = jQuery.trim( className ); + + } else { + elem.className = ""; + } + } + } + } + + return this; + }, + + toggleClass: function( value, stateVal ) { + var type = typeof value, + isBool = typeof stateVal === "boolean"; + + if ( jQuery.isFunction( value ) ) { + return this.each(function( i ) { + jQuery( this ).toggleClass( value.call(this, i, this.className, stateVal), stateVal ); + }); + } + + return this.each(function() { + if ( type === "string" ) { + // toggle individual class names + var className, + i = 0, + self = jQuery( this ), + state = stateVal, + classNames = value.split( rspace ); + + while ( (className = classNames[ i++ ]) ) { + // check each className given, space seperated list + state = isBool ? state : !self.hasClass( className ); + self[ state ? "addClass" : "removeClass" ]( className ); + } + + } else if ( type === "undefined" || type === "boolean" ) { + if ( this.className ) { + // store className if set + jQuery._data( this, "__className__", this.className ); + } + + // toggle whole className + this.className = this.className || value === false ? "" : jQuery._data( this, "__className__" ) || ""; + } + }); + }, + + hasClass: function( selector ) { + var className = " " + selector + " ", + i = 0, + l = this.length; + for ( ; i < l; i++ ) { + if ( this[i].nodeType === 1 && (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) > -1 ) { + return true; + } + } + + return false; + }, + + val: function( value ) { + var hooks, ret, isFunction, + elem = this[0]; + + if ( !arguments.length ) { + if ( elem ) { + hooks = jQuery.valHooks[ elem.nodeName.toLowerCase() ] || jQuery.valHooks[ elem.type ]; + + if ( hooks && "get" in hooks && (ret = hooks.get( elem, "value" )) !== undefined ) { + return ret; + } + + ret = elem.value; + + return typeof ret === "string" ? + // handle most common string cases + ret.replace(rreturn, "") : + // handle cases where value is null/undef or number + ret == null ? "" : ret; + } + + return; + } + + isFunction = jQuery.isFunction( value ); + + return this.each(function( i ) { + var self = jQuery(this), val; + + if ( this.nodeType !== 1 ) { + return; + } + + if ( isFunction ) { + val = value.call( this, i, self.val() ); + } else { + val = value; + } + + // Treat null/undefined as ""; convert numbers to string + if ( val == null ) { + val = ""; + } else if ( typeof val === "number" ) { + val += ""; + } else if ( jQuery.isArray( val ) ) { + val = jQuery.map(val, function ( value ) { + return value == null ? "" : value + ""; + }); + } + + hooks = jQuery.valHooks[ this.nodeName.toLowerCase() ] || jQuery.valHooks[ this.type ]; + + // If set returns undefined, fall back to normal setting + if ( !hooks || !("set" in hooks) || hooks.set( this, val, "value" ) === undefined ) { + this.value = val; + } + }); + } +}); + +jQuery.extend({ + valHooks: { + option: { + get: function( elem ) { + // attributes.value is undefined in Blackberry 4.7 but + // uses .value. See #6932 + var val = elem.attributes.value; + return !val || val.specified ? elem.value : elem.text; + } + }, + select: { + get: function( elem ) { + var value, i, max, option, + index = elem.selectedIndex, + values = [], + options = elem.options, + one = elem.type === "select-one"; + + // Nothing was selected + if ( index < 0 ) { + return null; + } + + // Loop through all the selected options + i = one ? index : 0; + max = one ? index + 1 : options.length; + for ( ; i < max; i++ ) { + option = options[ i ]; + + // Don't return options that are disabled or in a disabled optgroup + if ( option.selected && (jQuery.support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null) && + (!option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" )) ) { + + // Get the specific value for the option + value = jQuery( option ).val(); + + // We don't need an array for one selects + if ( one ) { + return value; + } + + // Multi-Selects return an array + values.push( value ); + } + } + + // Fixes Bug #2551 -- select.val() broken in IE after form.reset() + if ( one && !values.length && options.length ) { + return jQuery( options[ index ] ).val(); + } + + return values; + }, + + set: function( elem, value ) { + var values = jQuery.makeArray( value ); + + jQuery(elem).find("option").each(function() { + this.selected = jQuery.inArray( jQuery(this).val(), values ) >= 0; + }); + + if ( !values.length ) { + elem.selectedIndex = -1; + } + return values; + } + } + }, + + attrFn: { + val: true, + css: true, + html: true, + text: true, + data: true, + width: true, + height: true, + offset: true + }, + + attr: function( elem, name, value, pass ) { + var ret, hooks, notxml, + nType = elem.nodeType; + + // don't get/set attributes on text, comment and attribute nodes + if ( !elem || nType === 3 || nType === 8 || nType === 2 ) { + return; + } + + if ( pass && name in jQuery.attrFn ) { + return jQuery( elem )[ name ]( value ); + } + + // Fallback to prop when attributes are not supported + if ( typeof elem.getAttribute === "undefined" ) { + return jQuery.prop( elem, name, value ); + } + + notxml = nType !== 1 || !jQuery.isXMLDoc( elem ); + + // All attributes are lowercase + // Grab necessary hook if one is defined + if ( notxml ) { + name = name.toLowerCase(); + hooks = jQuery.attrHooks[ name ] || ( rboolean.test( name ) ? boolHook : nodeHook ); + } + + if ( value !== undefined ) { + + if ( value === null ) { + jQuery.removeAttr( elem, name ); + return; + + } else if ( hooks && "set" in hooks && notxml && (ret = hooks.set( elem, value, name )) !== undefined ) { + return ret; + + } else { + elem.setAttribute( name, "" + value ); + return value; + } + + } else if ( hooks && "get" in hooks && notxml && (ret = hooks.get( elem, name )) !== null ) { + return ret; + + } else { + + ret = elem.getAttribute( name ); + + // Non-existent attributes return null, we normalize to undefined + return ret === null ? + undefined : + ret; + } + }, + + removeAttr: function( elem, value ) { + var propName, attrNames, name, l, + i = 0; + + if ( value && elem.nodeType === 1 ) { + attrNames = value.toLowerCase().split( rspace ); + l = attrNames.length; + + for ( ; i < l; i++ ) { + name = attrNames[ i ]; + + if ( name ) { + propName = jQuery.propFix[ name ] || name; + + // See #9699 for explanation of this approach (setting first, then removal) + jQuery.attr( elem, name, "" ); + elem.removeAttribute( getSetAttribute ? name : propName ); + + // Set corresponding property to false for boolean attributes + if ( rboolean.test( name ) && propName in elem ) { + elem[ propName ] = false; + } + } + } + } + }, + + attrHooks: { + type: { + set: function( elem, value ) { + // We can't allow the type property to be changed (since it causes problems in IE) + if ( rtype.test( elem.nodeName ) && elem.parentNode ) { + jQuery.error( "type property can't be changed" ); + } else if ( !jQuery.support.radioValue && value === "radio" && jQuery.nodeName(elem, "input") ) { + // Setting the type on a radio button after the value resets the value in IE6-9 + // Reset value to it's default in case type is set after value + // This is for element creation + var val = elem.value; + elem.setAttribute( "type", value ); + if ( val ) { + elem.value = val; + } + return value; + } + } + }, + // Use the value property for back compat + // Use the nodeHook for button elements in IE6/7 (#1954) + value: { + get: function( elem, name ) { + if ( nodeHook && jQuery.nodeName( elem, "button" ) ) { + return nodeHook.get( elem, name ); + } + return name in elem ? + elem.value : + null; + }, + set: function( elem, value, name ) { + if ( nodeHook && jQuery.nodeName( elem, "button" ) ) { + return nodeHook.set( elem, value, name ); + } + // Does not return so that setAttribute is also used + elem.value = value; + } + } + }, + + propFix: { + tabindex: "tabIndex", + readonly: "readOnly", + "for": "htmlFor", + "class": "className", + maxlength: "maxLength", + cellspacing: "cellSpacing", + cellpadding: "cellPadding", + rowspan: "rowSpan", + colspan: "colSpan", + usemap: "useMap", + frameborder: "frameBorder", + contenteditable: "contentEditable" + }, + + prop: function( elem, name, value ) { + var ret, hooks, notxml, + nType = elem.nodeType; + + // don't get/set properties on text, comment and attribute nodes + if ( !elem || nType === 3 || nType === 8 || nType === 2 ) { + return; + } + + notxml = nType !== 1 || !jQuery.isXMLDoc( elem ); + + if ( notxml ) { + // Fix name and attach hooks + name = jQuery.propFix[ name ] || name; + hooks = jQuery.propHooks[ name ]; + } + + if ( value !== undefined ) { + if ( hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) { + return ret; + + } else { + return ( elem[ name ] = value ); + } + + } else { + if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ) { + return ret; + + } else { + return elem[ name ]; + } + } + }, + + propHooks: { + tabIndex: { + get: function( elem ) { + // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set + // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/ + var attributeNode = elem.getAttributeNode("tabindex"); + + return attributeNode && attributeNode.specified ? + parseInt( attributeNode.value, 10 ) : + rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ? + 0 : + undefined; + } + } + } +}); + +// Add the tabIndex propHook to attrHooks for back-compat (different case is intentional) +jQuery.attrHooks.tabindex = jQuery.propHooks.tabIndex; + +// Hook for boolean attributes +boolHook = { + get: function( elem, name ) { + // Align boolean attributes with corresponding properties + // Fall back to attribute presence where some booleans are not supported + var attrNode, + property = jQuery.prop( elem, name ); + return property === true || typeof property !== "boolean" && ( attrNode = elem.getAttributeNode(name) ) && attrNode.nodeValue !== false ? + name.toLowerCase() : + undefined; + }, + set: function( elem, value, name ) { + var propName; + if ( value === false ) { + // Remove boolean attributes when set to false + jQuery.removeAttr( elem, name ); + } else { + // value is true since we know at this point it's type boolean and not false + // Set boolean attributes to the same name and set the DOM property + propName = jQuery.propFix[ name ] || name; + if ( propName in elem ) { + // Only set the IDL specifically if it already exists on the element + elem[ propName ] = true; + } + + elem.setAttribute( name, name.toLowerCase() ); + } + return name; + } +}; + +// IE6/7 do not support getting/setting some attributes with get/setAttribute +if ( !getSetAttribute ) { + + fixSpecified = { + name: true, + id: true + }; + + // Use this for any attribute in IE6/7 + // This fixes almost every IE6/7 issue + nodeHook = jQuery.valHooks.button = { + get: function( elem, name ) { + var ret; + ret = elem.getAttributeNode( name ); + return ret && ( fixSpecified[ name ] ? ret.nodeValue !== "" : ret.specified ) ? + ret.nodeValue : + undefined; + }, + set: function( elem, value, name ) { + // Set the existing or create a new attribute node + var ret = elem.getAttributeNode( name ); + if ( !ret ) { + ret = document.createAttribute( name ); + elem.setAttributeNode( ret ); + } + return ( ret.nodeValue = value + "" ); + } + }; + + // Apply the nodeHook to tabindex + jQuery.attrHooks.tabindex.set = nodeHook.set; + + // Set width and height to auto instead of 0 on empty string( Bug #8150 ) + // This is for removals + jQuery.each([ "width", "height" ], function( i, name ) { + jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], { + set: function( elem, value ) { + if ( value === "" ) { + elem.setAttribute( name, "auto" ); + return value; + } + } + }); + }); + + // Set contenteditable to false on removals(#10429) + // Setting to empty string throws an error as an invalid value + jQuery.attrHooks.contenteditable = { + get: nodeHook.get, + set: function( elem, value, name ) { + if ( value === "" ) { + value = "false"; + } + nodeHook.set( elem, value, name ); + } + }; +} + + +// Some attributes require a special call on IE +if ( !jQuery.support.hrefNormalized ) { + jQuery.each([ "href", "src", "width", "height" ], function( i, name ) { + jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], { + get: function( elem ) { + var ret = elem.getAttribute( name, 2 ); + return ret === null ? undefined : ret; + } + }); + }); +} + +if ( !jQuery.support.style ) { + jQuery.attrHooks.style = { + get: function( elem ) { + // Return undefined in the case of empty string + // Normalize to lowercase since IE uppercases css property names + return elem.style.cssText.toLowerCase() || undefined; + }, + set: function( elem, value ) { + return ( elem.style.cssText = "" + value ); + } + }; +} + +// Safari mis-reports the default selected property of an option +// Accessing the parent's selectedIndex property fixes it +if ( !jQuery.support.optSelected ) { + jQuery.propHooks.selected = jQuery.extend( jQuery.propHooks.selected, { + get: function( elem ) { + var parent = elem.parentNode; + + if ( parent ) { + parent.selectedIndex; + + // Make sure that it also works with optgroups, see #5701 + if ( parent.parentNode ) { + parent.parentNode.selectedIndex; + } + } + return null; + } + }); +} + +// IE6/7 call enctype encoding +if ( !jQuery.support.enctype ) { + jQuery.propFix.enctype = "encoding"; +} + +// Radios and checkboxes getter/setter +if ( !jQuery.support.checkOn ) { + jQuery.each([ "radio", "checkbox" ], function() { + jQuery.valHooks[ this ] = { + get: function( elem ) { + // Handle the case where in Webkit "" is returned instead of "on" if a value isn't specified + return elem.getAttribute("value") === null ? "on" : elem.value; + } + }; + }); +} +jQuery.each([ "radio", "checkbox" ], function() { + jQuery.valHooks[ this ] = jQuery.extend( jQuery.valHooks[ this ], { + set: function( elem, value ) { + if ( jQuery.isArray( value ) ) { + return ( elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0 ); + } + } + }); +}); + + + + +var rformElems = /^(?:textarea|input|select)$/i, + rtypenamespace = /^([^\.]*)?(?:\.(.+))?$/, + rhoverHack = /\bhover(\.\S+)?\b/, + rkeyEvent = /^key/, + rmouseEvent = /^(?:mouse|contextmenu)|click/, + rfocusMorph = /^(?:focusinfocus|focusoutblur)$/, + rquickIs = /^(\w*)(?:#([\w\-]+))?(?:\.([\w\-]+))?$/, + quickParse = function( selector ) { + var quick = rquickIs.exec( selector ); + if ( quick ) { + // 0 1 2 3 + // [ _, tag, id, class ] + quick[1] = ( quick[1] || "" ).toLowerCase(); + quick[3] = quick[3] && new RegExp( "(?:^|\\s)" + quick[3] + "(?:\\s|$)" ); + } + return quick; + }, + quickIs = function( elem, m ) { + var attrs = elem.attributes || {}; + return ( + (!m[1] || elem.nodeName.toLowerCase() === m[1]) && + (!m[2] || (attrs.id || {}).value === m[2]) && + (!m[3] || m[3].test( (attrs[ "class" ] || {}).value )) + ); + }, + hoverHack = function( events ) { + return jQuery.event.special.hover ? events : events.replace( rhoverHack, "mouseenter$1 mouseleave$1" ); + }; + +/* + * Helper functions for managing events -- not part of the public interface. + * Props to Dean Edwards' addEvent library for many of the ideas. + */ +jQuery.event = { + + add: function( elem, types, handler, data, selector ) { + + var elemData, eventHandle, events, + t, tns, type, namespaces, handleObj, + handleObjIn, quick, handlers, special; + + // Don't attach events to noData or text/comment nodes (allow plain objects tho) + if ( elem.nodeType === 3 || elem.nodeType === 8 || !types || !handler || !(elemData = jQuery._data( elem )) ) { + return; + } + + // Caller can pass in an object of custom data in lieu of the handler + if ( handler.handler ) { + handleObjIn = handler; + handler = handleObjIn.handler; + } + + // Make sure that the handler has a unique ID, used to find/remove it later + if ( !handler.guid ) { + handler.guid = jQuery.guid++; + } + + // Init the element's event structure and main handler, if this is the first + events = elemData.events; + if ( !events ) { + elemData.events = events = {}; + } + eventHandle = elemData.handle; + if ( !eventHandle ) { + elemData.handle = eventHandle = function( e ) { + // Discard the second event of a jQuery.event.trigger() and + // when an event is called after a page has unloaded + return typeof jQuery !== "undefined" && (!e || jQuery.event.triggered !== e.type) ? + jQuery.event.dispatch.apply( eventHandle.elem, arguments ) : + undefined; + }; + // Add elem as a property of the handle fn to prevent a memory leak with IE non-native events + eventHandle.elem = elem; + } + + // Handle multiple events separated by a space + // jQuery(...).bind("mouseover mouseout", fn); + types = jQuery.trim( hoverHack(types) ).split( " " ); + for ( t = 0; t < types.length; t++ ) { + + tns = rtypenamespace.exec( types[t] ) || []; + type = tns[1]; + namespaces = ( tns[2] || "" ).split( "." ).sort(); + + // If event changes its type, use the special event handlers for the changed type + special = jQuery.event.special[ type ] || {}; + + // If selector defined, determine special event api type, otherwise given type + type = ( selector ? special.delegateType : special.bindType ) || type; + + // Update special based on newly reset type + special = jQuery.event.special[ type ] || {}; + + // handleObj is passed to all event handlers + handleObj = jQuery.extend({ + type: type, + origType: tns[1], + data: data, + handler: handler, + guid: handler.guid, + selector: selector, + quick: quickParse( selector ), + namespace: namespaces.join(".") + }, handleObjIn ); + + // Init the event handler queue if we're the first + handlers = events[ type ]; + if ( !handlers ) { + handlers = events[ type ] = []; + handlers.delegateCount = 0; + + // Only use addEventListener/attachEvent if the special events handler returns false + if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) { + // Bind the global event handler to the element + if ( elem.addEventListener ) { + elem.addEventListener( type, eventHandle, false ); + + } else if ( elem.attachEvent ) { + elem.attachEvent( "on" + type, eventHandle ); + } + } + } + + if ( special.add ) { + special.add.call( elem, handleObj ); + + if ( !handleObj.handler.guid ) { + handleObj.handler.guid = handler.guid; + } + } + + // Add to the element's handler list, delegates in front + if ( selector ) { + handlers.splice( handlers.delegateCount++, 0, handleObj ); + } else { + handlers.push( handleObj ); + } + + // Keep track of which events have ever been used, for event optimization + jQuery.event.global[ type ] = true; + } + + // Nullify elem to prevent memory leaks in IE + elem = null; + }, + + global: {}, + + // Detach an event or set of events from an element + remove: function( elem, types, handler, selector, mappedTypes ) { + + var elemData = jQuery.hasData( elem ) && jQuery._data( elem ), + t, tns, type, origType, namespaces, origCount, + j, events, special, handle, eventType, handleObj; + + if ( !elemData || !(events = elemData.events) ) { + return; + } + + // Once for each type.namespace in types; type may be omitted + types = jQuery.trim( hoverHack( types || "" ) ).split(" "); + for ( t = 0; t < types.length; t++ ) { + tns = rtypenamespace.exec( types[t] ) || []; + type = origType = tns[1]; + namespaces = tns[2]; + + // Unbind all events (on this namespace, if provided) for the element + if ( !type ) { + for ( type in events ) { + jQuery.event.remove( elem, type + types[ t ], handler, selector, true ); + } + continue; + } + + special = jQuery.event.special[ type ] || {}; + type = ( selector? special.delegateType : special.bindType ) || type; + eventType = events[ type ] || []; + origCount = eventType.length; + namespaces = namespaces ? new RegExp("(^|\\.)" + namespaces.split(".").sort().join("\\.(?:.*\\.)?") + "(\\.|$)") : null; + + // Remove matching events + for ( j = 0; j < eventType.length; j++ ) { + handleObj = eventType[ j ]; + + if ( ( mappedTypes || origType === handleObj.origType ) && + ( !handler || handler.guid === handleObj.guid ) && + ( !namespaces || namespaces.test( handleObj.namespace ) ) && + ( !selector || selector === handleObj.selector || selector === "**" && handleObj.selector ) ) { + eventType.splice( j--, 1 ); + + if ( handleObj.selector ) { + eventType.delegateCount--; + } + if ( special.remove ) { + special.remove.call( elem, handleObj ); + } + } + } + + // Remove generic event handler if we removed something and no more handlers exist + // (avoids potential for endless recursion during removal of special event handlers) + if ( eventType.length === 0 && origCount !== eventType.length ) { + if ( !special.teardown || special.teardown.call( elem, namespaces ) === false ) { + jQuery.removeEvent( elem, type, elemData.handle ); + } + + delete events[ type ]; + } + } + + // Remove the expando if it's no longer used + if ( jQuery.isEmptyObject( events ) ) { + handle = elemData.handle; + if ( handle ) { + handle.elem = null; + } + + // removeData also checks for emptiness and clears the expando if empty + // so use it instead of delete + jQuery.removeData( elem, [ "events", "handle" ], true ); + } + }, + + // Events that are safe to short-circuit if no handlers are attached. + // Native DOM events should not be added, they may have inline handlers. + customEvent: { + "getData": true, + "setData": true, + "changeData": true + }, + + trigger: function( event, data, elem, onlyHandlers ) { + // Don't do events on text and comment nodes + if ( elem && (elem.nodeType === 3 || elem.nodeType === 8) ) { + return; + } + + // Event object or event type + var type = event.type || event, + namespaces = [], + cache, exclusive, i, cur, old, ontype, special, handle, eventPath, bubbleType; + + // focus/blur morphs to focusin/out; ensure we're not firing them right now + if ( rfocusMorph.test( type + jQuery.event.triggered ) ) { + return; + } + + if ( type.indexOf( "!" ) >= 0 ) { + // Exclusive events trigger only for the exact event (no namespaces) + type = type.slice(0, -1); + exclusive = true; + } + + if ( type.indexOf( "." ) >= 0 ) { + // Namespaced trigger; create a regexp to match event type in handle() + namespaces = type.split("."); + type = namespaces.shift(); + namespaces.sort(); + } + + if ( (!elem || jQuery.event.customEvent[ type ]) && !jQuery.event.global[ type ] ) { + // No jQuery handlers for this event type, and it can't have inline handlers + return; + } + + // Caller can pass in an Event, Object, or just an event type string + event = typeof event === "object" ? + // jQuery.Event object + event[ jQuery.expando ] ? event : + // Object literal + new jQuery.Event( type, event ) : + // Just the event type (string) + new jQuery.Event( type ); + + event.type = type; + event.isTrigger = true; + event.exclusive = exclusive; + event.namespace = namespaces.join( "." ); + event.namespace_re = event.namespace? new RegExp("(^|\\.)" + namespaces.join("\\.(?:.*\\.)?") + "(\\.|$)") : null; + ontype = type.indexOf( ":" ) < 0 ? "on" + type : ""; + + // Handle a global trigger + if ( !elem ) { + + // TODO: Stop taunting the data cache; remove global events and always attach to document + cache = jQuery.cache; + for ( i in cache ) { + if ( cache[ i ].events && cache[ i ].events[ type ] ) { + jQuery.event.trigger( event, data, cache[ i ].handle.elem, true ); + } + } + return; + } + + // Clean up the event in case it is being reused + event.result = undefined; + if ( !event.target ) { + event.target = elem; + } + + // Clone any incoming data and prepend the event, creating the handler arg list + data = data != null ? jQuery.makeArray( data ) : []; + data.unshift( event ); + + // Allow special events to draw outside the lines + special = jQuery.event.special[ type ] || {}; + if ( special.trigger && special.trigger.apply( elem, data ) === false ) { + return; + } + + // Determine event propagation path in advance, per W3C events spec (#9951) + // Bubble up to document, then to window; watch for a global ownerDocument var (#9724) + eventPath = [[ elem, special.bindType || type ]]; + if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) { + + bubbleType = special.delegateType || type; + cur = rfocusMorph.test( bubbleType + type ) ? elem : elem.parentNode; + old = null; + for ( ; cur; cur = cur.parentNode ) { + eventPath.push([ cur, bubbleType ]); + old = cur; + } + + // Only add window if we got to document (e.g., not plain obj or detached DOM) + if ( old && old === elem.ownerDocument ) { + eventPath.push([ old.defaultView || old.parentWindow || window, bubbleType ]); + } + } + + // Fire handlers on the event path + for ( i = 0; i < eventPath.length && !event.isPropagationStopped(); i++ ) { + + cur = eventPath[i][0]; + event.type = eventPath[i][1]; + + handle = ( jQuery._data( cur, "events" ) || {} )[ event.type ] && jQuery._data( cur, "handle" ); + if ( handle ) { + handle.apply( cur, data ); + } + // Note that this is a bare JS function and not a jQuery handler + handle = ontype && cur[ ontype ]; + if ( handle && jQuery.acceptData( cur ) && handle.apply( cur, data ) === false ) { + event.preventDefault(); + } + } + event.type = type; + + // If nobody prevented the default action, do it now + if ( !onlyHandlers && !event.isDefaultPrevented() ) { + + if ( (!special._default || special._default.apply( elem.ownerDocument, data ) === false) && + !(type === "click" && jQuery.nodeName( elem, "a" )) && jQuery.acceptData( elem ) ) { + + // Call a native DOM method on the target with the same name name as the event. + // Can't use an .isFunction() check here because IE6/7 fails that test. + // Don't do default actions on window, that's where global variables be (#6170) + // IE<9 dies on focus/blur to hidden element (#1486) + if ( ontype && elem[ type ] && ((type !== "focus" && type !== "blur") || event.target.offsetWidth !== 0) && !jQuery.isWindow( elem ) ) { + + // Don't re-trigger an onFOO event when we call its FOO() method + old = elem[ ontype ]; + + if ( old ) { + elem[ ontype ] = null; + } + + // Prevent re-triggering of the same event, since we already bubbled it above + jQuery.event.triggered = type; + elem[ type ](); + jQuery.event.triggered = undefined; + + if ( old ) { + elem[ ontype ] = old; + } + } + } + } + + return event.result; + }, + + dispatch: function( event ) { + + // Make a writable jQuery.Event from the native event object + event = jQuery.event.fix( event || window.event ); + + var handlers = ( (jQuery._data( this, "events" ) || {} )[ event.type ] || []), + delegateCount = handlers.delegateCount, + args = [].slice.call( arguments, 0 ), + run_all = !event.exclusive && !event.namespace, + handlerQueue = [], + i, j, cur, jqcur, ret, selMatch, matched, matches, handleObj, sel, related; + + // Use the fix-ed jQuery.Event rather than the (read-only) native event + args[0] = event; + event.delegateTarget = this; + + // Determine handlers that should run if there are delegated events + // Avoid disabled elements in IE (#6911) and non-left-click bubbling in Firefox (#3861) + if ( delegateCount && !event.target.disabled && !(event.button && event.type === "click") ) { + + // Pregenerate a single jQuery object for reuse with .is() + jqcur = jQuery(this); + jqcur.context = this.ownerDocument || this; + + for ( cur = event.target; cur != this; cur = cur.parentNode || this ) { + selMatch = {}; + matches = []; + jqcur[0] = cur; + for ( i = 0; i < delegateCount; i++ ) { + handleObj = handlers[ i ]; + sel = handleObj.selector; + + if ( selMatch[ sel ] === undefined ) { + selMatch[ sel ] = ( + handleObj.quick ? quickIs( cur, handleObj.quick ) : jqcur.is( sel ) + ); + } + if ( selMatch[ sel ] ) { + matches.push( handleObj ); + } + } + if ( matches.length ) { + handlerQueue.push({ elem: cur, matches: matches }); + } + } + } + + // Add the remaining (directly-bound) handlers + if ( handlers.length > delegateCount ) { + handlerQueue.push({ elem: this, matches: handlers.slice( delegateCount ) }); + } + + // Run delegates first; they may want to stop propagation beneath us + for ( i = 0; i < handlerQueue.length && !event.isPropagationStopped(); i++ ) { + matched = handlerQueue[ i ]; + event.currentTarget = matched.elem; + + for ( j = 0; j < matched.matches.length && !event.isImmediatePropagationStopped(); j++ ) { + handleObj = matched.matches[ j ]; + + // Triggered event must either 1) be non-exclusive and have no namespace, or + // 2) have namespace(s) a subset or equal to those in the bound event (both can have no namespace). + if ( run_all || (!event.namespace && !handleObj.namespace) || event.namespace_re && event.namespace_re.test( handleObj.namespace ) ) { + + event.data = handleObj.data; + event.handleObj = handleObj; + + ret = ( (jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler ) + .apply( matched.elem, args ); + + if ( ret !== undefined ) { + event.result = ret; + if ( ret === false ) { + event.preventDefault(); + event.stopPropagation(); + } + } + } + } + } + + return event.result; + }, + + // Includes some event props shared by KeyEvent and MouseEvent + // *** attrChange attrName relatedNode srcElement are not normalized, non-W3C, deprecated, will be removed in 1.8 *** + props: "attrChange attrName relatedNode srcElement altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "), + + fixHooks: {}, + + keyHooks: { + props: "char charCode key keyCode".split(" "), + filter: function( event, original ) { + + // Add which for key events + if ( event.which == null ) { + event.which = original.charCode != null ? original.charCode : original.keyCode; + } + + return event; + } + }, + + mouseHooks: { + props: "button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "), + filter: function( event, original ) { + var eventDoc, doc, body, + button = original.button, + fromElement = original.fromElement; + + // Calculate pageX/Y if missing and clientX/Y available + if ( event.pageX == null && original.clientX != null ) { + eventDoc = event.target.ownerDocument || document; + doc = eventDoc.documentElement; + body = eventDoc.body; + + event.pageX = original.clientX + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - ( doc && doc.clientLeft || body && body.clientLeft || 0 ); + event.pageY = original.clientY + ( doc && doc.scrollTop || body && body.scrollTop || 0 ) - ( doc && doc.clientTop || body && body.clientTop || 0 ); + } + + // Add relatedTarget, if necessary + if ( !event.relatedTarget && fromElement ) { + event.relatedTarget = fromElement === event.target ? original.toElement : fromElement; + } + + // Add which for click: 1 === left; 2 === middle; 3 === right + // Note: button is not normalized, so don't use it + if ( !event.which && button !== undefined ) { + event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) ); + } + + return event; + } + }, + + fix: function( event ) { + if ( event[ jQuery.expando ] ) { + return event; + } + + // Create a writable copy of the event object and normalize some properties + var i, prop, + originalEvent = event, + fixHook = jQuery.event.fixHooks[ event.type ] || {}, + copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props; + + event = jQuery.Event( originalEvent ); + + for ( i = copy.length; i; ) { + prop = copy[ --i ]; + event[ prop ] = originalEvent[ prop ]; + } + + // Fix target property, if necessary (#1925, IE 6/7/8 & Safari2) + if ( !event.target ) { + event.target = originalEvent.srcElement || document; + } + + // Target should not be a text node (#504, Safari) + if ( event.target.nodeType === 3 ) { + event.target = event.target.parentNode; + } + + // For mouse/key events; add metaKey if it's not there (#3368, IE6/7/8) + if ( event.metaKey === undefined ) { + event.metaKey = event.ctrlKey; + } + + return fixHook.filter? fixHook.filter( event, originalEvent ) : event; + }, + + special: { + ready: { + // Make sure the ready event is setup + setup: jQuery.bindReady + }, + + load: { + // Prevent triggered image.load events from bubbling to window.load + noBubble: true + }, + + focus: { + delegateType: "focusin" + }, + blur: { + delegateType: "focusout" + }, + + beforeunload: { + setup: function( data, namespaces, eventHandle ) { + // We only want to do this special case on windows + if ( jQuery.isWindow( this ) ) { + this.onbeforeunload = eventHandle; + } + }, + + teardown: function( namespaces, eventHandle ) { + if ( this.onbeforeunload === eventHandle ) { + this.onbeforeunload = null; + } + } + } + }, + + simulate: function( type, elem, event, bubble ) { + // Piggyback on a donor event to simulate a different one. + // Fake originalEvent to avoid donor's stopPropagation, but if the + // simulated event prevents default then we do the same on the donor. + var e = jQuery.extend( + new jQuery.Event(), + event, + { type: type, + isSimulated: true, + originalEvent: {} + } + ); + if ( bubble ) { + jQuery.event.trigger( e, null, elem ); + } else { + jQuery.event.dispatch.call( elem, e ); + } + if ( e.isDefaultPrevented() ) { + event.preventDefault(); + } + } +}; + +// Some plugins are using, but it's undocumented/deprecated and will be removed. +// The 1.7 special event interface should provide all the hooks needed now. +jQuery.event.handle = jQuery.event.dispatch; + +jQuery.removeEvent = document.removeEventListener ? + function( elem, type, handle ) { + if ( elem.removeEventListener ) { + elem.removeEventListener( type, handle, false ); + } + } : + function( elem, type, handle ) { + if ( elem.detachEvent ) { + elem.detachEvent( "on" + type, handle ); + } + }; + +jQuery.Event = function( src, props ) { + // Allow instantiation without the 'new' keyword + if ( !(this instanceof jQuery.Event) ) { + return new jQuery.Event( src, props ); + } + + // Event object + if ( src && src.type ) { + this.originalEvent = src; + this.type = src.type; + + // Events bubbling up the document may have been marked as prevented + // by a handler lower down the tree; reflect the correct value. + this.isDefaultPrevented = ( src.defaultPrevented || src.returnValue === false || + src.getPreventDefault && src.getPreventDefault() ) ? returnTrue : returnFalse; + + // Event type + } else { + this.type = src; + } + + // Put explicitly provided properties onto the event object + if ( props ) { + jQuery.extend( this, props ); + } + + // Create a timestamp if incoming event doesn't have one + this.timeStamp = src && src.timeStamp || jQuery.now(); + + // Mark it as fixed + this[ jQuery.expando ] = true; +}; + +function returnFalse() { + return false; +} +function returnTrue() { + return true; +} + +// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding +// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html +jQuery.Event.prototype = { + preventDefault: function() { + this.isDefaultPrevented = returnTrue; + + var e = this.originalEvent; + if ( !e ) { + return; + } + + // if preventDefault exists run it on the original event + if ( e.preventDefault ) { + e.preventDefault(); + + // otherwise set the returnValue property of the original event to false (IE) + } else { + e.returnValue = false; + } + }, + stopPropagation: function() { + this.isPropagationStopped = returnTrue; + + var e = this.originalEvent; + if ( !e ) { + return; + } + // if stopPropagation exists run it on the original event + if ( e.stopPropagation ) { + e.stopPropagation(); + } + // otherwise set the cancelBubble property of the original event to true (IE) + e.cancelBubble = true; + }, + stopImmediatePropagation: function() { + this.isImmediatePropagationStopped = returnTrue; + this.stopPropagation(); + }, + isDefaultPrevented: returnFalse, + isPropagationStopped: returnFalse, + isImmediatePropagationStopped: returnFalse +}; + +// Create mouseenter/leave events using mouseover/out and event-time checks +jQuery.each({ + mouseenter: "mouseover", + mouseleave: "mouseout" +}, function( orig, fix ) { + jQuery.event.special[ orig ] = { + delegateType: fix, + bindType: fix, + + handle: function( event ) { + var target = this, + related = event.relatedTarget, + handleObj = event.handleObj, + selector = handleObj.selector, + ret; + + // For mousenter/leave call the handler if related is outside the target. + // NB: No relatedTarget if the mouse left/entered the browser window + if ( !related || (related !== target && !jQuery.contains( target, related )) ) { + event.type = handleObj.origType; + ret = handleObj.handler.apply( this, arguments ); + event.type = fix; + } + return ret; + } + }; +}); + +// IE submit delegation +if ( !jQuery.support.submitBubbles ) { + + jQuery.event.special.submit = { + setup: function() { + // Only need this for delegated form submit events + if ( jQuery.nodeName( this, "form" ) ) { + return false; + } + + // Lazy-add a submit handler when a descendant form may potentially be submitted + jQuery.event.add( this, "click._submit keypress._submit", function( e ) { + // Node name check avoids a VML-related crash in IE (#9807) + var elem = e.target, + form = jQuery.nodeName( elem, "input" ) || jQuery.nodeName( elem, "button" ) ? elem.form : undefined; + if ( form && !form._submit_attached ) { + jQuery.event.add( form, "submit._submit", function( event ) { + // If form was submitted by the user, bubble the event up the tree + if ( this.parentNode && !event.isTrigger ) { + jQuery.event.simulate( "submit", this.parentNode, event, true ); + } + }); + form._submit_attached = true; + } + }); + // return undefined since we don't need an event listener + }, + + teardown: function() { + // Only need this for delegated form submit events + if ( jQuery.nodeName( this, "form" ) ) { + return false; + } + + // Remove delegated handlers; cleanData eventually reaps submit handlers attached above + jQuery.event.remove( this, "._submit" ); + } + }; +} + +// IE change delegation and checkbox/radio fix +if ( !jQuery.support.changeBubbles ) { + + jQuery.event.special.change = { + + setup: function() { + + if ( rformElems.test( this.nodeName ) ) { + // IE doesn't fire change on a check/radio until blur; trigger it on click + // after a propertychange. Eat the blur-change in special.change.handle. + // This still fires onchange a second time for check/radio after blur. + if ( this.type === "checkbox" || this.type === "radio" ) { + jQuery.event.add( this, "propertychange._change", function( event ) { + if ( event.originalEvent.propertyName === "checked" ) { + this._just_changed = true; + } + }); + jQuery.event.add( this, "click._change", function( event ) { + if ( this._just_changed && !event.isTrigger ) { + this._just_changed = false; + jQuery.event.simulate( "change", this, event, true ); + } + }); + } + return false; + } + // Delegated event; lazy-add a change handler on descendant inputs + jQuery.event.add( this, "beforeactivate._change", function( e ) { + var elem = e.target; + + if ( rformElems.test( elem.nodeName ) && !elem._change_attached ) { + jQuery.event.add( elem, "change._change", function( event ) { + if ( this.parentNode && !event.isSimulated && !event.isTrigger ) { + jQuery.event.simulate( "change", this.parentNode, event, true ); + } + }); + elem._change_attached = true; + } + }); + }, + + handle: function( event ) { + var elem = event.target; + + // Swallow native change events from checkbox/radio, we already triggered them above + if ( this !== elem || event.isSimulated || event.isTrigger || (elem.type !== "radio" && elem.type !== "checkbox") ) { + return event.handleObj.handler.apply( this, arguments ); + } + }, + + teardown: function() { + jQuery.event.remove( this, "._change" ); + + return rformElems.test( this.nodeName ); + } + }; +} + +// Create "bubbling" focus and blur events +if ( !jQuery.support.focusinBubbles ) { + jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) { + + // Attach a single capturing handler while someone wants focusin/focusout + var attaches = 0, + handler = function( event ) { + jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ), true ); + }; + + jQuery.event.special[ fix ] = { + setup: function() { + if ( attaches++ === 0 ) { + document.addEventListener( orig, handler, true ); + } + }, + teardown: function() { + if ( --attaches === 0 ) { + document.removeEventListener( orig, handler, true ); + } + } + }; + }); +} + +jQuery.fn.extend({ + + on: function( types, selector, data, fn, /*INTERNAL*/ one ) { + var origFn, type; + + // Types can be a map of types/handlers + if ( typeof types === "object" ) { + // ( types-Object, selector, data ) + if ( typeof selector !== "string" ) { + // ( types-Object, data ) + data = selector; + selector = undefined; + } + for ( type in types ) { + this.on( type, selector, data, types[ type ], one ); + } + return this; + } + + if ( data == null && fn == null ) { + // ( types, fn ) + fn = selector; + data = selector = undefined; + } else if ( fn == null ) { + if ( typeof selector === "string" ) { + // ( types, selector, fn ) + fn = data; + data = undefined; + } else { + // ( types, data, fn ) + fn = data; + data = selector; + selector = undefined; + } + } + if ( fn === false ) { + fn = returnFalse; + } else if ( !fn ) { + return this; + } + + if ( one === 1 ) { + origFn = fn; + fn = function( event ) { + // Can use an empty set, since event contains the info + jQuery().off( event ); + return origFn.apply( this, arguments ); + }; + // Use same guid so caller can remove using origFn + fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ ); + } + return this.each( function() { + jQuery.event.add( this, types, fn, data, selector ); + }); + }, + one: function( types, selector, data, fn ) { + return this.on.call( this, types, selector, data, fn, 1 ); + }, + off: function( types, selector, fn ) { + if ( types && types.preventDefault && types.handleObj ) { + // ( event ) dispatched jQuery.Event + var handleObj = types.handleObj; + jQuery( types.delegateTarget ).off( + handleObj.namespace? handleObj.type + "." + handleObj.namespace : handleObj.type, + handleObj.selector, + handleObj.handler + ); + return this; + } + if ( typeof types === "object" ) { + // ( types-object [, selector] ) + for ( var type in types ) { + this.off( type, selector, types[ type ] ); + } + return this; + } + if ( selector === false || typeof selector === "function" ) { + // ( types [, fn] ) + fn = selector; + selector = undefined; + } + if ( fn === false ) { + fn = returnFalse; + } + return this.each(function() { + jQuery.event.remove( this, types, fn, selector ); + }); + }, + + bind: function( types, data, fn ) { + return this.on( types, null, data, fn ); + }, + unbind: function( types, fn ) { + return this.off( types, null, fn ); + }, + + live: function( types, data, fn ) { + jQuery( this.context ).on( types, this.selector, data, fn ); + return this; + }, + die: function( types, fn ) { + jQuery( this.context ).off( types, this.selector || "**", fn ); + return this; + }, + + delegate: function( selector, types, data, fn ) { + return this.on( types, selector, data, fn ); + }, + undelegate: function( selector, types, fn ) { + // ( namespace ) or ( selector, types [, fn] ) + return arguments.length == 1? this.off( selector, "**" ) : this.off( types, selector, fn ); + }, + + trigger: function( type, data ) { + return this.each(function() { + jQuery.event.trigger( type, data, this ); + }); + }, + triggerHandler: function( type, data ) { + if ( this[0] ) { + return jQuery.event.trigger( type, data, this[0], true ); + } + }, + + toggle: function( fn ) { + // Save reference to arguments for access in closure + var args = arguments, + guid = fn.guid || jQuery.guid++, + i = 0, + toggler = function( event ) { + // Figure out which function to execute + var lastToggle = ( jQuery._data( this, "lastToggle" + fn.guid ) || 0 ) % i; + jQuery._data( this, "lastToggle" + fn.guid, lastToggle + 1 ); + + // Make sure that clicks stop + event.preventDefault(); + + // and execute the function + return args[ lastToggle ].apply( this, arguments ) || false; + }; + + // link all the functions, so any of them can unbind this click handler + toggler.guid = guid; + while ( i < args.length ) { + args[ i++ ].guid = guid; + } + + return this.click( toggler ); + }, + + hover: function( fnOver, fnOut ) { + return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver ); + } +}); + +jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " + + "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " + + "change select submit keydown keypress keyup error contextmenu").split(" "), function( i, name ) { + + // Handle event binding + jQuery.fn[ name ] = function( data, fn ) { + if ( fn == null ) { + fn = data; + data = null; + } + + return arguments.length > 0 ? + this.on( name, null, data, fn ) : + this.trigger( name ); + }; + + if ( jQuery.attrFn ) { + jQuery.attrFn[ name ] = true; + } + + if ( rkeyEvent.test( name ) ) { + jQuery.event.fixHooks[ name ] = jQuery.event.keyHooks; + } + + if ( rmouseEvent.test( name ) ) { + jQuery.event.fixHooks[ name ] = jQuery.event.mouseHooks; + } +}); + + + +/*! + * Sizzle CSS Selector Engine + * Copyright 2011, The Dojo Foundation + * Released under the MIT, BSD, and GPL Licenses. + * More information: http://sizzlejs.com/ + */ +(function(){ + +var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g, + expando = "sizcache" + (Math.random() + '').replace('.', ''), + done = 0, + toString = Object.prototype.toString, + hasDuplicate = false, + baseHasDuplicate = true, + rBackslash = /\\/g, + rReturn = /\r\n/g, + rNonWord = /\W/; + +// Here we check if the JavaScript engine is using some sort of +// optimization where it does not always call our comparision +// function. If that is the case, discard the hasDuplicate value. +// Thus far that includes Google Chrome. +[0, 0].sort(function() { + baseHasDuplicate = false; + return 0; +}); + +var Sizzle = function( selector, context, results, seed ) { + results = results || []; + context = context || document; + + var origContext = context; + + if ( context.nodeType !== 1 && context.nodeType !== 9 ) { + return []; + } + + if ( !selector || typeof selector !== "string" ) { + return results; + } + + var m, set, checkSet, extra, ret, cur, pop, i, + prune = true, + contextXML = Sizzle.isXML( context ), + parts = [], + soFar = selector; + + // Reset the position of the chunker regexp (start from head) + do { + chunker.exec( "" ); + m = chunker.exec( soFar ); + + if ( m ) { + soFar = m[3]; + + parts.push( m[1] ); + + if ( m[2] ) { + extra = m[3]; + break; + } + } + } while ( m ); + + if ( parts.length > 1 && origPOS.exec( selector ) ) { + + if ( parts.length === 2 && Expr.relative[ parts[0] ] ) { + set = posProcess( parts[0] + parts[1], context, seed ); + + } else { + set = Expr.relative[ parts[0] ] ? + [ context ] : + Sizzle( parts.shift(), context ); + + while ( parts.length ) { + selector = parts.shift(); + + if ( Expr.relative[ selector ] ) { + selector += parts.shift(); + } + + set = posProcess( selector, set, seed ); + } + } + + } else { + // Take a shortcut and set the context if the root selector is an ID + // (but not if it'll be faster if the inner selector is an ID) + if ( !seed && parts.length > 1 && context.nodeType === 9 && !contextXML && + Expr.match.ID.test(parts[0]) && !Expr.match.ID.test(parts[parts.length - 1]) ) { + + ret = Sizzle.find( parts.shift(), context, contextXML ); + context = ret.expr ? + Sizzle.filter( ret.expr, ret.set )[0] : + ret.set[0]; + } + + if ( context ) { + ret = seed ? + { expr: parts.pop(), set: makeArray(seed) } : + Sizzle.find( parts.pop(), parts.length === 1 && (parts[0] === "~" || parts[0] === "+") && context.parentNode ? context.parentNode : context, contextXML ); + + set = ret.expr ? + Sizzle.filter( ret.expr, ret.set ) : + ret.set; + + if ( parts.length > 0 ) { + checkSet = makeArray( set ); + + } else { + prune = false; + } + + while ( parts.length ) { + cur = parts.pop(); + pop = cur; + + if ( !Expr.relative[ cur ] ) { + cur = ""; + } else { + pop = parts.pop(); + } + + if ( pop == null ) { + pop = context; + } + + Expr.relative[ cur ]( checkSet, pop, contextXML ); + } + + } else { + checkSet = parts = []; + } + } + + if ( !checkSet ) { + checkSet = set; + } + + if ( !checkSet ) { + Sizzle.error( cur || selector ); + } + + if ( toString.call(checkSet) === "[object Array]" ) { + if ( !prune ) { + results.push.apply( results, checkSet ); + + } else if ( context && context.nodeType === 1 ) { + for ( i = 0; checkSet[i] != null; i++ ) { + if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && Sizzle.contains(context, checkSet[i])) ) { + results.push( set[i] ); + } + } + + } else { + for ( i = 0; checkSet[i] != null; i++ ) { + if ( checkSet[i] && checkSet[i].nodeType === 1 ) { + results.push( set[i] ); + } + } + } + + } else { + makeArray( checkSet, results ); + } + + if ( extra ) { + Sizzle( extra, origContext, results, seed ); + Sizzle.uniqueSort( results ); + } + + return results; +}; + +Sizzle.uniqueSort = function( results ) { + if ( sortOrder ) { + hasDuplicate = baseHasDuplicate; + results.sort( sortOrder ); + + if ( hasDuplicate ) { + for ( var i = 1; i < results.length; i++ ) { + if ( results[i] === results[ i - 1 ] ) { + results.splice( i--, 1 ); + } + } + } + } + + return results; +}; + +Sizzle.matches = function( expr, set ) { + return Sizzle( expr, null, null, set ); +}; + +Sizzle.matchesSelector = function( node, expr ) { + return Sizzle( expr, null, null, [node] ).length > 0; +}; + +Sizzle.find = function( expr, context, isXML ) { + var set, i, len, match, type, left; + + if ( !expr ) { + return []; + } + + for ( i = 0, len = Expr.order.length; i < len; i++ ) { + type = Expr.order[i]; + + if ( (match = Expr.leftMatch[ type ].exec( expr )) ) { + left = match[1]; + match.splice( 1, 1 ); + + if ( left.substr( left.length - 1 ) !== "\\" ) { + match[1] = (match[1] || "").replace( rBackslash, "" ); + set = Expr.find[ type ]( match, context, isXML ); + + if ( set != null ) { + expr = expr.replace( Expr.match[ type ], "" ); + break; + } + } + } + } + + if ( !set ) { + set = typeof context.getElementsByTagName !== "undefined" ? + context.getElementsByTagName( "*" ) : + []; + } + + return { set: set, expr: expr }; +}; + +Sizzle.filter = function( expr, set, inplace, not ) { + var match, anyFound, + type, found, item, filter, left, + i, pass, + old = expr, + result = [], + curLoop = set, + isXMLFilter = set && set[0] && Sizzle.isXML( set[0] ); + + while ( expr && set.length ) { + for ( type in Expr.filter ) { + if ( (match = Expr.leftMatch[ type ].exec( expr )) != null && match[2] ) { + filter = Expr.filter[ type ]; + left = match[1]; + + anyFound = false; + + match.splice(1,1); + + if ( left.substr( left.length - 1 ) === "\\" ) { + continue; + } + + if ( curLoop === result ) { + result = []; + } + + if ( Expr.preFilter[ type ] ) { + match = Expr.preFilter[ type ]( match, curLoop, inplace, result, not, isXMLFilter ); + + if ( !match ) { + anyFound = found = true; + + } else if ( match === true ) { + continue; + } + } + + if ( match ) { + for ( i = 0; (item = curLoop[i]) != null; i++ ) { + if ( item ) { + found = filter( item, match, i, curLoop ); + pass = not ^ found; + + if ( inplace && found != null ) { + if ( pass ) { + anyFound = true; + + } else { + curLoop[i] = false; + } + + } else if ( pass ) { + result.push( item ); + anyFound = true; + } + } + } + } + + if ( found !== undefined ) { + if ( !inplace ) { + curLoop = result; + } + + expr = expr.replace( Expr.match[ type ], "" ); + + if ( !anyFound ) { + return []; + } + + break; + } + } + } + + // Improper expression + if ( expr === old ) { + if ( anyFound == null ) { + Sizzle.error( expr ); + + } else { + break; + } + } + + old = expr; + } + + return curLoop; +}; + +Sizzle.error = function( msg ) { + throw new Error( "Syntax error, unrecognized expression: " + msg ); +}; + +/** + * Utility function for retreiving the text value of an array of DOM nodes + * @param {Array|Element} elem + */ +var getText = Sizzle.getText = function( elem ) { + var i, node, + nodeType = elem.nodeType, + ret = ""; + + if ( nodeType ) { + if ( nodeType === 1 || nodeType === 9 ) { + // Use textContent || innerText for elements + if ( typeof elem.textContent === 'string' ) { + return elem.textContent; + } else if ( typeof elem.innerText === 'string' ) { + // Replace IE's carriage returns + return elem.innerText.replace( rReturn, '' ); + } else { + // Traverse it's children + for ( elem = elem.firstChild; elem; elem = elem.nextSibling) { + ret += getText( elem ); + } + } + } else if ( nodeType === 3 || nodeType === 4 ) { + return elem.nodeValue; + } + } else { + + // If no nodeType, this is expected to be an array + for ( i = 0; (node = elem[i]); i++ ) { + // Do not traverse comment nodes + if ( node.nodeType !== 8 ) { + ret += getText( node ); + } + } + } + return ret; +}; + +var Expr = Sizzle.selectors = { + order: [ "ID", "NAME", "TAG" ], + + match: { + ID: /#((?:[\w\u00c0-\uFFFF\-]|\\.)+)/, + CLASS: /\.((?:[\w\u00c0-\uFFFF\-]|\\.)+)/, + NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF\-]|\\.)+)['"]*\]/, + ATTR: /\[\s*((?:[\w\u00c0-\uFFFF\-]|\\.)+)\s*(?:(\S?=)\s*(?:(['"])(.*?)\3|(#?(?:[\w\u00c0-\uFFFF\-]|\\.)*)|)|)\s*\]/, + TAG: /^((?:[\w\u00c0-\uFFFF\*\-]|\\.)+)/, + CHILD: /:(only|nth|last|first)-child(?:\(\s*(even|odd|(?:[+\-]?\d+|(?:[+\-]?\d*)?n\s*(?:[+\-]\s*\d+)?))\s*\))?/, + POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^\-]|$)/, + PSEUDO: /:((?:[\w\u00c0-\uFFFF\-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/ + }, + + leftMatch: {}, + + attrMap: { + "class": "className", + "for": "htmlFor" + }, + + attrHandle: { + href: function( elem ) { + return elem.getAttribute( "href" ); + }, + type: function( elem ) { + return elem.getAttribute( "type" ); + } + }, + + relative: { + "+": function(checkSet, part){ + var isPartStr = typeof part === "string", + isTag = isPartStr && !rNonWord.test( part ), + isPartStrNotTag = isPartStr && !isTag; + + if ( isTag ) { + part = part.toLowerCase(); + } + + for ( var i = 0, l = checkSet.length, elem; i < l; i++ ) { + if ( (elem = checkSet[i]) ) { + while ( (elem = elem.previousSibling) && elem.nodeType !== 1 ) {} + + checkSet[i] = isPartStrNotTag || elem && elem.nodeName.toLowerCase() === part ? + elem || false : + elem === part; + } + } + + if ( isPartStrNotTag ) { + Sizzle.filter( part, checkSet, true ); + } + }, + + ">": function( checkSet, part ) { + var elem, + isPartStr = typeof part === "string", + i = 0, + l = checkSet.length; + + if ( isPartStr && !rNonWord.test( part ) ) { + part = part.toLowerCase(); + + for ( ; i < l; i++ ) { + elem = checkSet[i]; + + if ( elem ) { + var parent = elem.parentNode; + checkSet[i] = parent.nodeName.toLowerCase() === part ? parent : false; + } + } + + } else { + for ( ; i < l; i++ ) { + elem = checkSet[i]; + + if ( elem ) { + checkSet[i] = isPartStr ? + elem.parentNode : + elem.parentNode === part; + } + } + + if ( isPartStr ) { + Sizzle.filter( part, checkSet, true ); + } + } + }, + + "": function(checkSet, part, isXML){ + var nodeCheck, + doneName = done++, + checkFn = dirCheck; + + if ( typeof part === "string" && !rNonWord.test( part ) ) { + part = part.toLowerCase(); + nodeCheck = part; + checkFn = dirNodeCheck; + } + + checkFn( "parentNode", part, doneName, checkSet, nodeCheck, isXML ); + }, + + "~": function( checkSet, part, isXML ) { + var nodeCheck, + doneName = done++, + checkFn = dirCheck; + + if ( typeof part === "string" && !rNonWord.test( part ) ) { + part = part.toLowerCase(); + nodeCheck = part; + checkFn = dirNodeCheck; + } + + checkFn( "previousSibling", part, doneName, checkSet, nodeCheck, isXML ); + } + }, + + find: { + ID: function( match, context, isXML ) { + if ( typeof context.getElementById !== "undefined" && !isXML ) { + var m = context.getElementById(match[1]); + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document #6963 + return m && m.parentNode ? [m] : []; + } + }, + + NAME: function( match, context ) { + if ( typeof context.getElementsByName !== "undefined" ) { + var ret = [], + results = context.getElementsByName( match[1] ); + + for ( var i = 0, l = results.length; i < l; i++ ) { + if ( results[i].getAttribute("name") === match[1] ) { + ret.push( results[i] ); + } + } + + return ret.length === 0 ? null : ret; + } + }, + + TAG: function( match, context ) { + if ( typeof context.getElementsByTagName !== "undefined" ) { + return context.getElementsByTagName( match[1] ); + } + } + }, + preFilter: { + CLASS: function( match, curLoop, inplace, result, not, isXML ) { + match = " " + match[1].replace( rBackslash, "" ) + " "; + + if ( isXML ) { + return match; + } + + for ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) { + if ( elem ) { + if ( not ^ (elem.className && (" " + elem.className + " ").replace(/[\t\n\r]/g, " ").indexOf(match) >= 0) ) { + if ( !inplace ) { + result.push( elem ); + } + + } else if ( inplace ) { + curLoop[i] = false; + } + } + } + + return false; + }, + + ID: function( match ) { + return match[1].replace( rBackslash, "" ); + }, + + TAG: function( match, curLoop ) { + return match[1].replace( rBackslash, "" ).toLowerCase(); + }, + + CHILD: function( match ) { + if ( match[1] === "nth" ) { + if ( !match[2] ) { + Sizzle.error( match[0] ); + } + + match[2] = match[2].replace(/^\+|\s*/g, ''); + + // parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6' + var test = /(-?)(\d*)(?:n([+\-]?\d*))?/.exec( + match[2] === "even" && "2n" || match[2] === "odd" && "2n+1" || + !/\D/.test( match[2] ) && "0n+" + match[2] || match[2]); + + // calculate the numbers (first)n+(last) including if they are negative + match[2] = (test[1] + (test[2] || 1)) - 0; + match[3] = test[3] - 0; + } + else if ( match[2] ) { + Sizzle.error( match[0] ); + } + + // TODO: Move to normal caching system + match[0] = done++; + + return match; + }, + + ATTR: function( match, curLoop, inplace, result, not, isXML ) { + var name = match[1] = match[1].replace( rBackslash, "" ); + + if ( !isXML && Expr.attrMap[name] ) { + match[1] = Expr.attrMap[name]; + } + + // Handle if an un-quoted value was used + match[4] = ( match[4] || match[5] || "" ).replace( rBackslash, "" ); + + if ( match[2] === "~=" ) { + match[4] = " " + match[4] + " "; + } + + return match; + }, + + PSEUDO: function( match, curLoop, inplace, result, not ) { + if ( match[1] === "not" ) { + // If we're dealing with a complex expression, or a simple one + if ( ( chunker.exec(match[3]) || "" ).length > 1 || /^\w/.test(match[3]) ) { + match[3] = Sizzle(match[3], null, null, curLoop); + + } else { + var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not); + + if ( !inplace ) { + result.push.apply( result, ret ); + } + + return false; + } + + } else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) { + return true; + } + + return match; + }, + + POS: function( match ) { + match.unshift( true ); + + return match; + } + }, + + filters: { + enabled: function( elem ) { + return elem.disabled === false && elem.type !== "hidden"; + }, + + disabled: function( elem ) { + return elem.disabled === true; + }, + + checked: function( elem ) { + return elem.checked === true; + }, + + selected: function( elem ) { + // Accessing this property makes selected-by-default + // options in Safari work properly + if ( elem.parentNode ) { + elem.parentNode.selectedIndex; + } + + return elem.selected === true; + }, + + parent: function( elem ) { + return !!elem.firstChild; + }, + + empty: function( elem ) { + return !elem.firstChild; + }, + + has: function( elem, i, match ) { + return !!Sizzle( match[3], elem ).length; + }, + + header: function( elem ) { + return (/h\d/i).test( elem.nodeName ); + }, + + text: function( elem ) { + var attr = elem.getAttribute( "type" ), type = elem.type; + // IE6 and 7 will map elem.type to 'text' for new HTML5 types (search, etc) + // use getAttribute instead to test this case + return elem.nodeName.toLowerCase() === "input" && "text" === type && ( attr === type || attr === null ); + }, + + radio: function( elem ) { + return elem.nodeName.toLowerCase() === "input" && "radio" === elem.type; + }, + + checkbox: function( elem ) { + return elem.nodeName.toLowerCase() === "input" && "checkbox" === elem.type; + }, + + file: function( elem ) { + return elem.nodeName.toLowerCase() === "input" && "file" === elem.type; + }, + + password: function( elem ) { + return elem.nodeName.toLowerCase() === "input" && "password" === elem.type; + }, + + submit: function( elem ) { + var name = elem.nodeName.toLowerCase(); + return (name === "input" || name === "button") && "submit" === elem.type; + }, + + image: function( elem ) { + return elem.nodeName.toLowerCase() === "input" && "image" === elem.type; + }, + + reset: function( elem ) { + var name = elem.nodeName.toLowerCase(); + return (name === "input" || name === "button") && "reset" === elem.type; + }, + + button: function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && "button" === elem.type || name === "button"; + }, + + input: function( elem ) { + return (/input|select|textarea|button/i).test( elem.nodeName ); + }, + + focus: function( elem ) { + return elem === elem.ownerDocument.activeElement; + } + }, + setFilters: { + first: function( elem, i ) { + return i === 0; + }, + + last: function( elem, i, match, array ) { + return i === array.length - 1; + }, + + even: function( elem, i ) { + return i % 2 === 0; + }, + + odd: function( elem, i ) { + return i % 2 === 1; + }, + + lt: function( elem, i, match ) { + return i < match[3] - 0; + }, + + gt: function( elem, i, match ) { + return i > match[3] - 0; + }, + + nth: function( elem, i, match ) { + return match[3] - 0 === i; + }, + + eq: function( elem, i, match ) { + return match[3] - 0 === i; + } + }, + filter: { + PSEUDO: function( elem, match, i, array ) { + var name = match[1], + filter = Expr.filters[ name ]; + + if ( filter ) { + return filter( elem, i, match, array ); + + } else if ( name === "contains" ) { + return (elem.textContent || elem.innerText || getText([ elem ]) || "").indexOf(match[3]) >= 0; + + } else if ( name === "not" ) { + var not = match[3]; + + for ( var j = 0, l = not.length; j < l; j++ ) { + if ( not[j] === elem ) { + return false; + } + } + + return true; + + } else { + Sizzle.error( name ); + } + }, + + CHILD: function( elem, match ) { + var first, last, + doneName, parent, cache, + count, diff, + type = match[1], + node = elem; + + switch ( type ) { + case "only": + case "first": + while ( (node = node.previousSibling) ) { + if ( node.nodeType === 1 ) { + return false; + } + } + + if ( type === "first" ) { + return true; + } + + node = elem; + + case "last": + while ( (node = node.nextSibling) ) { + if ( node.nodeType === 1 ) { + return false; + } + } + + return true; + + case "nth": + first = match[2]; + last = match[3]; + + if ( first === 1 && last === 0 ) { + return true; + } + + doneName = match[0]; + parent = elem.parentNode; + + if ( parent && (parent[ expando ] !== doneName || !elem.nodeIndex) ) { + count = 0; + + for ( node = parent.firstChild; node; node = node.nextSibling ) { + if ( node.nodeType === 1 ) { + node.nodeIndex = ++count; + } + } + + parent[ expando ] = doneName; + } + + diff = elem.nodeIndex - last; + + if ( first === 0 ) { + return diff === 0; + + } else { + return ( diff % first === 0 && diff / first >= 0 ); + } + } + }, + + ID: function( elem, match ) { + return elem.nodeType === 1 && elem.getAttribute("id") === match; + }, + + TAG: function( elem, match ) { + return (match === "*" && elem.nodeType === 1) || !!elem.nodeName && elem.nodeName.toLowerCase() === match; + }, + + CLASS: function( elem, match ) { + return (" " + (elem.className || elem.getAttribute("class")) + " ") + .indexOf( match ) > -1; + }, + + ATTR: function( elem, match ) { + var name = match[1], + result = Sizzle.attr ? + Sizzle.attr( elem, name ) : + Expr.attrHandle[ name ] ? + Expr.attrHandle[ name ]( elem ) : + elem[ name ] != null ? + elem[ name ] : + elem.getAttribute( name ), + value = result + "", + type = match[2], + check = match[4]; + + return result == null ? + type === "!=" : + !type && Sizzle.attr ? + result != null : + type === "=" ? + value === check : + type === "*=" ? + value.indexOf(check) >= 0 : + type === "~=" ? + (" " + value + " ").indexOf(check) >= 0 : + !check ? + value && result !== false : + type === "!=" ? + value !== check : + type === "^=" ? + value.indexOf(check) === 0 : + type === "$=" ? + value.substr(value.length - check.length) === check : + type === "|=" ? + value === check || value.substr(0, check.length + 1) === check + "-" : + false; + }, + + POS: function( elem, match, i, array ) { + var name = match[2], + filter = Expr.setFilters[ name ]; + + if ( filter ) { + return filter( elem, i, match, array ); + } + } + } +}; + +var origPOS = Expr.match.POS, + fescape = function(all, num){ + return "\\" + (num - 0 + 1); + }; + +for ( var type in Expr.match ) { + Expr.match[ type ] = new RegExp( Expr.match[ type ].source + (/(?![^\[]*\])(?![^\(]*\))/.source) ); + Expr.leftMatch[ type ] = new RegExp( /(^(?:.|\r|\n)*?)/.source + Expr.match[ type ].source.replace(/\\(\d+)/g, fescape) ); +} + +var makeArray = function( array, results ) { + array = Array.prototype.slice.call( array, 0 ); + + if ( results ) { + results.push.apply( results, array ); + return results; + } + + return array; +}; + +// Perform a simple check to determine if the browser is capable of +// converting a NodeList to an array using builtin methods. +// Also verifies that the returned array holds DOM nodes +// (which is not the case in the Blackberry browser) +try { + Array.prototype.slice.call( document.documentElement.childNodes, 0 )[0].nodeType; + +// Provide a fallback method if it does not work +} catch( e ) { + makeArray = function( array, results ) { + var i = 0, + ret = results || []; + + if ( toString.call(array) === "[object Array]" ) { + Array.prototype.push.apply( ret, array ); + + } else { + if ( typeof array.length === "number" ) { + for ( var l = array.length; i < l; i++ ) { + ret.push( array[i] ); + } + + } else { + for ( ; array[i]; i++ ) { + ret.push( array[i] ); + } + } + } + + return ret; + }; +} + +var sortOrder, siblingCheck; + +if ( document.documentElement.compareDocumentPosition ) { + sortOrder = function( a, b ) { + if ( a === b ) { + hasDuplicate = true; + return 0; + } + + if ( !a.compareDocumentPosition || !b.compareDocumentPosition ) { + return a.compareDocumentPosition ? -1 : 1; + } + + return a.compareDocumentPosition(b) & 4 ? -1 : 1; + }; + +} else { + sortOrder = function( a, b ) { + // The nodes are identical, we can exit early + if ( a === b ) { + hasDuplicate = true; + return 0; + + // Fallback to using sourceIndex (in IE) if it's available on both nodes + } else if ( a.sourceIndex && b.sourceIndex ) { + return a.sourceIndex - b.sourceIndex; + } + + var al, bl, + ap = [], + bp = [], + aup = a.parentNode, + bup = b.parentNode, + cur = aup; + + // If the nodes are siblings (or identical) we can do a quick check + if ( aup === bup ) { + return siblingCheck( a, b ); + + // If no parents were found then the nodes are disconnected + } else if ( !aup ) { + return -1; + + } else if ( !bup ) { + return 1; + } + + // Otherwise they're somewhere else in the tree so we need + // to build up a full list of the parentNodes for comparison + while ( cur ) { + ap.unshift( cur ); + cur = cur.parentNode; + } + + cur = bup; + + while ( cur ) { + bp.unshift( cur ); + cur = cur.parentNode; + } + + al = ap.length; + bl = bp.length; + + // Start walking down the tree looking for a discrepancy + for ( var i = 0; i < al && i < bl; i++ ) { + if ( ap[i] !== bp[i] ) { + return siblingCheck( ap[i], bp[i] ); + } + } + + // We ended someplace up the tree so do a sibling check + return i === al ? + siblingCheck( a, bp[i], -1 ) : + siblingCheck( ap[i], b, 1 ); + }; + + siblingCheck = function( a, b, ret ) { + if ( a === b ) { + return ret; + } + + var cur = a.nextSibling; + + while ( cur ) { + if ( cur === b ) { + return -1; + } + + cur = cur.nextSibling; + } + + return 1; + }; +} + +// Check to see if the browser returns elements by name when +// querying by getElementById (and provide a workaround) +(function(){ + // We're going to inject a fake input element with a specified name + var form = document.createElement("div"), + id = "script" + (new Date()).getTime(), + root = document.documentElement; + + form.innerHTML = ""; + + // Inject it into the root element, check its status, and remove it quickly + root.insertBefore( form, root.firstChild ); + + // The workaround has to do additional checks after a getElementById + // Which slows things down for other browsers (hence the branching) + if ( document.getElementById( id ) ) { + Expr.find.ID = function( match, context, isXML ) { + if ( typeof context.getElementById !== "undefined" && !isXML ) { + var m = context.getElementById(match[1]); + + return m ? + m.id === match[1] || typeof m.getAttributeNode !== "undefined" && m.getAttributeNode("id").nodeValue === match[1] ? + [m] : + undefined : + []; + } + }; + + Expr.filter.ID = function( elem, match ) { + var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id"); + + return elem.nodeType === 1 && node && node.nodeValue === match; + }; + } + + root.removeChild( form ); + + // release memory in IE + root = form = null; +})(); + +(function(){ + // Check to see if the browser returns only elements + // when doing getElementsByTagName("*") + + // Create a fake element + var div = document.createElement("div"); + div.appendChild( document.createComment("") ); + + // Make sure no comments are found + if ( div.getElementsByTagName("*").length > 0 ) { + Expr.find.TAG = function( match, context ) { + var results = context.getElementsByTagName( match[1] ); + + // Filter out possible comments + if ( match[1] === "*" ) { + var tmp = []; + + for ( var i = 0; results[i]; i++ ) { + if ( results[i].nodeType === 1 ) { + tmp.push( results[i] ); + } + } + + results = tmp; + } + + return results; + }; + } + + // Check to see if an attribute returns normalized href attributes + div.innerHTML = ""; + + if ( div.firstChild && typeof div.firstChild.getAttribute !== "undefined" && + div.firstChild.getAttribute("href") !== "#" ) { + + Expr.attrHandle.href = function( elem ) { + return elem.getAttribute( "href", 2 ); + }; + } + + // release memory in IE + div = null; +})(); + +if ( document.querySelectorAll ) { + (function(){ + var oldSizzle = Sizzle, + div = document.createElement("div"), + id = "__sizzle__"; + + div.innerHTML = "

"; + + // Safari can't handle uppercase or unicode characters when + // in quirks mode. + if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) { + return; + } + + Sizzle = function( query, context, extra, seed ) { + context = context || document; + + // Only use querySelectorAll on non-XML documents + // (ID selectors don't work in non-HTML documents) + if ( !seed && !Sizzle.isXML(context) ) { + // See if we find a selector to speed up + var match = /^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec( query ); + + if ( match && (context.nodeType === 1 || context.nodeType === 9) ) { + // Speed-up: Sizzle("TAG") + if ( match[1] ) { + return makeArray( context.getElementsByTagName( query ), extra ); + + // Speed-up: Sizzle(".CLASS") + } else if ( match[2] && Expr.find.CLASS && context.getElementsByClassName ) { + return makeArray( context.getElementsByClassName( match[2] ), extra ); + } + } + + if ( context.nodeType === 9 ) { + // Speed-up: Sizzle("body") + // The body element only exists once, optimize finding it + if ( query === "body" && context.body ) { + return makeArray( [ context.body ], extra ); + + // Speed-up: Sizzle("#ID") + } else if ( match && match[3] ) { + var elem = context.getElementById( match[3] ); + + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document #6963 + if ( elem && elem.parentNode ) { + // Handle the case where IE and Opera return items + // by name instead of ID + if ( elem.id === match[3] ) { + return makeArray( [ elem ], extra ); + } + + } else { + return makeArray( [], extra ); + } + } + + try { + return makeArray( context.querySelectorAll(query), extra ); + } catch(qsaError) {} + + // qSA works strangely on Element-rooted queries + // We can work around this by specifying an extra ID on the root + // and working up from there (Thanks to Andrew Dupont for the technique) + // IE 8 doesn't work on object elements + } else if ( context.nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) { + var oldContext = context, + old = context.getAttribute( "id" ), + nid = old || id, + hasParent = context.parentNode, + relativeHierarchySelector = /^\s*[+~]/.test( query ); + + if ( !old ) { + context.setAttribute( "id", nid ); + } else { + nid = nid.replace( /'/g, "\\$&" ); + } + if ( relativeHierarchySelector && hasParent ) { + context = context.parentNode; + } + + try { + if ( !relativeHierarchySelector || hasParent ) { + return makeArray( context.querySelectorAll( "[id='" + nid + "'] " + query ), extra ); + } + + } catch(pseudoError) { + } finally { + if ( !old ) { + oldContext.removeAttribute( "id" ); + } + } + } + } + + return oldSizzle(query, context, extra, seed); + }; + + for ( var prop in oldSizzle ) { + Sizzle[ prop ] = oldSizzle[ prop ]; + } + + // release memory in IE + div = null; + })(); +} + +(function(){ + var html = document.documentElement, + matches = html.matchesSelector || html.mozMatchesSelector || html.webkitMatchesSelector || html.msMatchesSelector; + + if ( matches ) { + // Check to see if it's possible to do matchesSelector + // on a disconnected node (IE 9 fails this) + var disconnectedMatch = !matches.call( document.createElement( "div" ), "div" ), + pseudoWorks = false; + + try { + // This should fail with an exception + // Gecko does not error, returns false instead + matches.call( document.documentElement, "[test!='']:sizzle" ); + + } catch( pseudoError ) { + pseudoWorks = true; + } + + Sizzle.matchesSelector = function( node, expr ) { + // Make sure that attribute selectors are quoted + expr = expr.replace(/\=\s*([^'"\]]*)\s*\]/g, "='$1']"); + + if ( !Sizzle.isXML( node ) ) { + try { + if ( pseudoWorks || !Expr.match.PSEUDO.test( expr ) && !/!=/.test( expr ) ) { + var ret = matches.call( node, expr ); + + // IE 9's matchesSelector returns false on disconnected nodes + if ( ret || !disconnectedMatch || + // As well, disconnected nodes are said to be in a document + // fragment in IE 9, so check for that + node.document && node.document.nodeType !== 11 ) { + return ret; + } + } + } catch(e) {} + } + + return Sizzle(expr, null, null, [node]).length > 0; + }; + } +})(); + +(function(){ + var div = document.createElement("div"); + + div.innerHTML = "
"; + + // Opera can't find a second classname (in 9.6) + // Also, make sure that getElementsByClassName actually exists + if ( !div.getElementsByClassName || div.getElementsByClassName("e").length === 0 ) { + return; + } + + // Safari caches class attributes, doesn't catch changes (in 3.2) + div.lastChild.className = "e"; + + if ( div.getElementsByClassName("e").length === 1 ) { + return; + } + + Expr.order.splice(1, 0, "CLASS"); + Expr.find.CLASS = function( match, context, isXML ) { + if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) { + return context.getElementsByClassName(match[1]); + } + }; + + // release memory in IE + div = null; +})(); + +function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) { + for ( var i = 0, l = checkSet.length; i < l; i++ ) { + var elem = checkSet[i]; + + if ( elem ) { + var match = false; + + elem = elem[dir]; + + while ( elem ) { + if ( elem[ expando ] === doneName ) { + match = checkSet[elem.sizset]; + break; + } + + if ( elem.nodeType === 1 && !isXML ){ + elem[ expando ] = doneName; + elem.sizset = i; + } + + if ( elem.nodeName.toLowerCase() === cur ) { + match = elem; + break; + } + + elem = elem[dir]; + } + + checkSet[i] = match; + } + } +} + +function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) { + for ( var i = 0, l = checkSet.length; i < l; i++ ) { + var elem = checkSet[i]; + + if ( elem ) { + var match = false; + + elem = elem[dir]; + + while ( elem ) { + if ( elem[ expando ] === doneName ) { + match = checkSet[elem.sizset]; + break; + } + + if ( elem.nodeType === 1 ) { + if ( !isXML ) { + elem[ expando ] = doneName; + elem.sizset = i; + } + + if ( typeof cur !== "string" ) { + if ( elem === cur ) { + match = true; + break; + } + + } else if ( Sizzle.filter( cur, [elem] ).length > 0 ) { + match = elem; + break; + } + } + + elem = elem[dir]; + } + + checkSet[i] = match; + } + } +} + +if ( document.documentElement.contains ) { + Sizzle.contains = function( a, b ) { + return a !== b && (a.contains ? a.contains(b) : true); + }; + +} else if ( document.documentElement.compareDocumentPosition ) { + Sizzle.contains = function( a, b ) { + return !!(a.compareDocumentPosition(b) & 16); + }; + +} else { + Sizzle.contains = function() { + return false; + }; +} + +Sizzle.isXML = function( elem ) { + // documentElement is verified for cases where it doesn't yet exist + // (such as loading iframes in IE - #4833) + var documentElement = (elem ? elem.ownerDocument || elem : 0).documentElement; + + return documentElement ? documentElement.nodeName !== "HTML" : false; +}; + +var posProcess = function( selector, context, seed ) { + var match, + tmpSet = [], + later = "", + root = context.nodeType ? [context] : context; + + // Position selectors must be done after the filter + // And so must :not(positional) so we move all PSEUDOs to the end + while ( (match = Expr.match.PSEUDO.exec( selector )) ) { + later += match[0]; + selector = selector.replace( Expr.match.PSEUDO, "" ); + } + + selector = Expr.relative[selector] ? selector + "*" : selector; + + for ( var i = 0, l = root.length; i < l; i++ ) { + Sizzle( selector, root[i], tmpSet, seed ); + } + + return Sizzle.filter( later, tmpSet ); +}; + +// EXPOSE +// Override sizzle attribute retrieval +Sizzle.attr = jQuery.attr; +Sizzle.selectors.attrMap = {}; +jQuery.find = Sizzle; +jQuery.expr = Sizzle.selectors; +jQuery.expr[":"] = jQuery.expr.filters; +jQuery.unique = Sizzle.uniqueSort; +jQuery.text = Sizzle.getText; +jQuery.isXMLDoc = Sizzle.isXML; +jQuery.contains = Sizzle.contains; + + +})(); + + +var runtil = /Until$/, + rparentsprev = /^(?:parents|prevUntil|prevAll)/, + // Note: This RegExp should be improved, or likely pulled from Sizzle + rmultiselector = /,/, + isSimple = /^.[^:#\[\.,]*$/, + slice = Array.prototype.slice, + POS = jQuery.expr.match.POS, + // methods guaranteed to produce a unique set when starting from a unique set + guaranteedUnique = { + children: true, + contents: true, + next: true, + prev: true + }; + +jQuery.fn.extend({ + find: function( selector ) { + var self = this, + i, l; + + if ( typeof selector !== "string" ) { + return jQuery( selector ).filter(function() { + for ( i = 0, l = self.length; i < l; i++ ) { + if ( jQuery.contains( self[ i ], this ) ) { + return true; + } + } + }); + } + + var ret = this.pushStack( "", "find", selector ), + length, n, r; + + for ( i = 0, l = this.length; i < l; i++ ) { + length = ret.length; + jQuery.find( selector, this[i], ret ); + + if ( i > 0 ) { + // Make sure that the results are unique + for ( n = length; n < ret.length; n++ ) { + for ( r = 0; r < length; r++ ) { + if ( ret[r] === ret[n] ) { + ret.splice(n--, 1); + break; + } + } + } + } + } + + return ret; + }, + + has: function( target ) { + var targets = jQuery( target ); + return this.filter(function() { + for ( var i = 0, l = targets.length; i < l; i++ ) { + if ( jQuery.contains( this, targets[i] ) ) { + return true; + } + } + }); + }, + + not: function( selector ) { + return this.pushStack( winnow(this, selector, false), "not", selector); + }, + + filter: function( selector ) { + return this.pushStack( winnow(this, selector, true), "filter", selector ); + }, + + is: function( selector ) { + return !!selector && ( + typeof selector === "string" ? + // If this is a positional selector, check membership in the returned set + // so $("p:first").is("p:last") won't return true for a doc with two "p". + POS.test( selector ) ? + jQuery( selector, this.context ).index( this[0] ) >= 0 : + jQuery.filter( selector, this ).length > 0 : + this.filter( selector ).length > 0 ); + }, + + closest: function( selectors, context ) { + var ret = [], i, l, cur = this[0]; + + // Array (deprecated as of jQuery 1.7) + if ( jQuery.isArray( selectors ) ) { + var level = 1; + + while ( cur && cur.ownerDocument && cur !== context ) { + for ( i = 0; i < selectors.length; i++ ) { + + if ( jQuery( cur ).is( selectors[ i ] ) ) { + ret.push({ selector: selectors[ i ], elem: cur, level: level }); + } + } + + cur = cur.parentNode; + level++; + } + + return ret; + } + + // String + var pos = POS.test( selectors ) || typeof selectors !== "string" ? + jQuery( selectors, context || this.context ) : + 0; + + for ( i = 0, l = this.length; i < l; i++ ) { + cur = this[i]; + + while ( cur ) { + if ( pos ? pos.index(cur) > -1 : jQuery.find.matchesSelector(cur, selectors) ) { + ret.push( cur ); + break; + + } else { + cur = cur.parentNode; + if ( !cur || !cur.ownerDocument || cur === context || cur.nodeType === 11 ) { + break; + } + } + } + } + + ret = ret.length > 1 ? jQuery.unique( ret ) : ret; + + return this.pushStack( ret, "closest", selectors ); + }, + + // Determine the position of an element within + // the matched set of elements + index: function( elem ) { + + // No argument, return index in parent + if ( !elem ) { + return ( this[0] && this[0].parentNode ) ? this.prevAll().length : -1; + } + + // index in selector + if ( typeof elem === "string" ) { + return jQuery.inArray( this[0], jQuery( elem ) ); + } + + // Locate the position of the desired element + return jQuery.inArray( + // If it receives a jQuery object, the first element is used + elem.jquery ? elem[0] : elem, this ); + }, + + add: function( selector, context ) { + var set = typeof selector === "string" ? + jQuery( selector, context ) : + jQuery.makeArray( selector && selector.nodeType ? [ selector ] : selector ), + all = jQuery.merge( this.get(), set ); + + return this.pushStack( isDisconnected( set[0] ) || isDisconnected( all[0] ) ? + all : + jQuery.unique( all ) ); + }, + + andSelf: function() { + return this.add( this.prevObject ); + } +}); + +// A painfully simple check to see if an element is disconnected +// from a document (should be improved, where feasible). +function isDisconnected( node ) { + return !node || !node.parentNode || node.parentNode.nodeType === 11; +} + +jQuery.each({ + parent: function( elem ) { + var parent = elem.parentNode; + return parent && parent.nodeType !== 11 ? parent : null; + }, + parents: function( elem ) { + return jQuery.dir( elem, "parentNode" ); + }, + parentsUntil: function( elem, i, until ) { + return jQuery.dir( elem, "parentNode", until ); + }, + next: function( elem ) { + return jQuery.nth( elem, 2, "nextSibling" ); + }, + prev: function( elem ) { + return jQuery.nth( elem, 2, "previousSibling" ); + }, + nextAll: function( elem ) { + return jQuery.dir( elem, "nextSibling" ); + }, + prevAll: function( elem ) { + return jQuery.dir( elem, "previousSibling" ); + }, + nextUntil: function( elem, i, until ) { + return jQuery.dir( elem, "nextSibling", until ); + }, + prevUntil: function( elem, i, until ) { + return jQuery.dir( elem, "previousSibling", until ); + }, + siblings: function( elem ) { + return jQuery.sibling( elem.parentNode.firstChild, elem ); + }, + children: function( elem ) { + return jQuery.sibling( elem.firstChild ); + }, + contents: function( elem ) { + return jQuery.nodeName( elem, "iframe" ) ? + elem.contentDocument || elem.contentWindow.document : + jQuery.makeArray( elem.childNodes ); + } +}, function( name, fn ) { + jQuery.fn[ name ] = function( until, selector ) { + var ret = jQuery.map( this, fn, until ); + + if ( !runtil.test( name ) ) { + selector = until; + } + + if ( selector && typeof selector === "string" ) { + ret = jQuery.filter( selector, ret ); + } + + ret = this.length > 1 && !guaranteedUnique[ name ] ? jQuery.unique( ret ) : ret; + + if ( (this.length > 1 || rmultiselector.test( selector )) && rparentsprev.test( name ) ) { + ret = ret.reverse(); + } + + return this.pushStack( ret, name, slice.call( arguments ).join(",") ); + }; +}); + +jQuery.extend({ + filter: function( expr, elems, not ) { + if ( not ) { + expr = ":not(" + expr + ")"; + } + + return elems.length === 1 ? + jQuery.find.matchesSelector(elems[0], expr) ? [ elems[0] ] : [] : + jQuery.find.matches(expr, elems); + }, + + dir: function( elem, dir, until ) { + var matched = [], + cur = elem[ dir ]; + + while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) { + if ( cur.nodeType === 1 ) { + matched.push( cur ); + } + cur = cur[dir]; + } + return matched; + }, + + nth: function( cur, result, dir, elem ) { + result = result || 1; + var num = 0; + + for ( ; cur; cur = cur[dir] ) { + if ( cur.nodeType === 1 && ++num === result ) { + break; + } + } + + return cur; + }, + + sibling: function( n, elem ) { + var r = []; + + for ( ; n; n = n.nextSibling ) { + if ( n.nodeType === 1 && n !== elem ) { + r.push( n ); + } + } + + return r; + } +}); + +// Implement the identical functionality for filter and not +function winnow( elements, qualifier, keep ) { + + // Can't pass null or undefined to indexOf in Firefox 4 + // Set to 0 to skip string check + qualifier = qualifier || 0; + + if ( jQuery.isFunction( qualifier ) ) { + return jQuery.grep(elements, function( elem, i ) { + var retVal = !!qualifier.call( elem, i, elem ); + return retVal === keep; + }); + + } else if ( qualifier.nodeType ) { + return jQuery.grep(elements, function( elem, i ) { + return ( elem === qualifier ) === keep; + }); + + } else if ( typeof qualifier === "string" ) { + var filtered = jQuery.grep(elements, function( elem ) { + return elem.nodeType === 1; + }); + + if ( isSimple.test( qualifier ) ) { + return jQuery.filter(qualifier, filtered, !keep); + } else { + qualifier = jQuery.filter( qualifier, filtered ); + } + } + + return jQuery.grep(elements, function( elem, i ) { + return ( jQuery.inArray( elem, qualifier ) >= 0 ) === keep; + }); +} + + + + +function createSafeFragment( document ) { + var list = nodeNames.split( "|" ), + safeFrag = document.createDocumentFragment(); + + if ( safeFrag.createElement ) { + while ( list.length ) { + safeFrag.createElement( + list.pop() + ); + } + } + return safeFrag; +} + +var nodeNames = "abbr|article|aside|audio|canvas|datalist|details|figcaption|figure|footer|" + + "header|hgroup|mark|meter|nav|output|progress|section|summary|time|video", + rinlinejQuery = / jQuery\d+="(?:\d+|null)"/g, + rleadingWhitespace = /^\s+/, + rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig, + rtagName = /<([\w:]+)/, + rtbody = /", "" ], + legend: [ 1, "
", "
" ], + thead: [ 1, "", "
" ], + tr: [ 2, "", "
" ], + td: [ 3, "", "
" ], + col: [ 2, "", "
" ], + area: [ 1, "", "" ], + _default: [ 0, "", "" ] + }, + safeFragment = createSafeFragment( document ); + +wrapMap.optgroup = wrapMap.option; +wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; +wrapMap.th = wrapMap.td; + +// IE can't serialize and + + + + + + + + + + + + + + + + + + diff --git a/plugins/WebApollo/tests/js_tests/lib/jasmine-1.2.0/MIT.LICENSE b/plugins/WebApollo/tests/js_tests/lib/jasmine-1.2.0/MIT.LICENSE new file mode 100644 index 0000000000..7c435baaec --- /dev/null +++ b/plugins/WebApollo/tests/js_tests/lib/jasmine-1.2.0/MIT.LICENSE @@ -0,0 +1,20 @@ +Copyright (c) 2008-2011 Pivotal Labs + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/plugins/WebApollo/tests/js_tests/lib/jasmine-1.2.0/jasmine-html.js b/plugins/WebApollo/tests/js_tests/lib/jasmine-1.2.0/jasmine-html.js new file mode 100644 index 0000000000..a0b06394ec --- /dev/null +++ b/plugins/WebApollo/tests/js_tests/lib/jasmine-1.2.0/jasmine-html.js @@ -0,0 +1,616 @@ +jasmine.HtmlReporterHelpers = {}; + +jasmine.HtmlReporterHelpers.createDom = function(type, attrs, childrenVarArgs) { + var el = document.createElement(type); + + for (var i = 2; i < arguments.length; i++) { + var child = arguments[i]; + + if (typeof child === 'string') { + el.appendChild(document.createTextNode(child)); + } else { + if (child) { + el.appendChild(child); + } + } + } + + for (var attr in attrs) { + if (attr == "className") { + el[attr] = attrs[attr]; + } else { + el.setAttribute(attr, attrs[attr]); + } + } + + return el; +}; + +jasmine.HtmlReporterHelpers.getSpecStatus = function(child) { + var results = child.results(); + var status = results.passed() ? 'passed' : 'failed'; + if (results.skipped) { + status = 'skipped'; + } + + return status; +}; + +jasmine.HtmlReporterHelpers.appendToSummary = function(child, childElement) { + var parentDiv = this.dom.summary; + var parentSuite = (typeof child.parentSuite == 'undefined') ? 'suite' : 'parentSuite'; + var parent = child[parentSuite]; + + if (parent) { + if (typeof this.views.suites[parent.id] == 'undefined') { + this.views.suites[parent.id] = new jasmine.HtmlReporter.SuiteView(parent, this.dom, this.views); + } + parentDiv = this.views.suites[parent.id].element; + } + + parentDiv.appendChild(childElement); +}; + + +jasmine.HtmlReporterHelpers.addHelpers = function(ctor) { + for(var fn in jasmine.HtmlReporterHelpers) { + ctor.prototype[fn] = jasmine.HtmlReporterHelpers[fn]; + } +}; + +jasmine.HtmlReporter = function(_doc) { + var self = this; + var doc = _doc || window.document; + + var reporterView; + + var dom = {}; + + // Jasmine Reporter Public Interface + self.logRunningSpecs = false; + + self.reportRunnerStarting = function(runner) { + var specs = runner.specs() || []; + + if (specs.length == 0) { + return; + } + + createReporterDom(runner.env.versionString()); + doc.body.appendChild(dom.reporter); + + reporterView = new jasmine.HtmlReporter.ReporterView(dom); + reporterView.addSpecs(specs, self.specFilter); + }; + + self.reportRunnerResults = function(runner) { + reporterView && reporterView.complete(); + }; + + self.reportSuiteResults = function(suite) { + reporterView.suiteComplete(suite); + }; + + self.reportSpecStarting = function(spec) { + if (self.logRunningSpecs) { + self.log('>> Jasmine Running ' + spec.suite.description + ' ' + spec.description + '...'); + } + }; + + self.reportSpecResults = function(spec) { + reporterView.specComplete(spec); + }; + + self.log = function() { + var console = jasmine.getGlobal().console; + if (console && console.log) { + if (console.log.apply) { + console.log.apply(console, arguments); + } else { + console.log(arguments); // ie fix: console.log.apply doesn't exist on ie + } + } + }; + + self.specFilter = function(spec) { + if (!focusedSpecName()) { + return true; + } + + return spec.getFullName().indexOf(focusedSpecName()) === 0; + }; + + return self; + + function focusedSpecName() { + var specName; + + (function memoizeFocusedSpec() { + if (specName) { + return; + } + + var paramMap = []; + var params = doc.location.search.substring(1).split('&'); + + for (var i = 0; i < params.length; i++) { + var p = params[i].split('='); + paramMap[decodeURIComponent(p[0])] = decodeURIComponent(p[1]); + } + + specName = paramMap.spec; + })(); + + return specName; + } + + function createReporterDom(version) { + dom.reporter = self.createDom('div', { id: 'HTMLReporter', className: 'jasmine_reporter' }, + dom.banner = self.createDom('div', { className: 'banner' }, + self.createDom('span', { className: 'title' }, "Jasmine "), + self.createDom('span', { className: 'version' }, version)), + + dom.symbolSummary = self.createDom('ul', {className: 'symbolSummary'}), + dom.alert = self.createDom('div', {className: 'alert'}), + dom.results = self.createDom('div', {className: 'results'}, + dom.summary = self.createDom('div', { className: 'summary' }), + dom.details = self.createDom('div', { id: 'details' })) + ); + } +}; +jasmine.HtmlReporterHelpers.addHelpers(jasmine.HtmlReporter);jasmine.HtmlReporter.ReporterView = function(dom) { + this.startedAt = new Date(); + this.runningSpecCount = 0; + this.completeSpecCount = 0; + this.passedCount = 0; + this.failedCount = 0; + this.skippedCount = 0; + + this.createResultsMenu = function() { + this.resultsMenu = this.createDom('span', {className: 'resultsMenu bar'}, + this.summaryMenuItem = this.createDom('a', {className: 'summaryMenuItem', href: "#"}, '0 specs'), + ' | ', + this.detailsMenuItem = this.createDom('a', {className: 'detailsMenuItem', href: "#"}, '0 failing')); + + this.summaryMenuItem.onclick = function() { + dom.reporter.className = dom.reporter.className.replace(/ showDetails/g, ''); + }; + + this.detailsMenuItem.onclick = function() { + showDetails(); + }; + }; + + this.addSpecs = function(specs, specFilter) { + this.totalSpecCount = specs.length; + + this.views = { + specs: {}, + suites: {} + }; + + for (var i = 0; i < specs.length; i++) { + var spec = specs[i]; + this.views.specs[spec.id] = new jasmine.HtmlReporter.SpecView(spec, dom, this.views); + if (specFilter(spec)) { + this.runningSpecCount++; + } + } + }; + + this.specComplete = function(spec) { + this.completeSpecCount++; + + if (isUndefined(this.views.specs[spec.id])) { + this.views.specs[spec.id] = new jasmine.HtmlReporter.SpecView(spec, dom); + } + + var specView = this.views.specs[spec.id]; + + switch (specView.status()) { + case 'passed': + this.passedCount++; + break; + + case 'failed': + this.failedCount++; + break; + + case 'skipped': + this.skippedCount++; + break; + } + + specView.refresh(); + this.refresh(); + }; + + this.suiteComplete = function(suite) { + var suiteView = this.views.suites[suite.id]; + if (isUndefined(suiteView)) { + return; + } + suiteView.refresh(); + }; + + this.refresh = function() { + + if (isUndefined(this.resultsMenu)) { + this.createResultsMenu(); + } + + // currently running UI + if (isUndefined(this.runningAlert)) { + this.runningAlert = this.createDom('a', {href: "?", className: "runningAlert bar"}); + dom.alert.appendChild(this.runningAlert); + } + this.runningAlert.innerHTML = "Running " + this.completeSpecCount + " of " + specPluralizedFor(this.totalSpecCount); + + // skipped specs UI + if (isUndefined(this.skippedAlert)) { + this.skippedAlert = this.createDom('a', {href: "?", className: "skippedAlert bar"}); + } + + this.skippedAlert.innerHTML = "Skipping " + this.skippedCount + " of " + specPluralizedFor(this.totalSpecCount) + " - run all"; + + if (this.skippedCount === 1 && isDefined(dom.alert)) { + dom.alert.appendChild(this.skippedAlert); + } + + // passing specs UI + if (isUndefined(this.passedAlert)) { + this.passedAlert = this.createDom('span', {href: "?", className: "passingAlert bar"}); + } + this.passedAlert.innerHTML = "Passing " + specPluralizedFor(this.passedCount); + + // failing specs UI + if (isUndefined(this.failedAlert)) { + this.failedAlert = this.createDom('span', {href: "?", className: "failingAlert bar"}); + } + this.failedAlert.innerHTML = "Failing " + specPluralizedFor(this.failedCount); + + if (this.failedCount === 1 && isDefined(dom.alert)) { + dom.alert.appendChild(this.failedAlert); + dom.alert.appendChild(this.resultsMenu); + } + + // summary info + this.summaryMenuItem.innerHTML = "" + specPluralizedFor(this.runningSpecCount); + this.detailsMenuItem.innerHTML = "" + this.failedCount + " failing"; + }; + + this.complete = function() { + dom.alert.removeChild(this.runningAlert); + + this.skippedAlert.innerHTML = "Ran " + this.runningSpecCount + " of " + specPluralizedFor(this.totalSpecCount) + " - run all"; + + if (this.failedCount === 0) { + dom.alert.appendChild(this.createDom('span', {className: 'passingAlert bar'}, "Passing " + specPluralizedFor(this.passedCount))); + } else { + showDetails(); + } + + dom.banner.appendChild(this.createDom('span', {className: 'duration'}, "finished in " + ((new Date().getTime() - this.startedAt.getTime()) / 1000) + "s")); + }; + + return this; + + function showDetails() { + if (dom.reporter.className.search(/showDetails/) === -1) { + dom.reporter.className += " showDetails"; + } + } + + function isUndefined(obj) { + return typeof obj === 'undefined'; + } + + function isDefined(obj) { + return !isUndefined(obj); + } + + function specPluralizedFor(count) { + var str = count + " spec"; + if (count > 1) { + str += "s" + } + return str; + } + +}; + +jasmine.HtmlReporterHelpers.addHelpers(jasmine.HtmlReporter.ReporterView); + + +jasmine.HtmlReporter.SpecView = function(spec, dom, views) { + this.spec = spec; + this.dom = dom; + this.views = views; + + this.symbol = this.createDom('li', { className: 'pending' }); + this.dom.symbolSummary.appendChild(this.symbol); + + this.summary = this.createDom('div', { className: 'specSummary' }, + this.createDom('a', { + className: 'description', + href: '?spec=' + encodeURIComponent(this.spec.getFullName()), + title: this.spec.getFullName() + }, this.spec.description) + ); + + this.detail = this.createDom('div', { className: 'specDetail' }, + this.createDom('a', { + className: 'description', + href: '?spec=' + encodeURIComponent(this.spec.getFullName()), + title: this.spec.getFullName() + }, this.spec.getFullName()) + ); +}; + +jasmine.HtmlReporter.SpecView.prototype.status = function() { + return this.getSpecStatus(this.spec); +}; + +jasmine.HtmlReporter.SpecView.prototype.refresh = function() { + this.symbol.className = this.status(); + + switch (this.status()) { + case 'skipped': + break; + + case 'passed': + this.appendSummaryToSuiteDiv(); + break; + + case 'failed': + this.appendSummaryToSuiteDiv(); + this.appendFailureDetail(); + break; + } +}; + +jasmine.HtmlReporter.SpecView.prototype.appendSummaryToSuiteDiv = function() { + this.summary.className += ' ' + this.status(); + this.appendToSummary(this.spec, this.summary); +}; + +jasmine.HtmlReporter.SpecView.prototype.appendFailureDetail = function() { + this.detail.className += ' ' + this.status(); + + var resultItems = this.spec.results().getItems(); + var messagesDiv = this.createDom('div', { className: 'messages' }); + + for (var i = 0; i < resultItems.length; i++) { + var result = resultItems[i]; + + if (result.type == 'log') { + messagesDiv.appendChild(this.createDom('div', {className: 'resultMessage log'}, result.toString())); + } else if (result.type == 'expect' && result.passed && !result.passed()) { + messagesDiv.appendChild(this.createDom('div', {className: 'resultMessage fail'}, result.message)); + + if (result.trace.stack) { + messagesDiv.appendChild(this.createDom('div', {className: 'stackTrace'}, result.trace.stack)); + } + } + } + + if (messagesDiv.childNodes.length > 0) { + this.detail.appendChild(messagesDiv); + this.dom.details.appendChild(this.detail); + } +}; + +jasmine.HtmlReporterHelpers.addHelpers(jasmine.HtmlReporter.SpecView);jasmine.HtmlReporter.SuiteView = function(suite, dom, views) { + this.suite = suite; + this.dom = dom; + this.views = views; + + this.element = this.createDom('div', { className: 'suite' }, + this.createDom('a', { className: 'description', href: '?spec=' + encodeURIComponent(this.suite.getFullName()) }, this.suite.description) + ); + + this.appendToSummary(this.suite, this.element); +}; + +jasmine.HtmlReporter.SuiteView.prototype.status = function() { + return this.getSpecStatus(this.suite); +}; + +jasmine.HtmlReporter.SuiteView.prototype.refresh = function() { + this.element.className += " " + this.status(); +}; + +jasmine.HtmlReporterHelpers.addHelpers(jasmine.HtmlReporter.SuiteView); + +/* @deprecated Use jasmine.HtmlReporter instead + */ +jasmine.TrivialReporter = function(doc) { + this.document = doc || document; + this.suiteDivs = {}; + this.logRunningSpecs = false; +}; + +jasmine.TrivialReporter.prototype.createDom = function(type, attrs, childrenVarArgs) { + var el = document.createElement(type); + + for (var i = 2; i < arguments.length; i++) { + var child = arguments[i]; + + if (typeof child === 'string') { + el.appendChild(document.createTextNode(child)); + } else { + if (child) { el.appendChild(child); } + } + } + + for (var attr in attrs) { + if (attr == "className") { + el[attr] = attrs[attr]; + } else { + el.setAttribute(attr, attrs[attr]); + } + } + + return el; +}; + +jasmine.TrivialReporter.prototype.reportRunnerStarting = function(runner) { + var showPassed, showSkipped; + + this.outerDiv = this.createDom('div', { id: 'TrivialReporter', className: 'jasmine_reporter' }, + this.createDom('div', { className: 'banner' }, + this.createDom('div', { className: 'logo' }, + this.createDom('span', { className: 'title' }, "Jasmine"), + this.createDom('span', { className: 'version' }, runner.env.versionString())), + this.createDom('div', { className: 'options' }, + "Show ", + showPassed = this.createDom('input', { id: "__jasmine_TrivialReporter_showPassed__", type: 'checkbox' }), + this.createDom('label', { "for": "__jasmine_TrivialReporter_showPassed__" }, " passed "), + showSkipped = this.createDom('input', { id: "__jasmine_TrivialReporter_showSkipped__", type: 'checkbox' }), + this.createDom('label', { "for": "__jasmine_TrivialReporter_showSkipped__" }, " skipped") + ) + ), + + this.runnerDiv = this.createDom('div', { className: 'runner running' }, + this.createDom('a', { className: 'run_spec', href: '?' }, "run all"), + this.runnerMessageSpan = this.createDom('span', {}, "Running..."), + this.finishedAtSpan = this.createDom('span', { className: 'finished-at' }, "")) + ); + + this.document.body.appendChild(this.outerDiv); + + var suites = runner.suites(); + for (var i = 0; i < suites.length; i++) { + var suite = suites[i]; + var suiteDiv = this.createDom('div', { className: 'suite' }, + this.createDom('a', { className: 'run_spec', href: '?spec=' + encodeURIComponent(suite.getFullName()) }, "run"), + this.createDom('a', { className: 'description', href: '?spec=' + encodeURIComponent(suite.getFullName()) }, suite.description)); + this.suiteDivs[suite.id] = suiteDiv; + var parentDiv = this.outerDiv; + if (suite.parentSuite) { + parentDiv = this.suiteDivs[suite.parentSuite.id]; + } + parentDiv.appendChild(suiteDiv); + } + + this.startedAt = new Date(); + + var self = this; + showPassed.onclick = function(evt) { + if (showPassed.checked) { + self.outerDiv.className += ' show-passed'; + } else { + self.outerDiv.className = self.outerDiv.className.replace(/ show-passed/, ''); + } + }; + + showSkipped.onclick = function(evt) { + if (showSkipped.checked) { + self.outerDiv.className += ' show-skipped'; + } else { + self.outerDiv.className = self.outerDiv.className.replace(/ show-skipped/, ''); + } + }; +}; + +jasmine.TrivialReporter.prototype.reportRunnerResults = function(runner) { + var results = runner.results(); + var className = (results.failedCount > 0) ? "runner failed" : "runner passed"; + this.runnerDiv.setAttribute("class", className); + //do it twice for IE + this.runnerDiv.setAttribute("className", className); + var specs = runner.specs(); + var specCount = 0; + for (var i = 0; i < specs.length; i++) { + if (this.specFilter(specs[i])) { + specCount++; + } + } + var message = "" + specCount + " spec" + (specCount == 1 ? "" : "s" ) + ", " + results.failedCount + " failure" + ((results.failedCount == 1) ? "" : "s"); + message += " in " + ((new Date().getTime() - this.startedAt.getTime()) / 1000) + "s"; + this.runnerMessageSpan.replaceChild(this.createDom('a', { className: 'description', href: '?'}, message), this.runnerMessageSpan.firstChild); + + this.finishedAtSpan.appendChild(document.createTextNode("Finished at " + new Date().toString())); +}; + +jasmine.TrivialReporter.prototype.reportSuiteResults = function(suite) { + var results = suite.results(); + var status = results.passed() ? 'passed' : 'failed'; + if (results.totalCount === 0) { // todo: change this to check results.skipped + status = 'skipped'; + } + this.suiteDivs[suite.id].className += " " + status; +}; + +jasmine.TrivialReporter.prototype.reportSpecStarting = function(spec) { + if (this.logRunningSpecs) { + this.log('>> Jasmine Running ' + spec.suite.description + ' ' + spec.description + '...'); + } +}; + +jasmine.TrivialReporter.prototype.reportSpecResults = function(spec) { + var results = spec.results(); + var status = results.passed() ? 'passed' : 'failed'; + if (results.skipped) { + status = 'skipped'; + } + var specDiv = this.createDom('div', { className: 'spec ' + status }, + this.createDom('a', { className: 'run_spec', href: '?spec=' + encodeURIComponent(spec.getFullName()) }, "run"), + this.createDom('a', { + className: 'description', + href: '?spec=' + encodeURIComponent(spec.getFullName()), + title: spec.getFullName() + }, spec.description)); + + + var resultItems = results.getItems(); + var messagesDiv = this.createDom('div', { className: 'messages' }); + for (var i = 0; i < resultItems.length; i++) { + var result = resultItems[i]; + + if (result.type == 'log') { + messagesDiv.appendChild(this.createDom('div', {className: 'resultMessage log'}, result.toString())); + } else if (result.type == 'expect' && result.passed && !result.passed()) { + messagesDiv.appendChild(this.createDom('div', {className: 'resultMessage fail'}, result.message)); + + if (result.trace.stack) { + messagesDiv.appendChild(this.createDom('div', {className: 'stackTrace'}, result.trace.stack)); + } + } + } + + if (messagesDiv.childNodes.length > 0) { + specDiv.appendChild(messagesDiv); + } + + this.suiteDivs[spec.suite.id].appendChild(specDiv); +}; + +jasmine.TrivialReporter.prototype.log = function() { + var console = jasmine.getGlobal().console; + if (console && console.log) { + if (console.log.apply) { + console.log.apply(console, arguments); + } else { + console.log(arguments); // ie fix: console.log.apply doesn't exist on ie + } + } +}; + +jasmine.TrivialReporter.prototype.getLocation = function() { + return this.document.location; +}; + +jasmine.TrivialReporter.prototype.specFilter = function(spec) { + var paramMap = {}; + var params = this.getLocation().search.substring(1).split('&'); + for (var i = 0; i < params.length; i++) { + var p = params[i].split('='); + paramMap[decodeURIComponent(p[0])] = decodeURIComponent(p[1]); + } + + if (!paramMap.spec) { + return true; + } + return spec.getFullName().indexOf(paramMap.spec) === 0; +}; diff --git a/plugins/WebApollo/tests/js_tests/lib/jasmine-1.2.0/jasmine.css b/plugins/WebApollo/tests/js_tests/lib/jasmine-1.2.0/jasmine.css new file mode 100644 index 0000000000..826e575310 --- /dev/null +++ b/plugins/WebApollo/tests/js_tests/lib/jasmine-1.2.0/jasmine.css @@ -0,0 +1,81 @@ +body { background-color: #eeeeee; padding: 0; margin: 5px; overflow-y: scroll; } + +#HTMLReporter { font-size: 11px; font-family: Monaco, "Lucida Console", monospace; line-height: 14px; color: #333333; } +#HTMLReporter a { text-decoration: none; } +#HTMLReporter a:hover { text-decoration: underline; } +#HTMLReporter p, #HTMLReporter h1, #HTMLReporter h2, #HTMLReporter h3, #HTMLReporter h4, #HTMLReporter h5, #HTMLReporter h6 { margin: 0; line-height: 14px; } +#HTMLReporter .banner, #HTMLReporter .symbolSummary, #HTMLReporter .summary, #HTMLReporter .resultMessage, #HTMLReporter .specDetail .description, #HTMLReporter .alert .bar, #HTMLReporter .stackTrace { padding-left: 9px; padding-right: 9px; } +#HTMLReporter #jasmine_content { position: fixed; right: 100%; } +#HTMLReporter .version { color: #aaaaaa; } +#HTMLReporter .banner { margin-top: 14px; } +#HTMLReporter .duration { color: #aaaaaa; float: right; } +#HTMLReporter .symbolSummary { overflow: hidden; *zoom: 1; margin: 14px 0; } +#HTMLReporter .symbolSummary li { display: block; float: left; height: 7px; width: 14px; margin-bottom: 7px; font-size: 16px; } +#HTMLReporter .symbolSummary li.passed { font-size: 14px; } +#HTMLReporter .symbolSummary li.passed:before { color: #5e7d00; content: "\02022"; } +#HTMLReporter .symbolSummary li.failed { line-height: 9px; } +#HTMLReporter .symbolSummary li.failed:before { color: #b03911; content: "x"; font-weight: bold; margin-left: -1px; } +#HTMLReporter .symbolSummary li.skipped { font-size: 14px; } +#HTMLReporter .symbolSummary li.skipped:before { color: #bababa; content: "\02022"; } +#HTMLReporter .symbolSummary li.pending { line-height: 11px; } +#HTMLReporter .symbolSummary li.pending:before { color: #aaaaaa; content: "-"; } +#HTMLReporter .bar { line-height: 28px; font-size: 14px; display: block; color: #eee; } +#HTMLReporter .runningAlert { background-color: #666666; } +#HTMLReporter .skippedAlert { background-color: #aaaaaa; } +#HTMLReporter .skippedAlert:first-child { background-color: #333333; } +#HTMLReporter .skippedAlert:hover { text-decoration: none; color: white; text-decoration: underline; } +#HTMLReporter .passingAlert { background-color: #a6b779; } +#HTMLReporter .passingAlert:first-child { background-color: #5e7d00; } +#HTMLReporter .failingAlert { background-color: #cf867e; } +#HTMLReporter .failingAlert:first-child { background-color: #b03911; } +#HTMLReporter .results { margin-top: 14px; } +#HTMLReporter #details { display: none; } +#HTMLReporter .resultsMenu, #HTMLReporter .resultsMenu a { background-color: #fff; color: #333333; } +#HTMLReporter.showDetails .summaryMenuItem { font-weight: normal; text-decoration: inherit; } +#HTMLReporter.showDetails .summaryMenuItem:hover { text-decoration: underline; } +#HTMLReporter.showDetails .detailsMenuItem { font-weight: bold; text-decoration: underline; } +#HTMLReporter.showDetails .summary { display: none; } +#HTMLReporter.showDetails #details { display: block; } +#HTMLReporter .summaryMenuItem { font-weight: bold; text-decoration: underline; } +#HTMLReporter .summary { margin-top: 14px; } +#HTMLReporter .summary .suite .suite, #HTMLReporter .summary .specSummary { margin-left: 14px; } +#HTMLReporter .summary .specSummary.passed a { color: #5e7d00; } +#HTMLReporter .summary .specSummary.failed a { color: #b03911; } +#HTMLReporter .description + .suite { margin-top: 0; } +#HTMLReporter .suite { margin-top: 14px; } +#HTMLReporter .suite a { color: #333333; } +#HTMLReporter #details .specDetail { margin-bottom: 28px; } +#HTMLReporter #details .specDetail .description { display: block; color: white; background-color: #b03911; } +#HTMLReporter .resultMessage { padding-top: 14px; color: #333333; } +#HTMLReporter .resultMessage span.result { display: block; } +#HTMLReporter .stackTrace { margin: 5px 0 0 0; max-height: 224px; overflow: auto; line-height: 18px; color: #666666; border: 1px solid #ddd; background: white; white-space: pre; } + +#TrivialReporter { padding: 8px 13px; position: absolute; top: 0; bottom: 0; left: 0; right: 0; overflow-y: scroll; background-color: white; font-family: "Helvetica Neue Light", "Lucida Grande", "Calibri", "Arial", sans-serif; /*.resultMessage {*/ /*white-space: pre;*/ /*}*/ } +#TrivialReporter a:visited, #TrivialReporter a { color: #303; } +#TrivialReporter a:hover, #TrivialReporter a:active { color: blue; } +#TrivialReporter .run_spec { float: right; padding-right: 5px; font-size: .8em; text-decoration: none; } +#TrivialReporter .banner { color: #303; background-color: #fef; padding: 5px; } +#TrivialReporter .logo { float: left; font-size: 1.1em; padding-left: 5px; } +#TrivialReporter .logo .version { font-size: .6em; padding-left: 1em; } +#TrivialReporter .runner.running { background-color: yellow; } +#TrivialReporter .options { text-align: right; font-size: .8em; } +#TrivialReporter .suite { border: 1px outset gray; margin: 5px 0; padding-left: 1em; } +#TrivialReporter .suite .suite { margin: 5px; } +#TrivialReporter .suite.passed { background-color: #dfd; } +#TrivialReporter .suite.failed { background-color: #fdd; } +#TrivialReporter .spec { margin: 5px; padding-left: 1em; clear: both; } +#TrivialReporter .spec.failed, #TrivialReporter .spec.passed, #TrivialReporter .spec.skipped { padding-bottom: 5px; border: 1px solid gray; } +#TrivialReporter .spec.failed { background-color: #fbb; border-color: red; } +#TrivialReporter .spec.passed { background-color: #bfb; border-color: green; } +#TrivialReporter .spec.skipped { background-color: #bbb; } +#TrivialReporter .messages { border-left: 1px dashed gray; padding-left: 1em; padding-right: 1em; } +#TrivialReporter .passed { background-color: #cfc; display: none; } +#TrivialReporter .failed { background-color: #fbb; } +#TrivialReporter .skipped { color: #777; background-color: #eee; display: none; } +#TrivialReporter .resultMessage span.result { display: block; line-height: 2em; color: black; } +#TrivialReporter .resultMessage .mismatch { color: black; } +#TrivialReporter .stackTrace { white-space: pre; font-size: .8em; margin-left: 10px; max-height: 5em; overflow: auto; border: 1px inset red; padding: 1em; background: #eef; } +#TrivialReporter .finished-at { padding-left: 1em; font-size: .6em; } +#TrivialReporter.show-passed .passed, #TrivialReporter.show-skipped .skipped { display: block; } +#TrivialReporter #jasmine_content { position: fixed; right: 100%; } +#TrivialReporter .runner { border: 1px solid gray; display: block; margin: 5px 0; padding: 2px 0 2px 10px; } diff --git a/plugins/WebApollo/tests/js_tests/lib/jasmine-1.2.0/jasmine.js b/plugins/WebApollo/tests/js_tests/lib/jasmine-1.2.0/jasmine.js new file mode 100644 index 0000000000..03bf89a0c4 --- /dev/null +++ b/plugins/WebApollo/tests/js_tests/lib/jasmine-1.2.0/jasmine.js @@ -0,0 +1,2529 @@ +var isCommonJS = typeof window == "undefined"; + +/** + * Top level namespace for Jasmine, a lightweight JavaScript BDD/spec/testing framework. + * + * @namespace + */ +var jasmine = {}; +if (isCommonJS) exports.jasmine = jasmine; +/** + * @private + */ +jasmine.unimplementedMethod_ = function() { + throw new Error("unimplemented method"); +}; + +/** + * Use jasmine.undefined instead of undefined, since undefined is just + * a plain old variable and may be redefined by somebody else. + * + * @private + */ +jasmine.undefined = jasmine.___undefined___; + +/** + * Show diagnostic messages in the console if set to true + * + */ +jasmine.VERBOSE = false; + +/** + * Default interval in milliseconds for event loop yields (e.g. to allow network activity or to refresh the screen with the HTML-based runner). Small values here may result in slow test running. Zero means no updates until all tests have completed. + * + */ +jasmine.DEFAULT_UPDATE_INTERVAL = 250; + +/** + * Default timeout interval in milliseconds for waitsFor() blocks. + */ +jasmine.DEFAULT_TIMEOUT_INTERVAL = 5000; + +jasmine.getGlobal = function() { + function getGlobal() { + return this; + } + + return getGlobal(); +}; + +/** + * Allows for bound functions to be compared. Internal use only. + * + * @ignore + * @private + * @param base {Object} bound 'this' for the function + * @param name {Function} function to find + */ +jasmine.bindOriginal_ = function(base, name) { + var original = base[name]; + if (original.apply) { + return function() { + return original.apply(base, arguments); + }; + } else { + // IE support + return jasmine.getGlobal()[name]; + } +}; + +jasmine.setTimeout = jasmine.bindOriginal_(jasmine.getGlobal(), 'setTimeout'); +jasmine.clearTimeout = jasmine.bindOriginal_(jasmine.getGlobal(), 'clearTimeout'); +jasmine.setInterval = jasmine.bindOriginal_(jasmine.getGlobal(), 'setInterval'); +jasmine.clearInterval = jasmine.bindOriginal_(jasmine.getGlobal(), 'clearInterval'); + +jasmine.MessageResult = function(values) { + this.type = 'log'; + this.values = values; + this.trace = new Error(); // todo: test better +}; + +jasmine.MessageResult.prototype.toString = function() { + var text = ""; + for (var i = 0; i < this.values.length; i++) { + if (i > 0) text += " "; + if (jasmine.isString_(this.values[i])) { + text += this.values[i]; + } else { + text += jasmine.pp(this.values[i]); + } + } + return text; +}; + +jasmine.ExpectationResult = function(params) { + this.type = 'expect'; + this.matcherName = params.matcherName; + this.passed_ = params.passed; + this.expected = params.expected; + this.actual = params.actual; + this.message = this.passed_ ? 'Passed.' : params.message; + + var trace = (params.trace || new Error(this.message)); + this.trace = this.passed_ ? '' : trace; +}; + +jasmine.ExpectationResult.prototype.toString = function () { + return this.message; +}; + +jasmine.ExpectationResult.prototype.passed = function () { + return this.passed_; +}; + +/** + * Getter for the Jasmine environment. Ensures one gets created + */ +jasmine.getEnv = function() { + var env = jasmine.currentEnv_ = jasmine.currentEnv_ || new jasmine.Env(); + return env; +}; + +/** + * @ignore + * @private + * @param value + * @returns {Boolean} + */ +jasmine.isArray_ = function(value) { + return jasmine.isA_("Array", value); +}; + +/** + * @ignore + * @private + * @param value + * @returns {Boolean} + */ +jasmine.isString_ = function(value) { + return jasmine.isA_("String", value); +}; + +/** + * @ignore + * @private + * @param value + * @returns {Boolean} + */ +jasmine.isNumber_ = function(value) { + return jasmine.isA_("Number", value); +}; + +/** + * @ignore + * @private + * @param {String} typeName + * @param value + * @returns {Boolean} + */ +jasmine.isA_ = function(typeName, value) { + return Object.prototype.toString.apply(value) === '[object ' + typeName + ']'; +}; + +/** + * Pretty printer for expecations. Takes any object and turns it into a human-readable string. + * + * @param value {Object} an object to be outputted + * @returns {String} + */ +jasmine.pp = function(value) { + var stringPrettyPrinter = new jasmine.StringPrettyPrinter(); + stringPrettyPrinter.format(value); + return stringPrettyPrinter.string; +}; + +/** + * Returns true if the object is a DOM Node. + * + * @param {Object} obj object to check + * @returns {Boolean} + */ +jasmine.isDomNode = function(obj) { + return obj.nodeType > 0; +}; + +/** + * Returns a matchable 'generic' object of the class type. For use in expecations of type when values don't matter. + * + * @example + * // don't care about which function is passed in, as long as it's a function + * expect(mySpy).toHaveBeenCalledWith(jasmine.any(Function)); + * + * @param {Class} clazz + * @returns matchable object of the type clazz + */ +jasmine.any = function(clazz) { + return new jasmine.Matchers.Any(clazz); +}; + +/** + * Returns a matchable subset of a JSON object. For use in expectations when you don't care about all of the + * attributes on the object. + * + * @example + * // don't care about any other attributes than foo. + * expect(mySpy).toHaveBeenCalledWith(jasmine.objectContaining({foo: "bar"}); + * + * @param sample {Object} sample + * @returns matchable object for the sample + */ +jasmine.objectContaining = function (sample) { + return new jasmine.Matchers.ObjectContaining(sample); +}; + +/** + * Jasmine Spies are test doubles that can act as stubs, spies, fakes or when used in an expecation, mocks. + * + * Spies should be created in test setup, before expectations. They can then be checked, using the standard Jasmine + * expectation syntax. Spies can be checked if they were called or not and what the calling params were. + * + * A Spy has the following fields: wasCalled, callCount, mostRecentCall, and argsForCall (see docs). + * + * Spies are torn down at the end of every spec. + * + * Note: Do not call new jasmine.Spy() directly - a spy must be created using spyOn, jasmine.createSpy or jasmine.createSpyObj. + * + * @example + * // a stub + * var myStub = jasmine.createSpy('myStub'); // can be used anywhere + * + * // spy example + * var foo = { + * not: function(bool) { return !bool; } + * } + * + * // actual foo.not will not be called, execution stops + * spyOn(foo, 'not'); + + // foo.not spied upon, execution will continue to implementation + * spyOn(foo, 'not').andCallThrough(); + * + * // fake example + * var foo = { + * not: function(bool) { return !bool; } + * } + * + * // foo.not(val) will return val + * spyOn(foo, 'not').andCallFake(function(value) {return value;}); + * + * // mock example + * foo.not(7 == 7); + * expect(foo.not).toHaveBeenCalled(); + * expect(foo.not).toHaveBeenCalledWith(true); + * + * @constructor + * @see spyOn, jasmine.createSpy, jasmine.createSpyObj + * @param {String} name + */ +jasmine.Spy = function(name) { + /** + * The name of the spy, if provided. + */ + this.identity = name || 'unknown'; + /** + * Is this Object a spy? + */ + this.isSpy = true; + /** + * The actual function this spy stubs. + */ + this.plan = function() { + }; + /** + * Tracking of the most recent call to the spy. + * @example + * var mySpy = jasmine.createSpy('foo'); + * mySpy(1, 2); + * mySpy.mostRecentCall.args = [1, 2]; + */ + this.mostRecentCall = {}; + + /** + * Holds arguments for each call to the spy, indexed by call count + * @example + * var mySpy = jasmine.createSpy('foo'); + * mySpy(1, 2); + * mySpy(7, 8); + * mySpy.mostRecentCall.args = [7, 8]; + * mySpy.argsForCall[0] = [1, 2]; + * mySpy.argsForCall[1] = [7, 8]; + */ + this.argsForCall = []; + this.calls = []; +}; + +/** + * Tells a spy to call through to the actual implemenatation. + * + * @example + * var foo = { + * bar: function() { // do some stuff } + * } + * + * // defining a spy on an existing property: foo.bar + * spyOn(foo, 'bar').andCallThrough(); + */ +jasmine.Spy.prototype.andCallThrough = function() { + this.plan = this.originalValue; + return this; +}; + +/** + * For setting the return value of a spy. + * + * @example + * // defining a spy from scratch: foo() returns 'baz' + * var foo = jasmine.createSpy('spy on foo').andReturn('baz'); + * + * // defining a spy on an existing property: foo.bar() returns 'baz' + * spyOn(foo, 'bar').andReturn('baz'); + * + * @param {Object} value + */ +jasmine.Spy.prototype.andReturn = function(value) { + this.plan = function() { + return value; + }; + return this; +}; + +/** + * For throwing an exception when a spy is called. + * + * @example + * // defining a spy from scratch: foo() throws an exception w/ message 'ouch' + * var foo = jasmine.createSpy('spy on foo').andThrow('baz'); + * + * // defining a spy on an existing property: foo.bar() throws an exception w/ message 'ouch' + * spyOn(foo, 'bar').andThrow('baz'); + * + * @param {String} exceptionMsg + */ +jasmine.Spy.prototype.andThrow = function(exceptionMsg) { + this.plan = function() { + throw exceptionMsg; + }; + return this; +}; + +/** + * Calls an alternate implementation when a spy is called. + * + * @example + * var baz = function() { + * // do some stuff, return something + * } + * // defining a spy from scratch: foo() calls the function baz + * var foo = jasmine.createSpy('spy on foo').andCall(baz); + * + * // defining a spy on an existing property: foo.bar() calls an anonymnous function + * spyOn(foo, 'bar').andCall(function() { return 'baz';} ); + * + * @param {Function} fakeFunc + */ +jasmine.Spy.prototype.andCallFake = function(fakeFunc) { + this.plan = fakeFunc; + return this; +}; + +/** + * Resets all of a spy's the tracking variables so that it can be used again. + * + * @example + * spyOn(foo, 'bar'); + * + * foo.bar(); + * + * expect(foo.bar.callCount).toEqual(1); + * + * foo.bar.reset(); + * + * expect(foo.bar.callCount).toEqual(0); + */ +jasmine.Spy.prototype.reset = function() { + this.wasCalled = false; + this.callCount = 0; + this.argsForCall = []; + this.calls = []; + this.mostRecentCall = {}; +}; + +jasmine.createSpy = function(name) { + + var spyObj = function() { + spyObj.wasCalled = true; + spyObj.callCount++; + var args = jasmine.util.argsToArray(arguments); + spyObj.mostRecentCall.object = this; + spyObj.mostRecentCall.args = args; + spyObj.argsForCall.push(args); + spyObj.calls.push({object: this, args: args}); + return spyObj.plan.apply(this, arguments); + }; + + var spy = new jasmine.Spy(name); + + for (var prop in spy) { + spyObj[prop] = spy[prop]; + } + + spyObj.reset(); + + return spyObj; +}; + +/** + * Determines whether an object is a spy. + * + * @param {jasmine.Spy|Object} putativeSpy + * @returns {Boolean} + */ +jasmine.isSpy = function(putativeSpy) { + return putativeSpy && putativeSpy.isSpy; +}; + +/** + * Creates a more complicated spy: an Object that has every property a function that is a spy. Used for stubbing something + * large in one call. + * + * @param {String} baseName name of spy class + * @param {Array} methodNames array of names of methods to make spies + */ +jasmine.createSpyObj = function(baseName, methodNames) { + if (!jasmine.isArray_(methodNames) || methodNames.length === 0) { + throw new Error('createSpyObj requires a non-empty array of method names to create spies for'); + } + var obj = {}; + for (var i = 0; i < methodNames.length; i++) { + obj[methodNames[i]] = jasmine.createSpy(baseName + '.' + methodNames[i]); + } + return obj; +}; + +/** + * All parameters are pretty-printed and concatenated together, then written to the current spec's output. + * + * Be careful not to leave calls to jasmine.log in production code. + */ +jasmine.log = function() { + var spec = jasmine.getEnv().currentSpec; + spec.log.apply(spec, arguments); +}; + +/** + * Function that installs a spy on an existing object's method name. Used within a Spec to create a spy. + * + * @example + * // spy example + * var foo = { + * not: function(bool) { return !bool; } + * } + * spyOn(foo, 'not'); // actual foo.not will not be called, execution stops + * + * @see jasmine.createSpy + * @param obj + * @param methodName + * @returns a Jasmine spy that can be chained with all spy methods + */ +var spyOn = function(obj, methodName) { + return jasmine.getEnv().currentSpec.spyOn(obj, methodName); +}; +if (isCommonJS) exports.spyOn = spyOn; + +/** + * Creates a Jasmine spec that will be added to the current suite. + * + * // TODO: pending tests + * + * @example + * it('should be true', function() { + * expect(true).toEqual(true); + * }); + * + * @param {String} desc description of this specification + * @param {Function} func defines the preconditions and expectations of the spec + */ +var it = function(desc, func) { + return jasmine.getEnv().it(desc, func); +}; +if (isCommonJS) exports.it = it; + +/** + * Creates a disabled Jasmine spec. + * + * A convenience method that allows existing specs to be disabled temporarily during development. + * + * @param {String} desc description of this specification + * @param {Function} func defines the preconditions and expectations of the spec + */ +var xit = function(desc, func) { + return jasmine.getEnv().xit(desc, func); +}; +if (isCommonJS) exports.xit = xit; + +/** + * Starts a chain for a Jasmine expectation. + * + * It is passed an Object that is the actual value and should chain to one of the many + * jasmine.Matchers functions. + * + * @param {Object} actual Actual value to test against and expected value + */ +var expect = function(actual) { + return jasmine.getEnv().currentSpec.expect(actual); +}; +if (isCommonJS) exports.expect = expect; + +/** + * Defines part of a jasmine spec. Used in cominbination with waits or waitsFor in asynchrnous specs. + * + * @param {Function} func Function that defines part of a jasmine spec. + */ +var runs = function(func) { + jasmine.getEnv().currentSpec.runs(func); +}; +if (isCommonJS) exports.runs = runs; + +/** + * Waits a fixed time period before moving to the next block. + * + * @deprecated Use waitsFor() instead + * @param {Number} timeout milliseconds to wait + */ +var waits = function(timeout) { + jasmine.getEnv().currentSpec.waits(timeout); +}; +if (isCommonJS) exports.waits = waits; + +/** + * Waits for the latchFunction to return true before proceeding to the next block. + * + * @param {Function} latchFunction + * @param {String} optional_timeoutMessage + * @param {Number} optional_timeout + */ +var waitsFor = function(latchFunction, optional_timeoutMessage, optional_timeout) { + jasmine.getEnv().currentSpec.waitsFor.apply(jasmine.getEnv().currentSpec, arguments); +}; +if (isCommonJS) exports.waitsFor = waitsFor; + +/** + * A function that is called before each spec in a suite. + * + * Used for spec setup, including validating assumptions. + * + * @param {Function} beforeEachFunction + */ +var beforeEach = function(beforeEachFunction) { + jasmine.getEnv().beforeEach(beforeEachFunction); +}; +if (isCommonJS) exports.beforeEach = beforeEach; + +/** + * A function that is called after each spec in a suite. + * + * Used for restoring any state that is hijacked during spec execution. + * + * @param {Function} afterEachFunction + */ +var afterEach = function(afterEachFunction) { + jasmine.getEnv().afterEach(afterEachFunction); +}; +if (isCommonJS) exports.afterEach = afterEach; + +/** + * Defines a suite of specifications. + * + * Stores the description and all defined specs in the Jasmine environment as one suite of specs. Variables declared + * are accessible by calls to beforeEach, it, and afterEach. Describe blocks can be nested, allowing for specialization + * of setup in some tests. + * + * @example + * // TODO: a simple suite + * + * // TODO: a simple suite with a nested describe block + * + * @param {String} description A string, usually the class under test. + * @param {Function} specDefinitions function that defines several specs. + */ +var describe = function(description, specDefinitions) { + return jasmine.getEnv().describe(description, specDefinitions); +}; +if (isCommonJS) exports.describe = describe; + +/** + * Disables a suite of specifications. Used to disable some suites in a file, or files, temporarily during development. + * + * @param {String} description A string, usually the class under test. + * @param {Function} specDefinitions function that defines several specs. + */ +var xdescribe = function(description, specDefinitions) { + return jasmine.getEnv().xdescribe(description, specDefinitions); +}; +if (isCommonJS) exports.xdescribe = xdescribe; + + +// Provide the XMLHttpRequest class for IE 5.x-6.x: +jasmine.XmlHttpRequest = (typeof XMLHttpRequest == "undefined") ? function() { + function tryIt(f) { + try { + return f(); + } catch(e) { + } + return null; + } + + var xhr = tryIt(function() { + return new ActiveXObject("Msxml2.XMLHTTP.6.0"); + }) || + tryIt(function() { + return new ActiveXObject("Msxml2.XMLHTTP.3.0"); + }) || + tryIt(function() { + return new ActiveXObject("Msxml2.XMLHTTP"); + }) || + tryIt(function() { + return new ActiveXObject("Microsoft.XMLHTTP"); + }); + + if (!xhr) throw new Error("This browser does not support XMLHttpRequest."); + + return xhr; +} : XMLHttpRequest; +/** + * @namespace + */ +jasmine.util = {}; + +/** + * Declare that a child class inherit it's prototype from the parent class. + * + * @private + * @param {Function} childClass + * @param {Function} parentClass + */ +jasmine.util.inherit = function(childClass, parentClass) { + /** + * @private + */ + var subclass = function() { + }; + subclass.prototype = parentClass.prototype; + childClass.prototype = new subclass(); +}; + +jasmine.util.formatException = function(e) { + var lineNumber; + if (e.line) { + lineNumber = e.line; + } + else if (e.lineNumber) { + lineNumber = e.lineNumber; + } + + var file; + + if (e.sourceURL) { + file = e.sourceURL; + } + else if (e.fileName) { + file = e.fileName; + } + + var message = (e.name && e.message) ? (e.name + ': ' + e.message) : e.toString(); + + if (file && lineNumber) { + message += ' in ' + file + ' (line ' + lineNumber + ')'; + } + + return message; +}; + +jasmine.util.htmlEscape = function(str) { + if (!str) return str; + return str.replace(/&/g, '&') + .replace(//g, '>'); +}; + +jasmine.util.argsToArray = function(args) { + var arrayOfArgs = []; + for (var i = 0; i < args.length; i++) arrayOfArgs.push(args[i]); + return arrayOfArgs; +}; + +jasmine.util.extend = function(destination, source) { + for (var property in source) destination[property] = source[property]; + return destination; +}; + +/** + * Environment for Jasmine + * + * @constructor + */ +jasmine.Env = function() { + this.currentSpec = null; + this.currentSuite = null; + this.currentRunner_ = new jasmine.Runner(this); + + this.reporter = new jasmine.MultiReporter(); + + this.updateInterval = jasmine.DEFAULT_UPDATE_INTERVAL; + this.defaultTimeoutInterval = jasmine.DEFAULT_TIMEOUT_INTERVAL; + this.lastUpdate = 0; + this.specFilter = function() { + return true; + }; + + this.nextSpecId_ = 0; + this.nextSuiteId_ = 0; + this.equalityTesters_ = []; + + // wrap matchers + this.matchersClass = function() { + jasmine.Matchers.apply(this, arguments); + }; + jasmine.util.inherit(this.matchersClass, jasmine.Matchers); + + jasmine.Matchers.wrapInto_(jasmine.Matchers.prototype, this.matchersClass); +}; + + +jasmine.Env.prototype.setTimeout = jasmine.setTimeout; +jasmine.Env.prototype.clearTimeout = jasmine.clearTimeout; +jasmine.Env.prototype.setInterval = jasmine.setInterval; +jasmine.Env.prototype.clearInterval = jasmine.clearInterval; + +/** + * @returns an object containing jasmine version build info, if set. + */ +jasmine.Env.prototype.version = function () { + if (jasmine.version_) { + return jasmine.version_; + } else { + throw new Error('Version not set'); + } +}; + +/** + * @returns string containing jasmine version build info, if set. + */ +jasmine.Env.prototype.versionString = function() { + if (!jasmine.version_) { + return "version unknown"; + } + + var version = this.version(); + var versionString = version.major + "." + version.minor + "." + version.build; + if (version.release_candidate) { + versionString += ".rc" + version.release_candidate; + } + versionString += " revision " + version.revision; + return versionString; +}; + +/** + * @returns a sequential integer starting at 0 + */ +jasmine.Env.prototype.nextSpecId = function () { + return this.nextSpecId_++; +}; + +/** + * @returns a sequential integer starting at 0 + */ +jasmine.Env.prototype.nextSuiteId = function () { + return this.nextSuiteId_++; +}; + +/** + * Register a reporter to receive status updates from Jasmine. + * @param {jasmine.Reporter} reporter An object which will receive status updates. + */ +jasmine.Env.prototype.addReporter = function(reporter) { + this.reporter.addReporter(reporter); +}; + +jasmine.Env.prototype.execute = function() { + this.currentRunner_.execute(); +}; + +jasmine.Env.prototype.describe = function(description, specDefinitions) { + var suite = new jasmine.Suite(this, description, specDefinitions, this.currentSuite); + + var parentSuite = this.currentSuite; + if (parentSuite) { + parentSuite.add(suite); + } else { + this.currentRunner_.add(suite); + } + + this.currentSuite = suite; + + var declarationError = null; + try { + specDefinitions.call(suite); + } catch(e) { + declarationError = e; + } + + if (declarationError) { + this.it("encountered a declaration exception", function() { + throw declarationError; + }); + } + + this.currentSuite = parentSuite; + + return suite; +}; + +jasmine.Env.prototype.beforeEach = function(beforeEachFunction) { + if (this.currentSuite) { + this.currentSuite.beforeEach(beforeEachFunction); + } else { + this.currentRunner_.beforeEach(beforeEachFunction); + } +}; + +jasmine.Env.prototype.currentRunner = function () { + return this.currentRunner_; +}; + +jasmine.Env.prototype.afterEach = function(afterEachFunction) { + if (this.currentSuite) { + this.currentSuite.afterEach(afterEachFunction); + } else { + this.currentRunner_.afterEach(afterEachFunction); + } + +}; + +jasmine.Env.prototype.xdescribe = function(desc, specDefinitions) { + return { + execute: function() { + } + }; +}; + +jasmine.Env.prototype.it = function(description, func) { + var spec = new jasmine.Spec(this, this.currentSuite, description); + this.currentSuite.add(spec); + this.currentSpec = spec; + + if (func) { + spec.runs(func); + } + + return spec; +}; + +jasmine.Env.prototype.xit = function(desc, func) { + return { + id: this.nextSpecId(), + runs: function() { + } + }; +}; + +jasmine.Env.prototype.compareObjects_ = function(a, b, mismatchKeys, mismatchValues) { + if (a.__Jasmine_been_here_before__ === b && b.__Jasmine_been_here_before__ === a) { + return true; + } + + a.__Jasmine_been_here_before__ = b; + b.__Jasmine_been_here_before__ = a; + + var hasKey = function(obj, keyName) { + return obj !== null && obj[keyName] !== jasmine.undefined; + }; + + for (var property in b) { + if (!hasKey(a, property) && hasKey(b, property)) { + mismatchKeys.push("expected has key '" + property + "', but missing from actual."); + } + } + for (property in a) { + if (!hasKey(b, property) && hasKey(a, property)) { + mismatchKeys.push("expected missing key '" + property + "', but present in actual."); + } + } + for (property in b) { + if (property == '__Jasmine_been_here_before__') continue; + if (!this.equals_(a[property], b[property], mismatchKeys, mismatchValues)) { + mismatchValues.push("'" + property + "' was '" + (b[property] ? jasmine.util.htmlEscape(b[property].toString()) : b[property]) + "' in expected, but was '" + (a[property] ? jasmine.util.htmlEscape(a[property].toString()) : a[property]) + "' in actual."); + } + } + + if (jasmine.isArray_(a) && jasmine.isArray_(b) && a.length != b.length) { + mismatchValues.push("arrays were not the same length"); + } + + delete a.__Jasmine_been_here_before__; + delete b.__Jasmine_been_here_before__; + return (mismatchKeys.length === 0 && mismatchValues.length === 0); +}; + +jasmine.Env.prototype.equals_ = function(a, b, mismatchKeys, mismatchValues) { + mismatchKeys = mismatchKeys || []; + mismatchValues = mismatchValues || []; + + for (var i = 0; i < this.equalityTesters_.length; i++) { + var equalityTester = this.equalityTesters_[i]; + var result = equalityTester(a, b, this, mismatchKeys, mismatchValues); + if (result !== jasmine.undefined) return result; + } + + if (a === b) return true; + + if (a === jasmine.undefined || a === null || b === jasmine.undefined || b === null) { + return (a == jasmine.undefined && b == jasmine.undefined); + } + + if (jasmine.isDomNode(a) && jasmine.isDomNode(b)) { + return a === b; + } + + if (a instanceof Date && b instanceof Date) { + return a.getTime() == b.getTime(); + } + + if (a.jasmineMatches) { + return a.jasmineMatches(b); + } + + if (b.jasmineMatches) { + return b.jasmineMatches(a); + } + + if (a instanceof jasmine.Matchers.ObjectContaining) { + return a.matches(b); + } + + if (b instanceof jasmine.Matchers.ObjectContaining) { + return b.matches(a); + } + + if (jasmine.isString_(a) && jasmine.isString_(b)) { + return (a == b); + } + + if (jasmine.isNumber_(a) && jasmine.isNumber_(b)) { + return (a == b); + } + + if (typeof a === "object" && typeof b === "object") { + return this.compareObjects_(a, b, mismatchKeys, mismatchValues); + } + + //Straight check + return (a === b); +}; + +jasmine.Env.prototype.contains_ = function(haystack, needle) { + if (jasmine.isArray_(haystack)) { + for (var i = 0; i < haystack.length; i++) { + if (this.equals_(haystack[i], needle)) return true; + } + return false; + } + return haystack.indexOf(needle) >= 0; +}; + +jasmine.Env.prototype.addEqualityTester = function(equalityTester) { + this.equalityTesters_.push(equalityTester); +}; +/** No-op base class for Jasmine reporters. + * + * @constructor + */ +jasmine.Reporter = function() { +}; + +//noinspection JSUnusedLocalSymbols +jasmine.Reporter.prototype.reportRunnerStarting = function(runner) { +}; + +//noinspection JSUnusedLocalSymbols +jasmine.Reporter.prototype.reportRunnerResults = function(runner) { +}; + +//noinspection JSUnusedLocalSymbols +jasmine.Reporter.prototype.reportSuiteResults = function(suite) { +}; + +//noinspection JSUnusedLocalSymbols +jasmine.Reporter.prototype.reportSpecStarting = function(spec) { +}; + +//noinspection JSUnusedLocalSymbols +jasmine.Reporter.prototype.reportSpecResults = function(spec) { +}; + +//noinspection JSUnusedLocalSymbols +jasmine.Reporter.prototype.log = function(str) { +}; + +/** + * Blocks are functions with executable code that make up a spec. + * + * @constructor + * @param {jasmine.Env} env + * @param {Function} func + * @param {jasmine.Spec} spec + */ +jasmine.Block = function(env, func, spec) { + this.env = env; + this.func = func; + this.spec = spec; +}; + +jasmine.Block.prototype.execute = function(onComplete) { + try { + this.func.apply(this.spec); + } catch (e) { + this.spec.fail(e); + } + onComplete(); +}; +/** JavaScript API reporter. + * + * @constructor + */ +jasmine.JsApiReporter = function() { + this.started = false; + this.finished = false; + this.suites_ = []; + this.results_ = {}; +}; + +jasmine.JsApiReporter.prototype.reportRunnerStarting = function(runner) { + this.started = true; + var suites = runner.topLevelSuites(); + for (var i = 0; i < suites.length; i++) { + var suite = suites[i]; + this.suites_.push(this.summarize_(suite)); + } +}; + +jasmine.JsApiReporter.prototype.suites = function() { + return this.suites_; +}; + +jasmine.JsApiReporter.prototype.summarize_ = function(suiteOrSpec) { + var isSuite = suiteOrSpec instanceof jasmine.Suite; + var summary = { + id: suiteOrSpec.id, + name: suiteOrSpec.description, + type: isSuite ? 'suite' : 'spec', + children: [] + }; + + if (isSuite) { + var children = suiteOrSpec.children(); + for (var i = 0; i < children.length; i++) { + summary.children.push(this.summarize_(children[i])); + } + } + return summary; +}; + +jasmine.JsApiReporter.prototype.results = function() { + return this.results_; +}; + +jasmine.JsApiReporter.prototype.resultsForSpec = function(specId) { + return this.results_[specId]; +}; + +//noinspection JSUnusedLocalSymbols +jasmine.JsApiReporter.prototype.reportRunnerResults = function(runner) { + this.finished = true; +}; + +//noinspection JSUnusedLocalSymbols +jasmine.JsApiReporter.prototype.reportSuiteResults = function(suite) { +}; + +//noinspection JSUnusedLocalSymbols +jasmine.JsApiReporter.prototype.reportSpecResults = function(spec) { + this.results_[spec.id] = { + messages: spec.results().getItems(), + result: spec.results().failedCount > 0 ? "failed" : "passed" + }; +}; + +//noinspection JSUnusedLocalSymbols +jasmine.JsApiReporter.prototype.log = function(str) { +}; + +jasmine.JsApiReporter.prototype.resultsForSpecs = function(specIds){ + var results = {}; + for (var i = 0; i < specIds.length; i++) { + var specId = specIds[i]; + results[specId] = this.summarizeResult_(this.results_[specId]); + } + return results; +}; + +jasmine.JsApiReporter.prototype.summarizeResult_ = function(result){ + var summaryMessages = []; + var messagesLength = result.messages.length; + for (var messageIndex = 0; messageIndex < messagesLength; messageIndex++) { + var resultMessage = result.messages[messageIndex]; + summaryMessages.push({ + text: resultMessage.type == 'log' ? resultMessage.toString() : jasmine.undefined, + passed: resultMessage.passed ? resultMessage.passed() : true, + type: resultMessage.type, + message: resultMessage.message, + trace: { + stack: resultMessage.passed && !resultMessage.passed() ? resultMessage.trace.stack : jasmine.undefined + } + }); + } + + return { + result : result.result, + messages : summaryMessages + }; +}; + +/** + * @constructor + * @param {jasmine.Env} env + * @param actual + * @param {jasmine.Spec} spec + */ +jasmine.Matchers = function(env, actual, spec, opt_isNot) { + this.env = env; + this.actual = actual; + this.spec = spec; + this.isNot = opt_isNot || false; + this.reportWasCalled_ = false; +}; + +// todo: @deprecated as of Jasmine 0.11, remove soon [xw] +jasmine.Matchers.pp = function(str) { + throw new Error("jasmine.Matchers.pp() is no longer supported, please use jasmine.pp() instead!"); +}; + +// todo: @deprecated Deprecated as of Jasmine 0.10. Rewrite your custom matchers to return true or false. [xw] +jasmine.Matchers.prototype.report = function(result, failing_message, details) { + throw new Error("As of jasmine 0.11, custom matchers must be implemented differently -- please see jasmine docs"); +}; + +jasmine.Matchers.wrapInto_ = function(prototype, matchersClass) { + for (var methodName in prototype) { + if (methodName == 'report') continue; + var orig = prototype[methodName]; + matchersClass.prototype[methodName] = jasmine.Matchers.matcherFn_(methodName, orig); + } +}; + +jasmine.Matchers.matcherFn_ = function(matcherName, matcherFunction) { + return function() { + var matcherArgs = jasmine.util.argsToArray(arguments); + var result = matcherFunction.apply(this, arguments); + + if (this.isNot) { + result = !result; + } + + if (this.reportWasCalled_) return result; + + var message; + if (!result) { + if (this.message) { + message = this.message.apply(this, arguments); + if (jasmine.isArray_(message)) { + message = message[this.isNot ? 1 : 0]; + } + } else { + var englishyPredicate = matcherName.replace(/[A-Z]/g, function(s) { return ' ' + s.toLowerCase(); }); + message = "Expected " + jasmine.pp(this.actual) + (this.isNot ? " not " : " ") + englishyPredicate; + if (matcherArgs.length > 0) { + for (var i = 0; i < matcherArgs.length; i++) { + if (i > 0) message += ","; + message += " " + jasmine.pp(matcherArgs[i]); + } + } + message += "."; + } + } + var expectationResult = new jasmine.ExpectationResult({ + matcherName: matcherName, + passed: result, + expected: matcherArgs.length > 1 ? matcherArgs : matcherArgs[0], + actual: this.actual, + message: message + }); + this.spec.addMatcherResult(expectationResult); + return jasmine.undefined; + }; +}; + + + + +/** + * toBe: compares the actual to the expected using === + * @param expected + */ +jasmine.Matchers.prototype.toBe = function(expected) { + return this.actual === expected; +}; + +/** + * toNotBe: compares the actual to the expected using !== + * @param expected + * @deprecated as of 1.0. Use not.toBe() instead. + */ +jasmine.Matchers.prototype.toNotBe = function(expected) { + return this.actual !== expected; +}; + +/** + * toEqual: compares the actual to the expected using common sense equality. Handles Objects, Arrays, etc. + * + * @param expected + */ +jasmine.Matchers.prototype.toEqual = function(expected) { + return this.env.equals_(this.actual, expected); +}; + +/** + * toNotEqual: compares the actual to the expected using the ! of jasmine.Matchers.toEqual + * @param expected + * @deprecated as of 1.0. Use not.toEqual() instead. + */ +jasmine.Matchers.prototype.toNotEqual = function(expected) { + return !this.env.equals_(this.actual, expected); +}; + +/** + * Matcher that compares the actual to the expected using a regular expression. Constructs a RegExp, so takes + * a pattern or a String. + * + * @param expected + */ +jasmine.Matchers.prototype.toMatch = function(expected) { + return new RegExp(expected).test(this.actual); +}; + +/** + * Matcher that compares the actual to the expected using the boolean inverse of jasmine.Matchers.toMatch + * @param expected + * @deprecated as of 1.0. Use not.toMatch() instead. + */ +jasmine.Matchers.prototype.toNotMatch = function(expected) { + return !(new RegExp(expected).test(this.actual)); +}; + +/** + * Matcher that compares the actual to jasmine.undefined. + */ +jasmine.Matchers.prototype.toBeDefined = function() { + return (this.actual !== jasmine.undefined); +}; + +/** + * Matcher that compares the actual to jasmine.undefined. + */ +jasmine.Matchers.prototype.toBeUndefined = function() { + return (this.actual === jasmine.undefined); +}; + +/** + * Matcher that compares the actual to null. + */ +jasmine.Matchers.prototype.toBeNull = function() { + return (this.actual === null); +}; + +/** + * Matcher that boolean not-nots the actual. + */ +jasmine.Matchers.prototype.toBeTruthy = function() { + return !!this.actual; +}; + + +/** + * Matcher that boolean nots the actual. + */ +jasmine.Matchers.prototype.toBeFalsy = function() { + return !this.actual; +}; + + +/** + * Matcher that checks to see if the actual, a Jasmine spy, was called. + */ +jasmine.Matchers.prototype.toHaveBeenCalled = function() { + if (arguments.length > 0) { + throw new Error('toHaveBeenCalled does not take arguments, use toHaveBeenCalledWith'); + } + + if (!jasmine.isSpy(this.actual)) { + throw new Error('Expected a spy, but got ' + jasmine.pp(this.actual) + '.'); + } + + this.message = function() { + return [ + "Expected spy " + this.actual.identity + " to have been called.", + "Expected spy " + this.actual.identity + " not to have been called." + ]; + }; + + return this.actual.wasCalled; +}; + +/** @deprecated Use expect(xxx).toHaveBeenCalled() instead */ +jasmine.Matchers.prototype.wasCalled = jasmine.Matchers.prototype.toHaveBeenCalled; + +/** + * Matcher that checks to see if the actual, a Jasmine spy, was not called. + * + * @deprecated Use expect(xxx).not.toHaveBeenCalled() instead + */ +jasmine.Matchers.prototype.wasNotCalled = function() { + if (arguments.length > 0) { + throw new Error('wasNotCalled does not take arguments'); + } + + if (!jasmine.isSpy(this.actual)) { + throw new Error('Expected a spy, but got ' + jasmine.pp(this.actual) + '.'); + } + + this.message = function() { + return [ + "Expected spy " + this.actual.identity + " to not have been called.", + "Expected spy " + this.actual.identity + " to have been called." + ]; + }; + + return !this.actual.wasCalled; +}; + +/** + * Matcher that checks to see if the actual, a Jasmine spy, was called with a set of parameters. + * + * @example + * + */ +jasmine.Matchers.prototype.toHaveBeenCalledWith = function() { + var expectedArgs = jasmine.util.argsToArray(arguments); + if (!jasmine.isSpy(this.actual)) { + throw new Error('Expected a spy, but got ' + jasmine.pp(this.actual) + '.'); + } + this.message = function() { + if (this.actual.callCount === 0) { + // todo: what should the failure message for .not.toHaveBeenCalledWith() be? is this right? test better. [xw] + return [ + "Expected spy " + this.actual.identity + " to have been called with " + jasmine.pp(expectedArgs) + " but it was never called.", + "Expected spy " + this.actual.identity + " not to have been called with " + jasmine.pp(expectedArgs) + " but it was." + ]; + } else { + return [ + "Expected spy " + this.actual.identity + " to have been called with " + jasmine.pp(expectedArgs) + " but was called with " + jasmine.pp(this.actual.argsForCall), + "Expected spy " + this.actual.identity + " not to have been called with " + jasmine.pp(expectedArgs) + " but was called with " + jasmine.pp(this.actual.argsForCall) + ]; + } + }; + + return this.env.contains_(this.actual.argsForCall, expectedArgs); +}; + +/** @deprecated Use expect(xxx).toHaveBeenCalledWith() instead */ +jasmine.Matchers.prototype.wasCalledWith = jasmine.Matchers.prototype.toHaveBeenCalledWith; + +/** @deprecated Use expect(xxx).not.toHaveBeenCalledWith() instead */ +jasmine.Matchers.prototype.wasNotCalledWith = function() { + var expectedArgs = jasmine.util.argsToArray(arguments); + if (!jasmine.isSpy(this.actual)) { + throw new Error('Expected a spy, but got ' + jasmine.pp(this.actual) + '.'); + } + + this.message = function() { + return [ + "Expected spy not to have been called with " + jasmine.pp(expectedArgs) + " but it was", + "Expected spy to have been called with " + jasmine.pp(expectedArgs) + " but it was" + ]; + }; + + return !this.env.contains_(this.actual.argsForCall, expectedArgs); +}; + +/** + * Matcher that checks that the expected item is an element in the actual Array. + * + * @param {Object} expected + */ +jasmine.Matchers.prototype.toContain = function(expected) { + return this.env.contains_(this.actual, expected); +}; + +/** + * Matcher that checks that the expected item is NOT an element in the actual Array. + * + * @param {Object} expected + * @deprecated as of 1.0. Use not.toContain() instead. + */ +jasmine.Matchers.prototype.toNotContain = function(expected) { + return !this.env.contains_(this.actual, expected); +}; + +jasmine.Matchers.prototype.toBeLessThan = function(expected) { + return this.actual < expected; +}; + +jasmine.Matchers.prototype.toBeGreaterThan = function(expected) { + return this.actual > expected; +}; + +/** + * Matcher that checks that the expected item is equal to the actual item + * up to a given level of decimal precision (default 2). + * + * @param {Number} expected + * @param {Number} precision + */ +jasmine.Matchers.prototype.toBeCloseTo = function(expected, precision) { + if (!(precision === 0)) { + precision = precision || 2; + } + var multiplier = Math.pow(10, precision); + var actual = Math.round(this.actual * multiplier); + expected = Math.round(expected * multiplier); + return expected == actual; +}; + +/** + * Matcher that checks that the expected exception was thrown by the actual. + * + * @param {String} expected + */ +jasmine.Matchers.prototype.toThrow = function(expected) { + var result = false; + var exception; + if (typeof this.actual != 'function') { + throw new Error('Actual is not a function'); + } + try { + this.actual(); + } catch (e) { + exception = e; + } + if (exception) { + result = (expected === jasmine.undefined || this.env.equals_(exception.message || exception, expected.message || expected)); + } + + var not = this.isNot ? "not " : ""; + + this.message = function() { + if (exception && (expected === jasmine.undefined || !this.env.equals_(exception.message || exception, expected.message || expected))) { + return ["Expected function " + not + "to throw", expected ? expected.message || expected : "an exception", ", but it threw", exception.message || exception].join(' '); + } else { + return "Expected function to throw an exception."; + } + }; + + return result; +}; + +jasmine.Matchers.Any = function(expectedClass) { + this.expectedClass = expectedClass; +}; + +jasmine.Matchers.Any.prototype.jasmineMatches = function(other) { + if (this.expectedClass == String) { + return typeof other == 'string' || other instanceof String; + } + + if (this.expectedClass == Number) { + return typeof other == 'number' || other instanceof Number; + } + + if (this.expectedClass == Function) { + return typeof other == 'function' || other instanceof Function; + } + + if (this.expectedClass == Object) { + return typeof other == 'object'; + } + + return other instanceof this.expectedClass; +}; + +jasmine.Matchers.Any.prototype.jasmineToString = function() { + return ''; +}; + +jasmine.Matchers.ObjectContaining = function (sample) { + this.sample = sample; +}; + +jasmine.Matchers.ObjectContaining.prototype.jasmineMatches = function(other, mismatchKeys, mismatchValues) { + mismatchKeys = mismatchKeys || []; + mismatchValues = mismatchValues || []; + + var env = jasmine.getEnv(); + + var hasKey = function(obj, keyName) { + return obj != null && obj[keyName] !== jasmine.undefined; + }; + + for (var property in this.sample) { + if (!hasKey(other, property) && hasKey(this.sample, property)) { + mismatchKeys.push("expected has key '" + property + "', but missing from actual."); + } + else if (!env.equals_(this.sample[property], other[property], mismatchKeys, mismatchValues)) { + mismatchValues.push("'" + property + "' was '" + (other[property] ? jasmine.util.htmlEscape(other[property].toString()) : other[property]) + "' in expected, but was '" + (this.sample[property] ? jasmine.util.htmlEscape(this.sample[property].toString()) : this.sample[property]) + "' in actual."); + } + } + + return (mismatchKeys.length === 0 && mismatchValues.length === 0); +}; + +jasmine.Matchers.ObjectContaining.prototype.jasmineToString = function () { + return ""; +}; +// Mock setTimeout, clearTimeout +// Contributed by Pivotal Computer Systems, www.pivotalsf.com + +jasmine.FakeTimer = function() { + this.reset(); + + var self = this; + self.setTimeout = function(funcToCall, millis) { + self.timeoutsMade++; + self.scheduleFunction(self.timeoutsMade, funcToCall, millis, false); + return self.timeoutsMade; + }; + + self.setInterval = function(funcToCall, millis) { + self.timeoutsMade++; + self.scheduleFunction(self.timeoutsMade, funcToCall, millis, true); + return self.timeoutsMade; + }; + + self.clearTimeout = function(timeoutKey) { + self.scheduledFunctions[timeoutKey] = jasmine.undefined; + }; + + self.clearInterval = function(timeoutKey) { + self.scheduledFunctions[timeoutKey] = jasmine.undefined; + }; + +}; + +jasmine.FakeTimer.prototype.reset = function() { + this.timeoutsMade = 0; + this.scheduledFunctions = {}; + this.nowMillis = 0; +}; + +jasmine.FakeTimer.prototype.tick = function(millis) { + var oldMillis = this.nowMillis; + var newMillis = oldMillis + millis; + this.runFunctionsWithinRange(oldMillis, newMillis); + this.nowMillis = newMillis; +}; + +jasmine.FakeTimer.prototype.runFunctionsWithinRange = function(oldMillis, nowMillis) { + var scheduledFunc; + var funcsToRun = []; + for (var timeoutKey in this.scheduledFunctions) { + scheduledFunc = this.scheduledFunctions[timeoutKey]; + if (scheduledFunc != jasmine.undefined && + scheduledFunc.runAtMillis >= oldMillis && + scheduledFunc.runAtMillis <= nowMillis) { + funcsToRun.push(scheduledFunc); + this.scheduledFunctions[timeoutKey] = jasmine.undefined; + } + } + + if (funcsToRun.length > 0) { + funcsToRun.sort(function(a, b) { + return a.runAtMillis - b.runAtMillis; + }); + for (var i = 0; i < funcsToRun.length; ++i) { + try { + var funcToRun = funcsToRun[i]; + this.nowMillis = funcToRun.runAtMillis; + funcToRun.funcToCall(); + if (funcToRun.recurring) { + this.scheduleFunction(funcToRun.timeoutKey, + funcToRun.funcToCall, + funcToRun.millis, + true); + } + } catch(e) { + } + } + this.runFunctionsWithinRange(oldMillis, nowMillis); + } +}; + +jasmine.FakeTimer.prototype.scheduleFunction = function(timeoutKey, funcToCall, millis, recurring) { + this.scheduledFunctions[timeoutKey] = { + runAtMillis: this.nowMillis + millis, + funcToCall: funcToCall, + recurring: recurring, + timeoutKey: timeoutKey, + millis: millis + }; +}; + +/** + * @namespace + */ +jasmine.Clock = { + defaultFakeTimer: new jasmine.FakeTimer(), + + reset: function() { + jasmine.Clock.assertInstalled(); + jasmine.Clock.defaultFakeTimer.reset(); + }, + + tick: function(millis) { + jasmine.Clock.assertInstalled(); + jasmine.Clock.defaultFakeTimer.tick(millis); + }, + + runFunctionsWithinRange: function(oldMillis, nowMillis) { + jasmine.Clock.defaultFakeTimer.runFunctionsWithinRange(oldMillis, nowMillis); + }, + + scheduleFunction: function(timeoutKey, funcToCall, millis, recurring) { + jasmine.Clock.defaultFakeTimer.scheduleFunction(timeoutKey, funcToCall, millis, recurring); + }, + + useMock: function() { + if (!jasmine.Clock.isInstalled()) { + var spec = jasmine.getEnv().currentSpec; + spec.after(jasmine.Clock.uninstallMock); + + jasmine.Clock.installMock(); + } + }, + + installMock: function() { + jasmine.Clock.installed = jasmine.Clock.defaultFakeTimer; + }, + + uninstallMock: function() { + jasmine.Clock.assertInstalled(); + jasmine.Clock.installed = jasmine.Clock.real; + }, + + real: { + setTimeout: jasmine.getGlobal().setTimeout, + clearTimeout: jasmine.getGlobal().clearTimeout, + setInterval: jasmine.getGlobal().setInterval, + clearInterval: jasmine.getGlobal().clearInterval + }, + + assertInstalled: function() { + if (!jasmine.Clock.isInstalled()) { + throw new Error("Mock clock is not installed, use jasmine.Clock.useMock()"); + } + }, + + isInstalled: function() { + return jasmine.Clock.installed == jasmine.Clock.defaultFakeTimer; + }, + + installed: null +}; +jasmine.Clock.installed = jasmine.Clock.real; + +//else for IE support +jasmine.getGlobal().setTimeout = function(funcToCall, millis) { + if (jasmine.Clock.installed.setTimeout.apply) { + return jasmine.Clock.installed.setTimeout.apply(this, arguments); + } else { + return jasmine.Clock.installed.setTimeout(funcToCall, millis); + } +}; + +jasmine.getGlobal().setInterval = function(funcToCall, millis) { + if (jasmine.Clock.installed.setInterval.apply) { + return jasmine.Clock.installed.setInterval.apply(this, arguments); + } else { + return jasmine.Clock.installed.setInterval(funcToCall, millis); + } +}; + +jasmine.getGlobal().clearTimeout = function(timeoutKey) { + if (jasmine.Clock.installed.clearTimeout.apply) { + return jasmine.Clock.installed.clearTimeout.apply(this, arguments); + } else { + return jasmine.Clock.installed.clearTimeout(timeoutKey); + } +}; + +jasmine.getGlobal().clearInterval = function(timeoutKey) { + if (jasmine.Clock.installed.clearTimeout.apply) { + return jasmine.Clock.installed.clearInterval.apply(this, arguments); + } else { + return jasmine.Clock.installed.clearInterval(timeoutKey); + } +}; + +/** + * @constructor + */ +jasmine.MultiReporter = function() { + this.subReporters_ = []; +}; +jasmine.util.inherit(jasmine.MultiReporter, jasmine.Reporter); + +jasmine.MultiReporter.prototype.addReporter = function(reporter) { + this.subReporters_.push(reporter); +}; + +(function() { + var functionNames = [ + "reportRunnerStarting", + "reportRunnerResults", + "reportSuiteResults", + "reportSpecStarting", + "reportSpecResults", + "log" + ]; + for (var i = 0; i < functionNames.length; i++) { + var functionName = functionNames[i]; + jasmine.MultiReporter.prototype[functionName] = (function(functionName) { + return function() { + for (var j = 0; j < this.subReporters_.length; j++) { + var subReporter = this.subReporters_[j]; + if (subReporter[functionName]) { + subReporter[functionName].apply(subReporter, arguments); + } + } + }; + })(functionName); + } +})(); +/** + * Holds results for a set of Jasmine spec. Allows for the results array to hold another jasmine.NestedResults + * + * @constructor + */ +jasmine.NestedResults = function() { + /** + * The total count of results + */ + this.totalCount = 0; + /** + * Number of passed results + */ + this.passedCount = 0; + /** + * Number of failed results + */ + this.failedCount = 0; + /** + * Was this suite/spec skipped? + */ + this.skipped = false; + /** + * @ignore + */ + this.items_ = []; +}; + +/** + * Roll up the result counts. + * + * @param result + */ +jasmine.NestedResults.prototype.rollupCounts = function(result) { + this.totalCount += result.totalCount; + this.passedCount += result.passedCount; + this.failedCount += result.failedCount; +}; + +/** + * Adds a log message. + * @param values Array of message parts which will be concatenated later. + */ +jasmine.NestedResults.prototype.log = function(values) { + this.items_.push(new jasmine.MessageResult(values)); +}; + +/** + * Getter for the results: message & results. + */ +jasmine.NestedResults.prototype.getItems = function() { + return this.items_; +}; + +/** + * Adds a result, tracking counts (total, passed, & failed) + * @param {jasmine.ExpectationResult|jasmine.NestedResults} result + */ +jasmine.NestedResults.prototype.addResult = function(result) { + if (result.type != 'log') { + if (result.items_) { + this.rollupCounts(result); + } else { + this.totalCount++; + if (result.passed()) { + this.passedCount++; + } else { + this.failedCount++; + } + } + } + this.items_.push(result); +}; + +/** + * @returns {Boolean} True if everything below passed + */ +jasmine.NestedResults.prototype.passed = function() { + return this.passedCount === this.totalCount; +}; +/** + * Base class for pretty printing for expectation results. + */ +jasmine.PrettyPrinter = function() { + this.ppNestLevel_ = 0; +}; + +/** + * Formats a value in a nice, human-readable string. + * + * @param value + */ +jasmine.PrettyPrinter.prototype.format = function(value) { + if (this.ppNestLevel_ > 40) { + throw new Error('jasmine.PrettyPrinter: format() nested too deeply!'); + } + + this.ppNestLevel_++; + try { + if (value === jasmine.undefined) { + this.emitScalar('undefined'); + } else if (value === null) { + this.emitScalar('null'); + } else if (value === jasmine.getGlobal()) { + this.emitScalar(''); + } else if (value.jasmineToString) { + this.emitScalar(value.jasmineToString()); + } else if (typeof value === 'string') { + this.emitString(value); + } else if (jasmine.isSpy(value)) { + this.emitScalar("spy on " + value.identity); + } else if (value instanceof RegExp) { + this.emitScalar(value.toString()); + } else if (typeof value === 'function') { + this.emitScalar('Function'); + } else if (typeof value.nodeType === 'number') { + this.emitScalar('HTMLNode'); + } else if (value instanceof Date) { + this.emitScalar('Date(' + value + ')'); + } else if (value.__Jasmine_been_here_before__) { + this.emitScalar(''); + } else if (jasmine.isArray_(value) || typeof value == 'object') { + value.__Jasmine_been_here_before__ = true; + if (jasmine.isArray_(value)) { + this.emitArray(value); + } else { + this.emitObject(value); + } + delete value.__Jasmine_been_here_before__; + } else { + this.emitScalar(value.toString()); + } + } finally { + this.ppNestLevel_--; + } +}; + +jasmine.PrettyPrinter.prototype.iterateObject = function(obj, fn) { + for (var property in obj) { + if (property == '__Jasmine_been_here_before__') continue; + fn(property, obj.__lookupGetter__ ? (obj.__lookupGetter__(property) !== jasmine.undefined && + obj.__lookupGetter__(property) !== null) : false); + } +}; + +jasmine.PrettyPrinter.prototype.emitArray = jasmine.unimplementedMethod_; +jasmine.PrettyPrinter.prototype.emitObject = jasmine.unimplementedMethod_; +jasmine.PrettyPrinter.prototype.emitScalar = jasmine.unimplementedMethod_; +jasmine.PrettyPrinter.prototype.emitString = jasmine.unimplementedMethod_; + +jasmine.StringPrettyPrinter = function() { + jasmine.PrettyPrinter.call(this); + + this.string = ''; +}; +jasmine.util.inherit(jasmine.StringPrettyPrinter, jasmine.PrettyPrinter); + +jasmine.StringPrettyPrinter.prototype.emitScalar = function(value) { + this.append(value); +}; + +jasmine.StringPrettyPrinter.prototype.emitString = function(value) { + this.append("'" + value + "'"); +}; + +jasmine.StringPrettyPrinter.prototype.emitArray = function(array) { + this.append('[ '); + for (var i = 0; i < array.length; i++) { + if (i > 0) { + this.append(', '); + } + this.format(array[i]); + } + this.append(' ]'); +}; + +jasmine.StringPrettyPrinter.prototype.emitObject = function(obj) { + var self = this; + this.append('{ '); + var first = true; + + this.iterateObject(obj, function(property, isGetter) { + if (first) { + first = false; + } else { + self.append(', '); + } + + self.append(property); + self.append(' : '); + if (isGetter) { + self.append(''); + } else { + self.format(obj[property]); + } + }); + + this.append(' }'); +}; + +jasmine.StringPrettyPrinter.prototype.append = function(value) { + this.string += value; +}; +jasmine.Queue = function(env) { + this.env = env; + this.blocks = []; + this.running = false; + this.index = 0; + this.offset = 0; + this.abort = false; +}; + +jasmine.Queue.prototype.addBefore = function(block) { + this.blocks.unshift(block); +}; + +jasmine.Queue.prototype.add = function(block) { + this.blocks.push(block); +}; + +jasmine.Queue.prototype.insertNext = function(block) { + this.blocks.splice((this.index + this.offset + 1), 0, block); + this.offset++; +}; + +jasmine.Queue.prototype.start = function(onComplete) { + this.running = true; + this.onComplete = onComplete; + this.next_(); +}; + +jasmine.Queue.prototype.isRunning = function() { + return this.running; +}; + +jasmine.Queue.LOOP_DONT_RECURSE = true; + +jasmine.Queue.prototype.next_ = function() { + var self = this; + var goAgain = true; + + while (goAgain) { + goAgain = false; + + if (self.index < self.blocks.length && !this.abort) { + var calledSynchronously = true; + var completedSynchronously = false; + + var onComplete = function () { + if (jasmine.Queue.LOOP_DONT_RECURSE && calledSynchronously) { + completedSynchronously = true; + return; + } + + if (self.blocks[self.index].abort) { + self.abort = true; + } + + self.offset = 0; + self.index++; + + var now = new Date().getTime(); + if (self.env.updateInterval && now - self.env.lastUpdate > self.env.updateInterval) { + self.env.lastUpdate = now; + self.env.setTimeout(function() { + self.next_(); + }, 0); + } else { + if (jasmine.Queue.LOOP_DONT_RECURSE && completedSynchronously) { + goAgain = true; + } else { + self.next_(); + } + } + }; + self.blocks[self.index].execute(onComplete); + + calledSynchronously = false; + if (completedSynchronously) { + onComplete(); + } + + } else { + self.running = false; + if (self.onComplete) { + self.onComplete(); + } + } + } +}; + +jasmine.Queue.prototype.results = function() { + var results = new jasmine.NestedResults(); + for (var i = 0; i < this.blocks.length; i++) { + if (this.blocks[i].results) { + results.addResult(this.blocks[i].results()); + } + } + return results; +}; + + +/** + * Runner + * + * @constructor + * @param {jasmine.Env} env + */ +jasmine.Runner = function(env) { + var self = this; + self.env = env; + self.queue = new jasmine.Queue(env); + self.before_ = []; + self.after_ = []; + self.suites_ = []; +}; + +jasmine.Runner.prototype.execute = function() { + var self = this; + if (self.env.reporter.reportRunnerStarting) { + self.env.reporter.reportRunnerStarting(this); + } + self.queue.start(function () { + self.finishCallback(); + }); +}; + +jasmine.Runner.prototype.beforeEach = function(beforeEachFunction) { + beforeEachFunction.typeName = 'beforeEach'; + this.before_.splice(0,0,beforeEachFunction); +}; + +jasmine.Runner.prototype.afterEach = function(afterEachFunction) { + afterEachFunction.typeName = 'afterEach'; + this.after_.splice(0,0,afterEachFunction); +}; + + +jasmine.Runner.prototype.finishCallback = function() { + this.env.reporter.reportRunnerResults(this); +}; + +jasmine.Runner.prototype.addSuite = function(suite) { + this.suites_.push(suite); +}; + +jasmine.Runner.prototype.add = function(block) { + if (block instanceof jasmine.Suite) { + this.addSuite(block); + } + this.queue.add(block); +}; + +jasmine.Runner.prototype.specs = function () { + var suites = this.suites(); + var specs = []; + for (var i = 0; i < suites.length; i++) { + specs = specs.concat(suites[i].specs()); + } + return specs; +}; + +jasmine.Runner.prototype.suites = function() { + return this.suites_; +}; + +jasmine.Runner.prototype.topLevelSuites = function() { + var topLevelSuites = []; + for (var i = 0; i < this.suites_.length; i++) { + if (!this.suites_[i].parentSuite) { + topLevelSuites.push(this.suites_[i]); + } + } + return topLevelSuites; +}; + +jasmine.Runner.prototype.results = function() { + return this.queue.results(); +}; +/** + * Internal representation of a Jasmine specification, or test. + * + * @constructor + * @param {jasmine.Env} env + * @param {jasmine.Suite} suite + * @param {String} description + */ +jasmine.Spec = function(env, suite, description) { + if (!env) { + throw new Error('jasmine.Env() required'); + } + if (!suite) { + throw new Error('jasmine.Suite() required'); + } + var spec = this; + spec.id = env.nextSpecId ? env.nextSpecId() : null; + spec.env = env; + spec.suite = suite; + spec.description = description; + spec.queue = new jasmine.Queue(env); + + spec.afterCallbacks = []; + spec.spies_ = []; + + spec.results_ = new jasmine.NestedResults(); + spec.results_.description = description; + spec.matchersClass = null; +}; + +jasmine.Spec.prototype.getFullName = function() { + return this.suite.getFullName() + ' ' + this.description + '.'; +}; + + +jasmine.Spec.prototype.results = function() { + return this.results_; +}; + +/** + * All parameters are pretty-printed and concatenated together, then written to the spec's output. + * + * Be careful not to leave calls to jasmine.log in production code. + */ +jasmine.Spec.prototype.log = function() { + return this.results_.log(arguments); +}; + +jasmine.Spec.prototype.runs = function (func) { + var block = new jasmine.Block(this.env, func, this); + this.addToQueue(block); + return this; +}; + +jasmine.Spec.prototype.addToQueue = function (block) { + if (this.queue.isRunning()) { + this.queue.insertNext(block); + } else { + this.queue.add(block); + } +}; + +/** + * @param {jasmine.ExpectationResult} result + */ +jasmine.Spec.prototype.addMatcherResult = function(result) { + this.results_.addResult(result); +}; + +jasmine.Spec.prototype.expect = function(actual) { + var positive = new (this.getMatchersClass_())(this.env, actual, this); + positive.not = new (this.getMatchersClass_())(this.env, actual, this, true); + return positive; +}; + +/** + * Waits a fixed time period before moving to the next block. + * + * @deprecated Use waitsFor() instead + * @param {Number} timeout milliseconds to wait + */ +jasmine.Spec.prototype.waits = function(timeout) { + var waitsFunc = new jasmine.WaitsBlock(this.env, timeout, this); + this.addToQueue(waitsFunc); + return this; +}; + +/** + * Waits for the latchFunction to return true before proceeding to the next block. + * + * @param {Function} latchFunction + * @param {String} optional_timeoutMessage + * @param {Number} optional_timeout + */ +jasmine.Spec.prototype.waitsFor = function(latchFunction, optional_timeoutMessage, optional_timeout) { + var latchFunction_ = null; + var optional_timeoutMessage_ = null; + var optional_timeout_ = null; + + for (var i = 0; i < arguments.length; i++) { + var arg = arguments[i]; + switch (typeof arg) { + case 'function': + latchFunction_ = arg; + break; + case 'string': + optional_timeoutMessage_ = arg; + break; + case 'number': + optional_timeout_ = arg; + break; + } + } + + var waitsForFunc = new jasmine.WaitsForBlock(this.env, optional_timeout_, latchFunction_, optional_timeoutMessage_, this); + this.addToQueue(waitsForFunc); + return this; +}; + +jasmine.Spec.prototype.fail = function (e) { + var expectationResult = new jasmine.ExpectationResult({ + passed: false, + message: e ? jasmine.util.formatException(e) : 'Exception', + trace: { stack: e.stack } + }); + this.results_.addResult(expectationResult); +}; + +jasmine.Spec.prototype.getMatchersClass_ = function() { + return this.matchersClass || this.env.matchersClass; +}; + +jasmine.Spec.prototype.addMatchers = function(matchersPrototype) { + var parent = this.getMatchersClass_(); + var newMatchersClass = function() { + parent.apply(this, arguments); + }; + jasmine.util.inherit(newMatchersClass, parent); + jasmine.Matchers.wrapInto_(matchersPrototype, newMatchersClass); + this.matchersClass = newMatchersClass; +}; + +jasmine.Spec.prototype.finishCallback = function() { + this.env.reporter.reportSpecResults(this); +}; + +jasmine.Spec.prototype.finish = function(onComplete) { + this.removeAllSpies(); + this.finishCallback(); + if (onComplete) { + onComplete(); + } +}; + +jasmine.Spec.prototype.after = function(doAfter) { + if (this.queue.isRunning()) { + this.queue.add(new jasmine.Block(this.env, doAfter, this)); + } else { + this.afterCallbacks.unshift(doAfter); + } +}; + +jasmine.Spec.prototype.execute = function(onComplete) { + var spec = this; + if (!spec.env.specFilter(spec)) { + spec.results_.skipped = true; + spec.finish(onComplete); + return; + } + + this.env.reporter.reportSpecStarting(this); + + spec.env.currentSpec = spec; + + spec.addBeforesAndAftersToQueue(); + + spec.queue.start(function () { + spec.finish(onComplete); + }); +}; + +jasmine.Spec.prototype.addBeforesAndAftersToQueue = function() { + var runner = this.env.currentRunner(); + var i; + + for (var suite = this.suite; suite; suite = suite.parentSuite) { + for (i = 0; i < suite.before_.length; i++) { + this.queue.addBefore(new jasmine.Block(this.env, suite.before_[i], this)); + } + } + for (i = 0; i < runner.before_.length; i++) { + this.queue.addBefore(new jasmine.Block(this.env, runner.before_[i], this)); + } + for (i = 0; i < this.afterCallbacks.length; i++) { + this.queue.add(new jasmine.Block(this.env, this.afterCallbacks[i], this)); + } + for (suite = this.suite; suite; suite = suite.parentSuite) { + for (i = 0; i < suite.after_.length; i++) { + this.queue.add(new jasmine.Block(this.env, suite.after_[i], this)); + } + } + for (i = 0; i < runner.after_.length; i++) { + this.queue.add(new jasmine.Block(this.env, runner.after_[i], this)); + } +}; + +jasmine.Spec.prototype.explodes = function() { + throw 'explodes function should not have been called'; +}; + +jasmine.Spec.prototype.spyOn = function(obj, methodName, ignoreMethodDoesntExist) { + if (obj == jasmine.undefined) { + throw "spyOn could not find an object to spy upon for " + methodName + "()"; + } + + if (!ignoreMethodDoesntExist && obj[methodName] === jasmine.undefined) { + throw methodName + '() method does not exist'; + } + + if (!ignoreMethodDoesntExist && obj[methodName] && obj[methodName].isSpy) { + throw new Error(methodName + ' has already been spied upon'); + } + + var spyObj = jasmine.createSpy(methodName); + + this.spies_.push(spyObj); + spyObj.baseObj = obj; + spyObj.methodName = methodName; + spyObj.originalValue = obj[methodName]; + + obj[methodName] = spyObj; + + return spyObj; +}; + +jasmine.Spec.prototype.removeAllSpies = function() { + for (var i = 0; i < this.spies_.length; i++) { + var spy = this.spies_[i]; + spy.baseObj[spy.methodName] = spy.originalValue; + } + this.spies_ = []; +}; + +/** + * Internal representation of a Jasmine suite. + * + * @constructor + * @param {jasmine.Env} env + * @param {String} description + * @param {Function} specDefinitions + * @param {jasmine.Suite} parentSuite + */ +jasmine.Suite = function(env, description, specDefinitions, parentSuite) { + var self = this; + self.id = env.nextSuiteId ? env.nextSuiteId() : null; + self.description = description; + self.queue = new jasmine.Queue(env); + self.parentSuite = parentSuite; + self.env = env; + self.before_ = []; + self.after_ = []; + self.children_ = []; + self.suites_ = []; + self.specs_ = []; +}; + +jasmine.Suite.prototype.getFullName = function() { + var fullName = this.description; + for (var parentSuite = this.parentSuite; parentSuite; parentSuite = parentSuite.parentSuite) { + fullName = parentSuite.description + ' ' + fullName; + } + return fullName; +}; + +jasmine.Suite.prototype.finish = function(onComplete) { + this.env.reporter.reportSuiteResults(this); + this.finished = true; + if (typeof(onComplete) == 'function') { + onComplete(); + } +}; + +jasmine.Suite.prototype.beforeEach = function(beforeEachFunction) { + beforeEachFunction.typeName = 'beforeEach'; + this.before_.unshift(beforeEachFunction); +}; + +jasmine.Suite.prototype.afterEach = function(afterEachFunction) { + afterEachFunction.typeName = 'afterEach'; + this.after_.unshift(afterEachFunction); +}; + +jasmine.Suite.prototype.results = function() { + return this.queue.results(); +}; + +jasmine.Suite.prototype.add = function(suiteOrSpec) { + this.children_.push(suiteOrSpec); + if (suiteOrSpec instanceof jasmine.Suite) { + this.suites_.push(suiteOrSpec); + this.env.currentRunner().addSuite(suiteOrSpec); + } else { + this.specs_.push(suiteOrSpec); + } + this.queue.add(suiteOrSpec); +}; + +jasmine.Suite.prototype.specs = function() { + return this.specs_; +}; + +jasmine.Suite.prototype.suites = function() { + return this.suites_; +}; + +jasmine.Suite.prototype.children = function() { + return this.children_; +}; + +jasmine.Suite.prototype.execute = function(onComplete) { + var self = this; + this.queue.start(function () { + self.finish(onComplete); + }); +}; +jasmine.WaitsBlock = function(env, timeout, spec) { + this.timeout = timeout; + jasmine.Block.call(this, env, null, spec); +}; + +jasmine.util.inherit(jasmine.WaitsBlock, jasmine.Block); + +jasmine.WaitsBlock.prototype.execute = function (onComplete) { + if (jasmine.VERBOSE) { + this.env.reporter.log('>> Jasmine waiting for ' + this.timeout + ' ms...'); + } + this.env.setTimeout(function () { + onComplete(); + }, this.timeout); +}; +/** + * A block which waits for some condition to become true, with timeout. + * + * @constructor + * @extends jasmine.Block + * @param {jasmine.Env} env The Jasmine environment. + * @param {Number} timeout The maximum time in milliseconds to wait for the condition to become true. + * @param {Function} latchFunction A function which returns true when the desired condition has been met. + * @param {String} message The message to display if the desired condition hasn't been met within the given time period. + * @param {jasmine.Spec} spec The Jasmine spec. + */ +jasmine.WaitsForBlock = function(env, timeout, latchFunction, message, spec) { + this.timeout = timeout || env.defaultTimeoutInterval; + this.latchFunction = latchFunction; + this.message = message; + this.totalTimeSpentWaitingForLatch = 0; + jasmine.Block.call(this, env, null, spec); +}; +jasmine.util.inherit(jasmine.WaitsForBlock, jasmine.Block); + +jasmine.WaitsForBlock.TIMEOUT_INCREMENT = 10; + +jasmine.WaitsForBlock.prototype.execute = function(onComplete) { + if (jasmine.VERBOSE) { + this.env.reporter.log('>> Jasmine waiting for ' + (this.message || 'something to happen')); + } + var latchFunctionResult; + try { + latchFunctionResult = this.latchFunction.apply(this.spec); + } catch (e) { + this.spec.fail(e); + onComplete(); + return; + } + + if (latchFunctionResult) { + onComplete(); + } else if (this.totalTimeSpentWaitingForLatch >= this.timeout) { + var message = 'timed out after ' + this.timeout + ' msec waiting for ' + (this.message || 'something to happen'); + this.spec.fail({ + name: 'timeout', + message: message + }); + + this.abort = true; + onComplete(); + } else { + this.totalTimeSpentWaitingForLatch += jasmine.WaitsForBlock.TIMEOUT_INCREMENT; + var self = this; + this.env.setTimeout(function() { + self.execute(onComplete); + }, jasmine.WaitsForBlock.TIMEOUT_INCREMENT); + } +}; + +jasmine.version_= { + "major": 1, + "minor": 2, + "build": 0, + "revision": 1337005947 +}; diff --git a/plugins/WebApollo/tests/js_tests/spec/GFF3toJbrowseJsonSpec.js b/plugins/WebApollo/tests/js_tests/spec/GFF3toJbrowseJsonSpec.js new file mode 100644 index 0000000000..5e8d83119e --- /dev/null +++ b/plugins/WebApollo/tests/js_tests/spec/GFF3toJbrowseJsonSpec.js @@ -0,0 +1,135 @@ +describe("GFF3toJbrowseJson", function() { + // GFF3toNclist takes a data structure such as that returned by GFF3toJson.js + // and makes it into an nested containment list suitable for use in + // WebApollo and possibly Jbrowse. + + var nclistGen; + var parsedGFF3toJbrowseJsonInput, expectedJbrowseJsonOutput, actualJbrowseJsonOutput; + var gp; + + beforeEach(function() { + gp = new GFF3Parser; + nclistGen = new GFF3toJbrowseJson(); + makerGff3String = "Group1.33 maker gene 245454 247006 . + . ID=this_parent_id_12345;Name=maker-Group1%2E33-pred_gff_GNOMON-gene-4.137;\nGroup1.33 maker mRNA 245454 247006 . + . ID=1:gnomon_566853_mRNA;Parent=this_parent_id_12345;Name=gnomon_566853_mRNA;_AED=0.45;_eAED=0.45;_QI=138|1|1|1|1|1|4|191|259;\nGroup1.33 maker exon 245454 245533 . + . ID=1:gnomon_566853_mRNA:exon:5976;Parent=1:gnomon_566853_mRNA;\nGroup1.33 maker exon 245702 245879 . + . ID=1:gnomon_566853_mRNA:exon:5977;Parent=1:gnomon_566853_mRNA;\nGroup1.33 maker exon 246046 246278 . + . ID=1:gnomon_566853_mRNA:exon:5978;Parent=1:gnomon_566853_mRNA;\nGroup1.33 maker exon 246389 247006 . + . ID=1:gnomon_566853_mRNA:exon:5979;Parent=1:gnomon_566853_mRNA;\nGroup1.33 maker five_prime_UTR 245454 245533 . + . ID=1:gnomon_566853_mRNA:five_prime_utr;Parent=1:gnomon_566853_mRNA;\nGroup1.33 maker five_prime_UTR 245702 245759 . + . ID=1:gnomon_566853_mRNA:five_prime_utr;Parent=1:gnomon_566853_mRNA;\nGroup1.33 maker CDS 245760 245879 . + 0 ID=1:gnomon_566853_mRNA:cds;Parent=1:gnomon_566853_mRNA;\nGroup1.33 maker CDS 246046 246278 . + 0 ID=1:gnomon_566853_mRNA:cds;Parent=1:gnomon_566853_mRNA;\nGroup1.33 maker CDS 246389 246815 . + 1 ID=1:gnomon_566853_mRNA:cds;Parent=1:gnomon_566853_mRNA;\nGroup1.33 maker three_prime_UTR 246816 247006 . + . ID=1:gnomon_566853_mRNA:three_prime_utr;Parent=1:gnomon_566853_mRNA;\n"; + + // fixtures to test making jbrowse json from parsed GFF3 + expectedJbrowseJsonOutput = { // just putting this here for reference, I'm going to check most items in this struct manually below + "histograms" : { + "stats" : [ { + "basesPerBin" : "1000000", + "max" : 1, + "mean" : 1 + } ], + "meta" : [ { + "basesPerBin" : "1000000", + "arrayParams" : { + "length" : 1, + "chunkSize" : 10000, + "urlTemplate" : "hist-1000000-{Chunk}.json" + } + } ] + }, + "featureCount" : 1, + "intervals" : { + "nclist" : [ + [ 0, 0, 14, -1, "maker", null, "mRNA", null, "x0", "x0", + [ [ 1, 0, 3, -1, null, null, "exon", null, "p0", "p0", null ], + [ 1, 6, 9, -1, null, null, "exon", null, null, null, null ], + [ 1, 12, 14, -1, null, null, "exon", null, null, null, null ], + [ 1, 0, 14, -1, null, null, "wholeCDS", null, null, null, null ] + ] ] + ], + "classes" : [ { + "isArrayAttr" : { + "Subfeatures" : 1 + }, + "attributes" : [ "Start", "End", "Strand", "Source", "Phase", "Type", "Score", "Id", "Name", "Subfeatures" ] + }, { + "isArrayAttr" : { + }, + "attributes" : [ "Start", "End", "Strand", "Source", "Phase", "Type", "Score", "Id", "Name", "Subfeatures" ] + }, { + "isArrayAttr" : { + "Sublist" : 1 + }, + "attributes" : [ "Start", "End", "Chunk" ] + } ], + "maxEnd" : 247006, + "count" : 1, + "lazyClass" : 2, + "urlTemplate" : "lf-{Chunk}.json", + "minStart" : 245453 + }, + "formatVersion" : 1 + }; + + parsedGFF3toJbrowseJsonInput = gp.parse( makerGff3String ); + actualJbrowseJsonOutput = nclistGen.gff3toJbrowseJson(parsedGFF3toJbrowseJsonInput); + + }); + + xit("should respond to gff3toJbrowseJson", function() { + expect(nclistGen.gff3toJbrowseJson).toBeDefined(); + }); + + xit("should correctly set histograms/stats/meta in jbrowse json", function() { + expect(actualJbrowseJsonOutput["histograms"]).toEqual({"stats" : [ {"basesPerBin" : "1000000","max" : 1,"mean" : 1} ],"meta" : [ { "basesPerBin" : "1000000", "arrayParams" : { "length" : 1, "chunkSize" : 10000, "urlTemplate" : "hist-1000000-{Chunk}.json"}}]}); + }); + + xit("should correctly set featureCount in jbrowse json", function() { + expect(actualJbrowseJsonOutput["featureCount"]).toEqual(1); + }); + + xit("should correctly set ['intervals']['nclist'] in jbrowse json", function() { + expect(actualJbrowseJsonOutput["intervals"]["nclist"]).toEqual( + [0, 245454, 247006, "+", "maker", ".", "mRNA", ".", "1:gnomon_566853_mRNA", "gnomon_566853_mRNA", + [ [ 1, 0, 245454, 245533, "+", "maker", ".", "exon", ".", "1:gnomon_566853_mRNA:exon:5976", null], + [ 1, 0, 245702, 245879, "+", "maker", ".", "exon", ".", "1:gnomon_566853_mRNA:exon:5977", null] ] ] + ); + }); + + xit("should correctly set ['intervals']['classes'] in jbrowse json", function() { + expect(actualJbrowseJsonOutput["intervals"]["classes"]).toEqual( + [ { + "isArrayAttr" : { + "Subfeatures" : 1 + }, + "attributes" : [ "Start", "End", "Strand", "Source", "Phase", "Type", "Score", "Id", "Name", "Subfeatures" ] + }, { + "isArrayAttr" : { + }, + "attributes" : [ "Start", "End", "Strand", "Source", "Phase", "Type", "Score", "Id", "Name", "Subfeatures" ] + }, { + "isArrayAttr" : { + "Sublist" : 1 + }, + "attributes" : [ "Start", "End", "Chunk" ] + } ]); + + }); + + xit("should correctly set ['intervals']['maxEnd'] in jbrowse json", function() { + expect(actualJbrowseJsonOutput["intervals"]["maxEnd"]).toEqual( 245879 ); + }); + xit("should correctly set ['intervals']['count'] in jbrowse json", function() { + expect(actualJbrowseJsonOutput["intervals"]["count"]).toEqual( 1 ) + }); + + xit("should correctly set ['intervals']['lazyClass'] in jbrowse json", function() { + expect(actualJbrowseJsonOutput["intervals"]["lazyClass"]).toEqual(2) + }); + + xit("should correctly set ['intervals']['urlTemplate'] in jbrowse json", function() { + expect(actualJbrowseJsonOutput["intervals"]["urlTemplate"]).toEqual("lf-{Chunk}.json"); + }); + + xit("should correctly set ['intervals']['minStart'] in jbrowse json", function() { + expect(actualJbrowseJsonOutput["intervals"]["minStart"]).toEqual( 245454 ); + }); + + xit("should correctly set formatVersion in jbrowse json", function() { + expect(actualJbrowseJsonOutput["formatVersion"]).toEqual(1); + }); + + }); + diff --git a/plugins/WebApollo/tests/js_tests/spec/JSONUtilsSpec.js b/plugins/WebApollo/tests/js_tests/spec/JSONUtilsSpec.js new file mode 100644 index 0000000000..a9c2a9a794 --- /dev/null +++ b/plugins/WebApollo/tests/js_tests/spec/JSONUtilsSpec.js @@ -0,0 +1,130 @@ +describe("JSONUtils", function() { + /* + JSONUtils was made by Gregg/Ed to manipulate JSON data structures, especially to coerce various + kinds of JSON into JSON suitable for using with jbrowse or Webapollo. + JR added this spec file in 10/2012 to test convertParsedGFF3JsonToFeatureArray(), but we can add tests + for the other stuff in JSONUtils later too. + + convertParsedGFF3JsonToFeatureArray() + takes one feature and all of its subfeatures (children/grandchildren/great-grandchildren/...) from + a parsed GFF3 data struct (returned from GFF3toJson()), and returns a a two-level feature array for + the lowest and next-lowest level. For example, given a data struct for a parsed gene/mRNA/exon GFF3 + it would return a two-level feature array for the mRNA and all of it's exons. + + An example of input fixture is in fixtures/parsedGff3Json2FeatureArrayTest.parsedGff3Json + An example of expected output is in fixtures/parsedGff3Json2FeatureArrayTest.featureArray + + Both are basically the same as what's used in the tests below. + */ + + var jsonUtil; + var parsedGFF3StringInput, featureArrayOutput; + var parsedGFF3toJbrowseJsonInput, expectedJbrowseJsonOutput; + + beforeEach(function() { + jsonUtil = new JSONUtils(); + parsedGFF3StringInput = { + "parsedData" : [ + [{ + 'ID':'maker-Group1%2E33-pred_gff_GNOMON-gene-4.137', + 'data': ['Group1.33','maker','gene','245454','247006','.','+','.','ID=maker-Group1%2E33-pred_gff_GNOMON-gene-4.137;Name=maker-Group1%252E33-pred_gff_GNOMON-gene-4.137'], + 'children': [ + [{ + 'ID':'1:gnomon_566853_mRNA', + 'data':['Group1.33','maker','mRNA','245454','247006','.','+','.','ID=1:gnomon_566853_mRNA;Parent=maker-Group1%2E33-pred_gff_GNOMON-gene-4.137;Name=gnomon_566853_mRNA;_AED=0.45;_eAED=0.45;_QI=138|1|1|1|1|1|4|191|259'], + 'children':[ + [{'ID':'1:gnomon_566853_mRNA:exon:5976', + 'data':['Group1.33','maker','exon','245454','245533','.','+','.','ID=1:gnomon_566853_mRNA:exon:5976;Parent=1:gnomon_566853_mRNA'], + 'children':[], + }], + [{'ID':'1:gnomon_566853_mRNA:exon:5977', + 'data': ['Group1.33','maker','exon','245702','245879','.','+','.','ID=1:gnomon_566853_mRNA:exon:5977;Parent=1:gnomon_566853_mRNA'], + 'children':[],} ] + ] + }] + ]}] + ], + "parseErrors" : [""], + "parseWarnings" : [""] + }; + }); + + it("should respond to convertParsedGFF3JsonToFeatureArray", function() { + expect(jsonUtil.convertParsedGFF3JsonToFeatureArray).toBeDefined(); + }); + + it("should respond to determineParsedGff3Depth", function() { + expect(jsonUtil.determineParsedGff3Depth).toBeDefined(); + }); + + it("should properly determineParsedGff3Depth of gene/mRNA/exon parsedGFF3 struct", function() { + expect(jsonUtil.determineParsedGff3Depth( parsedGFF3StringInput ) ).toEqual( 3 ); + }); + + it("should respond to getFeatureAtGivenDepth", function() { + expect(jsonUtil.getFeatureAtGivenDepth).toBeDefined(); + }); + + it("should properly getFeatureAtGivenDepth of gene/mRNA/exon parsedGFF3 struct", function() { + expect(jsonUtil.getFeatureAtGivenDepth(parsedGFF3StringInput, 2) ).toEqual( + [ { "ID" : '1:gnomon_566853_mRNA', "data" : [ 'Group1.33', 'maker', 'mRNA', '245454', '247006', '.', '+', '.', 'ID=1:gnomon_566853_mRNA;Parent=maker-Group1%2E33-pred_gff_GNOMON-gene-4.137;Name=gnomon_566853_mRNA;_AED=0.45;_eAED=0.45;_QI=138|1|1|1|1|1|4|191|259' ], children : [ [ { "ID" : '1:gnomon_566853_mRNA:exon:5976', "data" : [ 'Group1.33', 'maker', 'exon', '245454', '245533', '.', '+', '.', 'ID=1:gnomon_566853_mRNA:exon:5976;Parent=1:gnomon_566853_mRNA' ], children : [ ] } ], [ { "ID" : '1:gnomon_566853_mRNA:exon:5977', "data" : [ 'Group1.33', 'maker', 'exon', '245702', '245879', '.', '+', '.', 'ID=1:gnomon_566853_mRNA:exon:5977;Parent=1:gnomon_566853_mRNA' ], children : [ ] } ] ] } ] + ); + }); + + it("should return an array", function() { + featureArrayOutput = jsonUtil.convertParsedGFF3JsonToFeatureArray( parsedGFF3StringInput ); + expect(featureArrayOutput).toBeDefined(); + }); + + // test parent (mRNA in this case) + it("should set first field feature array to 0", function() { + featureArrayOutput = jsonUtil.convertParsedGFF3JsonToFeatureArray( parsedGFF3StringInput ); + expect(featureArrayOutput[0]).toEqual(0); + }); + + it("should correctly set parent's Start/End/Strand/Source/Phase/Type/Score/Id/Name", function() { + featureArrayOutput = jsonUtil.convertParsedGFF3JsonToFeatureArray( parsedGFF3StringInput ); + expect(featureArrayOutput[1]).toEqual(245454); // Start + expect(featureArrayOutput[2]).toEqual(247006); //End + expect(featureArrayOutput[3]).toEqual("+"); //Strand + expect(featureArrayOutput[4]).toEqual("maker"); //Source + expect(featureArrayOutput[5]).toEqual("."); //Phase + expect(featureArrayOutput[6]).toEqual("mRNA"); //Type + expect(featureArrayOutput[7]).toEqual("."); //Score + expect(featureArrayOutput[8]).toEqual("1:gnomon_566853_mRNA"); //Id + expect(featureArrayOutput[9]).toEqual("gnomon_566853_mRNA"); //Name + }); + + it("should correctly first child's Start/End/Strand/Source/Phase/Type/Score/Id/Name", function() { + // first child + featureArrayOutput = jsonUtil.convertParsedGFF3JsonToFeatureArray( parsedGFF3StringInput ); + expect(featureArrayOutput[10][0][0]).toEqual(1); // ? + expect(featureArrayOutput[10][0][1]).toEqual(245454); // Start + expect(featureArrayOutput[10][0][2]).toEqual(245533); //End + expect(featureArrayOutput[10][0][3]).toEqual("+"); //Strand + expect(featureArrayOutput[10][0][4]).toEqual("maker"); //Source + expect(featureArrayOutput[10][0][5]).toEqual("."); //Phase + expect(featureArrayOutput[10][0][6]).toEqual("exon"); //Type + expect(featureArrayOutput[10][0][7]).toEqual("."); //Score + expect(featureArrayOutput[10][0][8]).toEqual("1:gnomon_566853_mRNA:exon:5976"); //Id + expect(featureArrayOutput[10][0][9]).toEqual(null); //Name + }); + + it("should correctly second child's Start/End/Strand/Source/Phase/Type/Score/Id/Name", function() { + // second child + featureArrayOutput = jsonUtil.convertParsedGFF3JsonToFeatureArray( parsedGFF3StringInput ); + expect(featureArrayOutput[10].length).toEqual(2); // should actually be a second child + expect(featureArrayOutput[10][1][0]).toEqual(1); // ? + expect(featureArrayOutput[10][1][1]).toEqual(245702); // Start + expect(featureArrayOutput[10][1][2]).toEqual(245879); //End + expect(featureArrayOutput[10][1][3]).toEqual("+"); //Strand + expect(featureArrayOutput[10][1][4]).toEqual("maker"); //Source + expect(featureArrayOutput[10][1][5]).toEqual("."); //Phase + expect(featureArrayOutput[10][1][6]).toEqual("exon"); //Type + expect(featureArrayOutput[10][1][7]).toEqual("."); //Score + expect(featureArrayOutput[10][1][8]).toEqual("1:gnomon_566853_mRNA:exon:5977"); //Id + expect(featureArrayOutput[10][1][9]).toEqual(null); //Name + }); + + }); + diff --git a/plugins/WebApollo/tests/perl_tests/flatfile-to-json.pl.t b/plugins/WebApollo/tests/perl_tests/flatfile-to-json.pl.t new file mode 100644 index 0000000000..6eea2cb27a --- /dev/null +++ b/plugins/WebApollo/tests/perl_tests/flatfile-to-json.pl.t @@ -0,0 +1,283 @@ +use strict; +use warnings; + +use JBlibs; + +use Test::More; +use Test::Warn; + +use Bio::JBrowse::Cmd::FlatFileToJson; + +use File::Spec::Functions qw( catfile catdir ); +use File::Temp (); +use File::Copy::Recursive 'dircopy'; + +use lib '../../tests/perl_tests/lib'; +use FileSlurping 'slurp'; + +sub run_with(@) { + #system $^X, 'bin/flatfile-to-json.pl', @_; + #ok( ! $?, 'flatfile-to-json.pl ran ok' ); + my @args = @_; + warnings_are { + Bio::JBrowse::Cmd::FlatFileToJson->new( @args )->run; + } [], 'ran without warnings'; +} + +sub tempdir { + my $tempdir = File::Temp->newdir( CLEANUP => $ENV{KEEP_ALL} ? 0 : 1 ); + #diag "using temp dir $tempdir"; + return $tempdir; +} + +{ #diag "running on volvox"; + + my $tempdir = tempdir(); + my $read_json = sub { slurp( $tempdir, @_ ) }; + dircopy( 'tests/data/volvox_formatted_refseqs', $tempdir ); + + run_with ( + '--out' => $tempdir, + '--bed' => 'sample_data/raw/volvox/volvox-remark.bed', + '--trackLabel' => 'ExampleFeatures', + '--key' => 'Example Features', + '--autocomplete' => 'all', + '--cssClass' => 'feature2', + '--clientConfig' => '{"featureCss": "height: 8px;", "histScale": 2}', + '--urltemplate' => 'http://example.com/{name}/{start}/{end}', + ); + + #system "find $tempdir -type f"; + #die 'break'; + + run_with ( + '--out' => $tempdir, + '--gff' => 'sample_data/raw/volvox/volvox.gff3', + '--trackLabel' => 'CDS', + '--key' => 'Predicted genes', + '--type' => 'CDS:predicted,mRNA:exonerate,mRNA:predicted', + '--autocomplete' => 'all', + '--cssClass' => 'cds', + '--compress', + '--getPhase', + '--getSubfeatures', + ); + + my $hist_output = $read_json->(qw( tracks ExampleFeatures ctgA hist-10000-0.json )); + is_deeply( $hist_output, [4,3,4,3,4,1], 'got right histogram output for ExampleFeatures' ) or diag explain( $hist_output ); + + my $names_output = $read_json->(qw( tracks ExampleFeatures ctgA names.json )); + is_deeply( $names_output->[3], + [ + [ + 'f05' + ], + 'ExampleFeatures', + 'f05', + 'ctgA', + 4715, + 5968, + undef + ], + 'got the right names output' + ) or diag explain $names_output; + + my $cds_trackdata = $read_json->(qw( tracks CDS ctgA trackData.jsonz )); + is( $cds_trackdata->{featureCount}, 3, 'got right feature count for CDS track' ) or diag explain $cds_trackdata; + is( scalar( @{$cds_trackdata->{histograms}{meta}}), + scalar( @{$cds_trackdata->{histograms}{stats}}), + 'have stats for each precalculated hist' ); + + is( ref $cds_trackdata->{intervals}{nclist}[2][10], 'ARRAY', 'exonerate mRNA has its subfeatures' ) + or diag explain $cds_trackdata; + is( scalar @{$cds_trackdata->{intervals}{nclist}[2][10]}, 5, 'exonerate mRNA has 5 subfeatures' ); + + my $tracklist = $read_json->('trackList.json'); + is_deeply( $tracklist->{tracks}[1]{style}, + { featureCss => 'height: 8px;', + histScale => 2, + className => 'feature2', + linkTemplate => 'http://example.com/{name}/{start}/{end}' + }, + '--clientConfig and --urltemplate options seem to work' + ) or diag explain $tracklist; + + #system "find $tempdir"; +} + +{# diag "running on single_au9_gene.gff3, testing --type filtering"; + + my $tempdir = tempdir(); + dircopy( 'tests/data/AU9', $tempdir ); + + run_with ( + '--out' => $tempdir, + '--gff' => "tests/data/AU9/single_au9_gene.gff3", + '--trackLabel' => 'AU_mRNA', + '--key' => 'AU mRNA', + '--type' => 'mRNA', + '--autocomplete' => 'all', + '--cssClass' => 'transcript', + '--getPhase', + '--getSubfeatures', + ); + + #system "find $tempdir"; + + my $read_json = sub { slurp( $tempdir, @_ ) }; + my $cds_trackdata = $read_json->(qw( tracks AU_mRNA Group1.33 trackData.json )); + is( $cds_trackdata->{featureCount}, 1, 'got right feature count' ) or diag explain $cds_trackdata; + is( ref $cds_trackdata->{intervals}{nclist}[0][10], 'ARRAY', 'mRNA has its subfeatures' ) + or diag explain $cds_trackdata; + is( scalar @{$cds_trackdata->{intervals}{nclist}[0][10]}, 7, 'mRNA has 7 subfeatures' ); + + my $tracklist = $read_json->( 'trackList.json' ); + is( $tracklist->{tracks}[0]{key}, 'AU mRNA', 'got a tracklist' ) or diag explain $tracklist; + is_deeply( $tracklist->{tracks}[0]{style}, { className => 'transcript' }, 'got the right style' ) or diag explain $tracklist; + + # run it again with a different CSS class, check that it updated + run_with ( + '--out' => $tempdir, + '--gff' => "tests/data/AU9/single_au9_gene.gff3", + '--trackLabel' => 'AU_mRNA', + '--key' => 'AU mRNA', + '--type' => 'mRNA', + '--autocomplete' => 'all', + '--cssClass' => 'foo_fake_class', + '--getPhase', + '--getSubfeatures', + ); + + $tracklist = $read_json->( 'trackList.json' ); + is( $tracklist->{tracks}[0]{key}, 'AU mRNA', 'got a tracklist' ); + is_deeply( $tracklist->{tracks}[0]{style}, { className => 'foo_fake_class'}, 'got the right style' ); + + # check that we got the same data as before + $cds_trackdata = $read_json->(qw( tracks AU_mRNA Group1.33 trackData.json )); + is( $cds_trackdata->{featureCount}, 1, 'got right feature count' ) or diag explain $cds_trackdata; + is( ref $cds_trackdata->{intervals}{nclist}[0][10], 'ARRAY', 'mRNA has its subfeatures' ) + or diag explain $cds_trackdata; + is( scalar @{$cds_trackdata->{intervals}{nclist}[0][10]}, 7, 'mRNA has 7 subfeatures' ); +} + +{ #diag "running on single_au9_gene.gff3, testing that we emit 2 levels of subfeatures"; + + my $tempdir = tempdir(); + dircopy( 'tests/data/AU9', $tempdir ); + + run_with ( + '--out' => $tempdir, + '--gff' => "tests/data/AU9/single_au9_gene.gff3", + '--trackLabel' => 'AU_mRNA', + '--key' => 'AU mRNA', + '--type' => 'gene', + '--autocomplete' => 'all', + '--cssClass' => 'transcript', + '--getPhase', + '--getSubfeatures', + ); + + #system "find $tempdir"; + + my $read_json = sub { slurp( $tempdir, @_ ) }; + my $cds_trackdata = $read_json->(qw( tracks AU_mRNA Group1.33 trackData.json )); + is( $cds_trackdata->{featureCount}, 1, 'got right feature count' ) or diag explain $cds_trackdata; + is( ref $cds_trackdata->{intervals}{nclist}[0][10], 'ARRAY', 'gene has its subfeatures' ) + or diag explain $cds_trackdata; + is( scalar @{$cds_trackdata->{intervals}{nclist}[0][10]}, 1, 'gene has 1 subfeature' ); + is( ref $cds_trackdata->{intervals}{nclist}[0][10][0][10], 'ARRAY', 'mRNA has its subfeatures' ) + or diag explain $cds_trackdata; + is( scalar @{$cds_trackdata->{intervals}{nclist}[0][10][0][10]}, 7, 'mRNA has 7 subfeatures' ); +} + +for my $testfile ( "tests/data/au9_scaffold_subset.gff3", "tests/data/au9_scaffold_subset_sync.gff3" ) { + # add a test for duplicate lazyclasses bug found by Gregg + + my $tempdir = tempdir(); + dircopy( 'tests/data/AU9', $tempdir ); + run_with ( + '--out' => $tempdir, + '--gff' => $testfile, + '--arrowheadClass' => 'transcript-arrowhead', + '--getSubfeatures', + '--subfeatureClasses' => '{"CDS": "transcript-CDS", "UTR": "transcript-UTR", "exon":"transcript-exon", "three_prime_UTR":"transcript-three_prime_UTR", "five_prime_UTR":"transcript-five_prime_UTR", "stop_codon":null, "start_codon":null}', + '--cssClass' => 'transcript', + '--type' => 'mRNA', + '--trackLabel' => 'au9_full1', + ); + + my $read_json = sub { slurp( $tempdir, @_ ) }; + my $cds_trackdata = $read_json->(qw( tracks au9_full1 Group1.33 trackData.json )); + is( $cds_trackdata->{featureCount}, 28, 'got right feature count' ) or diag explain $cds_trackdata; + is( scalar @{$cds_trackdata->{intervals}{classes}}, 3, 'got the right number of classes' ) + or diag explain $cds_trackdata->{intervals}{classes}; + + #system "find $tempdir"; +} + +{ + # test for warnings + my $tempdir = tempdir(); + run_with ( + '--out' => $tempdir, + '--gff' => catfile('tests','data','SL2.40ch10_sample.gff3'), + '--compress', + '--key' => 'Assembly', + '--trackLabel' => 'assembly', + ); + my $read_json = sub { slurp( $tempdir, @_ ) }; + my $trackdata = FileSlurping::slurp_tree( catdir( $tempdir, qw( tracks assembly SL2.40ch10 ))); + is( scalar( grep @{$trackdata->{$_}} == 0, + grep /^lf/, + keys %$trackdata + ), + 0, + 'no empty chunks in trackdata' + ) or diag explain $trackdata; +} + +{ #diag "running on Group1.33_Amel_4.5.maker.gff with --webApollo flag, test for webapollo friendly nclist attribute, CDS features combined into wholeCDS features, and UTR features merged into an exon features"; + + my $tempdir = tempdir(); + dircopy( 'tests/data/MAKER', $tempdir ); + + run_with ( + '--out' => $tempdir, + '--gff' => 'tests/data/MAKER/Group1.33_Amel_4.5.maker.gff', + '--arrowheadClass' => 'trellis-arrowhead', + '--getSubs', + '--subfeatureClasses' => '{"CDS": "ogsv3-CDS", "UTR": "ogsv3-UTR", "exon":"ogsv3-exon", "wholeCDS":null}', + '--cssClass' => 'refseq-transcript', + '--type' => 'mRNA', + '--trackLabel' => 'just_maker_singleton', + '--webApollo', + '--renderClassName' => 'ogsv3-transcript-render' + ); + + my $read_json = sub { slurp( $tempdir, @_ ) }; + my $track_data = $read_json->(qw( tracks just_maker_singleton Group1.33 trackData.json )); + my $track_list = $read_json->(qw( trackList.json )); + + # make sure we got rid of CDS features + my @CDSfeat = grep {$_->[6] eq 'CDS' } @{$track_data->{'intervals'}->{'nclist'}->[0]->[10]}; + ok(scalar @CDSfeat == 0, '--webApollo flag gets rid of CDS features'); + + # check wholeCDS + my @wholeCDSfeat = grep {$_->[6] eq 'wholeCDS' } @{$track_data->{'intervals'}->{'nclist'}->[0]->[10]}; + ok(scalar @wholeCDSfeat == 1, '--webApollo flag causes wholeCDS feature to be created'); + is_deeply( $wholeCDSfeat[0], [ 1, 245759, 246815, 1, 'maker', 0, "wholeCDS", undef, '1:gnomon_566853_mRNA:cds', undef, [] ], + 'got the right wholeCDS feature' + ) or diag explain $wholeCDSfeat[0]; + + my @utr_feats = grep {$_->[6] =~ '((five|three)_prime_)*UTR$' } @{$track_data->{'intervals'}->{'nclist'}->[0]->[10]}; + ok( scalar @utr_feats == 0, '--webApollo flag gets rid of UTR and five|three_prime_UTR features'); + + # check for "renderClassName" : "ogsv3-transcript-render" keyval in mRNA feature + ok($track_list->{'tracks'}->[3]->{'style'}->{'renderClassName'} eq 'ogsv3-transcript-render', '--renderClassName ogsv3-transcript-render flag puts "renderClassName" : "ogsv3-transcript-render" into mRNA feature'); + + # check for "type" values are changed from "FeatureTrack" to "DraggableFeatureTrack" in mRNA feature + ok($track_list->{'tracks'}->[3]->{'type'} eq 'DraggableFeatureTrack','--webApollo flag changes type values to DraggableFeatureTrack in mRNA feature'); + +} + +done_testing; diff --git a/plugins/WebApollo/tests/selenium_tests/lib/WebApolloTest.py b/plugins/WebApollo/tests/selenium_tests/lib/WebApolloTest.py new file mode 100644 index 0000000000..941bc13eb3 --- /dev/null +++ b/plugins/WebApollo/tests/selenium_tests/lib/WebApolloTest.py @@ -0,0 +1,35 @@ +import os +import sys +import time +sys.path.append( 'tests/selenium_tests' ) # relative to JBrowse root + +from jbrowse_selenium import JBrowseTest + +class WebApolloTest (JBrowseTest): + + wa_url = None + + def setUp( self ): + super( WebApolloTest, self ).setUp() + self.login( os.environ['WA_USER'], os.environ['WA_PASS'] ) + self.browser.get( self.baseURL() ) + + def baseURL( self ): + return self.waURL()+'/jbrowse/index.html' + + def waURL( self ): + if not self.wa_url: + self.wa_url = os.environ['WA_URL'] + return self.wa_url + + def login( self, username, password ): + self.browser.get( self.waURL() + '/Login' ); + username_input = self.assert_element('//input[@id="username"]') + password_input = self.assert_element('//input[@id="password"]') + username_input.send_keys(username) + password_input.send_keys(password) + login_button = self.assert_element('//button[@id="login_button"]') + login_button.click() + time.sleep( 0.4 ) + pass + diff --git a/plugins/WebApollo/tests/selenium_tests/lib/__init__.py b/plugins/WebApollo/tests/selenium_tests/lib/__init__.py new file mode 100644 index 0000000000..101831e276 --- /dev/null +++ b/plugins/WebApollo/tests/selenium_tests/lib/__init__.py @@ -0,0 +1,2 @@ +from WebApolloTest import WebApolloTest + diff --git a/plugins/WebApollo/tests/selenium_tests/pythium_test.py b/plugins/WebApollo/tests/selenium_tests/pythium_test.py new file mode 100644 index 0000000000..fd7decd1e9 --- /dev/null +++ b/plugins/WebApollo/tests/selenium_tests/pythium_test.py @@ -0,0 +1,29 @@ +import unittest +from lib import WebApolloTest; + +class PythiumTest(WebApolloTest, unittest.TestCase): + + data_dir = 'sample_data/json/volvox' + + def setUp( self ): + # call( "rm -rf sample_data/json/volvox/", shell=True ) + # call( "bin/prepare-refseqs.pl --fasta docs/tutorial/data_files/volvox.fa --out sample_data/json/volvox/", shell=True ) + # call( "bin/biodb-to-json.pl --conf docs/tutorial/conf_files/volvox.json --out sample_data/json/volvox/", shell=True ) + # call( "bin/wig-to-json.pl --out sample_data/json/volvox/ --wig docs/tutorial/data_files/volvox_microarray.wig", shell=True ) + # call( "bin/add-track-json.pl sample_data/raw/volvox/volvox_microarray.bw.conf sample_data/json/volvox/trackList.json", shell=True ) + # call( "bin/add-track-json.pl sample_data/raw/volvox/volvox-sorted.bam.conf sample_data/json/volvox/trackList.json", shell=True ) + # call( "bin/add-track-json.pl sample_data/raw/volvox/volvox-sorted.bam.coverage.conf sample_data/json/volvox/trackList.json", shell=True ) + # call( "bin/generate-names.pl --dir sample_data/json/volvox/", shell=True ) + super( PythiumTest, self ).setUp() + + + def test_pythium( self ): + test_ref = 'scf1117875582023'; + # select "ctgA from the dropdown + self.select_refseq( test_ref ) + + # check a good browser title + assert test_ref in self.browser.title, "browser title is actually %s" % self.browser.title + + self.browser.close() + diff --git a/release-notes.txt b/release-notes.txt index 793eb5a643..aef241053b 100644 --- a/release-notes.txt +++ b/release-notes.txt @@ -1,5 +1,94 @@ {{$NEXT}} + * Added a timeout to HTMLFeatures and Alignments tracks to prevent + data-heavy tracks (like BAM tracks with very deep coverage) from + freezing or crashing a user's browser. + + * Greatly improved speed and responsiveness of BAM data backend. + + * Added support in HTMLFeatures and Alignments tracks for a + `style.featureScale` configuration variable, which, if set, + specifies a minimum zoom scale (pixels per basepair) for displaying + features. If zoomed out more than this (i.e. fewer pixels per bp), + either histograms or a "too many features" message will be + displayed. + +1.7.6 2013-01-10 01:25:58 America/New_York + + * Fixed a bug in the BAM direct-access backend that prevented some + BAM files from being displayed. + +1.7.5 2012-12-12 13:40:12 America/New_York + + * Fixed a bug in which typing a key that is bound to a global + keyboard shortcut (currently only 't' or '?') in the location box + would erroneously execute the action for that global shortcut. + Thanks to Gregor Rot for pointing this out. + + * Fixed a bug in which toggling 'Show labels' in the track menu did + not re-layout the track on the first toggling. + + * Make columns in the faceted track selector initially each be an + equal percentage of the total width of the grid. Thanks to Steffi + Geisen for pointing this out. + +1.7.4 2012-12-06 23:08:22 America/New_York + + * Fixed a bug preventing loading of JBrowse in some browsers. Thanks + to Steffi Geisen for pointing this out. + + * Fixed a bug in the BigWig data backend that prevented some BigWig + files with large numbers of reference sequences from displaying. + Thanks to Gregg Helt for providing sample data to help isolate + this. + + * Fixed a bug in the BigWig data backend that prevented BigWig files + rendering in Safari. Thanks to Gregor Rot for his help in isolating this. + + * Worked around a bug in Safari 6 (and probably earlier) in which + HTTP byte-range requests are erroneously cached. Thanks to Gregor + Rot for pointing out the Safari problems. + + * Fixed some minor styling bugs in the facet menus of the faceted + track selector. + + * Fixed blurry edges of location trapezoid in Firefox (Eric Derohanian). + +1.7.3 2012-11-28 23:29:48 America/New_York + + * Fixed several more bugs in the BAM data backend that prevented + display of some BAM files. Thanks to Gleb Kuznetzov for help in + isolating these. + + * Fixed bug in display of faceted track selector in which the facet + titles were taking up too much vertical height. Thanks to Steffi + Geisen for pointing this out. + + * "Alignments" tracks now parse an alignment's CIGAR string if it + does not have an MD field, and display mismatches and skipped + sequence regions (particularly important for RNA-seq alignments). + Thanks to Gregg Helt for providing the sample dataset used to test + this. + + * Added support for a `showReverseStrand` config variable to Sequence + track that, if set to false, turns off display of the reverse + sequence strand. + + * "Alignments" tracks now show reads with missing mate pairs with a + red crosshatched pattern instead of with a red border. + + * Added an Apache .htaccess file to the JBrowse root directory that + enabled CORS by default for all files under it, if AllowOverride is + on. + + * Fixed bug in which the vertical scroll position can sometimes be + set too far down when zooming in and out. + + * Fixed some bugs in server-side formatting code for feature tracks: + data was recorded multiple times in JSON files in some + circumstances. Thanks to Volodymyr Zavidovych and Steffi Geisen + for pointing this out. + 1.7.2 2012-11-09 15:40:06 America/New_York * Fixed more bugs in BAM backends that failed to load some types of diff --git a/setup.sh b/setup.sh index 08b5034bee..23161ef6ef 100755 --- a/setup.sh +++ b/setup.sh @@ -10,6 +10,20 @@ done_message () { fi } +echo > setup.log; + +# log information about this system +( + echo '============== System information ===='; + set -x; + lsb_release -a; + uname -a; + sw_vers; + system_profiler; + grep MemTotal /proc/meminfo; + echo; echo; +) >>setup.log 2>&1; + echo -n "Installing Perl prerequisites ..." if ! ( perl -MExtUtils::MakeMaker -e 1 >/dev/null 2>&1); then echo; @@ -20,7 +34,7 @@ fi; bin/cpanm -v --notest -l extlib/ --installdeps . < /dev/null; set -e; bin/cpanm -v --notest -l extlib/ --installdeps . < /dev/null; -) >setup.log 2>&1; +) >>setup.log 2>&1; done_message "" "As a first troubleshooting step, make sure development libraries and header files for GD, Zlib, and libpng are installed and try again."; echo diff --git a/src/JBrowse/Browser.js b/src/JBrowse/Browser.js index 3d34dced1b..938c7539ad 100644 --- a/src/JBrowse/Browser.js +++ b/src/JBrowse/Browser.js @@ -1,7 +1,18 @@ var _gaq = _gaq || []; // global task queue for Google Analytics +require( { + packages: [ 'dijit', 'dojox', 'jszlib', + { name: 'lazyload', main: 'lazyload' }, + 'dgrid', 'xstyle', 'put-selector' + ] + }, + [], + function() { define( [ 'dojo/_base/lang', + 'dojo/on', + 'dojo/_base/Deferred', + 'dojo/DeferredList', 'dojo/topic', 'dojo/aspect', 'dojo/_base/array', @@ -11,16 +22,29 @@ define( [ 'dijit/form/ComboBox', 'dijit/form/Button', 'dijit/form/Select', + 'dijit/form/DropDownButton', + 'dijit/DropDownMenu', + 'dijit/MenuItem', 'JBrowse/Util', 'JBrowse/Store/LazyTrie', - 'JBrowse/Store/Autocomplete', + 'JBrowse/Store/Names/LazyTrieDojoData', + 'dojo/store/DataStore', + 'JBrowse/Store/Names/Hash', 'JBrowse/GenomeView', 'JBrowse/TouchScreenSupport', 'JBrowse/ConfigManager', - 'JBrowse/View/InfoDialog' + 'JBrowse/View/InfoDialog', + 'JBrowse/View/FileDialog', + 'JBrowse/View/LocationChoiceDialog', + 'dijit/focus', + 'lazyload', // for dynamic CSS loading + 'dojo/domReady!' ], function( lang, + on, + Deferred, + DeferredList, topic, aspect, array, @@ -30,13 +54,22 @@ define( [ dijitComboBox, dijitButton, dijitSelectBox, + dijitDropDownButton, + dijitDropDownMenu, + dijitMenuItem, Util, LazyTrie, - AutocompleteStore, + NamesLazyTrieDojoDataStore, + DojoDataStore, + NamesHashStore, GenomeView, Touch, ConfigManager, - InfoDialog + InfoDialog, + FileDialog, + LocationChoiceDialog, + dijitFocus, + LazyLoad ) { var dojof = Util.dojof; @@ -62,9 +95,7 @@ var dojof = Util.dojof; */ var Browser = function(params) { - this.deferredFunctions = []; this.globalKeyboardShortcuts = {}; - this.isInitialized = false; this.config = params; if( ! this.config.baseUrl ) @@ -76,19 +107,45 @@ var Browser = function(params) { this.container.onselectstart = function() { return false; }; this.container.genomeBrowser = this; - // init our touch device support - this.addDeferred( Touch.loadTouch ); - // schedule the config load, the first step in the initialization // process, to happen when the page is done loading - dojo.addOnLoad( dojo.hitch( this,'loadConfig' ) ); - dojo.connect( this, 'onConfigLoaded', Util.debugHandler( this, 'loadUserCSS' )); - dojo.connect( this, 'onConfigLoaded', Util.debugHandler( this, 'loadRefSeqs' )); - dojo.connect( this, 'onConfigLoaded', Util.debugHandler( this, 'loadNames' )); - dojo.connect( this, 'onRefSeqsLoaded', Util.debugHandler( this, 'initView' )); - dojo.connect( this, 'onRefSeqsLoaded', Util.debugHandler( this, 'reportUsageStats' )); - dojo.connect( this, 'onRefSeqsLoaded', Util.debugHandler( this, 'initPlugins' )); + var thisB = this; + dojo.addOnLoad( function() { + thisB.loadConfig().then( function() { + thisB.loadNames(); + thisB.loadUserCSS().then( function() { + thisB.initPlugins().then( function() { + thisB.initTrackMetadata(); + thisB.loadRefSeqs().then( function() { + thisB.initView().then( function() { + Touch.loadTouch(); // init touch device support + thisB.navigateTo( thisB._initialLocation() ); + thisB.passMilestone( 'completely initialized', { success: true } ); + }); + thisB.reportUsageStats(); + }); + }); + }); + }); + }); +}; + +Browser.prototype._initialLocation = function() { + var oldLocMap = dojo.fromJson( this.cookie('location') ) || {}; + if( this.config.location ) { + return this.config.location; + } else if( oldLocMap[this.refSeq.name] ) { + return oldLocMap[this.refSeq.name].l || oldLocMap[this.refSeq.name]; + } else if( this.config.defaultLocation ){ + return this.config.defaultLocation; + } else { + return Util.assembleLocString({ + ref: this.refSeq.name, + start: 0.4 * ( this.refSeq.start + this.refSeq.end ), + end: 0.6 * ( this.refSeq.start + this.refSeq.end ) + }); + } }; Browser.prototype.version = function() { @@ -96,34 +153,92 @@ Browser.prototype.version = function() { return BUILD_SYSTEM_JBROWSE_VERSION || 'development'; }.call(); + +/** + * Get a plugin, if it is present. Note that, if plugin + * initialization is not yet complete, it may be a while before the + * callback is called. + * + * Callback is called with one parameter, the desired plugin object, + * or undefined if it does not exist. + */ +Browser.prototype.getPlugin = function( name, callback ) { + this.afterMilestone( 'initPlugins', dojo.hitch( this, function() { + callback( this.plugins[name] ); + })); +}; + /** * Load and instantiate any plugins defined in the configuration. */ Browser.prototype.initPlugins = function() { - var plugins = this.config.plugins; + return this._milestoneFunction( 'initPlugins', function( deferred ) { + this.plugins = {}; + var plugins = this.config.plugins || []; - // coerce plugins to array of objects - plugins = array.map( dojo.isArray(plugins) ? plugins : [plugins], function( p ) { - return typeof p == 'object' ? p : { 'class_': p }; - }); + if( ! plugins ) { + deferred.resolve({success: true}); + return; + } - var pluginClasses = array.map( plugins, function( p ) { - return p.class_; - }); + // coerce plugins to array of objects + plugins = array.map( dojo.isArray(plugins) ? plugins : [plugins], function( p ) { + return typeof p == 'object' ? p : { 'name': p }; + }); - this.plugins = []; + var pluginNames = array.map( plugins, function( p ) { + return p.name; + }); - require( pluginClasses, dojo.hitch( this, function() { - array.forEach( arguments, function( pluginClass, i ) { - this.plugins.push( - new pluginClass( - dojo.mixin( dojo.clone( plugins[i] ), { browser: this } ) - ) - ); - }, this ); + var pluginDeferreds = array.map( plugins, function(p) { + return new Deferred(); + }); + + // fire the "all plugins done" deferred when all of the plugins are done loading + (new DeferredList( pluginDeferreds )) + .then( function() { deferred.resolve({success: true}); }); + + require( { + packages: array.map( pluginNames, function(c) { return { name: c, location: "../plugins/"+c+"/js" }; }) + }, + pluginNames, + dojo.hitch( this, function() { + array.forEach( arguments, function( pluginClass, i ) { + var pluginName = pluginNames[i]; + var thisPluginDone = pluginDeferreds[i]; + if( typeof pluginClass == 'string' ) { + console.error("could not load plugin "+pluginName+": "+pluginClass); + } else { + // make the plugin's arguments out of + // its little obj in 'plugins', and + // also anything in the top-level + // conf under its plugin name + var args = dojo.mixin( + dojo.clone( plugins[i] ), + this.config[pluginName]||{}); + args.browser = this; + args = dojo.mixin( args, { browser: this } ); + + // load its css + this._loadCSS( + {url: 'plugins/'+pluginName+'/css/main.css'}, + function() { + thisPluginDone.resolve({success:true}); + }, + function() { + // succeed loading even if the css load failed. not all plugins necessarily have css + thisPluginDone.resolve({success:true}); + } + ); + + // instantiate the plugin + var plugin = new pluginClass( args ); + this.plugins[ pluginName ] = plugin; + } + }, this ); + })); + }); - console.log( this.plugins ); - })); }; /** @@ -167,21 +282,24 @@ Browser.prototype.fatalError = function( error ) { }; Browser.prototype.loadRefSeqs = function() { - // load our ref seqs - if( typeof this.config.refSeqs == 'string' ) - this.config.refSeqs = { url: this.config.refSeqs }; - dojo.xhrGet( - { - url: this.config.refSeqs.url, - handleAs: 'json', - load: dojo.hitch( this, function(o) { - this.addRefseqs(o); - this.onRefSeqsLoaded(); - }), - error: dojo.hitch( this, function(e) { - this.fatalError('Failed to load reference sequence info: '+e); - }) - }); + return this._milestoneFunction( 'loadRefSeqs', function( deferred ) { + // load our ref seqs + if( typeof this.config.refSeqs == 'string' ) + this.config.refSeqs = { url: this.config.refSeqs }; + dojo.xhrGet( + { + url: this.config.refSeqs.url, + handleAs: 'json', + load: dojo.hitch( this, function(o) { + this.addRefseqs( o ); + deferred.resolve({success:true}); + }), + error: dojo.hitch( this, function(e) { + this.fatalError('Failed to load reference sequence info: '+e); + deferred.resolve({ success: false, error: e }); + }) + }); + }); }; /** @@ -190,149 +308,382 @@ Browser.prototype.loadRefSeqs = function() { Browser.prototype.onRefSeqsLoaded = function() {}; Browser.prototype.loadUserCSS = function() { - if( this.config.css && ! dojo.isArray( this.config.css ) ) - this.config.css = [ this.config.css ]; - dojo.forEach( this.config.css || [], function(css) { + return this._milestoneFunction( 'loadUserCSS', function( deferred ) { + if( this.config.css && ! dojo.isArray( this.config.css ) ) + this.config.css = [ this.config.css ]; + + var css = this.config.css || []; + if( ! css.length ) { + deferred.resolve({success:true}); + return; + } + + var that = this; + var cssDeferreds = array.map( css, function( css ) { + var d = new Deferred(); + that._loadCSS( + css, + function() { d.resolve({success:true}); }, + function() { d.resolve({success:false}); } + ); + return d; + }); + + new DeferredList(cssDeferreds) + .then( function() { deferred.resolve({success:true}); } ); + }); +}; + +Browser.prototype._loadCSS = function( css, successCallback, errorCallback ) { if( typeof css == 'string' ) { - dojo.create('style', { type: 'text/css', innerHTML: css }, this.container ); - } else if( typeof css == 'object' ) { - dojo.create('link', { rel: 'stylesheet', href: css.url, type: 'text/css'}, document.head ); + // if it has '{' in it, it probably is not a URL, but is a string of CSS statements + if( css.indexOf('{') > -1 ) { + dojo.create('style', { "data-from": 'JBrowse Config', type: 'text/css', innerHTML: css }, document.head ); + successCallback && successCallback(); + } + // otherwise, it must be a URL + else { + css = { url: css }; + } + } + if( typeof css == 'object' ) { + LazyLoad.css( css.url, successCallback ); } - },this); }; /** * Load our name index. */ Browser.prototype.loadNames = function() { - // load our name index - if (this.config.nameUrl) - this.names = new LazyTrie(this.config.nameUrl, "lazy-{Chunk}.json"); + return this._milestoneFunction( 'loadNames', function( deferred ) { + var conf = dojo.mixin( dojo.clone( this.config.names || {} ), + this.config.autocomplete || {} ); + if( ! conf.url ) + conf.url = this.config.nameUrl || 'data/names/'; + + if( conf.baseUrl ) + conf.url = Util.resolveUrl( conf.baseUrl, conf.url ); + + if( conf.type == 'Hash' ) + this.nameStore = new NamesHashStore( dojo.mixin({ browser: this }, conf) ); + else + // wrap the older LazyTrieDojoDataStore with + // dojo.store.DataStore to conform with the dojo/store API + this.nameStore = new DojoDataStore({ + store: new NamesLazyTrieDojoDataStore({ + browser: this, + namesTrie: new LazyTrie( conf.url, "lazy-{Chunk}.json"), + stopPrefixes: conf.stopPrefixes, + resultLimit: conf.resultLimit || 15, + tooManyMatchesMessage: conf.tooManyMatchesMessage + }) + }); + + deferred.resolve({success: true}); + }); }; Browser.prototype.initView = function() { - //set up top nav/overview pane and main GenomeView pane - dojo.addClass(document.body, this.config.theme || "tundra"); - - var topPane = dojo.create( 'div',{ style: {overflow: 'hidden'}}, this.container ); - - var overview = dojo.create( 'div', { className: 'overview', id: 'overview' }, topPane ); - // overview=0 hides the overview, but we still need it to exist - if( ! this.config.show_overview ) - overview.style.cssText = "display: none"; - - if( this.config.show_nav ) - this.navbox = this.createNavBox( topPane ); - - // make our little top-links box with links to help, etc. - var linkContainer = dojo.create('div', { className: 'topLink' }); - dojo.create('a', { - className: 'powered_by', - innerHTML: 'JBrowse', - href: 'http://jbrowse.org', - title: 'powered by JBrowse' - }, linkContainer ); - - if( this.config.show_nav && this.config.show_tracklist && this.config.show_overview ) - linkContainer.appendChild( this.makeShareLink() ); - else - linkContainer.appendChild( this.makeFullViewLink() ); - - if( this.config.show_nav ) - linkContainer.appendChild( this.makeHelpDialog() ); - - ( this.config.show_nav ? this.navbox : this.container ).appendChild( linkContainer ); - - - this.viewElem = document.createElement("div"); - this.viewElem.className = "dragWindow"; - this.container.appendChild( this.viewElem); - - this.containerWidget = new dijitBorderContainer({ - liveSplitters: false, - design: "sidebar", - gutters: false - }, this.container); - var contentWidget = - new dijitContentPane({region: "top"}, topPane); - - //create location trapezoid - if( this.config.show_nav ) { - this.locationTrap = dojo.create('div', {className: 'locationTrap'}, topPane ); - this.locationTrap.className = "locationTrap"; - } + var thisObj = this; + return this._milestoneFunction('initView', function( deferred ) { + + //set up top nav/overview pane and main GenomeView pane + dojo.addClass( this.container, "jbrowse"); // browser container has an overall .jbrowse class + dojo.addClass( document.body, this.config.theme || "tundra"); //< tundra dijit theme - // hook up GenomeView - this.view = this.viewElem.view = - new GenomeView(this, this.viewElem, 250, this.refSeq, 1/200, - this.config.browserRoot); - dojo.connect( this.view, "onFineMove", this, "onFineMove" ); - dojo.connect( this.view, "onCoarseMove", this, "onCoarseMove" ); - - this.browserWidget = - new dijitContentPane({region: "center"}, this.viewElem); - dojo.connect( this.browserWidget, "resize", this, 'onResize' ); - dojo.connect( this.browserWidget, "resize", this.view, 'onResize' ); - - // (this stuff below is just a callback pyramid to make it synchronous) - // init the track metadata - this.initTrackMetadata( dojo.hitch(this, function() { - //set up the track list - this.createTrackList( dojo.hitch( this, function(){ - this.containerWidget.startup(); - this.onResize(); - this.view.onResize(); - - //set initial location - var oldLocMap = dojo.fromJson( this.cookie('location') ) || {}; - if (this.config.location) { - this.navigateTo(this.config.location); - } else if (oldLocMap[this.refSeq.name]) { - this.navigateTo( oldLocMap[this.refSeq.name].l || oldLocMap[this.refSeq.name] ); - } else if (this.config.defaultLocation){ - this.navigateTo(this.config.defaultLocation); - } else { - this.navigateTo( Util.assembleLocString({ - ref: this.refSeq.name, - start: 0.4 * ( this.refSeq.start + this.refSeq.end ), - end: 0.6 * ( this.refSeq.start + this.refSeq.end ) - }) - ); + var topPane = dojo.create( 'div',{ style: {overflow: 'hidden'}}, this.container ); + + // make our top menu bar + var menuBar = dojo.create( + 'div', + { + className: this.config.show_nav ? 'menuBar' : 'topLink' + } + ); + thisObj.menuBar = menuBar; + ( this.config.show_nav ? topPane : this.container ).appendChild( menuBar ); + + var overview = dojo.create( 'div', { className: 'overview', id: 'overview' }, topPane ); + this.overviewDiv = overview; + // overview=0 hides the overview, but we still need it to exist + if( ! this.config.show_overview ) + overview.style.cssText = "display: none"; + + if( this.config.show_nav ) + this.navbox = this.createNavBox( topPane ); + + // make our little top-links box with links to help, etc. + this.poweredByLink = dojo.create('a', { + className: 'powered_by', + innerHTML: 'JBrowse', + href: 'http://jbrowse.org', + title: 'powered by JBrowse' + }, menuBar ); + + if( this.config.show_nav ) { + + this.addGlobalMenuItem( 'file', + new dijitMenuItem( + { + label: 'Open', + iconClass: 'dijitIconFolderOpen', + onClick: dojo.hitch( this, 'openFileDialog' ) + }) + ); + var fileMenu = this.makeGlobalMenu('file'); + if( fileMenu ) { + var fileButton = new dijitDropDownButton( + { className: 'file', + innerHTML: 'File', + //title: '', + dropDown: fileMenu + }); + dojo.addClass( fileButton.domNode, 'menu' ); + menuBar.appendChild( fileButton.domNode ); } - // make our global keyboard shortcut handler - dojo.connect( document.body, 'onkeypress', this, 'globalKeyHandler' ); + var configMenu = this.makeGlobalMenu('options'); + if( configMenu ) { + var configLink = new dijitDropDownButton( + { className: 'config', + innerHTML: ' Options', + title: 'configure JBrowse', + dropDown: configMenu + }); + menuBar.appendChild( configLink.domNode ); + } + } - // configure our event routing - this._initEventRouting(); + if( this.config.show_nav && this.config.show_tracklist && this.config.show_overview ) + menuBar.appendChild( this.makeShareLink() ); + else + menuBar.appendChild( this.makeFullViewLink() ); + + if( this.config.show_nav ) + menuBar.appendChild( this.makeHelpDialog() ); + + this.viewElem = document.createElement("div"); + this.viewElem.className = "dragWindow"; + this.container.appendChild( this.viewElem); + + this.containerWidget = new dijitBorderContainer({ + liveSplitters: false, + design: "sidebar", + gutters: false + }, this.container); + var contentWidget = + new dijitContentPane({region: "top"}, topPane); + + // hook up GenomeView + this.view = this.viewElem.view = + new GenomeView(this, this.viewElem, 250, this.refSeq, 1/200 ); + + dojo.connect( this.view, "onFineMove", this, "onFineMove" ); + dojo.connect( this.view, "onCoarseMove", this, "onCoarseMove" ); + + this.browserWidget = + new dijitContentPane({region: "center"}, this.viewElem); + dojo.connect( this.browserWidget, "resize", this, 'onResize' ); + dojo.connect( this.browserWidget, "resize", this.view, 'onResize' ); + + //set initial location + this.afterMilestone( 'loadRefSeqs', dojo.hitch( this, function() { + this.afterMilestone( 'initTrackMetadata', dojo.hitch( this, function() { + this.createTrackList().then( dojo.hitch( this, function() { + + this.containerWidget.startup(); + this.onResize(); + this.view.onResize(); + + // make our global keyboard shortcut handler + on( document.body, 'keypress', dojo.hitch( this, 'globalKeyHandler' )); + + // configure our event routing + this._initEventRouting(); + + // done with initView + deferred.resolve({ success: true }); + })); + })); + })); + }); +}; - this.isInitialized = true; - //if someone calls methods on this browser object - //before it's fully initialized, then we defer - //those functions until now - dojo.forEach( this.deferredFunctions, function(f) { - f.call(this); - },this ); +/** + * Track type registry, used by GUI elements that need to offer + * options regarding selecting track types. Can register a track + * type, and get the data structure describing what track types are + * known. + */ +Browser.prototype.registerTrackType = function( args ) { - this.deferredFunctions = []; - })); - })); + var types = this.getTrackTypes(); + var typeName = args.type; + var defaultFor = args.defaultForStoreTypes || []; + var humanLabel = args.label; + + // add it to known track types + types.knownTrackTypes.push( typeName ); + + // add its label + if( args.label ) + types.trackTypeLabels[typeName] = args.label; + + // uniqify knownTrackTypes + var seen = {}; + types.knownTrackTypes = array.filter( types.knownTrackTypes, function( type ) { + var s = seen[type]; + seen[type] = true; + return !s; + }); + + // set it as default for the indicated types, if any + array.forEach( defaultFor, function( storeName ) { + types.trackTypeDefaults[storeName] = typeName; + }); + + // store the whole structure in this object + this._knownTrackTypes = types; +}; +Browser.prototype.getTrackTypes = function() { + // create the default types if necessary + if( ! this._knownTrackTypes ) + this._knownTrackTypes = { + // map of store type -> default track type to use for the store + trackTypeDefaults: { + 'JBrowse/Store/SeqFeature/BAM' : 'JBrowse/View/Track/Alignments', + 'JBrowse/Store/SeqFeature/NCList' : 'JBrowse/View/Track/HTMLFeatures', + 'JBrowse/Store/SeqFeature/BigWig' : 'JBrowse/View/Track/Wiggle/XYPlot', + 'JBrowse/Store/Sequence/StaticChunked': 'JBrowse/View/Track/Sequence' + }, + + knownTrackTypes: [ + 'JBrowse/View/Track/Alignments', + 'JBrowse/View/Track/FeatureCoverage', + 'JBrowse/View/Track/HTMLFeatures', + 'JBrowse/View/Track/Wiggle/XYPlot', + 'JBrowse/View/Track/Wiggle/Density', + 'JBrowse/View/Track/Sequence' + ], + + trackTypeLabels: { + } + }; + + return this._knownTrackTypes; +}; + + + +Browser.prototype.openFileDialog = function() { + new FileDialog({ browser: this }) + .show({ + openCallback: dojo.hitch( this, function( results ) { + var confs = results.trackConfs || []; + if( confs.length ) { + + // tuck away each of the store configurations in + // our store configuration, and replace them with + // their names. + array.forEach( confs, function( conf ) { + var storeConf = conf.store; + if( storeConf && typeof storeConf == 'object' ) { + delete conf.store; + var name = this._addStoreConfig( storeConf.name, storeConf ); + conf.store = name; + } + },this); + + // send out a message about how the user wants to create the new tracks + this.publish( '/jbrowse/v1/v/tracks/new', confs ); + + // if requested, send out another message that the user wants to show them + if( results.trackDisposition == 'openImmediately' ) + this.publish( '/jbrowse/v1/v/tracks/show', confs ); + } + }) + }); +}; + +Browser.prototype.addTracks = function( confs ) { + // just register the track configurations right now + this._addTrackConfigs( confs ); +}; +Browser.prototype.replaceTracks = function( confs ) { + // just add-or-replace the track configurations + this._replaceTrackConfigs( confs ); +}; +Browser.prototype.deleteTracks = function( confs ) { + // de-register the track configurations + this._deleteTrackConfigs( confs ); +}; + + +Browser.prototype.makeGlobalMenu = function( menuName ) { + var items = ( this._globalMenuItems || {} )[menuName] || []; + if( ! items.length ) + return null; + + var menu = new dijitDropDownMenu({ leftClickToOpen: true }); + dojo.forEach( items, function( item ) { + menu.addChild( item ); + }); + dojo.addClass( menu.domNode, 'globalMenu' ); + menu.startup(); + return menu; +}; + +Browser.prototype.addGlobalMenuItem = function( menuName, item ) { + if( ! this._globalMenuItems ) + this._globalMenuItems = {}; + if( ! this._globalMenuItems[ menuName ] ) + this._globalMenuItems[ menuName ] = []; + this._globalMenuItems[ menuName ].push( item ); }; /** - * Initialize our event routing, which is mostly echoing logical - * commands from the user interacting with the views. + * Initialize our message routing, subscribing to messages, forwarding + * them around, and so forth. + * + * "v" (view) + * Requests from the user. These go only to the browser, which is + * the central point forx deciding what to do about them. This is + * usually just forwarding the command as one or more "c" messages. + * + * "c" (command) + * Commands from authority, like the Browser object. These cause + * things to actually happen in the UI: things to be shown or + * hidden, actions taken, and so forth. + * + * "n" (notification) + * Notification that something just happened. + * * @private */ Browser.prototype._initEventRouting = function() { - this.subscribe('/jbrowse/v1/v/tracks/hide', dojo.hitch( this, function( trackConfigs ) { - this.publish( '/jbrowse/v1/c/tracks/hide', trackConfigs ); - })); - this.subscribe('/jbrowse/v1/v/tracks/show', dojo.hitch( this, function( trackConfigs ) { - this.addRecentlyUsedTracks( dojo.map(trackConfigs, function(c){ return c.label;}) ); - this.publish( '/jbrowse/v1/c/tracks/show', trackConfigs ); - })); + var that = this; + + that.subscribe('/jbrowse/v1/v/tracks/hide', function( trackConfigs ) { + that.publish( '/jbrowse/v1/c/tracks/hide', trackConfigs ); + }); + that.subscribe('/jbrowse/v1/v/tracks/show', function( trackConfigs ) { + that.addRecentlyUsedTracks( dojo.map(trackConfigs, function(c){ return c.label;}) ); + that.publish( '/jbrowse/v1/c/tracks/show', trackConfigs ); + }); + + that.subscribe('/jbrowse/v1/v/tracks/new', function( trackConfigs ) { + that.addTracks( trackConfigs ); + that.publish( '/jbrowse/v1/c/tracks/new', trackConfigs ); + }); + that.subscribe('/jbrowse/v1/v/tracks/replace', function( trackConfigs ) { + that.replaceTracks( trackConfigs ); + that.publish( '/jbrowse/v1/c/tracks/replace', trackConfigs ); + }); + that.subscribe('/jbrowse/v1/v/tracks/delete', function( trackConfigs ) { + that.deleteTracks( trackConfigs ); + that.publish( '/jbrowse/v1/c/tracks/delete', trackConfigs ); + }); }; /** @@ -421,7 +772,7 @@ Browser.prototype.getStore = function( storeName, callback ) { } require( [ storeClassName ], dojo.hitch( this, function( storeClass ) { - var storeArgs = dojo.mixin( dojo.clone(conf), + var storeArgs = dojo.mixin( conf, { browser: this, refSeq: this.refSeq @@ -432,6 +783,28 @@ Browser.prototype.getStore = function( storeName, callback ) { })); }; +/** + * Add a store configuration to the browser. If name is falsy, will + * autogenerate one. + * @private + */ +var uniqCounter = 0; +Browser.prototype._addStoreConfig = function( /**String*/ name, /**Object*/ storeConfig ) { + name = name || 'addStore'+uniqCounter++; + + if( ! this.config.stores ) + this.config.stores = {}; + if( ! this._storeCache ) + this._storeCache = {}; + + if( this.config.stores[name] || this._storeCache[name] ) { + throw "store "+name+" already exists!"; + } + + this.config.stores[name] = storeConfig; + return name; +}; + Browser.prototype.clearStores = function() { this._storeCache = {}; }; @@ -474,6 +847,7 @@ Browser.prototype._calculateClientStats = function() { '+' ), 'tracks-count': this.config.tracks.length, + 'plugins': dojof.keys( this.plugins ).sort().join(','), // screen geometry 'scn-h': scn ? scn.height : null, @@ -553,6 +927,65 @@ Browser.prototype.addRecentlyUsedTracks = function( trackLabels ) { return newRecent; }; +/** + * Run a function that will eventually resolve the named Deferred + * (milestone). + * @param {String} name the name of the Deferred + */ +Browser.prototype._milestoneFunction = function( /**String*/ name, func ) { + + var thisB = this; + var args = Array.prototype.slice.call( arguments, 2 ); + + var d = thisB._getDeferred( name ); + args.unshift( d ); + try { + func.apply( thisB, args ) ; + } catch(e) { + console.error(''+e, e.stack); + d.resolve({ success:false, error: e }); + } + + return d; +}; + +/** + * Fetch or create a named Deferred, which is how milestones are implemented. + */ +Browser.prototype._getDeferred = function( name ) { + if( ! this._deferred ) + this._deferred = {}; + return this._deferred[name] = this._deferred[name] || new Deferred(); +}; +/** + * Attach a callback to a milestone. + */ +Browser.prototype.afterMilestone = function( name, func ) { + return this._getDeferred(name) + .then( function() { + try { + func(); + } catch( e ) { + console.error( ''+e, e.stack, e ); + } + }); +}; +/** + * Indicate that we've reached a milestone in the initalization + * process. Will run all the callbacks associated with that + * milestone. + */ +Browser.prototype.passMilestone = function( name, result ) { + return this._getDeferred(name).resolve( result ); +}; +/** + * Return true if we have reached the named milestone, false otherwise. + */ +Browser.prototype.reachedMilestone = function( name ) { + return this._getDeferred(name).fired >= 0; +}; + + /** * Load our configuration file(s) based on the parameters thex * constructor was passed. Does not return until all files are @@ -560,18 +993,94 @@ Browser.prototype.addRecentlyUsedTracks = function( trackLabels ) { * @returns nothing meaningful */ Browser.prototype.loadConfig = function () { - var c = new ConfigManager({ config: this.config, defaults: this._configDefaults(), browser: this }); - c.getFinalConfig( dojo.hitch(this, function( finishedConfig ) { + return this._milestoneFunction( 'loadConfig', function( deferred ) { + var c = new ConfigManager({ config: this.config, defaults: this._configDefaults(), browser: this }); + c.getFinalConfig( dojo.hitch(this, function( finishedConfig ) { this.config = finishedConfig; - // index the track configurations by name - this.trackConfigsByName = {}; - dojo.forEach( this.config.tracks || [], function(conf){ - this.trackConfigsByName[conf.label] = conf; + // pass the tracks configurations through + // addTrackConfigs so that it will be indexed and such + var tracks = finishedConfig.tracks || []; + delete finishedConfig.tracks; + this._addTrackConfigs( tracks ); + + // coerce some config keys to boolean + dojo.forEach( ['show_tracklist','show_nav','show_overview'], function(v) { + this.config[v] = this._coerceBoolean( this.config[v] ); },this); - this.onConfigLoaded(); - })); + // set empty tracks array if we have none + if( ! this.config.tracks ) + this.config.tracks = []; + + deferred.resolve({success:true}); + })); + }); +}; + +/** + * Add new track configurations. + * @private + */ +Browser.prototype._addTrackConfigs = function( /**Array*/ configs ) { + + if( ! this.config.tracks ) + this.config.tracks = []; + if( ! this.trackConfigsByName ) + this.trackConfigsByName = {}; + + array.forEach( configs, function(conf){ + + // if( this.trackConfigsByName[ conf.label ] ) { + // console.warn("track with label "+conf.label+" already exists, skipping"); + // return; + // } + + this.trackConfigsByName[conf.label] = conf; + this.config.tracks.push( conf ); + + },this); + + return configs; +}; +/** + * Replace existing track configurations. + * @private + */ +Browser.prototype._replaceTrackConfigs = function( /**Array*/ newConfigs ) { + if( ! this.trackConfigsByName ) + this.trackConfigsByName = {}; + + array.forEach( newConfigs, function( conf ) { + if( ! this.trackConfigsByName[ conf.label ] ) { + console.warn("track with label "+conf.label+" does not exist yet. creating a new one."); + } + + this.trackConfigsByName[conf.label] = + dojo.mixin( this.trackConfigsByName[ conf.label ] || {}, conf ); + },this); +}; +/** + * Delete existing track configs. + * @private + */ +Browser.prototype._deleteTrackConfigs = function( configsToDelete ) { + // remove from this.config.tracks + this.config.tracks = array.filter( this.config.tracks || [], function( conf ) { + return ! array.some( configsToDelete, function( toDelete ) { + return toDelete.label == conf.label; + }); + }); + + // remove from trackConfigsByName + array.forEach( configsToDelete, function( toDelete ) { + if( ! this.trackConfigsByName[ toDelete.label ] ) { + console.warn( "track "+toDelete.label+" does not exist, cannot delete" ); + return; + } + + delete this.trackConfigsByName[ toDelete.label ]; + },this); }; Browser.prototype._configDefaults = function() { @@ -583,20 +1092,6 @@ Browser.prototype._configDefaults = function() { }; }; -/** - * Hook run after the configuration is all loaded. - */ -Browser.prototype.onConfigLoaded = function() { - // coerce some config keys to boolean - dojo.forEach( ['show_tracklist','show_nav','show_overview'], function(v) { - this.config[v] = this._coerceBoolean( this.config[v] ); - },this); - - // set empty tracks array if we have none - if( ! this.config.tracks ) - this.config.tracks = []; -}; - /** * Coerce a value of unknown type to a boolean, treating string 'true' * and 'false' as the values they indicate, and string numbers as @@ -625,17 +1120,6 @@ Browser.prototype._coerceBoolean = function(val) { } }; -/** - * Add a function to be executed once JBrowse is initialized - * @param f function to be executed - */ -Browser.prototype.addDeferred = function(f) { - if (this.isInitialized) - f(); - else - this.deferredFunctions.push(f); -}; - /** * @param refSeqs {Array} array of refseq records to add to the browser */ @@ -680,22 +1164,12 @@ Browser.prototype.onFineMove = function(startbp, endbp) { * this.view.overviewBox.w) + this.view.overviewBox.l); var trapRight = Math.round((((endbp - this.view.ref.start) / length) * this.view.overviewBox.w) + this.view.overviewBox.l); - - var locationTrapStyle = dojo.isIE - ? "top: " + this.view.overviewBox.t + "px;" - + "height: " + this.view.overviewBox.h + "px;" - + "left: " + trapLeft + "px;" - + "width: " + (trapRight - trapLeft) + "px;" - + "border-width: 0px" - : "top: " + this.view.overviewBox.t + "px;" - + "height: " + this.view.overviewBox.h + "px;" - + "left: " + this.view.overviewBox.l + "px;" - + "width: " + (trapRight - trapLeft) + "px;" - + "border-width: " + "0px " - + (this.view.overviewBox.w - trapRight) + "px " - + this.view.locationTrapHeight + "px " + trapLeft + "px;"; - - this.locationTrap.style.cssText = locationTrapStyle; + dojo.style( this.locationTrap, { + width: (trapRight - trapLeft) + "px", + borderBottomWidth: this.view.locationTrapHeight + "px", + borderLeftWidth: trapLeft + "px", + borderRightWidth: (this.view.overviewBox.w - trapRight) + "px" + }); } }; @@ -703,96 +1177,98 @@ Browser.prototype.onFineMove = function(startbp, endbp) { * Asynchronously initialize our track metadata. */ Browser.prototype.initTrackMetadata = function( callback ) { - var metaDataSourceClasses = dojo.map( - (this.config.trackMetadata||{}).sources || [], - function( sourceDef ) { - var url = sourceDef.url || 'trackMeta.csv'; - var type = sourceDef.type || ( - /\.csv$/i.test(url) ? 'csv' : - /\.js(on)?$/i.test(url) ? 'json' : - 'csv' - ); - var storeClass = sourceDef['class'] - || { csv: 'dojox/data/CsvStore', json: 'dojox/data/JsonRestStore' }[type]; - if( !storeClass ) { - console.error( "No store class found for type '" - +type+"', cannot load track metadata from URL "+url); - return null; - } - return { class_: storeClass, url: url }; - }); - - - require( Array.prototype.concat.apply( ['JBrowse/Store/TrackMetaData'], - dojo.map( metaDataSourceClasses, function(c) { return c.class_; } ) ), - dojo.hitch(this,function( MetaDataStore ) { - var mdStores = []; - for( var i = 1; inavigateToLocation(), except it attempts to display the given + * location with a little bit of flanking sequence to each side, if + * possible. + */ +Browser.prototype.showRegion = function( location ) { + var flank = Math.round( ( location.end - location.start ) * 0.2 ); + //go to location, with some flanking region + this.navigateToLocation({ ref: location.ref, + start: location.start - flank, + end: location.end + flank + }); + + // if the location has a track associated with it, show it + if( location.tracks ) { + this.showTracks( array.map( location.tracks, function( t ) { return t && (t.label || t.name) || t; } )); + } +}; + /** * navigate to a given location * @example @@ -816,46 +1312,43 @@ Browser.prototype.onVisibleTracksChanged = function() { */ Browser.prototype.navigateTo = function(loc) { - if (!this.isInitialized) { - this.deferredFunctions.push(function() { this.navigateTo(loc); }); - return; - } - - // if it's a foo:123..456 location, go there - var location = Util.parseLocString( loc ); - if( location ) { - this.navigateToLocation( location ); - } - // otherwise, if it's just a word, try to figure out what it is - else { - - // is it just the name of one of our ref seqs? - var ref = Util.matchRefSeqName( loc, this.allRefs ); - if( ref ) { - // see if we have a stored location for this ref seq in a - // cookie, and go there if we do - var oldLoc; - try { - oldLoc = Util.parseLocString( - dojo.fromJson( - this.cookie("location") - )[ref.name].l - ); - oldLoc.ref = ref.name; // force the refseq name; older cookies don't have it - } catch (x) {} - if( oldLoc ) { - this.navigateToLocation( oldLoc ); - return; - } else { - // if we don't just go to the middle 80% of that refseq - this.navigateToLocation({ref: ref.name, start: ref.end*0.1, end: ref.end*0.9 }); - return; - } + this.afterMilestone( 'completely initialized', dojo.hitch( this, function() { + // if it's a foo:123..456 location, go there + var location = typeof loc == 'string' ? Util.parseLocString( loc ) : loc; + if( location ) { + this.navigateToLocation( location ); } + // otherwise, if it's just a word, try to figure out what it is + else { + + // is it just the name of one of our ref seqs? + var ref = Util.matchRefSeqName( loc, this.allRefs ); + if( ref ) { + // see if we have a stored location for this ref seq in a + // cookie, and go there if we do + var oldLoc; + try { + oldLoc = Util.parseLocString( + dojo.fromJson( + this.cookie("location") + )[ref.name].l + ); + oldLoc.ref = ref.name; // force the refseq name; older cookies don't have it + } catch (x) {} + if( oldLoc ) { + this.navigateToLocation( oldLoc ); + return; + } else { + // if we don't just go to the middle 80% of that refseq + this.navigateToLocation({ref: ref.name, start: ref.end*0.1, end: ref.end*0.9 }); + return; + } + } - // lastly, try to search our feature names for it - this.searchNames( loc ); - } + // lastly, try to search our feature names for it + this.searchNames( loc ); + } + })); }; // given an object like { ref: 'foo', start: 2, end: 100 }, set the @@ -879,10 +1372,13 @@ Browser.prototype.navigateToLocation = function( location ) { // if it's the same sequence, just go there if( location.ref == this.refSeq.name) { + this.view.setLocation( this.refSeq, location.start, location.end ); + this._updateLocationCookies( location ); + } // if different, we need to poke some other things before going there else { @@ -895,6 +1391,8 @@ Browser.prototype.navigateToLocation = function( location ) { this.view.setLocation( this.refSeq, location.start, location.end ); + this._updateLocationCookies( location ); + this.showTracks( curTracks ); } @@ -906,44 +1404,56 @@ Browser.prototype.navigateToLocation = function( location ) { * view location to any that match. */ Browser.prototype.searchNames = function( /**String*/ loc ) { - var brwsr = this; - this.names.exactMatch( loc, function(nameMatches) { - var goingTo, - i; + var thisB = this; + this.nameStore.query({ name: loc }) + .then( function( nameMatches ) { + + // if we have no matches, pop up a dialog saying so, and + // do nothing more + if( ! nameMatches.length ) { + new InfoDialog( + { + title: 'Not found', + content: 'Not found: '+loc+'', + className: 'notfound-dialog' + }).show(); + return; + } - var post1_4 = typeof nameMatches[0][0] == 'string'; + var goingTo; //first check for exact case match - for (i = 0; i < nameMatches.length; i++) { - if (nameMatches[i][ post1_4 ? 0 : 1 ] == loc) + for (var i = 0; i < nameMatches.length; i++) { + if( nameMatches[i].name == loc ) goingTo = nameMatches[i]; } //if no exact case match, try a case-insentitive match - if (!goingTo) { - for (i = 0; i < nameMatches.length; i++) { - if (nameMatches[i][ post1_4 ? 0 : 1].toLowerCase() == loc.toLowerCase()) + if( !goingTo ) { + for( i = 0; i < nameMatches.length; i++ ) { + if( nameMatches[i].name.toLowerCase() == loc.toLowerCase() ) goingTo = nameMatches[i]; } } //else just pick a match - if (!goingTo) goingTo = nameMatches[0]; - var startbp = parseInt( goingTo[ post1_4 ? 4 : 3 ]); - var endbp = parseInt( goingTo[ post1_4 ? 5 : 4 ]); - var flank = Math.round((endbp - startbp) * .2); - //go to location, with some flanking region - brwsr.navigateTo( goingTo[ post1_4 ? 3 : 2] - + ":" + (startbp - flank) - + ".." + (endbp + flank)); - brwsr.showTracks(brwsr.names.extra[nameMatches[0][ post1_4 ? 1 : 0 ]]); - }, - // if no match for the name is found, show a popup dialog saying this. - function() { - new InfoDialog( - { - title: 'Not found', - content: 'Not found: '+loc+'', - className: 'notfound-dialog' - }).show(); + if( !goingTo ) goingTo = nameMatches[0]; + + // if it has one location, go to it + if( goingTo.location ) { + + //go to location, with some flanking region + thisB.showRegion( goingTo.location ); + } + // otherwise, pop up a dialog with a list of the locations to choose from + else if( goingTo.multipleLocations ) { + new LocationChoiceDialog( + { + browser: thisB, + locationChoices: goingTo.multipleLocations, + title: 'Choose '+goingTo.name+' location', + prompt: '"'+goingTo.name+'" is found in multiple locations. Please choose a location to view.' + }) + .show(); + } } ); }; @@ -960,27 +1470,24 @@ Browser.prototype.searchNames = function( /**String*/ loc ) { */ Browser.prototype.showTracks = function( trackNames ) { - if( !this.isInitialized ) { - this.deferredFunctions.push( function() { this.showTracks(trackNames); } ); - return; - } - - if( typeof trackNames == 'string' ) - trackNames = trackNames.split(','); - - if( ! trackNames ) - return; - - var trackConfs = dojo.filter( - dojo.map( trackNames, function(n) { - return this.trackConfigsByName[n]; - }, this), - function(c) {return c;} // filter out confs that are missing - ); + this.afterMilestone('completely initialized', dojo.hitch( this, function() { + if( typeof trackNames == 'string' ) + trackNames = trackNames.split(','); + + if( ! trackNames ) + return; + + var trackConfs = dojo.filter( + dojo.map( trackNames, function(n) { + return this.trackConfigsByName[n]; + }, this), + function(c) {return c;} // filter out confs that are missing + ); - // publish some events with the tracks to instruct the views to show them. - this.publish( '/jbrowse/v1/c/tracks/show', trackConfs ); - this.publish( '/jbrowse/v1/n/tracks/visibleChanged' ); + // publish some events with the tracks to instruct the views to show them. + this.publish( '/jbrowse/v1/c/tracks/show', trackConfs ); + this.publish( '/jbrowse/v1/n/tracks/visibleChanged' ); + })); }; Browser.prototype.makeHelpDialog = function () { @@ -1049,12 +1556,13 @@ Browser.prototype.makeHelpDialog = function () { }, helpdiv ); // make a Help link that will show the dialog and set a handler on it - var helplink = document.createElement('a'); - helplink.className = 'topLink'; - helplink.title = 'Help'; - helplink.style.cursor = 'help'; - helplink.appendChild( document.createTextNode('Help')); - dojo.connect(helplink, 'onclick', function() { dialog.show(); }); + var helpButton = new dijitButton( + { + className: 'help', + title: 'Help', + innerHTML: ' Help', + onClick: function() { dialog.show(); } + }); this.setGlobalKeyboardShortcut( '?', dialog, 'show' ); dojo.connect( document.body, 'onkeydown', function(evt) { @@ -1062,7 +1570,7 @@ Browser.prototype.makeHelpDialog = function () { dialog.hide(); }); - return helplink; + return helpButton.domNode; }; /** @@ -1086,7 +1594,11 @@ Browser.prototype.setGlobalKeyboardShortcut = function( keychar ) { * Key event handler that implements all global keyboard shortcuts. */ Browser.prototype.globalKeyHandler = function( evt ) { - var shortcut = this.globalKeyboardShortcuts[ evt.keyChar ]; + // if some digit widget is focused, don't process any global keyboard shortcuts + if( dijitFocus.curNode ) + return; + + var shortcut = this.globalKeyboardShortcuts[ evt.keyChar || String.fromCharCode( evt.charCode || evt.keyCode ) ]; if( shortcut ) { shortcut.call( this ); evt.stopPropagation(); @@ -1102,23 +1614,17 @@ Browser.prototype.makeShareLink = function () { var shareURL = '#'; // make the share link - var link = dojo.create( - 'a', - { - className: 'topLink', - href: '#', - innerHTML: 'Share', + var button = new dijitButton({ + className: 'share', + innerHTML: ' Share', title: 'share this view', - style: { - position: 'relative' - }, - onclick: function() { + onClick: function() { URLinput.value = shareURL; previewLink.href = shareURL; sharePane.show(); - var lp = dojo.position(link); + var lp = dojo.position( button.domNode ); dojo.style( sharePane.domNode, { top: (lp.y+lp.h) + 'px', right: 0, @@ -1152,7 +1658,7 @@ Browser.prototype.makeShareLink = function () { onblur: function() { copyReminder.style.display = 'none'; } }); var previewLink = dojo.create('a', { - innerHTML: 'preview', + innerHTML: 'Preview', target: '_blank', href: shareURL, style: { display: 'block', "float": 'right' } @@ -1187,9 +1693,9 @@ Browser.prototype.makeShareLink = function () { ); }); dojo.connect( this, "onCoarseMove", updateShareURL ); - this.subscribe( '/jbrowse/v1/v/tracks/changed', updateShareURL ); + this.subscribe( '/jbrowse/v1/n/tracks/visibleChanged', updateShareURL ); - return link; + return button.domNode; }; Browser.prototype.makeFullViewLink = function () { @@ -1217,8 +1723,8 @@ Browser.prototype.makeFullViewLink = function () { }) ); }); - dojo.connect( this, "onCoarseMove", update_link ); - this.subscribe( '/jbrowse/v1/v/tracks/changed', update_link ); + dojo.connect( this, "onCoarseMove", update_link ); + this.subscribe( '/jbrowse/v1/n/tracks/visibleChanged', update_link ); return link; }; @@ -1228,21 +1734,8 @@ Browser.prototype.makeFullViewLink = function () { */ Browser.prototype.onCoarseMove = function(startbp, endbp) { - var length = this.view.ref.end - this.view.ref.start; - var trapLeft = Math.round((((startbp - this.view.ref.start) / length) - * this.view.overviewBox.w) + this.view.overviewBox.l); - var trapRight = Math.round((((endbp - this.view.ref.start) / length) - * this.view.overviewBox.w) + this.view.overviewBox.l); - - this.view.locationThumb.style.cssText = - "height: " + (this.view.overviewBox.h - 4) + "px; " - + "left: " + trapLeft + "px; " - + "width: " + (trapRight - trapLeft) + "px;" - + "z-index: 20"; - //since this method gets triggered by the initial GenomeView.sizeInit, - //we don't want to save whatever location we happen to start at - if( ! this.isInitialized ) return; + this._updateLocationThumb(); var currRegion = { start: startbp, end: endbp, ref: this.refSeq.name }; @@ -1259,9 +1752,37 @@ Browser.prototype.onCoarseMove = function(startbp, endbp) { if( this.refSeqSelectBox ) this.refSeqSelectBox.set( 'value', this.refSeq.name, false ); + if( this.reachedMilestone('completely initialized') ) { + this._updateLocationCookies( currRegion ); + document.title = Util.assembleLocString( currRegion ); + } + + // send out a message notifying of the move + this.publish( '/jbrowse/v1/n/navigate', currRegion ); +}; + +Browser.prototype._updateLocationThumb = function() { + var startbp = this.view.minVisible(); + var endbp = this.view.maxVisible(); + + var length = this.view.ref.end - this.view.ref.start; + var trapLeft = Math.round((((startbp - this.view.ref.start) / length) + * this.view.overviewBox.w) + this.view.overviewBox.l); + var trapRight = Math.round((((endbp - this.view.ref.start) / length) + * this.view.overviewBox.w) + this.view.overviewBox.l); - // update the location and refseq cookies - var locString = Util.assembleLocString( currRegion ); + this.view.locationThumb.style.cssText = + "height: " + (this.view.overviewBox.h - 4) + "px; " + + "left: " + trapLeft + "px; " + + "width: " + (trapRight - trapLeft) + "px;" + + "z-index: 20"; +}; + +/** + * update the location and refseq cookies + */ +Browser.prototype._updateLocationCookies = function( location ) { + var locString = typeof location == 'string' ? location : Util.assembleLocString( location ); var oldLocMap = dojo.fromJson( this.cookie('location') ) || { "_version": 1 }; if( ! oldLocMap["_version"] ) oldLocMap = this._migrateLocMap( oldLocMap ); @@ -1269,8 +1790,6 @@ Browser.prototype.onCoarseMove = function(startbp, endbp) { oldLocMap = this._limitLocMap( oldLocMap, this.config.maxSavedLocations || 10 ); this.cookie( 'location', dojo.toJson(oldLocMap), {expires: 60}); this.cookie( 'refseq', this.refSeq.name ); - - document.title = locString; }; /** @@ -1343,11 +1862,11 @@ Browser.prototype.cookie = function() { */ Browser.prototype.createNavBox = function( parent ) { - var navbox = document.createElement("div"); var browserRoot = this.config.browserRoot ? this.config.browserRoot : ""; - navbox.id = "navbox"; - parent.appendChild(navbox); - navbox.style.cssText = "text-align: center; z-index: 10;"; + + var navbox = dojo.create( 'div', { id: 'navbox', style: { 'text-align': 'center' } }, parent ); + + this.locationTrap = dojo.create('div', {className: 'locationTrap'}, navbox ); var four_nbsp = String.fromCharCode(160); four_nbsp = four_nbsp + four_nbsp + four_nbsp + four_nbsp; navbox.appendChild(document.createTextNode( four_nbsp )); @@ -1438,60 +1957,23 @@ Browser.prototype.createNavBox = function( parent ) { // if we have fewer than 30 ref seqs, or `refSeqDropdown: true` is // set in the config, then put in a dropdown box for selecting // reference sequences - if( this.refSeqOrder.length && this.refSeqOrder.length < 30 || this.config.refSeqDropdown ) { - this.refSeqSelectBox = new dijitSelectBox({ - name: 'refseq', - value: this.refSeq ? this.refSeq.name : null, - options: array.map( this.refSeqOrder || [], - function( refseqName ) { - return { label: refseqName, value: refseqName }; - }), - onChange: dojo.hitch(this, function( newRefName ) { - this.navigateToLocation({ ref: newRefName }); - }) - }).placeAt( navbox ); - } - - // calculate how big to make the location box: make it big enough to hold the - var locLength = this.config.locationBoxLength || function() { - - // if we have no refseqs, just use 20 chars - if( ! this.refSeqOrder.length ) - return 20; - - // if there are not tons of refseqs, pick the longest-named - // one. otherwise just pick the last one - var ref = this.refSeqOrder.length < 1000 - && function() { - var longestNamedRef; - array.forEach( this.refSeqOrder, function(name) { - var ref = this.allRefs[name]; - if( ! ref.length ) - ref.length = ref.end - ref.start + 1; - if( ! longestNamedRef || longestNamedRef.length < ref.length ) - longestNamedRef = ref; - }, this ); - return longestNamedRef; - }.call(this) - || this.refSeqOrder.length && this.allRefs[ this.refSeqOrder[ this.refSeqOrder.length - 1 ] ] - || 20; - - var locstring = Util.assembleLocStringWithLength({ ref: ref.name, start: ref.end-1, end: ref.end, length: ref.length }); - //console.log( locstring, locstring.length ); - return locstring.length; - }.call(this) || 20; + var refSeqSelectBoxPlaceHolder = dojo.create('span', {}, navbox ); // make the location box this.locationBox = new dijitComboBox( { id: "location", name: "location", - style: { width: locLength+'ex' }, + style: { width: '25ex' }, maxLength: 400, - store: this._makeLocationAutocompleteStore(), searchAttr: "name" }, dojo.create('input', {}, navbox) ); + this.afterMilestone( 'loadNames', dojo.hitch(this, function() { + if( this.nameStore ) + this.locationBox.set( 'store', this.nameStore ); + })); + this.locationBox.focusNode.spellcheck = false; dojo.query('div.dijitArrowButton', this.locationBox.domNode ).orphan(); dojo.connect( this.locationBox.focusNode, "keydown", this, function(event) { @@ -1519,11 +2001,11 @@ Browser.prototype.createNavBox = function( parent ) { }; // prevent the "more matches" option from being clicked - var oldSetValue = dropDownProto._setValueAttr; - dropDownProto._setValueAttr = function( value ) { - if( value.target && value.target.item && value.target.item.hitLimit ) + var oldOnClick = dropDownProto.onClick; + dropDownProto.onClick = function( node ) { + if( dojo.hasClass(node, 'moreMatches' ) ) return null; - return oldSetValue.apply( this, arguments ); + return oldOnClick.apply( this, arguments ); }; }).call(this); @@ -1538,22 +2020,62 @@ Browser.prototype.createNavBox = function( parent ) { }) }, dojo.create('button',{},navbox)); + + this.afterMilestone('loadRefSeqs', dojo.hitch( this, function() { + if( this.refSeqOrder.length && this.refSeqOrder.length < 30 || this.config.refSeqDropdown ) { + this.refSeqSelectBox = new dijitSelectBox({ + name: 'refseq', + value: this.refSeq ? this.refSeq.name : null, + options: array.map( this.refSeqOrder || [], + function( refseqName ) { + return { label: refseqName, value: refseqName }; + }), + onChange: dojo.hitch(this, function( newRefName ) { + this.navigateToLocation({ ref: newRefName }); + }) + }).placeAt( refSeqSelectBoxPlaceHolder ); + } + + // calculate how big to make the location box: make it big enough to hold the + var locLength = this.config.locationBoxLength || function() { + + // if we have no refseqs, just use 20 chars + if( ! this.refSeqOrder.length ) + return 20; + + // if there are not tons of refseqs, pick the longest-named + // one. otherwise just pick the last one + var ref = this.refSeqOrder.length < 1000 + && function() { + var longestNamedRef; + array.forEach( this.refSeqOrder, function(name) { + var ref = this.allRefs[name]; + if( ! ref.length ) + ref.length = ref.end - ref.start + 1; + if( ! longestNamedRef || longestNamedRef.length < ref.length ) + longestNamedRef = ref; + }, this ); + return longestNamedRef; + }.call(this) + || this.refSeqOrder.length && this.allRefs[ this.refSeqOrder[ this.refSeqOrder.length - 1 ] ] + || 20; + + var locstring = Util.assembleLocStringWithLength({ ref: ref.name, start: ref.end-1, end: ref.end, length: ref.length }); + //console.log( locstring, locstring.length ); + return locstring.length; + }.call(this) || 20; + + + this.locationBox.domNode.style.width = locLength+'ex'; + })); + return navbox; }; -Browser.prototype._makeLocationAutocompleteStore = function() { - var conf = this.config.autocomplete||{}; - return new AutocompleteStore({ - namesTrie: this.names, - stopPrefixes: conf.stopPrefixes, - resultLimit: conf.resultLimit || 15 - }); -}; return Browser; -}); - +}); }); /* diff --git a/src/JBrowse/CodonTable.js b/src/JBrowse/CodonTable.js new file mode 100644 index 0000000000..e89a1e6029 --- /dev/null +++ b/src/JBrowse/CodonTable.js @@ -0,0 +1,105 @@ +define( [], + function() { + +var CodonTable = { + "TCA" : "S", + "TCC" : "S", + "TCG" : "S", + "TCT" : "S", + "TTC" : "F", + "TTT" : "F", + "TTA" : "L", + "TTG" : "L", + "TAC" : "Y", + "TAT" : "Y", + "TAA" : "*", + "TAG" : "*", + "TGC" : "C", + "TGT" : "C", + "TGA" : "*", + "TGG" : "W", + "CTA" : "L", + "CTC" : "L", + "CTG" : "L", + "CTT" : "L", + "CCA" : "P", + "CCC" : "P", + "CCG" : "P", + "CCT" : "P", + "CAC" : "H", + "CAT" : "H", + "CAA" : "Q", + "CAG" : "Q", + "CGA" : "R", + "CGC" : "R", + "CGG" : "R", + "CGT" : "R", + "ATA" : "I", + "ATC" : "I", + "ATT" : "I", + "ATG" : "M", + "ACA" : "T", + "ACC" : "T", + "ACG" : "T", + "ACT" : "T", + "AAC" : "N", + "AAT" : "N", + "AAA" : "K", + "AAG" : "K", + "AGC" : "S", + "AGT" : "S", + "AGA" : "R", + "AGG" : "R", + "GTA" : "V", + "GTC" : "V", + "GTG" : "V", + "GTT" : "V", + "GCA" : "A", + "GCC" : "A", + "GCG" : "A", + "GCT" : "A", + "GAC" : "D", + "GAT" : "D", + "GAA" : "E", + "GAG" : "E", + "GGA" : "G", + "GGC" : "G", + "GGG" : "G", + "GGT" : "G" +}; + + +/** +* take CodonTable above and generate larger codon table that includes +* all permutations of upper and lower case nucleotides +*/ +var tempCodonTable = { }; +for (var codon in CodonTable) { + // looping through codon table, make sure not hitting generic properties... + if (CodonTable.hasOwnProperty(codon)) { + var aa = CodonTable[codon]; + // console.log("Codon: ", codon, ", aa: ", aa); + var nucs = []; + for (var i=0; i<3; i++) { + var nuc = codon.charAt(i); + nucs[i] = []; + nucs[i][0] = nuc.toUpperCase(); + nucs[i][1] = nuc.toLowerCase(); + } + for (var i=0; i<2; i++) { + var n0 = nucs[0][i]; + for (var j=0; j<2; j++) { + var n1 = nucs[1][j]; + for (var k=0; k<2; k++) { + var n2 = nucs[2][k]; + var triplet = n0 + n1 + n2; + tempCodonTable[triplet] = aa; + // console.log("triplet: ", triplet, ", aa: ", aa ); + } + } + } + } +} + +return tempCodonTable; +}); \ No newline at end of file diff --git a/src/JBrowse/ConfigAdaptor/AdaptorUtil.js b/src/JBrowse/ConfigAdaptor/AdaptorUtil.js new file mode 100644 index 0000000000..7a9fd28574 --- /dev/null +++ b/src/JBrowse/ConfigAdaptor/AdaptorUtil.js @@ -0,0 +1,37 @@ +define( [ 'dojox/lang/functional/object', + 'dojox/lang/functional/fold' + ], function() { + var AdaptorUtil; + AdaptorUtil = { + + evalHooks: function( conf ) { + for( var x in conf ) { + if( typeof conf[x] == 'object' ) + // recur + conf[x] = this.evalHooks( conf[x] ); + else if( typeof conf[x] == 'string' ) { + // compile + var spec = conf[x]; + if( /^function\s*\(/.test(spec) && /\}[\s;]*$/.test(spec) ) { + conf[x] = this.evalHook(spec); + } + } + } + return conf; + }, + + evalHook: function() { + // can't bind arguments because the closure compiler + // renames variables, and we need to assign in the eval + if ( "string" != typeof arguments[0]) + return arguments[0]; + try { + eval("arguments[0]="+arguments[0]+";"); + } catch (e) { + console.error("eval failed for callback '"+arguments[0]+"': "+e); + } + return arguments[0]; + } + } + return AdaptorUtil; +}); diff --git a/src/JBrowse/ConfigAdaptor/JB_json_v1.js b/src/JBrowse/ConfigAdaptor/JB_json_v1.js index b76e4b5096..408212c5c8 100644 --- a/src/JBrowse/ConfigAdaptor/JB_json_v1.js +++ b/src/JBrowse/ConfigAdaptor/JB_json_v1.js @@ -2,8 +2,9 @@ define( [ 'dojo/_base/declare', 'dojo/_base/array', 'dojo/_base/json', 'JBrowse/Util', - 'JBrowse/Digest/Crc32' - ], function( declare, array, json, Util, digest ) { + 'JBrowse/Digest/Crc32', + 'JBrowse/ConfigAdaptor/AdaptorUtil' + ], function( declare, array, json, Util, digest, AdaptorUtil ) { return declare('JBrowse.ConfigAdaptor.JB_json_v1',null, @@ -32,21 +33,26 @@ return declare('JBrowse.ConfigAdaptor.JB_json_v1',null, load: function( /**Object*/ args ) { var that = this; if( args.config.url ) { + var url = Util.resolveUrl( args.baseUrl || window.location.href, args.config.url ); + var handleError = function(e) { + e.url = url; + if( args.onFailure ) + args.onFailure.call( args.context || this, e ); + }; dojo.xhrGet({ - url: Util.resolveUrl( args.baseUrl || window.location.href, args.config.url ), + url: url, handleAs: 'text', load: function( o ) { - window.setTimeout( dojo.hitch(this, function() { - o = that.parse_conf( o, args ); - o = that.regularize_conf( o, args ); - args.onSuccess.call( args.context || this, o ); - }, 10 )); + try { + o = that.parse_conf( o, args ) || {}; + o.sourceUrl = url; + o = that.regularize_conf( o, args ); + args.onSuccess.call( args.context || that, o ); + } catch(e) { + handleError(e); + } }, - error: function( i ) { - console.error( ''+i ); - if( args.onFailure ) - args.onFailure.call( args.context || this, i); - } + error: handleError }); } else if( args.config.data ) { @@ -81,15 +87,18 @@ return declare('JBrowse.ConfigAdaptor.JB_json_v1',null, if( o.baseUrl.length && ! /\/$/.test( o.baseUrl ) ) o.baseUrl += "/"; - // set a default baseUrl in each of the track confs if needed + // set a default baseUrl in each of the track confs, and the names conf, if needed if( o.sourceUrl ) { - dojo.forEach( o.tracks || [], function(t) { - if( ! t.baseUrl ) - t.baseUrl = o.baseUrl || '/'; - },this); + var addBase = [].concat( o.tracks || [] ); + if( o.names ) + addBase.push( o.names ); + dojo.forEach( addBase, function(t) { + if( ! t.baseUrl ) + t.baseUrl = o.baseUrl || '/'; + },this); } - o = this._evalHooks( o ); + o = AdaptorUtil.evalHooks( o ); o = this._regularizeTrackConfigs( o ); @@ -100,6 +109,20 @@ return declare('JBrowse.ConfigAdaptor.JB_json_v1',null, conf.stores = conf.stores || {}; array.forEach( conf.tracks || [], function( trackConfig ) { + + // if there is a `config` subpart, + // just copy its keys in to the + // top-level config + if( trackConfig.config ) { + var c = trackConfig.config; + delete trackConfig.config; + for( var prop in c ) { + if( !(prop in trackConfig) && c.hasOwnProperty(prop) ) { + trackConfig[prop] = c[prop]; + } + } + } + // skip if it's a new-style track def if( trackConfig.store ) return; @@ -138,7 +161,8 @@ return declare('JBrowse.ConfigAdaptor.JB_json_v1',null, urlTemplate: trackConfig.urlTemplate, compress: trackConfig.compress, baseUrl: trackConfig.baseUrl, - type: storeClass + type: storeClass, + subfeatures: trackConfig.subfeatures }; // if this is the first sequence store we see, and we @@ -153,6 +177,7 @@ return declare('JBrowse.ConfigAdaptor.JB_json_v1',null, // connect it to the track conf trackConfig.store = storeConf.name; + }, this); return conf; @@ -164,34 +189,6 @@ return declare('JBrowse.ConfigAdaptor.JB_json_v1',null, class_ = root+'/'+class_; class_ = class_.replace(/^\//); return class_; - }, - - _evalHooks: function( conf ) { - for( var x in conf ) { - if( typeof conf[x] == 'object' ) - // recur - conf[x] = this._evalHooks( conf[x] ); - else if( typeof conf[x] == 'string' ) { - // compile - var spec = conf[x]; - if( /^function\s*\(/.test(spec) && /\}[\s;]*$/.test(spec) ) { - conf[x] = this._evalHook(spec); - } - } - } - return conf; - }, - _evalHook: function( hook ) { - // can't bind arguments because the closure compiler - // renames variables, and we need to assign in the eval - if ( "string" != typeof hook ) - return hook; - try { - eval('arguments[0]='+hook+';'); - } catch (e) { - console.error("error parsing parsing JavaScript callback: '"+hook+"': "+e); - } - return (function(h) { return h; }).apply( this, arguments ); } }); -}); \ No newline at end of file +}); diff --git a/src/JBrowse/ConfigAdaptor/conf.js b/src/JBrowse/ConfigAdaptor/conf.js new file mode 100644 index 0000000000..3b6f206a97 --- /dev/null +++ b/src/JBrowse/ConfigAdaptor/conf.js @@ -0,0 +1,120 @@ +// Code for parsing GBrowse config files +// Output : a JS object + +// Based (now *extremely* loosely) on +// https://github.com/shockie/node-iniparser -> released under the MIT license + + +define(['dojo/_base/declare','JBrowse/Util','JBrowse/ConfigAdaptor/AdaptorUtil'], function(declare,Util,AdaptorUtil) { +return declare('JBrowse.ConfigAdaptor.gbrowse',null, + + { + + constructor: function() {}, + + load: function(args){ + var that = this; + dojo.xhrGet({ + url: Util.resolveUrl( args.baseUrl || window.location.href, args.config.url ), + handleAs: 'text', + load: dojo.hitch( that, function(data) { + var gbConfig = this.parse(data); + args.onSuccess.call( that, gbConfig ); + }), + error: function(e) { + console.error( '' + e ); + if( args.onFailure ) + args.onFailure.call( args.context || this, e ); + } + }); + }, + + parse: function(data){ + this.regex = { + section: /^\s*\[\s*([^\]\/]*)\s*\]\s*$/, + subsection: /^\s*\[\s*([^\]]*)\/([^\]]*)\s*\]\s*$/, + param: /^(\w[\w\.\-\_\:\s]+)=\s*(.*?)\s*$/, + comment: /^\s*(#|\/\/).*$/, + emptyLine: /^\s*$/, + newLine: /\r\n|\r|\n/, + code: /^\s*function\s*\(/ + }; + this.value = {}; + this.lines = data.split(this.regex.newLine); + this.section = null; + this.subsection = null; + var n = this.lines.length; + + + //Process each line + for (var i = 0; i < n; i++) { + if (this.regex.comment.test(this.lines[i])) { // #this is a comment + // do nothing, since it's a comment. // // this is also a comment + } else if (this.regex.param.test(this.lines[i])) { // param = * + i = this.param(i); + } else if (this.regex.subsection.test(this.lines[i])) { // [section_name] + this.subSection(i); + } else if (this.regex.section.test(this.lines[i])){ // [section/subsection] + this.mainSection(i); + } + }; + + return AdaptorUtil.evalHooks(this.value); //Returns the JS object + }, + + //called for: something = * + param: function(i){ + var line = this.lines; var rx = this.regex; + var lineNum = i+1; + + var match = this.lines[i].match(this.regex.param); // Check for a value + match[2].trim(); // on the first + if (!isNaN(match[2].trim())) { // line, then check + match[2] = parseFloat(match[2]); // the rest of the + } // block + + var tmpStrVal = match[2] ? match[2] : ''; + var divider = this.regex.code.test(line[lineNum]) ? "\n" : ' '; + + // while (line is defined, and not a parameter, section, or subsection) + while (typeof line[lineNum] !== 'undefined' && (! ( rx.param.test(line[lineNum]) || + rx.section.test(line[lineNum]) || rx.subsection.test(line[lineNum])))){ + //if (line is not a comment or empty) + if (! ( rx.comment.test(line[lineNum]) || rx.emptyLine.test(line[lineNum]) )) { + if (tmpStrVal === ''){ + tmpStrVal += line[lineNum].trim(); + } else { + tmpStrVal = tmpStrVal + divider + line[lineNum].trim(); + } + } + lineNum++; + } + var match = this.lines[i].match(this.regex.param); + if (this.subsection && this.section) { + this.value[this.section][this.subsection][match[1].trim()] = tmpStrVal; + } else if (this.section){ + this.value[this.section][match[1].trim()] = tmpStrVal; + } else { + this.value[match[1].trim()] = tmpStrVal; + } + return lineNum - 1; //The line it should continue at. + }, + + //called for: [foobar] + mainSection: function(i) { + var match = this.lines[i].match(this.regex.section); + this.section = match[1].trim(); + this.value[this.section] = {}; + this.subsection = null; + }, + + //called for: [foo/bar] + subSection: function(i) { + var match = this.lines[i].match(this.regex.subsection); + this.section = match[1].trim(); + this.subsection = match[2].trim(); + this.value[this.section] = {}; + this.value[this.section][this.subsection] = {}; + } + }); +}); diff --git a/src/JBrowse/ConfigManager.js b/src/JBrowse/ConfigManager.js index 187e13bc44..4da2f8b6ba 100644 --- a/src/JBrowse/ConfigManager.js +++ b/src/JBrowse/ConfigManager.js @@ -18,7 +18,8 @@ constructor: function( args ) { this.defaults = dojo.clone( args.defaults || {} ); this.browser = args.browser; this.skipValidation = args.skipValidation; - this.topLevelIncludes = this.config.include; + this.topLevelIncludes = this.config.include || this.defaults.include; + delete this.defaults.include; delete this.config.include; }, @@ -36,7 +37,7 @@ getFinalConfig: function( callback ) { // now validate the final merged config, and finally give it // to the callback - this._applyDefaults( this.config, this.defaults ); + this.config = this._applyDefaults( this.config, this.defaults ); if( ! this.skipValidation ) this._validateConfig( this.config ); callback( this.config ); @@ -117,15 +118,14 @@ _loadIncludes: function( inputConfig, callback ) { loadingResult.data = config_data_with_includes_resolved; if( ! --configs_remaining ) callback( this._mergeIncludes( inputConfig, included_configs ) ); - //if you need a backtrace: window.setTimeout( function() { that.onConfigLoaded(); }, 1 ); })); }), onFailure: dojo.hitch( this, function( error ) { loadingResult.error = error; - console.error(error); + if( error.status != 404 ) // if it's a missing file, browser will have logged it + this._fatalError( error ); if( ! --configs_remaining ) callback( this._mergeIncludes( inputConfig, included_configs ) ); - //if you need a backtrace: window.setTimeout( function() { that.onConfigLoaded(); }, 1 ); }) }); })); @@ -170,7 +170,7 @@ _validateConfig: function( c ) { this._fatalError( 'Must provide a baseUrl in configuration' ); } if( this.hasFatalErrors ) - throw "Errors in configuration, aborting."; + throw "Errors in configuration, aborting"; }, /** @@ -178,7 +178,8 @@ _validateConfig: function( c ) { */ _fatalError: function( error ) { this.hasFatalErrors = true; - console.error(error); + if( error.url ) + error = error + ' when loading '+error.url; this.browser.fatalError( error ); }, diff --git a/src/JBrowse/Finisher.js b/src/JBrowse/Finisher.js index 26364379ef..ae35820731 100644 --- a/src/JBrowse/Finisher.js +++ b/src/JBrowse/Finisher.js @@ -3,6 +3,7 @@ define(['dojo/_base/declare'], function(declare) { constructor: function(fun) { this.fun = fun; this.count = 0; + this.finished = false; }, inc: function() { this.count++; @@ -12,8 +13,10 @@ define(['dojo/_base/declare'], function(declare) { this.finish(); }, finish: function() { - if (this.count <= 0) + if (this.count <= 0 && !this.finished) { this.fun(); + this.finished = true; + } } }); }); diff --git a/src/JBrowse/GenomeView.js b/src/JBrowse/GenomeView.js index e4a0d948df..ea2030aaf5 100644 --- a/src/JBrowse/GenomeView.js +++ b/src/JBrowse/GenomeView.js @@ -1,4 +1,6 @@ define([ + 'dojo/_base/declare', + 'dojo/_base/array', 'JBrowse/Util', 'dojo/dnd/move', 'dojo/dnd/Source', @@ -9,6 +11,8 @@ define([ 'JBrowse/View/Animation/Zoomer', 'JBrowse/View/Animation/Slider' ], function( + declare, + array, Util, dndMove, dndSource, @@ -22,35 +26,56 @@ define([ var dojof = Util.dojof; +// weird subclass of dojo dnd constrained mover to make the location +// thumb behave better +var locationThumbMover = declare( dndMove.constrainedMoveable, { + constructor: function(node, params){ + this.constraints = function(){ + var n = this.node.parentNode, + mb = dojo.marginBox(n); + mb.t = 0; + return mb; + }; + } +}); + /** * Main view class, shows a scrollable, horizontal view of annotation * tracks. NOTE: All coordinates are interbase. * @class * @constructor */ -var GenomeView = function( browser, elem, stripeWidth, refseq, zoomLevel, browserRoot) { +var GenomeView = function( browser, elem, stripeWidth, refseq, zoomLevel ) { // keep a reference to the main browser object this.browser = browser; + //the page element that the GenomeView lives in + this.elem = elem; + + // var seqCharSize = this.calculateSequenceCharacterSize( elem ); + var charSize = this.getSequenceCharacterSize(); + this.charWidth = charSize.width; + this.seqHeight = charSize.height; this.posHeight = this.calculatePositionLabelHeight( elem ); // Add an arbitrary 50% padding between the position labels and the // topmost track this.topSpace = 1.5 * this.posHeight; - // arbitrary max px per bp - this.maxPxPerBp = 20; + // WebApollo needs max zoom level to be sequence residues char width + this.maxPxPerBp = this.charWidth; + + console.log("charWidth: " + this.charWidth); + console.log("seqHeight: " + this.seqHeight); //the reference sequence this.ref = refseq; //current scale, in pixels per bp this.pxPerBp = zoomLevel; - //path prefix for static assets (e.g., cursors) - this.browserRoot = browserRoot ? browserRoot : ""; + //width, in pixels, of the vertical stripes this.stripeWidth = stripeWidth; - //the page element that the GenomeView lives in - this.elem = elem; + // the scrollContainer is the element that changes position // when the user scrolls @@ -91,7 +116,7 @@ var GenomeView = function( browser, elem, stripeWidth, refseq, zoomLevel, browse //width, in pixels, of stripes at full zoom, is 10bp this.fullZoomStripe = stripeWidth/10 * this.maxPxPerBp; - this.overview = dojo.byId("overview"); + this.overview = this.browser.overviewDiv; this.overviewBox = dojo.marginBox(this.overview); this.tracks = []; @@ -131,7 +156,7 @@ var GenomeView = function( browser, elem, stripeWidth, refseq, zoomLevel, browse this.locationThumb = document.createElement("div"); this.locationThumb.className = "locationThumb"; this.overview.appendChild(this.locationThumb); - this.locationThumbMover = new dndMove.parentConstrainedMoveable(this.locationThumb, {area: "margin", within: true}); + this.locationThumbMover = new locationThumbMover(this.locationThumb, {area: "margin", within: true}); if ( dojo.isIE ) { // if using IE, we have to do scrolling with CSS @@ -226,8 +251,10 @@ var GenomeView = function( browser, elem, stripeWidth, refseq, zoomLevel, browse } ) ); - this.browser.subscribe( '/jbrowse/v1/c/tracks/show', dojo.hitch( this, 'showTracks' )); - this.browser.subscribe( '/jbrowse/v1/c/tracks/hide', dojo.hitch( this, 'hideTracks' )); + this.browser.subscribe( '/jbrowse/v1/c/tracks/show', dojo.hitch( this, 'showTracks' )); + this.browser.subscribe( '/jbrowse/v1/c/tracks/hide', dojo.hitch( this, 'hideTracks' )); + this.browser.subscribe( '/jbrowse/v1/c/tracks/replace', dojo.hitch( this, 'replaceTracks' )); + this.browser.subscribe( '/jbrowse/v1/c/tracks/delete', dojo.hitch( this, 'hideTracks' )); // render our UI tracks (horizontal scale tracks, grid lines, and so forth) dojo.forEach(this.uiTracks, function(track) { @@ -356,16 +383,14 @@ GenomeView.prototype._behaviors = function() { return { apply_on_init: true, apply: function() { var handles = []; - this.overviewTrackIterate( function(t) { - handles.push( dojo.connect( - t.div, 'mousedown', - dojo.hitch( this, 'startRubberZoom', - dojo.hitch(this,'overview_absXtoBp'), - t.div, - t.div - ) - )); - }); + handles.push( dojo.connect( + this.overview, 'mousedown', + dojo.hitch( this, 'startRubberZoom', + dojo.hitch(this,'overview_absXtoBp'), + this.overview, + this.overview + ) + )); handles.push( dojo.connect( this.scrollContainer, "mousewheel", this, 'wheelScroll', false ), dojo.connect( this.scrollContainer, "DOMMouseScroll", this, 'wheelScroll', false ), @@ -540,6 +565,37 @@ GenomeView.prototype._behaviors = function() { return { } };}; + +GenomeView.prototype.getSequenceCharacterSize = function() { + if (! this._charSize) { + this._charSize = this.calculateSequenceCharacterSize(this.elem); + } + return this._charSize; +} +/** + * Conducts a test with DOM elements to measure sequence text width + * and height. + */ +GenomeView.prototype.calculateSequenceCharacterSize = function( containerElement ) { + var widthTest = document.createElement("div"); + widthTest.className = "wa-sequence"; + widthTest.style.visibility = "hidden"; + var widthText = "12345678901234567890123456789012345678901234567890"; + widthTest.appendChild(document.createTextNode(widthText)); + containerElement.appendChild(widthTest); + console.log("charWidth calc element: "); + console.log(widthTest); + + var result = { + width: widthTest.clientWidth / widthText.length, + height: widthTest.clientHeight + }; + + containerElement.removeChild(widthTest); + return result; +}; + + /** * Conduct a DOM test to calculate the height of div.pos-label * elements with a line of text in them. @@ -1125,7 +1181,7 @@ GenomeView.prototype.scaleMouseOut = function( evt ) { * Draws the red line across the work area, or updates it if it already exists. */ GenomeView.prototype.drawVerticalPositionLine = function( parent, evt){ - var numX = evt.pageX; + var numX = evt.pageX + 2; if( ! this.verticalPositionLine ){ // if line does not exist, create it @@ -1136,7 +1192,10 @@ GenomeView.prototype.drawVerticalPositionLine = function( parent, evt){ var line = this.verticalPositionLine; line.style.display = 'block'; //make line visible - line.style.left = numX +'px'; //set location on screen + line.style.left = numX+'px'; //set location on screen + var scaleTrackPos = dojo.position( this.scaleTrackDiv ); + line.style.top = scaleTrackPos.y + 'px'; + this.drawBasePairLabel({ name: 'single', offset: 0, x: numX, parent: parent }); }; @@ -1160,7 +1219,7 @@ GenomeView.prototype.drawBasePairLabel = function ( args ){ this.basePairLabels[name] = dojo.create( 'div', { className: 'basePairLabel'+(args.className ? ' '+args.className : '' ), style: { top: scaleTrackPos.y + scaleTrackPos.h - 3 + 'px' } - }, args.parent ); + }, document.body ); } var label = this.basePairLabels[name]; @@ -1313,7 +1372,16 @@ GenomeView.prototype.sizeInit = function() { this.overviewBox = dojo.marginBox(this.overview); //scale values, in pixels per bp, for all zoom levels - this.zoomLevels = [1/500000, 1/200000, 1/100000, 1/50000, 1/20000, 1/10000, 1/5000, 1/2000, 1/1000, 1/500, 1/200, 1/100, 1/50, 1/20, 1/10, 1/5, 1/2, 1, 2, 5, 10, this.maxPxPerBp ]; + var desiredZoomLevels = [1/500000, 1/200000, 1/100000, 1/50000, 1/20000, 1/10000, 1/5000, 1/2000, 1/1000, 1/500, 1/200, 1/100, 1/50, 1/20, 1/10, 1/5, 1/2, 1, 2, 5, 10, 20 ]; + + this.zoomLevels = []; + for (var i=0; i= maxPxPerBp, quit + } + this.zoomLevels.push(this.maxPxPerBp); + //make sure we don't zoom out too far while (((this.ref.end - this.ref.start) * this.zoomLevels[0]) < this.getWidth()) { @@ -1473,6 +1541,7 @@ GenomeView.prototype.updateOverviewHeight = function(trackName, height) { var overviewHeight = 0; this.overviewTrackIterate(function (track, view) { overviewHeight += track.height; + track.div.style.height = track.height+'px'; }); this.overview.style.height = overviewHeight + "px"; this.overviewBox = dojo.marginBox(this.overview); @@ -1520,8 +1589,14 @@ GenomeView.prototype.trimVertical = function(y) { } }; +GenomeView.prototype.redrawTracks = function() { + this.trackIterate( function(t) { t.hideAll(); } ); + this.showVisibleBlocks( true ); +}; + GenomeView.prototype.zoomIn = function(e, zoomLoc, steps) { if (this.animation) return; + this._unsetPosBeforeZoom(); if (zoomLoc === undefined) zoomLoc = 0.5; if (steps === undefined) steps = 1; steps = Math.min(steps, (this.zoomLevels.length - 1) - this.curZoom); @@ -1554,8 +1629,43 @@ GenomeView.prototype.zoomIn = function(e, zoomLoc, steps) { 700, zoomLoc); }; +/** WebApollo support for zooming directly to base level, and later restoring previous zoom level before zooming to base */ +GenomeView.prototype.zoomToBaseLevel = function(e, pos) { + if (this.animation) return; + // if (this.zoomLevels[this.curZoom] === this.charWidth) { console.log("already zoomed to base level"); return; } + // if at max zoomLevel then already zoomed to bases, so then no-op + var baseZoomIndex = this.zoomLevels.length - 1; + + if (this.curZoom === baseZoomIndex) { console.log("already zoomed to base level"); return; } + this._setPosBeforeZoom(this.minVisible(), this.maxVisible(), this.curZoom); + var zoomLoc = 0.5; + + this.showWait(); + this.trimVertical(); + + var relativeScale = this.zoomLevels[baseZoomIndex] / this.pxPerBp; + var fixedBp = pos; + this.curZoom = baseZoomIndex; + this.pxPerBp = this.zoomLevels[baseZoomIndex]; + + this.maxLeft = (this.pxPerBp * this.ref.end) - this.getWidth(); + + for (var track = 0; track < this.tracks.length; track++) + this.tracks[track].startZoom(this.pxPerBp, + fixedBp - ((zoomLoc * this.getWidth()) + / this.pxPerBp), + fixedBp + (((1 - zoomLoc) * this.getWidth()) + / this.pxPerBp)); + //YAHOO.log("centerBp: " + centerBp + "; estimated post-zoom start base: " + (centerBp - ((zoomLoc * this.getWidth()) / this.pxPerBp)) + ", end base: " + (centerBp + (((1 - zoomLoc) * this.getWidth()) / this.pxPerBp))); + new Zoomer(relativeScale, this, + function() {this.zoomUpdate(zoomLoc, fixedBp);}, + 700, zoomLoc); +}; + + GenomeView.prototype.zoomOut = function(e, zoomLoc, steps) { if (this.animation) return; + this._unsetPosBeforeZoom(); if (steps === undefined) steps = 1; steps = Math.min(steps, this.curZoom); if (0 == steps) return; @@ -1593,6 +1703,58 @@ GenomeView.prototype.zoomOut = function(e, zoomLoc, steps) { 700, zoomLoc); }; + +/** WebApollo support for zooming directly to base level, and later restoring previous zoom level before zooming to base */ +GenomeView.prototype.zoomBackOut = function(e) { + if (this.animation) { return; } + if (!this.isZoomedToBase()) { return; } + + var min = this.posBeforeZoom.min; + var max = this.posBeforeZoom.max; + var zoomIndex = this.posBeforeZoom.zoomIndex; + this.posBeforeZoom = undefined; + + var zoomLoc = 0.5; + this.showWait(); + + var scale = this.zoomLevels[zoomIndex] / this.pxPerBp; + var fixedBp = (min + max) / 2; + this.curZoom = zoomIndex; + this.pxPerBp = this.zoomLevels[zoomIndex]; + + for (var track = 0; track < this.tracks.length; track++) { + this.tracks[track].startZoom(this.pxPerBp, + fixedBp - ((zoomLoc * this.getWidth()) + / this.pxPerBp), + fixedBp + (((1 - zoomLoc) * this.getWidth()) + / this.pxPerBp)); + } + + this.minLeft = this.pxPerBp * this.ref.start; + var thisObj = this; + // Zooms take an arbitrary 700 milliseconds, which feels about right + // to me, although if the zooms were smoother they could probably + // get faster without becoming off-putting. -MS + new Zoomer(scale, this, + function() {thisObj.setLocation(thisObj.ref, min, max); thisObj.zoomUpdate(zoomLoc, fixedBp); }, + 700, zoomLoc); +}; + +/** WebApollo support for zooming directly to base level, and later restoring previous zoom level before zooming to base */ +GenomeView.prototype.isZoomedToBase = function() { + return this.posBeforeZoom !== undefined; +}; + +/** WebApollo support for zooming directly to base level, and later restoring previous zoom level before zooming to base */ +GenomeView.prototype._setPosBeforeZoom = function(min, max, zoomIndex) { + this.posBeforeZoom = { "min": min, "max": max, "zoomIndex": zoomIndex }; +}; + +/** WebApollo support for zooming directly to base level, and later restoring previous zoom level before zooming to base */ +GenomeView.prototype._unsetPosBeforeZoom = function() { + this.posBeforeZoom = undefined; +}; + GenomeView.prototype.zoomUpdate = function(zoomLoc, fixedBp) { var eWidth = this.elem.clientWidth; var centerPx = this.bpToPx(fixedBp) - (zoomLoc * eWidth) + (eWidth / 2); @@ -1671,15 +1833,18 @@ GenomeView.prototype.trackHeightUpdate = function(trackName, height) { this.trackHeights[track] = height; this.tracks[track].div.style.height = (height + this.trackPadding) + "px"; var nextTop = this.trackTops[track]; + var lastTop = 0; if (this.tracks[track].shown) nextTop += height + this.trackPadding; for (var i = track + 1; i < this.tracks.length; i++) { this.trackTops[i] = nextTop; this.tracks[i].div.style.top = nextTop + "px"; + lastTop = nextTop; if (this.tracks[i].shown) nextTop += this.trackHeights[i] + this.trackPadding; } - this.containerHeight = Math.max( nextTop||0, this.getY() + this.getHeight() ); + this.containerHeight = Math.max( nextTop||0, Math.min( this.getY(), lastTop ) + this.getHeight() ); this.scrollContainer.style.height = this.containerHeight + "px"; + this.setY( this.getY() ); this.updateStaticElements({ height: this.getHeight() }); }; @@ -1708,6 +1873,8 @@ GenomeView.prototype.showVisibleBlocks = function(updateHeight, pos, startX, end view.pxPerBp, containerStart, containerEnd); }); + + this.browser.publish( '/jbrowse/v1/n/tracks/redraw' ); }; /** @@ -1729,6 +1896,43 @@ GenomeView.prototype.showTracks = function( trackConfigs ) { this.updateTrackList(); }; +/** + * Replace the track configurations that are currently visible in the genome view. + * @param trackConfigs {Array[Object]} array of track configuration + * objects to add + */ +GenomeView.prototype.replaceTracks = function( trackConfigs ) { + // for each one + array.forEach( trackConfigs, function( conf ) { + // figure out its position in the genome view and delete it + var anchor; + var done; + var listNode = this.trackDndWidget.parent; + array.forEach( listNode.children, function( item ) { + if( done ) + return; + + var track = item.track; + if( track && (track.config.label == conf.label) ) { + done = 1; + this.trackDndWidget.delItem( item.id ); + if( item && item.parentNode ) + item.parentNode.removeChild(item); + } else { + anchor = item; + } + },this); + + this.updateTrackList(); + + // insert the new track config into the trackDndWidget after the 'before' + this.trackDndWidget.insertNodes( false, [conf], false, anchor ); + },this); + + if( trackConfigs.length ) + this.updateTrackList(); +}; + /** * Remove the given track (configs) from the genome view. * @param trackConfigs {Array[Object]} array of track configurations @@ -1741,8 +1945,8 @@ GenomeView.prototype.hideTracks = function( /**Array[String]*/ trackConfigs ) { },this); if( ! displayed.length ) return; - // insert the track configs into the trackDndWidget ( the widget - // will call create() on the confs to render them) + // remove the track configs from the trackDndWidget ( the widget + // will call create() on the confs to render them ) dojo.forEach( displayed, function( conf ) { this.trackDndWidget.forInItems(function(obj, id, map) { if( conf.label === obj.data.label ) { @@ -1802,12 +2006,12 @@ GenomeView.prototype.renderTrack = function( /**Object*/ trackConfig ) { } var cssName = function(str) { // replace weird characters and lowercase - return str.replace(/[^A-Za-z_]/g,'_').toLowerCase(); + return str.replace(/[^A-Za-z_0-9]/g,'_').toLowerCase(); }; var trackName = trackConfig.label; var trackDiv = dojo.create('div', { - className: ['track', cssName('track_'+trackClass), cssName('track_'+trackName)].join(' '), + className: ['track', cssName('track_'+trackConfig.type), cssName('track_'+trackName)].join(' '), id: "track_" + trackName }); trackDiv.trackName = trackName; @@ -1847,6 +2051,10 @@ GenomeView.prototype.renderTrack = function( /**Object*/ trackConfig ) { // parallel and have whichever one completes last do the actual // track making. + if( ! trackConfig.store ) + console.warn("configuration for track "+trackConfig.label+" has no store set", trackConfig ); + + // get the store this.browser.getStore( trackConfig.store, function( s ) { store = s; @@ -1919,7 +2127,7 @@ GenomeView.prototype.updateTrackList = function() { // publish a message if the visible tracks or their ordering has changed if( oldtracks != dojo.toJson( this.trackIndices || {} ) ) { - this.browser.publish( '/jbrowse/v1/v/tracks/changed', [this.visibleTrackNames()] ); + this.browser.publish( '/jbrowse/v1/n/tracks/visibleChanged', [this.visibleTrackNames()] ); this.showVisibleBlocks(); } }; diff --git a/src/JBrowse/Model/ArrayRepr.js b/src/JBrowse/Model/ArrayRepr.js index 31fb68bd4b..5a1c10d9fe 100644 --- a/src/JBrowse/Model/ArrayRepr.js +++ b/src/JBrowse/Model/ArrayRepr.js @@ -141,7 +141,7 @@ ArrayRepr.prototype.set = function(obj, attr, val) { if (attr in this.fields[obj[0]]) { obj[this.fields[obj[0]][attr]] = val; } else { - var adhocIndex = self.classes[obj[0]].length + 1; + var adhocIndex = this.classes[obj[0]].attributes.length + 1; if (adhocIndex >= obj.length) obj[adhocIndex] = {}; obj[adhocIndex][attr] = val; diff --git a/src/JBrowse/Model/FileBlob.js b/src/JBrowse/Model/FileBlob.js index cc29c9550e..bbf97e7ca8 100644 --- a/src/JBrowse/Model/FileBlob.js +++ b/src/JBrowse/Model/FileBlob.js @@ -21,14 +21,21 @@ var FileBlob = declare( null, }, slice: function(start, length) { - var sliceFunc = this.blob.webkitSlice || this.blob.mozSlice || this.blob.slice; - return new JBrowse.Model.Blob( + var sliceFunc = this.blob.mozSlice || this.blob.slice || this.blob.webkitSlice; + return new FileBlob( length ? sliceFunc.call( this.blob, start, start + length ) : sliceFunc.call( this.blob, start ) ); }, - fetch: function(callback) { + read: function( offset, length, callback, failCallback ) { + var start = this.start + offset, + end = start + length; + this.slice( offset, length ) + .fetch( callback, failCallback ); + }, + + fetch: function( callback, failCallback ) { var that = this, reader = new FileReader(); reader.onloadend = function(ev) { diff --git a/src/JBrowse/Model/Location.js b/src/JBrowse/Model/Location.js new file mode 100644 index 0000000000..e1191d556e --- /dev/null +++ b/src/JBrowse/Model/Location.js @@ -0,0 +1,28 @@ +define([ + 'JBrowse/Util' + ], + function( + Util + ) { + +return Util.fastDeclare( +{ + constructor: function( args ) { + if( args ) { + this.ref = args.ref; + this.start = args.start; + this.end = args.end; + this.strand = args.strand; + this.tracks = args.tracks; + } + }, + toString: function() { + return Util.assembleLocString(this); + }, + localeCompare: function( b ) { + var as = this.toString(); + var bs = b.toString(); + return as.localeCompare( bs ); + } +}); +}); \ No newline at end of file diff --git a/src/JBrowse/Model/SimpleFeature.js b/src/JBrowse/Model/SimpleFeature.js new file mode 100644 index 0000000000..98e0b0fc58 --- /dev/null +++ b/src/JBrowse/Model/SimpleFeature.js @@ -0,0 +1,51 @@ +define([ + 'JBrowse/Util' + ], + function( Util ) { + +var counter = 0; + +return Util.fastDeclare({ + + constructor: function( args ) { + args = args || {}; + this.data = args.data || {}; + this._uniqueID = args.id || 'SimpleFeature_'+(counter++); + this._parent = args.parent; + }, + + get: function(name) { + return this.data[ name ]; + }, + + set: function( name, val ) { + this.data[ name ] = val; + }, + + tags: function() { + var t = []; + var d = this.data; + for( var k in d ) { + if( d.hasOwnProperty( k ) ) + t.push( k ); + } + return t; + }, + + id: function( newid ) { + if( newid ) + this._uniqueID = newid; + return this._uniqueID; + }, + + parent: function() { + return this._parent; + }, + + children: function() { + return this.get('subfeatures'); + } + +}); + +}); \ No newline at end of file diff --git a/src/JBrowse/Store/Hash.js b/src/JBrowse/Store/Hash.js new file mode 100644 index 0000000000..a4daee96b8 --- /dev/null +++ b/src/JBrowse/Store/Hash.js @@ -0,0 +1,94 @@ +define( [ + 'dojo/_base/declare', + 'dojo/_base/array', + 'dojo/_base/Deferred', + 'dojo/store/JsonRest', + 'dojo/store/util/QueryResults', + 'JBrowse/Digest/Crc32' + ], + function( + declare, + array, + Deferred, + dojoJSONRest, + QueryResults, + digest + ) { + +return declare( null, { + + constructor: function( args ) { + // make sure url has a trailing slash + var url = /\/$/.test( args.url ) ? args.url : args.url + '/'; + this.bucketStore = new dojoJSONRest({ + target: url + }); + + this.meta = {}; + + this.browser = args.browser; + + // this.ready is a Deferred that will be resolved when we have + // read the meta.json file with the params of this hashstore + this.ready = this._readMeta(); + }, + + _readMeta: function() { + var thisB = this; + return this.bucketStore.get( 'meta.json' ) + .then( function( meta ) { + dojo.mixin( thisB.meta, meta || {} ); + thisB.meta.hash_hex_characters = Math.ceil( thisB.meta.hash_bits / 4 ); + }); + }, + + query: function( query, options ) { + return this.get( (query.name || '').toString() ) + .then( function( value ) { + return QueryResults( (value||{}).exact || [] ); + }); + }, + + get: function( key ) { + return this._getBucket(key) + .then( function( bucket ) { + return bucket[key]; + }); + }, + + _getBucket: function( key ) { + var thisB = this; + var bucketP = new Deferred(); + this.ready.then( function() { + var bucketIdent = thisB._hash( key ); + thisB.bucketStore.get( thisB._hexToDirPath( bucketIdent ) ) + .then(function(d) { bucketP.resolve(d); } ); + }); + + return bucketP; + }, + + _hexToDirPath: function( hex ) { + // zero-pad the hex string to be 8 chars if necessary + while( hex.length < 8 ) + hex = '0'+hex; + hex = hex.substr( 8-this.meta.hash_hex_characters ); + var dirpath = []; + for( var i = 0; i < hex.length; i += 3 ) { + dirpath.push( hex.substring( i, i+3 ) ); + } + return dirpath.join('/') + '.json'; + }, + + _hash: function( data ) { + return digest.objectFingerprint( data ) + .toString(16) + .toLowerCase() + .replace('-','n'); + }, + + getIdentity: function( object ) { + return object.id; + } +}); +}); \ No newline at end of file diff --git a/src/JBrowse/Store/LRUCache.js b/src/JBrowse/Store/LRUCache.js index f705bbd7ad..7e89bae5d5 100644 --- a/src/JBrowse/Store/LRUCache.js +++ b/src/JBrowse/Store/LRUCache.js @@ -58,7 +58,7 @@ return declare( null, return; } else { - this._log( 'hit', keyString, record.value ); + this._log( 'hit', keyString ); this._touch( record ); window.setTimeout( function() { callback( record.value ); @@ -139,7 +139,7 @@ return declare( null, try { cb.call( this, value, error ); } catch(x) { - console.error(x); + console.error(''+x, x.stack, x); } }, this ); }, keyString, inKey, fillRecord )); diff --git a/src/JBrowse/Store/NCList.js b/src/JBrowse/Store/NCList.js index c710b562e3..8a082c3887 100644 --- a/src/JBrowse/Store/NCList.js +++ b/src/JBrowse/Store/NCList.js @@ -20,6 +20,7 @@ After */ function NCList() { + this.topList = []; } NCList.prototype.importExisting = function(nclist, attrs, baseURL, @@ -34,10 +35,23 @@ NCList.prototype.importExisting = function(nclist, attrs, baseURL, this.lazyChunks = {}; }; +/** + * + * Given an array of features, creates the nested containment list data structure + * WARNING: DO NOT USE directly for adding additional intervals! + * completely replaces existing nested containment structure + * (erases current topList and subarrays, repopulates from intervals) + * currently assumes each feature is array as described above + */ NCList.prototype.fill = function(intervals, attrs) { //intervals: array of arrays of [start, end, ...] //attrs: an ArrayRepr object //half-open? + if (intervals.length == 0) { + this.topList = []; + return; + } + this.attrs = attrs; this.start = attrs.makeFastGetter("Start"); this.end = attrs.makeFastGetter("End"); @@ -48,7 +62,7 @@ NCList.prototype.fill = function(intervals, attrs) { //sort by OL myIntervals.sort(function(a, b) { if (start(a) != start(b)) - return start(a) - start(b()); + return start(a) - start(b); else return end(b) - end(a); }); @@ -56,6 +70,7 @@ NCList.prototype.fill = function(intervals, attrs) { var curList = new Array(); this.topList = curList; curList.push(myIntervals[0]); + if (myIntervals.length == 1) return; var curInterval, topSublist; for (var i = 1, len = myIntervals.length; i < len; i++) { curInterval = myIntervals[i]; @@ -127,7 +142,7 @@ NCList.prototype.iterHelper = function(arr, from, to, fun, finish, finish.inc(); Util.maybeLoad({ url: Util.resolveUrl(this.baseURL, this.lazyUrlTemplate.replace( - /\{Chunk\}/g, chunkNum + /\{Chunk\}/ig, chunkNum ) ), handleAs: 'json' }, @@ -169,8 +184,12 @@ NCList.prototype.iterate = function(from, to, fun, postFun) { //testGet: test on start or end var testGet = (from > to) ? this.end : this.start; var finish = new Finisher(postFun); + + + if (this.topList.length > 0) { this.iterHelper(this.topList, from, to, fun, finish, inc, searchGet, testGet, [0]); + } finish.finish(); }; diff --git a/src/JBrowse/Store/Names/Hash.js b/src/JBrowse/Store/Names/Hash.js new file mode 100644 index 0000000000..f61dc9805a --- /dev/null +++ b/src/JBrowse/Store/Names/Hash.js @@ -0,0 +1,175 @@ +define( [ + 'dojo/_base/declare', + 'dojo/_base/array', + 'dojo/store/util/QueryResults', + 'JBrowse/Util', + 'JBrowse/Store/Hash', + 'JBrowse/Model/Location' + ], + function( + declare, + array, + QueryResults, + Util, + HashStore, + Location + ) { + +return declare( HashStore, +{ + + constructor: function( args ) { + + this.tooManyMatchesMessage = args.tooManyMatchesMessage || '(too many matches to display)'; + + // generate stopPrefixes + var stopPrefixes = this.stopPrefixes = {}; + // make our stopPrefixes an object as { prefix: true, ... } + // with all possible prefixes of our stop prefixes + if( args.stopPrefixes ) { + var prefixesInput = typeof args.stopPrefixes == 'string' + ? [ args.stopPrefixes ] : args.stopPrefixes; + + dojo.forEach( prefixesInput, function(prefix) { + while( prefix.length ) { + stopPrefixes[prefix] = true; + prefix = prefix.substr( 0, prefix.length - 1 ); + } + }); + } + }, + + _nameRecordToItem: function( nameRecord ) { + if( nameRecord.hitLimit ) { + // it's a too-many-matches marker + return { name: this.tooManyMatchesMessage, hitLimit: true }; + } + else { + // it's an actual name record + var item = {}; + if( typeof nameRecord == 'object' ) { + item.name = nameRecord[0]; + var trackConfig = this._findTrackConfig( ((this.meta||{}).track_names||{})[ nameRecord[1] ] ); + item.location = new Location({ + ref: nameRecord[3], + start: parseInt( nameRecord[4] ), + end: parseInt( nameRecord[5] ), + tracks: [ trackConfig ] + }); + } else { + item.name = nameRecord; + } + return item; + } + }, + + // look in the browser's track configuration for the track with the given label + _findTrackConfig: function( trackLabel ) { + if( ! trackLabel ) + return null; + + var track = null; + var i = array.some( this.browser.config.tracks, function( t ) { + if( t.label == trackLabel ) { + track = t; + return true; + } + return false; + }); + + return track; + }, + + _makeResults: function( nameRecords ) { + // convert the name records into dojo.store-compliant data + // items, sort them by name and location + var results = array.map( nameRecords, dojo.hitch(this,'_nameRecordToItem') ) + .sort( function( a, b ) { + return a.name.localeCompare( b.name ) + || a.location.localeCompare( b.location ); + }); + + var last; + var hitLimit; + + // aggregate them and make labels for them. for names with + // multiple locations, make a multipleLocations member. + results = array.filter( results, function( i ) { + if( i.hitLimit ) { + hitLimit = i; + if( ! hitLimit.label ) + hitLimit.label = hitLimit.name || 'too many matches'; + return false; + } + else if( last && last.name == i.name ) { + last.label = last.name + ' multiple locations'; + if( last.multipleLocations ) { + last.multipleLocations.push( i.location ); + } else { + last.multipleLocations = [last.location,i.location]; + delete last.location; + } + return false; + } + last = i; + last.label = last.name + + ( last.location ? ' '+last.location+'' + : '' + ); + return true; + }); + + if( hitLimit ) + results.push( hitLimit ); + + return QueryResults( results ); + }, + + // case-insensitive, and supports prefix queries like 'foo*' + query: function( query, options ) { + // remove trailing asterisks from query.name + var thisB = this; + var name = ( query.name || '' ).toString(); + + // lowercase the name if the store is all-lowercase + if( this.meta.lowercase_keys ) + name = name.toLowerCase(); + + var trailingStar = /\*$/; + if( trailingStar.test( name ) ) { + name = name.replace( trailingStar, '' ); + return this._getEntry( name ) + .then( function( value ) { + value = value || {}; + return thisB._makeResults( ( value.exact || [] ).concat( value.prefix || [] ) ); + }); + } + else { + return this._getEntry( name ) + .then( function( value ) { + return thisB._makeResults( (value||{}).exact || [] ); + }); + } + }, + + get: function( id ) { + // lowercase the id if the store is all-lowercase + if( this.meta.lowercase_keys ) + id = id.toLowerCase(); + + return this._getEntry( id ) + .then( function( bucket ) { + var nameRec = (bucket.exact||[])[0]; + return nameRec ? this._nameRecordToItem( nameRec ) : null; + }); + }, + + _getEntry: function( key ) { + return this._getBucket(key) + .then( function( bucket ) { + return bucket[key]; + }); + } + +}); +}); diff --git a/src/JBrowse/Store/Autocomplete.js b/src/JBrowse/Store/Names/LazyTrieDojoData.js similarity index 56% rename from src/JBrowse/Store/Autocomplete.js rename to src/JBrowse/Store/Names/LazyTrieDojoData.js index a943384792..f5d1e9c65f 100644 --- a/src/JBrowse/Store/Autocomplete.js +++ b/src/JBrowse/Store/Names/LazyTrieDojoData.js @@ -1,4 +1,19 @@ -define(['dojo/_base/declare'],function(declare) { +/** + * dojo.data.api.Read-compatible store object that reads data from an + * encapsulated JBrowse/Store/LazyTrie. + */ + +define([ + 'dojo/_base/declare', + 'dojo/_base/array', + 'JBrowse/Util', + 'JBrowse/Model/Location' + ],function( + declare, + array, + Util, + Location + ) { return declare( null, /** * @lends JBrowse.Store.Autocomplete.prototype @@ -6,6 +21,10 @@ return declare( null, { /** * @constructs + * @param args.namesTrie + * @param args.stopPrefixes + * @param args.resultLimit + * @param args.tooManyMatchesMessage */ constructor: function( /**Object*/ args ) { if( ! args.namesTrie ) @@ -50,11 +69,22 @@ return declare( null, }; }, + getFeatures: function() { + return { + 'dojo.data.api.Read': true, + 'dojo.data.api.Identity': true + }; + }, + + getIdentity: function( node ) { + console.log( node ); + }, + // dojo.data.api.Read support fetch: function( /**Object*/ request ) { var start = request.start || 0; - var matchLimit = Math.min( this.resultLimit, Math.max(0, request.count) ); + var matchLimit = Math.min( this.resultLimit, Math.max(0, request.count || Infinity ) ); var matchesRemaining = matchLimit; var scope = request.scope || dojo.global; var aborted = false; @@ -71,42 +101,64 @@ return declare( null, if( ! request.store ) request.store = this; - var gotTree = false; // stays false if tree isn't found - var matches = []; - var prefix = (request.query.name || '').replace(/\*$/,''); + if( request.onBegin ) + request.onBegin.call( scope, 0, request ); + + var prefix = (request.query.name || '').toString().replace(/\*$/,''); if( ! this.stopPrefixes[ prefix ] ) { this.namesTrie.mappingsFromPrefix( prefix, dojo.hitch( this, function(tree) { - gotTree = true; + var matches = []; + + if( aborted ) + return; + + // are we working with a post-JBrowse 1.4 data structure? + var post1_4 = tree[0] && tree[0][1] && tree[0][1][0] && typeof tree[0][1][0][0] == 'string'; + // use dojo.some so that we can break out of the loop when we hit the limit dojo.some( tree, function(node) { if( matchesRemaining-- ) { - matches.push({ name: this.nodeText(node) }); + var name = this.nodeText(node); + array.forEach( node[1], function(n) { + var location = new Location({ + ref: n[ post1_4 ? 3 : 2 ], + start: parseInt( n[ post1_4 ? 4 : 3 ]), + end: parseInt( n[ post1_4 ? 5 : 4 ]), + tracks: [ this.namesTrie.extra[ n[ post1_4 ? 1 : 0 ] ] ] + }); + + matches.push({ + name: name, + location: location + }); + },this); } return matchesRemaining < 0; },this); - })); - } - // if we found more than the match limit - if( matchesRemaining < 0 ) - matches.push({ name: this.tooManyMatchesMessage, hitLimit: true }); - - if( request.onBegin ) - request.onBegin.call( scope, matches.length, request ); - if( request.sort ) - matches.sort(dojo.data.util.sorter.createSortFunction(request.sort, this)); - if( request.onItem ) { - dojo.forEach( matches, function( item ) { - if( !aborted ) - request.onItem.call( scope, item, request ); - }); + // if we found more than the match limit + if( matchesRemaining < 0 ) + matches.push({ name: this.tooManyMatchesMessage, hitLimit: true }); + + if( request.sort ) + matches.sort( dojo.data.util.sorter.createSortFunction(request.sort, this) ); + if( !aborted && request.onItem ) + dojo.forEach( matches, function( item ) { + if( !aborted ) + request.onItem.call( scope, item, request ); + }); + if( !aborted && request.onComplete ) + request.onComplete.call( scope, matches, request ); + })); } - if(request.onComplete && !aborted){ - request.onComplete.call( scope, matches, request ); - } + else if( request.onComplete ) { + request.onComplete.call( scope, [], request ); + } + + return request; }, getValue: function( i, attr, defaultValue ) { @@ -119,7 +171,7 @@ return declare( null, }, getAttributes: function(item) { - return dojof.keys( item ); + return Util.dojof.keys( item ); }, hasAttribute: function(item,attr) { @@ -148,6 +200,11 @@ return declare( null, }, getLabelAttributes: function(i) { return ['name']; + }, + + getIdentity: function(i) { + return this.getLabel(i); } + }); }); \ No newline at end of file diff --git a/src/JBrowse/Store/RemoteBinaryFile.js b/src/JBrowse/Store/RemoteBinaryFile.js index c7000f8ff5..645cbed0b8 100644 --- a/src/JBrowse/Store/RemoteBinaryFile.js +++ b/src/JBrowse/Store/RemoteBinaryFile.js @@ -1,10 +1,11 @@ define([ 'dojo/_base/declare', 'dojo/_base/array', + 'dojo/has', 'JBrowse/Store/LRUCache', 'jszlib/arrayCopy' ], - function( declare, array, LRUCache, arrayCopy ) { + function( declare, array, has, LRUCache, arrayCopy ) { // contains chunks of files, stitches them together if necessary, wraps, and returns them // to satisfy requests @@ -190,7 +191,20 @@ return declare( null, var req = new XMLHttpRequest(); var length; - req.open('GET', request.url, true); + var url = request.url; + + // Safari browsers cache XHRs to a single resource, regardless + // of the byte range. So, requesting the first 32K, then + // requesting second 32K, can result in getting the first 32K + // twice. Seen first-hand on Safari 6, and @dasmoth reports + // the same thing on mobile Safari on IOS. So, if running + // Safari, put the byte range in a query param at the end of + // the URL to force Safari to pay attention to it. + if( has('safari') && request.end ) { + url = url + ( url.indexOf('?') > -1 ? '&' : '?' ) + 'safari_range=' + request.start +'-'+request.end; + } + + req.open('GET', url, true ); if( req.overrideMimeType ) req.overrideMimeType('text/plain; charset=x-user-defined'); if (request.end) { @@ -233,8 +247,11 @@ return declare( null, return; } } catch (x) { - console.error(''+x); - respond( null ); + console.error(''+x, x.stack, x); + // the response must have successful but + // empty, so respond with a zero-length + // arraybuffer + respond( new ArrayBuffer() ); return; } }).call(this); @@ -273,14 +290,19 @@ return declare( null, start, end, dojo.hitch( this, function( chunks ) { + + var totalSize = this.totalSizes[ args.url ]; + this._assembleChunks( start, end, - function() { + function( resultBuffer ) { + if( typeof totalSize == 'number' ) + resultBuffer.fileSize = totalSize; try { - args.success.apply( this, arguments ); + args.success.call( this, resultBuffer ); } catch( e ) { - console.error(''+e); + console.error(''+e, e.stack, e); if( args.failure ) args.failure( e ); } @@ -330,6 +352,9 @@ return declare( null, returnBuffer = new Uint8Array( fetchLength ); var cursor = 0; array.forEach( chunks, function( chunk ) { + if( !( chunk.value && chunk.value.byteLength ) ) // skip if the chunk has no data + return; + var b = new Uint8Array( chunk.value ); var bOffset = (start+cursor) - chunk.key.start; if( bOffset < 0 ) this._error('chunking error'); var length = Math.min( b.byteLength - bOffset, fetchLength - cursor ); diff --git a/src/JBrowse/Store/SeqFeature/BAM.js b/src/JBrowse/Store/SeqFeature/BAM.js index 33855f2116..5ae42d3b5f 100644 --- a/src/JBrowse/Store/SeqFeature/BAM.js +++ b/src/JBrowse/Store/SeqFeature/BAM.js @@ -26,6 +26,9 @@ var BAMStore = declare( [ SeqFeatureStore, DeferredStatsMixin, DeferredFeaturesM * @constructs */ constructor: function( args ) { + + this.createSubfeatures = args.subfeatures; + var bamBlob = args.bam || (function() { var url = Util.resolveUrl( args.baseUrl || '/', @@ -51,7 +54,8 @@ var BAMStore = declare( [ SeqFeatureStore, DeferredStatsMixin, DeferredFeaturesM bai: baiBlob }); - this.source = bamBlob.url ? bamBlob.url.match( /\/([^/\#\?]+)($|[\#\?])/ )[1] : undefined; + this.source = ( bamBlob.url ? bamBlob.url.match( /\/([^/\#\?]+)($|[\#\?])/ )[1] : + bamBlob.blob ? bamBlob.blob.name : undefined ) || undefined; this.bam.init({ success: dojo.hitch( this, '_estimateGlobalStats', @@ -78,8 +82,8 @@ var BAMStore = declare( [ SeqFeatureStore, DeferredStatsMixin, DeferredFeaturesM var statsFromInterval = function( refSeq, length, callback ) { var sampleCenter = refSeq.start*0.75 + refSeq.end*0.25; - var start = Math.round( sampleCenter - length/2 ); - var end = Math.round( sampleCenter + length/2 ); + var start = Math.max( 0, Math.round( sampleCenter - length/2 ) ); + var end = Math.min( Math.round( sampleCenter + length/2 ), refSeq.end ); this.bam.fetch( refSeq.name, start, end, dojo.hitch( this, function( features, error) { if ( error ) { console.error( error ); @@ -135,7 +139,12 @@ var BAMStore = declare( [ SeqFeatureStore, DeferredStatsMixin, DeferredFeaturesM var feature = features[i]; // skip if this alignment is unmapped, or if it does not actually overlap this range if (! (feature.get('unmapped') || feature.get('end') <= start || feature.get('start') >= end) ) - featCallback( feature ); + try { + featCallback( feature ); + } catch(e) { + errorCallback( e ); + return; + } if( i && !( i % maxFeaturesWithoutYielding ) ) { window.setTimeout( readFeatures, 1 ); diff --git a/src/JBrowse/Store/SeqFeature/BAM/Feature.js b/src/JBrowse/Store/SeqFeature/BAM/Feature.js deleted file mode 100644 index 1c5d7fcae0..0000000000 --- a/src/JBrowse/Store/SeqFeature/BAM/Feature.js +++ /dev/null @@ -1,384 +0,0 @@ -define( ['dojo/_base/array', - 'JBrowse/Util', - './Util' - ], - function( array, Util, BAMUtil ) { - - -var SEQRET_DECODER = ['=', 'A', 'C', 'x', 'G', 'x', 'x', 'x', 'T', 'x', 'x', 'x', 'x', 'x', 'x', 'N']; -var CIGAR_DECODER = ['M', 'I', 'D', 'N', 'S', 'H', 'P', '=', 'X', '?', '?', '?', '?', '?', '?', '?']; - -var readInt = BAMUtil.readInt; -var readShort = BAMUtil.readShort; -var readFloat = BAMUtil.readFloat; - -var Feature = Util.fastDeclare( - -/** - * @lends JBrowse.Store.BAM.Feature - */ -{ - - /** - * Feature object used for the JBrowse BAM backend. - * @param args.store the BAM store this feature comes from - * @param args.record optional BAM record (a plain object) containing the data for this feature - * @constructs - */ - constructor: function( args ) { - this.file = args.file; - this.store = args.store; - - var data = args.data - || args.bytes && this._fromBytes( args.bytes.byteArray, args.bytes.start, args.bytes.end ) - || args.record && dojo.clone(args.record); - - // figure out start and end - data.start = data.start || data.pos; - data.end = data.end || ( data.length_on_ref ? data.pos + data.length_on_ref : data.seq ? data.pos + data.seq.length : undefined ); - - // trying to determine orientation from 'XS' optional field, - // or from the seq_reverse_complemented flag - data.strand = ('XS' in data ) ? ( data.XS == '-' ? -1 : 1 ) : - data.seq_reverse_complemented ? -1 : - 1; - - data.score = data.mapping_quality || data.MQ || data.mq; - data.type = data.type || 'match'; - data.source = args.store.source; - - if( data.qual && data.qual.join ) - data.qual = data.qual.join(' '); - - if( data.readName ) { - data.name = data.readName; - delete data.readName; - } - delete data.pos; - - this._refID = data._refID; - delete data._refID; - - this.data = data; - this._subCounter = 0; - this._uniqueID = args.parent ? args.parent._uniqueID + '-' + ++args.parent._subCounter - : this.data.name+' at '+ data.seq_id + ':' + data.start + '..' + data.end; - - // var cigar = data.CIGAR || data.cigar; - // this.data.subfeatures = []; - // if( cigar ) { - // this.data.Gap = this._cigarToGap( cigar ); - // this.data.subfeatures.push.apply( this.data.subfeatures, this._cigarToSubfeats( cigar, this ) ); - // } - }, - - _fromBytes: function( byteArray, blockStart, blockEnd ) { - var record = {}; - - var refID = readInt(byteArray, blockStart + 4); - var pos = readInt(byteArray, blockStart + 8); - - var bmn = readInt(byteArray, blockStart + 12); - //var bin = (bmn & 0xffff0000) >> 16; - var mq = (bmn & 0xff00) >> 8; - var nl = bmn & 0xff; - - var flag_nc = readInt(byteArray, blockStart + 16); - this._decodeFlags( record, (flag_nc & 0xffff0000) >> 16 ); - - record.template_length = readInt(byteArray, blockStart + 32); - - var lseq = readInt(byteArray, blockStart + 20); - record.seq_length = lseq; - - // If the read is unmapped, no assumptions can be made about RNAME, POS, - // CIGAR, MAPQ, bits 0x2, 0x10 and 0x100 and the bit 0x20 of the next - // segment in the template. - var numCigarOps = flag_nc & 0xffff; - - // if this is a multi-segment read (e.g. mate pairs), parse - // out the position of the next segment and format it as a - // locstring - if( record.multi_segment_template ) { - var nextRefID = readInt(byteArray, blockStart + 24); - var nextSegment = this.file.indexToChr[nextRefID]; - if( nextSegment ) - record.next_segment_position = nextSegment.name+':'+readInt(byteArray, blockStart + 28); - } - - if( ! record.unmapped ) { - var readName = ''; - for (var j = 0; j < nl-1; ++j) { - readName += String.fromCharCode(byteArray[blockStart + 36 + j]); - } - } - - var p = blockStart + 36 + nl; - var cigar = ''; - var lref = 0; - for (var c = 0; c < numCigarOps; ++c) { - var cigop = readInt(byteArray, p); - var lop = cigop >> 4; - var op = CIGAR_DECODER[cigop & 0xf]; - cigar = cigar + lop + op; - switch (op) { - case 'M': - case 'D': - case 'N': - case '=': - case 'X': - lref += lop; - break; - } - p += 4; - } - if( ! record.unmapped ) { - record.cigar = cigar; - record.length_on_ref = lref; - } - - var seq = ''; - var seqBytes = (lseq + 1) >> 1; - for (var j = 0; j < seqBytes; ++j) { - var sb = byteArray[p + j]; - seq += SEQRET_DECODER[(sb & 0xf0) >> 4]; - seq += SEQRET_DECODER[(sb & 0x0f)]; - } - p += seqBytes; - record.seq = seq; - - if( ! record.unmapped ) { - var qseq = []; - for (var j = 0; j < lseq; ++j) { - qseq.push( byteArray[p + j] ); - } - } - - p += lseq; - - if( ! record.unmapped ) { - record.qual = qseq; - - record.pos = pos; - if( mq != 255 ) // value of 255 means MQ is not available - record.mapping_quality = mq; - record.readName = readName; - - record.seq_id = this.file.indexToChr[refID]; - if( record.seq_id ) - record.seq_id = record.seq_id.name; - - record._refID = refID; - } - - while (p <= blockEnd) { - var tag = String.fromCharCode(byteArray[p]) + String.fromCharCode(byteArray[p + 1]); - var origType = String.fromCharCode(byteArray[p + 2]); - var type = origType.toLowerCase(); - p += 3; - - var value; - if (type == 'a') { - value = String.fromCharCode( byteArray[p] ); - p += 1; - } else if (type == 'i' ) { - value = readInt(byteArray, p ); - p += 4; - } else if (type == 'c' ) { - value = byteArray[p]; - p += 1; - } else if (type == 's' ) { - value = readShort(byteArray, p); - p += 2; - } else if (type == 'f') { - value = readFloat( byteArray, p ); - p += 4; - } else if ( type == 'z' || type == 'h' ) { - value = ''; - while( true ) { - var cc = byteArray[p++]; - if( cc == 0 ) { - break; - } else { - value += String.fromCharCode(cc); - } - } - } else { - console.warn( "Unknown BAM tag type '"+origType - +'\', tags for '+(readName||'(unnamed read)') - +' may be incomplete' - ); - value = undefined; - p = blockEnd+1; // stop parsing tags - } - record[tag] = value; - } - return record; - }, - - /** - * Decode the BAM flags field and set them in the record. - */ - _decodeFlags: function( record, flags ) { - // the following explanations are taken verbatim from the SAM/BAM spec - - // 0x1 template having multiple segments in sequencing - // If 0x1 is unset, no assumptions can be made about 0x2, 0x8, 0x20, - // 0x40 and 0x80. - if( flags & 0x1 ) { - record.multi_segment_template = true; - // 0x2 each segment properly aligned according to the aligner - record.multi_segment_all_aligned = !!( flags & 0x2 ); - // 0x8 next segment in the template unmapped - record.multi_segment_next_segment_unmapped = !!( flags & 0x8 ); - // 0x20 SEQ of the next segment in the template being reversed - record.multi_segment_next_segment_reversed = !!( flags & 0x20 ); - - // 0x40 the first segment in the template - var first = !!( flags & 0x40 ); - // 0x80 the last segment in the template - var last = !!( flags & 0x80 ); - // * If 0x40 and 0x80 are both set, the segment is part of a linear - // template, but it is neither the first nor the last segment. If both - // 0x40 and 0x80 are unset, the index of the segment in the template is - // unknown. This may happen for a non-linear template or the index is - // lost in data processing. - if( first && last ) { - record.multi_segment_inner = true; - } - else if( first && !last ) { - record.multi_segment_first = true; - } - else if( !first && last ) { - record.multi_segment_last = true; - } - else { - record.multi_segment_index_unknown = true; - } - } - - // 0x4 segment unmapped - // * Bit 0x4 is the only reliable place to tell whether the segment is - // unmapped. If 0x4 is set, no assumptions can be made about RNAME, POS, - // CIGAR, MAPQ, bits 0x2, 0x10 and 0x100 and the bit 0x20 of the next - // segment in the template. - // only set unmapped if true - if( flags & 0x4 ) { - record.unmapped = true; - } else { - // 0x10 SEQ being reverse complemented - record.seq_reverse_complemented = !!(flags & 0x10); - - // 0x100 secondary alignment - // * Bit 0x100 marks the alignment not to be used in certain analyses - // when the tools in use are aware of this bit. - if( flags & 0x100 ) - record.secondary_alignment = true; - } - - // 0x200 not passing quality controls - // only set qc_failed if it is true - if( flags & 0x200 ) - record.qc_failed = true; - - // 0x400 PCR or optical duplicate - // only set duplicate if true - if ( flags & 0x400 ) - record.duplicate = true; - }, - - _parseCigar: function( cigar ) { - return array.map( cigar.match(/\d+\D/g), function( op ) { - return [ op.match(/\D/)[0].toUpperCase(), parseInt( op ) ]; - }); - }, - - /** - * take a cigar string, and initial position, return an array of subfeatures - */ - _cigarToSubfeats: function(cigar, parent) { - var subfeats = []; - var min = parent.get('start'); - var max; - var ops = this._parseCigar( cigar ); - for (var i = 0; i < ops.length; i++) { - var lop = ops[i][1]; - var op = ops[i][0]; // operation type - // converting "=" to "E" to avoid possible problems later with non-alphanumeric type name - if (op === "=") { op = "E"; } - - switch (op) { - case 'M': - case 'D': - case 'N': - case 'E': - case 'X': - max = min + lop; - break; - case 'I': - max = min; - break; - case 'P': // not showing padding deletions (possibly change this later -- could treat same as 'I' ?? ) - case 'H': // not showing hard clipping (since it's unaligned, and offset arg meant to be beginning of aligned part) - case 'S': // not showing soft clipping (since it's unaligned, and offset arg meant to be beginning of aligned part) - break; - // other possible cases - } - var subfeat = new Feature({ - store: this.store, - file: this.file, - data: { - type: 'match_part', - start: min, - end: max, - strand: parent.get('strand'), - cigar_op: lop+op - }, - parent: this - }); - if (op !== 'N') { - subfeats.push(subfeat); - } - min = max; - } - return subfeats; - }, - - /** - * Takes a CIGAR string, translates to a GFF3 Gap attribute - */ - _cigarToGap: function(cigar) { - return array.map( this._parseCigar( cigar ), function( op ) { - return ( { - // map the CIGAR operations to the less-descriptive - // GFF3 gap operations - M: 'M', - I: 'I', - D: 'D', - N: 'D', - S: 'M', - H: 'M', - P: 'I' - }[op[0]] || op[0] - )+op[1]; - }).join(' '); - }, - - get: function(name) { - return this.data[ name ]; - }, - - tags: function() { - var t = []; - var d = this.data; - for( var k in d ) { - if( d.hasOwnProperty( k ) ) - t.push( k ); - } - return t; - } - -}); - -return Feature; -}); diff --git a/src/JBrowse/Store/SeqFeature/BAM/File.js b/src/JBrowse/Store/SeqFeature/BAM/File.js index 5607edc795..ab5c9c7c91 100644 --- a/src/JBrowse/Store/SeqFeature/BAM/File.js +++ b/src/JBrowse/Store/SeqFeature/BAM/File.js @@ -4,7 +4,7 @@ define( [ 'JBrowse/Util', 'JBrowse/Store/LRUCache', './Util', - './Feature' + './LazyFeature' ], function( declare, array, Util, LRUCache, BAMUtil, BAMFeature ) { @@ -124,17 +124,19 @@ var BamFile = declare( null, for (var b = 0; b < nbin; ++b) { var bin = readInt(uncba, p); var nchnk = readInt(uncba, p+4); - p += 8 + (nchnk * 16); + p += 8; + for( var chunkNum = 0; chunkNum < nchnk; chunkNum++ ) { + var vo = readVirtualOffset( uncba, p ); + this._findMinAlignment( vo ); + p += 16; + } } var nintv = readInt(uncba, p); p += 4; - // as we're going through the index, figure out the smallest - // virtual offset in the indexes, which tells us where - // the BAM header ends - var firstVO = nintv ? readVirtualOffset(uncba,p) : null; - if( firstVO && ( ! this.minAlignmentVO || this.minAlignmentVO.cmp( firstVO ) < 0 ) ) - this.minAlignmentVO = firstVO; - - //console.log( ref, ''+firstVO ); + // as we're going through the linear index, figure out + // the smallest virtual offset in the indexes, which + // tells us where the BAM header ends + this._findMinAlignment( nintv ? readVirtualOffset(uncba,p) : null ); + p += nintv * 8; if( nbin > 0 || nintv > 0 ) { this.indices[ref] = new Uint8Array(header, blockStart, p - blockStart); @@ -147,17 +149,29 @@ var BamFile = declare( null, }), failCallback ); }, + _findMinAlignment: function( candidate ) { + if( candidate && ( ! this.minAlignmentVO || this.minAlignmentVO.cmp( candidate ) < 0 ) ) + this.minAlignmentVO = candidate; + }, + _readBAMheader: function( successCallback, failCallback ) { + // We have the virtual offset of the first alignment + // in the file. Cannot completely determine how + // much of the first part of the file to fetch to get just + // up to that, since the file is compressed. Thus, fetch + // up to the start of the BGZF block that the first + // alignment is in, plus 64KB, which should get us that whole + // BGZF block, assuming BGZF blocks are no bigger than 64KB. this.data.read( 0, - this.minAlignmentVO ? this.minAlignmentVO.block : null, + this.minAlignmentVO ? this.minAlignmentVO.block + 65535 : null, dojo.hitch( this, function(r) { var unc = BAMUtil.unbgzf(r); var uncba = new Uint8Array(unc); if( readInt(uncba, 0) != BAM_MAGIC) { dlog('Not a BAM file'); - failCallback(); + failCallback( 'Not a BAM file' ); return; } @@ -309,17 +323,8 @@ var BamFile = declare( null, return this.join(', '); }; - this.featureCache = this.featureCache || new LRUCache({ - name: 'bamFeatureCache', - fillCallback: dojo.hitch(this, '_fetchChunkFeatures' ), - sizeFunction: function( features ) { - return features.length; - }, - maxSize: 100000 // cache up to 100,000 BAM features - }); - try { - this.featureCache.get( chunks, function( features, error ) { + this._fetchChunkFeatures( chunks, function( features, error ) { if( error ) { callback( null, error ); } else { @@ -337,33 +342,49 @@ var BamFile = declare( null, _fetchChunkFeatures: function( chunks, callback ) { var thisB = this; - var features = []; - var chunksProcessed = 0; if( ! chunks.length ) { callback([]); return; } + var features = []; + var chunksProcessed = 0; + + var cache = this.featureCache = this.featureCache || new LRUCache({ + name: 'bamFeatureCache', + fillCallback: dojo.hitch( this, '_readChunk' ), + sizeFunction: function( features ) { + return features.length; + }, + maxSize: 100000 // cache up to 100,000 BAM features + }); + var error; array.forEach( chunks, function( c ) { - var fetchMin = c.minv.block; - var fetchMax = c.maxv.block + (1<<16); // *sigh* - - thisB.data.read(fetchMin, fetchMax - fetchMin + 1, function(r) { - try { - var data = BAMUtil.unbgzf(r, c.maxv.block - c.minv.block + 1); - - thisB.readBamFeatures( new Uint8Array(data), c.minv.offset, features, function() { - if( ++chunksProcessed == chunks.length ) - callback( features, error ); - }); - } catch( e ) { - error = e; - if( ++chunksProcessed == chunks.length ) - callback( null, error ); - } - }); + cache.get( c, function( f, e ) { + error = error || e; + features.push.apply( features, f ); + if( ++chunksProcessed == chunks.length ) + callback( features, error ); + }); + }); + + }, + + _readChunk: function( chunk, callback ) { + var thisB = this; + var features = []; + var fetchMin = chunk.minv.block; + var fetchMax = chunk.maxv.block + (1<<16); // *sigh* + + thisB.data.read(fetchMin, fetchMax - fetchMin + 1, function(r) { + try { + var data = BAMUtil.unbgzf(r, chunk.maxv.block - chunk.minv.block + 1); + thisB.readBamFeatures( new Uint8Array(data), chunk.minv.offset, features, callback ); + } catch( e ) { + callback( null, e ); + } }); }, @@ -382,7 +403,7 @@ var BamFile = declare( null, else if( featureCount <= maxFeaturesWithoutYielding ) { // if we've read no more than 200 features this cycle, read another one var blockSize = readInt(ba, blockStart); - var blockEnd = blockStart + blockSize; + var blockEnd = blockStart + 4 + blockSize - 1; // only try to read the feature if we have all the bytes for it if( blockEnd < ba.length ) { @@ -395,7 +416,7 @@ var BamFile = declare( null, featureCount++; } - blockStart = blockEnd + 4; + blockStart = blockEnd+1; } else { // if we're not done but we've read a good chunk of diff --git a/src/JBrowse/Store/SeqFeature/BAM/LazyFeature.js b/src/JBrowse/Store/SeqFeature/BAM/LazyFeature.js new file mode 100644 index 0000000000..68404deecf --- /dev/null +++ b/src/JBrowse/Store/SeqFeature/BAM/LazyFeature.js @@ -0,0 +1,414 @@ +define( ['dojo/_base/array', + 'JBrowse/Util', + './Util', + 'JBrowse/Model/SimpleFeature' + ], + function( array, Util, BAMUtil, SimpleFeature ) { + +var SEQRET_DECODER = ['=', 'A', 'C', 'x', 'G', 'x', 'x', 'x', 'T', 'x', 'x', 'x', 'x', 'x', 'x', 'N']; +var CIGAR_DECODER = ['M', 'I', 'D', 'N', 'S', 'H', 'P', '=', 'X', '?', '?', '?', '?', '?', '?', '?']; + +var readInt = BAMUtil.readInt; +var readShort = BAMUtil.readShort; +var readFloat = BAMUtil.readFloat; + +var Feature = Util.fastDeclare( +{ + constructor: function( args ) { + this.store = args.store; + this.file = args.file; + this.data = { + type: 'match', + source: args.store.source + }; + this.bytes = { + start: args.bytes.start, + end: args.bytes.end, + byteArray: args.bytes.byteArray + }; + + this._coreParse(); + }, + + get: function( field) { + return this._get( field.toLowerCase() ); + }, + + // same as get(), except requires lower-case arguments. used + // internally to save lots of calls to field.toLowerCase() + _get: function( field ) { + return field in this.data ? this.data[field] : // have we already parsed it out? + function() { + var v = this.data[field] = + this[field] ? this[field]() : // maybe we have a special parser for it + this._flagMasks[field] ? this._parseFlag( field ) : // or is it a flag? + this._parseTag( field ); // otherwise, look for it in the tags + return v; + }.call(this); + }, + + tags: function() { + return this._get('_tags'); + }, + + _tags: function() { + this._parseAllTags(); + + var tags = [ 'seq', 'seq_reverse_complemented', 'unmapped' ]; + if( ! this._get('unmapped') ) + tags.push( 'start', 'end', 'strand', 'score', 'qual', 'MQ', 'CIGAR', 'length_on_ref' ); + if( this._get('multi_segment_template') ) { + tags.push( 'multi_segment_all_aligned', + 'multi_segment_next_segment_unmapped', + 'multi_segment_next_segment_reversed', + 'multi_segment_first', + 'multi_segment_last', + 'secondary_alignment', + 'qc_failed', + 'duplicate', + 'next_segment_position' + ); + } + tags = tags.concat( this._tagList || [] ); + + var d = this.data; + for( var k in d ) { + if( d.hasOwnProperty( k ) && k[0] != '_' ) + tags.push( k ); + } + + var seen = {}; + tags = array.filter( tags, function(t) { + if( t in this.data && this.data[t] === undefined ) + return false; + + var lt = t.toLowerCase(); + var s = seen[lt]; + seen[lt] = true; + return ! s; + },this); + + return tags; + }, + + parent: function() { + return undefined; + }, + + children: function() { + return this._get('subfeatures'); + }, + + id: function() { + return this._get('name')+'/'+this._get('md')+'/'+this._get('cigar')+'/'+this._get('start'); + }, + + // special parsers + /** + * Mapping quality score. + */ + mq: function() { + var mq = (this._get('_bin_mq_nl') & 0xff00) >> 8; + return mq == 255 ? undefined : mq; + }, + score: function() { + return this._get('mq'); + }, + qual: function() { + if( this._get('unmapped') ) + return undefined; + + var qseq = []; + var byteArray = this.bytes.byteArray; + var p = this.bytes.start + 36 + this._get('_l_read_name') + this._get('_n_cigar_op')*4 + this._get('_seq_bytes'); + var lseq = this._get('seq_length'); + for (var j = 0; j < lseq; ++j) { + qseq.push( byteArray[p + j] ); + } + return qseq.join(' '); + }, + strand: function() { + var xs = this._get('xs'); + return xs ? ( xs == '-' ? -1 : 1 ) : + this._get('seq_reverse_complemented') ? -1 : 1; + }, + /** + * Length in characters of the read name. + */ + _l_read_name: function() { + return this._get('_bin_mq_nl') & 0xff; + }, + /** + * number of bytes in the sequence field + */ + _seq_bytes: function() { + return (this._get('seq_length') + 1) >> 1; + }, + seq: function() { + var seq = ''; + var byteArray = this.bytes.byteArray; + var p = this.bytes.start + 36 + this._get('_l_read_name') + this._get('_n_cigar_op')*4; + var seqBytes = this._get('_seq_bytes'); + for (var j = 0; j < seqBytes; ++j) { + var sb = byteArray[p + j]; + seq += SEQRET_DECODER[(sb & 0xf0) >> 4]; + seq += SEQRET_DECODER[(sb & 0x0f)]; + } + return seq; + }, + name: function() { + return this._get('_read_name'); + }, + _read_name: function() { + var byteArray = this.bytes.byteArray; + var readName = ''; + var nl = this._get('_l_read_name'); + var p = this.bytes.start + 36; + for (var j = 0; j < nl-1; ++j) { + readName += String.fromCharCode(byteArray[p+j]); + } + return readName; + }, + _n_cigar_op: function() { + return this._get('_flag_nc') & 0xffff; + }, + cigar: function() { + if( this._get('unmapped') ) + return undefined; + + var byteArray = this.bytes.byteArray; + var numCigarOps = this._get('_n_cigar_op'); + var p = this.bytes.start + 36 + this._get('_l_read_name'); + var cigar = ''; + var lref = 0; + for (var c = 0; c < numCigarOps; ++c) { + var cigop = readInt(byteArray, p); + var lop = cigop >> 4; + var op = CIGAR_DECODER[cigop & 0xf]; + cigar = cigar + lop + op; + lref += lop; + p += 4; + } + this.data.length_on_ref = lref; + return cigar; + }, + next_segment_position: function() { + var nextRefID = this._get('_next_refid'); + var nextSegment = this.file.indexToChr[nextRefID]; + if( nextSegment ) + return nextSegment.name+':'+this._get('_next_pos'); + else + return undefined; + }, + subfeatures: function() { + if( ! this.store.createSubfeatures ) + return undefined; + + var cigar = this._get('cigar'); + if( cigar ) + return this._cigarToSubfeats( cigar ); + + return undefined; + }, + length_on_ref: function() { + var c = this._get('cigar'); // the length_on_ref is set as a + // side effect of the CIGAR parsing + return this.data.length_on_ref; + }, + _flags: function() { + return (this.data._flag_nc & 0xffff0000) >> 16; + }, + end: function() { + return this._get('start') + ( this._get('length_on_ref') || this._get('seq_length') || undefined ); + }, + + seq_id: function() { + if( this._get('unmapped') ) + return undefined; + + return ( this.file.indexToChr[ this._refID ] || {} ).name; + }, + + /** + * parse the core data: start, end, strand, etc + */ + _coreParse: function() { + var byteArray = this.bytes.byteArray; + var dataStart = this.bytes.start+4; + + var tempBytes = new Uint8Array( 32 ); + for( var i = 0; i<32; i++ ) { + tempBytes[i] = byteArray[i+dataStart]; + } + var ints = new Int32Array( tempBytes.buffer ); + + var d = this.data; + this._refID = ints[0]; + d.start = ints[1]; + d._bin_mq_nl = ints[2]; + d._flag_nc = ints[3]; + d.seq_length = ints[4]; + d._next_refid = ints[5]; + d._next_pos = ints[6]; + d.template_length = ints[7]; + }, + + /** + * Get the value of a tag, parsing the tags as far as necessary. + * Only called if we have not already parsed that field. + */ + _parseTag: function( tagName ) { + // if all of the tags have been parsed and we're still being + // called, we already know that we have no such tag, because + // it would already have been cached. + if( this._allTagsParsed ) + return undefined; + + this._tagList = this._tagList || []; + var byteArray = this.bytes.byteArray; + var p = this._tagOffset || this.bytes.start + 36 + this._get('_l_read_name') + this._get('_n_cigar_op')*4 + this._get('_seq_bytes') + this._get('seq_length'); + + var blockEnd = this.bytes.end; + while( p < blockEnd && lcTag != tagName ) { + var tag = String.fromCharCode( byteArray[p], byteArray[ p+1 ] ); + var lcTag = tag.toLowerCase(); + var type = String.fromCharCode( byteArray[ p+2 ] ); + p += 3; + + var value; + switch( type.toLowerCase() ) { + case 'a': + value = String.fromCharCode( byteArray[p] ); + p += 1; + break; + case 'i': + value = readInt(byteArray, p ); + p += 4; + break; + case 'c': + value = byteArray[p]; + p += 1; + break; + case 's': + value = readShort(byteArray, p); + p += 2; + break; + case 'f': + value = readFloat( byteArray, p ); + p += 4; + break; + case 'z': + case 'h': + value = ''; + while( p <= blockEnd ) { + var cc = byteArray[p++]; + if( cc == 0 ) { + break; + } + else { + value += String.fromCharCode(cc); + } + } + break; + default: + console.warn( "Unknown BAM tag type '"+type + +"', tags may be incomplete" + ); + value = undefined; + p = blockEnd; // stop parsing tags + } + + this._tagOffset = p; + + this._tagList.push( tag ); + if( lcTag == tagName ) + return value; + else { + this.data[ lcTag ] = value; + } + } + this._allTagsParsed = true; + return undefined; + }, + _parseAllTags: function() { + this._parseTag(); // calling _parseTag with no arg just parses + // all the tags and returns the last one + }, + + _flagMasks: { + multi_segment_template: 0x1, + multi_segment_all_aligned: 0x2, + unmapped: 0x4, + multi_segment_next_segment_unmapped: 0x8, + seq_reverse_complemented: 0x10, + multi_segment_next_segment_reversed: 0x20, + multi_segment_first: 0x40, + multi_segment_last: 0x80, + secondary_alignment: 0x100, + qc_failed: 0x200, + duplicate: 0x400 + }, + + _parseFlag: function( flagName ) { + return !!( this._get('_flags') & this._flagMasks[flagName] ); + }, + + _parseCigar: function( cigar ) { + return array.map( cigar.match(/\d+\D/g), function( op ) { + return [ op.match(/\D/)[0].toUpperCase(), parseInt( op ) ]; + }); + }, + + /** + * take a cigar string, and initial position, return an array of subfeatures + */ + _cigarToSubfeats: function(cigar) { + var subfeats = []; + var min = this._get('start'); + var max; + var ops = this._parseCigar( cigar ); + for (var i = 0; i < ops.length; i++) { + var lop = ops[i][1]; + var op = ops[i][0]; // operation type + // converting "=" to "E" to avoid possible problems later with non-alphanumeric type name + if (op === "=") { op = "E"; } + + switch (op) { + case 'M': + case 'D': + case 'N': + case 'E': + case 'X': + max = min + lop; + break; + case 'I': + max = min; + break; + case 'P': // not showing padding deletions (possibly change this later -- could treat same as 'I' ?? ) + case 'H': // not showing hard clipping (since it's unaligned, and offset arg meant to be beginning of aligned part) + case 'S': // not showing soft clipping (since it's unaligned, and offset arg meant to be beginning of aligned part) + break; + // other possible cases + } + if( op !== 'N' ) { + var subfeat = new SimpleFeature({ + data: { + type: op, + start: min, + end: max, + strand: this._get('strand'), + cigar_op: lop+op + }, + parent: this + }); + subfeats.push(subfeat); + } + min = max; + } + return subfeats; + } + +}); + +return Feature; +}); \ No newline at end of file diff --git a/src/JBrowse/Store/SeqFeature/BAM/Util.js b/src/JBrowse/Store/SeqFeature/BAM/Util.js index f3cf5eba0d..c184b520fb 100644 --- a/src/JBrowse/Store/SeqFeature/BAM/Util.js +++ b/src/JBrowse/Store/SeqFeature/BAM/Util.js @@ -57,7 +57,7 @@ var Utils = { }, unbgzf: function(data, lim) { - lim = Math.min( lim || 1, data.byteLength - 27); + lim = Math.min( lim || Infinity, data.byteLength - 27); var oBlockList = []; var totalSize = 0; @@ -79,12 +79,27 @@ var Utils = { // var logLength = Math.min(data.byteLength-ptr[0], 40); // console.log( xlen, bSize, bSize - xlen - 19, new Uint8Array( data, ptr[0], logLength ), logLength ); - var unc = inflate( - data, - compressedDataOffset, - data.byteLength - compressedDataOffset, - ptr - ); + var unc; + try { + unc = inflate( + data, + compressedDataOffset, + data.byteLength - compressedDataOffset, + ptr + ); + } catch( inflateError ) { + // if we have a buffer error and we have already + // inflated some data, there is probably just an + // incomplete BGZF block at the end of the data, so + // ignore it and stop inflating + if( /^Z_BUF_ERROR/.test(inflateError.statusString) && oBlockList.length ) { + break; + } + // otherwise it's some other kind of real error + else { + throw inflateError; + } + } if( unc.byteLength ) { totalSize += unc.byteLength; oBlockList.push( unc ); diff --git a/src/JBrowse/Store/SeqFeature/BigWig.js b/src/JBrowse/Store/SeqFeature/BigWig.js index e5ee9497b4..6f503a0106 100644 --- a/src/JBrowse/Store/SeqFeature/BigWig.js +++ b/src/JBrowse/Store/SeqFeature/BigWig.js @@ -78,7 +78,7 @@ return declare([ SeqFeatureStore, DeferredFeaturesMixin, DeferredStatsMixin ], return; } - bwg.fileSize = headerSlice.totalSize; + bwg.fileSize = result.fileSize;; var header = result; var sa = new Int16Array(header); var la = new Int32Array(header); @@ -123,7 +123,7 @@ return declare([ SeqFeatureStore, DeferredFeaturesMixin, DeferredStatsMixin ], // parse the totalSummary if present (summary of all data in the file) if( bwg.totalSummaryOffset ) { - if( typeof Float64Array == 'function' ) { + if( Float64Array ) { (function() { var ua = new Uint32Array( header, bwg.totalSummaryOffset, 2 ); var da = new Float64Array( header, bwg.totalSummaryOffset+8, 4 ); @@ -153,6 +153,15 @@ return declare([ SeqFeatureStore, DeferredFeaturesMixin, DeferredStatsMixin ], ); }, + + _readInt: function(ba, offset) { + return (ba[offset + 3] << 24) | (ba[offset + 2] << 16) | (ba[offset + 1] << 8) | (ba[offset]); + }, + + _readShort: function(ba, offset) { + return (ba[offset + 1] << 8) | (ba[offset]); + }, + /** * @private */ @@ -166,37 +175,39 @@ return declare([ SeqFeatureStore, DeferredFeaturesMixin, DeferredStatsMixin ], ++udo; } + var readInt = this._readInt; + var readShort = this._readShort; + this.data.slice( this.chromTreeOffset, udo - this.chromTreeOffset ) .fetch(function(bpt) { if( !( Uint8Array && Int16Array && Int32Array ) ) { - this._failAllDeferred( 'Browser does not support typed arrays' ); + var msg = 'Browser does not support typed arrays'; + thisB._loading.resolve({success: false, error: msg}); return; } var ba = new Uint8Array(bpt); - var sa = new Int16Array(bpt); - var la = new Int32Array(bpt); + var la = new Int32Array(bpt, 0, 6); var bptMagic = la[0]; + if( bptMagic !== 2026540177 ) + throw "parse error: not a Kent bPlusTree"; var blockSize = la[1]; var keySize = la[2]; var valSize = la[3]; var itemCount = (la[4] << 32) | (la[5]); var rootNodeOffset = 32; - // dlog('blockSize=' + blockSize + ' keySize=' + keySize + ' valSize=' + valSize + ' itemCount=' + itemCount); + //dlog('blockSize=' + blockSize + ' keySize=' + keySize + ' valSize=' + valSize + ' itemCount=' + itemCount); var bptReadNode = function(offset) { - var nodeType = ba[offset]; - var cnt = sa[(offset/2) + 1]; - // dlog('ReadNode: ' + offset + ' type=' + nodeType + ' count=' + cnt); + if( offset >= ba.length ) + throw "reading beyond end of buffer"; + var isLeafNode = ba[offset]; + var cnt = readShort( ba, offset+2 ); + //dlog('ReadNode: ' + offset + ' type=' + isLeafNode + ' count=' + cnt); offset += 4; for (var n = 0; n < cnt; ++n) { - if (nodeType == 0) { - offset += keySize; - var childOffset = (la[offset/4] << 32) | (la[offset/4 + 1]); - offset += 8; - childOffset -= thisB.chromTreeOffset; - bptReadNode(childOffset); - } else { + if( isLeafNode ) { + // parse leaf node var key = ''; for (var ki = 0; ki < keySize; ++ki) { var charCode = ba[offset++]; @@ -204,23 +215,30 @@ return declare([ SeqFeatureStore, DeferredFeaturesMixin, DeferredStatsMixin ], key += String.fromCharCode(charCode); } } - var chromId = (ba[offset+3]<<24) | (ba[offset+2]<<16) | (ba[offset+1]<<8) | (ba[offset+0]); - var chromSize = (ba[offset + 7]<<24) | (ba[offset+6]<<16) | (ba[offset+5]<<8) | (ba[offset+4]); + var chromId = readInt( ba, offset ); + var chromSize = readInt( ba, offset+4 ); offset += 8; - // dlog(key + ':' + chromId + ',' + chromSize); + //dlog(key + ':' + chromId + ',' + chromSize); thisB.chromsToIDs[key] = chromId; if (key.indexOf('chr') == 0) { thisB.chromsToIDs[key.substr(3)] = chromId; } thisB.idsToChroms[chromId] = key; + } else { + // parse index node + offset += keySize; + var childOffset = (readInt( ba, offset+4 ) << 32) | readInt( ba, offset ); + offset += 8; + childOffset -= thisB.chromTreeOffset; + bptReadNode(childOffset); } } }; bptReadNode(rootNodeOffset); callback.call( thisB, thisB ); - }); + }); }, _getFeatures: function( query, featureCallback, endCallback, errorCallback ) { @@ -228,9 +246,10 @@ return declare([ SeqFeatureStore, DeferredFeaturesMixin, DeferredStatsMixin ], var chrName = query.ref; var min = query.start; var max = query.end; - var basesPerSpan = query.basesPerSpan || 1; - var v = this.getView( basesPerSpan ); + var v = query.basesPerSpan ? this.getView( 1/query.basesPerSpan ) : + query.scale ? this.getView( scale ) : + this.getView( 1 ); if( !v ) { endCallback(); diff --git a/src/JBrowse/Store/SeqFeature/GFF3.js b/src/JBrowse/Store/SeqFeature/GFF3.js new file mode 100644 index 0000000000..a1b28f584a --- /dev/null +++ b/src/JBrowse/Store/SeqFeature/GFF3.js @@ -0,0 +1,338 @@ +define( [ + 'dojo/_base/declare', + 'dojo/_base/lang', + 'dojo/_base/array', + 'dojo/_base/url', + 'JBrowse/Store/NCList', + 'JBrowse/Store/SeqFeature/NCList', + 'JBrowse/Store/SeqFeature', + 'JBrowse/Store/DeferredStatsMixin', + 'JBrowse/Store/DeferredFeaturesMixin', + 'JBrowse/Util', + 'JBrowse/Model/XHRBlob', + 'JBrowse/Model/ArrayRepr', + './GFF3/GFF3Parser' + ], + function( + declare, + lang, + array, + urlObj, + NCList, + NCListStore, + SeqFeatureStore, + DeferredStatsMixin, + DeferredFeaturesMixin, + Util, + XHRBlob, + ArrayRepr, + GFF3Parser + ) { + +return declare([ NCListStore ], + + /** + * @lends JBrowse.Store.SeqFeature.GFF3 + */ +{ + + // "-chains-": { constructor: "manual" }, + constructor: function( args ) { + // had to push some stuff that I'd like in constructor into _load instead, because need before rest of _load, but + // _load is getting called at end of NCList (superclass) constructor, so before this constructor called + // tried using manual constructor chaining, but this.inherited(args) didn't actually trigger + // recursive superclass chaining, just the first parent (NCList) constructor. + // Therefore SeqFeature, DeferredFeatureMixin, etc. weren't getting called, and manually + // calling every superclass/mixin would be asking for trouble later on... + // + // this.inherited(arguments); + }, + + _load: function() { + var args = this.args; + this.data = args.blob; + this.name = args.name || ( this.data.url && new urlObj( this.data.url ).path.replace(/^.+\//,'') ) || 'anonymous'; + console.log("called GFF3 load"); + + // load and index the gff3 here + var store = this; + if (this.data.blob instanceof File) { + var fil = this.data.blob; + var reader = new FileReader(); + reader.onload = function(e) { + var content = e.target.result; + console.log( "In GFF3 store, got the file: " + fil.name + ", type: " + fil.type + ", size: " + fil.size); + store.loadContent(content); + }; + reader.readAsText(fil); + console.log("called reader.readAsText"); + } + else if (this.data.url) { + var gffurl = this.data.url; + dojo.xhrGet( { + url: gffurl, + handleAs: "text", + load: function(response, ioArgs) { + console.log( "In GFF3 store, got data from URL: ", gffurl); + store.loadContent(response); + }, + error: function(response, ioArgs) { + console.error(response); + console.error(response.stack); + } + } ); + } + }, + + loadContent: function(content) { + var store = this; + console.log(" content start: " + content.substr(0, 50)); + var gparser = new GFF3Parser(); + var gff3_json = gparser.parse(content); + console.log("parsed GFF3:"); + console.log(gff3_json); + var results = this._gff3toJbrowseJson(gff3_json, store.args); + console.log("converted GFF3:"); + console.log(results); + var trackInfo = results.trackInfo; + var featArray = results.featArray; + store.attrs = new ArrayRepr(trackInfo.intervals.classes); + store.nclist.fill(featArray, store.attrs); + + // should also calculate the feature density (avg features per + // bp) and store it in: + // store._stats.featureDensity + store.globalStats.featureCount = trackInfo.featureCount; + // average feature density per base + store.globalStats.featureDensity = trackInfo.featureCount / store.refSeq.length; + console.log("feature count: " + store.globalStats.featureCount); + + // when the store is ready to handle requests for stats and features, run: + store._deferred.features.resolve({success: true}); + store._deferred.stats.resolve({success: true}); + }, + + _gff3toJbrowseJson: function(parsedGFF3, params) { + var trackInfo = {}; + trackInfo["intervals"] = {}; + + trackInfo["histograms"] = { + "stats" : [ + { + "basesPerBin" : "1000000", + "max" : 1, + "mean" : 1 + } + ], + "meta" : [ + { + "basesPerBin" : "1000000", + "arrayParams" : { + "length" : 1, + "chunkSize" : 10000, + "urlTemplate" : "hist-1000000-{Chunk}.json" + } + } + ] + }; + trackInfo["intervals"]["classes"] = + [ { + "isArrayAttr" : { + "Subfeatures" : 1 + }, + "attributes" : [ "Start", "End", "Strand", "Source", "Phase", "Type", "Score", "Id", "Name", "Subfeatures" ] + }, { + "isArrayAttr" : { + }, + "attributes" : [ "Start", "End", "Strand", "Source", "Phase", "Type", "Score", "Id", "Name", "Subfeatures" ] + }, { + "isArrayAttr" : { + "Sublist" : 1 + }, + "attributes" : [ "Start", "End", "Chunk" ] + } ]; + + trackInfo["intervals"]["lazyClass"] = 2; + trackInfo["intervals"]["urlTemplate"] = "lf-{Chunk}.json"; + trackInfo["formatVersion"] = 1; + + var featureCount = 0; + + // first check if we have only one feature, in which case parsedData is an object not an array + if ( typeof parsedGFF3.parsedData.length == 'undefined' ){ + trackInfo["featureCount"] = 1; + } + else { + trackInfo["featureCount"] = parsedGFF3.parsedData.length; + } + + // loop through each top level feature in parsedGFF3 and make array of featureArrays + var allGff3Features = new Array; // this is an array of featureArrays containing info for all features in parsedGFF3 + for( var k = 0; k < parsedGFF3.parsedData.length; k++ ) { + var jbrowseFeat = this._convertParsedGFF3JsonToFeatureArray( parsedGFF3.parsedData[k] ); + if (!! jbrowseFeat) { + for (l = 0; l < jbrowseFeat.length; l++){ + allGff3Features.push( jbrowseFeat[l] ); + } + } + } + + return { trackInfo: trackInfo, featArray: allGff3Features }; + + }, + + /** + * takes one parsed GFF3 feature and all of its subfeatures (children/grandchildren/great-grandchildren/...) + * from a parsed GFF3 data struct (returned from GFF3toJson()), and returns a a two-level feature array for + * the lowest and next-lowest level. For example, given a data struct for a parsed gene/mRNA/exon GFF3 + * it would return a two-level feature array for the all mRNA features and their exons. + */ + _convertParsedGFF3JsonToFeatureArray: function(parsedGff3) { + var featureArray = new Array(); + + // figure out how many levels we are dealing with here, b/c we need to return + // only the data for the lowest contained in the next lowest level, since Webapollo + // can only deal with two-level features. + var gff3Depth = this._determineParsedGff3Depth( parsedGff3 ); + + // okay, we know the depth, go down to gff3Depth - 1, and pull the features at this + // depth and their children. + + // get parents in parsedGff3.parsedData at depth - 1 + var theseParents; + if (gff3Depth == 1) { theseParents = [ parsedGff3 ]; } + else { theseParents = this._getFeaturesAtGivenDepth(parsedGff3, gff3Depth - 1); } + if (! theseParents || theseParents.length < 1) { + return featureArray; + } + + for ( j = 0; j < theseParents.length; j++ ){ + var thisItem = new Array(); + // set to zero because we want jbrowse/webapollo to look at the first entry in attr array to + // look up what each of the following fields in thisItem mean + thisItem[0] = 0; + // + // set parent info + // + var rawdata = theseParents[j].data[0].rawdata; + thisItem[1] = parseInt(rawdata[3])-1; // set start (-1 for converting from 1-based to 0-based) + thisItem[2] = parseInt(rawdata[4]); // set end + thisItem[3] = rawdata[6]; // set strand + thisItem[4] = rawdata[1]; // set source + thisItem[5] = rawdata[7]; // set phase + thisItem[6] = rawdata[2]; // set type + thisItem[7] = rawdata[5]; // set score + thisItem[8] = theseParents[j].ID; // set id + + var parsedNinthField = this._parsedNinthGff3Field(rawdata[8]); + if ( !!parsedNinthField["Name"] ){ + thisItem[9] = parsedNinthField["Name"]; + } + else { thisItem[9] = null; } + + // + // now set children info + // + var children = theseParents[j].children; + var subfeats = null; // make array for all child features + if ( theseParents[j].children && (theseParents[j].children.length > 0)) { + subfeats = []; + for (var i = 0; i < theseParents[j].children.length; i++ ){ + var childData = theseParents[j].children[i].data[0].rawdata; + var subfeat = []; + + subfeat[0] = 1; // ? + subfeat[1] = parseInt(childData[3])-1; // start (-1 for converting from 1-based to 0-based) + subfeat[2] = parseInt(childData[4]); // end + subfeat[3] = childData[6]; // strand + subfeat[4] = childData[1]; // source + subfeat[5] = childData[7]; // phase + subfeat[6] = childData[2]; // type + subfeat[7] = childData[5]; // score + + var childNinthField = this._parsedNinthGff3Field( childData[8] ); + if ( !!childNinthField["ID"] ){ + subfeat[8] = childNinthField["ID"]; + } + else { subfeat[8] = null; } + if ( !!childNinthField["Name"] ){ + subfeat[9] = childNinthField["Name"]; + } + else { subfeat[9] = null; } + subfeats[i] = subfeat; + } + } + thisItem[10] = subfeats; // load up children + + featureArray.push( thisItem ); + } + + return featureArray; + }, + + // recursive search of this feature to see how many levels there are, + // helper for _convertParsedGFF3JsonToFeatureArray. This determines the + // depth of the first feature it finds. + _determineParsedGff3Depth: function(gffFeature) { + var recursion_level = 0; + var maximum_recursion_level = 20; // paranoid about infinite recursion + var determineNumLevels = function(thisJsonFeature) { + recursion_level++; + if ( recursion_level > maximum_recursion_level ){ + return false; + } + // recurse if there there are children + //if ( !! thisJsonFeature[0] && thisJsonFeature[0]["children"] != null && thisJsonFeature[0]["children"].length > 0 ){ + // if ( determineNumLevels(thisJsonFeature[0]["children"][0] ) ){ + if ( thisJsonFeature.children != null && thisJsonFeature.children.length > 0 ){ + if ( determineNumLevels(thisJsonFeature.children[0]) ){ + return true; + } + } + return false; + }; + // determineNumLevels( parsedGff3.parsedData[0] ); + determineNumLevels( gffFeature ); + return recursion_level; + }, + + // helper feature for _convertParsedGFF3JsonToFeatureArray + // For a given top-level feature, returns descendant features at a given depth + _getFeaturesAtGivenDepth: function(gffFeature, depth) { + var recursion_level = 0; + var maximum_recursion_level = 20; // paranoid about infinite recursion + var getFeatures = function(thisJsonFeature, thisDepth, returnedFeatures) { + if ( recursion_level > maximum_recursion_level ){ + return null; + } + // are we at the right depth? + if ( recursion_level + 1 == thisDepth ){ + returnedFeatures.push( thisJsonFeature ); + } + else if ( thisJsonFeature.children != null && thisJsonFeature.children.length > 0 ){ + recursion_level++; + for (var m = 0; m < thisJsonFeature.children.length; m++){ + getFeatures( thisJsonFeature.children[m], depth, returnedFeatures ); + } + } + }; + var results = []; + getFeatures( gffFeature, depth, results ); + return results; + }, + + // helper feature for _convertParsedGFF3JsonToFeatureArray + // that parsed ninth field of gff3 file + _parsedNinthGff3Field: function(ninthField) { + // parse info in 9th field to get name + var ninthFieldArray = ninthField.split(";"); + var parsedNinthField = new Object; + for (var j = 0; j < ninthFieldArray.length; j++){ + var keyVal = ninthFieldArray[j].split("="); + parsedNinthField[ keyVal[0] ] = keyVal[1]; + } + return parsedNinthField; + } + +}); +}); \ No newline at end of file diff --git a/src/JBrowse/Store/SeqFeature/GFF3/GFF3Parser.js b/src/JBrowse/Store/SeqFeature/GFF3/GFF3Parser.js new file mode 100644 index 0000000000..1d797eadc9 --- /dev/null +++ b/src/JBrowse/Store/SeqFeature/GFF3/GFF3Parser.js @@ -0,0 +1,336 @@ +/* +Created by Justin Reese 9/2012 +justaddcoffee@gmail.com + +This is a simple GFF3 parser that takes a GFF3 file such as this: + +Group1.33 maker gene 245454 247006 . + . ID=maker-Group1%2E33-pred_gff_GNOMON-gene-4.137;Name=maker-Group1%252E33-pred_gff_GNOMON-gene-4.137; +Group1.33 maker mRNA 245454 247006 . + . ID=1:gnomon_566853_mRNA;Parent=maker-Group1%2E33-pred_gff_GNOMON-gene-4.137;Name=gnomon_566853_mRNA;_AED=0.45;_eAED=0.45;_QI=138|1|1|1|1|1|4|191|259; +Group1.33 maker exon 245454 245533 . + . ID=1:gnomon_566853_mRNA:exon:5976;Parent=1:gnomon_566853_mRNA; +Group1.33 maker exon 245702 245879 . + . ID=1:gnomon_566853_mRNA:exon:5977;Parent=1:gnomon_566853_mRNA; + +and returns a JSON data structure like this: +{ +"parsedData": [ // parsed data is an array + { + "ID": "maker-Group1%2E33-pred_gff_GNOMON-gene-4.137", + "data":[ + { + "rawdata" : ["Group1.33","maker","gene","245454","247006",".","+",".","ID=maker-Group1%2E33-pred_gff_GNOMON-gene-4.137;Name=maker-Group1%252E33-pred_gff_GNOMON-gene-4.137"], + "attributes" : {"ID" : ["maker-Group1%2E33-pred_gff_GNOMON-gene-4.137"], "Name" : ["maker-Group1%252E33-pred_gff_GNOMON-gene-4.137"]} + } + ], + "children": [ + { + "ID": "1:gnomon_566853_mRNA", + "data": [ + { + "rawdata" : ["Group1.33","maker","mRNA","245454","247006",".","+",".","ID=1:gnomon_566853_mRNA;Parent=maker-Group1%2E33-pred_gff_GNOMON-gene-4.137;Name=gnomon_566853_mRNA;_AED=0.45;_eAED=0.45;_QI=138|1|1|1|1|1|4|191|259"] + "attributes" : { "ID" : ["1:gnomon_566853_mRNA"], "Parent" : ["maker-Group1%2E33-pred_gff_GNOMON-gene-4.137"], "Name" : ["gnomon_566853_mRNA"], "_AED" : ["0.45"], "_eAED" : ["0.45"],"_QI" : ["138|1|1|1|1|1|4|191|259"] } + } + ], + "children": [ + { + "ID": "1:gnomon_566853_mRNA:exon:5976", + "data": [ + { + "rawdata" : ["Group1.33","maker","exon","245454","245533",".","+",".","ID=1:gnomon_566853_mRNA:exon:5976;Parent=1:gnomon_566853_mRNA"] + "attributes" : {"ID" : ["1:gnomon_566853_mRNA:exon:5976"], "Parent" : ["1:gnomon_566853_mRNA"]} + } + ], + "children": [], + }, + { + "ID": "1:gnomon_566853_mRNA:exon:5977", + "data": [ + { + "rawdata" : ["Group1.33","maker","exon","245702","245879",".","+",".","ID=1:gnomon_566853_mRNA:exon:5977;Parent=1:gnomon_566853_mRNA"] + "attributes" : {"ID" : ["1:gnomon_566853_mRNA:exon:5977"], "Parent" : ["1:gnomon_566853_mRNA"]} + } + ], + "children": [], + } + ] + } + ] + } + ], + ... next parent/child/descendants, e.g. gene/mRNA/exons or whatever ... +], +"parseErrors" : [""] +"parseWarnings" : ["no GFF3 pragma"] +} + +*/ + +define([], + function() { + + +function GFF3Parser() { +}; + +GFF3Parser.prototype.parse = function(gff3String) { + // Right now this method assumes that gff3String is the entire GFF3 + // file in string form. This sucks a bit because it means we'll have to + // have both the parsed and unparsed GFF3 data in memory which is + // a waste of memory and will affect performance when the GFF3 files + // are big. Maybe we can refactor this later to accept a stream instead + // of a string. + + // Pseudocode for what I'm doing below: + // for each line in giant GFF3 string (slurped GFF3 file): + // parse data into fields, parse 9th field into attributes hash + // if hasParentAttribute + // put into hasParent hash where key == id, value = hash of data struct with parsed fields and parsed attributes + // else + // put into noParent hash where key == id, value = hash of data struct with parsed fields and parsed attributes + // for each entry in noParent hash: + // put into JSON as Parent without any Children (yet) + // for each entry in hasParent has + // make sure Parent ID is in seenIDs, or continue (TODO: put in orphans and put error in parseErrors array) + // find Parent in data structure (depth first search) + // put into Children array of Parent + + // search for a given ID in children, grandchildren, great-grandchildren, etc. + var recursion_level = 0; + var maximum_recursion_level = 200; + var foundParents = 0; + var placeChildrenWithParent = function(thisLine, featureArrayToSearch) { + recursion_level++; + // first, search each item in featureArrayToSearch + for ( var j = 0; j < featureArrayToSearch.length; j++ ){ + + // search all parents + for ( var k = 0; k < thisLine["data"][0]["attributes"]["Parent"].length; k++ ) { + var thisParentId = thisLine["data"][0]["attributes"]["Parent"][k]; + if ( thisLine["ID"][0] == 'au9.g910.t3' ){ + console.log("j: " + j + " k: " + k ); + console.log("comparing " + thisParentId + " with " + featureArrayToSearch[j]["ID"] ); + } + if ( thisParentId == featureArrayToSearch[j]["ID"] ){ + featureArrayToSearch[j]["children"].push( thisLine ); + foundParents++; + } + } + // paranoid about infinite recursion + // if ( recursion_level > maximum_recursion_level ){ + // return false; + // } + + // recurse if there there are children + if ( featureArrayToSearch[j]["children"].length > 0 ){ + if ( placeChildrenWithParent(thisLine, featureArrayToSearch[j]["children"] )){ + foundParents++; + } + } + } + if ( foundParents > 0 ){ + return true; + } + else { + return false; + } + } + + // put feature in ["data"] for discontinuous features we've already "filed" + var df_recursion_level = 0; + var df_maximum_df_recursion_level = 200; + var placeDiscontiguousFeature = function(thisLine, featureArrayToSearch) { + df_recursion_level++; + var thisId = thisLine["data"][0]["attributes"]["ID"][0]; + // first, search each item in featureArrayToSearch + for ( var j = 0; j < featureArrayToSearch.length; j++ ){ + if ( thisId == featureArrayToSearch[j]["ID"] ){ + featureArrayToSearch[j]["data"] = featureArrayToSearch[j]["data"].concat( thisLine["data"] ); + featureArrayToSearch[j]["children"] = featureArrayToSearch[j]["children"].concat( thisLine["children"] ); + return true; + } + // paranoid about infinite recursion + if ( df_recursion_level > df_maximum_df_recursion_level ){ + return false; + } + // recurse if there there are children + if ( featureArrayToSearch[j]["children"].length > 0 ){ + if ( placeDiscontiguousFeature(thisLine, featureArrayToSearch[j]["children"] )){ + return true; + } + } + } + return false; + } + + var bigDataStruct = { + "parsedData" : [], + "parseErrors": [], + "parseWarnings": [] + }; // parsed GFF3 in JSON format, to be returned + + var lines = gff3String.match(/^.*((\r\n|\n|\r)|$)/gm); // this is wasteful, maybe try to avoid storing split lines separately later + var hasParent = {}; // child (or grandchild, or whatever) features + var noParent = {}; // toplevel features without parents + + var seenIDs = {}; + var noParentIDs = []; + var hasParentIDs = []; + + for (var i = 0; i < lines.length; i++) { + + // check for ##FASTA pragma + if( lines[i].match(/^##FASTA/) || lines[i].match(/^>/) ){ + break; + } + // skip comment lines + if( lines[i].match(/^#/) ){ + continue; + } + // skip comment lines + if( lines[i].match(/^\s*$/) ){ + continue; + } + // make sure lines[i] has stuff in it + if(typeof(lines[i]) == 'undefined' || lines[i] == null) { + continue; + } + lines[i] = lines[i].replace(/(\n|\r)+$/, ''); // chomp + var fields = lines[i].split("\t"); + // check that we have enough fields + if(fields.length < 9 ){ + console.log("Number of fields < 9! Skipping this line:\n\t" + lines[i] + "\n"); + bigDataStruct["parseWarnings"].push( "Number of fields < 9! Skipping this line:\n\t" + lines[i] + "\n" ); + continue; + } + else { + if (fields.length > 9 ){ + console.log("Number of fields > 9!\n\t" + lines[i] + "\nI'll try to parse this line anyway."); + bigDataStruct["parseWarnings"].push( "Number of fields > 9!\n\t" + lines[i] + "\nI'll try to parse this line anyway." ); + } + } + + // parse ninth field into key/value pairs + var attributesKeyVal = new Object; + if(typeof(fields[8]) != undefined && fields[8] != null) { + var ninthFieldSplit = fields[8].split(/;/); + for ( var j = 0; j < ninthFieldSplit.length; j++){ + /* + Multiple attributes of the same type are indicated by separating the + values with the comma "," character, as in: + Parent=AF2312,AB2812,abc-3 + */ + var theseKeyVals = ninthFieldSplit[j].split(/\=/); + if ( theseKeyVals.length >= 2 ){ + var key = unescape(theseKeyVals[0]); + var valArray = new Array; + + // see if we have multiple values + if ( theseKeyVals[1].match(/\,/) ){ // multiple values + if ( !! theseKeyVals[1] && theseKeyVals.length != undefined ){ + // value can be >1 thing separated by comma, for example for multiple parents + valArray = theseKeyVals[1].split(/\,/); + if ( !! valArray && valArray.length != undefined ){ + for ( k = 0; k < valArray.length; k++){ + valArray[k] = unescape(valArray[k]); + } + + } + valArray[0] = unescape(valArray[0]); + valArray[1] = unescape(valArray[1]); + } + } + else { // just one value + valArray[0] = unescape(theseKeyVals[1]); + } + attributesKeyVal[key] = valArray; + } + } + } + + if ( ! attributesKeyVal["ID"] ){ + attributesKeyVal["ID"] = []; + attributesKeyVal["ID"][0] = "parser_autogen_id_" + i; + } + + var thisLine = {"ID": attributesKeyVal["ID"][0], + "data": [ + {"rawdata" : fields, + "attributes" : attributesKeyVal + } + ], + "children": [] + }; + + if ( attributesKeyVal["Parent"] != undefined ){ + hasParent[attributesKeyVal["ID"][0]] = thisLine; + hasParentIDs.push( attributesKeyVal["ID"][0] ); + } + else { + noParent[attributesKeyVal["ID"][0]] = thisLine; + noParentIDs.push( attributesKeyVal["ID"][0] ); + } + + // keep track of what IDs we've seen + if ( isNaN(seenIDs[attributesKeyVal["ID"][0]]) ){ + seenIDs[attributesKeyVal["ID"][0]] = 1; + } + else { + seenIDs[attributesKeyVal["ID"][0]]++; + } + } + + var dealtWithIDs = {}; // list of IDs that have been processed + + // put things with no parent in parsedData straight away + for (var j = 0; j < noParentIDs.length; j++) { + var thisID = noParentIDs[j]; + var thisLine = noParent[thisID]; + + // is this a discontiguous feature that's already been "filed"? + if ( seenIDs[thisID] > 1 && dealtWithIDs[thisID] > 0 ){ // yes + placeDiscontiguousFeature(thisLine, bigDataStruct["parsedData"] ); + } + else { + bigDataStruct["parsedData"].push( thisLine ); + } + + // keep track of what IDs we've dealt with + if ( isNaN( dealtWithIDs[thisID] ) ){ + dealtWithIDs[thisID] = 1 + } + else { + dealtWithIDs[thisID]++; + } + + } + + // now put children (and grandchildren, and so on) in data struct + for (var k = 0; k < hasParentIDs.length; k++) { + var thisID = hasParentIDs[k]; + var thisLine = hasParent[thisID]; + + // is this a discontiguous feature that's already been "filed"? + if ( seenIDs[thisID] > 1 && dealtWithIDs[thisID] > 0 ){ // yes + placeDiscontiguousFeature(thisLine, bigDataStruct["parsedData"] ); + } + else { + // put this child in the right children array, recursively, or put it on top level and mark it as an orphan + if ( ! placeChildrenWithParent(thisLine, bigDataStruct["parsedData"] ) ){ + bigDataStruct["parsedData"].push( thisLine ); + bigDataStruct["parseWarnings"].push( thisID + " seems to be an orphan" ); + } + } + + // keep track of what IDs we've dealt with + if ( isNaN( dealtWithIDs[thisID] ) ){ + dealtWithIDs[thisID] = 1 + } + else { + dealtWithIDs[thisID]++; + } + + } + return bigDataStruct; +}; + +return GFF3Parser; + +}); \ No newline at end of file diff --git a/src/JBrowse/Store/SeqFeature/NCList.js b/src/JBrowse/Store/SeqFeature/NCList.js index 0df9eda0a8..5b20b3f732 100644 --- a/src/JBrowse/Store/SeqFeature/NCList.js +++ b/src/JBrowse/Store/SeqFeature/NCList.js @@ -19,9 +19,14 @@ define([ * @extends SeqFeatureStore */ +var idfunc = function() { return this._uniqueID; }; +var parentfunc = function() { return this._parent; }; +var childrenfunc = function() { return this.get('subfeatures'); }; + return declare([ SeqFeatureStore, DeferredFeaturesMixin, DeferredStatsMixin ], { constructor: function(args) { + this.args = args; this.nclist = this.makeNCList(); this.baseUrl = args.baseUrl; @@ -47,11 +52,7 @@ return declare([ SeqFeatureStore, DeferredFeaturesMixin, DeferredStatsMixin ], handleAs: "json", failOk: true, load: Util.debugHandler( this, function(o) { this.loadSuccess(o, url); }), - error: dojo.hitch( this, function(error) { - if( error.status != 404 ) - console.error(''+error); - this.loadFail(error, url); - }) + error: dojo.hitch( this, 'loadFail' ) }); }, @@ -87,9 +88,12 @@ return declare([ SeqFeatureStore, DeferredFeaturesMixin, DeferredStatsMixin ], }, - loadFail: function(trackInfo,url) { + loadFail: function( error, url ) { + if( error.status != 404 ) + console.error(''+error); this.empty = true; - this.setLoaded(); + this._deferred.stats.resolve( { success: false }); + this._deferred.features.resolve( { success: false }); }, // just forward histogram() and iterate() to our encapsulate nclist @@ -98,6 +102,11 @@ return declare([ SeqFeatureStore, DeferredFeaturesMixin, DeferredStatsMixin ], }, _getFeatures: function( query, origFeatCallback, finishCallback, errorCallback ) { + if( this.empty ) { + finishCallback(); + return; + } + var that = this; var startBase = query.start; var endBase = query.end; @@ -108,8 +117,12 @@ return declare([ SeqFeatureStore, DeferredFeaturesMixin, DeferredStatsMixin ], // NCList where the feature lives; it's unique across the // top-level NCList (the top-level NCList covers a // track/chromosome combination) - var uniqueID = path.join(","); - that._decorate_feature( accessors, feature, uniqueID ); + + // only need to decorate a feature once + if (! feature.decorated) { + var uniqueID = path.join(","); + that._decorate_feature( accessors, feature, uniqueID ); + } return origFeatCallback( feature ); }; @@ -118,13 +131,22 @@ return declare([ SeqFeatureStore, DeferredFeaturesMixin, DeferredStatsMixin ], // helper method to recursively add .get and .tags methods to a feature and its // subfeatures - _decorate_feature: function( accessors, feature, id ) { + + + _decorate_feature: function( accessors, feature, id, parent ) { feature.get = accessors.get; + // possibly include set method in decorations? not currently + // feature.set = accessors.set; feature.tags = accessors.tags; feature._uniqueID = id; + feature.id = idfunc; + feature._parent = parent; + feature.parent = parentfunc; + feature.children = childrenfunc; dojo.forEach( feature.get('subfeatures'), function(f,i) { - this._decorate_feature( accessors, f, id+'-'+i ); + this._decorate_feature( accessors, f, id+'-'+i, feature ); },this); + feature.decorated = true; } }); }); diff --git a/src/JBrowse/Store/SeqFeature/NCList_v0.js b/src/JBrowse/Store/SeqFeature/NCList_v0.js index 67a58504bf..e05a7b0e68 100644 --- a/src/JBrowse/Store/SeqFeature/NCList_v0.js +++ b/src/JBrowse/Store/SeqFeature/NCList_v0.js @@ -140,15 +140,7 @@ return declare( SFNCList, return subfieldOrder; }, featCallBack = function( feature, path ) { - feature.get = get; - feature.tags = tags; - feature._uniqueID = path.join(','); - var subfeatCtr = 0; - dojo.forEach( feature.get('subfeatures'), function(f) { - f.get = subget; - f.tags = subTags; - f._uniqueID = feature._uniqueID+'-'+(++subfeatCtr); - }); + that._decorate_feature( { get: get, tags: tags }, feature, path.join(',') ); return origFeatCallback( feature, path ); }; diff --git a/src/JBrowse/Store/Sequence/StaticChunked.js b/src/JBrowse/Store/Sequence/StaticChunked.js index dca856d679..fe1d90eef4 100644 --- a/src/JBrowse/Store/Sequence/StaticChunked.js +++ b/src/JBrowse/Store/Sequence/StaticChunked.js @@ -37,11 +37,17 @@ return declare( SeqFeatureStore, this.chunkCache = {}; this.compress = args.compress; this.urlTemplate = args.urlTemplate; + if( ! this.urlTemplate ) { + throw "no urlTemplate provided, cannot open sequence store"; + } + this.baseUrl = args.baseUrl; this.seqChunkSize = args.seqChunkSize; }, - getFeatures: function( query, callback, endCallback ) { + getFeatures: function( query, callback, endCallback, errorCallback ) { + + errorCallback = errorCallback || function(e) { console.error(e); }; var start = query.start; var end = query.end; @@ -68,7 +74,7 @@ return declare( SeqFeatureStore, }; })(); - var callbackInfo = { start: start, end: end, callback: callback }; + var callbackInfo = { start: start, end: end, success: callback, error: errorCallback }; if( !this.chunkCache[seqname] ) { this.chunkCache[seqname] = []; @@ -89,7 +95,11 @@ return declare( SeqFeatureStore, ), i ); - } else { + } + else if( chunk.error ) { + errorCallback( chunk.error ); + } + else { //console.log("added callback for %d .. %d", start, end); chunk.callbacks.push(callbackInfo); } @@ -126,21 +136,28 @@ return declare( SeqFeatureStore, dojo.xhrGet({ url: sequrl + i + ".txt" + ( this.compress ? 'z' : '' ), load: dojo.hitch( this, function( chunkRecord, response ) { - //console.log('response for chunk '+chunkRecord.num); - chunkRecord.sequence = response; - chunkRecord.loaded = true; + //console.log('response for chunk '+chunkRecord.num); + chunkRecord.sequence = response; + chunkRecord.loaded = true; + dojo.forEach( chunkRecord.callbacks, function(ci) { + ci.success( ci.start, + ci.end, + response.substring( ci.start - chunkRecord.num*chunkSize, + ci.end - chunkRecord.num*chunkSize + ), + i + ); + }); + delete chunkRecord.callbacks; + + }, chunkCacheForSeq[i] ), + error: dojo.hitch( this, function( chunkRecord, error ) { + chunkRecord.error = error; dojo.forEach( chunkRecord.callbacks, function(ci) { - ci.callback( ci.start, - ci.end, - response.substring( ci.start - chunkRecord.num*chunkSize, - ci.end - chunkRecord.num*chunkSize - ), - i - ); + ci.error( error ); }); delete chunkRecord.callbacks; - - }, chunkCacheForSeq[i] ) + }, chunkCacheForSeq[i]) }); } } diff --git a/src/JBrowse/Store/TrackMetaData.js b/src/JBrowse/Store/TrackMetaData.js index 8473130bd2..f2a016e973 100644 --- a/src/JBrowse/Store/TrackMetaData.js +++ b/src/JBrowse/Store/TrackMetaData.js @@ -6,7 +6,7 @@ define( 'JBrowse/Util', 'JBrowse/Digest/Crc32' ], - function( declare, dArray, simpleFetch, Util, Crc32 ) { + function( declare, array, simpleFetch, Util, Crc32 ) { var dojof = Util.dojof; var Meta = declare( null, @@ -65,20 +65,12 @@ var Meta = declare( null, this.onReadyFuncs = dojo.clone(args.onReady); } - // interpret the track configurations as a metadata store + // interpret the track configurations themselves as a metadata store this._indexItems( { store: this, - items: dojo.map( args.trackConfigs, function(conf) { - var metarecord = dojo.clone( conf.metadata || {} ); - metarecord.label = conf.label; - metarecord.key = conf.key; - metarecord.conf = conf; - metarecord['track type'] = conf.type; - if( conf.category ) - metarecord.category = conf.category; - return metarecord; - },this) + items: dojo.map( args.trackConfigs, + dojo.hitch( this, '_trackConfigToItem' ) ) } ); @@ -115,8 +107,74 @@ var Meta = declare( null, }); },this); } + + // listen for track-editing commands and update our track metadata accordingly + args.browser.subscribe( '/jbrowse/v1/c/tracks/new', + dojo.hitch( this, 'addTracks' )); + args.browser.subscribe( '/jbrowse/v1/c/tracks/replace', dojo.hitch( this, function( trackConfigs ) { + this.deleteTracks( trackConfigs ); + this.addTracks( trackConfigs ); + })); + args.browser.subscribe( '/jbrowse/v1/c/tracks/delete', + dojo.hitch( this, 'deleteTracks' )); }, + /** + * Convert a track config object into a data store item. + */ + _trackConfigToItem: function( conf ) { + var metarecord = dojo.clone( conf.metadata || {} ); + metarecord.label = conf.label; + metarecord.key = conf.key; + metarecord.conf = conf; + metarecord['track type'] = conf.type; + if( conf.category ) + metarecord.category = conf.category; + return metarecord; + }, + + addTracks: function( trackConfigs ) { + if( trackConfigs.length ) { + // clear the query cache + delete this.previousQueryFingerprint; + delete this.previousResults; + } + + array.forEach( trackConfigs, function( conf ) { + // insert in the indexes + this._indexItems({ + store: this, + items: [ this._trackConfigToItem( conf ) ] + }); + + var name = conf.label; + var item = this.fetchItemByIdentity( name ); + if( item ) + this.onNew( item ); + else + console.error( 'failed to add '+name+' track to track metadata store', conf ); + },this ); + }, + + deleteTracks: function( trackConfigs ) { + if( trackConfigs.length ) { + // clear the query cache + delete this.previousQueryFingerprint; + delete this.previousResults; + } + + // we don't actually delete things, we just mark them as + // deleted and filter out deleted ones when returning results. + array.forEach( trackConfigs, function( conf ) { + var name = conf.label; + var item = this.fetchItemByIdentity( name ); + if( item ) { + item.DELETED = true; + this.onDelete( item ); + } + },this); + }, + /** * Set the store's state to be ready (i.e. loaded), and calls all * our onReady callbacks. @@ -192,6 +250,8 @@ var Meta = declare( null, // record for this item var ident = this.getIdentity(item); var existingItem = this.identIndex[ ident ]; + if( existingItem && existingItem.DELETED ) + delete existingItem.DELETED; // skip this item if we have already // seen it from this store, or if we @@ -445,8 +505,9 @@ var Meta = declare( null, var filteredSets = []; if( textFilter ) { filteredSets.push( - dojo.filter( dojof.values( this.identIndex ), textFilter ) - .sort( dojo.hitch(this,'_itemSortFunc') ) + this._filterDeleted( + array.filter( dojof.values( this.identIndex ), textFilter ) + ).sort( dojo.hitch(this,'_itemSortFunc') ) ); filteredSets[0].facetName = 'Contains text'; } @@ -460,7 +521,7 @@ var Meta = declare( null, } dojo.forEach( values, function(value) { var idx = this.facetIndexes.byName[facetName].byValue[value] || {}; - items.push.apply( items, idx.items || [] ); + items.push.apply( items, this._filterDeleted( idx.items || [] ) ); },this); items.facetName = facetName; items.sort( dojo.hitch( this, '_itemSortFunc' )); @@ -477,7 +538,7 @@ var Meta = declare( null, var facetMatchCounts = {}; if( ! filteredSets.length ) { - results = dojof.values( this.identIndex ); + results = this._filterDeleted( dojof.values( this.identIndex ) ); } else { // calculate how many item records total we need to go through var leftToProcess = 0; @@ -603,6 +664,28 @@ var Meta = declare( null, onFetchSuccess: function() { }, + /** + * Event hook called when there are new items in the store. + */ + onNew: function( item ) { + }, + /** + * Event hook called when something is deleted from the store. + */ + onDelete: function( item ) { + }, + /** + * Event hook called when one or more items in the store have changed their values. + */ + onSet: function( item, attribute, oldvalue, newvalue ) { + }, + + _filterDeleted: function( items ) { + return array.filter( items, function(i) { + return ! i.DELETED; + }); + }, + /** * Compile a text search string into a function that tests whether * a given piece of text matches that search string. @@ -641,7 +724,7 @@ var Meta = declare( null, return dojo.hitch(this, function(item) { return dojo.some( this.facets, function(facetName) { var text = this.getValue( item, facetName ); - return dArray.every( wordREs, function(re) { return re.test(text); } ); + return array.every( wordREs, function(re) { return re.test(text); } ); },this); }); }, @@ -649,7 +732,8 @@ var Meta = declare( null, getFeatures: function() { return { 'dojo.data.api.Read': true, - 'dojo.data.api.Identity': true + 'dojo.data.api.Identity': true, + 'dojo.data.api.Notification': true }; }, close: function() {}, diff --git a/src/JBrowse/Util.js b/src/JBrowse/Util.js index 26a40ba44b..fd992fac06 100644 --- a/src/JBrowse/Util.js +++ b/src/JBrowse/Util.js @@ -1,7 +1,8 @@ // MISC -define( [ 'dojox/lang/functional/object', +define( [ 'dojo/_base/array', + 'dojox/lang/functional/object', 'dojox/lang/functional/fold' - ], function() { + ], function( array ) { var Util; Util = { dojof: dojox.lang.functional, @@ -168,7 +169,7 @@ Util = { && ("object" == typeof b[prop]) && ("object" == typeof a[prop]) ) { Util.deepUpdate(a[prop], b[prop]); - } else if( typeof a[prop] == 'undefined' || typeof b[prop] != undefined ){ + } else if( typeof a[prop] == 'undefined' || typeof b[prop] != 'undefined' ){ a[prop] = b[prop]; } } @@ -222,6 +223,9 @@ Util = { }, parseLocString: function( locstring ) { + if( typeof locstring != 'string' ) + return null; + locstring = dojo.trim( locstring ); // (chromosome) ( start ) ( sep ) ( end ) @@ -251,6 +255,22 @@ Util = { }; }, + basename: function( str, suffixList ) { + if( ! str || ! str.match ) + return undefined; + var m = str.match( /[\/\\]([^\/\\]+)[\/\/\/]*$/ ); + var bn = m ? m[1] || undefined : str; + if( bn && suffixList ) { + if( !( suffixList instanceof Array ) ) + suffixList = [ suffixList ]; + suffixList = array.map( suffixList, function( s ) { + return s.replace( /([\.\?\+])/g, '\\$1' ); + }); + bn = bn.replace( new RegExp( suffixList.join('|')+'$', 'i' ), '' ); + } + return bn; + }, + assembleLocString: function( loc_in ) { var s = '', types = { start: 'number', end: 'number', ref: 'string', strand: 'number' }, diff --git a/src/JBrowse/View/ConfirmDialog.js b/src/JBrowse/View/ConfirmDialog.js new file mode 100644 index 0000000000..31494ae416 --- /dev/null +++ b/src/JBrowse/View/ConfirmDialog.js @@ -0,0 +1,84 @@ +define([ + 'dojo/_base/declare', + 'dijit/focus', + 'dijit/Dialog', + 'dojo/on', + 'dijit/form/Button' + ], + function( declare, focus, dijitDialog, on, dijitButton ) { + + +return declare( dijitDialog, + + /** + * Dijit Dialog subclass that pops up a yes/no confirmation + * more pleasant for use as an information popup. + * @lends JBrowse.View.InfoDialog + */ +{ + autofocus: false, + + constructor: function( args ) { + + this.message = args.message || 'Do you really want to do this?'; + this.confirmLabel = args.confirmLabel || 'Yes'; + this.denyLabel = args.denyLabel || 'No'; + + dojo.connect( this, 'onLoad', this, '_addActionBar' ); + }, + + _addActionBar: function() { + var that = this; + if( this.get('content') && ! this.actionBar ) { + this.actionBar = dojo.create( 'div', { className: 'infoDialogActionBar dijitDialogPaneActionBar' }); + + new dijitButton({ className: 'yes', + label: this.confirmLabel, + onClick: function() { + that.callback( true ); + that.hide(); + } + }) + .placeAt( this.actionBar); + new dijitButton({ className: 'no', + label: this.denyLabel, + onClick: function() { + that.callback( false ); + that.hide(); + } + }) + .placeAt( this.actionBar); + + var c = this.get('content'); + var container = dojo.create( 'div', { className: 'infoDialogContent' }); + if( typeof c == 'string' ) + container.innerHTML = c; + else { + if( c.parentNode ) + c.parentNode.removeChild( c ); + container.addChild( c ); + } + this.set( 'content', + [ + container, + this.actionBar + ] + ); + } + }, + + + show: function( callback ) { + this.callback = callback || function() {}; + + this.set('content', this.message ); + + this._addActionBar(); + + this.inherited( arguments ); + + focus.focus( this.closeButtonNode ); + } + +}); +}); \ No newline at end of file diff --git a/src/JBrowse/View/Export/GFF3.js b/src/JBrowse/View/Export/GFF3.js index 1905573991..8ccc55e427 100644 --- a/src/JBrowse/View/Export/GFF3.js +++ b/src/JBrowse/View/Export/GFF3.js @@ -166,6 +166,8 @@ return declare( ExportBase, var valtype = typeof val; if( valtype == 'boolean' ) val = val ? 1 : 0; + else if( valtype == 'undefined' ) + return; tag = this._gff3_reserved_attribute(tag) || this._ensure_non_reserved( tag ); attrs[tag] = val; },this); diff --git a/src/JBrowse/View/Export/SequinTable.js b/src/JBrowse/View/Export/SequinTable.js new file mode 100644 index 0000000000..e526cc56ea --- /dev/null +++ b/src/JBrowse/View/Export/SequinTable.js @@ -0,0 +1,63 @@ +/** + * Support for Sequin Feature table export. See + * http://www.ncbi.nlm.nih.gov/Sequin/table.html. + */ + +define([ 'dojo/_base/declare', + 'dojo/_base/array', + 'JBrowse/View/Export' + ], + function( declare, array, ExportBase ) { + +return declare( ExportBase, + +{ + /** + * Data export driver for BED format. + * @constructs + */ + // constructor: function( args ) { + // }, + + /** + * print the BED track definition line + * @private + */ + _printHeader: function( feature ) { + // print the BED header + this.print( '>Feature '+(feature.get('seq_id') || this.refSeq.name)+"\n" ); + return true; + }, + + /** + * Format a feature into a string. + * @param {Object} feature feature object (like those returned from JBrowse/Store/SeqFeature/*) + * @returns {String} BED string representation of the feature + */ + formatFeature: function( feature ) { + if( ! this.headerPrinted ) + this.headerPrinted = this._printHeader( feature ); + + var featLine = [ feature.get('start')+1, + feature.get('end'), + feature.get('type') || 'region' + ]; + if( feature.get('strand') == -1 ) { + var t = featLine[0]; + featLine[0] = featLine[1]; + featLine[1] = t; + } + + // make the qualifiers + var qualifiers = array.map( + array.filter( feature.tags(), function(t) { + return ! { start: 1, end: 1, type: 1, strand: 1, seq_id: 1 }[ t.toLowerCase() ]; + }), + function( tag ) { + return [ tag.toLowerCase(), feature.get(tag) ]; + }); + + return featLine.join("\t")+"\n" + array.map( qualifiers, function( q ) { return "\t\t\t"+q.join("\t")+"\n"; } ).join(''); + } +}); +}); \ No newline at end of file diff --git a/src/JBrowse/View/FileDialog.js b/src/JBrowse/View/FileDialog.js new file mode 100644 index 0000000000..1b36402d4f --- /dev/null +++ b/src/JBrowse/View/FileDialog.js @@ -0,0 +1,229 @@ +define( [ + 'dojo/_base/declare', + 'dojo/_base/array', + 'dojo/aspect', + 'dijit/focus', + 'dijit/form/Button', + 'dijit/form/RadioButton', + 'dojo/dom-construct', + 'dijit/Dialog', + 'dojox/form/Uploader', + 'dojox/form/uploader/plugins/IFrame', + './FileDialog/ResourceList', + './FileDialog/TrackList' + ], + function( + declare, + array, + aspect, + dijitFocus, + Button, + RadioButton, + dom, + Dialog, + Uploaded, + ignore, + ResourceList, + TrackList + ) { + +return declare( null, { + + constructor: function( args ) { + this.browser = args.browser; + this.config = dojo.clone( args.config || {} ); + this.browserSupports = { + dnd: 'draggable' in document.createElement('span') + }; + }, + + _makeActionBar: function( openCallback, cancelCallback ) { + var actionBar = dom.create( + 'div', { + className: 'dijitDialogPaneActionBar' + }); + + var disChoices = this.trackDispositionChoice = [ + new RadioButton({ id: 'openImmediately', + value: 'openImmediately', + checked: true + }), + new RadioButton({ id: 'addToTrackList', + value: 'addToTrackList' + }) + ]; + + var aux = dom.create('div',{className:'aux'},actionBar); + disChoices[0].placeAt(aux); + dom.create('label', { for: 'openImmediately', innerHTML: 'Open immediately' }, aux ), + disChoices[1].placeAt(aux); + dom.create('label', { for: 'addToTrackList', innerHTML: 'Add to tracks' }, aux ); + + + new Button({ iconClass: 'dijitIconDelete', label: 'Cancel', + onClick: dojo.hitch( this, function() { + cancelCallback && cancelCallback(); + this.dialog.hide(); + }) + }) + .placeAt( actionBar ); + new Button({ iconClass: 'dijitIconFolderOpen', + label: 'Open', + onClick: dojo.hitch( this, function() { + openCallback && openCallback({ + trackConfs: this.trackList.getTrackConfigurations(), + trackDisposition: this.trackDispositionChoice[0].checked ? this.trackDispositionChoice[0].value : + this.trackDispositionChoice[1].checked ? this.trackDispositionChoice[1].value : + undefined + }); + this.dialog.hide(); + }) + }) + .placeAt( actionBar ); + + return { domNode: actionBar }; + }, + + show: function( args ) { + var dialog = this.dialog = new Dialog( + { title: "Open files", className: 'fileDialog' } + ); + + var localFilesControl = this._makeLocalFilesControl(); + var remoteURLsControl = this._makeRemoteURLsControl(); + var resourceListControl = this._makeResourceListControl(); + var trackListControl = this._makeTrackListControl(); + var actionBar = this._makeActionBar( args.openCallback, args.cancelCallback ); + + // connect the local files control to the resource list + dojo.connect( localFilesControl.uploader, 'onChange', function() { + resourceListControl.addLocalFiles( localFilesControl.uploader._files ); + }); + + // connect the remote URLs control to the resource list + dojo.connect( remoteURLsControl, 'onChange', function( urls ) { + resourceListControl.clearURLs(); + resourceListControl.addURLs( urls ); + }); + + // connect the resource list to the track list + dojo.connect( resourceListControl, 'onChange', function( resources ) { + trackListControl.update( resources ); + }); + + var div = function( attr, children ) { + var d = dom.create('div', attr ); + array.forEach( children, dojo.hitch( d, 'appendChild' )); + return d; + }; + var content = [ + dom.create( 'div', { className: 'intro', innerHTML: 'Add any combination of data files and URLs, and JBrowse will automatically suggest tracks to display their contents.' } ), + div( { className: 'resourceControls' }, + [ localFilesControl.domNode, remoteURLsControl.domNode ] + ), + resourceListControl.domNode, + trackListControl.domNode, + actionBar.domNode + ]; + dialog.set( 'content', content ); + dialog.show(); + + aspect.after( dialog, 'hide', dojo.hitch( this, function() { + dijitFocus.curNode && dijitFocus.curNode.blur(); + dialog.destroyRecursive(); + })); + }, + + _makeLocalFilesControl: function() { + var container = dom.create('div', { className: 'localFilesControl' }); + + dom.create('h3', { innerHTML: 'Local files' }, container ); + + var dragArea = dom.create('div', { className: 'dragArea' }, container ); + + var fileBox = new dojox.form.Uploader({ + multiple: true + }); + fileBox.placeAt( dragArea ); + + if( this.browserSupports.dnd ) { + // let the uploader process any files dragged into the dialog + fileBox.addDropTarget( this.dialog.domNode ); + + // add a message saying you can drag files in + dom.create( + 'div', { + className: 'dragMessage', + innerHTML: 'Select or drag files here.' + }, dragArea + ); + } + + // little elements used to show pipeline-like connections between the controls + dom.create( 'div', { className: 'connector', innerHTML: ' '}, container ); + + return { domNode: container, uploader: fileBox }; + }, + + _makeRemoteURLsControl: function() { + var container = dom.create('div', { className: 'remoteURLsControl' }); + + // make the input elements + dom.create('h3', { innerHTML: 'Remote URLs - one per line' }, container ); + + // the onChange here will be connected to by the other parts + // of the dialog to propagate changes to the text in the box + var self = { domNode: container, + onChange: function(urls) { + //console.log('urls changed'); + } + }; + self.input = dom.create( 'textarea', { + className: 'urlInput', + placeHolder: "http://paste.urls.here/example.bam", + cols: 25, + rows: 5, + spellcheck: false + }, container ); + + // set up the handlers to propagate changes + var realChange = function() { + var text = dojo.trim( self.input.value ); + var urls = text.length ? text.split( /\s+/ ) : []; + self.onChange( urls ); + }; + // watch the input text for changes. just do it every 700ms + // because there are many ways that text can get changed (like + // pasting), not all of which fire the same events. not using + // the onchange event, because that doesn't fire until the + // textarea loses focus. + var previousText = ''; + var checkFrequency = 900; + var checkForChange = function() { + // compare with all whitespace changed to commas so that + // we are insensitive to changes in whitespace + if( self.input.value.replace(/\s+/g,',') != previousText ) { + realChange(); + previousText = self.input.value.replace(/\s+/g,','); + } + window.setTimeout( checkForChange, checkFrequency ); + }; + window.setTimeout( checkForChange, checkFrequency ); + + // little elements used to show pipeline-like connections between the controls + dom.create( 'div', { className: 'connector', innerHTML: ' '}, container ); + + return self; + }, + + _makeResourceListControl: function () { + var rl = new ResourceList({ dialog: this }); + return rl; + }, + _makeTrackListControl: function() { + var tl = new TrackList({ browser: this.browser }); + this.trackList = tl; + return tl; + } +}); +}); diff --git a/src/JBrowse/View/FileDialog/ResourceList.js b/src/JBrowse/View/FileDialog/ResourceList.js new file mode 100644 index 0000000000..0e247611f1 --- /dev/null +++ b/src/JBrowse/View/FileDialog/ResourceList.js @@ -0,0 +1,152 @@ +define( ['dojo/_base/declare', + 'dojo/_base/array', + 'dojo/dom-construct', + 'dijit/form/Select' + ], + function( declare, array, dom, Select ) { + +return declare( null, { + + constructor: function( args ) { + this.dialog = args.dialog; + this.domNode = dom.create( 'div', { className: 'resourceList' } ); + this._updateView(); + }, + + clearLocalFiles: function() { + this._resources = array.filter( this._resources || [], function(res) { + return ! res.file; + }); + this._notifyChange(); + }, + + _notifyChange: function() { + this.onChange( array.map( this._resources || [], function( res ) { + var r = {}; + if( res.file ) + r.file = res.file; + if( res.url ) + r.url = res.url; + r.type = res.type.get('value'); + return r; + })); + }, + + _addResources: function( resources ) { + var seenFile = {}; + var allRes = ( this._resources||[] ).concat( resources ); + this._resources = array.filter( allRes.reverse(), function( res ) { + var key = res.file && res.file.name || res.url; + if( seenFile[key] ) { + return false; + } + seenFile[key] = true; + return true; + }).reverse(); + + this._updateView(); + this._notifyChange(); + }, + + addLocalFiles: function( fileList ) { + this._addResources( array.map( fileList, function(file) { + return { file: file }; + })); + }, + + clearURLs: function() { + this._resources = array.filter( this._resources || [], function(res) { + return ! res.url; + }); + this._notifyChange(); + }, + addURLs: function( urls ) { + this._addResources( array.map( urls, function(u) { + return { url: u }; + })); + }, + + // old-style handler stub + onChange: function() { }, + + _updateView: function() { + var container = this.domNode; + dom.empty( container ); + + dom.create('h3', { innerHTML: 'Files and URLs' }, container ); + + if( (this._resources||[]).length ) { + var table = dom.create('table',{}, container ); + + // render rows in the resource table for each resource in our + // list + array.forEach( this._resources, function( res, i){ + var that = this; + var tr = dom.create('tr', {}, table ); + var name = res.url || res.file.name; + + // make a selector for the resource's type + var typeSelect = new Select({ + options: [ + { label: 'file type?', value: null }, + { label: "GFF3", value: "gff3" }, + { label: "BigWig", value: "bigwig" }, + { label: "BAM", value: "bam" }, + { label: "BAI", value: "bai" } + ], + value: this.guessType( name ), + onChange: function() { + that._rememberedTypes = that._rememberedTypes||{}; + that._rememberedTypes[name] = this.get('value'); + that._notifyChange(); + } + }); + typeSelect.placeAt( dojo.create('td',{ width: '4%'},tr) ); + res.type = typeSelect; + + dojo.create( 'td', { + width: '1%', + innerHTML: '
' + },tr); + dojo.create('td',{ innerHTML: name },tr); + dojo.create('td',{ + width: '1%', + innerHTML: '
', + onclick: function(e) { + e.preventDefault && e.preventDefault(); + that.delete( res ); + } + }, tr); + }, this); + } + else { + dom.create('div', { className: 'emptyMessage', + innerHTML: 'Add files and URLs using the controls above.' + }, + container); + } + + // little elements used to show pipeline-like connections between the controls + dom.create( 'div', { className: 'connector', innerHTML: ' '}, container ); + }, + + delete: function( deleteResource ) { + this._resources = array.filter( this._resources || [], function(res) { + return res !== deleteResource; + }); + this._updateView(); + this._notifyChange(); + }, + + guessType: function( name ) { + return ( this._rememberedTypes||{} )[name] || ( + /\.bam$/i.test( name ) ? 'bam' : + /\.bai$/i.test( name ) ? 'bai' : + /\.gff3?$/i.test( name ) ? 'gff3' : + /\.(bw|bigwig)$/i.test( name ) ? 'bigwig' : + null + ); + } + +}); +}); diff --git a/src/JBrowse/View/FileDialog/TrackList.js b/src/JBrowse/View/FileDialog/TrackList.js new file mode 100644 index 0000000000..75e7d1cb1d --- /dev/null +++ b/src/JBrowse/View/FileDialog/TrackList.js @@ -0,0 +1,160 @@ +define(['dojo/_base/declare', + 'dojo/_base/array', + 'dojo/dom-construct', + 'JBrowse/Util', + 'dijit/form/TextBox', + 'dijit/form/Select', + 'dijit/form/Button', + './TrackList/BAMDriver', + './TrackList/BigWigDriver', + './TrackList/GFF3Driver', + 'JBrowse/View/TrackConfigEditor' + ], + function(declare, array, dom, Util, TextBox, Select, Button, BAMDriver, BigWigDriver, GFF3Driver, TrackConfigEditor ) { + +var uniqCounter = 0; + +return declare( null, { + +constructor: function( args ) { + this.browser = args.browser; + this.fileDialog = args.dialog; + this.domNode = dom.create('div', { className: 'trackList', innerHTML: 'track list!' }); + this.types = [ BAMDriver, BigWigDriver, GFF3Driver ]; + + this._updateDisplay(); +}, + + +getTrackConfigurations: function() { + return Util.dojof.values( this.trackConfs || {} ); +}, + +update: function( resources ) { + this.storeConfs = {}; + this.trackConfs = {}; + + this._makeStoreConfs( resources ); + + // make some track configurations from the store configurations + this._makeTrackConfs(); + + this._updateDisplay(); +}, + +_makeStoreConfs: function( resources ) { + // when called, rebuild the store and track configurations that we are going to add + this.storeConfs = this.storeConfs || {}; + + // anneal the given resources into a set of data store + // configurations by offering each file to each type driver in + // turn until no more are being accepted + var lastLength = 0; + while( resources.length && resources.length != lastLength ) { + resources = array.filter( resources, function( resource ) { + return ! array.some( this.types, function( typeDriver ) { + return typeDriver.tryResource( this.storeConfs, resource ); + },this); + },this); + + lastLength = resources.length; + } + + array.forEach( this.types, function( typeDriver ) { + typeDriver.finalizeConfiguration( this.storeConfs ); + },this); + + if( resources.length ) + console.warn( "Not all resources could be assigned to tracks. Unused resources:", resources ); +}, + +_makeTrackConfs: function() { + // object that maps store type -> default track type to use for the store + var typeMap = this.browser.getTrackTypes().trackTypeDefaults; + + for( var n in this.storeConfs ) { + var store = this.storeConfs[n]; + var trackType = typeMap[store.type] || 'JBrowse/View/Track/HTMLFeatures'; + + this.trackConfs = this.trackConfs || {}; + + this.trackConfs[ n ] = { + store: this.storeConfs[n], + label: n, + key: n.replace(/_\d+$/,'').replace(/_/g,' '), + type: trackType + }; + } +}, + +_delete: function( trackname ) { + delete (this.trackConfs||{})[trackname]; + this._updateDisplay(); +}, + +_updateDisplay: function() { + var that = this; + + // clear it + dom.empty( this.domNode ); + + dom.create('h3', { innerHTML: 'New Tracks' }, this.domNode ); + + if( ! Util.dojof.keys( this.trackConfs||{} ).length ) { + dom.create('div', { className: 'emptyMessage', + innerHTML: 'None' + },this.domNode); + } else { + var table = dom.create('table', { innerHTML: 'NameDisplay'}, this.domNode ); + + var trackTypes = this.browser.getTrackTypes(); + + for( var n in this.trackConfs ) { + var t = this.trackConfs[n]; + var r = dom.create('tr', {}, table ); + new TextBox({ + value: t.key, + onChange: function() { t.key = this.get('value'); } + }).placeAt( dom.create('td',{ className: 'name' }, r ) ); + new Select({ + options: array.map( trackTypes.knownTrackTypes, function( t ) { + var l = trackTypes.trackTypeLabels[t] + || t.replace('JBrowse/View/Track/','').replace(/\//g, ' '); + return { label: l, value: t }; + }), + value: t.type, + onChange: function() { + t.type = this.get('value'); + } + }).placeAt( dom.create('td',{ className: 'type' }, r ) ); + + new Button({ + className: 'edit', + title: 'edit configuration', + innerHTML: 'Edit Configuration', + onClick: function() { + new TrackConfigEditor( t ) + .show( function( result) { + dojo.mixin( t, result.conf ); + that._updateDisplay(); + }); + } + }).placeAt( dom.create('td', { className: 'edit' }, r ) ); + + dojo.create('td',{ + width: '1%', + innerHTML: '
', + onclick: function(e) { + e.preventDefault && e.preventDefault(); + that._delete( n ); + } + }, r); + + dom.create('td',{ className: 'type' }, r ); + } + } +} + +}); +}); + diff --git a/src/JBrowse/View/FileDialog/TrackList/BAMDriver.js b/src/JBrowse/View/FileDialog/TrackList/BAMDriver.js new file mode 100644 index 0000000000..68cdc1a292 --- /dev/null +++ b/src/JBrowse/View/FileDialog/TrackList/BAMDriver.js @@ -0,0 +1,148 @@ +define([ + 'JBrowse/Util', + 'JBrowse/Model/FileBlob', + 'JBrowse/Model/XHRBlob' + ], + function( Util, FileBlob, XHRBlob ) { +var uniqCounter = 0; +return { + + storeType: 'JBrowse/Store/SeqFeature/BAM', + + tryResource: function( configs, resource ) { + if( resource.type == 'bam' ) { + var basename = Util.basename( + resource.file ? resource.file.name : + resource.url ? resource.url : + '' + ); + if( !basename ) + return false; + + // go through the configs and see if there is one with a BAI that seems to match + for( var n in configs ) { + var c = configs[n]; + if( Util.basename( c.bai ? c.bai.url || c.bai.blob.name : c.baiUrlTemplate, '.bai' ) == basename ) { + // it's a match, put it in + c.bam = this._makeBlob( resource ); + return true; + } + } + // go through again and look for BAIs that don't have .bam on them + basename = Util.basename( basename, '.bam' ); + for( var n in configs ) { + var c = configs[n]; + if( Util.basename( c.bai ? c.bai.url || c.bai.blob.name : c.baiUrlTemplate, '.bai' ) == basename ) { + // it's a match, put it in + c.bam = this._makeBlob( resource ); + return true; + } + } + + // otherwise make a new store config for it + var newName = 'BAM_'+basename+'_'+uniqCounter++; + configs[newName] = { + type: this.storeType, + bam: this._makeBlob( resource ), + name: newName + }; + return true; + } else if( resource.type == 'bai' ) { + var basename = Util.basename( + resource.file ? resource.file.name : + resource.url ? resource.url : + '' + , '.bai' + ); + if( !basename ) + return false; + + // go through the configs and look for BAMs that match like zee.bam -> zee.bam.bai + for( var n in configs ) { + var c = configs[n]; + if( Util.basename( c.bam ? c.bam.url || c.bam.blob.name : c.urlTemplate ) == basename ) { + // it's a match, put it in + c.bai = this._makeBlob( resource ); + return true; + } + } + // go through again and look for BAMs that match like zee.bam -> zee.bai + for( var n in configs ) { + var c = configs[n]; + if( Util.basename( c.bam ? c.bam.url || c.bam.blob.name : c.urlTemplate, '.bam' ) == basename ) { + // it's a match, put it in + c.bai = this._makeBlob( resource ); + return true; + } + } + + // otherwise make a new store + var newName = 'BAM_'+Util.basename(basename,'.bam')+'_'+uniqCounter++; + configs[newName] = { + bai: this._makeBlob( resource ), + name: newName, + type: this.storeType + }; + return true; + } + else + return false; + }, + + // try to merge any singleton BAM and BAI stores. currently can only do this if there is one of each + finalizeConfiguration: function( configs ) { + var singletonBAIs = {}; + var singletonBAICount = 0; + var singletonBAMs = {}; + var singletonBAMCount = 0; + for( var n in configs ) { + var conf = configs[n]; + if( (conf.bai || conf.baiUrlTemplate) && ! ( conf.bam || conf.urlTemplate ) ) { + // singleton BAI + singletonBAICount++; + singletonBAIs[n] = conf; + } + else if(( conf.bam || conf.urlTemplate ) && ! ( conf.bai || conf.baiUrlTemplate) ) { + // singleton BAM + singletonBAMCount++; + singletonBAMs[n] = conf; + } + } + + // if we have a single BAM and single BAI left at the end, + // stick them together and we'll see what happens + if( singletonBAMCount == 1 && singletonBAICount == 1 ) { + for( var bainame in singletonBAIs ) { + for( var bamname in singletonBAMs ) { + if( singletonBAIs[bainame].baiUrlTemplate ) + singletonBAMs[bamname].baiUrlTemplate = singletonBAIs[bainame].baiUrlTemplate; + if( singletonBAIs[bainame].bai ) + singletonBAMs[bamname].bai = singletonBAIs[bainame].bai; + + delete configs[bainame]; + } + } + } + + // delete any remaining singleton BAIs, since they don't have + // a hope of working + for( var bainame in singletonBAIs ) { + delete configs[bainame]; + } + }, + + _makeBlob: function( resource ) { + var r = resource.file ? new FileBlob( resource.file ) : + resource.url ? new XHRBlob( resource.url ) : + null; + if( ! r ) + throw 'unknown resource type'; + return r; + + }, + + confIsValid: function( conf ) { + return (conf.bam || conf.urlTemplate) && ( conf.bai || conf.baiUrlTemplate || conf.urlTemplate ); + } +}; +}); diff --git a/src/JBrowse/View/FileDialog/TrackList/BigWigDriver.js b/src/JBrowse/View/FileDialog/TrackList/BigWigDriver.js new file mode 100644 index 0000000000..f05f0ee11b --- /dev/null +++ b/src/JBrowse/View/FileDialog/TrackList/BigWigDriver.js @@ -0,0 +1,52 @@ +define([ + 'JBrowse/Util', + 'JBrowse/Model/FileBlob', + 'JBrowse/Model/XHRBlob' + ], + function( Util, FileBlob, XHRBlob ) { +var uniqCounter = 0; +return { + + storeType: 'JBrowse/Store/SeqFeature/BigWig', + + tryResource: function( configs, resource ) { + if( resource.type == 'bigwig' ) { + var basename = Util.basename( + resource.file ? resource.file.name : + resource.url ? resource.url : + '' + ); + if( !basename ) + return false; + + var newName = 'BigWig_'+basename+'_'+uniqCounter++; + configs[newName] = { + type: this.storeType, + blob: this._makeBlob( resource ), + name: newName + }; + return true; + } + else + return false; + }, + + // try to merge any singleton BAM and BAI stores. currently can only do this if there is one of each + finalizeConfiguration: function( configs ) { + }, + + _makeBlob: function( resource ) { + var r = resource.file ? new FileBlob( resource.file ) : + resource.url ? new XHRBlob( resource.url ) : + null; + if( ! r ) + throw 'unknown resource type'; + return r; + + }, + + confIsValid: function( conf ) { + return conf.blob || conf.urlTemplate; + } +}; +}); diff --git a/src/JBrowse/View/FileDialog/TrackList/GFF3Driver.js b/src/JBrowse/View/FileDialog/TrackList/GFF3Driver.js new file mode 100644 index 0000000000..989d0c5e42 --- /dev/null +++ b/src/JBrowse/View/FileDialog/TrackList/GFF3Driver.js @@ -0,0 +1,52 @@ +define([ + 'JBrowse/Util', + 'JBrowse/Model/FileBlob', + 'JBrowse/Model/XHRBlob' + ], + function( Util, FileBlob, XHRBlob ) { +var uniqCounter = 0; +return { + + storeType: 'JBrowse/Store/SeqFeature/GFF3', + + tryResource: function( configs, resource ) { + if( resource.type == 'gff3' ) { + var basename = Util.basename( + resource.file ? resource.file.name : + resource.url ? resource.url : + '' + ); + if( !basename ) + return false; + + var newName = 'GFF3_'+basename+'_'+uniqCounter++; + configs[newName] = { + type: this.storeType, + blob: this._makeBlob( resource ), + name: newName + }; + return true; + } + else + return false; + }, + + // try to merge any singleton BAM and BAI stores. currently can only do this if there is one of each + finalizeConfiguration: function( configs ) { + }, + + _makeBlob: function( resource ) { + var r = resource.file ? new FileBlob( resource.file ) : + resource.url ? new XHRBlob( resource.url ) : + null; + if( ! r ) + throw 'unknown resource type'; + return r; + + }, + + confIsValid: function( conf ) { + return conf.blob || conf.urlTemplate; + } +}; +}); diff --git a/src/JBrowse/View/GranularRectLayout.js b/src/JBrowse/View/GranularRectLayout.js index 60172ba9e7..a948df2a79 100644 --- a/src/JBrowse/View/GranularRectLayout.js +++ b/src/JBrowse/View/GranularRectLayout.js @@ -1,3 +1,11 @@ +/** + * Rectangle-layout manager that lays out rectangles using bitmaps at + * resolution that may be somewhat lower than that of the coordinate + * system for the rectangles being laid out. `pitchX` and `pitchY` + * are the ratios of input scale resolution to internal bitmap + * resolution. + */ + define( ['dojo/_base/declare'], function( declare ) { @@ -10,7 +18,6 @@ return declare( null, this.rectangles = {}; this.maxTop = 0; this.pTotalHeight = 0; // total height, in units of bitmap squares (px/pitchY) - this.vertPadding = 2; // pixels }, /** @@ -23,14 +30,15 @@ return declare( null, if( this.rectangles[id] ) return this.rectangles[id].top * this.pitchY; - var pLeft = Math.floor( left / this.pitchX ); - var pRight = Math.floor( right / this.pitchX ); - var pHeight = Math.ceil( (height+this.vertPadding) / this.pitchY ); + var pLeft = Math.floor( left / this.pitchX ); + var pRight = Math.floor( right / this.pitchX ); + var pHeight = Math.ceil( height / this.pitchY ); var midX = Math.floor((pLeft+pRight)/2); var rectangle = { id: id, l: pLeft, r: pRight, mX: midX, h: pHeight }; - for( var top=0; top <= this.pTotalHeight; top++ ){ - if(! this._collides(rectangle,top) ) + + for(var top = 0; top <= this.pTotalHeight; top++ ){ + if( ! this._collides(rectangle,top) ) break; } rectangle.top = top; diff --git a/src/JBrowse/View/LocationChoiceDialog.js b/src/JBrowse/View/LocationChoiceDialog.js new file mode 100644 index 0000000000..fe5ee6b961 --- /dev/null +++ b/src/JBrowse/View/LocationChoiceDialog.js @@ -0,0 +1,100 @@ +/** + * Dialog box that prompts the user to choose between several + * different available locations to navigate to. + */ + +define([ + 'dojo/_base/declare', + 'dojo/dom-construct', + 'dojo/aspect', + 'dijit/Dialog', + 'dijit/form/Button', + 'dijit/focus', + 'JBrowse/View/LocationList' + ], + function( + declare, + dom, + aspect, + Dialog, + dijitButton, + dijitFocus, + LocationListView + ) { +return declare( null, { + + /** + * @param args.browser the Browser object + * @param args.locationChoices [Array] array of Location objects + * to choose from. The locations can optionally have 'label' + * attributes. + * @param args.title optional title of the dialog box. + * @param args.prompt optional text prompt to show at the top of the dialog. + * @param args.goCallback optional function to call for executing a 'Go' action. gets ( location, value, node, options ) + * @param args.showCallback optional function to call for executing a 'Show' action. gets ( location, value, node, options) + */ + constructor: function( args ) { + this.browser = args.browser; + this.config = dojo.clone( args.config || {} ); + this.locationChoices = args.locationChoices || []; + this.title = args.title || 'Choose location'; + this.prompt = args.prompt; + this.goCallback = args.goCallback; + this.showCallback = args.showCallback; + }, + + show: function() { + var dialog = this.dialog = new Dialog( + { title: this.title, + className: 'locationChoiceDialog', + style: { width: '70%' } + } + ); + var container = dom.create('div',{}); + + // show the description if there is one + if( this.prompt ) { + dom.create('div', { + className: 'prompt', + innerHTML: this.prompt + }, container ); + } + + var browser = this.browser; + this.locationListView = new LocationListView( + { browser: browser, + locations: this.locationChoices, + buttons: [ + { + className: 'show', + innerHTML: 'Show', + onClick: this.showCallback || function( location ) { browser.showRegion( location ); } + }, + { + className: 'go', + innerHTML: 'Go', + onClick: this.goCallback || function( location ) { dialog.hide(); browser.showRegion( location ); } + } + ] + }, + dom.create( 'div', { + className: 'locationList', + style: { maxHeight: 0.5*this.browser.container.offsetHeight+'px'} + },container) + ); + + this.actionBar = dojo.create( 'div', { className: 'infoDialogActionBar dijitDialogPaneActionBar' }); + new dijitButton({ iconClass: 'dijitIconDelete', + label: 'Cancel', onClick: dojo.hitch( dialog, 'hide' ) + }) + .placeAt(this.actionBar); + + dialog.set( 'content', [ container, this.actionBar ] ); + dialog.show(); + aspect.after( dialog, 'hide', dojo.hitch( this, function() { + dijitFocus.curNode && dijitFocus.curNode.blur(); + dialog.destroyRecursive(); + })); + } +}); +}); \ No newline at end of file diff --git a/src/JBrowse/View/LocationList.js b/src/JBrowse/View/LocationList.js new file mode 100644 index 0000000000..28ec43ee52 --- /dev/null +++ b/src/JBrowse/View/LocationList.js @@ -0,0 +1,72 @@ +/** + * Generic component that displays a list of genomic locations, along + * with buttons to execute actions on them. + */ + +define([ + 'dojo/_base/declare', + 'dojo/_base/array', + 'dojo/dom-construct', + 'dijit/form/Button', + 'dgrid/Grid', + 'dgrid/extensions/DijitRegistry' + ], + function( + declare, + array, + dom, + dijitButton, + DGrid, + DGridDijitRegistry + ) { + +var Grid = declare([DGrid,DGridDijitRegistry]); + +return declare(null,{ + constructor: function( args, parent ) { + var thisB = this; + this.browser = args.browser; + var columns = [ + { label: 'Reference', field: 'ref' }, + { label: 'Start', field: 'start' }, + { label: 'End', field: 'end' } + ]; + + if( args.locations && args.locations.length && args.locations[0].tracks ) + columns.push({ + label: 'Track', + field: 'tracks', + formatter: function(tracks) { + return array.map( array.filter( tracks, function(t) { return t; }), // remove nulls + function(t) { + return t.key || t.name || t.label || t; + }) + .join(', '); + } + }); + + if( array.some( args.locations || [], function(l) { return l.label; }) ) { + columns.unshift( { label: 'Name', field: 'label' } ); + } + + if( args.buttons ) { + columns.push({ + label: '', + className: 'goButtonColumn', + renderCell: function( object, value, node, options ) { + var container = dom.create('div'); + array.forEach( args.buttons, function( button ) { + var buttonArgs = dojo.mixin( {}, button ); + buttonArgs.onClick = function() { button.onClick( object, value, node, options ); }; + new dijitButton( buttonArgs ).placeAt( container ); + }); + return container; + } + }); + } + + this.grid = new Grid({ columns: columns }, parent ); + this.grid.renderArray( args.locations ); + } +}); +}); \ No newline at end of file diff --git a/src/JBrowse/View/Ruler.js b/src/JBrowse/View/Ruler.js index f73e2f9085..90ac92f3f7 100644 --- a/src/JBrowse/View/Ruler.js +++ b/src/JBrowse/View/Ruler.js @@ -3,7 +3,8 @@ define( [ 'dojox/charting/Chart', 'dojox/charting/axis2d/Default', 'dojox/charting/plot2d/Bubble', - 'dojo/NodeList-dom' + 'dojo/NodeList-dom', + 'dojo/number' ], function( query, Chart ) { /** diff --git a/src/JBrowse/View/Track/Alignments.js b/src/JBrowse/View/Track/Alignments.js index 5ccd17d7bc..0fc123e02c 100644 --- a/src/JBrowse/View/Track/Alignments.js +++ b/src/JBrowse/View/Track/Alignments.js @@ -5,6 +5,7 @@ define( ['dojo/_base/declare', ], function( declare, array, Util, HTMLFeatures ) { +// return declare( HTMLFeatures, return declare( HTMLFeatures, /** * @lends JBrowse.View.Track.Alignments @@ -20,15 +21,24 @@ return declare( HTMLFeatures, style: { _defaultLabelScale: 50, className: 'alignment', - arrowheadClass: 'arrowhead' + arrowheadClass: 'arrowhead', + centerChildrenVertically: true, + showMismatches: true, + showSubfeatures: false } } ); }, - renderFeature: function( feature, uniqueId, block, scale ) { + renderFeature: function( feature, uniqueId, block, scale, labelScale, descriptionScale, + containerStart, containerEnd ) { var featDiv = this.inherited( arguments ); - this._drawMismatches( feature, featDiv, scale ); + + var displayStart = Math.max( feature.get('start'), containerStart ); + var displayEnd = Math.min( feature.get('end'), containerEnd ); + if( this.config.style.showMismatches ) { + this._drawMismatches( feature, featDiv, scale, displayStart, displayEnd ); + } // if this feature is part of a multi-segment read, and not // all of its segments are aligned, add missing_mate to its @@ -40,46 +50,113 @@ return declare( HTMLFeatures, }, + handleSubFeatures: function( feature, featDiv, + displayStart, displayEnd, block ) { + if( this.config.style.showSubfeatures ) { + this.inherited(arguments); + } + }, + /** * draw base-mismatches on the feature */ - _drawMismatches: function( feature, featDiv, scale ) { + _drawMismatches: function( feature, featDiv, scale, displayStart, displayEnd ) { + var featLength = displayEnd - displayStart; // recall: scale is pixels/basepair - if ( scale >= 0.5 ) { + if ( featLength*scale > 1 ) { var mismatches = this._getMismatches( feature ); var charSize = this.getCharacterMeasurements(); var drawChars = scale >= charSize.w; - var featureLength = feature.get('end') - feature.get('start'); - array.forEach( mismatches, function( mismatch ) { - array.forEach( mismatch.bases, function( base, i ) { - dojo.create('span', { - className: 'mismatch base base_'+(base == '*' ? 'deletion' : base.toLowerCase()), - title: base == '*' ? 'deletion' : null, - style: { - position: 'absolute', - left: (mismatch.start+i)/featureLength*100 + '%', - width: Math.max(scale,1) + 'px' - }, - innerHTML: drawChars ? base : '' - }, featDiv ); - }, this ); - }); + var start = feature.get('start') + mismatch.start; + var end = start + mismatch.length; + + // if the feature has been truncated to where it doesn't cover + // this mismatch anymore, just skip this mismatch + if ( end <= displayStart || start >= displayEnd ) + return; + + var base = mismatch.base; + var mDisplayStart = Math.max( start, displayStart ); + var mDisplayEnd = Math.min( end, displayEnd ); + var mDisplayWidth = mDisplayEnd - mDisplayStart; + var overall = dojo.create('span', { + className: mismatch.type + ' base_'+base.toLowerCase(), + style: { + position: 'absolute', + left: 100 * ( mDisplayStart - displayStart)/featLength + '%', + width: scale*mDisplayWidth>1 ? 100 * mDisplayWidth/featLength + '%' : '1px' + } + }, featDiv ); + + // give the mismatch a mouseover if not drawing a character with the mismatch base + if( ! drawChars ) + overall.title = base; + + if( drawChars && mismatch.length <= 20 ) { + for( var i = 0; i= mDisplayStart && basePosition <= mDisplayEnd ) { + dojo.create('span',{ + className: 'base base_'+base.toLowerCase(), + style: { + position: 'absolute', + width: scale+'px', + left: (basePosition-mDisplayStart)/mDisplayWidth*100 + '%' + }, + innerHTML: base + }, overall ); + } + } + } + }, this ); } }, _getMismatches: function( feature ) { - var seq = feature.get('seq'); - if( ! seq ) - return m; - + var mismatches = []; // parse the MD tag if it has one - var mdTag = feature.get('MD'); - if( mdTag ) { - return this._mdToMismatches( feature, mdTag ); + if( feature.get('MD') ) { + mismatches.push.apply( mismatches, this._mdToMismatches( feature, feature.get('MD') ) ); + } + // parse the CIGAR tag if it has one + if( feature.get('cigar') ) { + mismatches.push.apply( mismatches, this._cigarToMismatches( feature, feature.get('cigar') ) ); } - return []; + return mismatches; + }, + + _parseCigar: function( cigar ) { + return array.map( cigar.match(/\d+\D/g), function( op ) { + return [ op.match(/\D/)[0].toUpperCase(), parseInt( op ) ]; + }); + }, + + _cigarToMismatches: function( feature, cigarstring ) { + var ops = this._parseCigar( cigarstring ); + var currOffset = 0; + var mismatches = []; + array.forEach( ops, function( oprec ) { + var op = oprec[0].toUpperCase(); + if( !op ) + return; + var len = oprec[1]; + // if( op == 'M' || op == '=' || op == 'E' ) { + // // nothing + // } + if( op == 'I' ) + mismatches.push( { start: currOffset, type: 'insertion', base: ''+len, length: 1 }); + else if( op == 'D' ) + mismatches.push( { start: currOffset, type: 'deletion', base: '*', length: len }); + else if( op == 'N' ) + mismatches.push( { start: currOffset, type: 'skip', base: 'N', length: len }); + else if( op == 'X' ) + mismatches.push( { start: currOffset, type: 'mismatch', base: 'X', length: len }); + + currOffset += len; + }); + return mismatches; }, /** @@ -89,33 +166,35 @@ return declare( HTMLFeatures, */ _mdToMismatches: function( feature, mdstring ) { var mismatchRecords = []; - var curr = { start: 0, bases: '' }; + var curr = { start: 0, base: '', length: 0, type: 'mismatch' }; var seq = feature.get('seq'); var nextRecord = function() { mismatchRecords.push( curr ); - curr = { start: curr.start + curr.bases.length, bases: ''}; + curr = { start: curr.start + curr.length, length: 0, base: '', type: 'mismatch'}; }; array.forEach( mdstring.match(/(\d+|\^[a-z]+|[a-z])/ig), function( token ) { if( token.match(/^\d/) ) { // matching bases curr.start += parseInt( token ); } else if( token.match(/^\^/) ) { // insertion in the template - var i = token.length-1; - while( i-- ) { - curr.bases += '*'; - } + curr.length = token.length-1; + curr.base = '*'; + curr.type = 'deletion'; nextRecord(); } else if( token.match(/^[a-z]/i) ) { // mismatch - curr.bases = seq.substr( curr.start, token.length ); - nextRecord(); + for( var i = 0; ih and w, diff --git a/src/JBrowse/View/Track/BlockBased.js b/src/JBrowse/View/Track/BlockBased.js index 4b17b7d94f..6087507e10 100644 --- a/src/JBrowse/View/Track/BlockBased.js +++ b/src/JBrowse/View/Track/BlockBased.js @@ -2,6 +2,7 @@ define( [ 'dojo/_base/declare', 'dojo/_base/lang', 'dojo/aspect', + 'dojo/dom-construct', 'dojo/dom-geometry', 'JBrowse/View/InfoDialog', 'dijit/Dialog', @@ -10,11 +11,14 @@ define( [ 'dijit/MenuItem', 'dijit/CheckedMenuItem', 'dijit/MenuSeparator', - 'JBrowse/Util' + 'JBrowse/Util', + 'JBrowse/View/TrackConfigEditor', + 'JBrowse/View/ConfirmDialog' ], function( declare, lang, aspect, + dom, domGeom, InfoDialog, Dialog, @@ -23,7 +27,9 @@ define( [ dijitMenuItem, dijitCheckedMenuItem, dijitMenuSeparator, - Util + Util, + TrackConfigEditor, + ConfirmDialog ) { return declare( null, @@ -45,7 +51,7 @@ return declare( null, this.refSeq = args.refSeq; this.name = args.label || this.config.label; this.key = args.key || this.config.key || this.name; - this.loaded = false; + this._changedCallback = args.changeCallback || function(){}; this.height = 0; this.shown = true; @@ -298,25 +304,30 @@ return declare( null, //this.div.style.backgroundColor = "#eee"; }, + /** + * _changeCallback invoked here is passed in costructor, + * and typically is GenomeView.showVisibleBlocks() + */ changed: function() { this.hideAll(); if( this._changedCallback ) this._changedCallback(); }, - fillLoading: function( blockIndex, block ) { + _makeLoadingMessage: function() { var msgDiv = dojo.create( 'div', { className: 'loading', innerHTML: '
Loading', title: 'Loading data...', style: { visibility: 'hidden' } - }, block ); + }); window.setTimeout(function() { msgDiv.style.visibility = 'visible'; }, 200); - this.heightUpdate( dojo.position(msgDiv).h, blockIndex ); + return msgDiv; }, fillError: function( blockIndex, block ) { + dom.empty(block); var msgDiv = dojo.create( 'div', { className: 'error', @@ -324,7 +335,17 @@ return declare( null, +(this.error ? '
Diagnostic message
'+this.error+'' : '' ), title: 'An error occurred' }, block ); - this.heightUpdate( dojo.position(msgDiv).h, blockIndex ); + this.heightUpdate( dojo.position(msgDiv).h, blockIndex ); + }, + + fillTooManyFeaturesMessage: function( blockIndex, block, scale ) { + this.fillMessage( + blockIndex, + block, + 'Too much data to show' + + (scale >= this.browser.view.maxPxPerBp ? '': '; zoom in to see detail') + + '.' + ); }, _showBlock: function(blockIndex, startBase, endBase, scale, @@ -358,7 +379,37 @@ return declare( null, containerStart, containerEnd]; - this.fillBlock.apply( this, args ); + + // loadMessage is an opaque mask div that we place over the + // block until the fillBlock finishes + var loadMessage = this._makeLoadingMessage(); + blockDiv.appendChild( loadMessage ); + + var finish = function() { + if( blockDiv && loadMessage.parentNode ) + blockDiv.removeChild( loadMessage ); + }; + + try { + this.fillBlock({ + blockIndex: blockIndex, + block: blockDiv, + leftBlock: this.blocks[blockIndex - 1], + rightBlock: this.blocks[blockIndex + 1], + leftBase: startBase, + rightBase: endBase, + scale: scale, + stripeWidth: this.widthPx, + containerStart: containerStart, + containerEnd: containerEnd, + finishCallback: finish + }); + } catch( e ) { + this.error = e; + console.error( e, e.stack ); + this.fillError( blockIndex, blockDiv ); + finish(); + } }, moveBlocks: function(delta) { @@ -636,12 +687,35 @@ return declare( null, * @returns {Array} menu options for this track's menu (usually contains save as, etc) */ _trackMenuOptions: function() { + var that = this; return [ { label: 'About this track', title: 'About track: '+(this.key||this.name), iconClass: 'jbrowseIconHelp', action: 'contentDialog', content: dojo.hitch(this,'_trackDetailsContent') + }, + { label: 'Edit config', + title: "edit this track's configuration", + iconClass: 'dijitIconConfigure', + action: function() { + new TrackConfigEditor( that.config ) + .show( function( result ) { + // replace this track's configuration + that.browser.publish( '/jbrowse/v1/v/tracks/replace', [result.conf] ); + }); + } + }, + { label: 'Delete track', + title: "delete this track", + iconClass: 'dijitIconDelete', + action: function() { + new ConfirmDialog({ title: 'Delete track?', message: 'Really delete this track?' }) + .show( function( confirmed ) { + if( confirmed ) + that.browser.publish( '/jbrowse/v1/v/tracks/delete', [that.config] ); + }); + } } ]; }, @@ -803,6 +877,19 @@ return declare( null, menu.bindDomNode( this.label ); this.trackMenu = menu; } + }, + + + // display a rendering-timeout message + fillTimeout: function( blockIndex, block ) { + dom.empty( block ); + dojo.addClass( block, 'timed_out' ); + this.fillMessage( blockIndex, block, + 'This region took too long' + + ' to display, possibly because' + + ' it contains too much data.' + + ' Try zooming in to show a smaller region.' + ); } }); diff --git a/src/JBrowse/View/Track/Canvas.js b/src/JBrowse/View/Track/Canvas.js index c08a9de14e..8455dee0cd 100644 --- a/src/JBrowse/View/Track/Canvas.js +++ b/src/JBrowse/View/Track/Canvas.js @@ -19,34 +19,55 @@ return declare( BlockBased, } }, - fillBlock: function( blockIndex, block, - leftBlock, rightBlock, - leftBase, rightBase, - scale, stripeWidth, - containerStart, containerEnd) { + testCanvasSupport: function( blockIndex, block ) { + try { + dojo.create('canvas').getContext('2d').fillStyle = 'red'; + return true; + } catch( e ) { + this.error = 'This browser does not support HTML canvas elements.'; + this.fillError( blockIndex, block ); + return false; + } + }, + + fillBlock: function( args ) { + var blockIndex = args.blockIndex; + var block = args.block; + var leftBase = args.leftBase; + var rightBase = args.rightBase; + var scale = args.scale; + + if( ! this.testCanvasSupport( blockIndex, block ) ) + return; var blockWidth = rightBase - leftBase; this.heightUpdate( this.height, blockIndex ); - this.renderCanvases( scale, leftBase, rightBase, dojo.hitch(this, function( canvases ) { - dojo.forEach( canvases, function(c) { - this.heightUpdate( c.height, blockIndex ); - c.className = 'canvas-track'; - if (!(c.parentNode && c.parentNode.parentNode)) { - c.style.position = "absolute"; - c.style.left = (100 * ((c.startBase - leftBase) / blockWidth)) + "%"; - switch (this.config.align) { - case "top": - c.style.top = "0px"; - break; - case "bottom": - default: - c.style.bottom = this.trackPadding + "px"; - break; - } - block.appendChild(c); - } - }, this); - })); + this.renderCanvases( scale, leftBase, rightBase, dojo.hitch(this, 'layoutCanvases', args ) ); + }, + + layoutCanvases: function( /**Object*/ args, /**Array[canvas]*/ canvases ) { + var block = args.block; + var leftBase = args.leftBase; + var rightBase = args.rightBase; + + dojo.forEach( canvases, function(c) { + this.heightUpdate( c.height, blockIndex ); + c.className = 'canvas-track'; + if (!(c.parentNode && c.parentNode.parentNode)) { + c.style.position = "absolute"; + c.style.left = (100 * ((c.startBase - leftBase) / blockWidth)) + "%"; + switch (this.config.align) { + case "top": + c.style.top = "0px"; + break; + case "bottom": + default: + c.style.bottom = this.trackPadding + "px"; + break; + } + block.appendChild(c); + } + }, this); }, startZoom: function(destScale, destStart, destEnd) { diff --git a/src/JBrowse/View/Track/CanvasFeatures.js b/src/JBrowse/View/Track/CanvasFeatures.js new file mode 100644 index 0000000000..15d6d50f18 --- /dev/null +++ b/src/JBrowse/View/Track/CanvasFeatures.js @@ -0,0 +1,180 @@ +/** + * Feature track that draws features using HTML5 canvas elements. + */ + +define( [ + 'dojo/_base/declare', + 'dojo/dom-construct', + 'dojo/_base/array', + 'JBrowse/View/GranularRectLayout', + 'JBrowse/View/Track/Canvas' + ], + function( declare, dom, array, Layout, CanvasTrack ) { + +return declare( CanvasTrack, { + + constructor: function( args ) { + }, + + _defaultConfig: function() { + return { + maxFeatureScreenDensity: 400, + style: { + bgcolor: 'goldenrod', + fgcolor: null, + height: 3, + marginBottom: 1 + } + }; + }, + + fillBlock: function( args ) { + var blockIndex = args.blockIndex; + var block = args.block; + var leftBase = args.leftBase; + var rightBase = args.rightBase; + var scale = args.scale; + + if( ! this.testCanvasSupport( blockIndex, block ) ) + return; + + var region = { ref: this.refSeq.name, start: leftBase, end: rightBase }; + + this.store.getRegionStats( + region, + dojo.hitch( this, function( stats ) { + + var density = stats.featureDensity; + var featureScale = this.config.style.featureScale || density / this.config.maxFeatureScreenDensity; // (feat/bp) / ( feat/px ) = px/bp ) + + if( scale < featureScale ) { + this.fillTooManyFeaturesMessage( + blockIndex, + block, + scale + ); + args.finishCallback(); + } + else { + this.fillFeatures( dojo.mixin( {stats: stats}, args ) ); + } + })); + }, + + _getLayout: function( scale ) { + // create the layout if we need to, and if we can + if( ( ! this.layout || this.layout.pitchX != 4/scale ) && scale ) + this.layout = new Layout({pitchX: 4/scale, pitchY: this.config.layoutPitchY || (this.config.style.height + this.config.style.marginBottom) }); + + return this.layout; + }, + + fillFeatures: function( args ) { + var track = this; + + var blockIndex = args.blockIndex; + var block = args.block; + var scale = args.scale; + var leftBase = args.leftBase; + var rightBase = args.rightBase; + var finishCallback = args.finishCallback; + + var timedOut = false; + var timeOutError = { toString: function() { return 'Timed out trying to display '+track.name+' block '+blockIndex; } }; + if( this.config.blockDisplayTimeout ) + window.setTimeout( function() { timedOut = true; }, this.config.blockDisplayTimeout ); + + var fRects = []; + var featCallback = dojo.hitch(this,function( feature ) { + if( timedOut ) + throw timeOutError; + + fRects.push( this.layoutFeature( feature, leftBase, scale ) ); + }); + + this.store.getFeatures( { ref: this.refSeq.name, + start: leftBase, + end: rightBase + }, + featCallback, + function () { + var totalHeight = track._getLayout(scale).getTotalHeight(); + var c = dojo.create( + 'canvas', + { height: totalHeight, + width: block.offsetWidth+1, + style: { cursor: 'default' }, + innerHTML: 'Your web browser cannot display this type of track.', + className: 'canvas-track' + }, + block + ); + track.renderFeatures( fRects, c ); + + track.layoutCanvases([c]); + track.heightUpdate( totalHeight, + blockIndex ); + finishCallback(); + }, + function( error ) { + track.error = error; + if( error === timeOutError ) { + track.fillTimeout( blockIndex, block ); + } else { + console.error( error, error.stack ); + track.fillError( blockIndex, block ); + } + finishCallback(); + } + ); + }, + + // calculate the placement of the feature on the canvas for this + // block. + layoutFeature: function( feature, leftBase, scale ) { + var layoutStart = feature.get('start'); + var layoutEnd = feature.get('end'); + + var fHeight = this.config.style.height; + var levelHeight = fHeight + this.config.style.marginBottom; + + var uniqueId = feature.id(); + var top = this._getLayout( scale ) + .addRect( uniqueId, + layoutStart, + layoutEnd, + levelHeight); + + var fRect = { + w: (layoutEnd-layoutStart)*scale, + l: (layoutStart-leftBase)*scale, + h: fHeight, + t: top, + + f: feature + }; + return fRect; + }, + + // draw the features on the canvas + renderFeatures: function( fRects, canvas ) { + var context = canvas.getContext('2d'); + var fgcolor = this.config.style.fgcolor; + context.fillStyle = this.config.style.bgcolor; + array.forEach( fRects, function( fRect ) { + context.fillRect( fRect.l, fRect.t, fRect.w, fRect.h ); + }); + if( fgcolor ) { + context.lineWidth = 1; + context.strokeStyle = fgcolor; + array.forEach( fRects, function( fRect ) { + // need to stroke a smaller rectangle to remain within + // the bounds of the feature's overall height and + // width, because of the way stroking is done in + // canvas. thus the +0.5 and -1 business. + context.strokeRect( fRect.l+0.5, fRect.t+0.5, fRect.w-1, fRect.h-1 ); + }); + } + } +}); +}); \ No newline at end of file diff --git a/src/JBrowse/View/Track/ExportMixin.js b/src/JBrowse/View/Track/ExportMixin.js index f2638b637c..12c6290257 100644 --- a/src/JBrowse/View/Track/ExportMixin.js +++ b/src/JBrowse/View/Track/ExportMixin.js @@ -2,12 +2,14 @@ define( [ 'dojo/_base/array', 'dojo/aspect', 'dojo/has', + 'dojo/window', + 'dojo/dom-construct', 'JBrowse/Util', 'dijit/form/Button', 'dijit/form/RadioButton', 'dijit/Dialog' ], - function( array, aspect, has, Util, dijitButton, dijitRadioButton, dijitDialog ) { + function( array, aspect, has, dojoWindow, dom, Util, dijitButton, dijitRadioButton, dijitDialog ) { /** * Mixin for a track that can export its data. * @lends JBrowse.View.Track.ExportMixin @@ -50,7 +52,7 @@ return { region.canExport = this._canExportRegion( region ); },this.track); - var form = dojo.create('form', { onSubmit: function() { return false; } }); + var form = dom.create('form', { onSubmit: function() { return false; } }); form.innerHTML = '' + '
' + ' Region to save' @@ -77,16 +79,19 @@ return { var fmts = ''; var checked = 0; array.forEach( this.track._exportFormats(), function(fmt) { + if( ! fmt.name ) { + fmt = { name: fmt, label: fmt }; + } fmts += ' ' - + ' ' + +' data-dojo-type="dijit.form.RadioButton" name="format" id="format'+fmt.name+'" value="'+fmt.name+'" />' + + ' ' + '
'; - }); + },this); return fmts; }.call(this) + '
'; - var actionBar = dojo.create( 'div', { + var actionBar = dom.create( 'div', { className: 'dijitDialogPaneActionBar' }); @@ -99,6 +104,7 @@ return { label: 'View', disabled: ! array.some(possibleRegions,function(r) { return r.canExport; }), onClick: dojo.hitch( this.track, function() { + var track = this; viewButton.set('disabled',true); viewButton.set('iconClass','jbrowseIconBusy'); @@ -106,14 +112,14 @@ return { var format = this._readRadio( form.elements.format ); this.exportRegion( region, format, function(output) { dialog.hide(); - var text = dojo.create('textarea', { - rows: 30, + var text = dom.create('textarea', { + rows: Math.round( dojoWindow.getBox().h / 12 * 0.5 ), wrap: 'soft', cols: 80, readonly: true }); text.value = output; - var actionBar = dojo.create( 'div', { + var actionBar = dom.create( 'div', { className: 'dijitDialogPaneActionBar' }); var exportView = new dijitDialog({ @@ -132,10 +138,10 @@ return { { iconClass: 'dijitIconSave', label: 'Save', - onClick: dojo.hitch(this, function() { + onClick: function() { exportView.hide(); - window.location.href="data:application/x-"+format.toLowerCase()+","+escape(output); - }) + track._fileDownload({ format: format, data: output }); + } }).placeAt(actionBar); } @@ -160,10 +166,10 @@ return { var region = this._readRadio( form.elements.region ); dlButton.set('disabled',true); dlButton.set('iconClass','jbrowseIconBusy'); - this.exportRegion( region, format, function( output ) { + this.exportRegion( region, format, dojo.hitch( this, function( output ) { dialog.hide(); - window.location.href="data:application/x-"+format.toLowerCase()+","+escape(output); - }); + this._fileDownload({ format: format, data: output }); + })); })}) .placeAt( actionBar ); } @@ -171,6 +177,17 @@ return { return [ form, actionBar ]; }, + _fileDownload: function( args ) { + // do the file download by setting the src of a hidden iframe, + // because missing with the href of the window messes up + // WebApollo long polling + var iframe = dom.create( 'iframe', { + style: { display: 'none' } + },this.div ); + iframe.src = "data:"+( args.format ? 'application/x-'+args.format.toLowerCase() : 'text/plain' ) + +","+escape( args.data || '' ); + }, + // cross-platform function for (portably) reading the value of a radio control. sigh. *rolls eyes* _readRadio: function( r ) { if( r.length ) { diff --git a/src/JBrowse/View/Track/FeatureCoverage.js b/src/JBrowse/View/Track/FeatureCoverage.js index 98dd45a47b..458d8bec7e 100644 --- a/src/JBrowse/View/Track/FeatureCoverage.js +++ b/src/JBrowse/View/Track/FeatureCoverage.js @@ -21,6 +21,17 @@ var CoverageFeature = Util.fastDeclare( return declare( Wiggle, { + + _defaultConfig: function() { + return Util.deepUpdate( + dojo.clone( this.inherited(arguments) ), + { + min_score: 0, + max_score: 100 + } + ); + }, + getGlobalStats: function() { return {}; }, @@ -28,28 +39,37 @@ return declare( Wiggle, getFeatures: function( query, featureCallback, finishCallback, errorCallback ) { var leftBase = query.start; var rightBase = query.end; - var coverage = new Array( rightBase-leftBase ); + var scale = query.scale; // px/bp + var widthBp = rightBase-leftBase; + var widthPx = widthBp * ( query.scale || 1/query.basesPerSpan); + + var binWidth = Math.ceil( query.basesPerSpan ); // in bp + + var coverageBins = new Array( Math.ceil( widthBp/binWidth ) ); + var bpToBin = function( bp ) { + return Math.floor( (bp-leftBase) / binWidth ); + }; + this.store.getFeatures( query, dojo.hitch( this, function( feature ) { - var end = feature.get('end'); - for( var i = feature.get('start')+1; i <= end; i++ ) { - coverage[i-leftBase] = (coverage[i-leftBase] || 0) + 1; + var startBin = bpToBin( feature.get('start') ); + var endBin = bpToBin( feature.get('end')-1 ); + for( var i = startBin; i <= endBin; i++ ) { + coverageBins[i] = (coverageBins[i] || 0) + 1; } }), function () { // make fake features from the coverage - var currFeat; - array.forEach( coverage, function( c, i ) { - if( currFeat && c == currFeat.score ) { - currFeat.end = leftBase+i; - } else { - if( currFeat ) - featureCallback( currFeat ); - currFeat = new CoverageFeature({ start: leftBase + i - 1, end: leftBase+i, score: c || 0 }); - } - }); - + for( var i = 0; i < coverageBins.length; i++ ) { + var score = coverageBins[i] || 0; + var bpOffset = leftBase+binWidth*i; + featureCallback( new CoverageFeature({ + start: bpOffset, + end: bpOffset+binWidth, + score: score + })); + } finishCallback(); } ); diff --git a/src/JBrowse/View/Track/FixedImage.js b/src/JBrowse/View/Track/FixedImage.js index d88d081b98..5ef60d5216 100644 --- a/src/JBrowse/View/Track/FixedImage.js +++ b/src/JBrowse/View/Track/FixedImage.js @@ -53,11 +53,13 @@ return declare( BlockBased, }, - fillBlock: function(blockIndex, block, - leftBlock, rightBlock, - leftBase, rightBase, - scale, stripeWidth, - containerStart, containerEnd) { + fillBlock: function( args ) { + var blockIndex = args.blockIndex; + var block = args.block; + var leftBase = args.leftBase; + var rightBase = args.rightBase; + var scale = args.scale; + var finishCallback = args.finishCallback || function() {}; var blockWidth = rightBase - leftBase; @@ -92,6 +94,7 @@ return declare( BlockBased, im.onload = loadhandler; }, this); + finishCallback(); }), dojo.hitch( this, function( error ) { if( error.status == 404 ) { @@ -100,6 +103,7 @@ return declare( BlockBased, this.error = error; this.fillError( blockIndex, block ); } + finishCallback(); }) ); }, diff --git a/src/JBrowse/View/Track/FixedImage/Wiggle.js b/src/JBrowse/View/Track/FixedImage/Wiggle.js index 676fb39125..fd25945a1e 100644 --- a/src/JBrowse/View/Track/FixedImage/Wiggle.js +++ b/src/JBrowse/View/Track/FixedImage/Wiggle.js @@ -42,7 +42,7 @@ var Wiggle = declare( FixedImage, makeWiggleYScale: function() { var thisB = this; this.store.getGlobalStats( function( stats ) { - if( ! this.yscale ) + if( ! thisB.yscale ) thisB.makeYScale({ min: stats.scoreMin, max: stats.scoreMax }); }); } diff --git a/src/JBrowse/View/Track/GridLines.js b/src/JBrowse/View/Track/GridLines.js index 983c7817fb..158e931e17 100644 --- a/src/JBrowse/View/Track/GridLines.js +++ b/src/JBrowse/View/Track/GridLines.js @@ -21,13 +21,10 @@ return dojo.declare( BlockBased, makeTrackLabel: function() {}, makeTrackMenu: function() {}, - fillBlock: function(blockIndex, block, - leftBlock, rightBlock, - leftBase, rightBase, scale, - padding, stripeWidth) { - - this.renderGridlines( block, leftBase, rightBase ); - this.heightUpdate(100, blockIndex); + fillBlock: function( args ) { + this.renderGridlines( args.block, args.leftBase, args.rightBase ); + args.finishCallback(); + this.heightUpdate(100, args.blockIndex); }, renderGridlines: function(block,leftBase,rightBase) { diff --git a/src/JBrowse/View/Track/HTMLFeatures.js b/src/JBrowse/View/Track/HTMLFeatures.js index e70216cbed..78ba734929 100644 --- a/src/JBrowse/View/Track/HTMLFeatures.js +++ b/src/JBrowse/View/Track/HTMLFeatures.js @@ -2,6 +2,7 @@ define( [ 'dojo/_base/declare', 'dojo/_base/lang', 'dojo/_base/array', + 'dojo/dom-construct', 'dojo/dom-geometry', 'dojo/on', 'dojo/has', @@ -19,6 +20,7 @@ define( [ function( declare, lang, array, + dom, domGeom, on, has, @@ -50,12 +52,22 @@ var HTMLFeatures = declare( BlockBased, { //number of histogram bins per block this.numBins = 25; this.histLabel = false; - this.padding = 5; + + this.defaultPadding = 5; + this.padding = this.defaultPadding; + + this.glyphHeightPad = 1; + this.levelHeightPad = 2; + this.labelPad = 1; + + // if calculated feature % width would be less than minFeatWidth, then set width to minFeatWidth instead + this.minFeatWidth = 0.1; + this.trackPadding = args.trackPadding; this.heightCache = {}; // cache for the heights of some // feature elements, indexed by the - // complete className of the feature + // complete cassName of the feature // make a default click event handler if( ! (this.config.events||{}).click ) { @@ -114,7 +126,7 @@ HTMLFeatures = declare( HTMLFeatures, description: true, maxFeatureScreenDensity: 0.5, - layoutPitchY: 6, + blockDisplayTimeout: 5000, style: { className: "feature2", @@ -126,7 +138,8 @@ HTMLFeatures = declare( HTMLFeatures, minSubfeatureWidth: 6, maxDescriptionLength: 70, - showLabels: true + showLabels: true, + centerChildrenVertically: true // by default use feature child centering }, hooks: { create: function(track, feat ) { @@ -152,10 +165,11 @@ HTMLFeatures = declare( HTMLFeatures, defaultFeatureDetail: function( /** JBrowse.Track */ track, /** Object */ f, /** HTMLElement */ featDiv, /** HTMLElement */ container ) { var fmt = dojo.hitch( this, '_fmtDetailField' ); container = container || dojo.create('div', { className: 'detail feature-detail feature-detail-'+track.name, innerHTML: '' } ); - container.innerHTML += fmt( 'Name', f.get('name') ); - container.innerHTML += fmt( 'Type', f.get('type') ); - container.innerHTML += fmt( 'Description', f.get('note') ); - container.innerHTML += fmt( + var coreDetails = dojo.create('div', { className: 'core' }, container ); + coreDetails.innerHTML += fmt( 'Name', f.get('name') ); + coreDetails.innerHTML += fmt( 'Type', f.get('type') ); + coreDetails.innerHTML += fmt( 'Description', f.get('note') ); + coreDetails.innerHTML += fmt( 'Position', Util.assembleLocString({ start: f.get('start'), end: f.get('end'), @@ -163,13 +177,18 @@ HTMLFeatures = declare( HTMLFeatures, strand: f.get('strand') }) ); - container.innerHTML += fmt( 'Length', Util.addCommas(f.get('end')-f.get('start'))+' b' ); + coreDetails.innerHTML += fmt( 'Length', Util.addCommas(f.get('end')-f.get('start'))+' bp' ); // render any additional tags as just key/value var additionalTags = array.filter( f.tags(), function(t) { return ! {name:1,start:1,end:1,strand:1,note:1,subfeatures:1,type:1}[t.toLowerCase()]; }); - dojo.forEach( additionalTags.sort(), function(t) { - container.innerHTML += fmt( t, f.get(t) ); - }); + if( additionalTags.length ) { + var at_html = '

Attributes

'; + dojo.forEach( additionalTags.sort(), function(t) { + at_html += fmt( t, f.get(t) ); + }); + at_html += '
'; + container.innerHTML += at_html; + } // render the sequence underlying this feature if possible var field_container = dojo.create('div', { className: 'field_container feature_sequence' }, container ); @@ -186,6 +205,7 @@ HTMLFeatures = declare( HTMLFeatures, if( refSeqStore ) { refSeqStore.getFeatures( { ref: this.refSeq.name, start: f.get('start'), end: f.get('end')}, + // feature callback dojo.hitch( this, function( feature ) { var seq = feature.get('seq'); valueContainer = dojo.byId(valueContainerID) || valueContainer; @@ -205,9 +225,17 @@ HTMLFeatures = declare( HTMLFeatures, f.get('strand') == -1 ? Util.revcom(seq) : seq, valueContainer ); - })); + }), + // end callback + function() {}, + // error callback + dojo.hitch( this, function() { + valueContainer = dojo.byId(valueContainerID) || valueContainer; + valueContainer.innerHTML = 'reference sequence not available'; + }) + ); } else { - valueContainer.innerHTML = 'reference sequences not loaded'; + valueContainer.innerHTML = 'reference sequence not available'; } })); @@ -298,7 +326,12 @@ HTMLFeatures = declare( HTMLFeatures, }; }, - fillHist: function( blockIndex, block, leftBase, rightBase, stripeWidth ) { + fillHist: function( args ) { + var blockIndex = args.blockIndex; + var block = args.block; + var leftBase = args.leftBase; + var rightBase = args.rightBase; + var stripeWidth = args.stripeWidth; var dims = this._histDimensions( Math.abs( rightBase - leftBase ) ); @@ -315,7 +348,7 @@ HTMLFeatures = declare( HTMLFeatures, if (!(typeof hist[bin] == 'number' && isFinite(hist[bin]))) continue; binDiv = document.createElement("div"); - binDiv.className = "hist "+track.config.style.className + "-hist"; + binDiv.className = "hist feature-hist "+track.config.style.className + "-hist"; binDiv.style.cssText = "left: " + ((bin / track.numBins) * 100) + "%; " + "height: " @@ -382,6 +415,8 @@ HTMLFeatures = declare( HTMLFeatures, this.store.histogram( leftBase, rightBase, this.numBins, makeHistBlock); } + + args.finishCallback(); }, endZoom: function(destScale, destBlockBases) { @@ -436,7 +471,14 @@ HTMLFeatures = declare( HTMLFeatures, },this); }, - fillBlock: function( blockIndex, block, leftBlock, rightBlock, leftBase, rightBase, scale, stripeWidth, containerStart, containerEnd ) { + fillBlock: function( args ) { + var blockIndex = args.blockIndex; + var block = args.block; + var leftBase = args.leftBase; + var rightBase = args.rightBase; + var scale = args.scale; + var containerStart = args.containerStart; + var containerEnd = args.containerEnd; var region = { ref: this.refSeq.name, start: leftBase, end: rightBase }; @@ -444,8 +486,9 @@ HTMLFeatures = declare( HTMLFeatures, region, dojo.hitch( this, function( stats ) { - var density = stats.featureDensity; - var histScale = this.config.style.histScale || density * this.config.style._defaultHistScale; + var density = stats.featureDensity; + var histScale = this.config.style.histScale || density * this.config.style._defaultHistScale; + var featureScale = this.config.style.featureScale || density / this.config.maxFeatureScreenDensity; // (feat/bp) / ( feat/px ) = px/bp ) // only update the label once for each block size var blockBases = Math.abs( leftBase-rightBase ); @@ -462,20 +505,18 @@ HTMLFeatures = declare( HTMLFeatures, // if we our store offers density histograms, and we are zoomed out far enough, draw them if( this.store.histograms && scale < histScale ) { - this.fillHist( blockIndex, block, leftBase, rightBase, stripeWidth, - containerStart, containerEnd); + this.fillHist( args ); } // if we have no histograms, check the predicted density of // features on the screen, and display a message if it's // bigger than maxFeatureScreenDensity - else if( stats.featureDensity / scale > this.config.maxFeatureScreenDensity ) { - this.fillMessage( + else if( scale < featureScale ) { + this.fillTooManyFeaturesMessage( blockIndex, block, - 'Too many features to show' - + (scale >= this.browser.view.maxPxPerBp ? '': '; zoom in to see detail') - + '.' + scale ); + args.finishCallback(); } else { // if we have transitioned to viewing features, delete the @@ -483,9 +524,7 @@ HTMLFeatures = declare( HTMLFeatures, if( this.yscale ) { this._removeYScale(); } - this.fillFeatures(blockIndex, block, leftBlock, rightBlock, - leftBase, rightBase, scale, stats, - containerStart, containerEnd); + this.fillFeatures( dojo.mixin( {stats: stats}, args ) ); } })); }, @@ -564,23 +603,24 @@ HTMLFeatures = declare( HTMLFeatures, overlaps = overlaps || []; for (var i = 0; i < overlaps.length; i++) { - //if the feature overlaps destBlock, - //move to destBlock & re-position - sourceSlot = sourceBlock.featureNodes[ overlaps[i] ]; - if (sourceSlot && ("label" in sourceSlot)) { + //if the feature overlaps destBlock, + //move to destBlock & re-position + sourceSlot = sourceBlock.featureNodes[ overlaps[i] ]; + if (sourceSlot && ("label" in sourceSlot)) { sourceSlot.label.parentNode.removeChild(sourceSlot.label); - } - if (sourceSlot && sourceSlot.feature) { - if ( sourceSlot.layoutEnd > destLeft - && sourceSlot.feature.get('start') < destRight ) { + } + if (sourceSlot && sourceSlot.feature) { + if ( sourceSlot.layoutEnd > destLeft + && sourceSlot.feature.get('start') < destRight ) { + + sourceSlot.parentNode.removeChild(sourceSlot); - sourceBlock.removeChild(sourceSlot); delete sourceBlock.featureNodes[ overlaps[i] ]; - var featDiv = - this.renderFeature(sourceSlot.feature, overlaps[i], - destBlock, scale, sourceSlot._labelScale, sourceSlot._descriptionScale, - containerStart, containerEnd, destBlock ); + /* feature render, adding to block, centering refactored into addFeatureToBlock() */ + var featDiv = this.addFeatureToBlock( sourceSlot.feature, overlaps[i], + destBlock, scale, sourceSlot._labelScale, sourceSlot._descriptionScale, + containerStart, containerEnd ); } } } @@ -588,23 +628,32 @@ HTMLFeatures = declare( HTMLFeatures, /** * arguments: - * @param block div to be filled with info - * @param leftBlock div to the left of the block to be filled - * @param rightBlock div to the right of the block to be filled - * @param leftBase starting base of the block - * @param rightBase ending base of the block - * @param scale pixels per base at the current zoom level - * @param containerStart don't make HTML elements extend further left than this - * @param containerEnd don't make HTML elements extend further right than this. 0-based. + * @param args.block div to be filled with info + * @param args.leftBlock div to the left of the block to be filled + * @param args.rightBlock div to the right of the block to be filled + * @param args.leftBase starting base of the block + * @param args.rightBase ending base of the block + * @param args.scale pixels per base at the current zoom level + * @param args.containerStart don't make HTML elements extend further left than this + * @param args.containerEnd don't make HTML elements extend further right than this. 0-based. */ - fillFeatures: function(blockIndex, block, leftBlock, rightBlock, leftBase, rightBase, scale, stats, containerStart, containerEnd) { + fillFeatures: function(args) { + var blockIndex = args.blockIndex; + var block = args.block; + var leftBase = args.leftBase; + var rightBase = args.rightBase; + var scale = args.scale; + var stats = args.stats; + var containerStart = args.containerStart; + var containerEnd = args.containerEnd; + var finishCallback = args.finishCallback; this.scale = scale; block.featureNodes = {}; //determine the glyph height, arrowhead width, label text dimensions, etc. - if (!this.haveMeasurements) { + if( !this.haveMeasurements ) { this.measureStyles(); this.haveMeasurements = true; } @@ -613,17 +662,24 @@ HTMLFeatures = declare( HTMLFeatures, var descriptionScale = this.config.style.descriptionScale || stats.featureDensity * this.config.style._defaultDescriptionScale; var curTrack = this; + + var timedOut = false; + var timeOutError = { toString: function() { return 'Timed out trying to display '+curTrack.name+' block '+blockIndex; } }; + if( this.config.blockDisplayTimeout ) + window.setTimeout( function() { timedOut = true; }, this.config.blockDisplayTimeout ); + var featCallback = dojo.hitch(this,function( feature ) { - var uniqueId = feature._uniqueID; + if( timedOut ) + throw timeOutError; + + var uniqueId = feature.id(); if( ! this._featureIsRendered( uniqueId ) ) { - this.renderFeature( feature, uniqueId, block, scale, labelScale, descriptionScale, - containerStart, containerEnd, block ); + /* feature render, adding to block, centering refactored into addFeatureToBlock() */ + var featDiv = this.addFeatureToBlock( feature, uniqueId, block, scale, labelScale, descriptionScale, + containerStart, containerEnd ); } }); - // var startBase = goLeft ? rightBase : leftBase; - // var endBase = goLeft ? leftBase : rightBase; - this.store.getFeatures( { ref: this.refSeq.name, start: leftBase, end: rightBase @@ -632,14 +688,35 @@ HTMLFeatures = declare( HTMLFeatures, function () { curTrack.heightUpdate(curTrack._getLayout(scale).getTotalHeight(), blockIndex); + finishCallback(); }, function( error ) { curTrack.error = error; - curTrack.fillError( blockIndex, block ); + if( error === timeOutError ) { + curTrack.fillTimeout( blockIndex, block ); + } else { + console.error( error, error.stack ); + curTrack.fillError( blockIndex, block ); + } + finishCallback(); } ); }, + /** + * Creates feature div, adds to block, and centers subfeatures. + * Overridable by subclasses that need more control over the substructure. + */ + addFeatureToBlock: function( feature, uniqueId, block, scale, labelScale, descriptionScale, + containerStart, containerEnd ) { + var featDiv = this.renderFeature( feature, uniqueId, block, scale, labelScale, descriptionScale, + containerStart, containerEnd ); + block.appendChild( featDiv ); + if( this.config.style.centerChildrenVertically ) + this._centerChildrenVertically( featDiv ); + return featDiv; + }, + /** * Returns true if a feature is visible and rendered someplace in the blocks of this track. * @private @@ -679,8 +756,8 @@ HTMLFeatures = declare( HTMLFeatures, if (Util.is_ie6) heightTest.appendChild(document.createComment("foo")); document.body.appendChild(heightTest); glyphBox = domGeom.getMarginBox(heightTest); - this.glyphHeight = glyphBox.h; - this.padding += glyphBox.w; + this.glyphHeight = Math.round(glyphBox.h); + this.padding = this.defaultPadding + glyphBox.w; document.body.removeChild(heightTest); //determine the width of the arrowhead, if any @@ -700,7 +777,28 @@ HTMLFeatures = declare( HTMLFeatures, } }, - renderFeature: function( feature, uniqueId, block, scale, labelScale, descriptionScale, containerStart, containerEnd, destBlock ) { + getFeatDiv: function( feature ) { + var id = this.getId( feature ); + if( ! id ) + return null; + + for( var i = 0; i < this.blocks.length; i++ ) { + var b = this.blocks[i]; + if( b && b.featureNodes ) { + var f = b.featureNodes[id]; + if( f ) + return f; + } + } + + return null; + }, + + getId: function( f ) { + return f.id(); + }, + + renderFeature: function( feature, uniqueId, block, scale, labelScale, descriptionScale, containerStart, containerEnd ) { //featureStart and featureEnd indicate how far left or right //the feature extends in bp space, including labels //and arrowheads if applicable @@ -711,8 +809,29 @@ HTMLFeatures = declare( HTMLFeatures, featureEnd = parseInt(featureEnd); if( typeof featureStart == 'string' ) featureStart = parseInt(featureStart); + // layoutStart: start genome coord (at current scale) of horizontal space need to render feature, + // including decorations (arrowhead, label, etc) and padding + var layoutStart = featureStart; + // layoutEnd: end genome coord (at current scale) of horizontal space need to render feature, + // including decorations (arrowhead, label, etc) and padding + var layoutEnd = featureEnd; + + // JBrowse now draws arrowheads within feature genome coord bounds + // For WebApollo we're keeping arrow outside of feature genome coord bounds, + // because otherwise arrow can obscure edge-matching, CDS/UTR transitions, small inton/exons, etc. + // Would like to implement arrowhead change in WebApollo plugin, but would need to refactor HTMLFeature more to allow for that + if (this.config.style.arrowheadClass) { + switch (feature.get('strand')) { + case 1: + case '+': + layoutEnd += (this.plusArrowWidth / scale); break; + case -1: + case '-': + layoutStart -= (this.minusArrowWidth / scale); break; + } + } - var levelHeight = this.glyphHeight; + var levelHeight = this.glyphHeight + this.glyphHeightPad; // if the label extends beyond the feature, use the // label end position as the end position for layout @@ -725,27 +844,28 @@ HTMLFeatures = declare( HTMLFeatures, // calculated height of the feature if it will be displayed if( this.showLabels && scale >= labelScale ) { if (name) { - featureEnd = Math.max(featureEnd, featureStart + (''+name).length * this.labelWidth / scale ); - levelHeight += this.labelHeight + 1; + layoutEnd = Math.max(layoutEnd, layoutStart + (''+name).length * this.labelWidth / scale ); + levelHeight += this.labelHeight + this.labelPad; } if( description ) { - featureEnd = Math.max( featureEnd, featureStart + (''+description).length * this.labelWidth / scale ); - levelHeight += this.labelHeight + 1; + layoutEnd = Math.max( layoutEnd, layoutStart + (''+description).length * this.labelWidth / scale ); + levelHeight += this.labelHeight + this.labelPad; } } - featureEnd += Math.max(1, this.padding / scale); + layoutEnd += Math.max(1, this.padding / scale); - var top = this._getLayout( scale ).addRect( uniqueId, - featureStart, - featureEnd, - levelHeight); + var top = this._getLayout( scale ) + .addRect( uniqueId, + layoutStart, + layoutEnd, + levelHeight); var featDiv = this.config.hooks.create(this, feature ); this._connectFeatDivHandlers( featDiv ); featDiv.track = this; featDiv.feature = feature; - featDiv.layoutEnd = featureEnd; - featDiv.className = (featDiv.className ? featDiv.className + " " : "") + "feature"; + featDiv.layoutEnd = layoutEnd; + // (callbackArgs are the args that will be passed to callbacks // in this feature's context menu or left-click handlers) featDiv.callbackArgs = [ this, featDiv.feature, featDiv ]; @@ -759,30 +879,33 @@ HTMLFeatures = declare( HTMLFeatures, block.featureNodes[uniqueId] = featDiv; // record whether this feature protrudes beyond the left and/or right side of the block - if( featureStart < block.startBase ) { + if( layoutStart < block.startBase ) { if( ! block.leftOverlaps ) block.leftOverlaps = []; block.leftOverlaps.push( uniqueId ); } - if( featureEnd > block.endBase ) { + if( layoutEnd > block.endBase ) { if( ! block.rightOverlaps ) block.rightOverlaps = []; block.rightOverlaps.push( uniqueId ); } + dojo.addClass(featDiv, "feature"); + var className = this.config.style.className; + if (className == "{type}") { className = feature.get('type'); } var strand = feature.get('strand'); switch (strand) { case 1: case '+': - featDiv.className = featDiv.className + " " + this.config.style.className + " plus-" + this.config.style.className; break; + dojo.addClass(featDiv, "plus-" + className); break; case -1: case '-': - featDiv.className = featDiv.className + " " + this.config.style.className + " minus-" + this.config.style.className; break; + dojo.addClass(featDiv, "minus-" + className); break; default: - featDiv.className = featDiv.className + " " + this.config.style.className; break; + dojo.addClass(featDiv, className); } - var phase = feature.get('phase'); if ((phase !== null) && (phase !== undefined)) - featDiv.className = featDiv.className + " " + featDiv.className + "_phase" + phase; +// featDiv.className = featDiv.className + " " + featDiv.className + "_phase" + phase; + dojo.addClass(featDiv, className + "_phase" + phase); // Since some browsers don't deal well with the situation where // the feature goes way, way offscreen, we truncate the feature @@ -790,10 +913,10 @@ HTMLFeatures = declare( HTMLFeatures, // To make sure the truncated end of the feature never gets shown, // we'll destroy and re-create the feature (with updated truncated // boundaries) in the transfer method. - var displayStart = Math.max( feature.get('start'), containerStart ); - var displayEnd = Math.min( feature.get('end'), containerEnd ); + var displayStart = Math.max( featureStart, containerStart ); + var displayEnd = Math.min( featureEnd, containerEnd ); var blockWidth = block.endBase - block.startBase; - var featwidth = Math.max( 1, (100 * ((displayEnd - displayStart) / blockWidth))); + var featwidth = Math.max( this.minFeatWidth, (100 * ((displayEnd - displayStart) / blockWidth))); featDiv.style.cssText = "left:" + (100 * (displayStart - block.startBase) / blockWidth) + "%;" + "top:" + top + "px;" @@ -804,26 +927,18 @@ HTMLFeatures = declare( HTMLFeatures, var ah = document.createElement("div"); var featwidth_px = featwidth/100*blockWidth*scale; - // NOTE: arrowheads are hidden until they are centered by - // _centerFeatureElements, so that they don't jump around - // on the screen switch (strand) { case 1: case '+': - if( featwidth_px > this.plusArrowWidth*1.1 ) { - ah.className = "plus-" + this.config.style.arrowheadClass; - ah.style.cssText = "visibility: hidden; position: absolute; right: 0px; top: 0px; z-index: 100;"; - featDiv.appendChild(ah); - } + ah.className = "plus-" + this.config.style.arrowheadClass; + ah.style.cssText = "left: 100%;" + featDiv.appendChild(ah); break; case -1: case '-': - if( featwidth_px > this.minusArrowWidth*1.1 ) { - ah.className = "minus-" + this.config.style.arrowheadClass; - ah.style.cssText = - "visibility: hidden; position: absolute; left: 0px; top: 0px; z-index: 100;"; - featDiv.appendChild(ah); - } + ah.className = "minus-" + this.config.style.arrowheadClass; + ah.style.cssText = "left: " + (-this.minusArrowWidth) + "px;" + featDiv.appendChild(ah); break; } } @@ -835,13 +950,13 @@ HTMLFeatures = declare( HTMLFeatures, +( description ? '
'+description+'
' : '' ), style: { top: (top + this.glyphHeight + 2) + "px", - left: (100 * (featureStart - block.startBase) / blockWidth)+'%' + left: (100 * (layoutStart - block.startBase) / blockWidth)+'%' } }, block ); this._connectFeatDivHandlers( labelDiv ); - featDiv.label = labelDiv; + featDiv.label = labelDiv; featDiv.labelDiv = labelDiv; labelDiv.feature = feature; @@ -851,74 +966,71 @@ HTMLFeatures = declare( HTMLFeatures, labelDiv.callbackArgs = [ this, featDiv.feature, featDiv ]; } - if( destBlock ) { - destBlock.appendChild(featDiv); + if( featwidth > this.config.style.minSubfeatureWidth ) { + this.handleSubFeatures(feature, featDiv, displayStart, displayEnd, block); } - // defer subfeature rendering and modification hooks into a - // timeout so that navigation feels faster. - window.setTimeout( dojo.hitch( this, - function() { - - if( featwidth > this.config.style.minSubfeatureWidth ) { - var subfeatures = feature.get('subfeatures'); - if( subfeatures ) { - for (var i = 0; i < subfeatures.length; i++) { - this.renderSubfeature(feature, featDiv, - subfeatures[i], - displayStart, displayEnd); - } - } - } - - //ie6 doesn't respect the height style if the div is empty - if (Util.is_ie6) featDiv.appendChild(document.createComment()); - //TODO: handle event-handler-related IE leaks + // render the popup menu if configured + if( this.config.menuTemplate ) { + window.setTimeout( dojo.hitch( this, '_connectMenus', featDiv ), 50+Math.random()*150 ); + } - /* Temi / AP adding right menu click - AP new schema menuTemplate: an array where everything except - children, popup and url are passed on as properties to a new - dijit.Menu object - */ + if ( typeof this.config.hooks.modify == 'function' ) { + this.config.hooks.modify(this, feature, featDiv); + } - // render the popup menu if configured - if( this.config.menuTemplate ) { - this._connectMenus( featDiv ); - } - if( destBlock ) - this._centerFeatureElements(featDiv); + return featDiv; + }, - if ( typeof this.config.hooks.modify == 'function' ) { - this.config.hooks.modify(this, feature, featDiv); - } - }),50+Math.random()*50); + handleSubFeatures: function( feature, featDiv, + displayStart, displayEnd, block ) { + var subfeatures = feature.get('subfeatures'); + if( subfeatures ) { + for (var i = 0; i < subfeatures.length; i++) { + this.renderSubfeature( feature, featDiv, + subfeatures[i], + displayStart, displayEnd, block ); + } + } + }, - return featDiv; + /** + * Get the height of a div. Caches div heights based on + * classname. + */ + _getHeight: function( theDiv ) { + if (this.config.disableHeightCache) { + return theDiv.offsetHeight || 0; + } + else { + var c = this.heightCache[ theDiv.className ]; + if( c ) + return c; + c = theDiv.offsetHeight || 0; + this.heightCache[ theDiv.className ] = c; + return c; + } }, /** * Vertically centers all the child elements of a feature div. * @private */ - _centerFeatureElements: function( /**HTMLElement*/ featDiv ) { - var getHeight = this.config.disableHeightCache - ? function(child) { return child.offsetHeight || 0; } - : function( child ) { - var c = this.heightCache[ child.className ]; - if( c ) - return c; - c = child.offsetHeight || 0; - this.heightCache[ child.className ] = c; - return c; - }; - - for( var i = 0; i< featDiv.childNodes.length; i++ ) { - var child = featDiv.childNodes[i]; - // cache the height of elements, for speed. - var h = getHeight.call(this,child); - dojo.style( child, { marginTop: '0', top: ((this.glyphHeight-h)/2) + 'px', visibility: 'visible' }); - } + _centerChildrenVertically: function( /**HTMLElement*/ featDiv ) { + if( featDiv.childNodes.length > 0 ) { + var parentHeight = this._getHeight(featDiv); + for( var i = 0; i< featDiv.childNodes.length; i++ ) { + var child = featDiv.childNodes[i]; + // cache the height of elements, for speed. + var h = this._getHeight(child); + dojo.style( child, { marginTop: '0', top: ((parentHeight-h)/2) + 'px' }); + // recursively center any descendants + if (child.childNodes.length > 0) { + this._centerChildrenVertically( child ); + } + } + } }, /** @@ -942,7 +1054,6 @@ HTMLFeatures = declare( HTMLFeatures, on( featDiv, 'mouseover', refreshMenu ); if( featDiv.labelDiv ) on( featDiv.labelDiv, 'mouseover', refreshMenu ); - dojo.connect( featDiv.contextMenu, 'onMouseMove', refreshMenu ); }, _refreshMenu: function( featDiv ) { @@ -987,44 +1098,69 @@ HTMLFeatures = declare( HTMLFeatures, return menu; }, - renderSubfeature: function(feature, featDiv, subfeature, displayStart, displayEnd) { + renderSubfeature: function( feature, featDiv, subfeature, displayStart, displayEnd, block ) { var subStart = subfeature.get('start'); var subEnd = subfeature.get('end'); var featLength = displayEnd - displayStart; - - var subDiv = document.createElement("div"); - var type = subfeature.get('type'); - subDiv.className = (this.config.style.subfeatureClasses||{})[type] || this.config.style.className + '-' + type; - switch ( subfeature.get('strand') ) { - case 1: - case '+': - subDiv.className += " plus-" + subDiv.className; break; - case -1: - case '-': - subDiv.className += " minus-" + subDiv.className; break; + var className; + if( this.config.style.subfeatureClasses ) { + className = this.config.style.subfeatureClasses[type]; + // if no class mapping specified for type, default to subfeature.get('type') + if (className === undefined) { className = type; } + // if subfeatureClasses specifies that subfeature type explicitly maps to null className + // then don't render the feature + else if (className === null) { + return null; + } + } + else { + // if no config.style.subfeatureClasses to specify subfeature class mapping, default to subfeature.get('type') + className = type; + } + var subDiv = document.createElement("div"); + dojo.addClass(subDiv, "subfeature"); + // check for className to avoid adding "null", "plus-null", "minus-null" + if (className) { + switch ( subfeature.get('strand') ) { + case 1: + case '+': + dojo.addClass(subDiv, "plus-" + className); break; + case -1: + case '-': + dojo.addClass(subDiv, "minus-" + className); break; + default: + dojo.addClass(subDiv, className); + } } // if the feature has been truncated to where it doesn't cover // this subfeature anymore, just skip this subfeature - if ((subEnd <= displayStart) || (subStart >= displayEnd)) return; + if ( subEnd <= displayStart || subStart >= displayEnd ) + return null; if (Util.is_ie6) subDiv.appendChild(document.createComment()); - // NOTE: subfeatures are hidden until they are centered by - // _centerFeatureElements, so that they don't jump around - // on the screen - subDiv.style.cssText = - "visibility: hidden; left: " + (100 * ((subStart - displayStart) / featLength)) + "%;" - + "top: 0px;" + subDiv.style.cssText = "left: " + (100 * ((subStart - displayStart) / featLength)) + "%;" + "width: " + (100 * ((subEnd - subStart) / featLength)) + "%;"; featDiv.appendChild(subDiv); + + block.featureNodes[ subfeature.id() ] = subDiv; + + return subDiv; }, _getLayout: function( scale ) { + + //determine the glyph height, arrowhead width, label text dimensions, etc. + if (!this.haveMeasurements) { + this.measureStyles(); + this.haveMeasurements = true; + } + // create the layout if we need to, and we can - if( ( ! this.layout || this.layout.pitchX != 4/scale ) && scale ) - this.layout = new Layout({pitchX: 4/scale, pitchY: this.layoutPitchY || this.config.layoutPitchY }); + if( ( ! this.layout || this.layout.pitchX != 4/scale ) && scale ) + this.layout = new Layout({pitchX: 4/scale, pitchY: this.config.layoutPitchY || (this.glyphHeight + this.glyphHeightPad) }); return this.layout; }, @@ -1032,15 +1168,18 @@ HTMLFeatures = declare( HTMLFeatures, delete this.layout; }, - // when all the blocks are hidden, we also should recalculate our - // layout + /** + * indicates a change to this track has happened that may require a re-layout + * clearing layout here, and relying on superclass BlockBased.changed() call and + * standard _changedCallback function passed in track constructor to trigger relayout + */ changed: function() { - this.inherited(arguments); this._clearLayout(); + this.inherited(arguments); }, _exportFormats: function() { - return [ 'GFF3', 'BED' ]; + return [ 'GFF3', 'BED', { name: 'SequinTable', label: 'Sequin Table' } ]; }, _trackMenuOptions: function() { diff --git a/src/JBrowse/View/Track/LocationScale.js b/src/JBrowse/View/Track/LocationScale.js index 8f78d23198..c655f85ff5 100644 --- a/src/JBrowse/View/Track/LocationScale.js +++ b/src/JBrowse/View/Track/LocationScale.js @@ -16,17 +16,18 @@ return declare(BlockBased, this.loaded = true; this.labelClass = args.labelClass; this.posHeight = args.posHeight; - this.height = args.posHeight; + this.height = Math.round( args.posHeight * 1.2 ); }, // this track has no track label or track menu, stub them out makeTrackLabel: function() {}, makeTrackMenu: function() {}, - fillBlock: function(blockIndex, block, - leftBlock, rightBlock, - leftBase, rightBase, scale, - padding, stripeWidth) { + fillBlock: function( args ) { + var blockIndex = args.blockIndex; + var block = args.block; + var leftBase = args.leftBase; + var posLabel = document.createElement("div"); var numtext = Util.addCommas( leftBase+1 ); posLabel.className = this.labelClass; @@ -37,7 +38,8 @@ return declare(BlockBased, posLabel.appendChild( document.createTextNode( numtext ) ); block.appendChild(posLabel); - this.heightUpdate(this.posHeight, blockIndex); + this.heightUpdate( Math.round( this.posHeight*1.2 ), blockIndex); + args.finishCallback(); } }); }); \ No newline at end of file diff --git a/src/JBrowse/View/Track/Sequence.js b/src/JBrowse/View/Track/Sequence.js index 96e53e011a..831c0d7c90 100644 --- a/src/JBrowse/View/Track/Sequence.js +++ b/src/JBrowse/View/Track/Sequence.js @@ -29,7 +29,10 @@ SequenceTrack.extend( */ { _defaultConfig: function() { - return { maxExportSpan: 500000 }; + return { + maxExportSpan: 500000, + showReverseStrand: true + }; }, _exportFormats: function() { return ['FASTA']; @@ -48,11 +51,12 @@ SequenceTrack.extend( nbsp: String.fromCharCode(160), - fillBlock:function(blockIndex, block, - leftBlock, rightBlock, - leftBase, rightBase, - scale, stripeWidth, - containerStart, containerEnd) { + fillBlock:function( args ) { + var blockIndex = args.blockIndex; + var block = args.block; + var leftBase = args.leftBase; + var rightBase = args.rightBase; + var scale = args.scale; var charSize = this.getCharacterMeasurements(); @@ -80,6 +84,8 @@ SequenceTrack.extend( }, block ); this.heightUpdate( blur.offsetHeight+2*blur.offsetTop, blockIndex ); } + + args.finishCallback(); }, _fillSequenceBlock: function( block, scale, feature ) { @@ -113,9 +119,11 @@ SequenceTrack.extend( seqNode.appendChild( this._renderSeqDiv( start, end, seq, scale )); // and one for the reverse strand - var comp = this._renderSeqDiv( start, end, Util.complement(seq), scale ); - comp.className = 'revcom'; - seqNode.appendChild( comp ); + if( this.config.showReverseStrand ) { + var comp = this._renderSeqDiv( start, end, Util.complement(seq), scale ); + comp.className = 'revcom'; + seqNode.appendChild( comp ); + } }, /** @@ -130,12 +138,16 @@ SequenceTrack.extend( var container = document.createElement('div'); var charWidth = 100/(end-start)+"%"; var drawChars = scale >= charSize.w; + var bigTiles = scale > charSize.w + 4; // whether to add .big styles to the base tiles for( var i=0; i'; + this.applyButton.set('disabled',true); + }, + _clearErrors: function() { + dom.empty( this.errorReportArea ); + this.applyButton.set('disabled',false); + }, + + _parseNewConfig: function( conf ) { + var newconf; + try { + newconf = JSON.parse( conf, true ); + this._clearErrors(); + } catch(e) { + this._reportError( e ); + } + if( newconf ) + newconf.store = this.trackConfig.store; + return newconf; + } + +}); +}); \ No newline at end of file diff --git a/src/JBrowse/View/TrackList/Faceted.js b/src/JBrowse/View/TrackList/Faceted.js index feeed2d01d..3c46899157 100644 --- a/src/JBrowse/View/TrackList/Faceted.js +++ b/src/JBrowse/View/TrackList/Faceted.js @@ -3,12 +3,12 @@ define( 'dojo/_base/declare', 'dojo/_base/array', 'dijit/layout/AccordionContainer', - 'dijit/layout/AccordionPane', + 'dijit/layout/ContentPane', 'JBrowse/Util', 'dojox/grid/EnhancedGrid', 'dojox/grid/enhanced/plugins/IndirectSelection' ], - function ( declare, dArray, AccordionContainer, AccordionPane, Util, EnhancedGrid ){ + function ( declare, dArray, AccordionContainer, ContentPane, Util, EnhancedGrid ){ var dojof = Util.dojof; return declare( 'JBrowse.View.TrackList.Faceted', null, @@ -60,6 +60,8 @@ return declare( 'JBrowse.View.TrackList.Faceted', null, // subscribe to commands coming from the the controller this.browser.subscribe( '/jbrowse/v1/c/tracks/hide', dojo.hitch( this, 'setTracksInactive' )); + this.browser.subscribe( '/jbrowse/v1/c/tracks/delete', + dojo.hitch( this, 'setTracksInactive' )); this.renderInitial(); @@ -89,10 +91,12 @@ return declare( 'JBrowse.View.TrackList.Faceted', null, }); }); }); + this.trackDataStore.onReady( this, '_updateFacetCounts' ); // just once at start dojo.connect( this.trackDataStore, 'onFetchSuccess', this, '_updateGridSelections' ); dojo.connect( this.trackDataStore, 'onFetchSuccess', this, '_updateMatchCount' ); + }, /** @@ -306,6 +310,13 @@ return declare( 'JBrowse.View.TrackList.Faceted', null, }, renderGrid: function() { + + var displayColumns = dojo.filter( + this.displayColumns || this.trackDataStore.getFacetNames(), + dojo.hitch(this, '_isDisplayableColumn') + ); + var colWidth = 90/displayColumns.length; + var grid = new EnhancedGrid({ id: 'trackSelectGrid', store: this.trackDataStore, @@ -314,13 +325,11 @@ return declare( 'JBrowse.View.TrackList.Faceted', null, noDataMessage: "No tracks match the filtering criteria.", structure: [ dojo.map( - dojo.filter( this.displayColumns || this.trackDataStore.getFacetNames(), - dojo.hitch(this, '_isDisplayableColumn') - ), + displayColumns, function(facetName) { // rename name to key to avoid configuration confusion facetName = {name: 'key'}[facetName.toLowerCase()] || facetName; - return {'name': this._facetDisplayName(facetName), 'field': facetName.toLowerCase(), 'width': '100px'}; + return {'name': this._facetDisplayName(facetName), 'field': facetName.toLowerCase(), 'width': colWidth+'%'}; }, this ) @@ -537,17 +546,17 @@ return declare( 'JBrowse.View.TrackList.Faceted', null, /** * Make HTML elements for a single facet selector. * @private - * @returns {dijit.layout.AccordionPane} + * @returns {dijit.layout.ContentPane} */ _renderFacetSelector: function( /**String*/ facetName, /**Array[String]*/ values ) { - var facetPane = new AccordionPane( + var facetPane = new ContentPane( { - title: '
' + this._facetDisplayName(facetName) + ' ' - + '
' + + '' }); // make a selection control for the values of this facet @@ -782,9 +791,11 @@ return declare( 'JBrowse.View.TrackList.Faceted', null, // internal memory of what tracks should be on. for( var i= 0; i < Math.min( this.dataGrid.get('rowCount'), this.dataGrid.get('rowsPerPage') ); i++ ) { var item = this.dataGrid.getItem( i ); - var label = this.dataGrid.store.getIdentity( item ); - if( this.tracksActive[label] ) - this.dataGrid.rowSelectCell.toggleRow( i, true ); + if( item ) { + var label = this.dataGrid.store.getIdentity( item ); + if( this.tracksActive[label] ) + this.dataGrid.rowSelectCell.toggleRow( i, true ); + } } }); @@ -799,6 +810,7 @@ return declare( 'JBrowse.View.TrackList.Faceted', null, dojo.forEach( trackConfigs, function(conf) { this.tracksActive[conf.label] = true; },this); + this._updateGridSelections(); }, /** @@ -809,6 +821,7 @@ return declare( 'JBrowse.View.TrackList.Faceted', null, dojo.forEach( trackConfigs, function(conf) { delete this.tracksActive[conf.label]; },this); + this._updateGridSelections(); }, /** diff --git a/src/JBrowse/View/TrackList/Simple.js b/src/JBrowse/View/TrackList/Simple.js index 41a58931ba..12c75ca8c7 100644 --- a/src/JBrowse/View/TrackList/Simple.js +++ b/src/JBrowse/View/TrackList/Simple.js @@ -1,9 +1,10 @@ define(['dojo/_base/declare', + 'dojo/_base/array', 'dijit/layout/ContentPane', 'dojo/dnd/Source', 'dojo/fx/easing' ], - function( declare, ContentPane, dndSource, animationEasing ) { + function( declare, array, ContentPane, dndSource, animationEasing ) { return declare( 'JBrowse.View.TrackList.Simple', null, /** @lends JBrowse.View.TrackList.Simple.prototype */ @@ -61,10 +62,42 @@ return declare( 'JBrowse.View.TrackList.Simple', null, // subscribe to commands coming from the the controller this.browser.subscribe( '/jbrowse/v1/c/tracks/show', dojo.hitch( this, 'setTracksActive' )); - - // subscribe to commands coming from the the controller this.browser.subscribe( '/jbrowse/v1/c/tracks/hide', dojo.hitch( this, 'setTracksInactive' )); + this.browser.subscribe( '/jbrowse/v1/c/tracks/new', + dojo.hitch( this, 'addTracks' )); + this.browser.subscribe( '/jbrowse/v1/c/tracks/replace', + dojo.hitch( this, 'replaceTracks' )); + this.browser.subscribe( '/jbrowse/v1/c/tracks/delete', + dojo.hitch( this, 'deleteTracks' )); + }, + + addTracks: function( trackConfigs ) { + // note that new tracks are, by default, hidden, so we just put them in the list + this.trackListWidget.insertNodes( + false, + trackConfigs + ); + + this._blinkTracks( trackConfigs ); + }, + + replaceTracks: function( trackConfigs ) { + // for each one + array.forEach( trackConfigs, function( conf ) { + // figure out its position in the genome view and delete it + var oldNode = this.inactiveTrackNodes[ conf.label ]; + if( ! oldNode ) + return; + delete this.inactiveTrackNodes[ conf.label ]; + + this.trackDndWidget.delItem( oldNode.id ); + if( oldNode.parentNode ) + oldNode.parentNode.removeChild( oldNode ); + + // insert the new track config into the trackDndWidget after the 'before' + this.trackListWidget.insertNodes( false, [conf], false, oldNode.previousSibling ); + },this); }, /** @private */ @@ -101,7 +134,7 @@ return declare( 'JBrowse.View.TrackList.Simple', null, 'div', { className: 'tracklist-label', title: 'drag or double-click to activate', - innerHTML: trackConfig.key + innerHTML: trackConfig.key || trackConfig.name || trackConfig.label } ); //in the list, wrap the list item in a container for @@ -126,24 +159,25 @@ return declare( 'JBrowse.View.TrackList.Simple', null, /** * Given an array of track configs, update the track list to show - * that they are turned on. + * that they are turned on. For this list, that just means + * deleting them from our widget. */ setTracksActive: function( /**Array[Object]*/ trackConfigs ) { - // remove any tracks in our track list that are being set as visible - dojo.forEach( trackConfigs || [], function( conf ) { - this.trackListWidget.forInItems(function(obj, id, map) { - if( conf.label === obj.data.label ) { - - this.trackListWidget.delItem( id ); + this.deleteTracks( trackConfigs ); + }, - var item = dojo.byId(id); - if( item && item.parentNode ) - item.parentNode.removeChild(item); + deleteTracks: function( /**Array[Object]*/ trackConfigs ) { + // remove any tracks in our track list that are being set as visible + array.forEach( trackConfigs || [], function( conf ) { + var oldNode = this.inactiveTrackNodes[ conf.label ]; + if( ! oldNode ) + return; + delete this.inactiveTrackNodes[ conf.label ]; - delete this.inactiveTrackNodes[ conf.label ]; + if( oldNode.parentNode ) + oldNode.parentNode.removeChild( oldNode ); - } - },this); + this.trackListWidget.delItem( oldNode.id ); },this); }, @@ -157,29 +191,35 @@ return declare( 'JBrowse.View.TrackList.Simple', null, if( ! this.dndDrop ) { var n = this.trackListWidget.insertNodes( false, trackConfigs ); - // scroll the tracklist all the way to the bottom so we can see the blinking nodes - n.node.scrollTop = n.node.scrollHeight; - // blink the track(s) that we just turned off to make it // easier for users to tell where they went. // note that insertNodes will have put its html element in // inactivetracknodes - dojo.forEach( trackConfigs, function(c) { + this._blinkTracks( trackConfigs ); + } + }, + + _blinkTracks: function( trackConfigs ) { + // scroll the tracklist all the way to the bottom so we can see the blinking nodes + this.trackListWidget.node.scrollTop = this.trackListWidget.node.scrollHeight; + + array.forEach( trackConfigs, function(c) { var label = this.inactiveTrackNodes[c.label].firstChild; - dojo.animateProperty({ - node: label, - duration: 400, - properties: { - backgroundColor: { start: '#DEDEDE', end: '#FFDE2B' } - }, - easing: animationEasing.sine, - repeat: 2, - onEnd: function() { - label.style.backgroundColor = null; - } - }).play(); + if( label ) { + dojo.animateProperty({ + node: label, + duration: 400, + properties: { + backgroundColor: { start: '#DEDEDE', end: '#FFDE2B' } + }, + easing: animationEasing.sine, + repeat: 2, + onEnd: function() { + label.style.backgroundColor = null; + } + }).play(); + } },this); - } }, /** diff --git a/src/dgrid b/src/dgrid new file mode 160000 index 0000000000..7790123296 --- /dev/null +++ b/src/dgrid @@ -0,0 +1 @@ +Subproject commit 77901232965572a7e955ee17168751be9e19fb1d diff --git a/src/jszlib b/src/jszlib index fb8037c428..450d8f1ff6 160000 --- a/src/jszlib +++ b/src/jszlib @@ -1 +1 @@ -Subproject commit fb8037c4285bcba79ce5d27628641fb03397a89a +Subproject commit 450d8f1ff648928959ac909a98f0836932ed33be diff --git a/src/lazyload b/src/lazyload new file mode 160000 index 0000000000..d428749c54 --- /dev/null +++ b/src/lazyload @@ -0,0 +1 @@ +Subproject commit d428749c5400213340d65d6156f43224ee477586 diff --git a/src/perl5/Bio/JBrowse/Cmd/FlatFileToJson.pm b/src/perl5/Bio/JBrowse/Cmd/FlatFileToJson.pm index 53aa05997e..f5c0c24eaa 100644 --- a/src/perl5/Bio/JBrowse/Cmd/FlatFileToJson.pm +++ b/src/perl5/Bio/JBrowse/Cmd/FlatFileToJson.pm @@ -207,7 +207,7 @@ sub _find_passing_features { # if this feature passes, we're done, just return it ? ( $feature ) # otherwise, look for passing features in its subfeatures - : _find_passing_features( $pass_feature, @{$feature->{child_features}} ); + : _find_passing_features( $pass_feature, @{$feature->{subfeatures}} ); } @_; } diff --git a/src/perl5/Bio/JBrowse/Cmd/FormatSequences.pm b/src/perl5/Bio/JBrowse/Cmd/FormatSequences.pm index 1eef4d6b29..3cf75b96b6 100644 --- a/src/perl5/Bio/JBrowse/Cmd/FormatSequences.pm +++ b/src/perl5/Bio/JBrowse/Cmd/FormatSequences.pm @@ -197,10 +197,8 @@ sub run { $old->[$i] = delete $refs{$old->[$i]->{name}}; } } - foreach my $newRef (values %refSeqs) { - if( $refs{$newRef->{name}} ) { - push @{$old}, $newRef; - } + foreach my $name (sort keys %refs) { + push @{$old}, $refs{$name}; } return $old; }); diff --git a/src/perl5/Bio/JBrowse/Cmd/NCFormatter.pm b/src/perl5/Bio/JBrowse/Cmd/NCFormatter.pm index a15b6101a3..7cf33ce8b5 100644 --- a/src/perl5/Bio/JBrowse/Cmd/NCFormatter.pm +++ b/src/perl5/Bio/JBrowse/Cmd/NCFormatter.pm @@ -3,7 +3,7 @@ package Bio::JBrowse::Cmd::NCFormatter; use base 'Bio::JBrowse::Cmd'; use GenomeDB; -use ExternalSorter; +use Bio::JBrowse::ExternalSorter; sub _format { my ( $self, %args ) = @_; @@ -13,9 +13,9 @@ sub _format { my $types = $self->opt('type'); @$types = split /,/, join ',', @$types; - # The ExternalSorter will get flattened [chrom, [start, end, ...]] + # The Bio::JBrowse::ExternalSorter will get flattened [chrom, [start, end, ...]] # arrays from the feature_stream - my $sorter = ExternalSorter->new( + my $sorter = Bio::JBrowse::ExternalSorter->new( do { my $startIndex = $feature_stream->startIndex; my $endIndex = $feature_stream->endIndex; @@ -37,6 +37,8 @@ sub _format { my $chrom = $feat->{seq_id}; $featureCounts{$chrom} += 1; + $feat = $self->transform_feature( $feat ); + my $row = [ $chrom, $feature_stream->flatten_to_feature( $feat ), $feature_stream->flatten_to_name( $feat ), @@ -86,4 +88,9 @@ sub _format { } } +# stub +sub transform_feature { + return $_[1]; +} + 1; diff --git a/src/perl5/ExternalSorter.pm b/src/perl5/Bio/JBrowse/ExternalSorter.pm similarity index 89% rename from src/perl5/ExternalSorter.pm rename to src/perl5/Bio/JBrowse/ExternalSorter.pm index 457884514c..8b710ed113 100644 --- a/src/perl5/ExternalSorter.pm +++ b/src/perl5/Bio/JBrowse/ExternalSorter.pm @@ -1,11 +1,11 @@ =head1 NAME -ExternalSorter - efficiently sort arrayrefs with a given comparison function +Bio::JBrowse::ExternalSorter - efficiently sort arrayrefs with a given comparison function =head1 SYNOPSIS # make a new sorter that sorts by column 4, then column 3 - my $sorter = ExternalSorter->new( + my $sorter = Bio::JBrowse::ExternalSorter->new( sub ($$) { $_[0]->[4] <=> $_[1]->[4] || @@ -29,7 +29,7 @@ ExternalSorter - efficiently sort arrayrefs with a given comparison function =cut -package ExternalSorter; +package Bio::JBrowse::ExternalSorter; use strict; use warnings; @@ -128,12 +128,12 @@ sub flush { # each segment must have at least one element return if ($#sorted < 0); - croak "ExternalSorter is already finished" + croak "Bio::JBrowse::ExternalSorter is already finished" if $self->{finished}; - my $fh = File::Temp->new($self->{tmpDir} ? (DIR => $self->{tmpDir}) : (), - UNLINK => 0, - TEMPLATE => 'sort-XXXXXXXXXX') + my $fh = File::Temp->new( $self->{tmpDir} ? (DIR => $self->{tmpDir}) : (), + SUFFIX => '.sort', + UNLINK => 0 ) or croak "couldn't open temp file: $!\n"; my $fn = $fh->filename; $fh->close() @@ -187,4 +187,8 @@ sub readOne { return $item; } +sub DESTROY { + unlink $_ for @{shift->{segments}||[]} +} + 1; diff --git a/src/perl5/Bio/JBrowse/FeatureStream.pm b/src/perl5/Bio/JBrowse/FeatureStream.pm index 63b2d5daf5..0e9c3effd6 100644 --- a/src/perl5/Bio/JBrowse/FeatureStream.pm +++ b/src/perl5/Bio/JBrowse/FeatureStream.pm @@ -9,7 +9,7 @@ package Bio::JBrowse::FeatureStream; use strict; use warnings; -use Digest::MurmurHash (); +use List::MoreUtils 'uniq'; sub new { my $class = shift; @@ -24,16 +24,24 @@ sub new { sub flatten_to_feature { my ( $self, $f ) = @_; - my $subfeatures = [ map $self->flatten_to_feature($_), @{$f->{child_features}} ]; - my $class = $self->_get_class( $f ); my @f = ( $class->{index}, - @{$f}{ $self->_fixed_fields }, - (map $f->{attributes}{$_}[0], @{$class->{variable_fields}}), - $subfeatures + @{$f}{ @{$class->{fields}} } ); + for my $subfeature_field (qw( subfeatures derived_features )) { + if( my $sfi = $class->{field_idx}{ $subfeature_field } ) { + $f[ $sfi+1 ] = [ + map { + $self->flatten_to_feature($_) + } @{$f[$sfi+1]} + ]; + } + } + # use Data::Dump 'dump'; + # print dump($_)."\n" for \@f, $class; + # convert start to interbase and numify it $f[1] -= 1; # numify end @@ -45,43 +53,45 @@ sub flatten_to_feature { return \@f; } -sub _fixed_fields { - return qw{ start end strand source phase type score }; -} - +my %skip_field = map { $_ => 1 } qw( start end strand ); sub _get_class { my ( $self, $f ) = @_; - my @attrs = keys %{$f->{attributes}}; - my $attr_fingerprint = Digest::MurmurHash::murmur_hash( join '-', @attrs ); - - return $self->{classes}{$attr_fingerprint} ||= { - index => $self->{class_count}++, # the classes start from 1. so what. - fields => [ $self->_fixed_fields, @attrs], - fixed_fields => [ $self->_fixed_fields ], - variable_fields => \@attrs, + my @attrs = keys %$f; + my $attr_fingerprint = join '-', @attrs; + + return $self->{classes}{$attr_fingerprint} ||= do { + my @fields = ( 'start', 'end', 'strand', ( grep !$skip_field{$_}, @attrs ) ); + my $i = 0; + { + index => $self->{class_count}++, # the classes start from 1. so what. + fields => \@fields, + field_idx => { map { $_ => $i++ } @fields }, + # assumes that if a field is an array for one feature, it will be for all of them + array_fields => [ grep ref($f->{$_}) eq 'ARRAY', @attrs ] + } }; } sub flatten_to_name { my ( $self, $f ) = @_; + my @nameattrs = grep /^(name|id|alias)\d*$/, keys %$f; my @namerec = ( - [ grep defined, @{ $f->{attributes}{Name} || $f->{attributes}{ID} || [] }, @{$f->{attributes}{Alias}} ], + [ grep defined, @{$f}{@nameattrs} ], $self->{track_label}, - $f->{attributes}{Name}[0], - $f->{seq_id}, - (map $_+0, @{$f}{'start','end'}), - $f->{attributes}{ID}[0], + $f->{name} || $f->{id} || $f->{alias}, + $f->{seq_id} || die, + (map $_+0, @{$f}{'start','end'}) ); - $namerec[4]--; #< to one-based + $namerec[4]--; #< to zero-based return \@namerec; } sub arrayReprClasses { my ( $self ) = @_; return [ map { - attributes => [ map ucfirst, @{$_->{fields}}, 'Subfeatures' ], - isArrayAttr => { Subfeatures => 1 } + attributes => [ map ucfirst, @{$_->{fields}} ], + isArrayAttr => { map { ucfirst($_) => 1 } @{$_->{array_fields}} }, }, sort { $a->{index} <=> $b->{index} } values %{ $self->{classes} } @@ -91,4 +101,21 @@ sub arrayReprClasses { sub startIndex { 1 } sub endIndex { 2 } + +# given a hashref like { tagname => [ value1, value2 ], ... } +# flatten it to numbered tagnames like { tagname => value1, tagname2 => value2 } +sub _flatten_multivalues { + my ( $self, $h ) = @_; + my %flattened; + + for my $key ( keys %$h ) { + my $v = $h->{$key}; + for( my $i = 0; $i < @$v; $i++ ) { + $flattened{ $key.($i ? $i+1 : '')} = $v->[$i]; + } + } + + return \%flattened; +} + 1; diff --git a/src/perl5/Bio/JBrowse/FeatureStream/BioPerl.pm b/src/perl5/Bio/JBrowse/FeatureStream/BioPerl.pm index 530a9d81d6..2d8a6698a6 100644 --- a/src/perl5/Bio/JBrowse/FeatureStream/BioPerl.pm +++ b/src/perl5/Bio/JBrowse/FeatureStream/BioPerl.pm @@ -10,6 +10,8 @@ use strict; use warnings; use base 'Bio::JBrowse::FeatureStream'; +use List::MoreUtils 'uniq'; + sub next_items { my ( $self ) = @_; return map $self->_bp_to_hashref( $_ ), @@ -22,7 +24,7 @@ sub _bp_to_hashref { no warnings 'uninitialized'; my %h; - @h{qw{ seq_id start end strand source phase type child_features }} = + @h{qw{ seq_id start end strand source phase type }} = ( $f->seq_id, $f->start, $f->end, @@ -30,22 +32,41 @@ sub _bp_to_hashref { $f->source_tag, {0=>0,1=>1,2=>2}->{$f->phase}, $f->primary_tag || undef, - [ map $self->_bp_to_hashref($_), $f->get_SeqFeatures ], ); for(qw( seq_id start end strand source type )) { - $h{$_} = undef if $h{$_} eq '.'; + if( $h{$_} eq '.' ) { + delete $h{$_}; + } + } + for ( keys %h ) { + if( ! defined $h{$_} ) { + delete $h{$_}; + } else { + $h{$_} = [ $h{$_} ]; + } + } + my @subfeatures = $f->get_SeqFeatures; + if( @subfeatures ) { + $h{subfeatures} = [[ map $self->_bp_to_hashref($_), @subfeatures ]]; + } + + for my $tag ( $f->get_all_tags ) { + my $lctag = lc $tag; + push @{ $h{ $lctag } ||= [] }, $f->get_tag_values($tag); + } + + for ( keys %h ) { + $h{$_} = [ uniq grep { defined && ($_ ne '.') } @{$h{$_}} ]; + unless( @{$h{$_}} ) { + delete $h{$_}; + } } - $h{attributes} = { - map { - my $t = $_; - $t => [ grep $_ ne '.', $f->get_tag_values($t) ] - } $f->get_all_tags - }; - if( ! $h{attributes}{Name} and defined( my $label = $self->_label( $f ) )) { - $h{attributes}{Name} = [ $label ]; + if( ! $h{name} and defined( my $label = $self->_label( $f ) )) { + $h{name} = [ $label ]; } - return \%h; + + return $self->_flatten_multivalues( \%h ); }; sub _label { diff --git a/src/perl5/Bio/JBrowse/FeatureStream/GFF3_LowLevel.pm b/src/perl5/Bio/JBrowse/FeatureStream/GFF3_LowLevel.pm index 44978f9b98..536c8af8c0 100644 --- a/src/perl5/Bio/JBrowse/FeatureStream/GFF3_LowLevel.pm +++ b/src/perl5/Bio/JBrowse/FeatureStream/GFF3_LowLevel.pm @@ -12,10 +12,57 @@ use warnings; use base 'Bio::JBrowse::FeatureStream'; sub next_items { - while ( my $i = $_[0]->{parser}->next_item ) { - return $i if $i->{child_features}; + my ( $self ) = @_; + while ( my $i = $self->{parser}->next_item ) { + return $self->_to_hashref( $i ) if $i->{child_features}; } return; } +sub _to_hashref { + my ( $self, $f ) = @_; + # use Data::Dump 'dump'; + # if( ref $f ne 'HASH' ) { + # Carp::confess( dump $f ); + # } + $f = { %$f }; + my $a = delete $f->{attributes}; + my %h; + for my $key ( keys %$f) { + my $lck = lc $key; + my $v = $f->{$key}; + if( defined $v && ( ref($v) ne 'ARRAY' || @$v ) ) { + unshift @{ $h{ $lck } ||= [] }, $v; + } + } + # rename child_features to subfeatures + if( $h{child_features} ) { + $h{subfeatures} = [ + map { + [ map $self->_to_hashref( $_ ), @$_ ] + } @{delete $h{child_features}} + ]; + } + if( $h{derived_features} ) { + $h{derived_features} = [ + map { + [ map $self->_to_hashref( $_ ), @$_ ] + } @{$h{derived_features}} + ]; + } + + my %skip_attributes = ( Parent => 1 ); + for my $key ( sort keys %{ $a || {} } ) { + my $lck = lc $key; + if( !$skip_attributes{$key} ) { + push @{ $h{$lck} ||= [] }, @{$a->{$key}}; + } + } + + my $flat = $self->_flatten_multivalues( \%h ); + return $flat; +} + + + 1; diff --git a/src/perl5/Bio/JBrowse/HashStore.pm b/src/perl5/Bio/JBrowse/HashStore.pm new file mode 100644 index 0000000000..038b0da097 --- /dev/null +++ b/src/perl5/Bio/JBrowse/HashStore.pm @@ -0,0 +1,288 @@ +=head1 NAME + +Bio::JBrowse::HashStore - on-disk 2-level hash table + +=head1 DESCRIPTION + +Makes an on-disk hash table, designed to be easily read as static files over HTTP. + +Makes a set of JSON-encoded files at paths based on a hash of the key. +For example: + + path/to/dir/29c/c14/fc.json + path/to/dir/23f/5ad/11.json + path/to/dir/711/7c1/29.json + path/to/dir/5ec/b24/6a.json + path/to/dir/4de/9ac/c6.json + path/to/dir/41b/c43/27.json + path/to/dir/28c/d86/e9.json + +Where each file contains a JSON object containing data items like: + + { foo: "bar", ... } + +Where "foo" is the original key, and "bar" is the JSON-encoded data. + +=cut + +package Bio::JBrowse::HashStore; +use strict; +use warnings; + +use JSON 2; + +use File::Spec (); +use File::Path (); + +use Cache::Ref::FIFO (); + +use Bio::JBrowse::ExternalSorter; + +my $bucket_class = 'Bio::JBrowse::HashStore::Bucket'; + + +=head2 open( dir => "/path/to/dir", hash_bits => 16 ) + +=cut + +sub open { + my $class = shift; + + # source of data: defaults, overridden by open args, overridden by meta.json contents + my $self = bless { @_ }, $class; + + $self->empty if $self->{empty}; + + %$self = ( + %$self, + meta => $self->_read_meta + ); + + $self->{hash_bits} ||= $self->{meta}{hash_bits} || 16; + $self->{meta}{hash_bits} = $self->{hash_bits}; + $self->{hash_characters} = int( $self->{hash_bits}/4 ); + $self->{file_extension} = '.json'; + + $self->{bucket_cache} = Cache::Ref::FIFO->new( size => 2000 ); + $self->{bucket_path_cache_by_key} = Cache::Ref::FIFO->new( size => 200_000 ); + $self->{bucket_path_cache_by_hash} = Cache::Ref::FIFO->new( size => 200_000 ); + + return bless $self, $class; +} + +# write out meta.json file when the store itself is destroyed +sub DESTROY { + my ( $self ) = @_; + File::Path::mkpath( $self->{dir} ); + my $meta_path = $self->_meta_path; + CORE::open my $out, '>', $meta_path or die "$! writing $meta_path"; + $out->print( JSON::to_json( $self->{meta} ) ) + or die "$! writing $meta_path"; +} +sub _meta_path { + File::Spec->catfile( shift->{dir}, 'meta.json' ); +} +sub _read_meta { + my ( $self ) = @_; + my $meta_path = $self->_meta_path; + return {} unless -r $meta_path; + CORE::open my $meta, '<', $meta_path or die "$! reading $meta_path"; + local $/; + my $d = eval { JSON::from_json( scalar <$meta> ) }; + warn $@ if $@; + return $d || {}; +} + +=head2 get( $key ) + +=cut + +sub get { + my ( $self, $key ) = @_; + my $bucket = $self->_getBucket( $key ); + return $bucket->{data}{$key}; +} + + +=head2 set( $key, $value ) + +=cut + +sub set { + my ( $self, $key, $value ) = @_; + + my $bucket = $self->_getBucket( $key ); + $bucket->{data}{$key} = $value; + $bucket->{dirty} = 1; + $self->{meta}{last_changed_entry} = $key; + + return $value; +} + +=head2 sort_stream( $data_stream ) + +Given a data stream (sub that returns arrayrefs of [ key, (any amount +of other data) ] when called repeatedly), returns another stream that +emits small objects that can be used to get and set the contents of +the name store at that key ( $entry->get and $entry->set( $value ) ) +and will return the original data you passed if you call $entry->data. + +Using this can greatly speed up bulk operations on the hash store, +because it allows the internal caches of the HashStore to operate at +maximum efficiency. + +This is achieved by doing an external sort of the data items, which +involves writing all of the data items to temporary files and then +reading them back in sorted order. + +=cut + +sub sort_stream { + my ( $self, $in_stream ) = @_; + + my $sorter = Bio::JBrowse::ExternalSorter->new( + sub ($$) { + $_[0]->[0] cmp $_[1]->[0] + }, 32_000_000 ); + + while( my $data = $in_stream->() ) { + # hash each of the keys and values, spool them to a single log file + $sorter->add( [ $self->_hexHash( $data->[0] ), $data ] ); + } + $sorter->finish; + + return sub { + my $d = $sorter->get or return; + return Bio::JBrowse::HashStore::Entry->new( + store => $self, + key => $d->[1][0], + data => $d->[1], + hex_hash => $d->[0] + ); + }; +} + +=head2 empty + +Clear the store of all contents. Deletes all files and directories +from the store directory. + +=cut + +sub empty { + my ( $self ) = @_; + File::Path::rmtree( $self->{dir} ); + File::Path::mkpath( $self->{dir} ); +} + +########## helper methods ########### + +sub _hexHash { + my ( $self, $key ) = @_; + my $crc = ( $self->{crc} ||= do { require Digest::Crc32; Digest::Crc32->new } ) + ->strcrc32( $key ); + my $hex = lc sprintf( '%08x', $crc ); + $hex = substr( $hex, 8-$self->{hash_characters} ); + return $hex; +} + +sub _hexToPath { + my ( $self, $hex ) = @_; + my @dir = ( $self->{dir}, reverse $hex =~ /(.{1,3})/g ); + my $file = (pop @dir).$self->{file_extension}; + my $dir = File::Spec->catdir(@dir); + return { dir => $dir, fullpath => File::Spec->catfile( $dir, $file ) }; +} + +sub _getBucket { + my ( $self, $key ) = @_; + my $pathinfo = $self->{bucket_path_cache_by_key}->compute( $key, sub { $self->_hexToPath( $self->_hexHash( $key ) ); } ); + return $self->{bucket_cache}->compute( $pathinfo->{fullpath}, sub { $self->_readBucket( $pathinfo ); } ); +} + +sub _readBucket { + my ( $self, $pathinfo ) = @_; + + my $path = $pathinfo->{fullpath}; + my $dir = $pathinfo->{dir}; + + if( -f $path ) { + local $/; + CORE::open my $in, '<', $path or die "$! reading $path"; + return $bucket_class->new( + dir => $dir, + fullpath => $path, + data => eval { JSON::from_json( scalar <$in> ) } || {} + ); + } + else { + return $bucket_class->new( + dir => $dir, + fullpath => $path, + data => {}, + dirty => 1 + ); + } +} + + +######## inner class for on-disk hash buckets ########## + +package Bio::JBrowse::HashStore::Bucket; + +sub new { + my $class = shift; + bless { @_ }, $class; +} + +# when a bucket is deleted, flush it to disk +sub DESTROY { + my ( $self ) = @_; + + return unless $self->{dirty} && %{$self->{data}}; + + File::Path::mkpath( $self->{dir} ); + CORE::open my $out, '>', $self->{fullpath} or die "$! writing $self->{fullpath}"; + $out->print( JSON::to_json( $self->{data} ) ) or die "$! writing to $self->{fullpath}"; +} + +package Bio::JBrowse::HashStore::Entry; + +sub new { + my $class = shift; + bless { @_ }, $class; +} + +sub get { + my ( $self ) = @_; + my $bucket = $self->_getBucket; + return $bucket->{data}{ $self->{key} }; +} + +sub set { + my ( $self, $value ) = @_; + + my $bucket = $self->_getBucket; + $bucket->{data}{ $self->{key} } = $value; + $bucket->{dirty} = 1; + $self->{store}{meta}{last_changed_entry} = $self->{key}; + + return $value; +} + +sub data { + $_[0]->{data}; +} + +sub store { + $_[0]->{store}; +} + +sub _getBucket { + my ( $self ) = @_; + my $store = $self->{store}; + my $pathinfo = $store->{bucket_path_cache_by_hash}->compute( $self->{hex_hash}, sub { $store->_hexToPath( $self->{hex_hash} ); } ); + return $store->{bucket_cache}->compute( $pathinfo->{fullpath}, sub { $store->_readBucket( $pathinfo ); } ); +} + +1; diff --git a/src/perl5/GenomeDB.pm b/src/perl5/GenomeDB.pm index e26fb01830..0916e880b1 100644 --- a/src/perl5/GenomeDB.pm +++ b/src/perl5/GenomeDB.pm @@ -109,9 +109,21 @@ sub writeTrackEntry { return $trackData; }; - $self->{rootStore}->modify($trackListPath, $setTrackEntry); + $self->modifyTrackList( $setTrackEntry ); } +=head2 modifyTrackList( sub {} ) + +Modify the trackList.json file with the given subroutine. + +=cut + +sub modifyTrackList { + my ( $self, $sub ) = @_; + $self->{rootStore}->modify($trackListPath, $sub); +} + + =head2 createFeatureTrack( $label, \%config, $key, $jsclass ) Create a new FeatureTrack object in this data dir with the given diff --git a/src/perl5/JBlibs.pm b/src/perl5/JBlibs.pm index 85b41ab2c5..02d1b977c4 100644 --- a/src/perl5/JBlibs.pm +++ b/src/perl5/JBlibs.pm @@ -15,11 +15,18 @@ for my $d ( $dir, catdir( $dir, updir() ), catdir( $dir, updir(), updir() )) { $extlib = catfile( $d, 'extlib' ); last if -e $extlib; } + +require lib; + if( -e $extlib ) { - require lib; lib->import( 'extlib/lib/perl5' ); require local::lib; local::lib->import( $extlib ); } +# add all plugin dirs to the lib path also +for my $pluginLib ( glob 'plugins/*/perl5' ) { + lib->import( $pluginLib ); +} + 1; diff --git a/src/perl5/NameHandler.pm b/src/perl5/NameHandler.pm index ebd15cb0c5..a3ab51529e 100644 --- a/src/perl5/NameHandler.pm +++ b/src/perl5/NameHandler.pm @@ -1,6 +1,6 @@ =head1 NAME -NameHandler - create JSON indices of feature names +NameHandler - create indices of feature names =head1 SYNOPSIS @@ -36,7 +36,7 @@ use JSON 2; # TODO: find a central place to put this knowledge our $chromIndex = 3; -my $nameFile = "names.json"; +my $nameFile = "names.txt"; =head1 new( \&directory_callback ) @@ -73,15 +73,8 @@ sub addName { carp "chrom not defined in " . JSON::to_json($nameArr) . "\n"; } - my $nameFile = $self->{nameFiles}->{$chrom}; - if ( defined $nameFile ) { - $nameFile->print(","); - } else { - $self->{nameFiles}->{$chrom} = - $nameFile = $self->_newChrom($chrom); - } - - $nameFile->print( JSON::to_json($nameArr, {pretty => 0}) ) + my $nameFile = $self->{nameFiles}->{$chrom} ||= $self->_newChrom($chrom); + $nameFile->print( JSON::to_json( $nameArr, {pretty => 0} ), "\n" ) or die "couldn't write to file for $chrom: $!"; } @@ -98,7 +91,6 @@ sub _newChrom { my $namefile = "$chromDir/$nameFile"; my $fh = IO::File->new( $namefile, '>' ) or die "$! writing $namefile"; - $fh->print( "[" ); return $fh; } @@ -113,7 +105,6 @@ sub finish { foreach my $chrom (keys %{$self->{nameFiles}}) { my $fh = $self->{nameFiles}->{$chrom}; if( $fh && $fh->opened ) { - $fh->print("]"); $fh->close or die "$! closing names file for ref seq $chrom"; } } diff --git a/src/put-selector b/src/put-selector new file mode 160000 index 0000000000..f64ede2230 --- /dev/null +++ b/src/put-selector @@ -0,0 +1 @@ +Subproject commit f64ede2230f913c0ca224dce03106c1edc0ec542 diff --git a/src/xstyle b/src/xstyle new file mode 160000 index 0000000000..5c457b479d --- /dev/null +++ b/src/xstyle @@ -0,0 +1 @@ +Subproject commit 5c457b479db2cfd05d8a16a2f092ff82c4a7add6 diff --git a/tests/data/foo.bed b/tests/data/foo.bed new file mode 100644 index 0000000000..ac5e671cdb --- /dev/null +++ b/tests/data/foo.bed @@ -0,0 +1,20 @@ +chr10 102746607 102747330 chr10_100010101 1 + +chr10 102756707 102757063 chr10_100020212 1 + +chr10 102757103 102757628 chr10_100020608 1 + +chr10 102758816 102759393 chr10_100022332 1 + +chr10 102759402 102759798 chr10_100023087 1 + +chr10 102763502 102763900 chr10_100027151 1 + +chr10 102778574 102779028 chr10_100042744 1 + +chr10 102790835 102791548 chr10_100059467 1 + +chr10 102807700 102808458 chr10_100076094 1 + +chr10 102809834 102810339 chr10_100078435 1 + +chr10 102820652 102821466 chr10_100089212 1 + +chr10 102821565 102821902 chr10_100090127 1 + +chr10 102822305 102822874 chr10_100090866 1 + +chr10 102825930 102826474 chr10_100094501 1 + +chr10 102826938 102827286 chr10_100095501 1 + +chr10 102827366 102827778 chr10_100095928 1 + +chr10 102883063 102883551 chr10_100154436 1 + +chr10 102891173 102891794 chr10_100162617 1 + +chr10 102893599 102894301 chr10_100165069 1 + +chr10 102905801 102906693 chr10_100177356 1 + diff --git a/tests/data/hg19_formatted/tracks/knownGene/chr1/names.json b/tests/data/hg19_formatted/tracks/knownGene/chr1/names.json deleted file mode 100644 index 44b465656a..0000000000 --- a/tests/data/hg19_formatted/tracks/knownGene/chr1/names.json +++ /dev/null @@ -1 +0,0 @@ -[[["uc001aaa.3"],"knownGene","uc001aaa.3","chr1",11873,14409],[["uc010nxq.1"],"knownGene","uc010nxq.1","chr1",11873,14409],[["uc010nxr.1"],"knownGene","uc010nxr.1","chr1",11873,14409],[["uc001aah.3"],"knownGene","uc001aah.3","chr1",14362,29370],[["uc009vir.2"],"knownGene","uc009vir.2","chr1",14362,29370],[["uc009viq.2"],"knownGene","uc009viq.2","chr1",14362,29370],[["uc001aac.3"],"knownGene","uc001aac.3","chr1",14362,29370],[["uc001aab.3"],"knownGene","uc001aab.3","chr1",14362,24901],[["uc009vit.2"],"knownGene","uc009vit.2","chr1",14362,19759],[["uc001aae.3"],"knownGene","uc001aae.3","chr1",14362,19759],[["uc009viu.2"],"knownGene","uc009viu.2","chr1",14362,19759],[["uc009vis.2"],"knownGene","uc009vis.2","chr1",14362,16765],[["uc009viv.2"],"knownGene","uc009viv.2","chr1",14406,29370],[["uc009viw.2"],"knownGene","uc009viw.2","chr1",14406,29370],[["uc009vix.2"],"knownGene","uc009vix.2","chr1",15602,29370],[["uc009vjd.2"],"knownGene","uc009vjd.2","chr1",15795,18061],[["uc009viz.2"],"knownGene","uc009viz.2","chr1",16606,29370],[["uc009viy.2"],"knownGene","uc009viy.2","chr1",16606,29370],[["uc009vjb.1"],"knownGene","uc009vjb.1","chr1",16857,29961],[["uc010nxs.1"],"knownGene","uc010nxs.1","chr1",16857,29370],[["uc001aai.1"],"knownGene","uc001aai.1","chr1",16857,19759],[["uc009vjc.1"],"knownGene","uc009vjc.1","chr1",16857,17751],[["uc009vje.2"],"knownGene","uc009vje.2","chr1",17232,29370],[["uc009vjf.2"],"knownGene","uc009vjf.2","chr1",17605,29370],[["uc001aak.2"],"knownGene","uc001aak.2","chr1",34611,36081],[["uc001aal.1"],"knownGene","uc001aal.1","chr1",69090,70008],[["uc010nxt.1"],"knownGene","uc010nxt.1","chr1",89294,237877],[["uc001aam.3"],"knownGene","uc001aam.3","chr1",137838,139228],[["uc001aaq.1"],"knownGene","uc001aaq.1","chr1",321083,321114],[["uc001aar.1"],"knownGene","uc001aar.1","chr1",321145,321223],[["uc009vjk.2"],"knownGene","uc009vjk.2","chr1",322036,326938],[["uc001aav.3"],"knownGene","uc001aav.3","chr1",323891,328580],[["uc001aau.2"],"knownGene","uc001aau.2","chr1",323891,328580],[["uc010nxu.1"],"knownGene","uc010nxu.1","chr1",367658,368595],[["uc001aax.1"],"knownGene","uc001aax.1","chr1",420205,421839],[["uc001aaz.2"],"knownGene","uc001aaz.2","chr1",566461,568045],[["uc001aba.1"],"knownGene","uc001aba.1","chr1",568148,568842],[["uc001abb.2"],"knownGene","uc001abb.2","chr1",568843,568912],[["uc001abc.2"],"knownGene","uc001abc.2","chr1",569326,570349],[["uc010nxv.1"],"knownGene","uc010nxv.1","chr1",621097,622034],[["uc002khh.2"],"knownGene","uc002khh.2","chr1",661139,679736],[["uc009vjm.2"],"knownGene","uc009vjm.2","chr1",661139,670994],[["uc001abe.3"],"knownGene","uc001abe.3","chr1",661139,665731],[["uc001abi.1"],"knownGene","uc001abi.1","chr1",668401,668479],[["uc001abj.2"],"knownGene","uc001abj.2","chr1",668510,668541],[["uc010nxw.1"],"knownGene","uc010nxw.1","chr1",671807,671885],[["uc001abl.2"],"knownGene","uc001abl.2","chr1",671916,671947],[["uc001abm.2"],"knownGene","uc001abm.2","chr1",674239,679736],[["uc001abo.2"],"knownGene","uc001abo.2","chr1",700236,714006],[["uc010nxx.1"],"knownGene","uc010nxx.1","chr1",761586,762902],[["uc001abr.1"],"knownGene","uc001abr.1","chr1",763063,789740],[["uc001abp.1"],"knownGene","uc001abp.1","chr1",763063,788997],[["uc001abq.1"],"knownGene","uc001abq.1","chr1",763063,788997],[["uc009vjo.1"],"knownGene","uc009vjo.1","chr1",763063,788997],[["uc009vjn.1"],"knownGene","uc009vjn.1","chr1",763063,788902],[["uc001abs.2"],"knownGene","uc001abs.2","chr1",791897,794579],[["uc001abt.3"],"knownGene","uc001abt.3","chr1",803452,812182],[["uc001abu.1"],"knownGene","uc001abu.1","chr1",846814,850328],[["uc010nxy.1"],"knownGene","uc010nxy.1","chr1",852952,854817],[["uc010nxz.1"],"knownGene","uc010nxz.1","chr1",852952,854817],[["uc001abv.1"],"knownGene","uc001abv.1","chr1",860529,871276],[["uc001abw.1"],"knownGene","uc001abw.1","chr1",861120,879961],[["uc001abx.1"],"knownGene","uc001abx.1","chr1",871151,879961],[["uc001abz.3"],"knownGene","uc001abz.3","chr1",879583,894679],[["uc009vjq.2"],"knownGene","uc009vjq.2","chr1",879583,894679],[["uc001aby.3"],"knownGene","uc001aby.3","chr1",879583,893918],[["uc009vjr.1"],"knownGene","uc009vjr.1","chr1",893650,894679],[["uc001aca.1"],"knownGene","uc001aca.1","chr1",895966,901095],[["uc001acb.1"],"knownGene","uc001acb.1","chr1",896828,897858],[["uc010nya.1"],"knownGene","uc010nya.1","chr1",897008,897858],[["uc001acc.1"],"knownGene","uc001acc.1","chr1",897460,901095],[["uc010nyb.1"],"knownGene","uc010nyb.1","chr1",897734,899229],[["uc001acd.2"],"knownGene","uc001acd.2","chr1",901876,910482],[["uc001acf.2"],"knownGene","uc001acf.2","chr1",901876,910482],[["uc001ace.2"],"knownGene","uc001ace.2","chr1",901876,910482],[["uc001ach.2"],"knownGene","uc001ach.2","chr1",910578,917473],[["uc001acg.2"],"knownGene","uc001acg.2","chr1",910578,912021],[["uc001aci.2"],"knownGene","uc001aci.2","chr1",934341,935552],[["uc010nyc.1"],"knownGene","uc010nyc.1","chr1",934341,935552],[["uc001acj.3"],"knownGene","uc001acj.3","chr1",948846,949915],[["uc001ack.1"],"knownGene","uc001ack.1","chr1",955502,991492],[["uc009vjs.1"],"knownGene","uc009vjs.1","chr1",995082,997436],[["uc001acl.1"],"knownGene","uc001acl.1","chr1",995116,1001833],[["uc001acu.2"],"knownGene","uc001acu.2","chr1",1017197,1051736],[["uc001act.2"],"knownGene","uc001act.2","chr1",1017197,1051736],[["uc001acr.2"],"knownGene","uc001acr.2","chr1",1017197,1051736],[["uc001acs.2"],"knownGene","uc001acs.2","chr1",1017197,1051736],[["uc001acp.2"],"knownGene","uc001acp.2","chr1",1017197,1041507],[["uc001acn.2"],"knownGene","uc001acn.2","chr1",1017197,1027554],[["uc001acm.2"],"knownGene","uc001acm.2","chr1",1017197,1027483],[["uc009vju.1"],"knownGene","uc009vju.1","chr1",1017197,1027483],[["uc010nyd.1"],"knownGene","uc010nyd.1","chr1",1017197,1026945],[["uc001acv.2"],"knownGene","uc001acv.2","chr1",1072396,1079432],[["uc001acw.2"],"knownGene","uc001acw.2","chr1",1102483,1102578],[["uc010nye.1"],"knownGene","uc010nye.1","chr1",1103242,1103332],[["uc010nyf.1"],"knownGene","uc010nyf.1","chr1",1104384,1104467],[["uc001acx.1"],"knownGene","uc001acx.1","chr1",1108435,1114935],[["uc001acy.2"],"knownGene","uc001acy.2","chr1",1109285,1133313],[["uc010nyg.1"],"knownGene","uc010nyg.1","chr1",1109285,1133313],[["uc001acz.1"],"knownGene","uc001acz.1","chr1",1115076,1121241],[["uc001adb.2"],"knownGene","uc001adb.2","chr1",1138888,1142089],[["uc001adc.2"],"knownGene","uc001adc.2","chr1",1138888,1142089],[["uc001add.2"],"knownGene","uc001add.2","chr1",1138888,1142089],[["uc001ada.2"],"knownGene","uc001ada.2","chr1",1138888,1141060],[["uc001ade.2"],"knownGene","uc001ade.2","chr1",1146706,1149512],[["uc001adf.2"],"knownGene","uc001adf.2","chr1",1146720,1149512],[["uc001adh.3"],"knownGene","uc001adh.3","chr1",1152288,1167447],[["uc001adi.3"],"knownGene","uc001adi.3","chr1",1152288,1167447],[["uc009vjv.2"],"knownGene","uc009vjv.2","chr1",1152288,1167447],[["uc009vjw.2"],"knownGene","uc009vjw.2","chr1",1152288,1167447],[["uc001adg.2"],"knownGene","uc001adg.2","chr1",1152288,1156731],[["uc001adj.1"],"knownGene","uc001adj.1","chr1",1158103,1159348],[["uc001adk.2"],"knownGene","uc001adk.2","chr1",1167628,1170418],[["uc001adl.1"],"knownGene","uc001adl.1","chr1",1177832,1182102],[["uc001ado.2"],"knownGene","uc001ado.2","chr1",1189293,1209234],[["uc001adp.2"],"knownGene","uc001adp.2","chr1",1189293,1209234],[["uc001adq.2"],"knownGene","uc001adq.2","chr1",1189293,1209234],[["uc001adr.2"],"knownGene","uc001adr.2","chr1",1189293,1209234],[["uc001ads.2"],"knownGene","uc001ads.2","chr1",1189293,1209234],[["uc001adn.2"],"knownGene","uc001adn.2","chr1",1189293,1209188],[["uc001adm.2"],"knownGene","uc001adm.2","chr1",1189293,1203372],[["uc010nyh.1"],"knownGene","uc010nyh.1","chr1",1193437,1196954],[["uc001adt.1"],"knownGene","uc001adt.1","chr1",1215815,1227409],[["uc001adu.1"],"knownGene","uc001adu.1","chr1",1215815,1227409],[["uc001adw.2"],"knownGene","uc001adw.2","chr1",1217488,1227409],[["uc001adv.2"],"knownGene","uc001adv.2","chr1",1217488,1227409],[["uc001adx.2"],"knownGene","uc001adx.2","chr1",1217536,1227409],[["uc001aeb.2"],"knownGene","uc001aeb.2","chr1",1227763,1243269],[["uc001aea.2"],"knownGene","uc001aea.2","chr1",1227763,1241309],[["uc001ady.2"],"knownGene","uc001ady.2","chr1",1227763,1234335],[["uc001aec.1"],"knownGene","uc001aec.1","chr1",1234123,1244989],[["uc001aed.2"],"knownGene","uc001aed.2","chr1",1243993,1247056],[["uc010nyi.1"],"knownGene","uc010nyi.1","chr1",1243993,1247056],[["uc009vjx.2"],"knownGene","uc009vjx.2","chr1",1244465,1247056],[["uc001aee.1"],"knownGene","uc001aee.1","chr1",1246964,1260046],[["uc001aef.1"],"knownGene","uc001aef.1","chr1",1246964,1260046],[["uc009vjz.1"],"knownGene","uc009vjz.1","chr1",1246964,1260046],[["uc010nyj.1"],"knownGene","uc010nyj.1","chr1",1246964,1260046],[["uc001aeg.1"],"knownGene","uc001aeg.1","chr1",1246964,1260046],[["uc001aeh.1"],"knownGene","uc001aeh.1","chr1",1246964,1260046],[["uc001aei.1"],"knownGene","uc001aei.1","chr1",1246964,1260046],[["uc001aej.1"],"knownGene","uc001aej.1","chr1",1246964,1260046],[["uc001aek.1"],"knownGene","uc001aek.1","chr1",1246964,1260046],[["uc009vjy.1"],"knownGene","uc009vjy.1","chr1",1246964,1252830],[["uc001aem.1"],"knownGene","uc001aem.1","chr1",1254058,1260046],[["uc001ael.1"],"knownGene","uc001ael.1","chr1",1254058,1260046],[["uc001aen.1"],"knownGene","uc001aen.1","chr1",1254076,1260046],[["uc001aeo.2"],"knownGene","uc001aeo.2","chr1",1260142,1264275],[["uc010nyk.1"],"knownGene","uc010nyk.1","chr1",1266725,1269843],[["uc001aer.3"],"knownGene","uc001aer.3","chr1",1270658,1284492],[["uc002quu.2"],"knownGene","uc002quu.2","chr1",1270658,1275557],[["uc009vka.2"],"knownGene","uc009vka.2","chr1",1270658,1275557],[["uc001aeu.1"],"knownGene","uc001aeu.1","chr1",1270663,1277504],[["uc001afa.2"],"knownGene","uc001afa.2","chr1",1288071,1297157],[["uc010nyl.1"],"knownGene","uc010nyl.1","chr1",1288071,1293942],[["uc001aez.2"],"knownGene","uc001aez.2","chr1",1288071,1293942],[["uc001aew.2"],"knownGene","uc001aew.2","chr1",1288071,1293927],[["uc001aex.3"],"knownGene","uc001aex.3","chr1",1288071,1293927],[["uc001aey.3"],"knownGene","uc001aey.3","chr1",1288071,1293927],[["uc001afc.2"],"knownGene","uc001afc.2","chr1",1309109,1310818],[["uc001afd.2"],"knownGene","uc001afd.2","chr1",1309109,1310580],[["uc009vkb.1"],"knownGene","uc009vkb.1","chr1",1309109,1310562],[["uc001afb.1"],"knownGene","uc001afb.1","chr1",1309109,1310246],[["uc001afh.2"],"knownGene","uc001afh.2","chr1",1321090,1334718],[["uc001afj.2"],"knownGene","uc001afj.2","chr1",1321090,1334718],[["uc001afk.2"],"knownGene","uc001afk.2","chr1",1321090,1334718],[["uc001afi.2"],"knownGene","uc001afi.2","chr1",1321090,1334718],[["uc001afg.1"],"knownGene","uc001afg.1","chr1",1321090,1333722],[["uc001aff.1"],"knownGene","uc001aff.1","chr1",1321090,1328183],[["uc010nym.1"],"knownGene","uc010nym.1","chr1",1321090,1327029],[["uc001afn.1"],"knownGene","uc001afn.1","chr1",1334909,1338075],[["uc001afm.2"],"knownGene","uc001afm.2","chr1",1334909,1337425],[["uc009vkd.2"],"knownGene","uc009vkd.2","chr1",1334911,1337425],[["uc009vkc.1"],"knownGene","uc009vkc.1","chr1",1334911,1336650],[["uc001afo.3"],"knownGene","uc001afo.3","chr1",1337276,1342693],[["uc010nyn.1"],"knownGene","uc010nyn.1","chr1",1340412,1342693],[["uc010nyo.1"],"knownGene","uc010nyo.1","chr1",1353801,1356650],[["uc001afq.2"],"knownGene","uc001afq.2","chr1",1353801,1356650],[["uc001afp.2"],"knownGene","uc001afp.2","chr1",1353801,1356650],[["uc010nyp.1"],"knownGene","uc010nyp.1","chr1",1361507,1363166],[["uc001afr.2"],"knownGene","uc001afr.2","chr1",1370908,1376145],[["uc001afs.2"],"knownGene","uc001afs.2","chr1",1370908,1376145],[["uc001aft.2"],"knownGene","uc001aft.2","chr1",1385068,1405538],[["uc001afv.2"],"knownGene","uc001afv.2","chr1",1407163,1431581],[["uc001afx.2"],"knownGene","uc001afx.2","chr1",1413405,1431581],[["uc001afw.2"],"knownGene","uc001afw.2","chr1",1413405,1418847],[["uc001afy.2"],"knownGene","uc001afy.2","chr1",1425460,1431581],[["uc001afz.1"],"knownGene","uc001afz.1","chr1",1447554,1470064],[["uc001aga.1"],"knownGene","uc001aga.1","chr1",1447554,1470064],[["uc001agb.1"],"knownGene","uc001agb.1","chr1",1447909,1470064],[["uc001agc.1"],"knownGene","uc001agc.1","chr1",1467448,1470064],[["uc009vkf.2"],"knownGene","uc009vkf.2","chr1",1470158,1475740],[["uc001agd.2"],"knownGene","uc001agd.2","chr1",1477053,1510262],[["uc009vkg.1"],"knownGene","uc009vkg.1","chr1",1478559,1510262],[["uc001age.1"],"knownGene","uc001age.1","chr1",1497731,1510262],[["uc001agf.1"],"knownGene","uc001agf.1","chr1",1535818,1543166],[["uc001agg.2"],"knownGene","uc001agg.2","chr1",1550883,1565984],[["uc001agh.2"],"knownGene","uc001agh.2","chr1",1550883,1565984],[["uc001agi.2"],"knownGene","uc001agi.2","chr1",1550883,1565984],[["uc001agj.2"],"knownGene","uc001agj.2","chr1",1550883,1565984],[["uc001agk.2"],"knownGene","uc001agk.2","chr1",1550883,1565984],[["uc001agm.2"],"knownGene","uc001agm.2","chr1",1551284,1565984],[["uc001agl.1"],"knownGene","uc001agl.1","chr1",1551284,1564946],[["uc010nyq.1"],"knownGene","uc010nyq.1","chr1",1551689,1565984],[["uc009vkh.2"],"knownGene","uc009vkh.2","chr1",1559153,1565984],[["uc001agn.2"],"knownGene","uc001agn.2","chr1",1560370,1565984],[["uc001ago.2"],"knownGene","uc001ago.2","chr1",1564485,1565984],[["uc001agp.2"],"knownGene","uc001agp.2","chr1",1567559,1570029],[["uc001agq.2"],"knownGene","uc001agq.2","chr1",1567559,1570029],[["uc001agr.2"],"knownGene","uc001agr.2","chr1",1568161,1570029],[["uc009vki.2"],"knownGene","uc009vki.2","chr1",1568566,1570029],[["uc001aha.1"],"knownGene","uc001aha.1","chr1",1571099,1655775],[["uc001agw.1"],"knownGene","uc001agw.1","chr1",1571099,1655775],[["uc001agv.1"],"knownGene","uc001agv.1","chr1",1571099,1655775],[["uc001agy.1"],"knownGene","uc001agy.1","chr1",1571099,1655775],[["uc001agx.1"],"knownGene","uc001agx.1","chr1",1571099,1655775],[["uc001agz.1"],"knownGene","uc001agz.1","chr1",1571099,1655775],[["uc001ags.1"],"knownGene","uc001ags.1","chr1",1571099,1647917],[["uc001agt.1"],"knownGene","uc001agt.1","chr1",1571099,1647917],[["uc009vkj.2"],"knownGene","uc009vkj.2","chr1",1571099,1576737],[["uc010nyr.1"],"knownGene","uc010nyr.1","chr1",1577746,1580625],[["uc001ahc.1"],"knownGene","uc001ahc.1","chr1",1586822,1590469],[["uc009vkl.1"],"knownGene","uc009vkl.1","chr1",1590989,1624243],[["uc001ahh.3"],"knownGene","uc001ahh.3","chr1",1592939,1677431],[["uc001ahf.3"],"knownGene","uc001ahf.3","chr1",1592939,1624243],[["uc001ahg.3"],"knownGene","uc001ahg.3","chr1",1592939,1624243],[["uc001ahe.3"],"knownGene","uc001ahe.3","chr1",1592939,1601578],[["uc009vkm.1"],"knownGene","uc009vkm.1","chr1",1601213,1671143],[["uc009vkn.1"],"knownGene","uc009vkn.1","chr1",1601878,1624243],[["uc001ahi.1"],"knownGene","uc001ahi.1","chr1",1631377,1633247],[["uc009vko.1"],"knownGene","uc009vko.1","chr1",1631785,1633247],[["uc009vkr.2"],"knownGene","uc009vkr.2","chr1",1634171,1655791],[["uc009vks.2"],"knownGene","uc009vks.2","chr1",1634171,1655791],[["uc009vkp.2"],"knownGene","uc009vkp.2","chr1",1634171,1640391],[["uc009vkq.2"],"knownGene","uc009vkq.2","chr1",1634171,1640391],[["uc001ahj.3"],"knownGene","uc001ahj.3","chr1",1634171,1639684],[["uc010nys.1"],"knownGene","uc010nys.1","chr1",1635664,1655791],[["uc010nyt.1"],"knownGene","uc010nyt.1","chr1",1635988,1655791],[["uc010nyu.1"],"knownGene","uc010nyu.1","chr1",1637080,1655791],[["uc009vkt.1"],"knownGene","uc009vkt.1","chr1",1640232,1655791],[["uc009vku.1"],"knownGene","uc009vku.1","chr1",1640232,1655791],[["uc009vkv.1"],"knownGene","uc009vkv.1","chr1",1640232,1655791],[["uc001aht.1"],"knownGene","uc001aht.1","chr1",1640956,1655543],[["uc001ahw.1"],"knownGene","uc001ahw.1","chr1",1647784,1655543],[["uc001ahu.1"],"knownGene","uc001ahu.1","chr1",1647784,1655471],[["uc001ahv.1"],"knownGene","uc001ahv.1","chr1",1647784,1655471],[["uc001ahx.1"],"knownGene","uc001ahx.1","chr1",1656053,1663343],[["uc001ahy.2"],"knownGene","uc001ahy.2","chr1",1656278,1677431],[["uc001ahz.2"],"knownGene","uc001ahz.2","chr1",1656278,1677431],[["uc001aia.1"],"knownGene","uc001aia.1","chr1",1658824,1662665],[["uc001aib.1"],"knownGene","uc001aib.1","chr1",1663680,1677431],[["uc001aie.2"],"knownGene","uc001aie.2","chr1",1682677,1711508],[["uc001aid.3"],"knownGene","uc001aid.3","chr1",1682677,1710290],[["uc001aic.2"],"knownGene","uc001aic.2","chr1",1682677,1709909],[["uc009vkw.2"],"knownGene","uc009vkw.2","chr1",1682677,1709888],[["uc010nyv.1"],"knownGene","uc010nyv.1","chr1",1682677,1690081],[["uc009vkx.1"],"knownGene","uc009vkx.1","chr1",1685548,1696885],[["uc001aif.2"],"knownGene","uc001aif.2","chr1",1716729,1822495],[["uc009vky.2"],"knownGene","uc009vky.2","chr1",1716729,1822495],[["uc001aig.1"],"knownGene","uc001aig.1","chr1",1822909,1824112],[["uc001aih.1"],"knownGene","uc001aih.1","chr1",1846265,1848733],[["uc001aij.2"],"knownGene","uc001aij.2","chr1",1849028,1850740],[["uc001aii.2"],"knownGene","uc001aii.2","chr1",1849028,1850236],[["uc001ail.2"],"knownGene","uc001ail.2","chr1",1853396,1859368],[["uc001aik.2"],"knownGene","uc001aik.2","chr1",1853396,1858842],[["uc001aim.1"],"knownGene","uc001aim.1","chr1",1884751,1935276],[["uc009vkz.1"],"knownGene","uc009vkz.1","chr1",1886585,1922414],[["uc001ain.1"],"knownGene","uc001ain.1","chr1",1915109,1935276],[["uc001aio.1"],"knownGene","uc001aio.1","chr1",1944651,1946969],[["uc001aip.2"],"knownGene","uc001aip.2","chr1",1950767,1962192],[["uc001aiq.2"],"knownGene","uc001aiq.2","chr1",1981908,2116832],[["uc001air.2"],"knownGene","uc001air.2","chr1",2005085,2116832],[["uc010nyw.1"],"knownGene","uc010nyw.1","chr1",2005511,2116832],[["uc001ais.2"],"knownGene","uc001ais.2","chr1",2036154,2116832],[["uc009vla.2"],"knownGene","uc009vla.2","chr1",2075889,2116832],[["uc010nyx.1"],"knownGene","uc010nyx.1","chr1",2076795,2116832],[["uc009vlb.2"],"knownGene","uc009vlb.2","chr1",2076795,2088166],[["uc001ait.2"],"knownGene","uc001ait.2","chr1",2100286,2116832],[["uc001aiu.1"],"knownGene","uc001aiu.1","chr1",2112574,2114663],[["uc009vlc.1"],"knownGene","uc009vlc.1","chr1",2113232,2115314],[["uc001aix.1"],"knownGene","uc001aix.1","chr1",2115916,2139172],[["uc001aiv.1"],"knownGene","uc001aiv.1","chr1",2115916,2126214],[["uc001aiw.1"],"knownGene","uc001aiw.1","chr1",2115916,2126214],[["uc001aiy.2"],"knownGene","uc001aiy.2","chr1",2120988,2126214],[["uc001aiz.1"],"knownGene","uc001aiz.1","chr1",2121236,2123179],[["uc001aja.3"],"knownGene","uc001aja.3","chr1",2160133,2241651],[["uc001ajb.1"],"knownGene","uc001ajb.1","chr1",2252695,2322993],[["uc009vld.2"],"knownGene","uc009vld.2","chr1",2263565,2322993],[["uc001ajc.3"],"knownGene","uc001ajc.3","chr1",2281852,2284100],[["uc001ajd.1"],"knownGene","uc001ajd.1","chr1",2286615,2322993],[["uc010nyy.1"],"knownGene","uc010nyy.1","chr1",2309494,2322993],[["uc001aje.1"],"knownGene","uc001aje.1","chr1",2323213,2336874],[["uc001ajf.1"],"knownGene","uc001ajf.1","chr1",2323213,2336874],[["uc001ajg.2"],"knownGene","uc001ajg.2","chr1",2336242,2344010],[["uc001ajh.2"],"knownGene","uc001ajh.2","chr1",2336242,2344010],[["uc001aji.1"],"knownGene","uc001aji.1","chr1",2407753,2436964],[["uc001ajk.1"],"knownGene","uc001ajk.1","chr1",2411622,2436969],[["uc001ajj.1"],"knownGene","uc001ajj.1","chr1",2411622,2436965],[["uc009vle.1"],"knownGene","uc009vle.1","chr1",2411622,2436964],[["uc010nyz.1"],"knownGene","uc010nyz.1","chr1",2411622,2436891],[["uc001ajl.1"],"knownGene","uc001ajl.1","chr1",2430182,2436964],[["uc001ajm.1"],"knownGene","uc001ajm.1","chr1",2439974,2458035],[["uc010nza.1"],"knownGene","uc010nza.1","chr1",2439974,2458035],[["uc001ajn.2"],"knownGene","uc001ajn.2","chr1",2460184,2461684],[["uc001ajp.2"],"knownGene","uc001ajp.2","chr1",2481358,2484284],[["uc001ajo.2"],"knownGene","uc001ajo.2","chr1",2481358,2484284],[["uc001ajq.2"],"knownGene","uc001ajq.2","chr1",2481721,2484284],[["uc010nzb.1"],"knownGene","uc010nzb.1","chr1",2483213,2488450],[["uc001ajr.2"],"knownGene","uc001ajr.2","chr1",2487804,2495265],[["uc001ajs.2"],"knownGene","uc001ajs.2","chr1",2487804,2495265],[["uc001ajt.1"],"knownGene","uc001ajt.1","chr1",2487804,2495188],[["uc009vlf.1"],"knownGene","uc009vlf.1","chr1",2487804,2492974],[["uc010nzc.1"],"knownGene","uc010nzc.1","chr1",2487804,2490438],[["uc001aju.1"],"knownGene","uc001aju.1","chr1",2518248,2522902],[["uc001ajw.1"],"knownGene","uc001ajw.1","chr1",2518248,2522902],[["uc001ajv.1"],"knownGene","uc001ajv.1","chr1",2518248,2522902],[["uc010nzd.1"],"knownGene","uc010nzd.1","chr1",2518248,2522902],[["uc010nze.1"],"knownGene","uc010nze.1","chr1",2518248,2522902],[["uc010nzf.1"],"knownGene","uc010nzf.1","chr1",2518248,2522902],[["uc001ajx.1"],"knownGene","uc001ajx.1","chr1",2518516,2522902],[["uc001ajy.2"],"knownGene","uc001ajy.2","chr1",2522080,2564481],[["uc009vlg.1"],"knownGene","uc009vlg.1","chr1",2522080,2560960],[["uc001ajz.2"],"knownGene","uc001ajz.2","chr1",2938045,2939465],[["uc001aka.2"],"knownGene","uc001aka.2","chr1",2976182,2980350],[["uc010nzg.1"],"knownGene","uc010nzg.1","chr1",2980635,2984289],[["uc001akc.2"],"knownGene","uc001akc.2","chr1",2985743,3355183],[["uc001akd.2"],"knownGene","uc001akd.2","chr1",2985743,3355183],[["uc001ake.2"],"knownGene","uc001ake.2","chr1",2985743,3355183],[["uc001akf.2"],"knownGene","uc001akf.2","chr1",2985743,3355183],[["uc009vlh.2"],"knownGene","uc009vlh.2","chr1",2985743,3355183],[["uc001akg.3"],"knownGene","uc001akg.3","chr1",3371146,3397675],[["uc001aki.2"],"knownGene","uc001aki.2","chr1",3382568,3397675],[["uc001akj.2"],"knownGene","uc001akj.2","chr1",3383534,3397675],[["uc010nzh.1"],"knownGene","uc010nzh.1","chr1",3388170,3397675],[["uc009vli.1"],"knownGene","uc009vli.1","chr1",3388170,3391021],[["uc001akl.2"],"knownGene","uc001akl.2","chr1",3404512,3528059],[["uc001akk.2"],"knownGene","uc001akk.2","chr1",3404512,3448012],[["uc001akm.2"],"knownGene","uc001akm.2","chr1",3541555,3546692],[["uc009vlj.2"],"knownGene","uc009vlj.2","chr1",3541555,3546692],[["uc001ako.2"],"knownGene","uc001ako.2","chr1",3547331,3566671],[["uc001akn.3"],"knownGene","uc001akn.3","chr1",3547336,3566671],[["uc010nzi.1"],"knownGene","uc010nzi.1","chr1",3548458,3566671],[["uc001akp.2"],"knownGene","uc001akp.2","chr1",3569128,3650467],[["uc001akq.2"],"knownGene","uc001akq.2","chr1",3569128,3650456],[["uc001akr.2"],"knownGene","uc001akr.2","chr1",3607235,3650467],[["uc009vlk.1"],"knownGene","uc009vlk.1","chr1",3607235,3650467],[["uc001aks.2"],"knownGene","uc001aks.2","chr1",3607235,3650467],[["uc010nzj.1"],"knownGene","uc010nzj.1","chr1",3607235,3646314],[["uc010nzk.1"],"knownGene","uc010nzk.1","chr1",3614609,3650467],[["uc009vll.2"],"knownGene","uc009vll.2","chr1",3614609,3625097],[["uc010nzl.1"],"knownGene","uc010nzl.1","chr1",3644041,3650467],[["uc009vlm.2"],"knownGene","uc009vlm.2","chr1",3652549,3663886],[["uc001akt.3"],"knownGene","uc001akt.3","chr1",3652549,3663335],[["uc001akv.2"],"knownGene","uc001akv.2","chr1",3668964,3688209],[["uc001akw.3"],"knownGene","uc001akw.3","chr1",3689351,3692545],[["uc001akx.1"],"knownGene","uc001akx.1","chr1",3696783,3713068],[["uc001aky.2"],"knownGene","uc001aky.2","chr1",3728644,3773797],[["uc010nzm.1"],"knownGene","uc010nzm.1","chr1",3728652,3773797],[["uc001akz.2"],"knownGene","uc001akz.2","chr1",3750235,3773797],[["uc001alc.2"],"knownGene","uc001alc.2","chr1",3773844,3801992],[["uc001ale.2"],"knownGene","uc001ale.2","chr1",3773844,3801992],[["uc009vlp.2"],"knownGene","uc009vlp.2","chr1",3773844,3801992],[["uc001alb.2"],"knownGene","uc001alb.2","chr1",3773844,3801992],[["uc010nzn.1"],"knownGene","uc010nzn.1","chr1",3773844,3801992],[["uc009vlq.2"],"knownGene","uc009vlq.2","chr1",3773844,3801992],[["uc009vlr.2"],"knownGene","uc009vlr.2","chr1",3773844,3801992],[["uc001ald.2"],"knownGene","uc001ald.2","chr1",3773844,3801992],[["uc009vlo.1"],"knownGene","uc009vlo.1","chr1",3773844,3783050],[["uc001ala.1"],"knownGene","uc001ala.1","chr1",3773844,3782962],[["uc009vln.1"],"knownGene","uc009vln.1","chr1",3773844,3782564],[["uc001alf.2"],"knownGene","uc001alf.2","chr1",3805702,3816857],[["uc009vls.2"],"knownGene","uc009vls.2","chr1",3805702,3816857],[["uc001alh.3"],"knownGene","uc001alh.3","chr1",3816967,3833877],[["uc001alg.2"],"knownGene","uc001alg.2","chr1",3816967,3832009],[["uc010nzo.1"],"knownGene","uc010nzo.1","chr1",3816967,3832009],[["uc001ali.1"],"knownGene","uc001ali.1","chr1",4000676,4015322],[["uc001alj.2"],"knownGene","uc001alj.2","chr1",4472110,4484744],[["uc001aln.2"],"knownGene","uc001aln.2","chr1",4715104,4843850],[["uc001alm.1"],"knownGene","uc001alm.1","chr1",4715104,4837854],[["uc001alo.3"],"knownGene","uc001alo.3","chr1",4847557,4852182],[["uc001alp.1"],"knownGene","uc001alp.1","chr1",5621768,5728315],[["uc001alq.1"],"knownGene","uc001alq.1","chr1",5922869,6052531],[["uc001alr.1"],"knownGene","uc001alr.1","chr1",5922870,5928435],[["uc001als.1"],"knownGene","uc001als.1","chr1",5936013,6052531],[["uc009vlt.1"],"knownGene","uc009vlt.1","chr1",5937152,6052531],[["uc001alt.1"],"knownGene","uc001alt.1","chr1",5937152,6052531],[["uc009vlu.1"],"knownGene","uc009vlu.1","chr1",5946556,5965543],[["uc009vlv.1"],"knownGene","uc009vlv.1","chr1",6052765,6160523],[["uc001alv.1"],"knownGene","uc001alv.1","chr1",6086379,6160523],[["uc001alw.1"],"knownGene","uc001alw.1","chr1",6086379,6160523],[["uc001alu.2"],"knownGene","uc001alu.2","chr1",6086379,6158613],[["uc001alx.1"],"knownGene","uc001alx.1","chr1",6094342,6160523],[["uc001aly.1"],"knownGene","uc001aly.1","chr1",6105980,6160523],[["uc009vlw.1"],"knownGene","uc009vlw.1","chr1",6105980,6160523],[["uc001amb.1"],"knownGene","uc001amb.1","chr1",6161852,6240183],[["uc001ama.1"],"knownGene","uc001ama.1","chr1",6161852,6204215],[["uc001alz.1"],"knownGene","uc001alz.1","chr1",6161852,6191808],[["uc001amc.1"],"knownGene","uc001amc.1","chr1",6181164,6206931],[["uc009vlx.1"],"knownGene","uc009vlx.1","chr1",6181553,6196925],[["uc001amd.2"],"knownGene","uc001amd.2","chr1",6245080,6259679],[["uc001ame.2"],"knownGene","uc001ame.2","chr1",6245080,6259679],[["uc001amg.2"],"knownGene","uc001amg.2","chr1",6266188,6281351],[["uc001amf.1"],"knownGene","uc001amf.1","chr1",6266188,6268366],[["uc001amh.2"],"knownGene","uc001amh.2","chr1",6268677,6270959],[["uc010nzp.1"],"knownGene","uc010nzp.1","chr1",6268940,6278429],[["uc001amk.2"],"knownGene","uc001amk.2","chr1",6281254,6296044],[["uc001aml.2"],"knownGene","uc001aml.2","chr1",6281254,6296044],[["uc001amm.2"],"knownGene","uc001amm.2","chr1",6297870,6299490],[["uc009vly.1"],"knownGene","uc009vly.1","chr1",6304261,6305638],[["uc001amo.1"],"knownGene","uc001amo.1","chr1",6307413,6310123],[["uc001amp.1"],"knownGene","uc001amp.1","chr1",6308855,6321035],[["uc001amt.2"],"knownGene","uc001amt.2","chr1",6324332,6453826],[["uc001amu.2"],"knownGene","uc001amu.2","chr1",6324332,6453826],[["uc001amv.2"],"knownGene","uc001amv.2","chr1",6324332,6453826],[["uc010nzq.1"],"knownGene","uc010nzq.1","chr1",6324332,6453438],[["uc001ams.2"],"knownGene","uc001ams.2","chr1",6324332,6445883],[["uc001amr.2"],"knownGene","uc001amr.2","chr1",6324332,6420764],[["uc001amq.2"],"knownGene","uc001amq.2","chr1",6324332,6419004],[["uc001amw.2"],"knownGene","uc001amw.2","chr1",6472499,6484730],[["uc001amx.2"],"knownGene","uc001amx.2","chr1",6475294,6479979],[["uc001amy.2"],"knownGene","uc001amy.2","chr1",6484847,6521003],[["uc001amz.2"],"knownGene","uc001amz.2","chr1",6508102,6521003],[["uc001ana.2"],"knownGene","uc001ana.2","chr1",6521220,6526255],[["uc001anb.2"],"knownGene","uc001anb.2","chr1",6521220,6526255],[["uc001anc.2"],"knownGene","uc001anc.2","chr1",6521220,6526255],[["uc001and.2"],"knownGene","uc001and.2","chr1",6521220,6526255],[["uc009vlz.2"],"knownGene","uc009vlz.2","chr1",6521220,6526255],[["uc001ane.2"],"knownGene","uc001ane.2","chr1",6521220,6526255],[["uc001anf.2"],"knownGene","uc001anf.2","chr1",6521220,6526255],[["uc001ang.2"],"knownGene","uc001ang.2","chr1",6521220,6526255],[["uc001anh.2"],"knownGene","uc001anh.2","chr1",6521220,6526255],[["uc001ani.1"],"knownGene","uc001ani.1","chr1",6524170,6526255],[["uc001anq.1"],"knownGene","uc001anq.1","chr1",6526151,6580069],[["uc001anp.1"],"knownGene","uc001anp.1","chr1",6526151,6580069],[["uc001ano.1"],"knownGene","uc001ano.1","chr1",6526151,6557484],[["uc001ann.1"],"knownGene","uc001ann.1","chr1",6526151,6556756],[["uc001anm.1"],"knownGene","uc001anm.1","chr1",6526151,6551760],[["uc009vmb.1"],"knownGene","uc009vmb.1","chr1",6526151,6550640],[["uc001anl.1"],"knownGene","uc001anl.1","chr1",6526151,6550640],[["uc001ank.1"],"knownGene","uc001ank.1","chr1",6526151,6546014],[["uc010nzr.1"],"knownGene","uc010nzr.1","chr1",6526151,6545529],[["uc009vma.1"],"knownGene","uc009vma.1","chr1",6526151,6537718],[["uc001anj.1"],"knownGene","uc001anj.1","chr1",6526151,6531643],[["uc001anr.1"],"knownGene","uc001anr.1","chr1",6527298,6529301],[["uc001ans.2"],"knownGene","uc001ans.2","chr1",6585209,6614581],[["uc010nzs.1"],"knownGene","uc010nzs.1","chr1",6585209,6614581],[["uc001ant.2"],"knownGene","uc001ant.2","chr1",6615433,6639816],[["uc001anu.2"],"knownGene","uc001anu.2","chr1",6615433,6639816],[["uc001anv.2"],"knownGene","uc001anv.2","chr1",6615433,6639816],[["uc001anw.2"],"knownGene","uc001anw.2","chr1",6615433,6639816],[["uc009vmc.1"],"knownGene","uc009vmc.1","chr1",6640055,6649339],[["uc001anx.2"],"knownGene","uc001anx.2","chr1",6640062,6649339],[["uc009vmd.1"],"knownGene","uc009vmd.1","chr1",6640068,6649339],[["uc001any.1"],"knownGene","uc001any.1","chr1",6645361,6649339],[["uc001anz.1"],"knownGene","uc001anz.1","chr1",6650778,6662929],[["uc001aoa.2"],"knownGene","uc001aoa.2","chr1",6650784,6662929],[["uc009vme.2"],"knownGene","uc009vme.2","chr1",6650784,6659871],[["uc001aob.3"],"knownGene","uc001aob.3","chr1",6673755,6684092],[["uc001aoc.2"],"knownGene","uc001aoc.2","chr1",6684924,6693621],[["uc001aoe.1"],"knownGene","uc001aoe.1","chr1",6685209,6695645],[["uc001aod.2"],"knownGene","uc001aod.2","chr1",6685209,6693621],[["uc001aof.2"],"knownGene","uc001aof.2","chr1",6694227,6761966],[["uc001aog.2"],"knownGene","uc001aog.2","chr1",6694227,6761966],[["uc010nzu.1"],"knownGene","uc010nzu.1","chr1",6694227,6761966],[["uc010nzt.1"],"knownGene","uc010nzt.1","chr1",6694227,6741097],[["uc001aoi.2"],"knownGene","uc001aoi.2","chr1",6845383,7829763],[["uc001aoh.2"],"knownGene","uc001aoh.2","chr1",6845383,6932097],[["uc010nzv.1"],"knownGene","uc010nzv.1","chr1",7732053,7805082],[["uc001aok.3"],"knownGene","uc001aok.3","chr1",7740147,7829763],[["uc001aoj.2"],"knownGene","uc001aoj.2","chr1",7796403,7829763],[["uc009vmf.2"],"knownGene","uc009vmf.2","chr1",7804894,7829763],[["uc001aol.2"],"knownGene","uc001aol.2","chr1",7831328,7841491],[["uc001aon.2"],"knownGene","uc001aon.2","chr1",7844379,7864017],[["uc009vmg.1"],"knownGene","uc009vmg.1","chr1",7844439,7890221],[["uc001aoo.2"],"knownGene","uc001aoo.2","chr1",7844713,7905236],[["uc001aop.2"],"knownGene","uc001aop.2","chr1",7844713,7905236],[["uc010nzw.1"],"knownGene","uc010nzw.1","chr1",7844713,7905236],[["uc009vmh.1"],"knownGene","uc009vmh.1","chr1",7844713,7890221],[["uc001aoq.2"],"knownGene","uc001aoq.2","chr1",7903143,7973294],[["uc001aos.2"],"knownGene","uc001aos.2","chr1",7907672,7913565],[["uc001aor.2"],"knownGene","uc001aor.2","chr1",7907672,7913178],[["uc001aot.2"],"knownGene","uc001aot.2","chr1",7979907,8000887],[["uc001aou.3"],"knownGene","uc001aou.3","chr1",8021713,8045341],[["uc001aox.3"],"knownGene","uc001aox.3","chr1",8021713,8045341],[["uc001aov.3"],"knownGene","uc001aov.3","chr1",8021713,8045341],[["uc001aow.3"],"knownGene","uc001aow.3","chr1",8021713,8032014],[["uc001aoy.1"],"knownGene","uc001aoy.1","chr1",8043018,8045341],[["uc001aoz.2"],"knownGene","uc001aoz.2","chr1",8071779,8086393],[["uc001apa.1"],"knownGene","uc001apa.1","chr1",8073486,8075752],[["uc001apb.2"],"knownGene","uc001apb.2","chr1",8384389,8404226],[["uc001apc.2"],"knownGene","uc001apc.2","chr1",8390197,8404226],[["uc001ape.2"],"knownGene","uc001ape.2","chr1",8412465,8877699],[["uc001apf.2"],"knownGene","uc001apf.2","chr1",8412465,8877699],[["uc001apd.2"],"knownGene","uc001apd.2","chr1",8412465,8483747],[["uc010nzx.1"],"knownGene","uc010nzx.1","chr1",8420171,8585844],[["uc001apg.1"],"knownGene","uc001apg.1","chr1",8440651,8441235],[["uc001aph.1"],"knownGene","uc001aph.1","chr1",8525029,8813897],[["uc001apj.1"],"knownGene","uc001apj.1","chr1",8921062,8938780],[["uc001apk.1"],"knownGene","uc001apk.1","chr1",8921062,8938780],[["uc001apl.1"],"knownGene","uc001apl.1","chr1",8921062,8938780],[["uc009vmi.1"],"knownGene","uc009vmi.1","chr1",8921062,8938780],[["uc009vmj.1"],"knownGene","uc009vmj.1","chr1",8921062,8938780],[["uc009vmk.1"],"knownGene","uc009vmk.1","chr1",8921062,8938780],[["uc001api.1"],"knownGene","uc001api.1","chr1",8921062,8931356],[["uc009vml.1"],"knownGene","uc009vml.1","chr1",8923172,8938780],[["uc009vmm.1"],"knownGene","uc009vmm.1","chr1",8931005,8938780],[["uc001apm.2"],"knownGene","uc001apm.2","chr1",9005921,9035146],[["uc009vmn.2"],"knownGene","uc009vmn.2","chr1",9005921,9035146],[["uc009vmo.1"],"knownGene","uc009vmo.1","chr1",9063358,9086404],[["uc010oab.1"],"knownGene","uc010oab.1","chr1",9097006,9148510],[["uc001apo.2"],"knownGene","uc001apo.2","chr1",9097006,9129887],[["uc010oaa.1"],"knownGene","uc010oaa.1","chr1",9097006,9129887],[["uc010nzz.1"],"knownGene","uc010nzz.1","chr1",9097006,9129653],[["uc010nzy.1"],"knownGene","uc010nzy.1","chr1",9097006,9109319],[["uc001app.3"],"knownGene","uc001app.3","chr1",9101427,9129887],[["uc010oac.1"],"knownGene","uc010oac.1","chr1",9101427,9129653],[["uc001apq.1"],"knownGene","uc001apq.1","chr1",9164475,9189229],[["uc010oad.1"],"knownGene","uc010oad.1","chr1",9164475,9189229],[["uc001apr.2"],"knownGene","uc001apr.2","chr1",9169161,9189229],[["uc001aps.2"],"knownGene","uc001aps.2","chr1",9186960,9189356],[["uc009vmq.2"],"knownGene","uc009vmq.2","chr1",9208346,9242451],[["uc001apt.2"],"knownGene","uc001apt.2","chr1",9294862,9331392],[["uc010oae.1"],"knownGene","uc010oae.1","chr1",9352940,9429588],[["uc001apv.2"],"knownGene","uc001apv.2","chr1",9415765,9429588],[["uc001apw.2"],"knownGene","uc001apw.2","chr1",9599527,9642830],[["uc001apx.2"],"knownGene","uc001apx.2","chr1",9599527,9642830],[["uc001apz.2"],"knownGene","uc001apz.2","chr1",9648976,9674935],[["uc001apy.2"],"knownGene","uc001apy.2","chr1",9648976,9665006],[["uc001aqb.3"],"knownGene","uc001aqb.3","chr1",9711789,9789171],[["uc001aqa.2"],"knownGene","uc001aqa.2","chr1",9711789,9775827],[["uc001aqc.3"],"knownGene","uc001aqc.3","chr1",9712668,9714644],[["uc001aqd.2"],"knownGene","uc001aqd.2","chr1",9732485,9747627],[["uc010oaf.1"],"knownGene","uc010oaf.1","chr1",9751524,9789171],[["uc001aqe.3"],"knownGene","uc001aqe.3","chr1",9770162,9789171],[["uc001aqh.2"],"knownGene","uc001aqh.2","chr1",9789079,9884550],[["uc001aqi.2"],"knownGene","uc001aqi.2","chr1",9789079,9884550],[["uc010oag.1"],"knownGene","uc010oag.1","chr1",9789079,9884550],[["uc001aqf.2"],"knownGene","uc001aqf.2","chr1",9789079,9793604],[["uc001aqk.1"],"knownGene","uc001aqk.1","chr1",9908333,9970316],[["uc001aql.1"],"knownGene","uc001aql.1","chr1",9908333,9970316],[["uc009vmr.2"],"knownGene","uc009vmr.2","chr1",9989777,10003427],[["uc010oah.1"],"knownGene","uc010oah.1","chr1",9989777,10003427],[["uc001aqo.2"],"knownGene","uc001aqo.2","chr1",9989777,10003387],[["uc001aqm.2"],"knownGene","uc001aqm.2","chr1",9989777,10002840],[["uc001aqn.2"],"knownGene","uc001aqn.2","chr1",9989777,10002840],[["uc001aqp.2"],"knownGene","uc001aqp.2","chr1",10003485,10045555],[["uc001aqq.2"],"knownGene","uc001aqq.2","chr1",10057254,10076077],[["uc009vms.2"],"knownGene","uc009vms.2","chr1",10057254,10076077],[["uc001aqs.3"],"knownGene","uc001aqs.3","chr1",10093015,10241294],[["uc001aqr.3"],"knownGene","uc001aqr.3","chr1",10093015,10241294],[["uc010oai.1"],"knownGene","uc010oai.1","chr1",10093015,10241294],[["uc010oaj.1"],"knownGene","uc010oaj.1","chr1",10093015,10241294],[["uc001aqt.1"],"knownGene","uc001aqt.1","chr1",10192426,10211639],[["uc001aqu.2"],"knownGene","uc001aqu.2","chr1",10231013,10241294],[["uc001aqw.3"],"knownGene","uc001aqw.3","chr1",10270763,10441659],[["uc001aqv.3"],"knownGene","uc001aqv.3","chr1",10270763,10368653],[["uc009vmt.2"],"knownGene","uc009vmt.2","chr1",10270763,10334467],[["uc001aqx.3"],"knownGene","uc001aqx.3","chr1",10271673,10441659],[["uc001aqy.2"],"knownGene","uc001aqy.2","chr1",10292307,10441654],[["uc001aqz.2"],"knownGene","uc001aqz.2","chr1",10292307,10441654],[["uc001ara.2"],"knownGene","uc001ara.2","chr1",10292307,10441654],[["uc001arb.2"],"knownGene","uc001arb.2","chr1",10292307,10441654],[["uc001arc.2"],"knownGene","uc001arc.2","chr1",10459084,10480200],[["uc001ard.2"],"knownGene","uc001ard.2","chr1",10459084,10480200],[["uc010oak.1"],"knownGene","uc010oak.1","chr1",10459084,10480200],[["uc010oal.1"],"knownGene","uc010oal.1","chr1",10459174,10480200],[["uc001arf.2"],"knownGene","uc001arf.2","chr1",10490158,10512208],[["uc001arg.2"],"knownGene","uc001arg.2","chr1",10490158,10512208],[["uc001are.2"],"knownGene","uc001are.2","chr1",10490158,10502864],[["uc001arh.2"],"knownGene","uc001arh.2","chr1",10490799,10502864],[["uc001ari.2"],"knownGene","uc001ari.2","chr1",10509970,10512208],[["uc001arj.2"],"knownGene","uc001arj.2","chr1",10520604,10532613],[["uc001ark.2"],"knownGene","uc001ark.2","chr1",10520604,10532613],[["uc001arn.2"],"knownGene","uc001arn.2","chr1",10535002,10690813],[["uc009vmv.2"],"knownGene","uc009vmv.2","chr1",10535002,10690813],[["uc010oam.1"],"knownGene","uc010oam.1","chr1",10535002,10690813],[["uc010oan.1"],"knownGene","uc010oan.1","chr1",10535002,10690813],[["uc009vmu.1"],"knownGene","uc009vmu.1","chr1",10535002,10683924],[["uc001arm.1"],"knownGene","uc001arm.1","chr1",10535002,10638484],[["uc001arl.2"],"knownGene","uc001arl.2","chr1",10535002,10580063],[["uc009vmw.2"],"knownGene","uc009vmw.2","chr1",10588311,10690813],[["uc001aro.2"],"knownGene","uc001aro.2","chr1",10696667,10856707],[["uc001arp.1"],"knownGene","uc001arp.1","chr1",10707269,10856707],[["uc009vmx.2"],"knownGene","uc009vmx.2","chr1",10713040,10754507],[["uc001arq.1"],"knownGene","uc001arq.1","chr1",10718063,10721455],[["uc001arr.1"],"knownGene","uc001arr.1","chr1",11006532,11024258],[["uc010oao.1"],"knownGene","uc010oao.1","chr1",11006532,11024258],[["uc001ars.1"],"knownGene","uc001ars.1","chr1",11006532,11024258],[["uc001art.2"],"knownGene","uc001art.2","chr1",11072678,11085548],[["uc010oap.1"],"knownGene","uc010oap.1","chr1",11072678,11085548],[["uc001aru.2"],"knownGene","uc001aru.2","chr1",11086580,11107285],[["uc001arv.2"],"knownGene","uc001arv.2","chr1",11104855,11107285],[["uc001arw.2"],"knownGene","uc001arw.2","chr1",11104855,11107285],[["uc001arx.1"],"knownGene","uc001arx.1","chr1",11105155,11107285],[["uc001arz.1"],"knownGene","uc001arz.1","chr1",11114648,11120091],[["uc001ary.1"],"knownGene","uc001ary.1","chr1",11114648,11116841],[["uc001asa.2"],"knownGene","uc001asa.2","chr1",11126677,11159938],[["uc001asb.2"],"knownGene","uc001asb.2","chr1",11126677,11159938],[["uc009vmy.1"],"knownGene","uc009vmy.1","chr1",11139767,11159938],[["uc001asd.2"],"knownGene","uc001asd.2","chr1",11166588,11322608],[["uc001asc.2"],"knownGene","uc001asc.2","chr1",11166588,11191615],[["uc001ase.2"],"knownGene","uc001ase.2","chr1",11249397,11256037],[["uc001asg.2"],"knownGene","uc001asg.2","chr1",11333254,11348490],[["uc001ash.3"],"knownGene","uc001ash.3","chr1",11539294,11597639],[["uc009vmz.1"],"knownGene","uc009vmz.1","chr1",11539294,11541938],[["uc001asi.1"],"knownGene","uc001asi.1","chr1",11561046,11586928],[["uc001asj.2"],"knownGene","uc001asj.2","chr1",11708449,11714739],[["uc009vna.2"],"knownGene","uc009vna.2","chr1",11708449,11714739],[["uc009vnb.1"],"knownGene","uc009vnb.1","chr1",11709143,11714401],[["uc001ask.2"],"knownGene","uc001ask.2","chr1",11714431,11723383],[["uc001asm.2"],"knownGene","uc001asm.2","chr1",11714913,11723383],[["uc001asl.2"],"knownGene","uc001asl.2","chr1",11714913,11723383],[["uc001asn.2"],"knownGene","uc001asn.2","chr1",11714913,11723383],[["uc010oar.1"],"knownGene","uc010oar.1","chr1",11714913,11723383],[["uc010oas.1"],"knownGene","uc010oas.1","chr1",11714913,11723383],[["uc010oaq.1"],"knownGene","uc010oaq.1","chr1",11714913,11718713],[["uc001aso.2"],"knownGene","uc001aso.2","chr1",11724149,11734407],[["uc009vnc.2"],"knownGene","uc009vnc.2","chr1",11734537,11751678],[["uc001asq.3"],"knownGene","uc001asq.3","chr1",11734537,11751678],[["uc001asp.2"],"knownGene","uc001asp.2","chr1",11734537,11741495],[["uc001asr.1"],"knownGene","uc001asr.1","chr1",11751780,11780336],[["uc001ass.1"],"knownGene","uc001ass.1","chr1",11782186,11785914],[["uc001ast.2"],"knownGene","uc001ast.2","chr1",11796141,11810827],[["uc001asu.2"],"knownGene","uc001asu.2","chr1",11796141,11810827],[["uc001asv.2"],"knownGene","uc001asv.2","chr1",11796141,11810827],[["uc001asw.2"],"knownGene","uc001asw.2","chr1",11796141,11810827],[["uc001asx.2"],"knownGene","uc001asx.2","chr1",11796141,11810827],[["uc001asy.1"],"knownGene","uc001asy.1","chr1",11824461,11826573],[["uc001asz.2"],"knownGene","uc001asz.2","chr1",11832138,11849641],[["uc001ata.2"],"knownGene","uc001ata.2","chr1",11839858,11849641],[["uc001atc.1"],"knownGene","uc001atc.1","chr1",11845786,11866115],[["uc001atb.1"],"knownGene","uc001atb.1","chr1",11845786,11863440],[["uc001atd.1"],"knownGene","uc001atd.1","chr1",11862937,11865470],[["uc009vnd.1"],"knownGene","uc009vnd.1","chr1",11862937,11865470],[["uc001ate.3"],"knownGene","uc001ate.3","chr1",11866206,11903200],[["uc010oat.1"],"knownGene","uc010oat.1","chr1",11866206,11903200],[["uc010oau.1"],"knownGene","uc010oau.1","chr1",11866206,11903200],[["uc009vnh.1"],"knownGene","uc009vnh.1","chr1",11866206,11889379],[["uc009vnf.1"],"knownGene","uc009vnf.1","chr1",11866206,11888276],[["uc009vng.1"],"knownGene","uc009vng.1","chr1",11866206,11888276],[["uc009vne.1"],"knownGene","uc009vne.1","chr1",11866206,11876844],[["uc010oav.1"],"knownGene","uc010oav.1","chr1",11900375,11907674],[["uc010oaw.1"],"knownGene","uc010oaw.1","chr1",11900375,11907674],[["uc010oax.1"],"knownGene","uc010oax.1","chr1",11900375,11907674],[["uc010oay.1"],"knownGene","uc010oay.1","chr1",11900375,11907674],[["uc010oaz.1"],"knownGene","uc010oaz.1","chr1",11900375,11907674],[["uc010oba.1"],"knownGene","uc010oba.1","chr1",11900375,11907674],[["uc001ati.2"],"knownGene","uc001ati.2","chr1",11905768,11907840],[["uc001atj.2"],"knownGene","uc001atj.2","chr1",11917521,11918992],[["uc001atk.2"],"knownGene","uc001atk.2","chr1",11980123,11986480],[["uc001atl.1"],"knownGene","uc001atl.1","chr1",11982231,11986480],[["uc001atm.2"],"knownGene","uc001atm.2","chr1",11994745,12035593],[["uc010obb.1"],"knownGene","uc010obb.1","chr1",11994745,12035593],[["uc001atn.3"],"knownGene","uc001atn.3","chr1",12040237,12073571],[["uc009vni.2"],"knownGene","uc009vni.2","chr1",12040237,12073571],[["uc001ato.1"],"knownGene","uc001ato.1","chr1",12079511,12092106],[["uc001atq.2"],"knownGene","uc001atq.2","chr1",12123433,12204262],[["uc010obc.1"],"knownGene","uc010obc.1","chr1",12123433,12204262],[["uc001atr.2"],"knownGene","uc001atr.2","chr1",12185957,12204262],[["uc001ats.2"],"knownGene","uc001ats.2","chr1",12185957,12204262],[["uc001att.2"],"knownGene","uc001att.2","chr1",12227059,12269276],[["uc001atu.2"],"knownGene","uc001atu.2","chr1",12227059,12269276],[["uc009vnk.2"],"knownGene","uc009vnk.2","chr1",12227059,12269276],[["uc001atv.2"],"knownGene","uc001atv.2","chr1",12290112,12572096],[["uc001atw.2"],"knownGene","uc001atw.2","chr1",12290112,12572096],[["uc001atx.2"],"knownGene","uc001atx.2","chr1",12335881,12572096],[["uc001aty.1"],"knownGene","uc001aty.1","chr1",12371510,12398045],[["uc009vnl.2"],"knownGene","uc009vnl.2","chr1",12427724,12572096],[["uc010obd.1"],"knownGene","uc010obd.1","chr1",12469883,12572096],[["uc001atz.1"],"knownGene","uc001atz.1","chr1",12567299,12567451],[["uc001auc.2"],"knownGene","uc001auc.2","chr1",12627939,12677820],[["uc001aub.2"],"knownGene","uc001aub.2","chr1",12627939,12676788],[["uc009vnm.2"],"knownGene","uc009vnm.2","chr1",12638984,12677820],[["uc001aud.3"],"knownGene","uc001aud.3","chr1",12640134,12677820],[["uc001aue.1"],"knownGene","uc001aue.1","chr1",12640550,12656106],[["uc001auf.2"],"knownGene","uc001auf.2","chr1",12704565,12727096],[["uc009vnn.1"],"knownGene","uc009vnn.1","chr1",12776117,12788726],[["uc001aug.1"],"knownGene","uc001aug.1","chr1",12776117,12788726],[["uc001auh.2"],"knownGene","uc001auh.2","chr1",12806162,12821101],[["uc010obe.1"],"knownGene","uc010obe.1","chr1",12806162,12819698],[["uc001aui.2"],"knownGene","uc001aui.2","chr1",12834983,12838046],[["uc001auj.1"],"knownGene","uc001auj.1","chr1",12851545,12856223],[["uc001auk.2"],"knownGene","uc001auk.2","chr1",12884467,12891264],[["uc009vno.2"],"knownGene","uc009vno.2","chr1",12907235,12908237],[["uc010obf.1"],"knownGene","uc010obf.1","chr1",12907262,12908578],[["uc001aum.1"],"knownGene","uc001aum.1","chr1",12916940,12921764],[["uc001aun.2"],"knownGene","uc001aun.2","chr1",12939032,12946025],[["uc001auo.2"],"knownGene","uc001auo.2","chr1",12952727,12958094],[["uc001aup.2"],"knownGene","uc001aup.2","chr1",12976449,12980566],[["uc001aur.2"],"knownGene","uc001aur.2","chr1",12998301,13117751],[["uc001auq.2"],"knownGene","uc001auq.2","chr1",12998301,13007406],[["uc009vnq.1"],"knownGene","uc009vnq.1","chr1",13035542,13038381],[["uc001aus.1"],"knownGene","uc001aus.1","chr1",13108513,13117751],[["uc010obg.1"],"knownGene","uc010obg.1","chr1",13182960,13183967],[["uc001aut.1"],"knownGene","uc001aut.1","chr1",13328195,13331692],[["uc001auu.1"],"knownGene","uc001auu.1","chr1",13359818,13369057],[["uc001auv.2"],"knownGene","uc001auv.2","chr1",13386648,13390765],[["uc010obh.1"],"knownGene","uc010obh.1","chr1",13386648,13389770],[["uc001auw.1"],"knownGene","uc001auw.1","chr1",13421175,13428191],[["uc009vnt.1"],"knownGene","uc009vnt.1","chr1",13447413,13452656],[["uc010obi.1"],"knownGene","uc010obi.1","chr1",13447413,13452656],[["uc009vnu.1"],"knownGene","uc009vnu.1","chr1",13474052,13477569],[["uc001aux.2"],"knownGene","uc001aux.2","chr1",13495253,13498257],[["uc009vnv.1"],"knownGene","uc009vnv.1","chr1",13516065,13526943],[["uc001auy.2"],"knownGene","uc001auy.2","chr1",13607430,13611550],[["uc001auz.3"],"knownGene","uc001auz.3","chr1",13629937,13635298],[["uc001ava.1"],"knownGene","uc001ava.1","chr1",13641972,13648988],[["uc009vnw.1"],"knownGene","uc009vnw.1","chr1",13668268,13673511],[["uc009vny.1"],"knownGene","uc009vny.1","chr1",13694888,13698405],[["uc009vnz.1"],"knownGene","uc009vnz.1","chr1",13716087,13719064],[["uc009voa.1"],"knownGene","uc009voa.1","chr1",13736906,13747803],[["uc001avb.2"],"knownGene","uc001avb.2","chr1",13801446,13840242],[["uc001avc.2"],"knownGene","uc001avc.2","chr1",13910251,13944450],[["uc001avd.2"],"knownGene","uc001avd.2","chr1",13910251,13944450],[["uc009vob.2"],"knownGene","uc009vob.2","chr1",13910761,13944450],[["uc009voc.2"],"knownGene","uc009voc.2","chr1",13910761,13944450],[["uc001ave.2"],"knownGene","uc001ave.2","chr1",13911966,13944450],[["uc001avf.2"],"knownGene","uc001avf.2","chr1",13911966,13944450],[["uc001avg.2"],"knownGene","uc001avg.2","chr1",14026734,14151572],[["uc001avi.2"],"knownGene","uc001avi.2","chr1",14031349,14151572],[["uc001avh.2"],"knownGene","uc001avh.2","chr1",14031349,14114573],[["uc001avj.2"],"knownGene","uc001avj.2","chr1",14057494,14114573],[["uc009voe.2"],"knownGene","uc009voe.2","chr1",14075855,14151572],[["uc009vof.2"],"knownGene","uc009vof.2","chr1",14075855,14151572],[["uc001avk.2"],"knownGene","uc001avk.2","chr1",14075855,14114573],[["uc009vod.1"],"knownGene","uc009vod.1","chr1",14075855,14106820],[["uc001avl.1"],"knownGene","uc001avl.1","chr1",14146461,14150513],[["uc001avm.3"],"knownGene","uc001avm.3","chr1",14925212,15444543],[["uc009vog.1"],"knownGene","uc009vog.1","chr1",14925212,15394651],[["uc010obj.1"],"knownGene","uc010obj.1","chr1",14925212,15394651],[["uc001avo.2"],"knownGene","uc001avo.2","chr1",15250624,15394651],[["uc001avp.2"],"knownGene","uc001avp.2","chr1",15256295,15394651],[["uc001avq.2"],"knownGene","uc001avq.2","chr1",15272414,15394651],[["uc001avr.2"],"knownGene","uc001avr.2","chr1",15287179,15394651],[["uc001avs.3"],"knownGene","uc001avs.3","chr1",15427703,15444543],[["uc001avv.3"],"knownGene","uc001avv.3","chr1",15438311,15478960],[["uc009voh.2"],"knownGene","uc009voh.2","chr1",15438311,15478960],[["uc001avw.3"],"knownGene","uc001avw.3","chr1",15479027,15546973],[["uc010obk.1"],"knownGene","uc010obk.1","chr1",15479027,15546973],[["uc001avy.2"],"knownGene","uc001avy.2","chr1",15480228,15546973],[["uc001avx.2"],"knownGene","uc001avx.2","chr1",15480228,15546973],[["uc001avz.2"],"knownGene","uc001avz.2","chr1",15480228,15546872],[["uc001awb.2"],"knownGene","uc001awb.2","chr1",15573767,15724622],[["uc001awa.1"],"knownGene","uc001awa.1","chr1",15573767,15672019],[["uc001awc.1"],"knownGene","uc001awc.1","chr1",15653175,15670372],[["uc001awd.1"],"knownGene","uc001awd.1","chr1",15668231,15711054],[["uc010obl.1"],"knownGene","uc010obl.1","chr1",15671578,15724622],[["uc001awe.1"],"knownGene","uc001awe.1","chr1",15671911,15724622],[["uc001awf.2"],"knownGene","uc001awf.2","chr1",15684286,15690810],[["uc001awg.2"],"knownGene","uc001awg.2","chr1",15707196,15726776],[["uc001awh.2"],"knownGene","uc001awh.2","chr1",15736390,15756839],[["uc001awi.1"],"knownGene","uc001awi.1","chr1",15764937,15773153],[["uc001awj.1"],"knownGene","uc001awj.1","chr1",15764937,15773153],[["uc001awk.2"],"knownGene","uc001awk.2","chr1",15783222,15798585],[["uc001awl.2"],"knownGene","uc001awl.2","chr1",15802595,15817894],[["uc001awm.1"],"knownGene","uc001awm.1","chr1",15817323,15850790],[["uc001awq.2"],"knownGene","uc001awq.2","chr1",15818796,15851384],[["uc010obm.1"],"knownGene","uc010obm.1","chr1",15818796,15851221],[["uc001awn.2"],"knownGene","uc001awn.2","chr1",15818796,15850790],[["uc001awo.2"],"knownGene","uc001awo.2","chr1",15818796,15850790],[["uc001awp.2"],"knownGene","uc001awp.2","chr1",15818796,15850790],[["uc009voi.2"],"knownGene","uc009voi.2","chr1",15818796,15850790],[["uc001aws.2"],"knownGene","uc001aws.2","chr1",15853351,15898226],[["uc001awt.2"],"knownGene","uc001awt.2","chr1",15853351,15898226],[["uc001awr.1"],"knownGene","uc001awr.1","chr1",15853351,15893091],[["uc001awu.2"],"knownGene","uc001awu.2","chr1",15886020,15918872],[["uc001awv.1"],"knownGene","uc001awv.1","chr1",15899151,15911605],[["uc001awx.1"],"knownGene","uc001awx.1","chr1",15944069,15986748],[["uc001aww.2"],"knownGene","uc001aww.2","chr1",15944069,15960794],[["uc009voj.1"],"knownGene","uc009voj.1","chr1",15956819,15986748],[["uc010obn.1"],"knownGene","uc010obn.1","chr1",15986363,15988216],[["uc001awz.2"],"knownGene","uc001awz.2","chr1",15992765,15995535],[["uc010obo.1"],"knownGene","uc010obo.1","chr1",16010826,16061262],[["uc001axb.1"],"knownGene","uc001axb.1","chr1",16062808,16067884],[["uc009vok.1"],"knownGene","uc009vok.1","chr1",16065739,16067885],[["uc001axc.2"],"knownGene","uc001axc.2","chr1",16068916,16074475],[["uc001axd.1"],"knownGene","uc001axd.1","chr1",16083153,16113084],[["uc001axf.2"],"knownGene","uc001axf.2","chr1",16085254,16114431],[["uc001axe.1"],"knownGene","uc001axe.1","chr1",16085254,16113084],[["uc001axg.1"],"knownGene","uc001axg.1","chr1",16090990,16101715],[["uc001axh.1"],"knownGene","uc001axh.1","chr1",16091029,16113084],[["uc001axi.1"],"knownGene","uc001axi.1","chr1",16091458,16113084],[["uc009vol.1"],"knownGene","uc009vol.1","chr1",16133656,16134194],[["uc001axj.2"],"knownGene","uc001axj.2","chr1",16160709,16174642],[["uc001axk.1"],"knownGene","uc001axk.1","chr1",16174358,16266950],[["uc010obp.1"],"knownGene","uc010obp.1","chr1",16200609,16266950],[["uc001axl.3"],"knownGene","uc001axl.3","chr1",16268365,16302627],[["uc010obq.1"],"knownGene","uc010obq.1","chr1",16268365,16302627],[["uc010obr.1"],"knownGene","uc010obr.1","chr1",16268365,16302627],[["uc010obs.1"],"knownGene","uc010obs.1","chr1",16268365,16302627],[["uc010obt.1"],"knownGene","uc010obt.1","chr1",16270321,16302627],[["uc010obu.1"],"knownGene","uc010obu.1","chr1",16270365,16302627],[["uc009vom.1"],"knownGene","uc009vom.1","chr1",16271431,16302627],[["uc010obv.1"],"knownGene","uc010obv.1","chr1",16272256,16302627],[["uc009von.1"],"knownGene","uc009von.1","chr1",16274237,16302627],[["uc001axm.1"],"knownGene","uc001axm.1","chr1",16317618,16317647],[["uc001axn.2"],"knownGene","uc001axn.2","chr1",16330730,16333180],[["uc001axs.2"],"knownGene","uc001axs.2","chr1",16340522,16346089],[["uc001axo.2"],"knownGene","uc001axo.2","chr1",16340522,16345285],[["uc001axp.2"],"knownGene","uc001axp.2","chr1",16340522,16345285],[["uc001axq.2"],"knownGene","uc001axq.2","chr1",16340522,16345285],[["uc001axr.2"],"knownGene","uc001axr.2","chr1",16340522,16345285],[["uc001axt.2"],"knownGene","uc001axt.2","chr1",16345369,16360544],[["uc001axw.3"],"knownGene","uc001axw.3","chr1",16348485,16383802],[["uc001axu.2"],"knownGene","uc001axu.2","chr1",16348485,16360544],[["uc001axv.2"],"knownGene","uc001axv.2","chr1",16348485,16360544],[["uc010obw.1"],"knownGene","uc010obw.1","chr1",16348485,16360544],[["uc010oby.1"],"knownGene","uc010oby.1","chr1",16355006,16358786],[["uc010obx.1"],"knownGene","uc010obx.1","chr1",16355006,16357169],[["uc010obz.1"],"knownGene","uc010obz.1","chr1",16361813,16400127],[["uc001axx.3"],"knownGene","uc001axx.3","chr1",16370246,16383802],[["uc001axy.3"],"knownGene","uc001axy.3","chr1",16375283,16383802],[["uc001axz.3"],"knownGene","uc001axz.3","chr1",16384264,16400127],[["uc001aya.1"],"knownGene","uc001aya.1","chr1",16450831,16482564],[["uc010oca.1"],"knownGene","uc010oca.1","chr1",16462083,16482564],[["uc001ayc.1"],"knownGene","uc001ayc.1","chr1",16524598,16539104],[["uc009voo.1"],"knownGene","uc009voo.1","chr1",16524598,16533705],[["uc001ayb.1"],"knownGene","uc001ayb.1","chr1",16524598,16533705],[["uc001ayd.2"],"knownGene","uc001ayd.2","chr1",16558182,16563659],[["uc001ayg.2"],"knownGene","uc001ayg.2","chr1",16576559,16678948],[["uc001ayf.2"],"knownGene","uc001ayf.2","chr1",16576559,16643088],[["uc001aye.3"],"knownGene","uc001aye.3","chr1",16576559,16580226],[["uc001ayh.2"],"knownGene","uc001ayh.2","chr1",16618833,16641930],[["uc001aym.3"],"knownGene","uc001aym.3","chr1",16693582,16724639],[["uc001ayi.3"],"knownGene","uc001ayi.3","chr1",16693582,16724639],[["uc001ayk.3"],"knownGene","uc001ayk.3","chr1",16693582,16724639],[["uc010ocb.1"],"knownGene","uc010ocb.1","chr1",16693582,16722607],[["uc001ayl.1"],"knownGene","uc001ayl.1","chr1",16722175,16763919],[["uc001ayn.2"],"knownGene","uc001ayn.2","chr1",16725138,16763919],[["uc010occ.1"],"knownGene","uc010occ.1","chr1",16725138,16763919],[["uc001ayo.2"],"knownGene","uc001ayo.2","chr1",16767166,16786582],[["uc010ocd.1"],"knownGene","uc010ocd.1","chr1",16767166,16786582],[["uc001ayq.2"],"knownGene","uc001ayq.2","chr1",16767166,16786582],[["uc001ayp.3"],"knownGene","uc001ayp.3","chr1",16767166,16786572],[["uc001ayt.2"],"knownGene","uc001ayt.2","chr1",16793930,16819196],[["uc001ayr.3"],"knownGene","uc001ayr.3","chr1",16795417,16803569],[["uc001ays.2"],"knownGene","uc001ays.2","chr1",16804749,16817579],[["uc009voq.1"],"knownGene","uc009voq.1","chr1",16860385,16863483],[["uc001ayv.1"],"knownGene","uc001ayv.1","chr1",16862254,16864669],[["uc001ayw.2"],"knownGene","uc001ayw.2","chr1",16888922,16890082],[["uc009vos.1"],"knownGene","uc009vos.1","chr1",16890411,16939982],[["uc009vot.1"],"knownGene","uc009vot.1","chr1",16892902,16913756],[["uc001ayz.1"],"knownGene","uc001ayz.1","chr1",16892902,16913756],[["uc010oce.1"],"knownGene","uc010oce.1","chr1",16893673,16918808],[["uc001aza.3"],"knownGene","uc001aza.3","chr1",16926097,16939982],[["uc001azc.1"],"knownGene","uc001azc.1","chr1",16931912,16939982],[["uc001azb.1"],"knownGene","uc001azb.1","chr1",16931912,16939752],[["uc009vov.1"],"knownGene","uc009vov.1","chr1",16944752,16957604],[["uc001aze.2"],"knownGene","uc001aze.2","chr1",16944752,16957604],[["uc010ocf.1"],"knownGene","uc010ocf.1","chr1",16944752,16952994],[["uc001azf.2"],"knownGene","uc001azf.2","chr1",16944757,16959841],[["uc001azg.1"],"knownGene","uc001azg.1","chr1",16951872,16971178],[["uc001azi.1"],"knownGene","uc001azi.1","chr1",16956164,16971178],[["uc001azj.1"],"knownGene","uc001azj.1","chr1",16959589,16969640],[["uc010och.1"],"knownGene","uc010och.1","chr1",16972068,16976914],[["uc009vow.2"],"knownGene","uc009vow.2","chr1",16972068,16974587],[["uc010ocg.1"],"knownGene","uc010ocg.1","chr1",16972068,16974587],[["uc001azl.3"],"knownGene","uc001azl.3","chr1",16972863,16976914],[["uc001azk.2"],"knownGene","uc001azk.2","chr1",16972863,16975287],[["uc010oci.1"],"knownGene","uc010oci.1","chr1",16972863,16974587],[["uc009vox.2"],"knownGene","uc009vox.2","chr1",16973907,16976914],[["uc001azm.3"],"knownGene","uc001azm.3","chr1",16973907,16976914],[["uc001azn.1"],"knownGene","uc001azn.1","chr1",17017712,17046652],[["uc010ocj.1"],"knownGene","uc010ocj.1","chr1",17033418,17037114],[["uc009voy.1"],"knownGene","uc009voy.1","chr1",17066767,17267729],[["uc010ock.1"],"knownGene","uc010ock.1","chr1",17081401,17090975],[["uc001azp.3"],"knownGene","uc001azp.3","chr1",17081401,17086552],[["uc001azs.1"],"knownGene","uc001azs.1","chr1",17215040,17216161],[["uc001azt.2"],"knownGene","uc001azt.2","chr1",17248444,17299474],[["uc009voz.1"],"knownGene","uc009voz.1","chr1",17249157,17280852],[["uc001azu.2"],"knownGene","uc001azu.2","chr1",17266388,17299474],[["uc001azv.2"],"knownGene","uc001azv.2","chr1",17294697,17299474],[["uc001azy.2"],"knownGene","uc001azy.2","chr1",17300999,17308081],[["uc010ocl.1"],"knownGene","uc010ocl.1","chr1",17300999,17308081],[["uc001azw.2"],"knownGene","uc001azw.2","chr1",17300999,17307173],[["uc001azx.2"],"knownGene","uc001azx.2","chr1",17300999,17307173],[["uc001baa.2"],"knownGene","uc001baa.2","chr1",17312452,17338423],[["uc001bab.2"],"knownGene","uc001bab.2","chr1",17312452,17338423],[["uc001bac.2"],"knownGene","uc001bac.2","chr1",17312452,17338423],[["uc001azz.1"],"knownGene","uc001azz.1","chr1",17312452,17316498],[["uc001bad.1"],"knownGene","uc001bad.1","chr1",17321981,17327342],[["uc009vpa.1"],"knownGene","uc009vpa.1","chr1",17321981,17326807],[["uc001bae.2"],"knownGene","uc001bae.2","chr1",17345226,17380665],[["uc001baf.2"],"knownGene","uc001baf.2","chr1",17393256,17445948],[["uc010ocm.1"],"knownGene","uc010ocm.1","chr1",17393256,17445948],[["uc001bag.1"],"knownGene","uc001bag.1","chr1",17405525,17445948],[["uc010ocn.1"],"knownGene","uc010ocn.1","chr1",17439786,17439808],[["uc001bah.1"],"knownGene","uc001bah.1","chr1",17531620,17572501],[["uc010oco.1"],"knownGene","uc010oco.1","chr1",17559775,17572501],[["uc010ocp.1"],"knownGene","uc010ocp.1","chr1",17559775,17572501],[["uc010ocq.1"],"knownGene","uc010ocq.1","chr1",17559775,17572501],[["uc009vpb.1"],"knownGene","uc009vpb.1","chr1",17566189,17572501],[["uc001bai.2"],"knownGene","uc001bai.2","chr1",17575592,17610725],[["uc001baj.2"],"knownGene","uc001baj.2","chr1",17634689,17690495],[["uc009vpc.2"],"knownGene","uc009vpc.2","chr1",17634689,17674911],[["uc001bak.1"],"knownGene","uc001bak.1","chr1",17698740,17728195],[["uc001bam.2"],"knownGene","uc001bam.2","chr1",17733251,17766220],[["uc001bal.2"],"knownGene","uc001bal.2","chr1",17733251,17765057],[["uc001ban.2"],"knownGene","uc001ban.2","chr1",17866329,18024369],[["uc009vpe.1"],"knownGene","uc009vpe.1","chr1",17866329,18016673],[["uc001bao.2"],"knownGene","uc001bao.2","chr1",17907047,18024369],[["uc001bap.2"],"knownGene","uc001bap.2","chr1",17907047,18024369],[["uc010ocr.1"],"knownGene","uc010ocr.1","chr1",17914910,17966476],[["uc001baq.2"],"knownGene","uc001baq.2","chr1",17941582,18024369],[["uc010ocs.1"],"knownGene","uc010ocs.1","chr1",17944810,18024369],[["uc001bar.2"],"knownGene","uc001bar.2","chr1",17944810,18024369],[["uc009vpf.2"],"knownGene","uc009vpf.2","chr1",17952450,18024369],[["uc001bas.2"],"knownGene","uc001bas.2","chr1",18020541,18024369],[["uc001bat.2"],"knownGene","uc001bat.2","chr1",18081807,18153556],[["uc001bau.1"],"knownGene","uc001bau.1","chr1",18434239,18704976],[["uc001bav.1"],"knownGene","uc001bav.1","chr1",18687860,18704976],[["uc001baw.1"],"knownGene","uc001baw.1","chr1",18701063,18702174],[["uc001bax.2"],"knownGene","uc001bax.2","chr1",18807423,18812478],[["uc009vpg.2"],"knownGene","uc009vpg.2","chr1",18807664,18812539],[["uc010oct.1"],"knownGene","uc010oct.1","chr1",18957499,19075359],[["uc001bay.2"],"knownGene","uc001bay.2","chr1",18957499,19062631],[["uc001baz.2"],"knownGene","uc001baz.2","chr1",18957499,19062631],[["uc001bba.1"],"knownGene","uc001bba.1","chr1",19166092,19186155],[["uc001bbb.2"],"knownGene","uc001bbb.2","chr1",19197925,19229293],[["uc001bbc.2"],"knownGene","uc001bbc.2","chr1",19197925,19229293],[["uc010ocu.1"],"knownGene","uc010ocu.1","chr1",19197925,19217385],[["uc001bbd.2"],"knownGene","uc001bbd.2","chr1",19230773,19282826],[["uc001bbe.1"],"knownGene","uc001bbe.1","chr1",19398603,19402005],[["uc001bbi.2"],"knownGene","uc001bbi.2","chr1",19401001,19536746],[["uc001bbh.2"],"knownGene","uc001bbh.2","chr1",19401001,19432336],[["uc001bbg.2"],"knownGene","uc001bbg.2","chr1",19401001,19431410],[["uc010ocw.1"],"knownGene","uc010ocw.1","chr1",19401001,19428129],[["uc009vph.2"],"knownGene","uc009vph.2","chr1",19401001,19427067],[["uc010ocv.1"],"knownGene","uc010ocv.1","chr1",19401001,19426171],[["uc001bbf.2"],"knownGene","uc001bbf.2","chr1",19401001,19408140],[["uc001bbj.1"],"knownGene","uc001bbj.1","chr1",19438133,19444474],[["uc001bbk.1"],"knownGene","uc001bbk.1","chr1",19447682,19478353],[["uc001bbm.1"],"knownGene","uc001bbm.1","chr1",19477417,19505714],[["uc001bbl.1"],"knownGene","uc001bbl.1","chr1",19477417,19483419],[["uc001bbo.2"],"knownGene","uc001bbo.2","chr1",19544584,19578046],[["uc001bbp.2"],"knownGene","uc001bbp.2","chr1",19544584,19578046],[["uc001bbq.2"],"knownGene","uc001bbq.2","chr1",19544584,19578046],[["uc001bbr.2"],"knownGene","uc001bbr.2","chr1",19544584,19578046],[["uc001bbn.2"],"knownGene","uc001bbn.2","chr1",19544584,19548410],[["uc001bbs.2"],"knownGene","uc001bbs.2","chr1",19578074,19586621],[["uc010ocx.1"],"knownGene","uc010ocx.1","chr1",19592475,19600568],[["uc010ocy.1"],"knownGene","uc010ocy.1","chr1",19592475,19600568],[["uc001bbv.1"],"knownGene","uc001bbv.1","chr1",19609056,19615280],[["uc001bbw.2"],"knownGene","uc001bbw.2","chr1",19630458,19638640],[["uc001bbx.2"],"knownGene","uc001bbx.2","chr1",19630458,19638640],[["uc009vpi.1"],"knownGene","uc009vpi.1","chr1",19634232,19638640],[["uc001bby.2"],"knownGene","uc001bby.2","chr1",19638739,19655793],[["uc001bbz.2"],"knownGene","uc001bbz.2","chr1",19638739,19655793],[["uc001bca.2"],"knownGene","uc001bca.2","chr1",19638739,19655793],[["uc001bcb.2"],"knownGene","uc001bcb.2","chr1",19638739,19655793],[["uc001bcc.2"],"knownGene","uc001bcc.2","chr1",19639222,19655793],[["uc001bce.2"],"knownGene","uc001bce.2","chr1",19665273,19811992],[["uc009vpk.2"],"knownGene","uc009vpk.2","chr1",19665273,19811992],[["uc010ocz.1"],"knownGene","uc010ocz.1","chr1",19665273,19811201],[["uc001bcd.2"],"knownGene","uc001bcd.2","chr1",19665273,19746253],[["uc001bcf.1"],"knownGene","uc001bcf.1","chr1",19673334,19675427],[["uc009vpl.1"],"knownGene","uc009vpl.1","chr1",19923466,19984945],[["uc001bci.1"],"knownGene","uc001bci.1","chr1",19923466,19955174],[["uc001bch.1"],"knownGene","uc001bch.1","chr1",19923466,19954804],[["uc001bcj.1"],"knownGene","uc001bcj.1","chr1",19969725,19984945],[["uc009vpm.1"],"knownGene","uc009vpm.1","chr1",19970248,19984945],[["uc001bck.1"],"knownGene","uc001bck.1","chr1",19970807,19984945],[["uc001bcl.2"],"knownGene","uc001bcl.2","chr1",19991779,20006054],[["uc001bcn.2"],"knownGene","uc001bcn.2","chr1",20008706,20126410],[["uc001bcm.2"],"knownGene","uc001bcm.2","chr1",20008706,20107259],[["uc001bco.1"],"knownGene","uc001bco.1","chr1",20008734,20125837],[["uc001bcp.1"],"knownGene","uc001bcp.1","chr1",20008734,20125837],[["uc009vpn.1"],"knownGene","uc009vpn.1","chr1",20071536,20125837],[["uc001bcq.1"],"knownGene","uc001bcq.1","chr1",20072024,20126758],[["uc001bcr.2"],"knownGene","uc001bcr.2","chr1",20140522,20141771],[["uc001bcs.3"],"knownGene","uc001bcs.3","chr1",20208887,20239429],[["uc001bct.1"],"knownGene","uc001bct.1","chr1",20246799,20250110],[["uc001bcv.2"],"knownGene","uc001bcv.2","chr1",20301924,20306932],[["uc010oda.1"],"knownGene","uc010oda.1","chr1",20301924,20306932],[["uc010odb.1"],"knownGene","uc010odb.1","chr1",20301924,20306932],[["uc001bcu.2"],"knownGene","uc001bcu.2","chr1",20301924,20306152],[["uc001bcw.2"],"knownGene","uc001bcw.2","chr1",20354671,20418393],[["uc001bcx.2"],"knownGene","uc001bcx.2","chr1",20354671,20418393],[["uc001bcy.2"],"knownGene","uc001bcy.2","chr1",20396700,20418393],[["uc001bcz.2"],"knownGene","uc001bcz.2","chr1",20438440,20446008],[["uc009vpo.2"],"knownGene","uc009vpo.2","chr1",20438440,20446008],[["uc009vpp.1"],"knownGene","uc009vpp.1","chr1",20465822,20476879],[["uc009vpq.1"],"knownGene","uc009vpq.1","chr1",20490483,20501687],[["uc001bdb.2"],"knownGene","uc001bdb.2","chr1",20512577,20519941],[["uc009vps.2"],"knownGene","uc009vps.2","chr1",20617411,20681387],[["uc010odc.1"],"knownGene","uc010odc.1","chr1",20617411,20681387],[["uc001bdd.2"],"knownGene","uc001bdd.2","chr1",20617411,20665715],[["uc001bde.3"],"knownGene","uc001bde.3","chr1",20659258,20681387],[["uc009vpt.2"],"knownGene","uc009vpt.2","chr1",20659258,20681387],[["uc001bdf.1"],"knownGene","uc001bdf.1","chr1",20687597,20755275],[["uc009vpu.1"],"knownGene","uc009vpu.1","chr1",20687597,20732187],[["uc001bdh.2"],"knownGene","uc001bdh.2","chr1",20808884,20812728],[["uc001bdg.2"],"knownGene","uc001bdg.2","chr1",20808884,20811138],[["uc001bdi.3"],"knownGene","uc001bdi.3","chr1",20825942,20834674],[["uc001bdj.2"],"knownGene","uc001bdj.2","chr1",20878931,20881512],[["uc001bdk.2"],"knownGene","uc001bdk.2","chr1",20915443,20945398],[["uc001bdl.2"],"knownGene","uc001bdl.2","chr1",20915443,20945398],[["uc009vpv.2"],"knownGene","uc009vpv.2","chr1",20915443,20945398],[["uc001bdm.2"],"knownGene","uc001bdm.2","chr1",20959947,20978003],[["uc001bdn.2"],"knownGene","uc001bdn.2","chr1",20972000,20978003],[["uc001bdo.1"],"knownGene","uc001bdo.1","chr1",20978259,20988037],[["uc009vpw.1"],"knownGene","uc009vpw.1","chr1",20978259,20988037],[["uc010odd.1"],"knownGene","uc010odd.1","chr1",20978259,20988037],[["uc010ode.1"],"knownGene","uc010ode.1","chr1",20978259,20988037],[["uc001bds.3"],"knownGene","uc001bds.3","chr1",20990508,21044317],[["uc001bdr.3"],"knownGene","uc001bdr.3","chr1",20990508,21044317],[["uc009vpx.2"],"knownGene","uc009vpx.2","chr1",20990508,21024981],[["uc001bdq.3"],"knownGene","uc001bdq.3","chr1",20990508,21011776],[["uc001bdp.3"],"knownGene","uc001bdp.3","chr1",20990508,21011689],[["uc001bdu.1"],"knownGene","uc001bdu.1","chr1",21046224,21059330],[["uc009vpy.1"],"knownGene","uc009vpy.1","chr1",21046224,21059133],[["uc001bdt.1"],"knownGene","uc001bdt.1","chr1",21046224,21059133],[["uc010odh.1"],"knownGene","uc010odh.1","chr1",21069170,21113799],[["uc001bdw.1"],"knownGene","uc001bdw.1","chr1",21069170,21113181],[["uc001bdv.1"],"knownGene","uc001bdv.1","chr1",21069170,21113124],[["uc010odg.1"],"knownGene","uc010odg.1","chr1",21069170,21101447],[["uc010odf.1"],"knownGene","uc010odf.1","chr1",21069170,21092024],[["uc001bdy.1"],"knownGene","uc001bdy.1","chr1",21069622,21107033],[["uc001bdz.2"],"knownGene","uc001bdz.2","chr1",21080550,21113799],[["uc001bea.2"],"knownGene","uc001bea.2","chr1",21080550,21113799],[["uc001beb.2"],"knownGene","uc001beb.2","chr1",21102148,21113133],[["uc001bed.2"],"knownGene","uc001bed.2","chr1",21132975,21503340],[["uc001bef.2"],"knownGene","uc001bef.2","chr1",21132975,21503340],[["uc001bee.2"],"knownGene","uc001bee.2","chr1",21132975,21503340],[["uc001bec.2"],"knownGene","uc001bec.2","chr1",21132975,21437876],[["uc010odj.1"],"knownGene","uc010odj.1","chr1",21132975,21377487],[["uc009vpz.2"],"knownGene","uc009vpz.2","chr1",21132975,21377487],[["uc010odi.1"],"knownGene","uc010odi.1","chr1",21132975,21299592],[["uc001beh.2"],"knownGene","uc001beh.2","chr1",21267739,21494532],[["uc010odk.1"],"knownGene","uc010odk.1","chr1",21267739,21415706],[["uc001beg.2"],"knownGene","uc001beg.2","chr1",21267739,21377487],[["uc001bem.2"],"knownGene","uc001bem.2","chr1",21543739,21672034],[["uc001bek.2"],"knownGene","uc001bek.2","chr1",21543739,21616982],[["uc010odl.1"],"knownGene","uc010odl.1","chr1",21543739,21616982],[["uc001bei.2"],"knownGene","uc001bei.2","chr1",21543739,21616766],[["uc001bej.2"],"knownGene","uc001bej.2","chr1",21543739,21606183],[["uc009vqa.1"],"knownGene","uc009vqa.1","chr1",21559597,21616982],[["uc001ben.1"],"knownGene","uc001ben.1","chr1",21602542,21604868],[["uc001beo.1"],"knownGene","uc001beo.1","chr1",21619782,21626225],[["uc001bep.1"],"knownGene","uc001bep.1","chr1",21749600,21754300],[["uc001beq.1"],"knownGene","uc001beq.1","chr1",21761832,21762609],[["uc001ber.2"],"knownGene","uc001ber.2","chr1",21766630,21811392],[["uc001bes.2"],"knownGene","uc001bes.2","chr1",21766630,21811392],[["uc009vqb.2"],"knownGene","uc009vqb.2","chr1",21766630,21811392],[["uc010odm.1"],"knownGene","uc010odm.1","chr1",21766630,21811392],[["uc001bet.2"],"knownGene","uc001bet.2","chr1",21835857,21904904],[["uc010odn.1"],"knownGene","uc010odn.1","chr1",21835857,21904904],[["uc010odo.1"],"knownGene","uc010odo.1","chr1",21835857,21904904],[["uc010odp.1"],"knownGene","uc010odp.1","chr1",21835857,21904904],[["uc001beu.3"],"knownGene","uc001beu.3","chr1",21877806,21904904],[["uc001bey.2"],"knownGene","uc001bey.2","chr1",21922708,21995856],[["uc001bex.2"],"knownGene","uc001bex.2","chr1",21922708,21995856],[["uc001bew.2"],"knownGene","uc001bew.2","chr1",21922708,21978348],[["uc001bev.2"],"knownGene","uc001bev.2","chr1",21922708,21946543],[["uc001bez.1"],"knownGene","uc001bez.1","chr1",21943798,21949011],[["uc001bfb.2"],"knownGene","uc001bfb.2","chr1",22004793,22109688],[["uc010odq.1"],"knownGene","uc010odq.1","chr1",22004793,22109688],[["uc009vqc.2"],"knownGene","uc009vqc.2","chr1",22004793,22109688],[["uc001bfc.2"],"knownGene","uc001bfc.2","chr1",22004793,22109688],[["uc001bfa.2"],"knownGene","uc001bfa.2","chr1",22004793,22051612],[["uc001bfd.1"],"knownGene","uc001bfd.1","chr1",22012384,22031108],[["uc001bfe.1"],"knownGene","uc001bfe.1","chr1",22047528,22109688],[["uc001bff.2"],"knownGene","uc001bff.2","chr1",22054339,22109688],[["uc001bfg.1"],"knownGene","uc001bfg.1","chr1",22138757,22151714],[["uc001bfh.1"],"knownGene","uc001bfh.1","chr1",22147942,22149041],[["uc001bfj.2"],"knownGene","uc001bfj.2","chr1",22148737,22263750],[["uc009vqd.2"],"knownGene","uc009vqd.2","chr1",22148737,22263750],[["uc001bfi.2"],"knownGene","uc001bfi.2","chr1",22148737,22157206],[["uc009vqe.1"],"knownGene","uc009vqe.1","chr1",22213707,22222803],[["uc009vqf.2"],"knownGene","uc009vqf.2","chr1",22303417,22333140],[["uc001bfk.2"],"knownGene","uc001bfk.2","chr1",22303417,22315845],[["uc001bfl.2"],"knownGene","uc001bfl.2","chr1",22328148,22339033],[["uc001bfm.3"],"knownGene","uc001bfm.3","chr1",22351706,22357713],[["uc001bfn.3"],"knownGene","uc001bfn.3","chr1",22352041,22357713],[["uc001bfq.2"],"knownGene","uc001bfq.2","chr1",22379119,22419435],[["uc001bfr.2"],"knownGene","uc001bfr.2","chr1",22379119,22419435],[["uc010odr.1"],"knownGene","uc010odr.1","chr1",22379119,22419435],[["uc010ods.1"],"knownGene","uc010ods.1","chr1",22379119,22419435],[["uc009vqh.2"],"knownGene","uc009vqh.2","chr1",22379119,22419435],[["uc001bfp.2"],"knownGene","uc001bfp.2","chr1",22379119,22417295],[["uc009vqg.1"],"knownGene","uc009vqg.1","chr1",22379119,22413359],[["uc010odt.1"],"knownGene","uc010odt.1","chr1",22443799,22470385],[["uc001bfs.3"],"knownGene","uc001bfs.3","chr1",22443799,22469519],[["uc001bft.2"],"knownGene","uc001bft.2","chr1",22778343,22857650],[["uc001bfu.2"],"knownGene","uc001bfu.2","chr1",22778343,22857650],[["uc009vqi.1"],"knownGene","uc009vqi.1","chr1",22778343,22857650],[["uc001bfv.1"],"knownGene","uc001bfv.1","chr1",22828068,22838627],[["uc001bfx.1"],"knownGene","uc001bfx.1","chr1",22890003,22930087],[["uc001bfw.2"],"knownGene","uc001bfw.2","chr1",22890003,22916103],[["uc001bfy.2"],"knownGene","uc001bfy.2","chr1",22963117,22966174],[["uc001bfz.2"],"knownGene","uc001bfz.2","chr1",22964072,22966174],[["uc001bgc.3"],"knownGene","uc001bgc.3","chr1",22970117,22974602],[["uc001bga.3"],"knownGene","uc001bga.3","chr1",22970117,22974602],[["uc001bgb.2"],"knownGene","uc001bgb.2","chr1",22970145,22974602],[["uc001bgd.2"],"knownGene","uc001bgd.2","chr1",22979681,22988028],[["uc001bge.2"],"knownGene","uc001bge.2","chr1",23037330,23241822],[["uc001bgf.2"],"knownGene","uc001bgf.2","chr1",23037330,23241822],[["uc009vqj.1"],"knownGene","uc009vqj.1","chr1",23037330,23241082],[["uc010odu.1"],"knownGene","uc010odu.1","chr1",23037331,23241822],[["uc001bgg.1"],"knownGene","uc001bgg.1","chr1",23243782,23247347],[["uc001bgh.1"],"knownGene","uc001bgh.1","chr1",23337326,23342343],[["uc001bgj.2"],"knownGene","uc001bgj.2","chr1",23345940,23410184],[["uc001bgi.2"],"knownGene","uc001bgi.2","chr1",23345940,23410184],[["uc001bgk.2"],"knownGene","uc001bgk.2","chr1",23410515,23495517],[["uc010odv.1"],"knownGene","uc010odv.1","chr1",23410515,23495517],[["uc001bgl.2"],"knownGene","uc001bgl.2","chr1",23416920,23495517],[["uc001bgm.1"],"knownGene","uc001bgm.1","chr1",23417682,23504301],[["uc001bgn.2"],"knownGene","uc001bgn.2","chr1",23518388,23521222],[["uc001bgp.3"],"knownGene","uc001bgp.3","chr1",23636276,23670853],[["uc001bgr.3"],"knownGene","uc001bgr.3","chr1",23636276,23670853],[["uc009vqk.2"],"knownGene","uc009vqk.2","chr1",23636276,23670853],[["uc001bgs.3"],"knownGene","uc001bgs.3","chr1",23636276,23670853],[["uc010odw.1"],"knownGene","uc010odw.1","chr1",23636276,23670853],[["uc010odx.1"],"knownGene","uc010odx.1","chr1",23636276,23670853],[["uc009vql.2"],"knownGene","uc009vql.2","chr1",23636276,23670853],[["uc001bgo.2"],"knownGene","uc001bgo.2","chr1",23636276,23638386],[["uc001bgu.2"],"knownGene","uc001bgu.2","chr1",23685941,23696357],[["uc001bgt.2"],"knownGene","uc001bgt.2","chr1",23685941,23694879],[["uc001bgv.2"],"knownGene","uc001bgv.2","chr1",23695463,23698278],[["uc001bgw.2"],"knownGene","uc001bgw.2","chr1",23695463,23698278],[["uc001bgx.1"],"knownGene","uc001bgx.1","chr1",23707554,23751261],[["uc009vqm.1"],"knownGene","uc009vqm.1","chr1",23710670,23720524],[["uc009vqn.1"],"knownGene","uc009vqn.1","chr1",23724035,23751261],[["uc010ody.1"],"knownGene","uc010ody.1","chr1",23735156,23751261],[["uc001bha.2"],"knownGene","uc001bha.2","chr1",23755055,23810750],[["uc010oea.1"],"knownGene","uc010oea.1","chr1",23755055,23810750],[["uc010odz.1"],"knownGene","uc010odz.1","chr1",23755055,23810677],[["uc001bgz.1"],"knownGene","uc001bgz.1","chr1",23755055,23763537],[["uc001bgy.1"],"knownGene","uc001bgy.1","chr1",23755055,23763170],[["uc001bhb.2"],"knownGene","uc001bhb.2","chr1",23755059,23765723],[["uc001bhc.1"],"knownGene","uc001bhc.1","chr1",23768993,23811057],[["uc001bhd.2"],"knownGene","uc001bhd.2","chr1",23801094,23803135],[["uc001bhe.1"],"knownGene","uc001bhe.1","chr1",23832921,23857713],[["uc001bhf.1"],"knownGene","uc001bhf.1","chr1",23853364,23855542],[["uc001bhh.3"],"knownGene","uc001bhh.3","chr1",23884409,23886322],[["uc001bhg.1"],"knownGene","uc001bhg.1","chr1",23884431,23885978],[["uc001bhi.3"],"knownGene","uc001bhi.3","chr1",23907984,23967056],[["uc001bhj.3"],"knownGene","uc001bhj.3","chr1",23953225,23967056],[["uc001bhk.2"],"knownGene","uc001bhk.2","chr1",24018293,24022913],[["uc001bhl.2"],"knownGene","uc001bhl.2","chr1",24018293,24022913],[["uc001bhm.2"],"knownGene","uc001bhm.2","chr1",24019085,24022913],[["uc001bhn.1"],"knownGene","uc001bhn.1","chr1",24019101,24022869],[["uc001bho.2"],"knownGene","uc001bho.2","chr1",24069855,24088548],[["uc001bhp.1"],"knownGene","uc001bhp.1","chr1",24086871,24104777],[["uc001bhq.2"],"knownGene","uc001bhq.2","chr1",24104875,24114720],[["uc010oeb.1"],"knownGene","uc010oeb.1","chr1",24104875,24114720],[["uc001bht.2"],"knownGene","uc001bht.2","chr1",24117645,24122027],[["uc001bhu.2"],"knownGene","uc001bhu.2","chr1",24117645,24122027],[["uc001bhs.1"],"knownGene","uc001bhs.1","chr1",24117645,24122025],[["uc001bhr.2"],"knownGene","uc001bhr.2","chr1",24117645,24122010],[["uc001bhx.1"],"knownGene","uc001bhx.1","chr1",24122088,24127294],[["uc009vqp.1"],"knownGene","uc009vqp.1","chr1",24122088,24127294],[["uc001bhy.1"],"knownGene","uc001bhy.1","chr1",24122088,24127294],[["uc001bhz.1"],"knownGene","uc001bhz.1","chr1",24122088,24127294],[["uc001bhv.1"],"knownGene","uc001bhv.1","chr1",24122088,24127034],[["uc001bhw.1"],"knownGene","uc001bhw.1","chr1",24122088,24127034],[["uc009vqo.1"],"knownGene","uc009vqo.1","chr1",24122088,24126060],[["uc001bia.2"],"knownGene","uc001bia.2","chr1",24122209,24123637],[["uc009vqq.1"],"knownGene","uc009vqq.1","chr1",24124576,24127294],[["uc001bic.2"],"knownGene","uc001bic.2","chr1",24128367,24165110],[["uc001bib.2"],"knownGene","uc001bib.2","chr1",24128367,24151949],[["uc010oec.1"],"knownGene","uc010oec.1","chr1",24128367,24151949],[["uc009vqr.2"],"knownGene","uc009vqr.2","chr1",24128367,24151949],[["uc009vqs.1"],"knownGene","uc009vqs.1","chr1",24130077,24151949],[["uc001bid.1"],"knownGene","uc001bid.1","chr1",24135776,24151949],[["uc001bie.2"],"knownGene","uc001bie.2","chr1",24171573,24194821],[["uc009vqt.1"],"knownGene","uc009vqt.1","chr1",24180849,24194821],[["uc010oed.1"],"knownGene","uc010oed.1","chr1",24186287,24194787],[["uc001bif.2"],"knownGene","uc001bif.2","chr1",24200460,24239817],[["uc001big.2"],"knownGene","uc001big.2","chr1",24286300,24289947],[["uc010oee.1"],"knownGene","uc010oee.1","chr1",24292938,24306821],[["uc001bij.1"],"knownGene","uc001bij.1","chr1",24292938,24306821],[["uc010oef.1"],"knownGene","uc010oef.1","chr1",24295572,24306821],[["uc001bin.3"],"knownGene","uc001bin.3","chr1",24382531,24438665],[["uc001bim.3"],"knownGene","uc001bim.3","chr1",24382531,24421493],[["uc001bil.3"],"knownGene","uc001bil.3","chr1",24382531,24393069],[["uc001bio.2"],"knownGene","uc001bio.2","chr1",24392137,24438665],[["uc001bip.1"],"knownGene","uc001bip.1","chr1",24408038,24434929],[["uc001biq.1"],"knownGene","uc001biq.1","chr1",24446260,24469611],[["uc009vrb.1"],"knownGene","uc009vrb.1","chr1",24446260,24469611],[["uc010oeh.1"],"knownGene","uc010oeh.1","chr1",24446260,24469611],[["uc010oeg.1"],"knownGene","uc010oeg.1","chr1",24446260,24463799],[["uc001bir.2"],"knownGene","uc001bir.2","chr1",24480647,24513751],[["uc001bis.2"],"knownGene","uc001bis.2","chr1",24480647,24513751],[["uc001bit.2"],"knownGene","uc001bit.2","chr1",24480647,24513751],[["uc001biu.2"],"knownGene","uc001biu.2","chr1",24480647,24513751],[["uc001biv.2"],"knownGene","uc001biv.2","chr1",24487868,24513751],[["uc010oei.1"],"knownGene","uc010oei.1","chr1",24526729,24538180],[["uc001biw.2"],"knownGene","uc001biw.2","chr1",24580829,24580859],[["uc001bix.2"],"knownGene","uc001bix.2","chr1",24645880,24681807],[["uc001biy.2"],"knownGene","uc001biy.2","chr1",24649529,24681807],[["uc001biz.2"],"knownGene","uc001biz.2","chr1",24649529,24681807],[["uc001bjd.2"],"knownGene","uc001bjd.2","chr1",24683489,24741587],[["uc001bjb.2"],"knownGene","uc001bjb.2","chr1",24683489,24740230],[["uc001bjc.2"],"knownGene","uc001bjc.2","chr1",24683489,24740230],[["uc001bja.2"],"knownGene","uc001bja.2","chr1",24683489,24727946],[["uc010oej.1"],"knownGene","uc010oej.1","chr1",24683489,24700300],[["uc001bje.1"],"knownGene","uc001bje.1","chr1",24687340,24740230],[["uc001bjf.2"],"knownGene","uc001bjf.2","chr1",24695212,24718169],[["uc001bjh.2"],"knownGene","uc001bjh.2","chr1",24742244,24799472],[["uc009vrc.2"],"knownGene","uc009vrc.2","chr1",24742244,24799472],[["uc001bjg.2"],"knownGene","uc001bjg.2","chr1",24742244,24792797],[["uc010oek.1"],"knownGene","uc010oek.1","chr1",24742244,24781313],[["uc001bji.2"],"knownGene","uc001bji.2","chr1",24782627,24792862],[["uc001bjj.2"],"knownGene","uc001bjj.2","chr1",24829386,24862425],[["uc009vrd.2"],"knownGene","uc009vrd.2","chr1",24840803,24862425],[["uc009vre.2"],"knownGene","uc009vre.2","chr1",24840803,24862425],[["uc009vrf.2"],"knownGene","uc009vrf.2","chr1",24840803,24862425],[["uc009vrg.2"],"knownGene","uc009vrg.2","chr1",24840803,24862425],[["uc001bjk.1"],"knownGene","uc001bjk.1","chr1",24882601,24935816],[["uc001bjm.2"],"knownGene","uc001bjm.2","chr1",24969593,24999771],[["uc010oel.1"],"knownGene","uc010oel.1","chr1",24969593,24999771],[["uc009vrh.1"],"knownGene","uc009vrh.1","chr1",24970049,24996078],[["uc009vri.1"],"knownGene","uc009vri.1","chr1",24975251,24998086],[["uc010oem.1"],"knownGene","uc010oem.1","chr1",24975349,24993416],[["uc001bjo.2"],"knownGene","uc001bjo.2","chr1",25071759,25170815],[["uc001bjn.2"],"knownGene","uc001bjn.2","chr1",25071759,25170758],[["uc001bjp.1"],"knownGene","uc001bjp.1","chr1",25071877,25169078],[["uc001bjr.2"],"knownGene","uc001bjr.2","chr1",25226002,25291501],[["uc009vrj.2"],"knownGene","uc009vrj.2","chr1",25226002,25291475],[["uc001bjq.2"],"knownGene","uc001bjq.2","chr1",25226002,25256770],[["uc010oen.1"],"knownGene","uc010oen.1","chr1",25226002,25256770],[["uc001bjs.2"],"knownGene","uc001bjs.2","chr1",25227543,25230414],[["uc009vrk.2"],"knownGene","uc009vrk.2","chr1",25255176,25291501],[["uc009vrl.1"],"knownGene","uc009vrl.1","chr1",25256077,25291612],[["uc001bjt.1"],"knownGene","uc001bjt.1","chr1",25548766,25559013],[["uc001bju.1"],"knownGene","uc001bju.1","chr1",25548766,25559013],[["uc010oeo.1"],"knownGene","uc010oeo.1","chr1",25553283,25559013],[["uc001bjv.1"],"knownGene","uc001bjv.1","chr1",25556799,25559013],[["uc001bjw.2"],"knownGene","uc001bjw.2","chr1",25568740,25573985],[["uc001bjz.2"],"knownGene","uc001bjz.2","chr1",25598980,25656935],[["uc001bkc.2"],"knownGene","uc001bkc.2","chr1",25598980,25656935],[["uc009vrm.2"],"knownGene","uc009vrm.2","chr1",25598980,25656935],[["uc001bka.2"],"knownGene","uc001bka.2","chr1",25598980,25656935],[["uc001bkb.2"],"knownGene","uc001bkb.2","chr1",25598980,25656935],[["uc009vrn.2"],"knownGene","uc009vrn.2","chr1",25598980,25656935],[["uc009vro.2"],"knownGene","uc009vro.2","chr1",25598980,25656935],[["uc009vrp.2"],"knownGene","uc009vrp.2","chr1",25598980,25656935],[["uc010oep.1"],"knownGene","uc010oep.1","chr1",25598980,25633432],[["uc001bkd.1"],"knownGene","uc001bkd.1","chr1",25629228,25631643],[["uc001bke.2"],"knownGene","uc001bke.2","chr1",25664810,25688850],[["uc010oeq.1"],"knownGene","uc010oeq.1","chr1",25664810,25688850],[["uc009vrr.2"],"knownGene","uc009vrr.2","chr1",25664810,25688850],[["uc009vrs.2"],"knownGene","uc009vrs.2","chr1",25664810,25688850],[["uc001bkj.2"],"knownGene","uc001bkj.2","chr1",25688740,25756683],[["uc001bkf.2"],"knownGene","uc001bkf.2","chr1",25688740,25747363],[["uc001bkg.2"],"knownGene","uc001bkg.2","chr1",25688740,25747363],[["uc001bkh.2"],"knownGene","uc001bkh.2","chr1",25688740,25747363],[["uc001bki.2"],"knownGene","uc001bki.2","chr1",25688740,25747363],[["uc001bkk.2"],"knownGene","uc001bkk.2","chr1",25757387,25826696],[["uc009vru.2"],"knownGene","uc009vru.2","chr1",25757387,25826696],[["uc009vrv.2"],"knownGene","uc009vrv.2","chr1",25757387,25826696],[["uc009vrt.2"],"knownGene","uc009vrt.2","chr1",25757387,25785383],[["uc001bkl.3"],"knownGene","uc001bkl.3","chr1",25870075,25895375],[["uc009vrw.2"],"knownGene","uc009vrw.2","chr1",25889284,25895375],[["uc009vrx.2"],"knownGene","uc009vrx.2","chr1",25889297,25895375],[["uc001bkm.2"],"knownGene","uc001bkm.2","chr1",25943958,26111258],[["uc009vry.1"],"knownGene","uc009vry.1","chr1",25943958,26111258],[["uc001bkn.2"],"knownGene","uc001bkn.2","chr1",26107204,26111258],[["uc010oer.1"],"knownGene","uc010oer.1","chr1",26126666,26144713],[["uc010oes.1"],"knownGene","uc010oes.1","chr1",26126666,26144713],[["uc001bkq.3"],"knownGene","uc001bkq.3","chr1",26146396,26159432],[["uc001bkr.3"],"knownGene","uc001bkr.3","chr1",26146396,26159432],[["uc010oet.1"],"knownGene","uc010oet.1","chr1",26146396,26159432],[["uc009vrz.2"],"knownGene","uc009vrz.2","chr1",26146396,26159432],[["uc010oeu.1"],"knownGene","uc010oeu.1","chr1",26146444,26150097],[["uc001bks.3"],"knownGene","uc001bks.3","chr1",26146683,26159432],[["uc001bkt.3"],"knownGene","uc001bkt.3","chr1",26147318,26159432],[["uc001bku.3"],"knownGene","uc001bku.3","chr1",26149020,26159432],[["uc001bkv.3"],"knownGene","uc001bkv.3","chr1",26152122,26159432],[["uc001bkw.1"],"knownGene","uc001bkw.1","chr1",26160496,26185848],[["uc001bkx.2"],"knownGene","uc001bkx.2","chr1",26187975,26197744],[["uc010oev.1"],"knownGene","uc010oev.1","chr1",26210677,26232993],[["uc001bky.2"],"knownGene","uc001bky.2","chr1",26210677,26219098],[["uc001blc.2"],"knownGene","uc001blc.2","chr1",26226608,26233368],[["uc001bla.2"],"knownGene","uc001bla.2","chr1",26226608,26232993],[["uc001blb.2"],"knownGene","uc001blb.2","chr1",26226608,26232993],[["uc001bkz.2"],"knownGene","uc001bkz.2","chr1",26226608,26232644],[["uc001bld.3"],"knownGene","uc001bld.3","chr1",26286259,26324648],[["uc001ble.3"],"knownGene","uc001ble.3","chr1",26286259,26324648],[["uc001blf.2"],"knownGene","uc001blf.2","chr1",26348270,26362952],[["uc001blg.1"],"knownGene","uc001blg.1","chr1",26364513,26372604],[["uc001blh.1"],"knownGene","uc001blh.1","chr1",26364513,26372604],[["uc001bli.1"],"knownGene","uc001bli.1","chr1",26377797,26394121],[["uc010oew.1"],"knownGene","uc010oew.1","chr1",26437655,26452024],[["uc001blj.3"],"knownGene","uc001blj.3","chr1",26438267,26452024],[["uc009vsb.2"],"knownGene","uc009vsb.2","chr1",26438267,26452024],[["uc001blk.2"],"knownGene","uc001blk.2","chr1",26485510,26489118],[["uc001bll.3"],"knownGene","uc001bll.3","chr1",26496387,26497362],[["uc001blm.3"],"knownGene","uc001blm.3","chr1",26503980,26516373],[["uc001bln.3"],"knownGene","uc001bln.3","chr1",26503980,26516373],[["uc009vsd.2"],"knownGene","uc009vsd.2","chr1",26503980,26516373],[["uc010oex.1"],"knownGene","uc010oex.1","chr1",26503980,26511677],[["uc009vse.2"],"knownGene","uc009vse.2","chr1",26503981,26516373],[["uc001blo.2"],"knownGene","uc001blo.2","chr1",26506786,26516373],[["uc010oez.1"],"knownGene","uc010oez.1","chr1",26517118,26529032],[["uc009vsf.2"],"knownGene","uc009vsf.2","chr1",26517118,26529032],[["uc010oey.1"],"knownGene","uc010oey.1","chr1",26517118,26528094],[["uc001blq.2"],"knownGene","uc001blq.2","chr1",26551810,26556330],[["uc001bls.1"],"knownGene","uc001bls.1","chr1",26560692,26605299],[["uc010ofa.1"],"knownGene","uc010ofa.1","chr1",26560692,26605299],[["uc001blr.2"],"knownGene","uc001blr.2","chr1",26560692,26605297],[["uc001blt.1"],"knownGene","uc001blt.1","chr1",26595780,26605299],[["uc001blu.2"],"knownGene","uc001blu.2","chr1",26606212,26608012],[["uc001blz.1"],"knownGene","uc001blz.1","chr1",26608772,26633195],[["uc001bma.2"],"knownGene","uc001bma.2","chr1",26608774,26644756],[["uc001blw.2"],"knownGene","uc001blw.2","chr1",26608774,26633195],[["uc001bly.2"],"knownGene","uc001bly.2","chr1",26608774,26633195],[["uc001blx.2"],"knownGene","uc001blx.2","chr1",26608774,26633195],[["uc001blv.2"],"knownGene","uc001blv.2","chr1",26608774,26629409],[["uc001bmb.1"],"knownGene","uc001bmb.1","chr1",26608848,26633067],[["uc010ofb.1"],"knownGene","uc010ofb.1","chr1",26610852,26633195],[["uc010ofc.1"],"knownGene","uc010ofc.1","chr1",26610852,26633195],[["uc001bmc.2"],"knownGene","uc001bmc.2","chr1",26644410,26647013],[["uc009vsg.1"],"knownGene","uc009vsg.1","chr1",26644410,26645690],[["uc001bmd.3"],"knownGene","uc001bmd.3","chr1",26648349,26670443],[["uc001bmf.3"],"knownGene","uc001bmf.3","chr1",26662956,26664968],[["uc009vsi.1"],"knownGene","uc009vsi.1","chr1",26671746,26680621],[["uc001bmh.1"],"knownGene","uc001bmh.1","chr1",26688124,26699266],[["uc009vsj.1"],"knownGene","uc009vsj.1","chr1",26688124,26699266],[["uc001bmg.1"],"knownGene","uc001bmg.1","chr1",26688124,26699266],[["uc001bmj.2"],"knownGene","uc001bmj.2","chr1",26737268,26756218],[["uc001bmi.1"],"knownGene","uc001bmi.1","chr1",26737268,26756210],[["uc001bmk.2"],"knownGene","uc001bmk.2","chr1",26758801,26797793],[["uc001bml.2"],"knownGene","uc001bml.2","chr1",26758801,26797793],[["uc001bmm.2"],"knownGene","uc001bmm.2","chr1",26758801,26797793],[["uc001bmn.2"],"knownGene","uc001bmn.2","chr1",26758801,26797793],[["uc010ofd.1"],"knownGene","uc010ofd.1","chr1",26758801,26797793],[["uc001bmo.1"],"knownGene","uc001bmo.1","chr1",26789254,26794028],[["uc001bmp.3"],"knownGene","uc001bmp.3","chr1",26798901,26803131],[["uc009vsk.2"],"knownGene","uc009vsk.2","chr1",26798901,26803131],[["uc001bmq.3"],"knownGene","uc001bmq.3","chr1",26800193,26803131],[["uc001bmr.1"],"knownGene","uc001bmr.1","chr1",26856248,26901520],[["uc010ofe.1"],"knownGene","uc010ofe.1","chr1",26857818,26901520],[["uc010off.1"],"knownGene","uc010off.1","chr1",26869652,26898724],[["uc001bms.1"],"knownGene","uc001bms.1","chr1",26872342,26901520],[["uc009vsl.1"],"knownGene","uc009vsl.1","chr1",26872342,26901520],[["uc001bmu.1"],"knownGene","uc001bmu.1","chr1",27022521,27108601],[["uc001bmv.1"],"knownGene","uc001bmv.1","chr1",27022521,27108601],[["uc001bmt.1"],"knownGene","uc001bmt.1","chr1",27022521,27102198],[["uc001bmw.1"],"knownGene","uc001bmw.1","chr1",27055870,27101711],[["uc001bmx.1"],"knownGene","uc001bmx.1","chr1",27097609,27108601],[["uc009vsm.1"],"knownGene","uc009vsm.1","chr1",27099305,27108601],[["uc009vsn.1"],"knownGene","uc009vsn.1","chr1",27100819,27108601],[["uc001bmy.2"],"knownGene","uc001bmy.2","chr1",27114454,27124886],[["uc001bmz.2"],"knownGene","uc001bmz.2","chr1",27114485,27124886],[["uc009vso.2"],"knownGene","uc009vso.2","chr1",27114485,27124886],[["uc010ofg.1"],"knownGene","uc010ofg.1","chr1",27114678,27124886],[["uc001bna.2"],"knownGene","uc001bna.2","chr1",27114685,27124886],[["uc001bnb.2"],"knownGene","uc001bnb.2","chr1",27153200,27182207],[["uc010ofh.1"],"knownGene","uc010ofh.1","chr1",27158508,27177097],[["uc001bnc.1"],"knownGene","uc001bnc.1","chr1",27189632,27190947],[["uc010ofi.1"],"knownGene","uc010ofi.1","chr1",27189786,27190449],[["uc001bnd.1"],"knownGene","uc001bnd.1","chr1",27205872,27216869],[["uc001bne.2"],"knownGene","uc001bne.2","chr1",27216979,27226962],[["uc009vsp.1"],"knownGene","uc009vsp.1","chr1",27216979,27226956],[["uc001bnf.2"],"knownGene","uc001bnf.2","chr1",27237975,27240567],[["uc001bng.1"],"knownGene","uc001bng.1","chr1",27248223,27272887],[["uc001bnh.1"],"knownGene","uc001bnh.1","chr1",27248223,27272887],[["uc009vsq.1"],"knownGene","uc009vsq.1","chr1",27248223,27272887],[["uc001bni.1"],"knownGene","uc001bni.1","chr1",27276060,27286897],[["uc001bnj.3"],"knownGene","uc001bnj.3","chr1",27320194,27327376],[["uc010ofj.1"],"knownGene","uc010ofj.1","chr1",27331512,27339333],[["uc001bnm.2"],"knownGene","uc001bnm.2","chr1",27425300,27481451],[["uc010ofk.1"],"knownGene","uc010ofk.1","chr1",27425300,27481451],[["uc001bnl.2"],"knownGene","uc001bnl.2","chr1",27425300,27430513],[["uc001bnn.2"],"knownGene","uc001bnn.2","chr1",27431941,27481451],[["uc001bno.2"],"knownGene","uc001bno.2","chr1",27561006,27635108],[["uc009vst.2"],"knownGene","uc009vst.2","chr1",27561006,27633934],[["uc001bnp.1"],"knownGene","uc001bnp.1","chr1",27587446,27634732],[["uc001bnq.2"],"knownGene","uc001bnq.2","chr1",27622816,27635108],[["uc001bnr.3"],"knownGene","uc001bnr.3","chr1",27648635,27662890],[["uc001bns.3"],"knownGene","uc001bns.3","chr1",27648635,27662890],[["uc001bnt.3"],"knownGene","uc001bnt.3","chr1",27648635,27662890],[["uc001bnu.3"],"knownGene","uc001bnu.3","chr1",27648635,27662890],[["uc001bnv.1"],"knownGene","uc001bnv.1","chr1",27668512,27680421],[["uc001bnw.1"],"knownGene","uc001bnw.1","chr1",27668512,27680421],[["uc009vsu.1"],"knownGene","uc009vsu.1","chr1",27668512,27680421],[["uc009vsv.1"],"knownGene","uc009vsv.1","chr1",27671363,27680421],[["uc001bnx.2"],"knownGene","uc001bnx.2","chr1",27671363,27678538],[["uc001bny.1"],"knownGene","uc001bny.1","chr1",27681669,27693337],[["uc009vsw.1"],"knownGene","uc009vsw.1","chr1",27681669,27693337],[["uc001bnz.1"],"knownGene","uc001bnz.1","chr1",27684646,27688358],[["uc001boa.2"],"knownGene","uc001boa.2","chr1",27695602,27701315],[["uc001bob.2"],"knownGene","uc001bob.2","chr1",27695602,27701315],[["uc001boc.2"],"knownGene","uc001boc.2","chr1",27705596,27709805],[["uc001bod.2"],"knownGene","uc001bod.2","chr1",27719151,27722315],[["uc001boe.2"],"knownGene","uc001boe.2","chr1",27730734,27732300],[["uc001bof.1"],"knownGene","uc001bof.1","chr1",27732125,27816669],[["uc010ofl.1"],"knownGene","uc010ofl.1","chr1",27732125,27816669],[["uc009vsy.2"],"knownGene","uc009vsy.2","chr1",27860793,27930143],[["uc009vsz.1"],"knownGene","uc009vsz.1","chr1",27873771,27930143],[["uc001boh.1"],"knownGene","uc001boh.1","chr1",27877379,27930361],[["uc001bom.2"],"knownGene","uc001bom.2","chr1",27938802,27961727],[["uc001bol.2"],"knownGene","uc001bol.2","chr1",27938802,27953106],[["uc001bok.2"],"knownGene","uc001bok.2","chr1",27938802,27952751],[["uc001boj.2"],"knownGene","uc001boj.2","chr1",27938802,27950573],[["uc001boi.2"],"knownGene","uc001boi.2","chr1",27938802,27942174],[["uc001bon.1"],"knownGene","uc001bon.1","chr1",27992571,27998724],[["uc001boo.1"],"knownGene","uc001boo.1","chr1",27992571,27998724],[["uc001bop.1"],"knownGene","uc001bop.1","chr1",27992571,27998724],[["uc001bor.2"],"knownGene","uc001bor.2","chr1",28052489,28089421],[["uc001boq.2"],"knownGene","uc001boq.2","chr1",28052489,28089421],[["uc001bos.2"],"knownGene","uc001bos.2","chr1",28052489,28089421],[["uc001bot.2"],"knownGene","uc001bot.2","chr1",28052489,28089421],[["uc010ofm.1"],"knownGene","uc010ofm.1","chr1",28052489,28089421],[["uc009vtb.2"],"knownGene","uc009vtb.2","chr1",28052489,28086274],[["uc001bou.3"],"knownGene","uc001bou.3","chr1",28099693,28150962],[["uc001bov.1"],"knownGene","uc001bov.1","chr1",28157292,28178183],[["uc001bow.1"],"knownGene","uc001bow.1","chr1",28157292,28178183],[["uc001box.1"],"knownGene","uc001box.1","chr1",28157292,28178183],[["uc009vtc.1"],"knownGene","uc009vtc.1","chr1",28157292,28178183],[["uc009vtd.1"],"knownGene","uc009vtd.1","chr1",28157292,28178183],[["uc001boy.1"],"knownGene","uc001boy.1","chr1",28160911,28161077],[["uc001bpc.3"],"knownGene","uc001bpc.3","chr1",28199054,28213192],[["uc001boz.2"],"knownGene","uc001boz.2","chr1",28199054,28213192],[["uc001bpa.2"],"knownGene","uc001bpa.2","chr1",28199054,28213192],[["uc010ofn.1"],"knownGene","uc010ofn.1","chr1",28199054,28213192],[["uc010ofo.1"],"knownGene","uc010ofo.1","chr1",28199054,28213192],[["uc001bpe.1"],"knownGene","uc001bpe.1","chr1",28218048,28241236],[["uc010ofp.1"],"knownGene","uc010ofp.1","chr1",28218048,28241236],[["uc001bpd.1"],"knownGene","uc001bpd.1","chr1",28218048,28241231],[["uc001bpg.2"],"knownGene","uc001bpg.2","chr1",28261503,28285662],[["uc010ofq.1"],"knownGene","uc010ofq.1","chr1",28261503,28285662],[["uc010ofr.1"],"knownGene","uc010ofr.1","chr1",28261503,28285662],[["uc001bpf.2"],"knownGene","uc001bpf.2","chr1",28261503,28282990],[["uc001bph.1"],"knownGene","uc001bph.1","chr1",28286503,28294604],[["uc001bpi.1"],"knownGene","uc001bpi.1","chr1",28300818,28415131],[["uc010ofs.1"],"knownGene","uc010ofs.1","chr1",28300818,28415131],[["uc010oft.1"],"knownGene","uc010oft.1","chr1",28300818,28415131],[["uc001bpj.2"],"knownGene","uc001bpj.2","chr1",28303785,28415131],[["uc001bpk.1"],"knownGene","uc001bpk.1","chr1",28314993,28415131],[["uc010ofu.1"],"knownGene","uc010ofu.1","chr1",28315045,28415131],[["uc010ofv.1"],"knownGene","uc010ofv.1","chr1",28421445,28423069],[["uc001bpm.3"],"knownGene","uc001bpm.3","chr1",28475863,28520447],[["uc009vte.2"],"knownGene","uc009vte.2","chr1",28475863,28520447],[["uc001bpl.2"],"knownGene","uc001bpl.2","chr1",28475863,28503191],[["uc001bpn.2"],"knownGene","uc001bpn.2","chr1",28526791,28559542],[["uc001bpo.2"],"knownGene","uc001bpo.2","chr1",28526791,28559542],[["uc001bpp.2"],"knownGene","uc001bpp.2","chr1",28562610,28564609],[["uc001bpq.2"],"knownGene","uc001bpq.2","chr1",28562610,28564609],[["uc001bpr.2"],"knownGene","uc001bpr.2","chr1",28562610,28564609],[["uc001bps.2"],"knownGene","uc001bps.2","chr1",28586005,28609001],[["uc001bpt.3"],"knownGene","uc001bpt.3","chr1",28655512,28662477],[["uc009vtg.2"],"knownGene","uc009vtg.2","chr1",28655512,28662477],[["uc001bpw.2"],"knownGene","uc001bpw.2","chr1",28696092,28826880],[["uc001bpx.2"],"knownGene","uc001bpx.2","chr1",28696092,28826880],[["uc001bpv.1"],"knownGene","uc001bpv.1","chr1",28696092,28823783],[["uc001bpu.2"],"knownGene","uc001bpu.2","chr1",28696092,28793723],[["uc001bpy.2"],"knownGene","uc001bpy.2","chr1",28764660,28826880],[["uc001bpz.2"],"knownGene","uc001bpz.2","chr1",28818161,28826874],[["uc001bqa.1"],"knownGene","uc001bqa.1","chr1",28832495,28865607],[["uc001bqb.1"],"knownGene","uc001bqb.1","chr1",28832495,28865607],[["uc001bqc.1"],"knownGene","uc001bqc.1","chr1",28832495,28865607],[["uc001bqd.2"],"knownGene","uc001bqd.2","chr1",28835901,28837381],[["uc001bqe.1"],"knownGene","uc001bqe.1","chr1",28844744,28865607],[["uc001bqf.1"],"knownGene","uc001bqf.1","chr1",28844744,28865607],[["uc001bqg.1"],"knownGene","uc001bqg.1","chr1",28844744,28865607],[["uc001bqh.2"],"knownGene","uc001bqh.2","chr1",28879528,28905056],[["uc001bqi.2"],"knownGene","uc001bqi.2","chr1",28879528,28905056],[["uc010ofw.1"],"knownGene","uc010ofw.1","chr1",28879528,28905056],[["uc001bqp.2"],"knownGene","uc001bqp.2","chr1",28905051,28909495],[["uc001bqo.2"],"knownGene","uc001bqo.2","chr1",28905051,28908383],[["uc001bqk.2"],"knownGene","uc001bqk.2","chr1",28905051,28908366],[["uc001bql.2"],"knownGene","uc001bql.2","chr1",28905051,28908366],[["uc001bqm.2"],"knownGene","uc001bqm.2","chr1",28905051,28908366],[["uc001bqn.2"],"knownGene","uc001bqn.2","chr1",28905051,28908366],[["uc001bqq.1"],"knownGene","uc001bqq.1","chr1",28905254,28905334],[["uc001bqr.2"],"knownGene","uc001bqr.2","chr1",28906275,28906405],[["uc001bqs.2"],"knownGene","uc001bqs.2","chr1",28906892,28907024],[["uc001bqt.2"],"knownGene","uc001bqt.2","chr1",28907431,28907565],[["uc001bqu.2"],"knownGene","uc001bqu.2","chr1",28918711,28921086],[["uc001bqv.2"],"knownGene","uc001bqv.2","chr1",28919026,28921086],[["uc001bqx.2"],"knownGene","uc001bqx.2","chr1",28929610,28969604],[["uc001bqy.2"],"knownGene","uc001bqy.2","chr1",28929610,28969604],[["uc001bqw.2"],"knownGene","uc001bqw.2","chr1",28929610,28948686],[["uc009vti.2"],"knownGene","uc009vti.2","chr1",28931450,28969604],[["uc009vtj.1"],"knownGene","uc009vtj.1","chr1",28975111,28975246],[["uc001bqz.2"],"knownGene","uc001bqz.2","chr1",28995243,29041385],[["uc001bra.2"],"knownGene","uc001bra.2","chr1",28995243,29041385],[["uc001brb.2"],"knownGene","uc001brb.2","chr1",28995243,29041385],[["uc001brc.2"],"knownGene","uc001brc.2","chr1",29063135,29096286],[["uc001brd.2"],"knownGene","uc001brd.2","chr1",29063135,29096286],[["uc010ofx.1"],"knownGene","uc010ofx.1","chr1",29063135,29096286],[["uc001bre.2"],"knownGene","uc001bre.2","chr1",29063461,29096286],[["uc001brf.1"],"knownGene","uc001brf.1","chr1",29138653,29190208],[["uc001brg.1"],"knownGene","uc001brg.1","chr1",29213627,29446958],[["uc001brh.1"],"knownGene","uc001brh.1","chr1",29213627,29446958],[["uc001bri.1"],"knownGene","uc001bri.1","chr1",29213627,29446958],[["uc001brj.1"],"knownGene","uc001brj.1","chr1",29213627,29446958],[["uc001brl.1"],"knownGene","uc001brl.1","chr1",29241090,29446958],[["uc001brk.2"],"knownGene","uc001brk.2","chr1",29241090,29391731],[["uc009vtk.1"],"knownGene","uc009vtk.1","chr1",29241090,29380164],[["uc001brm.1"],"knownGene","uc001brm.1","chr1",29313942,29442315],[["uc009vtl.1"],"knownGene","uc009vtl.1","chr1",29313959,29446958],[["uc009vtm.1"],"knownGene","uc009vtm.1","chr1",29313959,29446958],[["uc009vtn.1"],"knownGene","uc009vtn.1","chr1",29410408,29446958],[["uc001brn.1"],"knownGene","uc001brn.1","chr1",29445939,29450407],[["uc001bro.2"],"knownGene","uc001bro.2","chr1",29474250,29508637],[["uc010ofy.1"],"knownGene","uc010ofy.1","chr1",29474250,29508637],[["uc009vtp.2"],"knownGene","uc009vtp.2","chr1",29481207,29508637],[["uc001brp.1"],"knownGene","uc001brp.1","chr1",29519384,29557454],[["uc001brq.1"],"knownGene","uc001brq.1","chr1",29519384,29557454],[["uc001brr.1"],"knownGene","uc001brr.1","chr1",29519384,29557454],[["uc001brs.1"],"knownGene","uc001brs.1","chr1",29519384,29557454],[["uc001brt.1"],"knownGene","uc001brt.1","chr1",29526148,29557454],[["uc010ofz.1"],"knownGene","uc010ofz.1","chr1",29526148,29557454],[["uc001bru.2"],"knownGene","uc001bru.2","chr1",29563046,29653315],[["uc001brv.2"],"knownGene","uc001brv.2","chr1",29563046,29653315],[["uc001brw.2"],"knownGene","uc001brw.2","chr1",29563046,29653315],[["uc009vtq.2"],"knownGene","uc009vtq.2","chr1",29563046,29653315],[["uc009vtr.2"],"knownGene","uc009vtr.2","chr1",29563046,29653315],[["uc001brx.2"],"knownGene","uc001brx.2","chr1",29646721,29653315],[["uc001bry.3"],"knownGene","uc001bry.3","chr1",30486798,30510456],[["uc001brz.2"],"knownGene","uc001brz.2","chr1",31184125,31196432],[["uc001bsa.1"],"knownGene","uc001bsa.1","chr1",31187093,31192099],[["uc001bsb.1"],"knownGene","uc001bsb.1","chr1",31191618,31199593],[["uc001bsc.2"],"knownGene","uc001bsc.2","chr1",31205314,31230683],[["uc001bse.2"],"knownGene","uc001bse.2","chr1",31342312,31381480],[["uc001bsd.2"],"knownGene","uc001bsd.2","chr1",31342312,31351587],[["uc001bsk.1"],"knownGene","uc001bsk.1","chr1",31404352,31538763],[["uc010ogb.1"],"knownGene","uc010ogb.1","chr1",31404352,31538763],[["uc001bsh.1"],"knownGene","uc001bsh.1","chr1",31404352,31538564],[["uc001bsi.1"],"knownGene","uc001bsi.1","chr1",31404352,31538564],[["uc001bsj.1"],"knownGene","uc001bsj.1","chr1",31404352,31538564],[["uc010oga.1"],"knownGene","uc010oga.1","chr1",31404352,31538564],[["uc001bsg.1"],"knownGene","uc001bsg.1","chr1",31404352,31478878],[["uc001bsf.1"],"knownGene","uc001bsf.1","chr1",31404352,31465507],[["uc009vts.1"],"knownGene","uc009vts.1","chr1",31408535,31422052],[["uc001bsl.1"],"knownGene","uc001bsl.1","chr1",31441009,31441084],[["uc001bsm.2"],"knownGene","uc001bsm.2","chr1",31460911,31461480],[["uc010ogd.1"],"knownGene","uc010ogd.1","chr1",31652592,31712400],[["uc001bsn.2"],"knownGene","uc001bsn.2","chr1",31652592,31661034],[["uc010ogc.1"],"knownGene","uc010ogc.1","chr1",31652592,31661034],[["uc001bso.2"],"knownGene","uc001bso.2","chr1",31732416,31769644],[["uc010oge.1"],"knownGene","uc010oge.1","chr1",31732416,31769644],[["uc009vtt.2"],"knownGene","uc009vtt.2","chr1",31732416,31742513],[["uc001bsp.1"],"knownGene","uc001bsp.1","chr1",31769841,31837780],[["uc001bsq.1"],"knownGene","uc001bsq.1","chr1",31769841,31837780],[["uc010ogf.1"],"knownGene","uc010ogf.1","chr1",31769841,31837780],[["uc009vtu.1"],"knownGene","uc009vtu.1","chr1",31769841,31837780],[["uc001bsr.1"],"knownGene","uc001bsr.1","chr1",31769930,31837780],[["uc009vtv.1"],"knownGene","uc009vtv.1","chr1",31769930,31837780],[["uc001bss.1"],"knownGene","uc001bss.1","chr1",31838099,31845923],[["uc010ogg.1"],"knownGene","uc010ogg.1","chr1",31883047,31907524],[["uc001bst.2"],"knownGene","uc001bst.2","chr1",31885962,31907524],[["uc009vtw.1"],"knownGene","uc009vtw.1","chr1",31885962,31899166],[["uc010ogh.1"],"knownGene","uc010ogh.1","chr1",31886659,31907524],[["uc001bsu.2"],"knownGene","uc001bsu.2","chr1",31887268,31907524],[["uc001bsv.2"],"knownGene","uc001bsv.2","chr1",31887576,31907524],[["uc001bsx.2"],"knownGene","uc001bsx.2","chr1",31971815,31974166],[["uc001bsw.1"],"knownGene","uc001bsw.1","chr1",31971815,31973124],[["uc001bsy.1"],"knownGene","uc001bsy.1","chr1",31984035,31989846],[["uc001bsz.2"],"knownGene","uc001bsz.2","chr1",32013117,32053285],[["uc001bta.2"],"knownGene","uc001bta.2","chr1",32042085,32053285],[["uc010ogj.1"],"knownGene","uc010ogj.1","chr1",32042085,32053285],[["uc010ogi.1"],"knownGene","uc010ogi.1","chr1",32042085,32046561],[["uc010ogk.1"],"knownGene","uc010ogk.1","chr1",32042734,32051869],[["uc001btc.3"],"knownGene","uc001btc.3","chr1",32083300,32093212],[["uc009vtx.2"],"knownGene","uc009vtx.2","chr1",32083300,32092919],[["uc001btb.2"],"knownGene","uc001btb.2","chr1",32083300,32092919],[["uc001btd.2"],"knownGene","uc001btd.2","chr1",32084640,32092919],[["uc010ogl.1"],"knownGene","uc010ogl.1","chr1",32084651,32098117],[["uc001bte.1"],"knownGene","uc001bte.1","chr1",32095467,32098435],[["uc001bth.1"],"knownGene","uc001bth.1","chr1",32095470,32110477],[["uc001btg.1"],"knownGene","uc001btg.1","chr1",32095470,32101144],[["uc001btf.1"],"knownGene","uc001btf.1","chr1",32095470,32098254],[["uc010ogm.1"],"knownGene","uc010ogm.1","chr1",32099886,32110477],[["uc001btk.1"],"knownGene","uc001btk.1","chr1",32117847,32169768],[["uc001btj.1"],"knownGene","uc001btj.1","chr1",32117847,32164207],[["uc001bti.1"],"knownGene","uc001bti.1","chr1",32117847,32136007],[["uc001btl.3"],"knownGene","uc001btl.3","chr1",32144839,32169768],[["uc001btn.2"],"knownGene","uc001btn.2","chr1",32192718,32229648],[["uc001bto.2"],"knownGene","uc001bto.2","chr1",32192718,32229648],[["uc010ogq.1"],"knownGene","uc010ogq.1","chr1",32192718,32222882],[["uc010ogp.1"],"knownGene","uc010ogp.1","chr1",32192718,32222416],[["uc010ogo.1"],"knownGene","uc010ogo.1","chr1",32192718,32210332],[["uc010ogn.1"],"knownGene","uc010ogn.1","chr1",32192718,32202324],[["uc001btp.1"],"knownGene","uc001btp.1","chr1",32192718,32202280],[["uc001btm.2"],"knownGene","uc001btm.2","chr1",32192718,32201266],[["uc001btq.1"],"knownGene","uc001btq.1","chr1",32203800,32222416],[["uc010ogr.1"],"knownGene","uc010ogr.1","chr1",32204908,32222416],[["uc001bts.1"],"knownGene","uc001bts.1","chr1",32256024,32281580],[["uc001btr.1"],"knownGene","uc001btr.1","chr1",32256024,32258424],[["uc001btu.2"],"knownGene","uc001btu.2","chr1",32256032,32281580],[["uc001btv.2"],"knownGene","uc001btv.2","chr1",32256032,32281580],[["uc001btt.2"],"knownGene","uc001btt.2","chr1",32256032,32264266],[["uc001btw.1"],"knownGene","uc001btw.1","chr1",32260096,32264232],[["uc001btx.1"],"knownGene","uc001btx.1","chr1",32372021,32373712],[["uc001bty.1"],"knownGene","uc001bty.1","chr1",32373792,32403988],[["uc001btz.1"],"knownGene","uc001btz.1","chr1",32373792,32403988],[["uc010ogs.1"],"knownGene","uc010ogs.1","chr1",32373792,32385259],[["uc001buc.1"],"knownGene","uc001buc.1","chr1",32479490,32526450],[["uc001bub.2"],"knownGene","uc001bub.2","chr1",32479490,32509471],[["uc001bua.1"],"knownGene","uc001bua.1","chr1",32479490,32508320],[["uc010ogv.1"],"knownGene","uc010ogv.1","chr1",32538502,32568465],[["uc001bue.3"],"knownGene","uc001bue.3","chr1",32538502,32568465],[["uc001buf.3"],"knownGene","uc001buf.3","chr1",32538502,32568465],[["uc010ogw.1"],"knownGene","uc010ogw.1","chr1",32538502,32568465],[["uc010ogu.1"],"knownGene","uc010ogu.1","chr1",32538502,32566804],[["uc010ogt.1"],"knownGene","uc010ogt.1","chr1",32538502,32566163],[["uc001bug.2"],"knownGene","uc001bug.2","chr1",32573643,32642166],[["uc001buh.2"],"knownGene","uc001buh.2","chr1",32573643,32642166],[["uc010ogx.1"],"knownGene","uc010ogx.1","chr1",32573888,32642166],[["uc010ogy.1"],"knownGene","uc010ogy.1","chr1",32608579,32642166],[["uc009vtz.2"],"knownGene","uc009vtz.2","chr1",32622453,32642166],[["uc001bui.2"],"knownGene","uc001bui.2","chr1",32645344,32663885],[["uc001buj.2"],"knownGene","uc001buj.2","chr1",32645665,32663885],[["uc001bul.1"],"knownGene","uc001bul.1","chr1",32666201,32670991],[["uc001buk.2"],"knownGene","uc001buk.2","chr1",32666201,32670986],[["uc001bum.2"],"knownGene","uc001bum.2","chr1",32671235,32674288],[["uc009vua.2"],"knownGene","uc009vua.2","chr1",32671235,32674288],[["uc010ogz.1"],"knownGene","uc010ogz.1","chr1",32671235,32674288],[["uc001bun.2"],"knownGene","uc001bun.2","chr1",32674694,32681797],[["uc001buo.3"],"knownGene","uc001buo.3","chr1",32680077,32687926],[["uc001bup.3"],"knownGene","uc001bup.3","chr1",32680077,32687926],[["uc009vub.1"],"knownGene","uc009vub.1","chr1",32681273,32687926],[["uc010oha.1"],"knownGene","uc010oha.1","chr1",32681697,32687926],[["uc001buq.3"],"knownGene","uc001buq.3","chr1",32681799,32687926],[["uc001bur.3"],"knownGene","uc001bur.3","chr1",32687184,32697204],[["uc009vuc.2"],"knownGene","uc009vuc.2","chr1",32687958,32697204],[["uc001bus.2"],"knownGene","uc001bus.2","chr1",32688037,32697204],[["uc010ohb.1"],"knownGene","uc010ohb.1","chr1",32697261,32707311],[["uc001buv.3"],"knownGene","uc001buv.3","chr1",32697261,32707311],[["uc001but.2"],"knownGene","uc001but.2","chr1",32697261,32706265],[["uc001buw.2"],"knownGene","uc001buw.2","chr1",32712817,32714459],[["uc001bux.2"],"knownGene","uc001bux.2","chr1",32716839,32751765],[["uc001buy.2"],"knownGene","uc001buy.2","chr1",32739711,32751765],[["uc001buz.2"],"knownGene","uc001buz.2","chr1",32739711,32751765],[["uc010ohc.1"],"knownGene","uc010ohc.1","chr1",32739740,32745811],[["uc001bva.2"],"knownGene","uc001bva.2","chr1",32739925,32751765],[["uc001bvb.1"],"knownGene","uc001bvb.1","chr1",32757707,32799224],[["uc010ohd.1"],"knownGene","uc010ohd.1","chr1",32757707,32793590],[["uc010ohe.1"],"knownGene","uc010ohe.1","chr1",32757707,32793590],[["uc010ohf.1"],"knownGene","uc010ohf.1","chr1",32757992,32799224],[["uc001bvc.1"],"knownGene","uc001bvc.1","chr1",32795080,32799224],[["uc001bvd.2"],"knownGene","uc001bvd.2","chr1",32799440,32801834],[["uc001bve.1"],"knownGene","uc001bve.1","chr1",32826871,32829158],[["uc001bvf.2"],"knownGene","uc001bvf.2","chr1",32827861,32829922],[["uc001bvh.3"],"knownGene","uc001bvh.3","chr1",32830706,32860062],[["uc010ohg.1"],"knownGene","uc010ohg.1","chr1",32830706,32860062],[["uc010ohh.1"],"knownGene","uc010ohh.1","chr1",32830706,32860062],[["uc010ohi.1"],"knownGene","uc010ohi.1","chr1",32830706,32860062],[["uc001bvg.3"],"knownGene","uc001bvg.3","chr1",32830706,32860062],[["uc001bvj.2"],"knownGene","uc001bvj.2","chr1",32830788,32860062],[["uc001bvi.2"],"knownGene","uc001bvi.2","chr1",32830788,32860062],[["uc001bvk.2"],"knownGene","uc001bvk.2","chr1",32930657,33071541],[["uc001bvl.3"],"knownGene","uc001bvl.3","chr1",32930657,32953457],[["uc001bvn.2"],"knownGene","uc001bvn.2","chr1",33004771,33071541],[["uc001bvm.2"],"knownGene","uc001bvm.2","chr1",33004771,33066224],[["uc001bvo.1"],"knownGene","uc001bvo.1","chr1",33065772,33116185],[["uc001bvp.2"],"knownGene","uc001bvp.2","chr1",33087308,33116185],[["uc001bvq.2"],"knownGene","uc001bvq.2","chr1",33087308,33116185],[["uc001bvr.2"],"knownGene","uc001bvr.2","chr1",33116748,33151810],[["uc001bvs.2"],"knownGene","uc001bvs.2","chr1",33116748,33151810],[["uc010ohj.1"],"knownGene","uc010ohj.1","chr1",33116748,33151810],[["uc010ohk.1"],"knownGene","uc010ohk.1","chr1",33116958,33151810],[["uc001bvt.2"],"knownGene","uc001bvt.2","chr1",33145506,33168361],[["uc010ohl.1"],"knownGene","uc010ohl.1","chr1",33145506,33168361],[["uc001bvu.1"],"knownGene","uc001bvu.1","chr1",33207511,33240571],[["uc010ohm.1"],"knownGene","uc010ohm.1","chr1",33219686,33240571],[["uc001bvv.2"],"knownGene","uc001bvv.2","chr1",33231234,33240571],[["uc010ohn.1"],"knownGene","uc010ohn.1","chr1",33231234,33240571],[["uc001bvy.1"],"knownGene","uc001bvy.1","chr1",33240839,33283633],[["uc001bvx.1"],"knownGene","uc001bvx.1","chr1",33240839,33249356],[["uc001bvw.1"],"knownGene","uc001bvw.1","chr1",33240839,33247704],[["uc001bvz.2"],"knownGene","uc001bvz.2","chr1",33283042,33324475],[["uc001bwc.2"],"knownGene","uc001bwc.2","chr1",33283175,33324475],[["uc001bwa.1"],"knownGene","uc001bwa.1","chr1",33283175,33300665],[["uc001bwb.1"],"knownGene","uc001bwb.1","chr1",33283175,33300665],[["uc001bwd.2"],"knownGene","uc001bwd.2","chr1",33291698,33324475],[["uc001bwe.2"],"knownGene","uc001bwe.2","chr1",33327869,33330398],[["uc001bwf.1"],"knownGene","uc001bwf.1","chr1",33327876,33336347],[["uc001bwg.2"],"knownGene","uc001bwg.2","chr1",33330056,33338082],[["uc001bwh.2"],"knownGene","uc001bwh.2","chr1",33352097,33360246],[["uc001bwi.1"],"knownGene","uc001bwi.1","chr1",33360195,33366953],[["uc001bwj.1"],"knownGene","uc001bwj.1","chr1",33360195,33366953],[["uc001bwk.1"],"knownGene","uc001bwk.1","chr1",33360195,33366953],[["uc010oho.1"],"knownGene","uc010oho.1","chr1",33402051,33430286],[["uc001bwm.3"],"knownGene","uc001bwm.3","chr1",33402051,33430286],[["uc010ohp.1"],"knownGene","uc010ohp.1","chr1",33402051,33430286],[["uc001bwn.2"],"knownGene","uc001bwn.2","chr1",33452675,33498069],[["uc001bwo.1"],"knownGene","uc001bwo.1","chr1",33473585,33502492],[["uc010ohq.1"],"knownGene","uc010ohq.1","chr1",33473585,33502492],[["uc009vud.1"],"knownGene","uc009vud.1","chr1",33473585,33502492],[["uc001bwp.1"],"knownGene","uc001bwp.1","chr1",33478582,33502492],[["uc010ohr.1"],"knownGene","uc010ohr.1","chr1",33478582,33502492],[["uc001bwq.1"],"knownGene","uc001bwq.1","chr1",33478807,33502492],[["uc001bwt.1"],"knownGene","uc001bwt.1","chr1",33546713,33586131],[["uc001bwr.2"],"knownGene","uc001bwr.2","chr1",33546713,33585994],[["uc001bws.2"],"knownGene","uc001bws.2","chr1",33546713,33585994],[["uc009vue.2"],"knownGene","uc009vue.2","chr1",33546713,33585994],[["uc001bwu.2"],"knownGene","uc001bwu.2","chr1",33546748,33585994],[["uc001bwv.2"],"knownGene","uc001bwv.2","chr1",33546748,33585994],[["uc001bww.2"],"knownGene","uc001bww.2","chr1",33546793,33585994],[["uc001bwx.1"],"knownGene","uc001bwx.1","chr1",33547259,33586131],[["uc009vug.2"],"knownGene","uc009vug.2","chr1",33547778,33585994],[["uc001bwz.1"],"knownGene","uc001bwz.1","chr1",33547778,33567493],[["uc009vuf.1"],"knownGene","uc009vuf.1","chr1",33547778,33567493],[["uc001bwy.1"],"knownGene","uc001bwy.1","chr1",33547778,33567493],[["uc001bxa.1"],"knownGene","uc001bxa.1","chr1",33607471,33608831],[["uc001bxb.2"],"knownGene","uc001bxb.2","chr1",33611003,33647671],[["uc001bxc.1"],"knownGene","uc001bxc.1","chr1",33722173,33766320],[["uc001bxd.1"],"knownGene","uc001bxd.1","chr1",33772366,33786699],[["uc009vuh.1"],"knownGene","uc009vuh.1","chr1",33789223,33896216],[["uc001bxg.1"],"knownGene","uc001bxg.1","chr1",33789223,33841194],[["uc001bxh.1"],"knownGene","uc001bxh.1","chr1",33789223,33841194],[["uc001bxe.1"],"knownGene","uc001bxe.1","chr1",33789223,33815499],[["uc001bxf.1"],"knownGene","uc001bxf.1","chr1",33789223,33815499],[["uc001bxi.1"],"knownGene","uc001bxi.1","chr1",33832716,33896615],[["uc001bxj.3"],"knownGene","uc001bxj.3","chr1",33938231,33961993],[["uc009vui.2"],"knownGene","uc009vui.2","chr1",33938251,33961993],[["uc001bxk.2"],"knownGene","uc001bxk.2","chr1",33938251,33958212],[["uc001bxn.1"],"knownGene","uc001bxn.1","chr1",33979608,34631443],[["uc001bxm.1"],"knownGene","uc001bxm.1","chr1",33979608,34630875],[["uc001bxo.1"],"knownGene","uc001bxo.1","chr1",34057406,34175104],[["uc001bxp.2"],"knownGene","uc001bxp.2","chr1",34326075,34330391],[["uc001bxq.2"],"knownGene","uc001bxq.2","chr1",34329630,34330391],[["uc001bxr.2"],"knownGene","uc001bxr.2","chr1",34334556,34351058],[["uc001bxs.3"],"knownGene","uc001bxs.3","chr1",34632623,34684729],[["uc001bxt.2"],"knownGene","uc001bxt.2","chr1",34642552,34684729],[["uc001bxu.2"],"knownGene","uc001bxu.2","chr1",35220720,35224113],[["uc001bxv.1"],"knownGene","uc001bxv.1","chr1",35225341,35229325],[["uc001bxw.3"],"knownGene","uc001bxw.3","chr1",35226777,35227927],[["uc001bxx.2"],"knownGene","uc001bxx.2","chr1",35246789,35251966],[["uc001bxy.2"],"knownGene","uc001bxy.2","chr1",35247910,35251966],[["uc001bxz.3"],"knownGene","uc001bxz.3","chr1",35249171,35252849],[["uc010ohs.1"],"knownGene","uc010ohs.1","chr1",35250363,35251175],[["uc009vul.2"],"knownGene","uc009vul.2","chr1",35258170,35261346],[["uc001bya.2"],"knownGene","uc001bya.2","chr1",35258598,35261346],[["uc009vum.1"],"knownGene","uc009vum.1","chr1",35258599,35260816],[["uc001byb.2"],"knownGene","uc001byb.2","chr1",35319123,35325392],[["uc001byc.2"],"knownGene","uc001byc.2","chr1",35331037,35370984],[["uc001byd.3"],"knownGene","uc001byd.3","chr1",35439959,35450920],[["uc001bye.2"],"knownGene","uc001bye.2","chr1",35447177,35450920],[["uc001byf.1"],"knownGene","uc001byf.1","chr1",35449367,35497291],[["uc001byh.2"],"knownGene","uc001byh.2","chr1",35451768,35497569],[["uc010oht.1"],"knownGene","uc010oht.1","chr1",35451768,35497569],[["uc009vup.2"],"knownGene","uc009vup.2","chr1",35455581,35497569],[["uc009vuq.1"],"knownGene","uc009vuq.1","chr1",35457412,35497569],[["uc009vur.1"],"knownGene","uc009vur.1","chr1",35470732,35497291],[["uc001byk.2"],"knownGene","uc001byk.2","chr1",35482850,35497569],[["uc001byj.2"],"knownGene","uc001byj.2","chr1",35482850,35497291],[["uc001byi.2"],"knownGene","uc001byi.2","chr1",35482850,35497291],[["uc001bym.2"],"knownGene","uc001bym.2","chr1",35544971,35581454],[["uc001byn.2"],"knownGene","uc001byn.2","chr1",35544971,35581454],[["uc010ohu.1"],"knownGene","uc010ohu.1","chr1",35544971,35581454],[["uc001byo.2"],"knownGene","uc001byo.2","chr1",35544971,35581454],[["uc009vut.2"],"knownGene","uc009vut.2","chr1",35544971,35581454],[["uc009vus.1"],"knownGene","uc009vus.1","chr1",35544971,35570370],[["uc001byl.1"],"knownGene","uc001byl.1","chr1",35544971,35566700],[["uc001byr.2"],"knownGene","uc001byr.2","chr1",35641981,35656194],[["uc001byq.2"],"knownGene","uc001byq.2","chr1",35641981,35646083],[["uc001byp.2"],"knownGene","uc001byp.2","chr1",35641981,35646083],[["uc001bys.2"],"knownGene","uc001bys.2","chr1",35649202,35658743],[["uc001byt.2"],"knownGene","uc001byt.2","chr1",35734567,35887544],[["uc009vuu.2"],"knownGene","uc009vuu.2","chr1",35734567,35887544],[["uc001byu.2"],"knownGene","uc001byu.2","chr1",35734567,35887544],[["uc009vuv.2"],"knownGene","uc009vuv.2","chr1",35824525,35887544],[["uc001byv.2"],"knownGene","uc001byv.2","chr1",35833689,35835012],[["uc001byx.2"],"knownGene","uc001byx.2","chr1",35899091,36023037],[["uc001byw.2"],"knownGene","uc001byw.2","chr1",35899091,35920237],[["uc010ohv.1"],"knownGene","uc010ohv.1","chr1",35904142,35936561],[["uc010ohw.1"],"knownGene","uc010ohw.1","chr1",35925975,36023551],[["uc001byz.2"],"knownGene","uc001byz.2","chr1",35930145,36023037],[["uc010ohx.1"],"knownGene","uc010ohx.1","chr1",35932208,36023003],[["uc001bza.2"],"knownGene","uc001bza.2","chr1",36023392,36032378],[["uc001bzb.2"],"knownGene","uc001bzb.2","chr1",36023392,36032378],[["uc001bzc.2"],"knownGene","uc001bzc.2","chr1",36023392,36032378],[["uc001bzd.1"],"knownGene","uc001bzd.1","chr1",36035412,36107143],[["uc010ohy.1"],"knownGene","uc010ohy.1","chr1",36038970,36060925],[["uc001bzf.1"],"knownGene","uc001bzf.1","chr1",36067743,36107143],[["uc010ohz.1"],"knownGene","uc010ohz.1","chr1",36067743,36107127],[["uc001bzg.1"],"knownGene","uc001bzg.1","chr1",36068623,36107143],[["uc001bzh.1"],"knownGene","uc001bzh.1","chr1",36179476,36184790],[["uc001bzi.2"],"knownGene","uc001bzi.2","chr1",36201819,36235551],[["uc009vux.2"],"knownGene","uc009vux.2","chr1",36201819,36235551],[["uc001bzj.1"],"knownGene","uc001bzj.1","chr1",36273827,36321188],[["uc001bzk.2"],"knownGene","uc001bzk.2","chr1",36335408,36389897],[["uc001bzl.2"],"knownGene","uc001bzl.2","chr1",36348809,36389897],[["uc009vuy.2"],"knownGene","uc009vuy.2","chr1",36360722,36389897],[["uc001bzm.1"],"knownGene","uc001bzm.1","chr1",36391432,36395210],[["uc001bzn.1"],"knownGene","uc001bzn.1","chr1",36396318,36449010],[["uc001bzp.2"],"knownGene","uc001bzp.2","chr1",36396771,36522062],[["uc001bzq.2"],"knownGene","uc001bzq.2","chr1",36396771,36522062],[["uc001bzo.2"],"knownGene","uc001bzo.2","chr1",36396771,36450379],[["uc001bzr.2"],"knownGene","uc001bzr.2","chr1",36549675,36553875],[["uc001bzs.2"],"knownGene","uc001bzs.2","chr1",36549944,36553875],[["uc001bzt.2"],"knownGene","uc001bzt.2","chr1",36554452,36559532],[["uc001bzu.2"],"knownGene","uc001bzu.2","chr1",36554452,36559532],[["uc001bzv.1"],"knownGene","uc001bzv.1","chr1",36560845,36565850],[["uc001bzw.1"],"knownGene","uc001bzw.1","chr1",36560845,36565850],[["uc001bzy.2"],"knownGene","uc001bzy.2","chr1",36602174,36615098],[["uc001bzx.2"],"knownGene","uc001bzx.2","chr1",36602174,36615067],[["uc001bzz.2"],"knownGene","uc001bzz.2","chr1",36621802,36646436],[["uc001caa.2"],"knownGene","uc001caa.2","chr1",36621802,36646436],[["uc001cab.2"],"knownGene","uc001cab.2","chr1",36621802,36646436],[["uc001cac.2"],"knownGene","uc001cac.2","chr1",36638064,36646436],[["uc001cad.2"],"knownGene","uc001cad.2","chr1",36643069,36646436],[["uc001cae.3"],"knownGene","uc001cae.3","chr1",36690016,36770955],[["uc001caf.3"],"knownGene","uc001caf.3","chr1",36690016,36770955],[["uc001cag.1"],"knownGene","uc001cag.1","chr1",36704347,36755365],[["uc010oia.1"],"knownGene","uc010oia.1","chr1",36771993,36787379],[["uc010oic.1"],"knownGene","uc010oic.1","chr1",36772707,36790484],[["uc010oib.1"],"knownGene","uc010oib.1","chr1",36772707,36787379],[["uc009vuz.1"],"knownGene","uc009vuz.1","chr1",36784671,36786399],[["uc001caj.1"],"knownGene","uc001caj.1","chr1",36787631,36789755],[["uc001cai.1"],"knownGene","uc001cai.1","chr1",36787631,36788849],[["uc001cak.1"],"knownGene","uc001cak.1","chr1",36805224,36851485],[["uc001cal.1"],"knownGene","uc001cal.1","chr1",36805224,36851485],[["uc001cam.1"],"knownGene","uc001cam.1","chr1",36805224,36851485],[["uc009vva.1"],"knownGene","uc009vva.1","chr1",36805224,36851485],[["uc001can.1"],"knownGene","uc001can.1","chr1",36805230,36826941],[["uc001cao.1"],"knownGene","uc001cao.1","chr1",36859030,36863493],[["uc001cap.2"],"knownGene","uc001cap.2","chr1",36883507,36916052],[["uc001caq.2"],"knownGene","uc001caq.2","chr1",36883507,36916052],[["uc001car.2"],"knownGene","uc001car.2","chr1",36893902,36916052],[["uc001cas.2"],"knownGene","uc001cas.2","chr1",36921361,36930040],[["uc001cav.1"],"knownGene","uc001cav.1","chr1",36931643,36948509],[["uc001caw.1"],"knownGene","uc001caw.1","chr1",36931643,36948509],[["uc001cax.1"],"knownGene","uc001cax.1","chr1",36931643,36948509],[["uc001cay.1"],"knownGene","uc001cay.1","chr1",36931643,36948509],[["uc001cau.1"],"knownGene","uc001cau.1","chr1",36931643,36937992],[["uc009vvc.1"],"knownGene","uc009vvc.1","chr1",36931643,36937247],[["uc001cat.1"],"knownGene","uc001cat.1","chr1",36931643,36935441],[["uc001caz.2"],"knownGene","uc001caz.2","chr1",37261127,37499844],[["uc001cba.1"],"knownGene","uc001cba.1","chr1",37270218,37499844],[["uc001cbb.3"],"knownGene","uc001cbb.3","chr1",37940118,37949976],[["uc001cbc.1"],"knownGene","uc001cbc.1","chr1",37945750,37949976],[["uc001cbe.1"],"knownGene","uc001cbe.1","chr1",37958175,37980364],[["uc009vvd.1"],"knownGene","uc009vvd.1","chr1",37958175,37980364],[["uc001cbf.1"],"knownGene","uc001cbf.1","chr1",37958175,37980364],[["uc001cbg.1"],"knownGene","uc001cbg.1","chr1",37958175,37980364],[["uc001cbd.1"],"knownGene","uc001cbd.1","chr1",37958175,37979867],[["uc001cbh.1"],"knownGene","uc001cbh.1","chr1",37961485,37980364],[["uc001cbi.2"],"knownGene","uc001cbi.2","chr1",38002144,38019903],[["uc010oid.1"],"knownGene","uc010oid.1","chr1",38002144,38019903],[["uc001cbj.2"],"knownGene","uc001cbj.2","chr1",38022519,38032457],[["uc010oie.1"],"knownGene","uc010oie.1","chr1",38022519,38032457],[["uc001cbk.2"],"knownGene","uc001cbk.2","chr1",38032413,38061586],[["uc010oif.1"],"knownGene","uc010oif.1","chr1",38042028,38061586],[["uc009vve.2"],"knownGene","uc009vve.2","chr1",38049175,38061586],[["uc001cbl.1"],"knownGene","uc001cbl.1","chr1",38076950,38100491],[["uc001cbm.1"],"knownGene","uc001cbm.1","chr1",38077420,38100491],[["uc009vvf.1"],"knownGene","uc009vvf.1","chr1",38077420,38100491],[["uc009vvg.1"],"knownGene","uc009vvg.1","chr1",38077420,38100491],[["uc001cbp.2"],"knownGene","uc001cbp.2","chr1",38147249,38156192],[["uc010oig.1"],"knownGene","uc010oig.1","chr1",38147249,38156175],[["uc001cbo.2"],"knownGene","uc001cbo.2","chr1",38147249,38156175],[["uc001cbn.2"],"knownGene","uc001cbn.2","chr1",38147249,38149148],[["uc001cbq.1"],"knownGene","uc001cbq.1","chr1",38151944,38157888],[["uc001cbr.2"],"knownGene","uc001cbr.2","chr1",38158158,38175389],[["uc001cbs.2"],"knownGene","uc001cbs.2","chr1",38158158,38175389],[["uc010oih.1"],"knownGene","uc010oih.1","chr1",38158525,38171239],[["uc009vvh.1"],"knownGene","uc009vvh.1","chr1",38179554,38197254],[["uc001cbt.2"],"knownGene","uc001cbt.2","chr1",38179554,38186226],[["uc001cbv.1"],"knownGene","uc001cbv.1","chr1",38179560,38222363],[["uc001cbu.2"],"knownGene","uc001cbu.2","chr1",38179560,38218898],[["uc009vvi.2"],"knownGene","uc009vvi.2","chr1",38181646,38230824],[["uc001cbw.3"],"knownGene","uc001cbw.3","chr1",38225946,38230824],[["uc001cby.2"],"knownGene","uc001cby.2","chr1",38259773,38267278],[["uc001cbx.2"],"knownGene","uc001cbx.2","chr1",38259773,38267278],[["uc001cbz.2"],"knownGene","uc001cbz.2","chr1",38261159,38267278],[["uc001cca.1"],"knownGene","uc001cca.1","chr1",38268613,38273865],[["uc001ccb.1"],"knownGene","uc001ccb.1","chr1",38272650,38275126],[["uc001ccd.2"],"knownGene","uc001ccd.2","chr1",38273472,38275126],[["uc010oii.1"],"knownGene","uc010oii.1","chr1",38273472,38275126],[["uc001cce.1"],"knownGene","uc001cce.1","chr1",38275238,38325292],[["uc009vvj.1"],"knownGene","uc009vvj.1","chr1",38287792,38325292],[["uc001ccg.1"],"knownGene","uc001ccg.1","chr1",38326368,38412729],[["uc009vvk.1"],"knownGene","uc009vvk.1","chr1",38326368,38411522],[["uc001ccf.1"],"knownGene","uc001ccf.1","chr1",38326368,38397421],[["uc010oij.1"],"knownGene","uc010oij.1","chr1",38339664,38355396],[["uc001cch.2"],"knownGene","uc001cch.2","chr1",38394213,38411522],[["uc001cci.2"],"knownGene","uc001cci.2","chr1",38422653,38455761],[["uc010oik.1"],"knownGene","uc010oik.1","chr1",38422653,38455761],[["uc001cck.2"],"knownGene","uc001cck.2","chr1",38462443,38471234],[["uc001ccl.2"],"knownGene","uc001ccl.2","chr1",38462443,38471234],[["uc001ccm.2"],"knownGene","uc001ccm.2","chr1",38462443,38471234],[["uc001ccj.2"],"knownGene","uc001ccj.2","chr1",38462443,38471177],[["uc009vvl.1"],"knownGene","uc009vvl.1","chr1",38463408,38471177],[["uc001ccn.3"],"knownGene","uc001ccn.3","chr1",38478383,38490496],[["uc009vvm.2"],"knownGene","uc009vvm.2","chr1",38478383,38490496],[["uc010oil.1"],"knownGene","uc010oil.1","chr1",38478383,38490496],[["uc001cco.3"],"knownGene","uc001cco.3","chr1",38482254,38490496],[["uc001ccp.1"],"knownGene","uc001ccp.1","chr1",38509522,38512450],[["uc001ccr.2"],"knownGene","uc001ccr.2","chr1",39305014,39340166],[["uc001ccq.2"],"knownGene","uc001ccq.2","chr1",39305014,39325340],[["uc010oim.1"],"knownGene","uc010oim.1","chr1",39305014,39325340],[["uc001ccs.2"],"knownGene","uc001ccs.2","chr1",39328636,39339050],[["uc001cct.1"],"knownGene","uc001cct.1","chr1",39339266,39347289],[["uc001ccu.1"],"knownGene","uc001ccu.1","chr1",39351478,39407456],[["uc010oio.1"],"knownGene","uc010oio.1","chr1",39351478,39395185],[["uc010oin.1"],"knownGene","uc010oin.1","chr1",39351478,39385009],[["uc001ccv.2"],"knownGene","uc001ccv.2","chr1",39381176,39407456],[["uc001ccw.2"],"knownGene","uc001ccw.2","chr1",39456915,39471735],[["uc010oip.1"],"knownGene","uc010oip.1","chr1",39456915,39471735],[["uc010oiq.1"],"knownGene","uc010oiq.1","chr1",39456915,39471735],[["uc001ccx.2"],"knownGene","uc001ccx.2","chr1",39492005,39500286],[["uc001ccy.2"],"knownGene","uc001ccy.2","chr1",39492044,39500286],[["uc010ois.1"],"knownGene","uc010ois.1","chr1",39547117,39952789],[["uc010oir.1"],"knownGene","uc010oir.1","chr1",39547117,39568889],[["uc001cda.1"],"knownGene","uc001cda.1","chr1",39587984,39901433],[["uc010oit.1"],"knownGene","uc010oit.1","chr1",39670422,39748740],[["uc001cdc.1"],"knownGene","uc001cdc.1","chr1",39765881,39901433],[["uc001cdb.1"],"knownGene","uc001cdb.1","chr1",39765881,39839145],[["uc009vvq.1"],"knownGene","uc009vvq.1","chr1",39765881,39790406],[["uc010oiu.1"],"knownGene","uc010oiu.1","chr1",39796809,39952789],[["uc009vvt.1"],"knownGene","uc009vvt.1","chr1",39875175,39882154],[["uc001cde.1"],"knownGene","uc001cde.1","chr1",39927554,39952789],[["uc001cdf.1"],"knownGene","uc001cdf.1","chr1",39927554,39952789],[["uc001cdg.2"],"knownGene","uc001cdg.2","chr1",39934268,39952654],[["uc001cdh.2"],"knownGene","uc001cdh.2","chr1",39934286,39952654],[["uc001cdi.2"],"knownGene","uc001cdi.2","chr1",39957317,39995537],[["uc001cdk.2"],"knownGene","uc001cdk.2","chr1",39987952,40025370],[["uc001cdj.1"],"knownGene","uc001cdj.1","chr1",39987952,39991357],[["uc001cdl.2"],"knownGene","uc001cdl.2","chr1",40026484,40042521],[["uc010oiv.1"],"knownGene","uc010oiv.1","chr1",40026484,40042521],[["uc001cdm.2"],"knownGene","uc001cdm.2","chr1",40026484,40042521],[["uc001cdo.1"],"knownGene","uc001cdo.1","chr1",40033045,40033182],[["uc001cdp.2"],"knownGene","uc001cdp.2","chr1",40089103,40105348],[["uc010oiw.1"],"knownGene","uc010oiw.1","chr1",40089103,40098672],[["uc001cdq.1"],"knownGene","uc001cdq.1","chr1",40124792,40137710],[["uc001cdr.2"],"knownGene","uc001cdr.2","chr1",40144651,40157089],[["uc010oix.1"],"knownGene","uc010oix.1","chr1",40144651,40157089],[["uc001cdv.2"],"knownGene","uc001cdv.2","chr1",40204529,40229585],[["uc001cdw.2"],"knownGene","uc001cdw.2","chr1",40204529,40229585],[["uc001cds.1"],"knownGene","uc001cds.1","chr1",40204529,40219378],[["uc001cdt.1"],"knownGene","uc001cdt.1","chr1",40204529,40219378],[["uc010oiy.1"],"knownGene","uc010oiy.1","chr1",40204529,40219378],[["uc001cdu.1"],"knownGene","uc001cdu.1","chr1",40204529,40219378],[["uc001cdx.1"],"knownGene","uc001cdx.1","chr1",40208176,40219378],[["uc001cdz.1"],"knownGene","uc001cdz.1","chr1",40223902,40254533],[["uc001cea.1"],"knownGene","uc001cea.1","chr1",40229222,40254533],[["uc001ceb.1"],"knownGene","uc001ceb.1","chr1",40235196,40237020],[["uc009vvu.1"],"knownGene","uc009vvu.1","chr1",40235202,40237017],[["uc010oiz.1"],"knownGene","uc010oiz.1","chr1",40306707,40349177],[["uc001ceq.2"],"knownGene","uc001ceq.2","chr1",40306707,40349177],[["uc001cek.2"],"knownGene","uc001cek.2","chr1",40306707,40349177],[["uc009vvx.2"],"knownGene","uc009vvx.2","chr1",40306707,40349177],[["uc001cel.2"],"knownGene","uc001cel.2","chr1",40306707,40349177],[["uc001cem.2"],"knownGene","uc001cem.2","chr1",40306707,40349177],[["uc001cen.2"],"knownGene","uc001cen.2","chr1",40306707,40349177],[["uc001ceo.2"],"knownGene","uc001ceo.2","chr1",40306707,40349177],[["uc001cep.2"],"knownGene","uc001cep.2","chr1",40306707,40349177],[["uc001cec.3"],"knownGene","uc001cec.3","chr1",40306707,40319738],[["uc001ced.3"],"knownGene","uc001ced.3","chr1",40306707,40319738],[["uc001cee.3"],"knownGene","uc001cee.3","chr1",40306707,40319738],[["uc001cef.3"],"knownGene","uc001cef.3","chr1",40306707,40319738],[["uc001ceg.3"],"knownGene","uc001ceg.3","chr1",40306707,40319738],[["uc001ceh.3"],"knownGene","uc001ceh.3","chr1",40306707,40319738],[["uc009vvv.2"],"knownGene","uc009vvv.2","chr1",40306707,40319738],[["uc001cei.3"],"knownGene","uc001cei.3","chr1",40306707,40319738],[["uc010oja.1"],"knownGene","uc010oja.1","chr1",40319464,40319738],[["uc001cer.1"],"knownGene","uc001cer.1","chr1",40361097,40367687],[["uc001ces.1"],"knownGene","uc001ces.1","chr1",40361097,40367687],[["uc001cet.1"],"knownGene","uc001cet.1","chr1",40365285,40367687],[["uc001cev.2"],"knownGene","uc001cev.2","chr1",40420783,40435627],[["uc001ceu.2"],"knownGene","uc001ceu.2","chr1",40420783,40435627],[["uc010ojc.1"],"knownGene","uc010ojc.1","chr1",40420783,40435627],[["uc009vvy.2"],"knownGene","uc009vvy.2","chr1",40420783,40435627],[["uc010ojb.1"],"knownGene","uc010ojb.1","chr1",40420783,40434417],[["uc001cew.1"],"knownGene","uc001cew.1","chr1",40420819,40422587],[["uc001cex.2"],"knownGene","uc001cex.2","chr1",40432749,40435627],[["uc001cfa.3"],"knownGene","uc001cfa.3","chr1",40506254,40538323],[["uc001cey.3"],"knownGene","uc001cey.3","chr1",40506254,40538323],[["uc001cez.3"],"knownGene","uc001cez.3","chr1",40506254,40538323],[["uc009vvz.2"],"knownGene","uc009vvz.2","chr1",40506254,40538323],[["uc010oje.1"],"knownGene","uc010oje.1","chr1",40506254,40538323],[["uc010ojd.1"],"knownGene","uc010ojd.1","chr1",40506254,40525833],[["uc001cfb.2"],"knownGene","uc001cfb.2","chr1",40538381,40563142],[["uc010ojg.1"],"knownGene","uc010ojg.1","chr1",40538381,40563142],[["uc009vwa.2"],"knownGene","uc009vwa.2","chr1",40538381,40563142],[["uc010ojf.1"],"knownGene","uc010ojf.1","chr1",40538381,40558179],[["uc001cfc.3"],"knownGene","uc001cfc.3","chr1",40627040,40706592],[["uc001cfd.3"],"knownGene","uc001cfd.3","chr1",40696475,40706592],[["uc001cfe.2"],"knownGene","uc001cfe.2","chr1",40713572,40717365],[["uc001cff.2"],"knownGene","uc001cff.2","chr1",40722099,40723658],[["uc001cfg.2"],"knownGene","uc001cfg.2","chr1",40723732,40759855],[["uc001cfi.1"],"knownGene","uc001cfi.1","chr1",40766162,40783060],[["uc001cfh.1"],"knownGene","uc001cfh.1","chr1",40766162,40782981],[["uc001cfj.2"],"knownGene","uc001cfj.2","chr1",40839727,40888992],[["uc010ojh.1"],"knownGene","uc010ojh.1","chr1",40839727,40882027],[["uc001cfk.2"],"knownGene","uc001cfk.2","chr1",40840316,40888992],[["uc010oji.1"],"knownGene","uc010oji.1","chr1",40862471,40888992],[["uc010ojj.1"],"knownGene","uc010ojj.1","chr1",40879644,40888992],[["uc001cfl.1"],"knownGene","uc001cfl.1","chr1",40915778,40929352],[["uc001cfm.1"],"knownGene","uc001cfm.1","chr1",40915778,40929352],[["uc001cfn.1"],"knownGene","uc001cfn.1","chr1",40916336,40929352],[["uc001cfo.2"],"knownGene","uc001cfo.2","chr1",40943301,40962014],[["uc009vwb.2"],"knownGene","uc009vwb.2","chr1",40943301,40962014],[["uc010ojk.1"],"knownGene","uc010ojk.1","chr1",40943301,40962014],[["uc001cfp.2"],"knownGene","uc001cfp.2","chr1",40974432,40982212],[["uc001cfq.2"],"knownGene","uc001cfq.2","chr1",40974432,40982212],[["uc001cfr.2"],"knownGene","uc001cfr.2","chr1",40974460,40982212],[["uc001cfs.2"],"knownGene","uc001cfs.2","chr1",40974469,40982212],[["uc001cft.1"],"knownGene","uc001cft.1","chr1",40997232,41013839],[["uc001cfu.1"],"knownGene","uc001cfu.1","chr1",41086351,41131324],[["uc001cfv.1"],"knownGene","uc001cfv.1","chr1",41086351,41131324],[["uc010ojl.1"],"knownGene","uc010ojl.1","chr1",41154751,41157933],[["uc001cfx.3"],"knownGene","uc001cfx.3","chr1",41157241,41237273],[["uc009vwd.2"],"knownGene","uc009vwd.2","chr1",41157241,41237273],[["uc001cfz.2"],"knownGene","uc001cfz.2","chr1",41157241,41237273],[["uc010ojn.1"],"knownGene","uc010ojn.1","chr1",41157241,41237273],[["uc001cfy.3"],"knownGene","uc001cfy.3","chr1",41157241,41237273],[["uc010ojm.1"],"knownGene","uc010ojm.1","chr1",41157241,41232915],[["uc001cgc.2"],"knownGene","uc001cgc.2","chr1",41157679,41237273],[["uc001cgb.2"],"knownGene","uc001cgb.2","chr1",41175037,41237273],[["uc001cgd.3"],"knownGene","uc001cgd.3","chr1",41201296,41237273],[["uc001cge.2"],"knownGene","uc001cge.2","chr1",41204507,41237273],[["uc001cgf.1"],"knownGene","uc001cgf.1","chr1",41220041,41220105],[["uc001cgg.2"],"knownGene","uc001cgg.2","chr1",41222955,41223043],[["uc001cgh.1"],"knownGene","uc001cgh.1","chr1",41249683,41304360],[["uc001cgi.1"],"knownGene","uc001cgi.1","chr1",41249683,41304360],[["uc001cgj.2"],"knownGene","uc001cgj.2","chr1",41326728,41328018],[["uc001cgk.3"],"knownGene","uc001cgk.3","chr1",41445006,41478231],[["uc010ojo.1"],"knownGene","uc010ojo.1","chr1",41445006,41478231],[["uc010ojp.1"],"knownGene","uc010ojp.1","chr1",41447600,41462029],[["uc001cgl.3"],"knownGene","uc001cgl.3","chr1",41448832,41478231],[["uc010ojq.1"],"knownGene","uc010ojq.1","chr1",41454190,41478231],[["uc009vwe.2"],"knownGene","uc009vwe.2","chr1",41461588,41478231],[["uc009vwg.1"],"knownGene","uc009vwg.1","chr1",41481268,41487397],[["uc001cgm.1"],"knownGene","uc001cgm.1","chr1",41481268,41487387],[["uc001cgn.1"],"knownGene","uc001cgn.1","chr1",41481268,41487387],[["uc009vwf.1"],"knownGene","uc009vwf.1","chr1",41481268,41486458],[["uc001cgq.2"],"knownGene","uc001cgq.2","chr1",41492874,41707788],[["uc001cgr.2"],"knownGene","uc001cgr.2","chr1",41492874,41707788],[["uc001cgs.2"],"knownGene","uc001cgs.2","chr1",41492874,41707788],[["uc001cgt.2"],"knownGene","uc001cgt.2","chr1",41492874,41707788],[["uc001cgp.2"],"knownGene","uc001cgp.2","chr1",41492874,41628689],[["uc001cgo.2"],"knownGene","uc001cgo.2","chr1",41492874,41627104],[["uc010ojr.1"],"knownGene","uc010ojr.1","chr1",41492874,41625605],[["uc010ojs.1"],"knownGene","uc010ojs.1","chr1",41494255,41625605],[["uc001cgx.2"],"knownGene","uc001cgx.2","chr1",41944448,41950344],[["uc001cgu.2"],"knownGene","uc001cgu.2","chr1",41944448,41949874],[["uc001cgv.2"],"knownGene","uc001cgv.2","chr1",41944448,41949874],[["uc009vwh.2"],"knownGene","uc009vwh.2","chr1",41944448,41949874],[["uc001cgw.2"],"knownGene","uc001cgw.2","chr1",41944448,41949874],[["uc009vwi.2"],"knownGene","uc009vwi.2","chr1",41944448,41949874],[["uc009vwj.2"],"knownGene","uc009vwj.2","chr1",41944448,41949874],[["uc001cgz.3"],"knownGene","uc001cgz.3","chr1",41975684,42384496],[["uc001cha.3"],"knownGene","uc001cha.3","chr1",41975684,42384496],[["uc001cgy.2"],"knownGene","uc001cgy.2","chr1",41975684,42050989],[["uc001chb.1"],"knownGene","uc001chb.1","chr1",42312861,42501596],[["uc001chc.1"],"knownGene","uc001chc.1","chr1",42619091,42621495],[["uc001chd.1"],"knownGene","uc001chd.1","chr1",42628361,42630395],[["uc001chg.2"],"knownGene","uc001chg.2","chr1",42642210,42801548],[["uc001chf.2"],"knownGene","uc001chf.2","chr1",42642210,42800903],[["uc001che.2"],"knownGene","uc001che.2","chr1",42642210,42800636],[["uc001chh.1"],"knownGene","uc001chh.1","chr1",42656973,42800903],[["uc001chi.2"],"knownGene","uc001chi.2","chr1",42846467,42889900],[["uc001chj.2"],"knownGene","uc001chj.2","chr1",42896002,42921938],[["uc010ojt.1"],"knownGene","uc010ojt.1","chr1",42896002,42921938],[["uc001chk.2"],"knownGene","uc001chk.2","chr1",42922172,42926085],[["uc001chl.2"],"knownGene","uc001chl.2","chr1",42922172,42926085],[["uc001chm.2"],"knownGene","uc001chm.2","chr1",42929024,43120335],[["uc001chn.2"],"knownGene","uc001chn.2","chr1",42955599,43120335],[["uc010oju.1"],"knownGene","uc010oju.1","chr1",42962768,43047185],[["uc009vwk.1"],"knownGene","uc009vwk.1","chr1",43000559,43120335],[["uc001chp.2"],"knownGene","uc001chp.2","chr1",43002146,43061217],[["uc001chq.2"],"knownGene","uc001chq.2","chr1",43124047,43142428],[["uc009vwl.2"],"knownGene","uc009vwl.2","chr1",43124047,43133568],[["uc001chr.2"],"knownGene","uc001chr.2","chr1",43144356,43147329],[["uc001chs.2"],"knownGene","uc001chs.2","chr1",43148065,43168017],[["uc001cht.1"],"knownGene","uc001cht.1","chr1",43198763,43205925],[["uc001chu.2"],"knownGene","uc001chu.2","chr1",43198763,43205925],[["uc010ojv.1"],"knownGene","uc010ojv.1","chr1",43198763,43205925],[["uc001chv.2"],"knownGene","uc001chv.2","chr1",43212005,43232755],[["uc001chw.2"],"knownGene","uc001chw.2","chr1",43212005,43232755],[["uc001chx.3"],"knownGene","uc001chx.3","chr1",43212045,43232755],[["uc001chy.3"],"knownGene","uc001chy.3","chr1",43225667,43232755],[["uc001chz.2"],"knownGene","uc001chz.2","chr1",43231122,43232696],[["uc001cia.3"],"knownGene","uc001cia.3","chr1",43232915,43241414],[["uc001cib.2"],"knownGene","uc001cib.2","chr1",43272722,43283059],[["uc001cic.1"],"knownGene","uc001cic.1","chr1",43282775,43310660],[["uc001cid.1"],"knownGene","uc001cid.1","chr1",43282775,43310660],[["uc010ojw.1"],"knownGene","uc010ojw.1","chr1",43282775,43305384],[["uc001cie.1"],"knownGene","uc001cie.1","chr1",43291248,43310660],[["uc001cif.1"],"knownGene","uc001cif.1","chr1",43295585,43310660],[["uc001cig.2"],"knownGene","uc001cig.2","chr1",43312279,43318144],[["uc009vwm.2"],"knownGene","uc009vwm.2","chr1",43312279,43318144],[["uc001cih.2"],"knownGene","uc001cih.2","chr1",43314961,43318144],[["uc001cij.1"],"knownGene","uc001cij.1","chr1",43323292,43354460],[["uc001cik.2"],"knownGene","uc001cik.2","chr1",43391045,43424847],[["uc001cil.2"],"knownGene","uc001cil.2","chr1",43424774,43448990],[["uc009vwn.1"],"knownGene","uc009vwn.1","chr1",43585818,43611958],[["uc009vwo.2"],"knownGene","uc009vwo.2","chr1",43613593,43622064],[["uc001cio.2"],"knownGene","uc001cio.2","chr1",43629845,43736607],[["uc010ojx.1"],"knownGene","uc010ojx.1","chr1",43629845,43638241],[["uc001cin.2"],"knownGene","uc001cin.2","chr1",43629845,43637986],[["uc001cim.2"],"knownGene","uc001cim.2","chr1",43629845,43637649],[["uc010ojy.1"],"knownGene","uc010ojy.1","chr1",43637279,43637416],[["uc001cip.1"],"knownGene","uc001cip.1","chr1",43638025,43676549],[["uc001ciq.1"],"knownGene","uc001ciq.1","chr1",43638025,43676549],[["uc010ojz.1"],"knownGene","uc010ojz.1","chr1",43638025,43675788],[["uc001cir.2"],"knownGene","uc001cir.2","chr1",43735695,43739672],[["uc001cis.2"],"knownGene","uc001cis.2","chr1",43736256,43739672],[["uc001cit.3"],"knownGene","uc001cit.3","chr1",43747558,43751250],[["uc001ciu.2"],"knownGene","uc001ciu.2","chr1",43766663,43788778],[["uc010oke.1"],"knownGene","uc010oke.1","chr1",43766663,43788778],[["uc009vwq.2"],"knownGene","uc009vwq.2","chr1",43766663,43788778],[["uc010okd.1"],"knownGene","uc010okd.1","chr1",43766663,43779133],[["uc010okc.1"],"knownGene","uc010okc.1","chr1",43766663,43775203],[["uc010okb.1"],"knownGene","uc010okb.1","chr1",43766663,43772781],[["uc010oka.1"],"knownGene","uc010oka.1","chr1",43766663,43770948],[["uc010okf.1"],"knownGene","uc010okf.1","chr1",43770604,43779817],[["uc010okg.1"],"knownGene","uc010okg.1","chr1",43772812,43788778],[["uc001ciw.2"],"knownGene","uc001ciw.2","chr1",43803474,43820134],[["uc009vwr.2"],"knownGene","uc009vwr.2","chr1",43803474,43820134],[["uc001civ.2"],"knownGene","uc001civ.2","chr1",43803474,43815206],[["uc001cix.2"],"knownGene","uc001cix.2","chr1",43824625,43828871],[["uc001ciy.2"],"knownGene","uc001ciy.2","chr1",43824691,43828871],[["uc001cjb.2"],"knownGene","uc001cjb.2","chr1",43829072,43833699],[["uc001cjc.2"],"knownGene","uc001cjc.2","chr1",43829072,43833699],[["uc010okh.1"],"knownGene","uc010okh.1","chr1",43829072,43833699],[["uc001cja.2"],"knownGene","uc001cja.2","chr1",43829072,43833361],[["uc001ciz.2"],"knownGene","uc001ciz.2","chr1",43829072,43833087],[["uc001cje.1"],"knownGene","uc001cje.1","chr1",43849587,43855483],[["uc001cjg.3"],"knownGene","uc001cjg.3","chr1",43850397,43855483],[["uc001cjf.3"],"knownGene","uc001cjf.3","chr1",43850397,43855483],[["uc009vws.1"],"knownGene","uc009vws.1","chr1",43855555,43892209],[["uc001cji.1"],"knownGene","uc001cji.1","chr1",43855555,43878462],[["uc001cjh.2"],"knownGene","uc001cjh.2","chr1",43855555,43872564],[["uc001cjk.1"],"knownGene","uc001cjk.1","chr1",43888769,43918304],[["uc001cjl.1"],"knownGene","uc001cjl.1","chr1",43910922,43918304],[["uc001cjp.2"],"knownGene","uc001cjp.2","chr1",43916830,43919918],[["uc001cjn.2"],"knownGene","uc001cjn.2","chr1",43916830,43919634],[["uc001cjo.2"],"knownGene","uc001cjo.2","chr1",43916830,43919634],[["uc001cjm.2"],"knownGene","uc001cjm.2","chr1",43916830,43919176],[["uc001cjr.2"],"knownGene","uc001cjr.2","chr1",43996546,44089342],[["uc001cjs.2"],"knownGene","uc001cjs.2","chr1",43996546,44089342],[["uc001cjq.3"],"knownGene","uc001cjq.3","chr1",43996546,44045732],[["uc001cjt.3"],"knownGene","uc001cjt.3","chr1",44003868,44045732],[["uc001cju.2"],"knownGene","uc001cju.2","chr1",44056642,44089342],[["uc009vwt.2"],"knownGene","uc009vwt.2","chr1",44056642,44089342],[["uc001cjv.2"],"knownGene","uc001cjv.2","chr1",44056642,44089342],[["uc001cjw.2"],"knownGene","uc001cjw.2","chr1",44063744,44089342],[["uc001cjx.2"],"knownGene","uc001cjx.2","chr1",44115796,44171188],[["uc010oki.1"],"knownGene","uc010oki.1","chr1",44115796,44171188],[["uc001cjy.2"],"knownGene","uc001cjy.2","chr1",44165357,44173012],[["uc009vwu.1"],"knownGene","uc009vwu.1","chr1",44171494,44360149],[["uc001cjz.2"],"knownGene","uc001cjz.2","chr1",44173217,44396830],[["uc001cka.2"],"knownGene","uc001cka.2","chr1",44173217,44396830],[["uc001ckb.2"],"knownGene","uc001ckb.2","chr1",44173217,44396830],[["uc001ckc.2"],"knownGene","uc001ckc.2","chr1",44173217,44396830],[["uc001ckd.2"],"knownGene","uc001ckd.2","chr1",44173217,44396830],[["uc001cke.2"],"knownGene","uc001cke.2","chr1",44173217,44396830],[["uc001ckf.2"],"knownGene","uc001ckf.2","chr1",44173217,44396830],[["uc001ckg.2"],"knownGene","uc001ckg.2","chr1",44173217,44396830],[["uc001ckh.2"],"knownGene","uc001ckh.2","chr1",44173217,44396830],[["uc001cki.2"],"knownGene","uc001cki.2","chr1",44173217,44396830],[["uc010okj.1"],"knownGene","uc010okj.1","chr1",44173217,44385889],[["uc009vwv.2"],"knownGene","uc009vwv.2","chr1",44201903,44396830],[["uc001ckj.2"],"knownGene","uc001ckj.2","chr1",44201903,44396830],[["uc009vww.2"],"knownGene","uc009vww.2","chr1",44201903,44396830],[["uc001ckk.2"],"knownGene","uc001ckk.2","chr1",44201903,44396830],[["uc009vwy.2"],"knownGene","uc009vwy.2","chr1",44201903,44396830],[["uc009vwx.2"],"knownGene","uc009vwx.2","chr1",44201903,44396830],[["uc001ckm.2"],"knownGene","uc001ckm.2","chr1",44201903,44396830],[["uc001ckl.2"],"knownGene","uc001ckl.2","chr1",44201903,44396830],[["uc009vwz.2"],"knownGene","uc009vwz.2","chr1",44201903,44396830],[["uc001ckn.2"],"knownGene","uc001ckn.2","chr1",44201903,44396830],[["uc001ckp.2"],"knownGene","uc001ckp.2","chr1",44201903,44396830],[["uc001cko.2"],"knownGene","uc001cko.2","chr1",44201903,44396830],[["uc009vxa.2"],"knownGene","uc009vxa.2","chr1",44201903,44396830],[["uc001ckq.2"],"knownGene","uc001ckq.2","chr1",44201903,44396830],[["uc001ckr.2"],"knownGene","uc001ckr.2","chr1",44201903,44396830],[["uc009vxb.2"],"knownGene","uc009vxb.2","chr1",44201903,44396830],[["uc001cks.2"],"knownGene","uc001cks.2","chr1",44398991,44402911],[["uc001ckv.2"],"knownGene","uc001ckv.2","chr1",44398991,44402911],[["uc001ckt.2"],"knownGene","uc001ckt.2","chr1",44398991,44402911],[["uc001cku.2"],"knownGene","uc001cku.2","chr1",44401030,44402911],[["uc001ckw.2"],"knownGene","uc001ckw.2","chr1",44401653,44402911],[["uc001ckx.2"],"knownGene","uc001ckx.2","chr1",44412477,44433693],[["uc001cky.2"],"knownGene","uc001cky.2","chr1",44431610,44433693],[["uc001ckz.2"],"knownGene","uc001ckz.2","chr1",44435652,44439044],[["uc001cla.2"],"knownGene","uc001cla.2","chr1",44435652,44439044],[["uc010okk.1"],"knownGene","uc010okk.1","chr1",44435652,44439044],[["uc001clb.2"],"knownGene","uc001clb.2","chr1",44435681,44439044],[["uc001cld.2"],"knownGene","uc001cld.2","chr1",44440601,44443971],[["uc001cle.2"],"knownGene","uc001cle.2","chr1",44440601,44443971],[["uc001clc.2"],"knownGene","uc001clc.2","chr1",44440601,44443966],[["uc001clf.2"],"knownGene","uc001clf.2","chr1",44440642,44443966],[["uc001clg.2"],"knownGene","uc001clg.2","chr1",44444865,44456839],[["uc001clh.2"],"knownGene","uc001clh.2","chr1",44444865,44456839],[["uc010okl.1"],"knownGene","uc010okl.1","chr1",44445658,44456839],[["uc001cli.2"],"knownGene","uc001cli.2","chr1",44446182,44456839],[["uc010okm.1"],"knownGene","uc010okm.1","chr1",44457171,44497134],[["uc009vxe.2"],"knownGene","uc009vxe.2","chr1",44457171,44482228],[["uc001clj.2"],"knownGene","uc001clj.2","chr1",44457279,44462196],[["uc001clk.2"],"knownGene","uc001clk.2","chr1",44457473,44462196],[["uc009vxc.2"],"knownGene","uc009vxc.2","chr1",44457518,44462196],[["uc001cln.2"],"knownGene","uc001cln.2","chr1",44462155,44497134],[["uc010oko.1"],"knownGene","uc010oko.1","chr1",44462155,44497134],[["uc001cll.2"],"knownGene","uc001cll.2","chr1",44462155,44482997],[["uc001clm.2"],"knownGene","uc001clm.2","chr1",44462155,44482997],[["uc009vxd.2"],"knownGene","uc009vxd.2","chr1",44462155,44482997],[["uc010okn.1"],"knownGene","uc010okn.1","chr1",44462155,44482997],[["uc010okp.1"],"knownGene","uc010okp.1","chr1",44466438,44497134],[["uc009vxf.1"],"knownGene","uc009vxf.1","chr1",44514029,44595868],[["uc001clp.2"],"knownGene","uc001clp.2","chr1",44584521,44600807],[["uc001clq.1"],"knownGene","uc001clq.1","chr1",44679124,44686351],[["uc001clr.1"],"knownGene","uc001clr.1","chr1",44679124,44686351],[["uc001cls.1"],"knownGene","uc001cls.1","chr1",44679124,44686351],[["uc010oku.1"],"knownGene","uc010oku.1","chr1",44679124,44686351],[["uc010okt.1"],"knownGene","uc010okt.1","chr1",44679124,44684427],[["uc010oks.1"],"knownGene","uc010oks.1","chr1",44679124,44681440],[["uc010okq.1"],"knownGene","uc010okq.1","chr1",44679124,44681197],[["uc010okr.1"],"knownGene","uc010okr.1","chr1",44679124,44681197],[["uc001clt.2"],"knownGene","uc001clt.2","chr1",44686742,44820939],[["uc009vxg.2"],"knownGene","uc009vxg.2","chr1",44686742,44820939],[["uc010okw.1"],"knownGene","uc010okw.1","chr1",44686742,44820939],[["uc001clu.2"],"knownGene","uc001clu.2","chr1",44686742,44820939],[["uc010okv.1"],"knownGene","uc010okv.1","chr1",44686742,44818597],[["uc001clv.1"],"knownGene","uc001clv.1","chr1",44870959,45117396],[["uc001clw.1"],"knownGene","uc001clw.1","chr1",44871049,45117396],[["uc010oky.1"],"knownGene","uc010oky.1","chr1",44889495,45117396],[["uc010okx.1"],"knownGene","uc010okx.1","chr1",44889495,45110466],[["uc001clx.1"],"knownGene","uc001clx.1","chr1",45097651,45117396],[["uc010okz.1"],"knownGene","uc010okz.1","chr1",45097651,45117395],[["uc001cly.1"],"knownGene","uc001cly.1","chr1",45097663,45117396],[["uc001clz.1"],"knownGene","uc001clz.1","chr1",45097926,45117396],[["uc001cma.1"],"knownGene","uc001cma.1","chr1",45098014,45117395],[["uc001cmb.1"],"knownGene","uc001cmb.1","chr1",45100938,45140099],[["uc001cmc.2"],"knownGene","uc001cmc.2","chr1",45119501,45140099],[["uc001cmd.2"],"knownGene","uc001cmd.2","chr1",45119501,45140099],[["uc009vxh.1"],"knownGene","uc009vxh.1","chr1",45119653,45139750],[["uc010ola.1"],"knownGene","uc010ola.1","chr1",45119908,45125967],[["uc001cmf.2"],"knownGene","uc001cmf.2","chr1",45140393,45191263],[["uc001cmg.3"],"knownGene","uc001cmg.3","chr1",45205489,45233436],[["uc010olb.1"],"knownGene","uc010olb.1","chr1",45205489,45233436],[["uc010olc.1"],"knownGene","uc010olc.1","chr1",45212065,45233436],[["uc001cmh.3"],"knownGene","uc001cmh.3","chr1",45212084,45233436],[["uc001cmi.2"],"knownGene","uc001cmi.2","chr1",45241245,45244411],[["uc001cmj.1"],"knownGene","uc001cmj.1","chr1",45241536,45241610],[["uc001cmk.1"],"knownGene","uc001cmk.1","chr1",45242163,45242261],[["uc009vxi.2"],"knownGene","uc009vxi.2","chr1",45243513,45243582],[["uc001cml.2"],"knownGene","uc001cml.2","chr1",45244061,45244129],[["uc001cmm.2"],"knownGene","uc001cmm.2","chr1",45249258,45253426],[["uc001cmn.2"],"knownGene","uc001cmn.2","chr1",45266035,45271666],[["uc001cmo.2"],"knownGene","uc001cmo.2","chr1",45266707,45271666],[["uc001cmp.2"],"knownGene","uc001cmp.2","chr1",45271589,45272957],[["uc010ole.1"],"knownGene","uc010ole.1","chr1",45274153,45279801],[["uc010old.1"],"knownGene","uc010old.1","chr1",45274153,45279171],[["uc010olf.1"],"knownGene","uc010olf.1","chr1",45288087,45308616],[["uc010olg.1"],"knownGene","uc010olg.1","chr1",45288087,45308616],[["uc001cmt.1"],"knownGene","uc001cmt.1","chr1",45316449,45452282],[["uc001cmu.1"],"knownGene","uc001cmu.1","chr1",45316449,45452282],[["uc001cmv.1"],"knownGene","uc001cmv.1","chr1",45316449,45452282],[["uc001cmw.2"],"knownGene","uc001cmw.2","chr1",45340224,45452282],[["uc009vxk.2"],"knownGene","uc009vxk.2","chr1",45468220,45477027],[["uc010olh.1"],"knownGene","uc010olh.1","chr1",45468220,45477027],[["uc001cmy.3"],"knownGene","uc001cmy.3","chr1",45468220,45474223],[["uc001cmx.3"],"knownGene","uc001cmx.3","chr1",45468220,45471260],[["uc001cna.1"],"knownGene","uc001cna.1","chr1",45477829,45481341],[["uc001cnb.1"],"knownGene","uc001cnb.1","chr1",45477829,45481341],[["uc010oli.1"],"knownGene","uc010oli.1","chr1",45477829,45479662],[["uc010olj.1"],"knownGene","uc010olj.1","chr1",45478480,45480508],[["uc001cnc.1"],"knownGene","uc001cnc.1","chr1",45478528,45481341],[["uc001cnd.2"],"knownGene","uc001cnd.2","chr1",45482075,45672250],[["uc010olk.1"],"knownGene","uc010olk.1","chr1",45769581,45771290],[["uc001cne.2"],"knownGene","uc001cne.2","chr1",45792544,45794344],[["uc001cno.2"],"knownGene","uc001cno.2","chr1",45794914,45806142],[["uc001cnk.2"],"knownGene","uc001cnk.2","chr1",45794914,45806142],[["uc010oll.1"],"knownGene","uc010oll.1","chr1",45794914,45806142],[["uc001cnm.2"],"knownGene","uc001cnm.2","chr1",45794914,45806142],[["uc001cnl.2"],"knownGene","uc001cnl.2","chr1",45794914,45806142],[["uc009vxp.2"],"knownGene","uc009vxp.2","chr1",45794914,45806142],[["uc001cnn.2"],"knownGene","uc001cnn.2","chr1",45794914,45806142],[["uc001cnj.2"],"knownGene","uc001cnj.2","chr1",45794914,45805787],[["uc001cni.2"],"knownGene","uc001cni.2","chr1",45794914,45805787],[["uc001cnh.2"],"knownGene","uc001cnh.2","chr1",45794914,45805787],[["uc001cnf.2"],"knownGene","uc001cnf.2","chr1",45794914,45805629],[["uc009vxo.2"],"knownGene","uc009vxo.2","chr1",45794914,45805629],[["uc001cng.2"],"knownGene","uc001cng.2","chr1",45794914,45805629],[["uc009vxn.2"],"knownGene","uc009vxn.2","chr1",45794914,45800183],[["uc009vxq.2"],"knownGene","uc009vxq.2","chr1",45805341,45809649],[["uc001cnq.3"],"knownGene","uc001cnq.3","chr1",45805341,45809649],[["uc010olm.1"],"knownGene","uc010olm.1","chr1",45805341,45809649],[["uc010oln.1"],"knownGene","uc010oln.1","chr1",45805883,45808674],[["uc001cnr.3"],"knownGene","uc001cnr.3","chr1",45805892,45809649],[["uc001cns.1"],"knownGene","uc001cns.1","chr1",45809554,45956840],[["uc010olo.1"],"knownGene","uc010olo.1","chr1",45809554,45956840],[["uc009vxs.1"],"knownGene","uc009vxs.1","chr1",45809554,45956840],[["uc009vxr.1"],"knownGene","uc009vxr.1","chr1",45809554,45923543],[["uc010olp.1"],"knownGene","uc010olp.1","chr1",45864143,45956840],[["uc001cnw.2"],"knownGene","uc001cnw.2","chr1",45960580,45965646],[["uc001cnu.2"],"knownGene","uc001cnu.2","chr1",45960580,45965646],[["uc009vxt.1"],"knownGene","uc009vxt.1","chr1",45960580,45965646],[["uc001cnv.2"],"knownGene","uc001cnv.2","chr1",45960580,45965646],[["uc009vxu.1"],"knownGene","uc009vxu.1","chr1",45960580,45965646],[["uc001cnt.2"],"knownGene","uc001cnt.2","chr1",45960580,45964294],[["uc009vxv.2"],"knownGene","uc009vxv.2","chr1",45965855,45976737],[["uc001cny.2"],"knownGene","uc001cny.2","chr1",45965855,45976737],[["uc001coa.2"],"knownGene","uc001coa.2","chr1",45976707,45987609],[["uc001cob.2"],"knownGene","uc001cob.2","chr1",45976707,45987609],[["uc001coc.2"],"knownGene","uc001coc.2","chr1",45976707,45987609],[["uc001cnz.2"],"knownGene","uc001cnz.2","chr1",45976707,45984747],[["uc001cod.2"],"knownGene","uc001cod.2","chr1",46016497,46035720],[["uc001coe.2"],"knownGene","uc001coe.2","chr1",46016497,46035720],[["uc009vxw.2"],"knownGene","uc009vxw.2","chr1",46016497,46033753],[["uc001cof.2"],"knownGene","uc001cof.2","chr1",46033220,46035720],[["uc001cog.2"],"knownGene","uc001cog.2","chr1",46033653,46035720],[["uc001coh.1"],"knownGene","uc001coh.1","chr1",46049716,46084567],[["uc001coi.1"],"knownGene","uc001coi.1","chr1",46049716,46084567],[["uc001coj.1"],"knownGene","uc001coj.1","chr1",46049716,46084567],[["uc010olr.1"],"knownGene","uc010olr.1","chr1",46049716,46084567],[["uc010olq.1"],"knownGene","uc010olq.1","chr1",46049716,46078920],[["uc001cok.1"],"knownGene","uc001cok.1","chr1",46067732,46075186],[["uc001col.1"],"knownGene","uc001col.1","chr1",46077134,46084567],[["uc009vxy.2"],"knownGene","uc009vxy.2","chr1",46085716,46089729],[["uc010ols.1"],"knownGene","uc010ols.1","chr1",46085716,46089729],[["uc010olt.1"],"knownGene","uc010olt.1","chr1",46085716,46089729],[["uc001com.3"],"knownGene","uc001com.3","chr1",46085716,46089729],[["uc001con.3"],"knownGene","uc001con.3","chr1",46085716,46089729],[["uc009vxz.2"],"knownGene","uc009vxz.2","chr1",46085716,46089729],[["uc001coq.2"],"knownGene","uc001coq.2","chr1",46092977,46152302],[["uc001coo.2"],"knownGene","uc001coo.2","chr1",46092977,46101396],[["uc010olu.1"],"knownGene","uc010olu.1","chr1",46111451,46112357],[["uc001cor.1"],"knownGene","uc001cor.1","chr1",46153846,46160108],[["uc001cos.3"],"knownGene","uc001cos.3","chr1",46159999,46216485],[["uc001cou.2"],"knownGene","uc001cou.2","chr1",46164408,46216485],[["uc001cov.2"],"knownGene","uc001cov.2","chr1",46269284,46501797],[["uc001cow.2"],"knownGene","uc001cow.2","chr1",46269284,46501797],[["uc001coy.1"],"knownGene","uc001coy.1","chr1",46330049,46496962],[["uc001cox.1"],"knownGene","uc001cox.1","chr1",46330049,46472067],[["uc001coz.1"],"knownGene","uc001coz.1","chr1",46379259,46496433],[["uc009vya.2"],"knownGene","uc009vya.2","chr1",46379264,46489943],[["uc001cpa.2"],"knownGene","uc001cpa.2","chr1",46471912,46501793],[["uc010olw.1"],"knownGene","uc010olw.1","chr1",46505812,46642160],[["uc001cpc.3"],"knownGene","uc001cpc.3","chr1",46505812,46598708],[["uc009vyc.2"],"knownGene","uc009vyc.2","chr1",46505812,46598467],[["uc001cpb.3"],"knownGene","uc001cpb.3","chr1",46505812,46598380],[["uc009vyb.2"],"knownGene","uc009vyb.2","chr1",46505812,46598380],[["uc010olv.1"],"knownGene","uc010olv.1","chr1",46505812,46527810],[["uc001cpd.2"],"knownGene","uc001cpd.2","chr1",46640758,46651630],[["uc009vyd.1"],"knownGene","uc009vyd.1","chr1",46646197,46651630],[["uc001cpg.2"],"knownGene","uc001cpg.2","chr1",46654353,46685977],[["uc001cpf.2"],"knownGene","uc001cpf.2","chr1",46654353,46685977],[["uc001cpe.2"],"knownGene","uc001cpe.2","chr1",46654353,46664121],[["uc010olz.1"],"knownGene","uc010olz.1","chr1",46654353,46663171],[["uc010olx.1"],"knownGene","uc010olx.1","chr1",46654353,46663145],[["uc010oly.1"],"knownGene","uc010oly.1","chr1",46654353,46663145],[["uc001cpi.1"],"knownGene","uc001cpi.1","chr1",46655788,46659597],[["uc001cph.1"],"knownGene","uc001cph.1","chr1",46655788,46658237],[["uc001cpj.2"],"knownGene","uc001cpj.2","chr1",46661158,46663779],[["uc010oma.1"],"knownGene","uc010oma.1","chr1",46669005,46686927],[["uc009vye.2"],"knownGene","uc009vye.2","chr1",46713366,46744145],[["uc001cpl.2"],"knownGene","uc001cpl.2","chr1",46713366,46744145],[["uc001cpm.1"],"knownGene","uc001cpm.1","chr1",46724357,46744145],[["uc001cpn.2"],"knownGene","uc001cpn.2","chr1",46744072,46769038],[["uc010omb.1"],"knownGene","uc010omb.1","chr1",46744679,46769038],[["uc001cpo.1"],"knownGene","uc001cpo.1","chr1",46750676,46769038],[["uc001cpp.2"],"knownGene","uc001cpp.2","chr1",46769379,46782445],[["uc001cpq.2"],"knownGene","uc001cpq.2","chr1",46769379,46782445],[["uc001cpr.1"],"knownGene","uc001cpr.1","chr1",46806389,46830690],[["uc010omc.1"],"knownGene","uc010omc.1","chr1",46806389,46830690],[["uc009vyf.1"],"knownGene","uc009vyf.1","chr1",46806389,46830690],[["uc009vyg.1"],"knownGene","uc009vyg.1","chr1",46806875,46830690],[["uc001cpt.1"],"knownGene","uc001cpt.1","chr1",46807507,46830690],[["uc001cps.1"],"knownGene","uc001cps.1","chr1",46807507,46830690],[["uc001cpu.2"],"knownGene","uc001cpu.2","chr1",46859938,46879520],[["uc001cpv.2"],"knownGene","uc001cpv.2","chr1",46871259,46879520],[["uc001cpx.2"],"knownGene","uc001cpx.2","chr1",46972667,46979884],[["uc001cpw.2"],"knownGene","uc001cpw.2","chr1",46972667,46979884],[["uc009vyh.1"],"knownGene","uc009vyh.1","chr1",47011315,47016887],[["uc001cpy.2"],"knownGene","uc001cpy.2","chr1",47011315,47015678],[["uc001cqb.2"],"knownGene","uc001cqb.2","chr1",47023090,47069966],[["uc010omd.1"],"knownGene","uc010omd.1","chr1",47023090,47069966],[["uc001cqc.2"],"knownGene","uc001cqc.2","chr1",47023090,47069966],[["uc009vyi.2"],"knownGene","uc009vyi.2","chr1",47023090,47069966],[["uc010ome.1"],"knownGene","uc010ome.1","chr1",47023090,47069966],[["uc009vyj.2"],"knownGene","uc009vyj.2","chr1",47027154,47069966],[["uc001cqd.2"],"knownGene","uc001cqd.2","chr1",47034114,47069966],[["uc010omf.1"],"knownGene","uc010omf.1","chr1",47040146,47082563],[["uc001cqf.3"],"knownGene","uc001cqf.3","chr1",47073387,47082563],[["uc001cqe.3"],"knownGene","uc001cqe.3","chr1",47073387,47080805],[["uc001cqh.2"],"knownGene","uc001cqh.2","chr1",47098412,47134099],[["uc001cqi.2"],"knownGene","uc001cqi.2","chr1",47098412,47134099],[["uc009vyk.2"],"knownGene","uc009vyk.2","chr1",47098412,47131527],[["uc010omg.1"],"knownGene","uc010omg.1","chr1",47098412,47131527],[["uc001cqg.2"],"knownGene","uc001cqg.2","chr1",47098412,47131044],[["uc010omh.1"],"knownGene","uc010omh.1","chr1",47124358,47184736],[["uc001cqj.2"],"knownGene","uc001cqj.2","chr1",47137499,47139249],[["uc010omi.1"],"knownGene","uc010omi.1","chr1",47137499,47139166],[["uc001cqk.3"],"knownGene","uc001cqk.3","chr1",47140831,47184736],[["uc010omj.1"],"knownGene","uc010omj.1","chr1",47140831,47173723],[["uc001cql.1"],"knownGene","uc001cql.1","chr1",47149834,47184736],[["uc001cqn.3"],"knownGene","uc001cqn.3","chr1",47264669,47285020],[["uc001cqm.3"],"knownGene","uc001cqm.3","chr1",47264669,47285020],[["uc009vym.2"],"knownGene","uc009vym.2","chr1",47264669,47285020],[["uc010omk.1"],"knownGene","uc010omk.1","chr1",47264669,47285020],[["uc009vyl.1"],"knownGene","uc009vyl.1","chr1",47264669,47281083],[["uc010oml.1"],"knownGene","uc010oml.1","chr1",47276744,47279987],[["uc001cqo.1"],"knownGene","uc001cqo.1","chr1",47323905,47366147],[["uc009vyn.1"],"knownGene","uc009vyn.1","chr1",47333618,47366147],[["uc001cqp.3"],"knownGene","uc001cqp.3","chr1",47394847,47407156],[["uc001cqq.2"],"knownGene","uc001cqq.2","chr1",47397180,47407156],[["uc010omm.1"],"knownGene","uc010omm.1","chr1",47399624,47407156],[["uc001cqr.2"],"knownGene","uc001cqr.2","chr1",47427035,47516422],[["uc001cqs.2"],"knownGene","uc001cqs.2","chr1",47469911,47516422],[["uc001cqt.2"],"knownGene","uc001cqt.2","chr1",47489239,47516422],[["uc001cqu.1"],"knownGene","uc001cqu.1","chr1",47533159,47583992],[["uc001cqv.1"],"knownGene","uc001cqv.1","chr1",47603106,47614526],[["uc009vyo.2"],"knownGene","uc009vyo.2","chr1",47603106,47613151],[["uc009vyp.2"],"knownGene","uc009vyp.2","chr1",47603106,47613151],[["uc001cqw.2"],"knownGene","uc001cqw.2","chr1",47649261,47655771],[["uc001cqy.2"],"knownGene","uc001cqy.2","chr1",47681962,47697387],[["uc001cqx.2"],"knownGene","uc001cqx.2","chr1",47681962,47695443],[["uc009vyq.2"],"knownGene","uc009vyq.2","chr1",47681962,47689770],[["uc001cra.1"],"knownGene","uc001cra.1","chr1",47689675,47697892],[["uc001cqz.1"],"knownGene","uc001cqz.1","chr1",47689675,47697892],[["uc001crb.1"],"knownGene","uc001crb.1","chr1",47694867,47779819],[["uc001crc.1"],"knownGene","uc001crc.1","chr1",47715810,47779819],[["uc001crd.1"],"knownGene","uc001crd.1","chr1",47715810,47779819],[["uc001cre.1"],"knownGene","uc001cre.1","chr1",47715810,47779819],[["uc010omn.1"],"knownGene","uc010omn.1","chr1",47715810,47778828],[["uc010omo.1"],"knownGene","uc010omo.1","chr1",47715810,47778828],[["uc001crg.1"],"knownGene","uc001crg.1","chr1",47725960,47779819],[["uc001crf.1"],"knownGene","uc001crf.1","chr1",47725960,47749745],[["uc001cri.2"],"knownGene","uc001cri.2","chr1",47799468,47844510],[["uc010omp.1"],"knownGene","uc010omp.1","chr1",47799468,47844510],[["uc010omq.1"],"knownGene","uc010omq.1","chr1",47799468,47844510],[["uc001crh.2"],"knownGene","uc001crh.2","chr1",47799468,47824547],[["uc001crj.1"],"knownGene","uc001crj.1","chr1",47859449,47861215],[["uc001crk.2"],"knownGene","uc001crk.2","chr1",47881743,47883723],[["uc001crl.2"],"knownGene","uc001crl.2","chr1",47897807,47900313],[["uc001crm.2"],"knownGene","uc001crm.2","chr1",47901688,47906362],[["uc010omr.1"],"knownGene","uc010omr.1","chr1",48567386,48648100],[["uc001crn.2"],"knownGene","uc001crn.2","chr1",48688356,48714316],[["uc001cro.2"],"knownGene","uc001cro.2","chr1",48688356,48714316],[["uc010omt.1"],"knownGene","uc010omt.1","chr1",48688356,48714316],[["uc001crp.2"],"knownGene","uc001crp.2","chr1",48688356,48714316],[["uc010omu.1"],"knownGene","uc010omu.1","chr1",48688356,48714316],[["uc010oms.1"],"knownGene","uc010oms.1","chr1",48688356,48703519],[["uc009vyt.1"],"knownGene","uc009vyt.1","chr1",48704993,48714316],[["uc001crr.1"],"knownGene","uc001crr.1","chr1",48764277,48937845],[["uc001crs.1"],"knownGene","uc001crs.1","chr1",48764277,48937845],[["uc010omv.1"],"knownGene","uc010omv.1","chr1",48764277,48937845],[["uc001crt.2"],"knownGene","uc001crt.2","chr1",48862818,48937845],[["uc001cru.2"],"knownGene","uc001cru.2","chr1",48998526,50489626],[["uc010omw.1"],"knownGene","uc010omw.1","chr1",48998526,50489626],[["uc010omx.1"],"knownGene","uc010omx.1","chr1",48998526,50489626],[["uc001crv.1"],"knownGene","uc001crv.1","chr1",49049541,49511472],[["uc010omy.1"],"knownGene","uc010omy.1","chr1",49049541,49511472],[["uc001crx.3"],"knownGene","uc001crx.3","chr1",49193541,49242547],[["uc001crw.3"],"knownGene","uc001crw.3","chr1",49193541,49242547],[["uc001cry.3"],"knownGene","uc001cry.3","chr1",50513685,50667540],[["uc001crz.3"],"knownGene","uc001crz.3","chr1",50569581,50667540],[["uc001csa.3"],"knownGene","uc001csa.3","chr1",50571963,50667540],[["uc001csb.2"],"knownGene","uc001csb.2","chr1",50574593,50667540],[["uc001csc.3"],"knownGene","uc001csc.3","chr1",50574593,50667540],[["uc010omz.1"],"knownGene","uc010omz.1","chr1",50575287,50667540],[["uc009vyu.2"],"knownGene","uc009vyu.2","chr1",50575287,50663232],[["uc010onb.1"],"knownGene","uc010onb.1","chr1",50883228,50889141],[["uc010ona.1"],"knownGene","uc010ona.1","chr1",50883228,50887304],[["uc001cse.1"],"knownGene","uc001cse.1","chr1",50906934,51425936],[["uc009vyx.1"],"knownGene","uc009vyx.1","chr1",50906934,51425833],[["uc009vyw.1"],"knownGene","uc009vyw.1","chr1",50906934,51425525],[["uc010onc.1"],"knownGene","uc010onc.1","chr1",50906934,51078170],[["uc001csf.2"],"knownGene","uc001csf.2","chr1",51433607,51440307],[["uc001csg.2"],"knownGene","uc001csg.2","chr1",51435641,51440307],[["uc001csh.2"],"knownGene","uc001csh.2","chr1",51567905,51613752],[["uc001csi.3"],"knownGene","uc001csi.3","chr1",51701944,51739117],[["uc010onf.1"],"knownGene","uc010onf.1","chr1",51752930,51810785],[["uc010one.1"],"knownGene","uc010one.1","chr1",51752930,51796234],[["uc010ond.1"],"knownGene","uc010ond.1","chr1",51752930,51795845],[["uc001csk.2"],"knownGene","uc001csk.2","chr1",51752930,51787938],[["uc001csl.2"],"knownGene","uc001csl.2","chr1",51752930,51787938],[["uc001csj.2"],"knownGene","uc001csj.2","chr1",51752930,51763594],[["uc001csn.2"],"knownGene","uc001csn.2","chr1",51761211,51796234],[["uc001cso.1"],"knownGene","uc001cso.1","chr1",51762902,51796999],[["uc009vyy.1"],"knownGene","uc009vyy.1","chr1",51767243,51796617],[["uc001csq.1"],"knownGene","uc001csq.1","chr1",51819934,51984995],[["uc009vyz.1"],"knownGene","uc009vyz.1","chr1",51819934,51984995],[["uc001csp.3"],"knownGene","uc001csp.3","chr1",51819934,51887793],[["uc001csr.1"],"knownGene","uc001csr.1","chr1",51968781,51984995],[["uc001css.2"],"knownGene","uc001css.2","chr1",52042850,52254136],[["uc001cst.2"],"knownGene","uc001cst.2","chr1",52082545,52254136],[["uc001csx.2"],"knownGene","uc001csx.2","chr1",52082545,52254136],[["uc001csu.2"],"knownGene","uc001csu.2","chr1",52082545,52254136],[["uc001csv.2"],"knownGene","uc001csv.2","chr1",52082545,52254136],[["uc001csw.2"],"knownGene","uc001csw.2","chr1",52082545,52254136],[["uc009vza.2"],"knownGene","uc009vza.2","chr1",52082545,52254136],[["uc001csy.2"],"knownGene","uc001csy.2","chr1",52195492,52254136],[["uc001csz.2"],"knownGene","uc001csz.2","chr1",52195492,52254136],[["uc001cta.2"],"knownGene","uc001cta.2","chr1",52195522,52254136],[["uc001ctb.2"],"knownGene","uc001ctb.2","chr1",52225295,52254136],[["uc001ctc.3"],"knownGene","uc001ctc.3","chr1",52254867,52344609],[["uc001ctd.3"],"knownGene","uc001ctd.3","chr1",52254867,52344609],[["uc009vzb.2"],"knownGene","uc009vzb.2","chr1",52254867,52306186],[["uc001cte.2"],"knownGene","uc001cte.2","chr1",52255239,52343712],[["uc001ctf.2"],"knownGene","uc001ctf.2","chr1",52257249,52344609],[["uc010ong.1"],"knownGene","uc010ong.1","chr1",52260143,52344420],[["uc009vzc.1"],"knownGene","uc009vzc.1","chr1",52280222,52343712],[["uc001ctg.1"],"knownGene","uc001ctg.1","chr1",52302636,52305398],[["uc001cth.2"],"knownGene","uc001cth.2","chr1",52384836,52456348],[["uc001cti.2"],"knownGene","uc001cti.2","chr1",52485806,52521047],[["uc001ctj.1"],"knownGene","uc001ctj.1","chr1",52497776,52499472],[["uc001ctk.2"],"knownGene","uc001ctk.2","chr1",52521856,52554090],[["uc001ctl.2"],"knownGene","uc001ctl.2","chr1",52521856,52554090],[["uc010onh.1"],"knownGene","uc010onh.1","chr1",52521856,52554090],[["uc001ctm.2"],"knownGene","uc001ctm.2","chr1",52525495,52554090],[["uc001cto.2"],"knownGene","uc001cto.2","chr1",52608045,52812357],[["uc001ctp.2"],"knownGene","uc001ctp.2","chr1",52608045,52812357],[["uc001ctn.2"],"knownGene","uc001ctn.2","chr1",52608045,52729718],[["uc001ctq.1"],"knownGene","uc001ctq.1","chr1",52816266,52831864],[["uc001cts.2"],"knownGene","uc001cts.2","chr1",52818204,52825905],[["uc001ctr.2"],"knownGene","uc001ctr.2","chr1",52818204,52824133],[["uc001ctt.2"],"knownGene","uc001ctt.2","chr1",52838501,52870131],[["uc010oni.1"],"knownGene","uc010oni.1","chr1",52838501,52870131],[["uc001ctu.2"],"knownGene","uc001ctu.2","chr1",52838501,52870131],[["uc009vzd.2"],"knownGene","uc009vzd.2","chr1",52838501,52870131],[["uc001ctv.3"],"knownGene","uc001ctv.3","chr1",52870218,52883991],[["uc001ctw.3"],"knownGene","uc001ctw.3","chr1",52870218,52883991],[["uc001ctx.2"],"knownGene","uc001ctx.2","chr1",52888947,53018762],[["uc001cty.2"],"knownGene","uc001cty.2","chr1",52888947,53018762],[["uc001ctz.2"],"knownGene","uc001ctz.2","chr1",52888947,53018762],[["uc001cua.1"],"knownGene","uc001cua.1","chr1",52896675,52927288],[["uc009vze.1"],"knownGene","uc009vze.1","chr1",52903891,53018772],[["uc009vzf.1"],"knownGene","uc009vzf.1","chr1",52911936,53019130],[["uc001cub.2"],"knownGene","uc001cub.2","chr1",52927875,52992045],[["uc001cuc.2"],"knownGene","uc001cuc.2","chr1",52943379,53018762],[["uc001cud.2"],"knownGene","uc001cud.2","chr1",52980467,53018762],[["uc001cue.2"],"knownGene","uc001cue.2","chr1",53068042,53074722],[["uc001cuh.2"],"knownGene","uc001cuh.2","chr1",53099065,53135337],[["uc001cug.1"],"knownGene","uc001cug.1","chr1",53099065,53134793],[["uc001cuf.2"],"knownGene","uc001cuf.2","chr1",53099065,53122736],[["uc001cui.1"],"knownGene","uc001cui.1","chr1",53152513,53164038],[["uc001cuj.2"],"knownGene","uc001cuj.2","chr1",53192130,53293011],[["uc010onj.1"],"knownGene","uc010onj.1","chr1",53192130,53293011],[["uc009vzg.2"],"knownGene","uc009vzg.2","chr1",53192130,53282310],[["uc009vzh.2"],"knownGene","uc009vzh.2","chr1",53262405,53293011],[["uc001cuk.2"],"knownGene","uc001cuk.2","chr1",53308182,53360247],[["uc001cul.2"],"knownGene","uc001cul.2","chr1",53308182,53360247],[["uc010onk.1"],"knownGene","uc010onk.1","chr1",53361903,53392851],[["uc001cuo.3"],"knownGene","uc001cuo.3","chr1",53361903,53387591],[["uc001cup.3"],"knownGene","uc001cup.3","chr1",53361903,53387591],[["uc001cun.2"],"knownGene","uc001cun.2","chr1",53361903,53387375],[["uc010onn.1"],"knownGene","uc010onn.1","chr1",53370705,53387591],[["uc010onm.1"],"knownGene","uc010onm.1","chr1",53370705,53387375],[["uc010onl.1"],"knownGene","uc010onl.1","chr1",53370705,53387258],[["uc001cur.1"],"knownGene","uc001cur.1","chr1",53392947,53517282],[["uc001cus.1"],"knownGene","uc001cus.1","chr1",53392947,53517282],[["uc010ono.1"],"knownGene","uc010ono.1","chr1",53392947,53517282],[["uc010onp.1"],"knownGene","uc010onp.1","chr1",53392947,53517282],[["uc009vzi.1"],"knownGene","uc009vzi.1","chr1",53392947,53517282],[["uc001cuq.1"],"knownGene","uc001cuq.1","chr1",53392947,53461672],[["uc001cut.1"],"knownGene","uc001cut.1","chr1",53480561,53517282],[["uc001cuu.1"],"knownGene","uc001cuu.1","chr1",53480561,53517282],[["uc010onq.1"],"knownGene","uc010onq.1","chr1",53480561,53517282],[["uc001cuv.2"],"knownGene","uc001cuv.2","chr1",53527884,53551173],[["uc001cuw.2"],"knownGene","uc001cuw.2","chr1",53527884,53551173],[["uc010onr.1"],"knownGene","uc010onr.1","chr1",53527884,53551173],[["uc010ons.1"],"knownGene","uc010ons.1","chr1",53527884,53551173],[["uc001cuy.2"],"knownGene","uc001cuy.2","chr1",53552855,53608289],[["uc001cux.2"],"knownGene","uc001cux.2","chr1",53552855,53556654],[["uc001cuz.3"],"knownGene","uc001cuz.3","chr1",53573607,53608289],[["uc001cva.1"],"knownGene","uc001cva.1","chr1",53580247,53584281],[["uc001cvb.3"],"knownGene","uc001cvb.3","chr1",53662100,53679867],[["uc001cvd.2"],"knownGene","uc001cvd.2","chr1",53679773,53686289],[["uc001cve.2"],"knownGene","uc001cve.2","chr1",53679773,53686289],[["uc001cvc.2"],"knownGene","uc001cvc.2","chr1",53679773,53684238],[["uc001cvf.1"],"knownGene","uc001cvf.1","chr1",53692563,53704207],[["uc010ont.1"],"knownGene","uc010ont.1","chr1",53692563,53704207],[["uc001cvg.2"],"knownGene","uc001cvg.2","chr1",53704281,53708454],[["uc001cvi.1"],"knownGene","uc001cvi.1","chr1",53711211,53793821],[["uc001cvj.1"],"knownGene","uc001cvj.1","chr1",53711211,53793821],[["uc001cvk.1"],"knownGene","uc001cvk.1","chr1",53711211,53793821],[["uc001cvl.1"],"knownGene","uc001cvl.1","chr1",53711211,53793821],[["uc001cvh.1"],"knownGene","uc001cvh.1","chr1",53711211,53793071],[["uc001cvm.1"],"knownGene","uc001cvm.1","chr1",53716361,53734270],[["uc001cvn.1"],"knownGene","uc001cvn.1","chr1",53793904,53802889],[["uc009vzj.1"],"knownGene","uc009vzj.1","chr1",53904043,53905693],[["uc001cvq.1"],"knownGene","uc001cvq.1","chr1",53925071,53933158],[["uc001cvr.1"],"knownGene","uc001cvr.1","chr1",53971905,54199877],[["uc001cvs.2"],"knownGene","uc001cvs.2","chr1",54233389,54304175],[["uc010onu.1"],"knownGene","uc010onu.1","chr1",54233389,54304175],[["uc001cvt.2"],"knownGene","uc001cvt.2","chr1",54233389,54304175],[["uc009vzk.2"],"knownGene","uc009vzk.2","chr1",54233389,54304175],[["uc010onv.1"],"knownGene","uc010onv.1","chr1",54233389,54304175],[["uc001cvu.2"],"knownGene","uc001cvu.2","chr1",54317406,54355453],[["uc001cvv.2"],"knownGene","uc001cvv.2","chr1",54317406,54355453],[["uc001cvw.2"],"knownGene","uc001cvw.2","chr1",54317406,54355453],[["uc001cvx.2"],"knownGene","uc001cvx.2","chr1",54317406,54355453],[["uc001cvy.2"],"knownGene","uc001cvy.2","chr1",54317406,54355453],[["uc010onw.1"],"knownGene","uc010onw.1","chr1",54359860,54376758],[["uc009vzl.2"],"knownGene","uc009vzl.2","chr1",54359860,54376758],[["uc010onx.1"],"knownGene","uc010onx.1","chr1",54359860,54376758],[["uc001cwb.2"],"knownGene","uc001cwb.2","chr1",54359860,54376758],[["uc010ony.1"],"knownGene","uc010ony.1","chr1",54359860,54376758],[["uc001cwd.2"],"knownGene","uc001cwd.2","chr1",54359860,54376758],[["uc001cwe.2"],"knownGene","uc001cwe.2","chr1",54359860,54376758],[["uc001cwf.2"],"knownGene","uc001cwf.2","chr1",54359861,54376758],[["uc001cwg.2"],"knownGene","uc001cwg.2","chr1",54359861,54376758],[["uc001cwi.1"],"knownGene","uc001cwi.1","chr1",54387233,54411288],[["uc001cwh.2"],"knownGene","uc001cwh.2","chr1",54387235,54411288],[["uc001cwj.1"],"knownGene","uc001cwj.1","chr1",54412036,54433839],[["uc001cwl.1"],"knownGene","uc001cwl.1","chr1",54412036,54433839],[["uc001cwk.1"],"knownGene","uc001cwk.1","chr1",54412036,54433839],[["uc009vzm.1"],"knownGene","uc009vzm.1","chr1",54412036,54433839],[["uc001cwm.1"],"knownGene","uc001cwm.1","chr1",54474505,54483803],[["uc010onz.1"],"knownGene","uc010onz.1","chr1",54474505,54483803],[["uc010ooa.1"],"knownGene","uc010ooa.1","chr1",54474505,54483803],[["uc009vzn.1"],"knownGene","uc009vzn.1","chr1",54474505,54483803],[["uc001cwp.2"],"knownGene","uc001cwp.2","chr1",54497350,54519111],[["uc001cwq.2"],"knownGene","uc001cwq.2","chr1",54497350,54519111],[["uc001cwr.2"],"knownGene","uc001cwr.2","chr1",54497350,54519111],[["uc001cwo.2"],"knownGene","uc001cwo.2","chr1",54497350,54513686],[["uc001cwn.2"],"knownGene","uc001cwn.2","chr1",54497350,54510014],[["uc001cws.1"],"knownGene","uc001cws.1","chr1",54502282,54519111],[["uc001cwu.1"],"knownGene","uc001cwu.1","chr1",54519273,54578192],[["uc001cwt.1"],"knownGene","uc001cwt.1","chr1",54519273,54565416],[["uc001cwv.1"],"knownGene","uc001cwv.1","chr1",54604667,54619443],[["uc009vzo.2"],"knownGene","uc009vzo.2","chr1",54638028,54665746],[["uc001cwx.3"],"knownGene","uc001cwx.3","chr1",54638028,54665746],[["uc001cwy.3"],"knownGene","uc001cwy.3","chr1",54638028,54665746],[["uc001cww.2"],"knownGene","uc001cww.2","chr1",54638028,54661388],[["uc001cxb.1"],"knownGene","uc001cxb.1","chr1",54665839,54691137],[["uc001cxa.3"],"knownGene","uc001cxa.3","chr1",54665839,54684054],[["uc009vzp.2"],"knownGene","uc009vzp.2","chr1",54665839,54684054],[["uc001cxc.3"],"knownGene","uc001cxc.3","chr1",54665863,54684054],[["uc010oob.1"],"knownGene","uc010oob.1","chr1",54665874,54684054],[["uc001cxe.2"],"knownGene","uc001cxe.2","chr1",54692195,54872092],[["uc001cxf.2"],"knownGene","uc001cxf.2","chr1",54692195,54872092],[["uc001cxg.2"],"knownGene","uc001cxg.2","chr1",54692195,54872092],[["uc001cxd.2"],"knownGene","uc001cxd.2","chr1",54692195,54694507],[["uc001cxi.1"],"knownGene","uc001cxi.1","chr1",54751085,54753827],[["uc001cxj.1"],"knownGene","uc001cxj.1","chr1",55007929,55076000],[["uc001cxm.1"],"knownGene","uc001cxm.1","chr1",55013900,55100417],[["uc001cxl.1"],"knownGene","uc001cxl.1","chr1",55013900,55076000],[["uc001cxk.2"],"knownGene","uc001cxk.2","chr1",55013900,55064513],[["uc001cxn.2"],"knownGene","uc001cxn.2","chr1",55074850,55089200],[["uc001cxq.2"],"knownGene","uc001cxq.2","chr1",55107426,55207980],[["uc001cxs.2"],"knownGene","uc001cxs.2","chr1",55107426,55175939],[["uc010ood.1"],"knownGene","uc010ood.1","chr1",55107426,55175939],[["uc010ooe.1"],"knownGene","uc010ooe.1","chr1",55107426,55175939],[["uc010oof.1"],"knownGene","uc010oof.1","chr1",55107426,55175939],[["uc010ooc.1"],"knownGene","uc010ooc.1","chr1",55107426,55166134],[["uc001cxo.2"],"knownGene","uc001cxo.2","chr1",55107426,55129728],[["uc001cxr.1"],"knownGene","uc001cxr.1","chr1",55117460,55175939],[["uc009vzq.1"],"knownGene","uc009vzq.1","chr1",55118525,55175939],[["uc001cxt.1"],"knownGene","uc001cxt.1","chr1",55118525,55175939],[["uc010oog.1"],"knownGene","uc010oog.1","chr1",55118525,55165896],[["uc010ooh.1"],"knownGene","uc010ooh.1","chr1",55118525,55165896],[["uc009vzr.1"],"knownGene","uc009vzr.1","chr1",55148328,55175939],[["uc001cxu.2"],"knownGene","uc001cxu.2","chr1",55151930,55161454],[["uc001cxw.3"],"knownGene","uc001cxw.3","chr1",55181528,55207980],[["uc001cxx.3"],"knownGene","uc001cxx.3","chr1",55181528,55207980],[["uc001cxv.2"],"knownGene","uc001cxv.2","chr1",55181540,55207980],[["uc001cxy.2"],"knownGene","uc001cxy.2","chr1",55222572,55230187],[["uc009vzt.1"],"knownGene","uc009vzt.1","chr1",55246751,55266941],[["uc001cxz.3"],"knownGene","uc001cxz.3","chr1",55250224,55266941],[["uc001cya.3"],"knownGene","uc001cya.3","chr1",55271735,55307936],[["uc001cyb.3"],"knownGene","uc001cyb.3","chr1",55271735,55307936],[["uc001cyc.1"],"knownGene","uc001cyc.1","chr1",55315299,55352921],[["uc010ook.1"],"knownGene","uc010ook.1","chr1",55315299,55352481],[["uc010ooj.1"],"knownGene","uc010ooj.1","chr1",55315299,55341720],[["uc010ooi.1"],"knownGene","uc010ooi.1","chr1",55315299,55331353],[["uc001cyd.2"],"knownGene","uc001cyd.2","chr1",55446464,55457965],[["uc001cye.2"],"knownGene","uc001cye.2","chr1",55464616,55474464],[["uc001cyf.1"],"knownGene","uc001cyf.1","chr1",55505219,55530523],[["uc010ool.1"],"knownGene","uc010ool.1","chr1",55505219,55518464],[["uc010oom.1"],"knownGene","uc010oom.1","chr1",55505894,55530523],[["uc001cyg.3"],"knownGene","uc001cyg.3","chr1",55532038,55680762],[["uc001cyi.1"],"knownGene","uc001cyi.1","chr1",56046709,56200675],[["uc001cyj.1"],"knownGene","uc001cyj.1","chr1",56960432,57045257],[["uc001cyk.3"],"knownGene","uc001cyk.3","chr1",57110989,57181007],[["uc001cym.3"],"knownGene","uc001cym.3","chr1",57184477,57285369],[["uc001cyl.2"],"knownGene","uc001cyl.2","chr1",57184477,57227686],[["uc009vzu.1"],"knownGene","uc009vzu.1","chr1",57192169,57285369],[["uc009vzv.1"],"knownGene","uc009vzv.1","chr1",57253991,57285369],[["uc001cyn.2"],"knownGene","uc001cyn.2","chr1",57289360,57292593],[["uc001cyo.2"],"knownGene","uc001cyo.2","chr1",57320442,57383894],[["uc001cyp.2"],"knownGene","uc001cyp.2","chr1",57394884,57431688],[["uc010oon.1"],"knownGene","uc010oon.1","chr1",57394884,57431688],[["uc010ooo.1"],"knownGene","uc010ooo.1","chr1",57394884,57431688],[["uc001cyt.1"],"knownGene","uc001cyt.1","chr1",57463578,59012446],[["uc001cys.1"],"knownGene","uc001cys.1","chr1",57463578,58716211],[["uc009vzw.1"],"knownGene","uc009vzw.1","chr1",57463578,57773037],[["uc001cyq.1"],"knownGene","uc001cyq.1","chr1",57463578,57756838],[["uc001cyr.1"],"knownGene","uc001cyr.1","chr1",57463578,57756838],[["uc009vzx.1"],"knownGene","uc009vzx.1","chr1",57476352,57888872],[["uc001cyu.1"],"knownGene","uc001cyu.1","chr1",58326214,58328786],[["uc001cyv.1"],"knownGene","uc001cyv.1","chr1",58326265,58328786],[["uc001cyw.1"],"knownGene","uc001cyw.1","chr1",58933598,58934677],[["uc001cyx.1"],"knownGene","uc001cyx.1","chr1",58939503,59004982],[["uc001cyy.2"],"knownGene","uc001cyy.2","chr1",58946391,59012446],[["uc009vzz.2"],"knownGene","uc009vzz.2","chr1",58999094,59012446],[["uc001cyz.3"],"knownGene","uc001cyz.3","chr1",59041096,59043166],[["uc001cza.2"],"knownGene","uc001cza.2","chr1",59120411,59124660],[["uc009wab.1"],"knownGene","uc009wab.1","chr1",59125589,59165747],[["uc001czc.2"],"knownGene","uc001czc.2","chr1",59125589,59156089],[["uc009waa.1"],"knownGene","uc009waa.1","chr1",59125589,59134578],[["uc001czd.2"],"knownGene","uc001czd.2","chr1",59151777,59165747],[["uc001cze.2"],"knownGene","uc001cze.2","chr1",59246463,59249785],[["uc001czf.2"],"knownGene","uc001czf.2","chr1",59250822,59365384],[["uc010oop.1"],"knownGene","uc010oop.1","chr1",59250822,59365384],[["uc010ooq.1"],"knownGene","uc010ooq.1","chr1",59597609,59612479],[["uc009wac.2"],"knownGene","uc009wac.2","chr1",59762624,60228400],[["uc001czi.3"],"knownGene","uc001czi.3","chr1",59762624,60228400],[["uc001czj.3"],"knownGene","uc001czj.3","chr1",59762624,60228400],[["uc001czk.3"],"knownGene","uc001czk.3","chr1",59762624,60228400],[["uc001czh.2"],"knownGene","uc001czh.2","chr1",59762624,60165066],[["uc001czg.2"],"knownGene","uc001czg.2","chr1",59762624,60092526],[["uc001czl.3"],"knownGene","uc001czl.3","chr1",59775758,60228400],[["uc001czm.3"],"knownGene","uc001czm.3","chr1",59981325,60228400],[["uc001czn.2"],"knownGene","uc001czn.2","chr1",60238466,60254499],[["uc009wad.2"],"knownGene","uc009wad.2","chr1",60280462,60342049],[["uc001czo.2"],"knownGene","uc001czo.2","chr1",60280532,60342049],[["uc001czp.2"],"knownGene","uc001czp.2","chr1",60280843,60342049],[["uc010oor.1"],"knownGene","uc010oor.1","chr1",60282303,60342049],[["uc001czq.2"],"knownGene","uc001czq.2","chr1",60358980,60392423],[["uc001czs.1"],"knownGene","uc001czs.1","chr1",60454823,60539426],[["uc001czr.1"],"knownGene","uc001czr.1","chr1",60454823,60474495],[["uc001czt.1"],"knownGene","uc001czt.1","chr1",61125302,61291256],[["uc001czu.2"],"knownGene","uc001czu.2","chr1",61405916,61436448],[["uc001czy.2"],"knownGene","uc001czy.2","chr1",61542945,61928459],[["uc010oos.1"],"knownGene","uc010oos.1","chr1",61547533,61928459],[["uc001czw.2"],"knownGene","uc001czw.2","chr1",61547979,61928459],[["uc001czv.2"],"knownGene","uc001czv.2","chr1",61547979,61928459],[["uc001czx.2"],"knownGene","uc001czx.2","chr1",61869747,61928459],[["uc009wae.2"],"knownGene","uc009wae.2","chr1",61872233,61928459],[["uc001czz.1"],"knownGene","uc001czz.1","chr1",62146718,62191095],[["uc001dab.2"],"knownGene","uc001dab.2","chr1",62208148,62629589],[["uc001daa.2"],"knownGene","uc001daa.2","chr1",62208148,62580582],[["uc009waf.1"],"knownGene","uc009waf.1","chr1",62208148,62579918],[["uc001dad.3"],"knownGene","uc001dad.3","chr1",62237102,62580582],[["uc001dac.2"],"knownGene","uc001dac.2","chr1",62271119,62629174],[["uc009wag.2"],"knownGene","uc009wag.2","chr1",62417925,62644346],[["uc010oot.1"],"knownGene","uc010oot.1","chr1",62417925,62583005],[["uc010oou.1"],"knownGene","uc010oou.1","chr1",62439039,62580582],[["uc001dae.3"],"knownGene","uc001dae.3","chr1",62660495,62677998],[["uc001dah.3"],"knownGene","uc001dah.3","chr1",62701837,62785083],[["uc001dai.3"],"knownGene","uc001dai.3","chr1",62701837,62785083],[["uc001dag.3"],"knownGene","uc001dag.3","chr1",62701837,62738463],[["uc001daf.3"],"knownGene","uc001daf.3","chr1",62701837,62729096],[["uc001daj.1"],"knownGene","uc001daj.1","chr1",62901974,62917915],[["uc001dak.1"],"knownGene","uc001dak.1","chr1",62901974,62917915],[["uc001dal.1"],"knownGene","uc001dal.1","chr1",62902382,62917915],[["uc001dap.2"],"knownGene","uc001dap.2","chr1",62920397,63153969],[["uc001daq.2"],"knownGene","uc001daq.2","chr1",62920397,63153969],[["uc001dan.2"],"knownGene","uc001dan.2","chr1",62920397,63119464],[["uc001dao.2"],"knownGene","uc001dao.2","chr1",62920397,63119464],[["uc001dam.2"],"knownGene","uc001dam.2","chr1",62920397,63021660],[["uc010oov.1"],"knownGene","uc010oov.1","chr1",62923208,63001303],[["uc001dar.1"],"knownGene","uc001dar.1","chr1",62939652,62944675],[["uc009wah.1"],"knownGene","uc009wah.1","chr1",63049776,63153969],[["uc001das.1"],"knownGene","uc001das.1","chr1",63063186,63071180],[["uc001dat.2"],"knownGene","uc001dat.2","chr1",63249802,63330049],[["uc001dau.2"],"knownGene","uc001dau.2","chr1",63249802,63330049],[["uc001dav.2"],"knownGene","uc001dav.2","chr1",63624754,63630026],[["uc001daw.1"],"knownGene","uc001daw.1","chr1",63635822,63782901],[["uc001dax.2"],"knownGene","uc001dax.2","chr1",63788729,63790797],[["uc010oow.1"],"knownGene","uc010oow.1","chr1",63833260,63904232],[["uc001daz.2"],"knownGene","uc001daz.2","chr1",63836441,63904232],[["uc009waj.2"],"knownGene","uc009waj.2","chr1",63836441,63904232],[["uc010oox.1"],"knownGene","uc010oox.1","chr1",63876810,63904232],[["uc001dba.1"],"knownGene","uc001dba.1","chr1",63906461,63988835],[["uc001dbb.1"],"knownGene","uc001dbb.1","chr1",63906461,63988835],[["uc001dbc.1"],"knownGene","uc001dbc.1","chr1",63906461,63988835],[["uc001dbd.1"],"knownGene","uc001dbd.1","chr1",63906461,63988835],[["uc001dbe.1"],"knownGene","uc001dbe.1","chr1",63913649,63920639],[["uc009wak.1"],"knownGene","uc009wak.1","chr1",63919111,63988812],[["uc001dbf.2"],"knownGene","uc001dbf.2","chr1",63989012,64038363],[["uc001dbg.1"],"knownGene","uc001dbg.1","chr1",64014650,64016307],[["uc001dbh.2"],"knownGene","uc001dbh.2","chr1",64058946,64125914],[["uc010ooy.1"],"knownGene","uc010ooy.1","chr1",64059479,64125914],[["uc010ooz.1"],"knownGene","uc010ooz.1","chr1",64088900,64125914],[["uc001dbj.2"],"knownGene","uc001dbj.2","chr1",64239689,64644707],[["uc001dbi.3"],"knownGene","uc001dbi.3","chr1",64239689,64609041],[["uc001dbk.2"],"knownGene","uc001dbk.2","chr1",64560125,64577888],[["uc001dbl.2"],"knownGene","uc001dbl.2","chr1",64571007,64636980],[["uc001dbm.2"],"knownGene","uc001dbm.2","chr1",64645310,64647177],[["uc001dbn.1"],"knownGene","uc001dbn.1","chr1",64669489,64710027],[["uc001dbo.1"],"knownGene","uc001dbo.1","chr1",64936475,65158741],[["uc001dbp.1"],"knownGene","uc001dbp.1","chr1",64971596,65158741],[["uc001dbq.1"],"knownGene","uc001dbq.1","chr1",65029359,65158741],[["uc010opa.1"],"knownGene","uc010opa.1","chr1",65130348,65158741],[["uc001dbs.1"],"knownGene","uc001dbs.1","chr1",65210777,65298912],[["uc001dbt.1"],"knownGene","uc001dbt.1","chr1",65243305,65298912],[["uc010opb.1"],"knownGene","uc010opb.1","chr1",65243305,65298912],[["uc009wam.1"],"knownGene","uc009wam.1","chr1",65298905,65432619],[["uc001dbu.1"],"knownGene","uc001dbu.1","chr1",65298905,65432187],[["uc009wal.1"],"knownGene","uc009wal.1","chr1",65298905,65311323],[["uc001dbv.2"],"knownGene","uc001dbv.2","chr1",65338384,65343856],[["uc001dbw.2"],"knownGene","uc001dbw.2","chr1",65445260,65468159],[["uc001dbx.2"],"knownGene","uc001dbx.2","chr1",65524117,65524191],[["uc001dby.2"],"knownGene","uc001dby.2","chr1",65613231,65693173],[["uc009wan.2"],"knownGene","uc009wan.2","chr1",65613352,65693173],[["uc001dbz.2"],"knownGene","uc001dbz.2","chr1",65613512,65693173],[["uc001dca.2"],"knownGene","uc001dca.2","chr1",65613885,65693173],[["uc001dcb.1"],"knownGene","uc001dcb.1","chr1",65720144,65721848],[["uc001dcc.1"],"knownGene","uc001dcc.1","chr1",65720147,65858548],[["uc001dcd.1"],"knownGene","uc001dcd.1","chr1",65730429,65881552],[["uc010opc.1"],"knownGene","uc010opc.1","chr1",65730429,65881552],[["uc001dce.1"],"knownGene","uc001dce.1","chr1",65775227,65881552],[["uc001dci.2"],"knownGene","uc001dci.2","chr1",65886317,66102820],[["uc009waq.2"],"knownGene","uc009waq.2","chr1",65886317,66102820],[["uc001dch.2"],"knownGene","uc001dch.2","chr1",65886317,66101110],[["uc001dcg.2"],"knownGene","uc001dcg.2","chr1",65886317,66096093],[["uc001dcf.2"],"knownGene","uc001dcf.2","chr1",65886317,65898249],[["uc009wap.2"],"knownGene","uc009wap.2","chr1",65886317,65898249],[["uc009wao.2"],"knownGene","uc009wao.2","chr1",65886317,65893689],[["uc001dck.2"],"knownGene","uc001dck.2","chr1",65991424,66101110],[["uc001dcj.2"],"knownGene","uc001dcj.2","chr1",65991424,66096093],[["uc001dcn.2"],"knownGene","uc001dcn.2","chr1",66258192,66840261],[["uc009war.2"],"knownGene","uc009war.2","chr1",66258192,66840261],[["uc001dco.2"],"knownGene","uc001dco.2","chr1",66258855,66840261],[["uc001dcp.2"],"knownGene","uc001dcp.2","chr1",66458389,66840261],[["uc001dcq.2"],"knownGene","uc001dcq.2","chr1",66797792,66840261],[["uc009was.2"],"knownGene","uc009was.2","chr1",66820069,66840261],[["uc001dcr.2"],"knownGene","uc001dcr.2","chr1",66999824,67210767],[["uc010opd.1"],"knownGene","uc010opd.1","chr1",67109226,67210767],[["uc001dcs.2"],"knownGene","uc001dcs.2","chr1",67109226,67210767],[["uc001dct.2"],"knownGene","uc001dct.2","chr1",67109226,67210767],[["uc010ope.1"],"knownGene","uc010ope.1","chr1",67132271,67142710],[["uc009wat.2"],"knownGene","uc009wat.2","chr1",67136677,67210767],[["uc001dcu.2"],"knownGene","uc001dcu.2","chr1",67160376,67210767],[["uc001dcv.2"],"knownGene","uc001dcv.2","chr1",67218139,67244729],[["uc009wau.2"],"knownGene","uc009wau.2","chr1",67218139,67244729],[["uc009wav.2"],"knownGene","uc009wav.2","chr1",67218139,67244729],[["uc001dcw.2"],"knownGene","uc001dcw.2","chr1",67263424,67266939],[["uc001dcx.2"],"knownGene","uc001dcx.2","chr1",67278573,67390570],[["uc009wax.2"],"knownGene","uc009wax.2","chr1",67278573,67356505],[["uc009waw.2"],"knownGene","uc009waw.2","chr1",67278573,67340620],[["uc001dcy.2"],"knownGene","uc001dcy.2","chr1",67303287,67390570],[["uc001dcz.2"],"knownGene","uc001dcz.2","chr1",67336930,67390570],[["uc010opf.1"],"knownGene","uc010opf.1","chr1",67390577,67454302],[["uc009way.2"],"knownGene","uc009way.2","chr1",67390577,67454302],[["uc001ddc.2"],"knownGene","uc001ddc.2","chr1",67390577,67454302],[["uc001ddh.2"],"knownGene","uc001ddh.2","chr1",67390577,67454302],[["uc001ddf.2"],"knownGene","uc001ddf.2","chr1",67390577,67454302],[["uc001ddg.2"],"knownGene","uc001ddg.2","chr1",67390577,67454302],[["uc010opg.1"],"knownGene","uc010opg.1","chr1",67390577,67454302],[["uc001dde.2"],"knownGene","uc001dde.2","chr1",67390577,67454302],[["uc001dda.3"],"knownGene","uc001dda.3","chr1",67390577,67413922],[["uc001ddj.1"],"knownGene","uc001ddj.1","chr1",67395925,67454302],[["uc001ddi.2"],"knownGene","uc001ddi.2","chr1",67395925,67454302],[["uc001ddk.2"],"knownGene","uc001ddk.2","chr1",67465014,67520080],[["uc010oph.1"],"knownGene","uc010oph.1","chr1",67473197,67518730],[["uc001ddm.1"],"knownGene","uc001ddm.1","chr1",67557858,67600653],[["uc001ddn.1"],"knownGene","uc001ddn.1","chr1",67557858,67600653],[["uc001ddl.1"],"knownGene","uc001ddl.1","chr1",67557858,67594220],[["uc009waz.2"],"knownGene","uc009waz.2","chr1",67604589,67725648],[["uc001ddo.2"],"knownGene","uc001ddo.2","chr1",67632168,67725648],[["uc010opi.1"],"knownGene","uc010opi.1","chr1",67635024,67725648],[["uc010opj.1"],"knownGene","uc010opj.1","chr1",67635024,67725648],[["uc010opk.1"],"knownGene","uc010opk.1","chr1",67635024,67725648],[["uc010opl.1"],"knownGene","uc010opl.1","chr1",67635024,67725648],[["uc010opm.1"],"knownGene","uc010opm.1","chr1",67635024,67725648],[["uc001ddq.2"],"knownGene","uc001ddq.2","chr1",67635024,67725648],[["uc010opn.1"],"knownGene","uc010opn.1","chr1",67635024,67725648],[["uc001ddr.2"],"knownGene","uc001ddr.2","chr1",67635024,67725648],[["uc001ddp.2"],"knownGene","uc001ddp.2","chr1",67635024,67724260],[["uc010ops.1"],"knownGene","uc010ops.1","chr1",67648518,67725648],[["uc010opt.1"],"knownGene","uc010opt.1","chr1",67648518,67725648],[["uc010opu.1"],"knownGene","uc010opu.1","chr1",67648518,67725648],[["uc010opv.1"],"knownGene","uc010opv.1","chr1",67648518,67725648],[["uc010opw.1"],"knownGene","uc010opw.1","chr1",67648518,67725648],[["uc010opx.1"],"knownGene","uc010opx.1","chr1",67648518,67725648],[["uc010opy.1"],"knownGene","uc010opy.1","chr1",67648518,67725648],[["uc010opz.1"],"knownGene","uc010opz.1","chr1",67648518,67725648],[["uc010oqa.1"],"knownGene","uc010oqa.1","chr1",67648518,67725648],[["uc010oqb.1"],"knownGene","uc010oqb.1","chr1",67648518,67725648],[["uc010oqc.1"],"knownGene","uc010oqc.1","chr1",67648518,67725648],[["uc010oqd.1"],"knownGene","uc010oqd.1","chr1",67648518,67725648],[["uc010oqe.1"],"knownGene","uc010oqe.1","chr1",67648518,67725648],[["uc010oqf.1"],"knownGene","uc010oqf.1","chr1",67648518,67725648],[["uc010oqg.1"],"knownGene","uc010oqg.1","chr1",67648518,67725648],[["uc010oqh.1"],"knownGene","uc010oqh.1","chr1",67648518,67725648],[["uc010opo.1"],"knownGene","uc010opo.1","chr1",67648518,67724260],[["uc010opp.1"],"knownGene","uc010opp.1","chr1",67648518,67724260],[["uc010opq.1"],"knownGene","uc010opq.1","chr1",67648518,67724260],[["uc010opr.1"],"knownGene","uc010opr.1","chr1",67648518,67724260],[["uc001dds.2"],"knownGene","uc001dds.2","chr1",67673298,67725648],[["uc001ddt.2"],"knownGene","uc001ddt.2","chr1",67673298,67725648],[["uc001ddu.2"],"knownGene","uc001ddu.2","chr1",67773046,67862582],[["uc010oqi.1"],"knownGene","uc010oqi.1","chr1",67773046,67862582],[["uc010oqj.1"],"knownGene","uc010oqj.1","chr1",67773046,67862582],[["uc010oqk.1"],"knownGene","uc010oqk.1","chr1",67786015,67862582],[["uc010oql.1"],"knownGene","uc010oql.1","chr1",67786015,67862582],[["uc010oqm.1"],"knownGene","uc010oqm.1","chr1",67786015,67862582],[["uc010oqn.1"],"knownGene","uc010oqn.1","chr1",67786015,67862582],[["uc001ddx.2"],"knownGene","uc001ddx.2","chr1",67873494,67896123],[["uc001ddy.2"],"knownGene","uc001ddy.2","chr1",67873494,67896123],[["uc001ddv.2"],"knownGene","uc001ddv.2","chr1",67873494,67896123],[["uc001ddw.2"],"knownGene","uc001ddw.2","chr1",67873494,67896123],[["uc001ddz.1"],"knownGene","uc001ddz.1","chr1",68150882,68154019],[["uc009wbb.1"],"knownGene","uc009wbb.1","chr1",68150882,68154019],[["uc009wbc.1"],"knownGene","uc009wbc.1","chr1",68150882,68154019],[["uc009wbd.1"],"knownGene","uc009wbd.1","chr1",68150882,68154019],[["uc001dea.1"],"knownGene","uc001dea.1","chr1",68167148,68299142],[["uc001deb.1"],"knownGene","uc001deb.1","chr1",68297985,68668670],[["uc001dec.1"],"knownGene","uc001dec.1","chr1",68297985,68668670],[["uc001ded.2"],"knownGene","uc001ded.2","chr1",68511646,68516481],[["uc001dee.2"],"knownGene","uc001dee.2","chr1",68564151,68698253],[["uc001def.1"],"knownGene","uc001def.1","chr1",68591040,68698253],[["uc001deg.1"],"knownGene","uc001deg.1","chr1",68591040,68698253],[["uc009wbf.1"],"knownGene","uc009wbf.1","chr1",68591040,68659904],[["uc001deh.1"],"knownGene","uc001deh.1","chr1",68659538,68698253],[["uc001dei.1"],"knownGene","uc001dei.1","chr1",68894506,68915642],[["uc001dem.3"],"knownGene","uc001dem.3","chr1",68939836,68962799],[["uc001del.3"],"knownGene","uc001del.3","chr1",68939836,68962799],[["uc001dek.3"],"knownGene","uc001dek.3","chr1",68939836,68960378],[["uc001dej.3"],"knownGene","uc001dej.3","chr1",68939836,68947921],[["uc001den.2"],"knownGene","uc001den.2","chr1",68962358,69004308],[["uc001deo.1"],"knownGene","uc001deo.1","chr1",70032867,70340687],[["uc001dep.2"],"knownGene","uc001dep.2","chr1",70225857,70589169],[["uc009wbg.2"],"knownGene","uc009wbg.2","chr1",70225873,70589169],[["uc009wbh.1"],"knownGene","uc009wbh.1","chr1",70385004,70386000],[["uc001deq.2"],"knownGene","uc001deq.2","chr1",70502126,70589169],[["uc001der.1"],"knownGene","uc001der.1","chr1",70610496,70671275],[["uc001des.2"],"knownGene","uc001des.2","chr1",70671364,70717683],[["uc001det.2"],"knownGene","uc001det.2","chr1",70671364,70717683],[["uc009wbj.1"],"knownGene","uc009wbj.1","chr1",70671364,70697511],[["uc010oqo.1"],"knownGene","uc010oqo.1","chr1",70671364,70697511],[["uc009wbi.2"],"knownGene","uc009wbi.2","chr1",70671364,70695716],[["uc001deu.2"],"knownGene","uc001deu.2","chr1",70687144,70716186],[["uc001dev.2"],"knownGene","uc001dev.2","chr1",70695960,70717683],[["uc001dew.2"],"knownGene","uc001dew.2","chr1",70697230,70717683],[["uc001dex.3"],"knownGene","uc001dex.3","chr1",70724685,70820417],[["uc009wbk.2"],"knownGene","uc009wbk.2","chr1",70724685,70820417],[["uc001dey.3"],"knownGene","uc001dey.3","chr1",70818494,70820399],[["uc010oqp.1"],"knownGene","uc010oqp.1","chr1",70820492,70833703],[["uc001dfa.2"],"knownGene","uc001dfa.2","chr1",70820492,70833703],[["uc001dfb.2"],"knownGene","uc001dfb.2","chr1",70820492,70833703],[["uc001dfc.2"],"knownGene","uc001dfc.2","chr1",70820492,70833703],[["uc001dfd.2"],"knownGene","uc001dfd.2","chr1",70876954,70905252],[["uc001dfe.2"],"knownGene","uc001dfe.2","chr1",70876954,70905252],[["uc010oqq.1"],"knownGene","uc010oqq.1","chr1",70876954,70905252],[["uc009wbl.1"],"knownGene","uc009wbl.1","chr1",70876954,70897918],[["uc001dff.2"],"knownGene","uc001dff.2","chr1",71172135,71252149],[["uc001dfh.1"],"knownGene","uc001dfh.1","chr1",71318035,71513491],[["uc001dfg.1"],"knownGene","uc001dfg.1","chr1",71318035,71513491],[["uc001dfi.1"],"knownGene","uc001dfi.1","chr1",71318035,71513491],[["uc001dfj.1"],"knownGene","uc001dfj.1","chr1",71318035,71513491],[["uc001dfk.1"],"knownGene","uc001dfk.1","chr1",71318035,71513491],[["uc001dfl.1"],"knownGene","uc001dfl.1","chr1",71318035,71513491],[["uc009wbm.1"],"knownGene","uc009wbm.1","chr1",71327987,71513491],[["uc001dfm.1"],"knownGene","uc001dfm.1","chr1",71349400,71513491],[["uc001dfn.2"],"knownGene","uc001dfn.2","chr1",71349439,71513491],[["uc009wbn.1"],"knownGene","uc009wbn.1","chr1",71349439,71513491],[["uc009wbo.2"],"knownGene","uc009wbo.2","chr1",71418115,71513491],[["uc001dfo.2"],"knownGene","uc001dfo.2","chr1",71418115,71513491],[["uc001dfp.1"],"knownGene","uc001dfp.1","chr1",71436463,71513491],[["uc001dfq.2"],"knownGene","uc001dfq.2","chr1",71471537,71513491],[["uc001dfr.2"],"knownGene","uc001dfr.2","chr1",71512188,71532861],[["uc001dfs.2"],"knownGene","uc001dfs.2","chr1",71528974,71546745],[["uc001dft.2"],"knownGene","uc001dft.2","chr1",71528974,71546745],[["uc010oqr.1"],"knownGene","uc010oqr.1","chr1",71533313,71533399],[["uc001dfu.1"],"knownGene","uc001dfu.1","chr1",71547049,71703406],[["uc001dfw.2"],"knownGene","uc001dfw.2","chr1",71868625,72748405],[["uc010oqs.1"],"knownGene","uc010oqs.1","chr1",71868625,72748405],[["uc001dfv.2"],"knownGene","uc001dfv.2","chr1",71868625,72566614],[["uc001dfx.2"],"knownGene","uc001dfx.2","chr1",73771852,73804559],[["uc001dfy.3"],"knownGene","uc001dfy.3","chr1",74491703,74663871],[["uc001dfz.3"],"knownGene","uc001dfz.3","chr1",74491703,74663871],[["uc001dge.1"],"knownGene","uc001dge.1","chr1",74663925,75010108],[["uc001dgd.2"],"knownGene","uc001dgd.2","chr1",74663925,74930605],[["uc001dgc.1"],"knownGene","uc001dgc.1","chr1",74663925,74837776],[["uc010oqv.1"],"knownGene","uc010oqv.1","chr1",74663925,74699770],[["uc001dgb.1"],"knownGene","uc001dgb.1","chr1",74663925,74673120],[["uc010oqu.1"],"knownGene","uc010oqu.1","chr1",74663925,74671907],[["uc010oqt.1"],"knownGene","uc010oqt.1","chr1",74663925,74671889],[["uc001dgf.1"],"knownGene","uc001dgf.1","chr1",74701084,75010108],[["uc001dgg.2"],"knownGene","uc001dgg.2","chr1",75033795,75139422],[["uc001dgh.2"],"knownGene","uc001dgh.2","chr1",75043113,75091781],[["uc001dgi.3"],"knownGene","uc001dgi.3","chr1",75055012,75100538],[["uc001dgk.2"],"knownGene","uc001dgk.2","chr1",75171174,75199092],[["uc001dgj.2"],"knownGene","uc001dgj.2","chr1",75171174,75199092],[["uc001dgl.2"],"knownGene","uc001dgl.2","chr1",75171174,75199092],[["uc001dgm.2"],"knownGene","uc001dgm.2","chr1",75171174,75199092],[["uc001dgn.2"],"knownGene","uc001dgn.2","chr1",75198835,75232358],[["uc010oqw.1"],"knownGene","uc010oqw.1","chr1",75198835,75232358],[["uc010oqx.1"],"knownGene","uc010oqx.1","chr1",75198835,75232358],[["uc010oqy.1"],"knownGene","uc010oqy.1","chr1",75198861,75232358],[["uc001dgo.2"],"knownGene","uc001dgo.2","chr1",75594118,75627216],[["uc001dgp.1"],"knownGene","uc001dgp.1","chr1",75595658,75598261],[["uc001dgq.2"],"knownGene","uc001dgq.2","chr1",75600566,75627216],[["uc010oqz.1"],"knownGene","uc010oqz.1","chr1",75667815,76143610],[["uc001dgt.2"],"knownGene","uc001dgt.2","chr1",75667815,76076799],[["uc001dgs.2"],"knownGene","uc001dgs.2","chr1",75667815,76076799],[["uc001dgr.2"],"knownGene","uc001dgr.2","chr1",75667815,76076799],[["uc010orb.1"],"knownGene","uc010orb.1","chr1",75672075,76143610],[["uc010ora.1"],"knownGene","uc010ora.1","chr1",75672075,76081694],[["uc001dgu.2"],"knownGene","uc001dgu.2","chr1",75672075,76076799],[["uc001dgv.2"],"knownGene","uc001dgv.2","chr1",76103851,76188721],[["uc001dgw.3"],"knownGene","uc001dgw.3","chr1",76190042,76229353],[["uc009wbp.2"],"knownGene","uc009wbp.2","chr1",76190042,76229353],[["uc009wbr.2"],"knownGene","uc009wbr.2","chr1",76190042,76229353],[["uc010ore.1"],"knownGene","uc010ore.1","chr1",76190042,76229353],[["uc010orf.1"],"knownGene","uc010orf.1","chr1",76190042,76229353],[["uc010ord.1"],"knownGene","uc010ord.1","chr1",76190042,76227299],[["uc010orc.1"],"knownGene","uc010orc.1","chr1",76190042,76205795],[["uc001dgx.3"],"knownGene","uc001dgx.3","chr1",76192603,76229353],[["uc010org.1"],"knownGene","uc010org.1","chr1",76198200,76229353],[["uc009wbs.1"],"knownGene","uc009wbs.1","chr1",76211490,76227055],[["uc001dgy.1"],"knownGene","uc001dgy.1","chr1",76251885,76260764],[["uc009wbt.1"],"knownGene","uc009wbt.1","chr1",76251885,76260764],[["uc001dgz.2"],"knownGene","uc001dgz.2","chr1",76252756,76252834],[["uc001dha.1"],"knownGene","uc001dha.1","chr1",76253181,76260764],[["uc009wbu.1"],"knownGene","uc009wbu.1","chr1",76253573,76253657],[["uc009wbv.1"],"knownGene","uc009wbv.1","chr1",76255161,76255232],[["uc001dhc.1"],"knownGene","uc001dhc.1","chr1",76259715,76260764],[["uc001dhd.1"],"knownGene","uc001dhd.1","chr1",76262629,76378923],[["uc001dhe.1"],"knownGene","uc001dhe.1","chr1",76384559,76398116],[["uc001dhf.1"],"knownGene","uc001dhf.1","chr1",76384559,76398116],[["uc001dhh.2"],"knownGene","uc001dhh.2","chr1",76540388,77096669],[["uc010orh.1"],"knownGene","uc010orh.1","chr1",76540388,77096669],[["uc001dhg.3"],"knownGene","uc001dhg.3","chr1",76540388,77042890],[["uc001dhi.2"],"knownGene","uc001dhi.2","chr1",77333185,77529735],[["uc010ori.1"],"knownGene","uc010ori.1","chr1",77333185,77529735],[["uc009wbw.2"],"knownGene","uc009wbw.2","chr1",77334181,77529735],[["uc001dhj.2"],"knownGene","uc001dhj.2","chr1",77529660,77531392],[["uc001dhk.2"],"knownGene","uc001dhk.2","chr1",77554668,77685132],[["uc010orj.1"],"knownGene","uc010orj.1","chr1",77554668,77685132],[["uc009wbx.2"],"knownGene","uc009wbx.2","chr1",77554668,77685132],[["uc001dhl.1"],"knownGene","uc001dhl.1","chr1",77619220,77685132],[["uc001dhn.2"],"knownGene","uc001dhn.2","chr1",77747741,78025652],[["uc001dhm.1"],"knownGene","uc001dhm.1","chr1",77747741,77780745],[["uc001dho.2"],"knownGene","uc001dho.2","chr1",77748286,78025652],[["uc001dhr.2"],"knownGene","uc001dhr.2","chr1",78030190,78149104],[["uc001dhq.2"],"knownGene","uc001dhq.2","chr1",78030190,78148343],[["uc001dhp.2"],"knownGene","uc001dhp.2","chr1",78030190,78099090],[["uc009wbz.1"],"knownGene","uc009wbz.1","chr1",78050201,78148343],[["uc001dht.2"],"knownGene","uc001dht.2","chr1",78161675,78225537],[["uc001dhu.2"],"knownGene","uc001dhu.2","chr1",78161675,78225537],[["uc001dhs.2"],"knownGene","uc001dhs.2","chr1",78161675,78194397],[["uc009wca.1"],"knownGene","uc009wca.1","chr1",78161675,78163616],[["uc001dhw.2"],"knownGene","uc001dhw.2","chr1",78177339,78225537],[["uc001dhv.2"],"knownGene","uc001dhv.2","chr1",78177339,78207114],[["uc001dhx.2"],"knownGene","uc001dhx.2","chr1",78245308,78344077],[["uc010ork.1"],"knownGene","uc010ork.1","chr1",78245308,78344077],[["uc010orl.1"],"knownGene","uc010orl.1","chr1",78245308,78344077],[["uc001dhy.1"],"knownGene","uc001dhy.1","chr1",78268954,78327860],[["uc001dic.3"],"knownGene","uc001dic.3","chr1",78354199,78409576],[["uc001dib.3"],"knownGene","uc001dib.3","chr1",78354199,78409576],[["uc001dia.3"],"knownGene","uc001dia.3","chr1",78354199,78407893],[["uc009wcb.1"],"knownGene","uc009wcb.1","chr1",78354199,78407893],[["uc001did.1"],"knownGene","uc001did.1","chr1",78383644,78409576],[["uc001dif.1"],"knownGene","uc001dif.1","chr1",78383809,78409576],[["uc001dig.3"],"knownGene","uc001dig.3","chr1",78398726,78409576],[["uc001dih.3"],"knownGene","uc001dih.3","chr1",78412168,78444777],[["uc001dii.2"],"knownGene","uc001dii.2","chr1",78413592,78444777],[["uc010orm.1"],"knownGene","uc010orm.1","chr1",78413592,78444777],[["uc010orn.1"],"knownGene","uc010orn.1","chr1",78444933,78482993],[["uc001dij.2"],"knownGene","uc001dij.2","chr1",78470635,78482993],[["uc001dik.2"],"knownGene","uc001dik.2","chr1",78511588,78603111],[["uc009wcc.2"],"knownGene","uc009wcc.2","chr1",78695282,78835145],[["uc001dil.1"],"knownGene","uc001dil.1","chr1",78695282,78759574],[["uc001dim.2"],"knownGene","uc001dim.2","chr1",78956727,79006385],[["uc001din.2"],"knownGene","uc001din.2","chr1",78956727,79006385],[["uc010oro.1"],"knownGene","uc010oro.1","chr1",79086087,79111828],[["uc010orp.1"],"knownGene","uc010orp.1","chr1",79086087,79111828],[["uc010orq.1"],"knownGene","uc010orq.1","chr1",79086087,79111828],[["uc001dip.3"],"knownGene","uc001dip.3","chr1",79115476,79129761],[["uc010orr.1"],"knownGene","uc010orr.1","chr1",79115476,79127139],[["uc010ors.1"],"knownGene","uc010ors.1","chr1",79115476,79127139],[["uc001diq.3"],"knownGene","uc001diq.3","chr1",79355450,79472495],[["uc001dis.2"],"knownGene","uc001dis.2","chr1",81771844,82458106],[["uc001dit.3"],"knownGene","uc001dit.3","chr1",82165454,82458106],[["uc001diu.2"],"knownGene","uc001diu.2","chr1",82266081,82458106],[["uc001div.2"],"knownGene","uc001div.2","chr1",82266081,82458106],[["uc009wcd.2"],"knownGene","uc009wcd.2","chr1",82266081,82458106],[["uc001diw.2"],"knownGene","uc001diw.2","chr1",82415872,82458106],[["uc009wce.1"],"knownGene","uc009wce.1","chr1",82435997,82447660],[["uc001dix.3"],"knownGene","uc001dix.3","chr1",83439566,83451891],[["uc001diy.2"],"knownGene","uc001diy.2","chr1",83911736,83920453],[["uc001diz.3"],"knownGene","uc001diz.3","chr1",84041473,84326679],[["uc001dja.1"],"knownGene","uc001dja.1","chr1",84267442,84326229],[["uc001djc.2"],"knownGene","uc001djc.2","chr1",84335058,84464833],[["uc001djd.2"],"knownGene","uc001djd.2","chr1",84335058,84464833],[["uc001dje.2"],"knownGene","uc001dje.2","chr1",84335058,84464833],[["uc001djf.2"],"knownGene","uc001djf.2","chr1",84335058,84464833],[["uc001djb.2"],"knownGene","uc001djb.2","chr1",84335058,84418070],[["uc001djg.2"],"knownGene","uc001djg.2","chr1",84335383,84464833],[["uc001djh.1"],"knownGene","uc001djh.1","chr1",84543635,84546350],[["uc001djj.2"],"knownGene","uc001djj.2","chr1",84543744,84704179],[["uc001dji.2"],"knownGene","uc001dji.2","chr1",84543744,84670977],[["uc001djl.2"],"knownGene","uc001djl.2","chr1",84609951,84704179],[["uc001djk.2"],"knownGene","uc001djk.2","chr1",84609951,84670977],[["uc010ort.1"],"knownGene","uc010ort.1","chr1",84630064,84704179],[["uc001djn.2"],"knownGene","uc001djn.2","chr1",84630064,84704179],[["uc010oru.1"],"knownGene","uc010oru.1","chr1",84630064,84704179],[["uc001djp.2"],"knownGene","uc001djp.2","chr1",84630386,84704179],[["uc001djq.2"],"knownGene","uc001djq.2","chr1",84630386,84704179],[["uc009wcf.1"],"knownGene","uc009wcf.1","chr1",84630386,84670977],[["uc001djo.1"],"knownGene","uc001djo.1","chr1",84630386,84644921],[["uc010orv.1"],"knownGene","uc010orv.1","chr1",84647342,84704179],[["uc001djr.2"],"knownGene","uc001djr.2","chr1",84764048,84816480],[["uc010orw.1"],"knownGene","uc010orw.1","chr1",84767288,84816480],[["uc010orx.1"],"knownGene","uc010orx.1","chr1",84768333,84816480],[["uc001djs.2"],"knownGene","uc001djs.2","chr1",84810360,84816480],[["uc009wcg.2"],"knownGene","uc009wcg.2","chr1",84830647,84863576],[["uc001djt.1"],"knownGene","uc001djt.1","chr1",84864214,84880691],[["uc001dju.1"],"knownGene","uc001dju.1","chr1",84874033,84880691],[["uc009wch.1"],"knownGene","uc009wch.1","chr1",84874119,84880691],[["uc001djv.3"],"knownGene","uc001djv.3","chr1",84944919,84964032],[["uc001djw.3"],"knownGene","uc001djw.3","chr1",84964006,84972262],[["uc001djz.1"],"knownGene","uc001djz.1","chr1",84971973,85031875],[["uc001djy.1"],"knownGene","uc001djy.1","chr1",84971973,85018807],[["uc001djx.2"],"knownGene","uc001djx.2","chr1",84971973,84992550],[["uc001dka.2"],"knownGene","uc001dka.2","chr1",85018803,85040163],[["uc001dkb.2"],"knownGene","uc001dkb.2","chr1",85018803,85040163],[["uc001dkc.2"],"knownGene","uc001dkc.2","chr1",85018803,85040113],[["uc001dkd.2"],"knownGene","uc001dkd.2","chr1",85018803,85040113],[["uc001dke.1"],"knownGene","uc001dke.1","chr1",85093912,85100703],[["uc010ory.1"],"knownGene","uc010ory.1","chr1",85093912,85097429],[["uc001dki.2"],"knownGene","uc001dki.2","chr1",85109597,85156180],[["uc010osa.1"],"knownGene","uc010osa.1","chr1",85109597,85156180],[["uc001dkj.2"],"knownGene","uc001dkj.2","chr1",85109597,85156180],[["uc001dkg.2"],"knownGene","uc001dkg.2","chr1",85109597,85155972],[["uc001dkh.2"],"knownGene","uc001dkh.2","chr1",85109597,85155972],[["uc010orz.1"],"knownGene","uc010orz.1","chr1",85109597,85155972],[["uc001dkf.2"],"knownGene","uc001dkf.2","chr1",85109597,85136498],[["uc009wci.2"],"knownGene","uc009wci.2","chr1",85115312,85155972],[["uc001dkk.1"],"knownGene","uc001dkk.1","chr1",85121147,85156440],[["uc009wcj.1"],"knownGene","uc009wcj.1","chr1",85279085,85358896],[["uc001dkl.2"],"knownGene","uc001dkl.2","chr1",85279085,85331842],[["uc001dkm.2"],"knownGene","uc001dkm.2","chr1",85391266,85462796],[["uc001dkn.2"],"knownGene","uc001dkn.2","chr1",85391266,85462796],[["uc001dkp.2"],"knownGene","uc001dkp.2","chr1",85483765,85514169],[["uc001dkq.2"],"knownGene","uc001dkq.2","chr1",85483765,85514169],[["uc001dko.2"],"knownGene","uc001dko.2","chr1",85483765,85489203],[["uc001dkr.2"],"knownGene","uc001dkr.2","chr1",85490233,85514169],[["uc001dks.3"],"knownGene","uc001dks.3","chr1",85490241,85514169],[["uc001dkt.2"],"knownGene","uc001dkt.2","chr1",85527992,85598820],[["uc009wcl.2"],"knownGene","uc009wcl.2","chr1",85527992,85598820],[["uc009wcm.2"],"knownGene","uc009wcm.2","chr1",85623356,85666728],[["uc001dku.3"],"knownGene","uc001dku.3","chr1",85646848,85666728],[["uc001dkw.2"],"knownGene","uc001dkw.2","chr1",85715638,85725355],[["uc001dkv.2"],"knownGene","uc001dkv.2","chr1",85715638,85725355],[["uc001dkx.3"],"knownGene","uc001dkx.3","chr1",85723126,85725355],[["uc009wcn.2"],"knownGene","uc009wcn.2","chr1",85723126,85725355],[["uc001dkz.2"],"knownGene","uc001dkz.2","chr1",85731460,85743583],[["uc001dla.1"],"knownGene","uc001dla.1","chr1",85742397,85865646],[["uc001dlc.2"],"knownGene","uc001dlc.2","chr1",85784168,86044046],[["uc001dlb.2"],"knownGene","uc001dlb.2","chr1",85784168,85930889],[["uc009wco.2"],"knownGene","uc009wco.2","chr1",85784168,85930267],[["uc010osb.1"],"knownGene","uc010osb.1","chr1",85784168,85870180],[["uc001dle.2"],"knownGene","uc001dle.2","chr1",86046443,86049646],[["uc001dlg.2"],"knownGene","uc001dlg.2","chr1",86047597,86049646],[["uc009wcp.1"],"knownGene","uc009wcp.1","chr1",86048984,86049386],[["uc010osc.1"],"knownGene","uc010osc.1","chr1",86118491,86174116],[["uc001dlh.2"],"knownGene","uc001dlh.2","chr1",86118491,86174101],[["uc001dlj.2"],"knownGene","uc001dlj.2","chr1",86194917,86622154],[["uc010osd.1"],"knownGene","uc010osd.1","chr1",86194917,86622154],[["uc001dlk.2"],"knownGene","uc001dlk.2","chr1",86194917,86622154],[["uc010ose.1"],"knownGene","uc010ose.1","chr1",86194917,86622154],[["uc010osf.1"],"knownGene","uc010osf.1","chr1",86194917,86622154],[["uc001dli.2"],"knownGene","uc001dli.2","chr1",86194917,86428932],[["uc009wcq.2"],"knownGene","uc009wcq.2","chr1",86510811,86622446],[["uc001dll.1"],"knownGene","uc001dll.1","chr1",86814411,86862003],[["uc001dlm.1"],"knownGene","uc001dlm.1","chr1",86814411,86862003],[["uc001dln.2"],"knownGene","uc001dln.2","chr1",86814420,86862003],[["uc001dlo.2"],"knownGene","uc001dlo.2","chr1",86814420,86862003],[["uc001dlp.2"],"knownGene","uc001dlp.2","chr1",86814420,86862003],[["uc010osg.1"],"knownGene","uc010osg.1","chr1",86814420,86862003],[["uc001dlq.1"],"knownGene","uc001dlq.1","chr1",86824469,86862003],[["uc009wcr.1"],"knownGene","uc009wcr.1","chr1",86826108,86862003],[["uc001dlr.3"],"knownGene","uc001dlr.3","chr1",86889768,86922238],[["uc001dlt.2"],"knownGene","uc001dlt.2","chr1",86934394,86965972],[["uc001dls.1"],"knownGene","uc001dls.1","chr1",86934394,86960131],[["uc009wcs.2"],"knownGene","uc009wcs.2","chr1",87012758,87046430],[["uc009wct.2"],"knownGene","uc009wct.2","chr1",87012758,87046430],[["uc009wcu.2"],"knownGene","uc009wcu.2","chr1",87012758,87046430],[["uc010osh.1"],"knownGene","uc010osh.1","chr1",87099958,87121058],[["uc001dlw.2"],"knownGene","uc001dlw.2","chr1",87170256,87213866],[["uc001dlx.2"],"knownGene","uc001dlx.2","chr1",87170256,87213866],[["uc001dly.2"],"knownGene","uc001dly.2","chr1",87170256,87213866],[["uc001dlz.2"],"knownGene","uc001dlz.2","chr1",87170256,87213866],[["uc010osi.1"],"knownGene","uc010osi.1","chr1",87328129,87380107],[["uc010osj.1"],"knownGene","uc010osj.1","chr1",87328129,87380107],[["uc010osk.1"],"knownGene","uc010osk.1","chr1",87380334,87575680],[["uc001dmc.3"],"knownGene","uc001dmc.3","chr1",87380334,87564124],[["uc001dme.1"],"knownGene","uc001dme.1","chr1",87458689,87634884],[["uc001dmf.2"],"knownGene","uc001dmf.2","chr1",87595447,87634884],[["uc010osl.1"],"knownGene","uc010osl.1","chr1",87595447,87602350],[["uc010osm.1"],"knownGene","uc010osm.1","chr1",87597608,87602350],[["uc010osn.1"],"knownGene","uc010osn.1","chr1",87597608,87602350],[["uc010oso.1"],"knownGene","uc010oso.1","chr1",87597608,87602350],[["uc001dmg.3"],"knownGene","uc001dmg.3","chr1",87597608,87602350],[["uc001dmi.2"],"knownGene","uc001dmi.2","chr1",87794150,87814603],[["uc001dmj.2"],"knownGene","uc001dmj.2","chr1",87797350,87814603],[["uc001dmk.2"],"knownGene","uc001dmk.2","chr1",87819211,87837338],[["uc001dml.1"],"knownGene","uc001dml.1","chr1",89004735,89036543],[["uc001dmn.2"],"knownGene","uc001dmn.2","chr1",89149921,89301937],[["uc010osp.1"],"knownGene","uc010osp.1","chr1",89149921,89301937],[["uc010osq.1"],"knownGene","uc010osq.1","chr1",89149921,89301937],[["uc009wcv.2"],"knownGene","uc009wcv.2","chr1",89149921,89301937],[["uc001dmm.1"],"knownGene","uc001dmm.1","chr1",89149921,89271951],[["uc010osr.1"],"knownGene","uc010osr.1","chr1",89246721,89301937],[["uc001dmo.3"],"knownGene","uc001dmo.3","chr1",89318321,89357301],[["uc009wcw.1"],"knownGene","uc009wcw.1","chr1",89325822,89357301],[["uc001dmp.2"],"knownGene","uc001dmp.2","chr1",89401455,89458643],[["uc001dmq.2"],"knownGene","uc001dmq.2","chr1",89401455,89458643],[["uc001dmr.2"],"knownGene","uc001dmr.2","chr1",89401455,89458643],[["uc009wcx.2"],"knownGene","uc009wcx.2","chr1",89445139,89458643],[["uc001dms.2"],"knownGene","uc001dms.2","chr1",89445139,89458643],[["uc001dmt.2"],"knownGene","uc001dmt.2","chr1",89472366,89488549],[["uc010oss.1"],"knownGene","uc010oss.1","chr1",89472366,89488549],[["uc001dmu.2"],"knownGene","uc001dmu.2","chr1",89472366,89488549],[["uc001dmv.2"],"knownGene","uc001dmv.2","chr1",89472366,89488549],[["uc001dmx.2"],"knownGene","uc001dmx.2","chr1",89517986,89531043],[["uc001dmy.1"],"knownGene","uc001dmy.1","chr1",89571842,89616258],[["uc001dmz.1"],"knownGene","uc001dmz.1","chr1",89573309,89591799],[["uc001dna.2"],"knownGene","uc001dna.2","chr1",89597433,89641723],[["uc001dnb.2"],"knownGene","uc001dnb.2","chr1",89646831,89664633],[["uc001dnc.2"],"knownGene","uc001dnc.2","chr1",89724635,89738544],[["uc001dnd.2"],"knownGene","uc001dnd.2","chr1",89724635,89738544],[["uc001dne.1"],"knownGene","uc001dne.1","chr1",89728365,89738487],[["uc001dnf.2"],"knownGene","uc001dnf.2","chr1",89829435,89853719],[["uc010ost.1"],"knownGene","uc010ost.1","chr1",89829435,89853719],[["uc009wcy.1"],"knownGene","uc009wcy.1","chr1",89873237,89890493],[["uc001dni.2"],"knownGene","uc001dni.2","chr1",89990396,90063418],[["uc001dnh.2"],"knownGene","uc001dnh.2","chr1",89990396,90063418],[["uc001dnj.2"],"knownGene","uc001dnj.2","chr1",90024269,90063418],[["uc001dnk.1"],"knownGene","uc001dnk.1","chr1",90090407,90098453],[["uc001dnl.3"],"knownGene","uc001dnl.3","chr1",90098643,90185093],[["uc001dnm.2"],"knownGene","uc001dnm.2","chr1",90286572,90401987],[["uc001dnn.2"],"knownGene","uc001dnn.2","chr1",90287479,90401987],[["uc001dno.2"],"knownGene","uc001dno.2","chr1",90458825,90460525],[["uc001dnq.2"],"knownGene","uc001dnq.2","chr1",90460677,90494094],[["uc009wda.1"],"knownGene","uc009wda.1","chr1",90460677,90494094],[["uc001dnr.2"],"knownGene","uc001dnr.2","chr1",90460677,90494094],[["uc001dnp.3"],"knownGene","uc001dnp.3","chr1",90460677,90471999],[["uc001dns.2"],"knownGene","uc001dns.2","chr1",91177579,91182794],[["uc001dnu.1"],"knownGene","uc001dnu.1","chr1",91295103,91317175],[["uc001dnt.1"],"knownGene","uc001dnt.1","chr1",91295103,91301718],[["uc001dnw.2"],"knownGene","uc001dnw.2","chr1",91380859,91487671],[["uc001dnx.2"],"knownGene","uc001dnx.2","chr1",91380859,91487671],[["uc001dnv.2"],"knownGene","uc001dnv.2","chr1",91380859,91487030],[["uc001dny.1"],"knownGene","uc001dny.1","chr1",91403828,91487030],[["uc001doa.3"],"knownGene","uc001doa.3","chr1",91726323,91870426],[["uc010osu.1"],"knownGene","uc010osu.1","chr1",91726323,91870426],[["uc009wdb.2"],"knownGene","uc009wdb.2","chr1",91726323,91818208],[["uc001dob.3"],"knownGene","uc001dob.3","chr1",91727745,91813033],[["uc010osv.1"],"knownGene","uc010osv.1","chr1",91733301,91870426],[["uc001doc.1"],"knownGene","uc001doc.1","chr1",91842999,91866666],[["uc001doe.2"],"knownGene","uc001doe.2","chr1",91966403,91991320],[["uc001dof.2"],"knownGene","uc001dof.2","chr1",91966403,91991320],[["uc010osw.1"],"knownGene","uc010osw.1","chr1",91966403,91991320],[["uc009wdc.2"],"knownGene","uc009wdc.2","chr1",91966664,91991320],[["uc009wdd.2"],"knownGene","uc009wdd.2","chr1",91980375,91991320],[["uc010osx.1"],"knownGene","uc010osx.1","chr1",92100567,92109334],[["uc001doj.2"],"knownGene","uc001doj.2","chr1",92145901,92371559],[["uc001doh.2"],"knownGene","uc001doh.2","chr1",92145901,92351787],[["uc010osy.1"],"knownGene","uc010osy.1","chr1",92145901,92351787],[["uc001doi.2"],"knownGene","uc001doi.2","chr1",92145901,92351787],[["uc009wde.2"],"knownGene","uc009wde.2","chr1",92145901,92327603],[["uc001dok.3"],"knownGene","uc001dok.3","chr1",92414927,92479983],[["uc001dol.3"],"knownGene","uc001dol.3","chr1",92414927,92479983],[["uc010osz.1"],"knownGene","uc010osz.1","chr1",92414927,92479983],[["uc009wdf.2"],"knownGene","uc009wdf.2","chr1",92414927,92479983],[["uc010ota.1"],"knownGene","uc010ota.1","chr1",92414927,92479983],[["uc010otb.1"],"knownGene","uc010otb.1","chr1",92414928,92479983],[["uc001dom.3"],"knownGene","uc001dom.3","chr1",92417708,92479983],[["uc001don.2"],"knownGene","uc001don.2","chr1",92495532,92529093],[["uc001doo.2"],"knownGene","uc001doo.2","chr1",92545861,92613395],[["uc010otc.1"],"knownGene","uc010otc.1","chr1",92545861,92613395],[["uc010otd.1"],"knownGene","uc010otd.1","chr1",92632608,92650279],[["uc001dop.2"],"knownGene","uc001dop.2","chr1",92634414,92650279],[["uc001doq.2"],"knownGene","uc001doq.2","chr1",92683572,92711366],[["uc010ote.1"],"knownGene","uc010ote.1","chr1",92683572,92711366],[["uc001dor.2"],"knownGene","uc001dor.2","chr1",92711956,92764566],[["uc009wdg.2"],"knownGene","uc009wdg.2","chr1",92711956,92764566],[["uc001dos.2"],"knownGene","uc001dos.2","chr1",92711956,92764566],[["uc001dot.2"],"knownGene","uc001dot.2","chr1",92764521,92853732],[["uc009wdh.2"],"knownGene","uc009wdh.2","chr1",92764521,92853732],[["uc001dow.3"],"knownGene","uc001dow.3","chr1",92940318,92952433],[["uc001dov.3"],"knownGene","uc001dov.3","chr1",92940318,92951628],[["uc001dou.3"],"knownGene","uc001dou.3","chr1",92940318,92949356],[["uc001dox.2"],"knownGene","uc001dox.2","chr1",92974254,93257961],[["uc010otf.1"],"knownGene","uc010otf.1","chr1",92974254,93257961],[["uc001doy.1"],"knownGene","uc001doy.1","chr1",93029198,93159945],[["uc001doz.2"],"knownGene","uc001doz.2","chr1",93297593,93307480],[["uc001dpa.2"],"knownGene","uc001dpa.2","chr1",93297593,93307480],[["uc001dpb.2"],"knownGene","uc001dpb.2","chr1",93297916,93307480],[["uc001dpc.2"],"knownGene","uc001dpc.2","chr1",93298452,93427079],[["uc001dpd.2"],"knownGene","uc001dpd.2","chr1",93301783,93306626],[["uc001dpe.2"],"knownGene","uc001dpe.2","chr1",93302845,93302940],[["uc009wdi.1"],"knownGene","uc009wdi.1","chr1",93306275,93306408],[["uc001dpg.2"],"knownGene","uc001dpg.2","chr1",93307720,93427079],[["uc010otg.1"],"knownGene","uc010otg.1","chr1",93307720,93342152],[["uc009wdj.2"],"knownGene","uc009wdj.2","chr1",93544791,93604636],[["uc010oth.1"],"knownGene","uc010oth.1","chr1",93544791,93604636],[["uc009wdk.2"],"knownGene","uc009wdk.2","chr1",93544791,93604636],[["uc001dpi.3"],"knownGene","uc001dpi.3","chr1",93544791,93604636],[["uc010oti.1"],"knownGene","uc010oti.1","chr1",93544791,93604636],[["uc001dpj.3"],"knownGene","uc001dpj.3","chr1",93544791,93604636],[["uc001dph.2"],"knownGene","uc001dph.2","chr1",93544791,93585831],[["uc001dpl.3"],"knownGene","uc001dpl.3","chr1",93575786,93604636],[["uc001dpm.3"],"knownGene","uc001dpm.3","chr1",93594351,93604636],[["uc001dpn.2"],"knownGene","uc001dpn.2","chr1",93617410,93646246],[["uc001dpo.2"],"knownGene","uc001dpo.2","chr1",93617410,93646246],[["uc001dpp.2"],"knownGene","uc001dpp.2","chr1",93617410,93646246],[["uc001dpq.2"],"knownGene","uc001dpq.2","chr1",93645919,93744266],[["uc009wdl.1"],"knownGene","uc009wdl.1","chr1",93671066,93712511],[["uc001dpr.1"],"knownGene","uc001dpr.1","chr1",93720027,93730500],[["uc001dps.2"],"knownGene","uc001dps.2","chr1",93730202,93811374],[["uc001dpt.1"],"knownGene","uc001dpt.1","chr1",93775665,93811374],[["uc001dpu.2"],"knownGene","uc001dpu.2","chr1",93811477,93828146],[["uc010otj.1"],"knownGene","uc010otj.1","chr1",93811491,93828146],[["uc001dpv.2"],"knownGene","uc001dpv.2","chr1",93913838,94020216],[["uc001dpw.2"],"knownGene","uc001dpw.2","chr1",93913838,94020216],[["uc010otk.1"],"knownGene","uc010otk.1","chr1",93995208,94020216],[["uc010otl.1"],"knownGene","uc010otl.1","chr1",94009663,94020216],[["uc001dqb.2"],"knownGene","uc001dqb.2","chr1",94027350,94312706],[["uc001dqa.2"],"knownGene","uc001dqa.2","chr1",94027350,94147385],[["uc001dpz.2"],"knownGene","uc001dpz.2","chr1",94027350,94146926],[["uc001dpy.2"],"knownGene","uc001dpy.2","chr1",94027350,94079654],[["uc001dpx.3"],"knownGene","uc001dpx.3","chr1",94027350,94050719],[["uc009wdm.1"],"knownGene","uc009wdm.1","chr1",94036888,94050719],[["uc009wdn.2"],"knownGene","uc009wdn.2","chr1",94057524,94065586],[["uc001dqd.1"],"knownGene","uc001dqd.1","chr1",94219111,94240930],[["uc001dqe.1"],"knownGene","uc001dqe.1","chr1",94317792,94319887],[["uc001dqf.2"],"knownGene","uc001dqf.2","chr1",94335337,94344742],[["uc010otm.1"],"knownGene","uc010otm.1","chr1",94335337,94344742],[["uc009wdo.1"],"knownGene","uc009wdo.1","chr1",94342004,94344742],[["uc001dqg.1"],"knownGene","uc001dqg.1","chr1",94352589,94375012],[["uc001dqh.2"],"knownGene","uc001dqh.2","chr1",94458395,94586705],[["uc001dqi.1"],"knownGene","uc001dqi.1","chr1",94467113,94476485],[["uc009wdp.1"],"knownGene","uc009wdp.1","chr1",94475932,94484228],[["uc010otn.1"],"knownGene","uc010otn.1","chr1",94511192,94586705],[["uc009wdq.1"],"knownGene","uc009wdq.1","chr1",94615402,94740624],[["uc001dqj.3"],"knownGene","uc001dqj.3","chr1",94634463,94703307],[["uc001dqk.2"],"knownGene","uc001dqk.2","chr1",94642178,94661497],[["uc001dql.2"],"knownGene","uc001dql.2","chr1",94667455,94703307],[["uc001dqn.3"],"knownGene","uc001dqn.3","chr1",94883932,94984218],[["uc010oto.1"],"knownGene","uc010oto.1","chr1",94883932,94984218],[["uc010otp.1"],"knownGene","uc010otp.1","chr1",94883932,94984218],[["uc009wdr.2"],"knownGene","uc009wdr.2","chr1",94883932,94984218],[["uc001dqm.3"],"knownGene","uc001dqm.3","chr1",94883932,94944259],[["uc001dqo.3"],"knownGene","uc001dqo.3","chr1",94947048,94984218],[["uc001dqr.2"],"knownGene","uc001dqr.2","chr1",94994731,95007371],[["uc001dqs.2"],"knownGene","uc001dqs.2","chr1",94994731,95007371],[["uc001dqp.2"],"knownGene","uc001dqp.2","chr1",94994731,95006622],[["uc001dqq.2"],"knownGene","uc001dqq.2","chr1",94994731,95006622],[["uc001dqt.2"],"knownGene","uc001dqt.2","chr1",95005812,95007371],[["uc001dqu.2"],"knownGene","uc001dqu.2","chr1",95123089,95285834],[["uc001dqv.3"],"knownGene","uc001dqv.3","chr1",95285900,95360801],[["uc001dqx.3"],"knownGene","uc001dqx.3","chr1",95285900,95360801],[["uc010otq.1"],"knownGene","uc010otq.1","chr1",95285900,95360801],[["uc010otr.1"],"knownGene","uc010otr.1","chr1",95285900,95360801],[["uc001dqw.3"],"knownGene","uc001dqw.3","chr1",95286099,95360801],[["uc010ots.1"],"knownGene","uc010ots.1","chr1",95286099,95360801],[["uc009wds.2"],"knownGene","uc009wds.2","chr1",95290048,95360801],[["uc010ott.1"],"knownGene","uc010ott.1","chr1",95290048,95360801],[["uc010otu.1"],"knownGene","uc010otu.1","chr1",95292994,95356823],[["uc001dqz.3"],"knownGene","uc001dqz.3","chr1",95362508,95392735],[["uc010otx.1"],"knownGene","uc010otx.1","chr1",95362508,95392735],[["uc010otw.1"],"knownGene","uc010otw.1","chr1",95362508,95392638],[["uc010otv.1"],"knownGene","uc010otv.1","chr1",95362508,95391337],[["uc001dra.2"],"knownGene","uc001dra.2","chr1",95448278,95538507],[["uc001drb.2"],"knownGene","uc001drb.2","chr1",95582893,95663159],[["uc001drc.2"],"knownGene","uc001drc.2","chr1",95582994,95663159],[["uc001drd.3"],"knownGene","uc001drd.3","chr1",95583478,95710916],[["uc001dre.1"],"knownGene","uc001dre.1","chr1",95628774,95699538],[["uc009wdu.2"],"knownGene","uc009wdu.2","chr1",95699710,95712773],[["uc001drf.3"],"knownGene","uc001drf.3","chr1",95699710,95712773],[["uc001drh.3"],"knownGene","uc001drh.3","chr1",95699710,95712773],[["uc009wdv.2"],"knownGene","uc009wdv.2","chr1",95699710,95712773],[["uc001drg.3"],"knownGene","uc001drg.3","chr1",95699710,95712773],[["uc001dri.3"],"knownGene","uc001dri.3","chr1",95699710,95712773],[["uc010oty.1"],"knownGene","uc010oty.1","chr1",95699710,95710916],[["uc009wdt.2"],"knownGene","uc009wdt.2","chr1",95699710,95710916],[["uc001drj.1"],"knownGene","uc001drj.1","chr1",95820944,95846556],[["uc001drk.1"],"knownGene","uc001drk.1","chr1",95820944,95846556],[["uc001drl.2"],"knownGene","uc001drl.2","chr1",95975895,95981019],[["uc001drq.2"],"knownGene","uc001drq.2","chr1",97187174,97280599],[["uc001drr.2"],"knownGene","uc001drr.2","chr1",97187174,97280599],[["uc001drn.2"],"knownGene","uc001drn.2","chr1",97187174,97279217],[["uc001dro.2"],"knownGene","uc001dro.2","chr1",97187174,97279217],[["uc010otz.1"],"knownGene","uc010otz.1","chr1",97187174,97279217],[["uc001drp.2"],"knownGene","uc001drp.2","chr1",97187174,97279217],[["uc009wdw.2"],"knownGene","uc009wdw.2","chr1",97187174,97279217],[["uc001drm.2"],"knownGene","uc001drm.2","chr1",97187174,97239518],[["uc010oua.1"],"knownGene","uc010oua.1","chr1",97187346,97279217],[["uc001dru.2"],"knownGene","uc001dru.2","chr1",97188272,97280599],[["uc001drt.2"],"knownGene","uc001drt.2","chr1",97250614,97280599],[["uc001drs.1"],"knownGene","uc001drs.1","chr1",97250614,97279217],[["uc001drv.2"],"knownGene","uc001drv.2","chr1",97543301,98386615],[["uc010oub.1"],"knownGene","uc010oub.1","chr1",98157272,98386615],[["uc001drw.2"],"knownGene","uc001drw.2","chr1",98185314,98386615],[["uc001drx.1"],"knownGene","uc001drx.1","chr1",98453555,98515161],[["uc001dry.1"],"knownGene","uc001dry.1","chr1",98508912,98511014],[["uc009wdx.2"],"knownGene","uc009wdx.2","chr1",98509852,98511952],[["uc010ouc.1"],"knownGene","uc010ouc.1","chr1",99127235,99226054],[["uc001dsa.2"],"knownGene","uc001dsa.2","chr1",99127235,99226054],[["uc010oud.1"],"knownGene","uc010oud.1","chr1",99127235,99226054],[["uc001dsb.2"],"knownGene","uc001dsb.2","chr1",99355802,99470449],[["uc001dsc.2"],"knownGene","uc001dsc.2","chr1",99355802,99470449],[["uc001dsd.1"],"knownGene","uc001dsd.1","chr1",99469831,99614408],[["uc001dse.2"],"knownGene","uc001dse.2","chr1",99729899,99775136],[["uc010oue.1"],"knownGene","uc010oue.1","chr1",99729899,99775136],[["uc001dsg.2"],"knownGene","uc001dsg.2","chr1",100111430,100160096],[["uc001dsf.2"],"knownGene","uc001dsf.2","chr1",100111430,100155632],[["uc001dsh.1"],"knownGene","uc001dsh.1","chr1",100174258,100231349],[["uc001dsi.1"],"knownGene","uc001dsi.1","chr1",100315639,100389579],[["uc001dsj.1"],"knownGene","uc001dsj.1","chr1",100316044,100389579],[["uc001dsk.1"],"knownGene","uc001dsk.1","chr1",100316044,100389579],[["uc001dsl.1"],"knownGene","uc001dsl.1","chr1",100316044,100389579],[["uc001dsm.1"],"knownGene","uc001dsm.1","chr1",100316530,100389579],[["uc001dsn.1"],"knownGene","uc001dsn.1","chr1",100326765,100389579],[["uc001dso.1"],"knownGene","uc001dso.1","chr1",100434000,100435404],[["uc001dsp.1"],"knownGene","uc001dsp.1","chr1",100435539,100489006],[["uc001dsq.1"],"knownGene","uc001dsq.1","chr1",100435539,100489006],[["uc009wdy.1"],"knownGene","uc009wdy.1","chr1",100435539,100489006],[["uc001dsr.1"],"knownGene","uc001dsr.1","chr1",100435991,100489006],[["uc001dss.1"],"knownGene","uc001dss.1","chr1",100459157,100489006],[["uc001dst.2"],"knownGene","uc001dst.2","chr1",100503788,100548927],[["uc001dsu.2"],"knownGene","uc001dsu.2","chr1",100549103,100598511],[["uc009wdz.2"],"knownGene","uc009wdz.2","chr1",100549103,100598511],[["uc001dsv.2"],"knownGene","uc001dsv.2","chr1",100598705,100616053],[["uc010ouf.1"],"knownGene","uc010ouf.1","chr1",100598705,100616053],[["uc009wea.2"],"knownGene","uc009wea.2","chr1",100598705,100616053],[["uc001dsy.1"],"knownGene","uc001dsy.1","chr1",100614412,100643800],[["uc001dsz.1"],"knownGene","uc001dsz.1","chr1",100614412,100643800],[["uc001dsw.1"],"knownGene","uc001dsw.1","chr1",100614412,100643771],[["uc001dsx.1"],"knownGene","uc001dsx.1","chr1",100614412,100643771],[["uc001dta.2"],"knownGene","uc001dta.2","chr1",100652478,100715409],[["uc010oug.1"],"knownGene","uc010oug.1","chr1",100652478,100715409],[["uc001dtd.2"],"knownGene","uc001dtd.2","chr1",100731713,100758323],[["uc001dtc.2"],"knownGene","uc001dtc.2","chr1",100731713,100758323],[["uc010ouh.1"],"knownGene","uc010ouh.1","chr1",100731713,100739511],[["uc010oui.1"],"knownGene","uc010oui.1","chr1",100810583,100965021],[["uc009web.2"],"knownGene","uc009web.2","chr1",100810583,100963763],[["uc001dtg.3"],"knownGene","uc001dtg.3","chr1",100818022,100985832],[["uc009wee.2"],"knownGene","uc009wee.2","chr1",100818022,100985832],[["uc001dtf.2"],"knownGene","uc001dtf.2","chr1",100818022,100965021],[["uc009wed.1"],"knownGene","uc009wed.1","chr1",100818022,100965021],[["uc001dte.3"],"knownGene","uc001dte.3","chr1",100818022,100950925],[["uc009wec.1"],"knownGene","uc009wec.1","chr1",100818022,100856616],[["uc001dth.2"],"knownGene","uc001dth.2","chr1",101003727,101007582],[["uc001dti.2"],"knownGene","uc001dti.2","chr1",101185296,101204599],[["uc001dtj.2"],"knownGene","uc001dtj.2","chr1",101185296,101204599],[["uc010ouj.1"],"knownGene","uc010ouj.1","chr1",101185296,101204599],[["uc001dtk.1"],"knownGene","uc001dtk.1","chr1",101337940,101360418],[["uc001dtl.1"],"knownGene","uc001dtl.1","chr1",101337940,101360418],[["uc010ouk.1"],"knownGene","uc010ouk.1","chr1",101337940,101360418],[["uc001dtm.1"],"knownGene","uc001dtm.1","chr1",101337940,101360418],[["uc001dtn.2"],"knownGene","uc001dtn.2","chr1",101361631,101447311],[["uc001dto.2"],"knownGene","uc001dto.2","chr1",101361631,101447311],[["uc001dtz.2"],"knownGene","uc001dtz.2","chr1",101455179,101491644],[["uc001dtr.2"],"knownGene","uc001dtr.2","chr1",101455179,101491362],[["uc001dtq.2"],"knownGene","uc001dtq.2","chr1",101455179,101491362],[["uc001dts.2"],"knownGene","uc001dts.2","chr1",101455179,101491362],[["uc001dtt.2"],"knownGene","uc001dtt.2","chr1",101455179,101491362],[["uc001dtu.2"],"knownGene","uc001dtu.2","chr1",101455179,101491362],[["uc001dtv.2"],"knownGene","uc001dtv.2","chr1",101455179,101491362],[["uc001dtw.2"],"knownGene","uc001dtw.2","chr1",101455179,101491362],[["uc001dtx.2"],"knownGene","uc001dtx.2","chr1",101455179,101491362],[["uc001dty.2"],"knownGene","uc001dty.2","chr1",101455179,101491362],[["uc001dua.2"],"knownGene","uc001dua.2","chr1",101491408,101552817],[["uc001dub.2"],"knownGene","uc001dub.2","chr1",101491408,101552817],[["uc001duc.2"],"knownGene","uc001duc.2","chr1",101538215,101552817],[["uc001dud.2"],"knownGene","uc001dud.2","chr1",101702304,101707076],[["uc009weg.2"],"knownGene","uc009weg.2","chr1",101702458,101707076],[["uc001dug.2"],"knownGene","uc001dug.2","chr1",102268126,102462790],[["uc001duh.2"],"knownGene","uc001duh.2","chr1",102268126,102462790],[["uc001dui.2"],"knownGene","uc001dui.2","chr1",102268126,102462790],[["uc001duj.2"],"knownGene","uc001duj.2","chr1",102268126,102462790],[["uc001due.2"],"knownGene","uc001due.2","chr1",102268126,102312600],[["uc001duf.2"],"knownGene","uc001duf.2","chr1",102268126,102312600],[["uc001dul.2"],"knownGene","uc001dul.2","chr1",103342023,103574052],[["uc001dum.2"],"knownGene","uc001dum.2","chr1",103342023,103574052],[["uc001dun.2"],"knownGene","uc001dun.2","chr1",103342023,103574052],[["uc009weh.2"],"knownGene","uc009weh.2","chr1",103342023,103574052],[["uc001duk.2"],"knownGene","uc001duk.2","chr1",103342023,103496800],[["uc010oun.1"],"knownGene","uc010oun.1","chr1",104068577,104097857],[["uc010oul.1"],"knownGene","uc010oul.1","chr1",104068577,104096306],[["uc010oum.1"],"knownGene","uc010oum.1","chr1",104068577,104096306],[["uc010ouo.1"],"knownGene","uc010ouo.1","chr1",104078747,104122147],[["uc001duq.2"],"knownGene","uc001duq.2","chr1",104095895,104122147],[["uc010oup.1"],"knownGene","uc010oup.1","chr1",104112025,104114006],[["uc001dur.2"],"knownGene","uc001dur.2","chr1",104112334,104122147],[["uc001dus.1"],"knownGene","uc001dus.1","chr1",104118062,104153092],[["uc001dut.2"],"knownGene","uc001dut.2","chr1",104159998,104168393],[["uc010ouq.1"],"knownGene","uc010ouq.1","chr1",104159998,104162543],[["uc001duu.2"],"knownGene","uc001duu.2","chr1",104198140,104207172],[["uc001duv.2"],"knownGene","uc001duv.2","chr1",104198301,104207172],[["uc001dux.1"],"knownGene","uc001dux.1","chr1",104230039,104239073],[["uc001duw.1"],"knownGene","uc001duw.1","chr1",104230039,104238912],[["uc010our.1"],"knownGene","uc010our.1","chr1",104257374,104262492],[["uc001duy.2"],"knownGene","uc001duy.2","chr1",104292278,104301310],[["uc001duz.2"],"knownGene","uc001duz.2","chr1",104292439,104301310],[["uc001dva.2"],"knownGene","uc001dva.2","chr1",106144775,106161557],[["uc010ous.1"],"knownGene","uc010ous.1","chr1",107599266,107601907],[["uc001dvh.3"],"knownGene","uc001dvh.3","chr1",107682628,108024471],[["uc001dvf.3"],"knownGene","uc001dvf.3","chr1",107682628,108024471],[["uc001dvc.3"],"knownGene","uc001dvc.3","chr1",107682628,108024471],[["uc010out.1"],"knownGene","uc010out.1","chr1",107682628,108024471],[["uc001dvd.1"],"knownGene","uc001dvd.1","chr1",107683548,107953207],[["uc001dvi.2"],"knownGene","uc001dvi.2","chr1",107937775,108024471],[["uc001dve.2"],"knownGene","uc001dve.2","chr1",107937775,108024471],[["uc009wek.2"],"knownGene","uc009wek.2","chr1",107937775,108024471],[["uc001dvg.2"],"knownGene","uc001dvg.2","chr1",107937775,108024471],[["uc009wem.2"],"knownGene","uc009wem.2","chr1",107937775,108024471],[["uc001dvk.1"],"knownGene","uc001dvk.1","chr1",108113781,108507545],[["uc010ouw.1"],"knownGene","uc010ouw.1","chr1",108113781,108507545],[["uc001dvj.1"],"knownGene","uc001dvj.1","chr1",108113781,108231126],[["uc010ouv.1"],"knownGene","uc010ouv.1","chr1",108113781,108231126],[["uc010ouu.1"],"knownGene","uc010ouu.1","chr1",108113781,108220631],[["uc010oux.1"],"knownGene","uc010oux.1","chr1",108211462,108507545],[["uc001dvl.1"],"knownGene","uc001dvl.1","chr1",108211462,108506218],[["uc001dvn.3"],"knownGene","uc001dvn.3","chr1",108677448,108742974],[["uc001dvm.2"],"knownGene","uc001dvm.2","chr1",108677448,108735363],[["uc009weo.2"],"knownGene","uc009weo.2","chr1",108765962,108786703],[["uc001dvo.2"],"knownGene","uc001dvo.2","chr1",108765962,108786703],[["uc009wen.2"],"knownGene","uc009wen.2","chr1",108771541,108786703],[["uc001dvp.1"],"knownGene","uc001dvp.1","chr1",108803726,108816311],[["uc001dvq.2"],"knownGene","uc001dvq.2","chr1",108918459,108953432],[["uc001dvr.1"],"knownGene","uc001dvr.1","chr1",108963310,108975897],[["uc009wep.2"],"knownGene","uc009wep.2","chr1",108992903,109013259],[["uc009weq.2"],"knownGene","uc009weq.2","chr1",108992903,109013259],[["uc010ouy.1"],"knownGene","uc010ouy.1","chr1",109102970,109181948],[["uc001dvu.3"],"knownGene","uc001dvu.3","chr1",109190911,109204148],[["uc009wer.2"],"knownGene","uc009wer.2","chr1",109190911,109204148],[["uc001dvt.3"],"knownGene","uc001dvt.3","chr1",109190911,109203744],[["uc001dvv.3"],"knownGene","uc001dvv.3","chr1",109234931,109244420],[["uc001dvw.3"],"knownGene","uc001dvw.3","chr1",109234931,109244420],[["uc010ouz.1"],"knownGene","uc010ouz.1","chr1",109234931,109244420],[["uc001dvx.2"],"knownGene","uc001dvx.2","chr1",109255555,109285365],[["uc010ova.1"],"knownGene","uc010ova.1","chr1",109264956,109285365],[["uc001dvy.2"],"knownGene","uc001dvy.2","chr1",109289284,109352139],[["uc001dvz.2"],"knownGene","uc001dvz.2","chr1",109289284,109352139],[["uc001dwb.2"],"knownGene","uc001dwb.2","chr1",109358531,109400850],[["uc001dwa.2"],"knownGene","uc001dwa.2","chr1",109358531,109399716],[["uc010ovb.1"],"knownGene","uc010ovb.1","chr1",109365461,109506111],[["uc001dwc.2"],"knownGene","uc001dwc.2","chr1",109399838,109401144],[["uc010ove.1"],"knownGene","uc010ove.1","chr1",109419602,109476957],[["uc010ovc.1"],"knownGene","uc010ovc.1","chr1",109419602,109473043],[["uc010ovd.1"],"knownGene","uc010ovd.1","chr1",109419602,109473043],[["uc001dwf.1"],"knownGene","uc001dwf.1","chr1",109472129,109506111],[["uc001dwg.1"],"knownGene","uc001dwg.1","chr1",109472129,109506111],[["uc001dwe.1"],"knownGene","uc001dwe.1","chr1",109472129,109506099],[["uc009wes.1"],"knownGene","uc009wes.1","chr1",109477246,109493070],[["uc009wet.1"],"knownGene","uc009wet.1","chr1",109477246,109493070],[["uc001dwh.1"],"knownGene","uc001dwh.1","chr1",109486096,109506111],[["uc001dwl.2"],"knownGene","uc001dwl.2","chr1",109512839,109584850],[["uc001dwi.2"],"knownGene","uc001dwi.2","chr1",109512839,109584850],[["uc001dwj.2"],"knownGene","uc001dwj.2","chr1",109512839,109584850],[["uc010ovf.1"],"knownGene","uc010ovf.1","chr1",109512839,109560223],[["uc001dwk.2"],"knownGene","uc001dwk.2","chr1",109525903,109584850],[["uc001dwm.1"],"knownGene","uc001dwm.1","chr1",109606997,109618624],[["uc001dwn.2"],"knownGene","uc001dwn.2","chr1",109633402,109639553],[["uc009weu.2"],"knownGene","uc009weu.2","chr1",109633402,109639553],[["uc001dwo.1"],"knownGene","uc001dwo.1","chr1",109642814,109643234],[["uc009wew.2"],"knownGene","uc009wew.2","chr1",109648573,109656479],[["uc009wev.2"],"knownGene","uc009wev.2","chr1",109648573,109655369],[["uc001dwp.3"],"knownGene","uc001dwp.3","chr1",109648573,109655369],[["uc001dwq.2"],"knownGene","uc001dwq.2","chr1",109656532,109745853],[["uc010ovg.1"],"knownGene","uc010ovg.1","chr1",109656718,109749401],[["uc009wey.2"],"knownGene","uc009wey.2","chr1",109656718,109745853],[["uc009wex.1"],"knownGene","uc009wex.1","chr1",109656718,109743522],[["uc001dwr.2"],"knownGene","uc001dwr.2","chr1",109730600,109745853],[["uc001dws.1"],"knownGene","uc001dws.1","chr1",109740095,109742859],[["uc009wez.1"],"knownGene","uc009wez.1","chr1",109740095,109742859],[["uc001dwu.1"],"knownGene","uc001dwu.1","chr1",109756539,109780785],[["uc001dwv.1"],"knownGene","uc001dwv.1","chr1",109756539,109780785],[["uc001dww.1"],"knownGene","uc001dww.1","chr1",109756539,109780785],[["uc001dwx.1"],"knownGene","uc001dwx.1","chr1",109756539,109780785],[["uc009wfa.1"],"knownGene","uc009wfa.1","chr1",109756539,109780785],[["uc001dwt.1"],"knownGene","uc001dwt.1","chr1",109756539,109778831],[["uc001dwy.1"],"knownGene","uc001dwy.1","chr1",109756600,109780785],[["uc001dwz.1"],"knownGene","uc001dwz.1","chr1",109772013,109780785],[["uc001dxa.3"],"knownGene","uc001dxa.3","chr1",109792640,109818377],[["uc001dxh.2"],"knownGene","uc001dxh.2","chr1",109822178,109825808],[["uc001dxi.2"],"knownGene","uc001dxi.2","chr1",109822178,109825808],[["uc001dxj.2"],"knownGene","uc001dxj.2","chr1",109822178,109825808],[["uc001dxd.2"],"knownGene","uc001dxd.2","chr1",109822178,109825771],[["uc001dxe.2"],"knownGene","uc001dxe.2","chr1",109822178,109825771],[["uc001dxf.2"],"knownGene","uc001dxf.2","chr1",109822178,109825771],[["uc001dxg.2"],"knownGene","uc001dxg.2","chr1",109822178,109825771],[["uc001dxc.2"],"knownGene","uc001dxc.2","chr1",109822178,109825747],[["uc001dxb.2"],"knownGene","uc001dxb.2","chr1",109822178,109825041],[["uc001dxk.1"],"knownGene","uc001dxk.1","chr1",109834986,109849663],[["uc010ovh.1"],"knownGene","uc010ovh.1","chr1",109834986,109849663],[["uc001dxl.2"],"knownGene","uc001dxl.2","chr1",109834990,109849663],[["uc001dxm.1"],"knownGene","uc001dxm.1","chr1",109852191,109940563],[["uc010ovi.1"],"knownGene","uc010ovi.1","chr1",109852191,109935979],[["uc009wfb.2"],"knownGene","uc009wfb.2","chr1",109888372,109935979],[["uc001dxn.2"],"knownGene","uc001dxn.2","chr1",109944477,109969037],[["uc010ovj.1"],"knownGene","uc010ovj.1","chr1",109944477,109969037],[["uc001dxp.2"],"knownGene","uc001dxp.2","chr1",110009099,110024763],[["uc010ovk.1"],"knownGene","uc010ovk.1","chr1",110009099,110024763],[["uc001dxo.2"],"knownGene","uc001dxo.2","chr1",110009099,110021304],[["uc001dxq.2"],"knownGene","uc001dxq.2","chr1",110019390,110021304],[["uc001dxr.2"],"knownGene","uc001dxr.2","chr1",110026560,110035418],[["uc001dxs.2"],"knownGene","uc001dxs.2","chr1",110031468,110035418],[["uc001dxt.2"],"knownGene","uc001dxt.2","chr1",110033543,110035418],[["uc010ovl.1"],"knownGene","uc010ovl.1","chr1",110036657,110043062],[["uc010ovm.1"],"knownGene","uc010ovm.1","chr1",110036657,110043062],[["uc001dxu.2"],"knownGene","uc001dxu.2","chr1",110036700,110043062],[["uc001dxw.2"],"knownGene","uc001dxw.2","chr1",110036700,110043062],[["uc010ovn.1"],"knownGene","uc010ovn.1","chr1",110036700,110043062],[["uc010ovo.1"],"knownGene","uc010ovo.1","chr1",110036700,110043062],[["uc009wfd.2"],"knownGene","uc009wfd.2","chr1",110036700,110043062],[["uc010ovp.1"],"knownGene","uc010ovp.1","chr1",110036700,110043062],[["uc001dxx.3"],"knownGene","uc001dxx.3","chr1",110049446,110052336],[["uc001dxy.2"],"knownGene","uc001dxy.2","chr1",110082493,110088455],[["uc001dxz.2"],"knownGene","uc001dxz.2","chr1",110091185,110138452],[["uc010ovq.1"],"knownGene","uc010ovq.1","chr1",110141514,110141589],[["uc001dya.2"],"knownGene","uc001dya.2","chr1",110145889,110155705],[["uc009wfg.1"],"knownGene","uc009wfg.1","chr1",110162125,110173028],[["uc001dyb.1"],"knownGene","uc001dyb.1","chr1",110162458,110174677],[["uc009wfh.1"],"knownGene","uc009wfh.1","chr1",110162458,110174677],[["uc001dyc.1"],"knownGene","uc001dyc.1","chr1",110163275,110174677],[["uc010ovr.1"],"knownGene","uc010ovr.1","chr1",110163535,110174677],[["uc010ovs.1"],"knownGene","uc010ovs.1","chr1",110166653,110171117],[["uc001dyd.1"],"knownGene","uc001dyd.1","chr1",110168048,110174677],[["uc001dye.1"],"knownGene","uc001dye.1","chr1",110171948,110174677],[["uc001dyi.2"],"knownGene","uc001dyi.2","chr1",110198697,110217907],[["uc001dyh.2"],"knownGene","uc001dyh.2","chr1",110198697,110208123],[["uc001dyf.2"],"knownGene","uc001dyf.2","chr1",110198697,110204330],[["uc001dyg.2"],"knownGene","uc001dyg.2","chr1",110198697,110204330],[["uc009wfj.2"],"knownGene","uc009wfj.2","chr1",110198697,110204330],[["uc009wfi.2"],"knownGene","uc009wfi.2","chr1",110198697,110199958],[["uc010ovt.1"],"knownGene","uc010ovt.1","chr1",110210643,110226618],[["uc009wfk.2"],"knownGene","uc009wfk.2","chr1",110210643,110226618],[["uc001dyj.2"],"knownGene","uc001dyj.2","chr1",110210643,110217907],[["uc001dyk.2"],"knownGene","uc001dyk.2","chr1",110230417,110236366],[["uc001dyl.2"],"knownGene","uc001dyl.2","chr1",110230417,110236366],[["uc001dyn.2"],"knownGene","uc001dyn.2","chr1",110254863,110260888],[["uc010ovu.1"],"knownGene","uc010ovu.1","chr1",110254863,110260883],[["uc001dyo.2"],"knownGene","uc001dyo.2","chr1",110276553,110283660],[["uc001dyp.2"],"knownGene","uc001dyp.2","chr1",110276553,110283660],[["uc010ovv.1"],"knownGene","uc010ovv.1","chr1",110280037,110283133],[["uc001dys.1"],"knownGene","uc001dys.1","chr1",110292701,110306564],[["uc001dyq.1"],"knownGene","uc001dyq.1","chr1",110292701,110306564],[["uc001dyr.1"],"knownGene","uc001dyr.1","chr1",110292701,110306564],[["uc009wfm.1"],"knownGene","uc009wfm.1","chr1",110292701,110306564],[["uc009wfn.1"],"knownGene","uc009wfn.1","chr1",110294154,110306564],[["uc009wfo.1"],"knownGene","uc009wfo.1","chr1",110295307,110306564],[["uc001dyv.3"],"knownGene","uc001dyv.3","chr1",110453232,110472354],[["uc001dyw.3"],"knownGene","uc001dyw.3","chr1",110453232,110472354],[["uc001dyu.2"],"knownGene","uc001dyu.2","chr1",110453232,110469365],[["uc001dyt.2"],"knownGene","uc001dyt.2","chr1",110453232,110467824],[["uc001dyx.2"],"knownGene","uc001dyx.2","chr1",110527307,110566363],[["uc010ovw.1"],"knownGene","uc010ovw.1","chr1",110528109,110566363],[["uc001dyy.2"],"knownGene","uc001dyy.2","chr1",110546752,110566363],[["uc010ovx.1"],"knownGene","uc010ovx.1","chr1",110546754,110566363],[["uc001dyz.1"],"knownGene","uc001dyz.1","chr1",110574198,110597424],[["uc001dza.1"],"knownGene","uc001dza.1","chr1",110577240,110597424],[["uc009wfp.1"],"knownGene","uc009wfp.1","chr1",110577240,110597424],[["uc001dzb.2"],"knownGene","uc001dzb.2","chr1",110602997,110613322],[["uc001dzc.2"],"knownGene","uc001dzc.2","chr1",110655061,110656568],[["uc009wfq.2"],"knownGene","uc009wfq.2","chr1",110693131,110744821],[["uc001dze.1"],"knownGene","uc001dze.1","chr1",110735127,110737566],[["uc001dzg.2"],"knownGene","uc001dzg.2","chr1",110754064,110776665],[["uc001dzh.2"],"knownGene","uc001dzh.2","chr1",110754064,110776665],[["uc001dzi.2"],"knownGene","uc001dzi.2","chr1",110754064,110776665],[["uc009wfr.2"],"knownGene","uc009wfr.2","chr1",110754064,110769165],[["uc001dzf.2"],"knownGene","uc001dzf.2","chr1",110754064,110766704],[["uc001dzj.2"],"knownGene","uc001dzj.2","chr1",110829000,110881793],[["uc001dzl.1"],"knownGene","uc001dzl.1","chr1",110881944,110889303],[["uc001dzm.1"],"knownGene","uc001dzm.1","chr1",110881944,110889303],[["uc001dzn.1"],"knownGene","uc001dzn.1","chr1",110887099,110888734],[["uc001dzo.1"],"knownGene","uc001dzo.1","chr1",110905504,110933636],[["uc009wfs.1"],"knownGene","uc009wfs.1","chr1",110905504,110933636],[["uc001dzp.1"],"knownGene","uc001dzp.1","chr1",110905504,110933636],[["uc010ovy.1"],"knownGene","uc010ovy.1","chr1",110905504,110933636],[["uc001dzq.1"],"knownGene","uc001dzq.1","chr1",110905504,110933636],[["uc010ovz.1"],"knownGene","uc010ovz.1","chr1",110906247,110933636],[["uc001dzr.2"],"knownGene","uc001dzr.2","chr1",110943878,110950546],[["uc001dzs.2"],"knownGene","uc001dzs.2","chr1",110993787,110999974],[["uc009wft.1"],"knownGene","uc009wft.1","chr1",111016377,111031285],[["uc009wfu.1"],"knownGene","uc009wfu.1","chr1",111023387,111033891],[["uc001dzt.1"],"knownGene","uc001dzt.1","chr1",111059838,111061797],[["uc009wfv.1"],"knownGene","uc009wfv.1","chr1",111136202,111174096],[["uc009wfw.2"],"knownGene","uc009wfw.2","chr1",111145776,111148975],[["uc001dzu.2"],"knownGene","uc001dzu.2","chr1",111145776,111148344],[["uc001dzv.1"],"knownGene","uc001dzv.1","chr1",111214309,111217655],[["uc001dzw.2"],"knownGene","uc001dzw.2","chr1",111413820,111442557],[["uc001dzx.2"],"knownGene","uc001dzx.2","chr1",111415721,111442557],[["uc010owa.1"],"knownGene","uc010owa.1","chr1",111415777,111442557],[["uc001dzy.2"],"knownGene","uc001dzy.2","chr1",111415777,111442557],[["uc001eaa.2"],"knownGene","uc001eaa.2","chr1",111489812,111506566],[["uc001eab.2"],"knownGene","uc001eab.2","chr1",111489812,111506566],[["uc001dzz.2"],"knownGene","uc001dzz.2","chr1",111489812,111495583],[["uc001eac.1"],"knownGene","uc001eac.1","chr1",111489844,111506566],[["uc001ead.3"],"knownGene","uc001ead.3","chr1",111659954,111682838],[["uc001eae.3"],"knownGene","uc001eae.3","chr1",111659954,111682838],[["uc009wfy.2"],"knownGene","uc009wfy.2","chr1",111659954,111682838],[["uc001eaf.3"],"knownGene","uc001eaf.3","chr1",111659954,111682838],[["uc001eah.1"],"knownGene","uc001eah.1","chr1",111682248,111727724],[["uc001eag.2"],"knownGene","uc001eag.2","chr1",111682248,111703575],[["uc001eai.1"],"knownGene","uc001eai.1","chr1",111682832,111727724],[["uc001eaj.1"],"knownGene","uc001eaj.1","chr1",111682832,111727724],[["uc009wfz.1"],"knownGene","uc009wfz.1","chr1",111717500,111727724],[["uc001eal.1"],"knownGene","uc001eal.1","chr1",111729800,111747031],[["uc001eak.1"],"knownGene","uc001eak.1","chr1",111729800,111743281],[["uc001eam.2"],"knownGene","uc001eam.2","chr1",111770280,111786060],[["uc001ean.2"],"knownGene","uc001ean.2","chr1",111770280,111786060],[["uc001eao.2"],"knownGene","uc001eao.2","chr1",111772332,111786060],[["uc009wga.2"],"knownGene","uc009wga.2","chr1",111772332,111786060],[["uc009wgb.2"],"knownGene","uc009wgb.2","chr1",111823145,111828729],[["uc001eas.2"],"knownGene","uc001eas.2","chr1",111833483,111863184],[["uc001ear.2"],"knownGene","uc001ear.2","chr1",111833483,111863184],[["uc001eaq.2"],"knownGene","uc001eaq.2","chr1",111833483,111863184],[["uc009wgc.2"],"knownGene","uc009wgc.2","chr1",111833483,111863184],[["uc001eat.2"],"knownGene","uc001eat.2","chr1",111833483,111863184],[["uc001eav.2"],"knownGene","uc001eav.2","chr1",111853021,111863184],[["uc001eau.2"],"knownGene","uc001eau.2","chr1",111853021,111863184],[["uc009wgd.2"],"knownGene","uc009wgd.2","chr1",111853021,111863184],[["uc001eaw.2"],"knownGene","uc001eaw.2","chr1",111889194,111895639],[["uc001eax.2"],"knownGene","uc001eax.2","chr1",111889194,111895639],[["uc009wge.1"],"knownGene","uc009wge.1","chr1",111889194,111895639],[["uc001eay.2"],"knownGene","uc001eay.2","chr1",111890962,111895639],[["uc001eba.2"],"knownGene","uc001eba.2","chr1",111956937,111970399],[["uc010owb.1"],"knownGene","uc010owb.1","chr1",111956937,111970134],[["uc001eaz.2"],"knownGene","uc001eaz.2","chr1",111956937,111969690],[["uc010owc.1"],"knownGene","uc010owc.1","chr1",111966164,111970399],[["uc001ebb.2"],"knownGene","uc001ebb.2","chr1",111982512,111991830],[["uc010owd.1"],"knownGene","uc010owd.1","chr1",111982512,111991830],[["uc010owe.1"],"knownGene","uc010owe.1","chr1",111982512,111991830],[["uc009wgf.1"],"knownGene","uc009wgf.1","chr1",111991461,112002258],[["uc001ebc.2"],"knownGene","uc001ebc.2","chr1",111991742,112004523],[["uc001ebd.3"],"knownGene","uc001ebd.3","chr1",111991816,112004523],[["uc001ebe.2"],"knownGene","uc001ebe.2","chr1",112016603,112021133],[["uc001ebg.3"],"knownGene","uc001ebg.3","chr1",112025970,112106597],[["uc001ebf.2"],"knownGene","uc001ebf.2","chr1",112025970,112046743],[["uc001ebh.3"],"knownGene","uc001ebh.3","chr1",112042052,112046743],[["uc001ebi.2"],"knownGene","uc001ebi.2","chr1",112085054,112256100],[["uc001ebj.1"],"knownGene","uc001ebj.1","chr1",112141628,112150946],[["uc001ebk.2"],"knownGene","uc001ebk.2","chr1",112162404,112256100],[["uc001ebl.2"],"knownGene","uc001ebl.2","chr1",112162404,112256100],[["uc001ebm.2"],"knownGene","uc001ebm.2","chr1",112170091,112256100],[["uc001ebn.1"],"knownGene","uc001ebn.1","chr1",112256829,112259310],[["uc001ebp.1"],"knownGene","uc001ebp.1","chr1",112268369,112298419],[["uc001ebo.1"],"knownGene","uc001ebo.1","chr1",112268369,112282022],[["uc001ebq.1"],"knownGene","uc001ebq.1","chr1",112282462,112290420],[["uc001ebr.2"],"knownGene","uc001ebr.2","chr1",112287938,112298131],[["uc001ebs.2"],"knownGene","uc001ebs.2","chr1",112298189,112310198],[["uc010owf.1"],"knownGene","uc010owf.1","chr1",112298189,112310198],[["uc001ebt.2"],"knownGene","uc001ebt.2","chr1",112303018,112310198],[["uc001ebu.1"],"knownGene","uc001ebu.1","chr1",112318453,112531777],[["uc001ebv.1"],"knownGene","uc001ebv.1","chr1",112318453,112531777],[["uc001ebw.2"],"knownGene","uc001ebw.2","chr1",112533157,112541461],[["uc001ebx.2"],"knownGene","uc001ebx.2","chr1",112938799,113003785],[["uc001eby.1"],"knownGene","uc001eby.1","chr1",112938880,112941439],[["uc001ebz.2"],"knownGene","uc001ebz.2","chr1",112999439,113006063],[["uc001eca.2"],"knownGene","uc001eca.2","chr1",113010039,113063908],[["uc009wgg.2"],"knownGene","uc009wgg.2","chr1",113010039,113063908],[["uc001ecb.2"],"knownGene","uc001ecb.2","chr1",113051369,113063908],[["uc001ecg.2"],"knownGene","uc001ecg.2","chr1",113066141,113162405],[["uc001ecd.2"],"knownGene","uc001ecd.2","chr1",113066141,113162040],[["uc001ece.2"],"knownGene","uc001ece.2","chr1",113066141,113162040],[["uc001ecf.2"],"knownGene","uc001ecf.2","chr1",113066141,113162040],[["uc010owg.1"],"knownGene","uc010owg.1","chr1",113066141,113161761],[["uc010owh.1"],"knownGene","uc010owh.1","chr1",113066141,113161761],[["uc001ecc.2"],"knownGene","uc001ecc.2","chr1",113066141,113161550],[["uc009wgh.2"],"knownGene","uc009wgh.2","chr1",113066141,113153625],[["uc001eci.2"],"knownGene","uc001eci.2","chr1",113084416,113162040],[["uc001ech.2"],"knownGene","uc001ech.2","chr1",113084416,113161761],[["uc010owi.1"],"knownGene","uc010owi.1","chr1",113084416,113160839],[["uc009wgi.1"],"knownGene","uc009wgi.1","chr1",113084572,113161761],[["uc010owj.1"],"knownGene","uc010owj.1","chr1",113093222,113161761],[["uc001ecj.1"],"knownGene","uc001ecj.1","chr1",113162074,113214241],[["uc001eck.2"],"knownGene","uc001eck.2","chr1",113217047,113243367],[["uc001ecn.2"],"knownGene","uc001ecn.2","chr1",113217047,113243367],[["uc001ecm.2"],"knownGene","uc001ecm.2","chr1",113217047,113243367],[["uc001ecl.2"],"knownGene","uc001ecl.2","chr1",113217047,113243357],[["uc009wgj.1"],"knownGene","uc009wgj.1","chr1",113217469,113239156],[["uc001ecq.1"],"knownGene","uc001ecq.1","chr1",113243748,113250025],[["uc001ecr.1"],"knownGene","uc001ecr.1","chr1",113243748,113250025],[["uc009wgk.1"],"knownGene","uc009wgk.1","chr1",113243748,113250025],[["uc001ecp.1"],"knownGene","uc001ecp.1","chr1",113243748,113249678],[["uc001ect.1"],"knownGene","uc001ect.1","chr1",113252615,113257950],[["uc001ecs.1"],"knownGene","uc001ecs.1","chr1",113252615,113257913],[["uc009wgl.1"],"knownGene","uc009wgl.1","chr1",113252615,113255079],[["uc001ecu.2"],"knownGene","uc001ecu.2","chr1",113263188,113269854],[["uc001ecv.2"],"knownGene","uc001ecv.2","chr1",113263188,113269854],[["uc010owk.1"],"knownGene","uc010owk.1","chr1",113263188,113269854],[["uc010owl.1"],"knownGene","uc010owl.1","chr1",113263188,113269854],[["uc001ecw.1"],"knownGene","uc001ecw.1","chr1",113362795,113393265],[["uc001ecy.2"],"knownGene","uc001ecy.2","chr1",113454471,113498975],[["uc001ecx.2"],"knownGene","uc001ecx.2","chr1",113454471,113498685],[["uc001ecz.2"],"knownGene","uc001ecz.2","chr1",113458817,113498685],[["uc001eda.1"],"knownGene","uc001eda.1","chr1",113465971,113467295],[["uc001edc.1"],"knownGene","uc001edc.1","chr1",113499036,113542118],[["uc001edb.2"],"knownGene","uc001edb.2","chr1",113499036,113506688],[["uc001edd.2"],"knownGene","uc001edd.2","chr1",113499070,113511596],[["uc001ede.1"],"knownGene","uc001ede.1","chr1",113554308,113615724],[["uc001edf.1"],"knownGene","uc001edf.1","chr1",113615830,113667342],[["uc009wgn.1"],"knownGene","uc009wgn.1","chr1",113615830,113667342],[["uc001edg.1"],"knownGene","uc001edg.1","chr1",113739503,113748875],[["uc001edk.2"],"knownGene","uc001edk.2","chr1",113933474,114228535],[["uc001edi.3"],"knownGene","uc001edi.3","chr1",113933474,114228535],[["uc010owm.1"],"knownGene","uc010owm.1","chr1",113933474,114228535],[["uc001edh.3"],"knownGene","uc001edh.3","chr1",113933474,114224924],[["uc001edj.2"],"knownGene","uc001edj.2","chr1",114133105,114228535],[["uc009wgo.2"],"knownGene","uc009wgo.2","chr1",114223532,114228535],[["uc009wgp.1"],"knownGene","uc009wgp.1","chr1",114239823,114301777],[["uc001edm.2"],"knownGene","uc001edm.2","chr1",114239823,114257834],[["uc001edn.2"],"knownGene","uc001edn.2","chr1",114246448,114302098],[["uc001edo.1"],"knownGene","uc001edo.1","chr1",114248388,114256060],[["uc010own.1"],"knownGene","uc010own.1","chr1",114255891,114301355],[["uc001edp.2"],"knownGene","uc001edp.2","chr1",114267957,114302098],[["uc001edq.2"],"knownGene","uc001edq.2","chr1",114304454,114355070],[["uc001edr.2"],"knownGene","uc001edr.2","chr1",114304454,114355070],[["uc001eds.2"],"knownGene","uc001eds.2","chr1",114356439,114414375],[["uc009wgq.2"],"knownGene","uc009wgq.2","chr1",114356439,114414375],[["uc010owo.1"],"knownGene","uc010owo.1","chr1",114356439,114414375],[["uc001edt.2"],"knownGene","uc001edt.2","chr1",114356439,114414375],[["uc009wgr.2"],"knownGene","uc009wgr.2","chr1",114361920,114414375],[["uc009wgs.2"],"knownGene","uc009wgs.2","chr1",114361920,114414375],[["uc001edu.2"],"knownGene","uc001edu.2","chr1",114375568,114414375],[["uc001edv.1"],"knownGene","uc001edv.1","chr1",114399256,114443859],[["uc001edw.2"],"knownGene","uc001edw.2","chr1",114419436,114430169],[["uc001edx.2"],"knownGene","uc001edx.2","chr1",114419436,114430169],[["uc001edy.2"],"knownGene","uc001edy.2","chr1",114419436,114430169],[["uc001edz.1"],"knownGene","uc001edz.1","chr1",114424394,114430169],[["uc001eed.2"],"knownGene","uc001eed.2","chr1",114437676,114447741],[["uc010owp.1"],"knownGene","uc010owp.1","chr1",114437676,114447741],[["uc001eeb.2"],"knownGene","uc001eeb.2","chr1",114437676,114447482],[["uc001eec.2"],"knownGene","uc001eec.2","chr1",114437676,114447482],[["uc001eea.1"],"knownGene","uc001eea.1","chr1",114437677,114443022],[["uc001eee.1"],"knownGene","uc001eee.1","chr1",114437681,114439764],[["uc010owq.1"],"knownGene","uc010owq.1","chr1",114442030,114447482],[["uc001eeg.2"],"knownGene","uc001eeg.2","chr1",114448037,114456692],[["uc001eeh.2"],"knownGene","uc001eeh.2","chr1",114448037,114456692],[["uc001eei.2"],"knownGene","uc001eei.2","chr1",114448037,114456692],[["uc001eek.2"],"knownGene","uc001eek.2","chr1",114466623,114471880],[["uc001eej.2"],"knownGene","uc001eej.2","chr1",114466623,114471854],[["uc001eem.2"],"knownGene","uc001eem.2","chr1",114471995,114520421],[["uc001eel.2"],"knownGene","uc001eel.2","chr1",114471995,114514693],[["uc001een.2"],"knownGene","uc001een.2","chr1",114472438,114520421],[["uc001eeo.2"],"knownGene","uc001eeo.2","chr1",114493766,114520421],[["uc001eep.2"],"knownGene","uc001eep.2","chr1",114496498,114520421],[["uc001eeq.2"],"knownGene","uc001eeq.2","chr1",114506008,114520421],[["uc001eet.1"],"knownGene","uc001eet.1","chr1",114522029,114524876],[["uc001eer.1"],"knownGene","uc001eer.1","chr1",114522029,114524875],[["uc001ees.1"],"knownGene","uc001ees.1","chr1",114522029,114524875],[["uc001eev.2"],"knownGene","uc001eev.2","chr1",114631914,114696472],[["uc001eeu.2"],"knownGene","uc001eeu.2","chr1",114631914,114641887],[["uc001eew.2"],"knownGene","uc001eew.2","chr1",114935400,115053781],[["uc001eex.2"],"knownGene","uc001eex.2","chr1",114935400,115053781],[["uc010ows.1"],"knownGene","uc010ows.1","chr1",114935400,115006178],[["uc010owr.1"],"knownGene","uc010owr.1","chr1",114935400,114970516],[["uc001eey.1"],"knownGene","uc001eey.1","chr1",114946947,114949722],[["uc001eez.2"],"knownGene","uc001eez.2","chr1",115064017,115213044],[["uc001efa.2"],"knownGene","uc001efa.2","chr1",115110182,115124265],[["uc001efc.1"],"knownGene","uc001efc.1","chr1",115127195,115212732],[["uc001efd.1"],"knownGene","uc001efd.1","chr1",115127195,115212732],[["uc001efe.1"],"knownGene","uc001efe.1","chr1",115215721,115238176],[["uc001eff.1"],"knownGene","uc001eff.1","chr1",115215721,115238176],[["uc009wgu.2"],"knownGene","uc009wgu.2","chr1",115247078,115259515],[["uc001efh.3"],"knownGene","uc001efh.3","chr1",115247078,115252391],[["uc001efk.2"],"knownGene","uc001efk.2","chr1",115259537,115300671],[["uc001efm.2"],"knownGene","uc001efm.2","chr1",115259537,115300671],[["uc001efl.2"],"knownGene","uc001efl.2","chr1",115259537,115300671],[["uc009wgv.2"],"knownGene","uc009wgv.2","chr1",115259537,115300671],[["uc001efn.2"],"knownGene","uc001efn.2","chr1",115259537,115300671],[["uc001efi.2"],"knownGene","uc001efi.2","chr1",115259537,115292828],[["uc001efj.2"],"knownGene","uc001efj.2","chr1",115259537,115292828],[["uc001efp.3"],"knownGene","uc001efp.3","chr1",115312106,115323308],[["uc001efo.3"],"knownGene","uc001efo.3","chr1",115312106,115323308],[["uc001efr.2"],"knownGene","uc001efr.2","chr1",115397454,115537988],[["uc010owt.1"],"knownGene","uc010owt.1","chr1",115397454,115537988],[["uc001efq.2"],"knownGene","uc001efq.2","chr1",115397454,115537988],[["uc009wgw.2"],"knownGene","uc009wgw.2","chr1",115397454,115537988],[["uc001efs.1"],"knownGene","uc001efs.1","chr1",115572414,115576941],[["uc001eft.2"],"knownGene","uc001eft.2","chr1",115590634,115632115],[["uc001efu.1"],"knownGene","uc001efu.1","chr1",115828536,115880857],[["uc001efv.1"],"knownGene","uc001efv.1","chr1",116184573,116240845],[["uc009wgy.1"],"knownGene","uc009wgy.1","chr1",116184573,116240845],[["uc001efw.1"],"knownGene","uc001efw.1","chr1",116193897,116207386],[["uc001efx.3"],"knownGene","uc001efx.3","chr1",116242627,116311426],[["uc010owu.1"],"knownGene","uc010owu.1","chr1",116242627,116311426],[["uc001efy.2"],"knownGene","uc001efy.2","chr1",116379000,116383747],[["uc009wgz.2"],"knownGene","uc009wgz.2","chr1",116379000,116383333],[["uc001efz.2"],"knownGene","uc001efz.2","chr1",116461996,116468528],[["uc001egb.3"],"knownGene","uc001egb.3","chr1",116519118,116612672],[["uc001ega.2"],"knownGene","uc001ega.2","chr1",116519118,116574511],[["uc001egc.1"],"knownGene","uc001egc.1","chr1",116654375,116677861],[["uc010owv.1"],"knownGene","uc010owv.1","chr1",116915003,116946597],[["uc001ege.2"],"knownGene","uc001ege.2","chr1",116915794,116947394],[["uc001egd.2"],"knownGene","uc001egd.2","chr1",116915794,116928766],[["uc010oww.1"],"knownGene","uc010oww.1","chr1",116916488,116947394],[["uc010owx.1"],"knownGene","uc010owx.1","chr1",116925991,116947394],[["uc009whb.2"],"knownGene","uc009whb.2","chr1",116935486,116961244],[["uc001egg.3"],"knownGene","uc001egg.3","chr1",116941621,116961244],[["uc001egh.2"],"knownGene","uc001egh.2","chr1",116943469,116947394],[["uc001egi.3"],"knownGene","uc001egi.3","chr1",116947335,116961244],[["uc001egj.3"],"knownGene","uc001egj.3","chr1",116947335,116961244],[["uc001egk.3"],"knownGene","uc001egk.3","chr1",116947335,116961244],[["uc001egl.1"],"knownGene","uc001egl.1","chr1",117035644,117041834],[["uc001egm.2"],"knownGene","uc001egm.2","chr1",117057156,117113715],[["uc001egn.2"],"knownGene","uc001egn.2","chr1",117057156,117113715],[["uc010owy.1"],"knownGene","uc010owy.1","chr1",117061322,117113715],[["uc001ego.1"],"knownGene","uc001ego.1","chr1",117061852,117087226],[["uc001egp.3"],"knownGene","uc001egp.3","chr1",117064424,117113715],[["uc001egq.1"],"knownGene","uc001egq.1","chr1",117117030,117210314],[["uc001egr.1"],"knownGene","uc001egr.1","chr1",117117030,117210314],[["uc001egs.1"],"knownGene","uc001egs.1","chr1",117127160,117150953],[["uc001egu.3"],"knownGene","uc001egu.3","chr1",117297085,117311850],[["uc010owz.1"],"knownGene","uc010owz.1","chr1",117297085,117308084],[["uc010oxa.1"],"knownGene","uc010oxa.1","chr1",117297085,117308084],[["uc001egv.1"],"knownGene","uc001egv.1","chr1",117452688,117532972],[["uc010oxc.1"],"knownGene","uc010oxc.1","chr1",117544381,117579173],[["uc010oxd.1"],"knownGene","uc010oxd.1","chr1",117544381,117579173],[["uc009whd.2"],"knownGene","uc009whd.2","chr1",117544381,117579166],[["uc010oxb.1"],"knownGene","uc010oxb.1","chr1",117544381,117578874],[["uc001egy.2"],"knownGene","uc001egy.2","chr1",117602948,117645489],[["uc001egx.1"],"knownGene","uc001egx.1","chr1",117602948,117624997],[["uc001eha.2"],"knownGene","uc001eha.2","chr1",117653676,117664414],[["uc001egz.2"],"knownGene","uc001egz.2","chr1",117653676,117664411],[["uc009whe.2"],"knownGene","uc009whe.2","chr1",117653676,117664411],[["uc001ehb.2"],"knownGene","uc001ehb.2","chr1",117686209,117753549],[["uc001ehc.2"],"knownGene","uc001ehc.2","chr1",117686209,117753549],[["uc009whf.1"],"knownGene","uc009whf.1","chr1",117690234,117753549],[["uc001ehd.1"],"knownGene","uc001ehd.1","chr1",117910084,118068320],[["uc009whg.1"],"knownGene","uc009whg.1","chr1",117910084,118042176],[["uc001ehe.2"],"knownGene","uc001ehe.2","chr1",118148603,118171010],[["uc001ehf.2"],"knownGene","uc001ehf.2","chr1",118406107,118472302],[["uc001ehg.2"],"knownGene","uc001ehg.2","chr1",118419845,118472302],[["uc010oxe.1"],"knownGene","uc010oxe.1","chr1",118472371,118503049],[["uc001ehi.2"],"knownGene","uc001ehi.2","chr1",118472371,118502221],[["uc001ehh.2"],"knownGene","uc001ehh.2","chr1",118472371,118484470],[["uc001ehk.2"],"knownGene","uc001ehk.2","chr1",118496287,118727848],[["uc001ehl.1"],"knownGene","uc001ehl.1","chr1",119425665,119532179],[["uc009whj.1"],"knownGene","uc009whj.1","chr1",119425665,119441748],[["uc001ehm.2"],"knownGene","uc001ehm.2","chr1",119573840,119683295],[["uc001ehn.2"],"knownGene","uc001ehn.2","chr1",119573840,119683295],[["uc010oxg.1"],"knownGene","uc010oxg.1","chr1",119573840,119683295],[["uc010oxh.1"],"knownGene","uc010oxh.1","chr1",119573840,119683295],[["uc010oxf.1"],"knownGene","uc010oxf.1","chr1",119573840,119682973],[["uc010oxi.1"],"knownGene","uc010oxi.1","chr1",119576164,119682973],[["uc001ehp.1"],"knownGene","uc001ehp.1","chr1",119683047,119818596],[["uc009whk.1"],"knownGene","uc009whk.1","chr1",119683047,119726444],[["uc001eho.1"],"knownGene","uc001eho.1","chr1",119683047,119694031],[["uc001ehq.1"],"knownGene","uc001ehq.1","chr1",119911401,119936751],[["uc001ehr.1"],"knownGene","uc001ehr.1","chr1",119911401,119936751],[["uc001ehs.2"],"knownGene","uc001ehs.2","chr1",119957269,119965649],[["uc001ehu.2"],"knownGene","uc001ehu.2","chr1",119957772,119989120],[["uc001eht.2"],"knownGene","uc001eht.2","chr1",119957772,119965649],[["uc001ehv.1"],"knownGene","uc001ehv.1","chr1",120049825,120057681],[["uc001ehw.2"],"knownGene","uc001ehw.2","chr1",120049940,120057681],[["uc001ehx.1"],"knownGene","uc001ehx.1","chr1",120076170,120076936],[["uc001ehy.1"],"knownGene","uc001ehy.1","chr1",120161999,120190390],[["uc001ehz.2"],"knownGene","uc001ehz.2","chr1",120254418,120286848],[["uc009whm.2"],"knownGene","uc009whm.2","chr1",120254418,120286848],[["uc001eia.2"],"knownGene","uc001eia.2","chr1",120254418,120286848],[["uc009whn.2"],"knownGene","uc009whn.2","chr1",120254418,120286848],[["uc009whl.2"],"knownGene","uc009whl.2","chr1",120254418,120277603],[["uc001eib.2"],"knownGene","uc001eib.2","chr1",120262249,120286848],[["uc001eic.2"],"knownGene","uc001eic.2","chr1",120285421,120286848],[["uc001eid.2"],"knownGene","uc001eid.2","chr1",120291004,120311518],[["uc010oxj.1"],"knownGene","uc010oxj.1","chr1",120291004,120311518],[["uc001eie.2"],"knownGene","uc001eie.2","chr1",120291025,120307249],[["uc001eig.2"],"knownGene","uc001eig.2","chr1",120336641,120354203],[["uc001eif.2"],"knownGene","uc001eif.2","chr1",120336641,120354203],[["uc001eih.1"],"knownGene","uc001eih.1","chr1",120344945,120354203],[["uc010oxk.1"],"knownGene","uc010oxk.1","chr1",120377388,120387779],[["uc001eij.2"],"knownGene","uc001eij.2","chr1",120436156,120439113],[["uc001eik.2"],"knownGene","uc001eik.2","chr1",120454177,120612276],[["uc001eil.2"],"knownGene","uc001eil.2","chr1",120477736,120612276],[["uc001eim.3"],"knownGene","uc001eim.3","chr1",120492743,120612276],[["uc009whp.2"],"knownGene","uc009whp.2","chr1",120839004,120855680],[["uc001ein.3"],"knownGene","uc001ein.3","chr1",120839411,120855680],[["uc001eio.2"],"knownGene","uc001eio.2","chr1",120906033,120914842],[["uc001eip.2"],"knownGene","uc001eip.2","chr1",120926908,120935944],[["uc001eiq.2"],"knownGene","uc001eiq.2","chr1",120926908,120935944],[["uc010oxl.1"],"knownGene","uc010oxl.1","chr1",120926908,120935944],[["uc009whr.2"],"knownGene","uc009whr.2","chr1",120927646,120935944],[["uc009whs.2"],"knownGene","uc009whs.2","chr1",120929487,120935944],[["uc001eis.2"],"knownGene","uc001eis.2","chr1",121107151,121131151],[["uc001eiu.1"],"knownGene","uc001eiu.1","chr1",121260909,121313686],[["uc009wht.1"],"knownGene","uc009wht.1","chr1",121306423,121313686],[["uc001eiw.1"],"knownGene","uc001eiw.1","chr1",142618798,143257763],[["uc001eix.1"],"knownGene","uc001eix.1","chr1",142620644,142714605],[["uc001eiy.2"],"knownGene","uc001eiy.2","chr1",142660105,142660135],[["uc001eiz.1"],"knownGene","uc001eiz.1","chr1",142672191,142672219],[["uc001ejb.2"],"knownGene","uc001ejb.2","chr1",142803224,142888797],[["uc001ejc.2"],"knownGene","uc001ejc.2","chr1",142803530,142826641],[["uc001ejd.1"],"knownGene","uc001ejd.1","chr1",142804898,142890670],[["uc001eje.2"],"knownGene","uc001eje.2","chr1",142851396,142851424],[["uc009whu.1"],"knownGene","uc009whu.1","chr1",142853227,142855999],[["uc001ejf.1"],"knownGene","uc001ejf.1","chr1",143119060,143163748],[["uc001ejg.1"],"knownGene","uc001ejg.1","chr1",143168647,143168675],[["uc001ejh.1"],"knownGene","uc001ejh.1","chr1",143184707,143184737],[["uc001eji.1"],"knownGene","uc001eji.1","chr1",143185662,143185692],[["uc001ejj.2"],"knownGene","uc001ejj.2","chr1",143185981,143186010],[["uc001ejk.2"],"knownGene","uc001ejk.2","chr1",143289064,143289092],[["uc001ejl.1"],"knownGene","uc001ejl.1","chr1",143402283,143402313],[["uc001ejm.1"],"knownGene","uc001ejm.1","chr1",143402601,143402631],[["uc002zkn.1"],"knownGene","uc002zkn.1","chr1",143403553,143403583],[["uc001ejn.1"],"knownGene","uc001ejn.1","chr1",143424332,143467651],[["uc001ejo.2"],"knownGene","uc001ejo.2","chr1",143431367,143431397],[["uc001ejp.3"],"knownGene","uc001ejp.3","chr1",143647638,143744587],[["uc001ejq.2"],"knownGene","uc001ejq.2","chr1",143687145,143714180],[["uc009whw.1"],"knownGene","uc009whw.1","chr1",143687145,143705973],[["uc001ejr.3"],"knownGene","uc001ejr.3","chr1",143717588,143744587],[["uc009whx.2"],"knownGene","uc009whx.2","chr1",143718512,143744587],[["uc009why.2"],"knownGene","uc009why.2","chr1",143719238,143744587],[["uc001ejt.2"],"knownGene","uc001ejt.2","chr1",143767145,143767881],[["uc002qvn.1"],"knownGene","uc002qvn.1","chr1",143896451,143913143],[["uc010evy.1"],"knownGene","uc010evy.1","chr1",143896451,143913143],[["uc010oxm.1"],"knownGene","uc010oxm.1","chr1",143915747,144094477],[["uc001eju.1"],"knownGene","uc001eju.1","chr1",144044034,144044079],[["uc010oxn.1"],"knownGene","uc010oxn.1","chr1",144146806,144828810],[["uc010oxo.1"],"knownGene","uc010oxo.1","chr1",144146806,144828810],[["uc010oxp.1"],"knownGene","uc010oxp.1","chr1",144150981,144172451],[["uc010oxq.1"],"knownGene","uc010oxq.1","chr1",144151506,144186823],[["uc010oxr.1"],"knownGene","uc010oxr.1","chr1",144151518,144828810],[["uc001ejx.1"],"knownGene","uc001ejx.1","chr1",144160410,144191577],[["uc001ejz.1"],"knownGene","uc001ejz.1","chr1",144162000,144167711],[["uc010oxs.1"],"knownGene","uc010oxs.1","chr1",144166563,144167711],[["uc010oxt.1"],"knownGene","uc010oxt.1","chr1",144169908,144828810],[["uc010oxv.1"],"knownGene","uc010oxv.1","chr1",144174494,144204294],[["uc010oxu.1"],"knownGene","uc010oxu.1","chr1",144174494,144175642],[["uc010oxw.1"],"knownGene","uc010oxw.1","chr1",144175658,144212182],[["uc010oxx.1"],"knownGene","uc010oxx.1","chr1",144179473,144209011],[["uc010oxy.1"],"knownGene","uc010oxy.1","chr1",144181950,144204294],[["uc001ekg.1"],"knownGene","uc001ekg.1","chr1",144183587,144828810],[["uc010oxz.1"],"knownGene","uc010oxz.1","chr1",144184251,144223323],[["uc001ekk.1"],"knownGene","uc001ekk.1","chr1",144190581,144828810],[["uc010oya.1"],"knownGene","uc010oya.1","chr1",144190581,144201053],[["uc010oyb.1"],"knownGene","uc010oyb.1","chr1",144196230,144204294],[["uc001ekl.1"],"knownGene","uc001ekl.1","chr1",144196230,144201053],[["uc010oyc.1"],"knownGene","uc010oyc.1","chr1",144199908,144201053],[["uc009wir.2"],"knownGene","uc009wir.2","chr1",144201704,145334792],[["uc009wid.2"],"knownGene","uc009wid.2","chr1",144204185,144212182],[["uc001ekn.2"],"knownGene","uc001ekn.2","chr1",144204185,144209011],[["uc001ekp.3"],"knownGene","uc001ekp.3","chr1",144212642,144215424],[["uc010oyd.1"],"knownGene","uc010oyd.1","chr1",144218498,144828810],[["uc001ekq.1"],"knownGene","uc001ekq.1","chr1",144275887,144290006],[["uc001eks.2"],"knownGene","uc001eks.2","chr1",144300513,144341755],[["uc001ekr.3"],"knownGene","uc001ekr.3","chr1",144300513,144340773],[["uc001ekt.3"],"knownGene","uc001ekt.3","chr1",144300513,144340773],[["uc001ekv.2"],"knownGene","uc001ekv.2","chr1",144339562,144340773],[["uc001ekw.2"],"knownGene","uc001ekw.2","chr1",144363463,144364246],[["uc001ekz.3"],"knownGene","uc001ekz.3","chr1",144480747,144521969],[["uc001eky.3"],"knownGene","uc001eky.3","chr1",144480747,144520993],[["uc001ela.3"],"knownGene","uc001ela.3","chr1",144480747,144520993],[["uc001elb.3"],"knownGene","uc001elb.3","chr1",144514873,144519720],[["uc009wif.1"],"knownGene","uc009wif.1","chr1",144593695,144615303],[["uc001elc.2"],"knownGene","uc001elc.2","chr1",144593695,144597732],[["uc010oye.1"],"knownGene","uc010oye.1","chr1",144594403,145368682],[["uc001ele.2"],"knownGene","uc001ele.2","chr1",144596310,144604296],[["uc001elf.3"],"knownGene","uc001elf.3","chr1",144612023,144612727],[["uc009wig.1"],"knownGene","uc009wig.1","chr1",144614839,144828810],[["uc010oyf.1"],"knownGene","uc010oyf.1","chr1",144614958,145311154],[["uc010oyg.1"],"knownGene","uc010oyg.1","chr1",144614958,145311154],[["uc001eli.3"],"knownGene","uc001eli.3","chr1",144614958,144828810],[["uc009wii.1"],"knownGene","uc009wii.1","chr1",144615095,144822084],[["uc001elo.2"],"knownGene","uc001elo.2","chr1",144676872,145076079],[["uc001elm.3"],"knownGene","uc001elm.3","chr1",144676872,145039944],[["uc001eln.3"],"knownGene","uc001eln.3","chr1",144676872,145039944],[["uc001ell.1"],"knownGene","uc001ell.1","chr1",144676872,144995082],[["uc001elk.1"],"knownGene","uc001elk.1","chr1",144676872,144995022],[["uc001elp.2"],"knownGene","uc001elp.2","chr1",144811942,144828810],[["uc001elr.3"],"knownGene","uc001elr.3","chr1",144828972,144830389],[["uc001els.1"],"knownGene","uc001els.1","chr1",144832199,144833038],[["uc001elt.1"],"knownGene","uc001elt.1","chr1",144833046,144833912],[["uc001elu.1"],"knownGene","uc001elu.1","chr1",144833912,144834808],[["uc001elx.3"],"knownGene","uc001elx.3","chr1",144851427,145039944],[["uc001elw.3"],"knownGene","uc001elw.3","chr1",144851427,144995022],[["uc001elv.3"],"knownGene","uc001elv.3","chr1",144851427,144894125],[["uc001ema.2"],"knownGene","uc001ema.2","chr1",144862711,144868172],[["uc001emc.1"],"knownGene","uc001emc.1","chr1",144890590,144995022],[["uc001emd.1"],"knownGene","uc001emd.1","chr1",144890590,144995022],[["uc001emb.1"],"knownGene","uc001emb.1","chr1",144890590,144932032],[["uc001eme.1"],"knownGene","uc001eme.1","chr1",144895121,144922047],[["uc001emf.1"],"knownGene","uc001emf.1","chr1",144902727,144932447],[["uc001emh.2"],"knownGene","uc001emh.2","chr1",144951760,145076079],[["uc001emg.1"],"knownGene","uc001emg.1","chr1",144951760,144995022],[["uc001emi.3"],"knownGene","uc001emi.3","chr1",145004780,145005286],[["uc001emj.2"],"knownGene","uc001emj.2","chr1",145013718,145018393],[["uc001emk.2"],"knownGene","uc001emk.2","chr1",145074846,145076079],[["uc001eml.1"],"knownGene","uc001eml.1","chr1",145096406,145116922],[["uc001emp.3"],"knownGene","uc001emp.3","chr1",145209110,146424095],[["uc010oyh.1"],"knownGene","uc010oyh.1","chr1",145209110,145295525],[["uc001emo.2"],"knownGene","uc001emo.2","chr1",145209110,145291654],[["uc001emn.3"],"knownGene","uc001emn.3","chr1",145209110,145285911],[["uc001emm.3"],"knownGene","uc001emm.3","chr1",145209110,145285911],[["uc001emq.1"],"knownGene","uc001emq.1","chr1",145293232,145311154],[["uc001end.3"],"knownGene","uc001end.3","chr1",145293370,145368682],[["uc010oyi.1"],"knownGene","uc010oyi.1","chr1",145302653,145368682],[["uc010oyk.1"],"knownGene","uc010oyk.1","chr1",145311785,145368682],[["uc010oyl.1"],"knownGene","uc010oyl.1","chr1",145311785,145368682],[["uc010oyj.1"],"knownGene","uc010oyj.1","chr1",145311785,145320619],[["uc010oym.1"],"knownGene","uc010oym.1","chr1",145314903,145344236],[["uc010oyn.1"],"knownGene","uc010oyn.1","chr1",145318053,145353680],[["uc010oyo.1"],"knownGene","uc010oyo.1","chr1",145319623,145339512],[["uc001enc.2"],"knownGene","uc001enc.2","chr1",145322771,145364674],[["uc010oyp.1"],"knownGene","uc010oyp.1","chr1",145324347,145353680],[["uc010oyq.1"],"knownGene","uc010oyq.1","chr1",145344127,145364674],[["uc010oyr.1"],"knownGene","uc010oyr.1","chr1",145346372,145364674],[["uc001eng.1"],"knownGene","uc001eng.1","chr1",145372087,145373798],[["uc001enh.1"],"knownGene","uc001enh.1","chr1",145373798,145374694],[["uc001eni.2"],"knownGene","uc001eni.2","chr1",145413190,145417545],[["uc001enj.2"],"knownGene","uc001enj.2","chr1",145413190,145417545],[["uc001enk.2"],"knownGene","uc001enk.2","chr1",145413190,145417545],[["uc001enl.2"],"knownGene","uc001enl.2","chr1",145413190,145417545],[["uc001enn.3"],"knownGene","uc001enn.3","chr1",145438461,145442626],[["uc001enm.1"],"knownGene","uc001enm.1","chr1",145438510,145442592],[["uc010oys.1"],"knownGene","uc010oys.1","chr1",145439346,145442626],[["uc001enp.1"],"knownGene","uc001enp.1","chr1",145456235,145470387],[["uc001enq.1"],"knownGene","uc001enq.1","chr1",145470507,145475647],[["uc001enr.2"],"knownGene","uc001enr.2","chr1",145477084,145499090],[["uc009wiu.1"],"knownGene","uc009wiu.1","chr1",145499072,145501636],[["uc001ent.1"],"knownGene","uc001ent.1","chr1",145507637,145511444],[["uc001enu.1"],"knownGene","uc001enu.1","chr1",145507637,145511444],[["uc009wiv.1"],"knownGene","uc009wiv.1","chr1",145509752,145515899],[["uc010oyt.1"],"knownGene","uc010oyt.1","chr1",145509819,145516076],[["uc001enw.1"],"knownGene","uc001enw.1","chr1",145510431,145512878],[["uc001enx.2"],"knownGene","uc001enx.2","chr1",145514195,145515899],[["uc001eny.1"],"knownGene","uc001eny.1","chr1",145516382,145523731],[["uc010oyu.1"],"knownGene","uc010oyu.1","chr1",145516599,145523731],[["uc001eoa.2"],"knownGene","uc001eoa.2","chr1",145524989,145543867],[["uc010oyv.1"],"knownGene","uc010oyv.1","chr1",145524989,145543867],[["uc009wiw.2"],"knownGene","uc009wiw.2","chr1",145524989,145543867],[["uc001enz.1"],"knownGene","uc001enz.1","chr1",145524989,145529319],[["uc010oyw.1"],"knownGene","uc010oyw.1","chr1",145527927,145543867],[["uc001eob.1"],"knownGene","uc001eob.1","chr1",145549208,145568526],[["uc010oyx.1"],"knownGene","uc010oyx.1","chr1",145549208,145563099],[["uc010oyy.1"],"knownGene","uc010oyy.1","chr1",145575289,145580662],[["uc001eoc.1"],"knownGene","uc001eoc.1","chr1",145575987,145586546],[["uc001eod.1"],"knownGene","uc001eod.1","chr1",145580403,145586546],[["uc001eoe.2"],"knownGene","uc001eoe.2","chr1",145586493,145589435],[["uc001eof.1"],"knownGene","uc001eof.1","chr1",145588587,145590461],[["uc001eoh.2"],"knownGene","uc001eoh.2","chr1",145592605,145610884],[["uc001eoi.2"],"knownGene","uc001eoi.2","chr1",145592605,145610884],[["uc009wix.2"],"knownGene","uc009wix.2","chr1",145592605,145610884],[["uc001eog.2"],"knownGene","uc001eog.2","chr1",145592605,145610627],[["uc001eoj.2"],"knownGene","uc001eoj.2","chr1",145611035,145688774],[["uc001eok.2"],"knownGene","uc001eok.2","chr1",145611035,145688774],[["uc009wiy.2"],"knownGene","uc009wiy.2","chr1",145611035,145688774],[["uc001eol.1"],"knownGene","uc001eol.1","chr1",145695797,145715565],[["uc001eom.1"],"knownGene","uc001eom.1","chr1",145695932,145715565],[["uc010oyz.1"],"knownGene","uc010oyz.1","chr1",145698952,145706827],[["uc001eon.1"],"knownGene","uc001eon.1","chr1",145727725,145764073],[["uc001eoo.1"],"knownGene","uc001eoo.1","chr1",145727725,145764073],[["uc010oza.1"],"knownGene","uc010oza.1","chr1",145727725,145764073],[["uc001eos.2"],"knownGene","uc001eos.2","chr1",145764594,145827103],[["uc001eot.2"],"knownGene","uc001eot.2","chr1",145764594,145827103],[["uc010ozc.1"],"knownGene","uc010ozc.1","chr1",145764594,145827103],[["uc010ozd.1"],"knownGene","uc010ozd.1","chr1",145764594,145827103],[["uc010ozb.1"],"knownGene","uc010ozb.1","chr1",145764594,145826450],[["uc001eor.2"],"knownGene","uc001eor.2","chr1",145764594,145812027],[["uc001eoq.2"],"knownGene","uc001eoq.2","chr1",145764594,145790953],[["uc001eop.2"],"knownGene","uc001eop.2","chr1",145764594,145788795],[["uc010oze.1"],"knownGene","uc010oze.1","chr1",145765142,145827103],[["uc001eou.3"],"knownGene","uc001eou.3","chr1",145883867,145924048],[["uc009wiz.2"],"knownGene","uc009wiz.2","chr1",145897301,145924048],[["uc001eov.1"],"knownGene","uc001eov.1","chr1",145924387,145942619],[["uc010ozf.1"],"knownGene","uc010ozf.1","chr1",145924387,145932040],[["uc010ozh.1"],"knownGene","uc010ozh.1","chr1",146032542,146082765],[["uc001epa.2"],"knownGene","uc001epa.2","chr1",146032542,146082765],[["uc001eoz.2"],"knownGene","uc001eoz.2","chr1",146032542,146082431],[["uc001eoy.2"],"knownGene","uc001eoy.2","chr1",146032542,146068252],[["uc010ozg.1"],"knownGene","uc010ozg.1","chr1",146032542,146057734],[["uc009wjc.2"],"knownGene","uc009wjc.2","chr1",146032542,146057734],[["uc001eox.2"],"knownGene","uc001eox.2","chr1",146032542,146057622],[["uc010ozi.1"],"knownGene","uc010ozi.1","chr1",146215990,146221509],[["uc010ozj.1"],"knownGene","uc010ozj.1","chr1",146231025,146240540],[["uc010ozk.1"],"knownGene","uc010ozk.1","chr1",146334189,146460430],[["uc010ozl.1"],"knownGene","uc010ozl.1","chr1",146404588,146467638],[["uc001epd.2"],"knownGene","uc001epd.2","chr1",146490894,146514599],[["uc001epe.2"],"knownGene","uc001epe.2","chr1",146626686,146644129],[["uc010ozm.1"],"knownGene","uc010ozm.1","chr1",146626686,146644129],[["uc010ozn.1"],"knownGene","uc010ozn.1","chr1",146626686,146644129],[["uc009wjf.1"],"knownGene","uc009wjf.1","chr1",146633092,146644129],[["uc001epf.1"],"knownGene","uc001epf.1","chr1",146644349,146646784],[["uc001epg.1"],"knownGene","uc001epg.1","chr1",146649429,146651528],[["uc001eph.3"],"knownGene","uc001eph.3","chr1",146655884,146697230],[["uc001epi.2"],"knownGene","uc001epi.2","chr1",146657837,146697230],[["uc001epj.2"],"knownGene","uc001epj.2","chr1",146657837,146697230],[["uc001epk.3"],"knownGene","uc001epk.3","chr1",146680025,146697230],[["uc001epm.3"],"knownGene","uc001epm.3","chr1",146714290,146767441],[["uc001epn.3"],"knownGene","uc001epn.3","chr1",146714290,146767441],[["uc010ozo.1"],"knownGene","uc010ozo.1","chr1",146714290,146767441],[["uc009wjg.2"],"knownGene","uc009wjg.2","chr1",146714290,146767441],[["uc009wjh.2"],"knownGene","uc009wjh.2","chr1",146714290,146767441],[["uc010ozp.1"],"knownGene","uc010ozp.1","chr1",146714290,146767441],[["uc001epo.3"],"knownGene","uc001epo.3","chr1",146714290,146767441],[["uc001epp.2"],"knownGene","uc001epp.2","chr1",146730539,146989699],[["uc009wji.2"],"knownGene","uc009wji.2","chr1",146736038,146767441],[["uc010ozq.1"],"knownGene","uc010ozq.1","chr1",146736038,146757164],[["uc001epq.2"],"knownGene","uc001epq.2","chr1",147013181,147098013],[["uc010ozr.1"],"knownGene","uc010ozr.1","chr1",147083376,147096757],[["uc001epr.2"],"knownGene","uc001epr.2","chr1",147119167,147142634],[["uc009wjj.1"],"knownGene","uc009wjj.1","chr1",147121945,147142634],[["uc001ept.1"],"knownGene","uc001ept.1","chr1",147228331,147245484],[["uc001eps.1"],"knownGene","uc001eps.1","chr1",147228331,147232714],[["uc001epu.1"],"knownGene","uc001epu.1","chr1",147374935,147381393],[["uc001epv.3"],"knownGene","uc001epv.3","chr1",147400505,147465754],[["uc010ozt.1"],"knownGene","uc010ozt.1","chr1",147400505,147465754],[["uc010ozu.1"],"knownGene","uc010ozu.1","chr1",147400505,147465754],[["uc001epw.3"],"knownGene","uc001epw.3","chr1",147400505,147465754],[["uc010ozs.1"],"knownGene","uc010ozs.1","chr1",147400505,147465025],[["uc010ozv.1"],"knownGene","uc010ozv.1","chr1",147401128,147465754],[["uc001epx.3"],"knownGene","uc001epx.3","chr1",147415526,147465754],[["uc009wjm.2"],"knownGene","uc009wjm.2","chr1",147425566,147465754],[["uc001epy.3"],"knownGene","uc001epy.3","chr1",147440589,147465754],[["uc001epz.1"],"knownGene","uc001epz.1","chr1",147466093,147484331],[["uc010ozw.1"],"knownGene","uc010ozw.1","chr1",147466093,147473747],[["uc001eqg.2"],"knownGene","uc001eqg.2","chr1",147574323,148346929],[["uc001eqe.2"],"knownGene","uc001eqe.2","chr1",147574323,148346791],[["uc001eqf.2"],"knownGene","uc001eqf.2","chr1",147574323,148346791],[["uc010ozz.1"],"knownGene","uc010ozz.1","chr1",147574323,148005511],[["uc010ozy.1"],"knownGene","uc010ozy.1","chr1",147574323,147624601],[["uc001eqd.2"],"knownGene","uc001eqd.2","chr1",147574323,147624601],[["uc001eqc.2"],"knownGene","uc001eqc.2","chr1",147574323,147624267],[["uc001eqb.2"],"knownGene","uc001eqb.2","chr1",147574323,147610088],[["uc010ozx.1"],"knownGene","uc010ozx.1","chr1",147574323,147599571],[["uc009wjr.2"],"knownGene","uc009wjr.2","chr1",147574323,147599571],[["uc001eqa.2"],"knownGene","uc001eqa.2","chr1",147574323,147599459],[["uc001eqh.1"],"knownGene","uc001eqh.1","chr1",147680370,147691166],[["uc001eqi.1"],"knownGene","uc001eqi.1","chr1",147751385,147763966],[["uc001eqj.1"],"knownGene","uc001eqj.1","chr1",147751388,147760170],[["uc001eqk.1"],"knownGene","uc001eqk.1","chr1",147801123,147816764],[["uc001eql.2"],"knownGene","uc001eql.2","chr1",147835126,147931980],[["uc010paa.1"],"knownGene","uc010paa.1","chr1",147874654,147893482],[["uc001eqn.2"],"knownGene","uc001eqn.2","chr1",147905097,147931904],[["uc009wjx.1"],"knownGene","uc009wjx.1","chr1",147906021,147931980],[["uc009wjy.1"],"knownGene","uc009wjy.1","chr1",147906747,147931980],[["uc009wjz.1"],"knownGene","uc009wjz.1","chr1",147907097,147931980],[["uc009wka.1"],"knownGene","uc009wka.1","chr1",147925824,147930669],[["uc001eqo.1"],"knownGene","uc001eqo.1","chr1",147930760,148176401],[["uc001eqp.2"],"knownGene","uc001eqp.2","chr1",147954636,147955419],[["uc010pac.1"],"knownGene","uc010pac.1","chr1",148003642,148319619],[["uc010pab.1"],"knownGene","uc010pab.1","chr1",148003642,148257602],[["uc001eqq.2"],"knownGene","uc001eqq.2","chr1",148003642,148025863],[["uc001eqx.2"],"knownGene","uc001eqx.2","chr1",148005402,148269609],[["uc001eqs.1"],"knownGene","uc001eqs.1","chr1",148005402,148023669],[["uc010pad.1"],"knownGene","uc010pad.1","chr1",148005402,148011788],[["uc010paf.1"],"knownGene","uc010paf.1","chr1",148011679,148303022],[["uc010pae.1"],"knownGene","uc010pae.1","chr1",148011679,148271900],[["uc009wkf.1"],"knownGene","uc009wkf.1","chr1",148017501,148346791],[["uc010pag.1"],"knownGene","uc010pag.1","chr1",148201753,148202536],[["uc001erd.3"],"knownGene","uc001erd.3","chr1",148251112,148346929],[["uc001erc.3"],"knownGene","uc001erc.3","chr1",148251112,148346929],[["uc010paj.1"],"knownGene","uc010paj.1","chr1",148251112,148346929],[["uc001erb.2"],"knownGene","uc001erb.2","chr1",148251112,148337532],[["uc001eqz.2"],"knownGene","uc001eqz.2","chr1",148251112,148288722],[["uc010pah.1"],"knownGene","uc010pah.1","chr1",148251112,148267126],[["uc010pai.1"],"knownGene","uc010pai.1","chr1",148251112,148267126],[["uc010pal.1"],"knownGene","uc010pal.1","chr1",148252729,148301438],[["uc001erg.1"],"knownGene","uc001erg.1","chr1",148252729,148280742],[["uc010pak.1"],"knownGene","uc010pak.1","chr1",148252729,148276664],[["uc001erf.1"],"knownGene","uc001erf.1","chr1",148252729,148274381],[["uc010pam.1"],"knownGene","uc010pam.1","chr1",148257493,148325254],[["uc001erh.2"],"knownGene","uc001erh.2","chr1",148257493,148279343],[["uc001eri.1"],"knownGene","uc001eri.1","chr1",148257493,148267126],[["uc001erm.1"],"knownGene","uc001erm.1","chr1",148267017,148324367],[["uc001erl.1"],"knownGene","uc001erl.1","chr1",148267017,148317326],[["uc010pan.1"],"knownGene","uc010pan.1","chr1",148267017,148271900],[["uc001erz.2"],"knownGene","uc001erz.2","chr1",148271791,148326848],[["uc010pao.1"],"knownGene","uc010pao.1","chr1",148276555,148314847],[["uc010pap.1"],"knownGene","uc010pap.1","chr1",148279746,148295781],[["uc001erq.1"],"knownGene","uc001erq.1","chr1",148279746,148282340],[["uc010pau.1"],"knownGene","uc010pau.1","chr1",148282939,148342006],[["uc010pat.1"],"knownGene","uc010pat.1","chr1",148282939,148335752],[["uc010pas.1"],"knownGene","uc010pas.1","chr1",148282939,148322078],[["uc010par.1"],"knownGene","uc010par.1","chr1",148282939,148319619],[["uc010paq.1"],"knownGene","uc010paq.1","chr1",148282939,148310071],[["uc001eru.1"],"knownGene","uc001eru.1","chr1",148282939,148285533],[["uc010pav.1"],"knownGene","uc010pav.1","chr1",148305264,148347506],[["uc010paw.1"],"knownGene","uc010paw.1","chr1",148305264,148347506],[["uc001esa.1"],"knownGene","uc001esa.1","chr1",148314738,148336277],[["uc010pax.1"],"knownGene","uc010pax.1","chr1",148327470,148338469],[["uc010pay.1"],"knownGene","uc010pay.1","chr1",148556107,148556132],[["uc001esb.1"],"knownGene","uc001esb.1","chr1",148558268,148593783],[["uc001esc.2"],"knownGene","uc001esc.2","chr1",148560846,148596267],[["uc001esd.2"],"knownGene","uc001esd.2","chr1",148574411,148575140],[["uc010paz.1"],"knownGene","uc010paz.1","chr1",148644010,148644793],[["uc001ese.2"],"knownGene","uc001ese.2","chr1",148736447,148737176],[["uc010pba.1"],"knownGene","uc010pba.1","chr1",148739441,148758311],[["uc009wkt.1"],"knownGene","uc009wkt.1","chr1",148739561,148758311],[["uc010pbb.1"],"knownGene","uc010pbb.1","chr1",148806014,148806797],[["uc009wkv.1"],"knownGene","uc009wkv.1","chr1",148876039,148902123],[["uc010pbc.1"],"knownGene","uc010pbc.1","chr1",148928285,148951595],[["uc010pbd.1"],"knownGene","uc010pbd.1","chr1",148928285,148951595],[["uc009wkw.1"],"knownGene","uc009wkw.1","chr1",148930404,148953054],[["uc010pbe.1"],"knownGene","uc010pbe.1","chr1",149230715,149232553],[["uc010pbf.1"],"knownGene","uc010pbf.1","chr1",149279475,149291742],[["uc001esg.3"],"knownGene","uc001esg.3","chr1",149287450,149291742],[["uc010pbh.1"],"knownGene","uc010pbh.1","chr1",149369293,149378295],[["uc010pbg.1"],"knownGene","uc010pbg.1","chr1",149369293,149370314],[["uc009wkz.1"],"knownGene","uc009wkz.1","chr1",149370546,149375252],[["uc010pbi.1"],"knownGene","uc010pbi.1","chr1",149397113,149399229],[["uc001esj.2"],"knownGene","uc001esj.2","chr1",149553002,149553785],[["uc009wlb.1"],"knownGene","uc009wlb.1","chr1",149576160,149576700],[["uc009wlc.2"],"knownGene","uc009wlc.2","chr1",149576452,149672983],[["uc009wld.2"],"knownGene","uc009wld.2","chr1",149576452,149672983],[["uc001esk.3"],"knownGene","uc001esk.3","chr1",149576452,149616784],[["uc001esl.3"],"knownGene","uc001esl.3","chr1",149576452,149616784],[["uc009wle.1"],"knownGene","uc009wle.1","chr1",149577754,149582602],[["uc001eso.1"],"knownGene","uc001eso.1","chr1",149627308,149651107],[["uc001esn.1"],"knownGene","uc001esn.1","chr1",149627308,149641425],[["uc010pbj.1"],"knownGene","uc010pbj.1","chr1",149754245,149783928],[["uc001esp.3"],"knownGene","uc001esp.3","chr1",149754249,149764073],[["uc009wlg.2"],"knownGene","uc009wlg.2","chr1",149754256,149764073],[["uc009wlh.1"],"knownGene","uc009wlh.1","chr1",149755502,149760173],[["uc001esq.1"],"knownGene","uc001esq.1","chr1",149763335,149765367],[["uc010pbk.1"],"knownGene","uc010pbk.1","chr1",149765021,149783928],[["uc001esr.2"],"knownGene","uc001esr.2","chr1",149782118,149783928],[["uc010pbl.1"],"knownGene","uc010pbl.1","chr1",149784827,149785236],[["uc001ess.2"],"knownGene","uc001ess.2","chr1",149804220,149804615],[["uc001est.1"],"knownGene","uc001est.1","chr1",149804231,149806194],[["uc001esu.1"],"knownGene","uc001esu.1","chr1",149804241,149806194],[["uc001esv.2"],"knownGene","uc001esv.2","chr1",149812259,149812765],[["uc001esw.2"],"knownGene","uc001esw.2","chr1",149813785,149814318],[["uc001esx.2"],"knownGene","uc001esx.2","chr1",149822627,149823160],[["uc001esy.2"],"knownGene","uc001esy.2","chr1",149824180,149824686],[["uc001eta.1"],"knownGene","uc001eta.1","chr1",149830751,149832714],[["uc001esz.1"],"knownGene","uc001esz.1","chr1",149830751,149832704],[["uc001etb.2"],"knownGene","uc001etb.2","chr1",149832330,149832725],[["uc001etc.2"],"knownGene","uc001etc.2","chr1",149856011,149858232],[["uc001etd.2"],"knownGene","uc001etd.2","chr1",149858524,149858960],[["uc001ete.2"],"knownGene","uc001ete.2","chr1",149859019,149859466],[["uc001etf.2"],"knownGene","uc001etf.2","chr1",149871154,149872347],[["uc001etg.2"],"knownGene","uc001etg.2","chr1",149874875,149889434],[["uc009wlk.2"],"knownGene","uc009wlk.2","chr1",149874875,149878523],[["uc001eth.2"],"knownGene","uc001eth.2","chr1",149877023,149889434],[["uc001etk.1"],"knownGene","uc001etk.1","chr1",149895210,149900236],[["uc001etj.1"],"knownGene","uc001etj.1","chr1",149895210,149899962],[["uc001eti.1"],"knownGene","uc001eti.1","chr1",149895210,149897945],[["uc009wll.1"],"knownGene","uc009wll.1","chr1",149897437,149899962],[["uc001etl.3"],"knownGene","uc001etl.3","chr1",149900543,149908791],[["uc001etm.1"],"knownGene","uc001etm.1","chr1",149900543,149908266],[["uc010pbm.1"],"knownGene","uc010pbm.1","chr1",149902256,149908278],[["uc010pbn.1"],"knownGene","uc010pbn.1","chr1",149902683,149907028],[["uc010pbo.1"],"knownGene","uc010pbo.1","chr1",149907191,149908791],[["uc001etn.2"],"knownGene","uc001etn.2","chr1",149912232,149982686],[["uc001eto.2"],"knownGene","uc001eto.2","chr1",149932868,149943179],[["uc001etp.2"],"knownGene","uc001etp.2","chr1",150039341,150117504],[["uc010pbq.1"],"knownGene","uc010pbq.1","chr1",150039341,150117504],[["uc010pbp.1"],"knownGene","uc010pbp.1","chr1",150039341,150082742],[["uc009wlm.1"],"knownGene","uc009wlm.1","chr1",150039341,150065744],[["uc010pbs.1"],"knownGene","uc010pbs.1","chr1",150039399,150117504],[["uc010pbr.1"],"knownGene","uc010pbr.1","chr1",150039399,150054079],[["uc001etq.2"],"knownGene","uc001etq.2","chr1",150049266,150117504],[["uc001etr.2"],"knownGene","uc001etr.2","chr1",150121654,150131816],[["uc001ets.2"],"knownGene","uc001ets.2","chr1",150121654,150131816],[["uc001ett.2"],"knownGene","uc001ett.2","chr1",150122169,150131816],[["uc001etu.2"],"knownGene","uc001etu.2","chr1",150127086,150131816],[["uc001etw.2"],"knownGene","uc001etw.2","chr1",150190717,150208504],[["uc010pbv.1"],"knownGene","uc010pbv.1","chr1",150190717,150208504],[["uc010pbu.1"],"knownGene","uc010pbu.1","chr1",150190717,150207026],[["uc010pbt.1"],"knownGene","uc010pbt.1","chr1",150190717,150199127],[["uc001etv.3"],"knownGene","uc001etv.3","chr1",150190724,150208504],[["uc010pbw.1"],"knownGene","uc010pbw.1","chr1",150198939,150208504],[["uc001etx.2"],"knownGene","uc001etx.2","chr1",150230217,150237476],[["uc009wln.2"],"knownGene","uc009wln.2","chr1",150230217,150233729],[["uc001ety.1"],"knownGene","uc001ety.1","chr1",150237798,150241532],[["uc010pbx.1"],"knownGene","uc010pbx.1","chr1",150237798,150241532],[["uc001etz.1"],"knownGene","uc001etz.1","chr1",150237798,150241532],[["uc001eua.1"],"knownGene","uc001eua.1","chr1",150237798,150241532],[["uc010pby.1"],"knownGene","uc010pby.1","chr1",150237798,150241532],[["uc001eub.1"],"knownGene","uc001eub.1","chr1",150237798,150241532],[["uc010pbz.1"],"knownGene","uc010pbz.1","chr1",150237798,150241532],[["uc001euc.2"],"knownGene","uc001euc.2","chr1",150244772,150253325],[["uc001eud.2"],"knownGene","uc001eud.2","chr1",150245182,150253325],[["uc001eue.2"],"knownGene","uc001eue.2","chr1",150245182,150253325],[["uc001euf.2"],"knownGene","uc001euf.2","chr1",150245201,150253325],[["uc001eug.2"],"knownGene","uc001eug.2","chr1",150245201,150253325],[["uc001euh.2"],"knownGene","uc001euh.2","chr1",150254952,150259502],[["uc001eui.2"],"knownGene","uc001eui.2","chr1",150254952,150259502],[["uc001euj.2"],"knownGene","uc001euj.2","chr1",150255228,150259502],[["uc001euk.2"],"knownGene","uc001euk.2","chr1",150266268,150280818],[["uc001eul.2"],"knownGene","uc001eul.2","chr1",150266268,150280818],[["uc001eum.3"],"knownGene","uc001eum.3","chr1",150293927,150325703],[["uc010pca.1"],"knownGene","uc010pca.1","chr1",150293927,150325703],[["uc010pcb.1"],"knownGene","uc010pcb.1","chr1",150293927,150325703],[["uc009wlp.2"],"knownGene","uc009wlp.2","chr1",150293927,150318612],[["uc009wlo.2"],"knownGene","uc009wlo.2","chr1",150293927,150301343],[["uc009wlq.1"],"knownGene","uc009wlq.1","chr1",150305449,150318612],[["uc009wlr.2"],"knownGene","uc009wlr.2","chr1",150336989,150449039],[["uc001eup.3"],"knownGene","uc001eup.3","chr1",150336989,150449039],[["uc010pcc.1"],"knownGene","uc010pcc.1","chr1",150336989,150446032],[["uc001euq.2"],"knownGene","uc001euq.2","chr1",150459919,150479747],[["uc001eur.2"],"knownGene","uc001eur.2","chr1",150459919,150479747],[["uc009wlt.2"],"knownGene","uc009wlt.2","chr1",150459919,150479747],[["uc009wls.2"],"knownGene","uc009wls.2","chr1",150459919,150479747],[["uc010pcd.1"],"knownGene","uc010pcd.1","chr1",150459919,150471769],[["uc001eus.2"],"knownGene","uc001eus.2","chr1",150480486,150486264],[["uc001eut.2"],"knownGene","uc001eut.2","chr1",150480486,150486264],[["uc001euu.2"],"knownGene","uc001euu.2","chr1",150480486,150486264],[["uc001euv.2"],"knownGene","uc001euv.2","chr1",150480486,150486264],[["uc009wlu.2"],"knownGene","uc009wlu.2","chr1",150480486,150486264],[["uc010pce.1"],"knownGene","uc010pce.1","chr1",150480486,150484218],[["uc010pcf.1"],"knownGene","uc010pcf.1","chr1",150480486,150484218],[["uc001eux.2"],"knownGene","uc001eux.2","chr1",150521897,150533410],[["uc001euw.2"],"knownGene","uc001euw.2","chr1",150521897,150531221],[["uc009wlv.1"],"knownGene","uc009wlv.1","chr1",150521897,150524367],[["uc009wlw.2"],"knownGene","uc009wlw.2","chr1",150522297,150533410],[["uc010pcg.1"],"knownGene","uc010pcg.1","chr1",150522297,150533410],[["uc009wlx.2"],"knownGene","uc009wlx.2","chr1",150530420,150533410],[["uc001euz.2"],"knownGene","uc001euz.2","chr1",150547036,150552136],[["uc001eva.2"],"knownGene","uc001eva.2","chr1",150547036,150552136],[["uc010pch.1"],"knownGene","uc010pch.1","chr1",150547036,150552086],[["uc001evd.2"],"knownGene","uc001evd.2","chr1",150594603,150602098],[["uc001eve.2"],"knownGene","uc001eve.2","chr1",150594603,150602098],[["uc001evb.2"],"knownGene","uc001evb.2","chr1",150594603,150601609],[["uc001evc.2"],"knownGene","uc001evc.2","chr1",150594603,150601609],[["uc009wly.2"],"knownGene","uc009wly.2","chr1",150595754,150602098],[["uc001evg.2"],"knownGene","uc001evg.2","chr1",150595754,150602098],[["uc001evh.2"],"knownGene","uc001evh.2","chr1",150595754,150602098],[["uc001evf.2"],"knownGene","uc001evf.2","chr1",150595754,150601609],[["uc009wlz.1"],"knownGene","uc009wlz.1","chr1",150598117,150602098],[["uc001evi.2"],"knownGene","uc001evi.2","chr1",150599523,150602098],[["uc001evj.2"],"knownGene","uc001evj.2","chr1",150618700,150669672],[["uc010pci.1"],"knownGene","uc010pci.1","chr1",150618700,150669672],[["uc001evk.1"],"knownGene","uc001evk.1","chr1",150670541,150693352],[["uc001evl.1"],"knownGene","uc001evl.1","chr1",150670541,150693352],[["uc001evm.1"],"knownGene","uc001evm.1","chr1",150670541,150693352],[["uc001evn.2"],"knownGene","uc001evn.2","chr1",150702553,150738305],[["uc010pcj.1"],"knownGene","uc010pcj.1","chr1",150702553,150738305],[["uc001evo.1"],"knownGene","uc001evo.1","chr1",150722344,150738305],[["uc001evp.1"],"knownGene","uc001evp.1","chr1",150768686,150780812],[["uc001evq.1"],"knownGene","uc001evq.1","chr1",150768686,150780812],[["uc009wma.1"],"knownGene","uc009wma.1","chr1",150778336,150780812],[["uc001evr.1"],"knownGene","uc001evr.1","chr1",150782185,150849186],[["uc001evs.1"],"knownGene","uc001evs.1","chr1",150782185,150849186],[["uc001evt.1"],"knownGene","uc001evt.1","chr1",150782185,150849186],[["uc009wmb.1"],"knownGene","uc009wmb.1","chr1",150782185,150849186],[["uc009wmc.1"],"knownGene","uc009wmc.1","chr1",150782185,150849186],[["uc009wmd.1"],"knownGene","uc009wmd.1","chr1",150782185,150849186],[["uc010pck.1"],"knownGene","uc010pck.1","chr1",150782185,150789924],[["uc009wme.1"],"knownGene","uc009wme.1","chr1",150790395,150849186],[["uc010pcl.1"],"knownGene","uc010pcl.1","chr1",150795669,150849186],[["uc001evv.2"],"knownGene","uc001evv.2","chr1",150898814,150937220],[["uc001evu.2"],"knownGene","uc001evu.2","chr1",150898814,150937220],[["uc009wmf.2"],"knownGene","uc009wmf.2","chr1",150898814,150923566],[["uc001evw.3"],"knownGene","uc001evw.3","chr1",150898824,150917794],[["uc009wmg.1"],"knownGene","uc009wmg.1","chr1",150898956,150936321],[["uc001evy.2"],"knownGene","uc001evy.2","chr1",150937649,150947440],[["uc001evz.2"],"knownGene","uc001evz.2","chr1",150937649,150947440],[["uc009wmh.2"],"knownGene","uc009wmh.2","chr1",150937649,150947440],[["uc001ewa.2"],"knownGene","uc001ewa.2","chr1",150954498,150968114],[["uc010pcn.1"],"knownGene","uc010pcn.1","chr1",150969301,150980854],[["uc001ewg.2"],"knownGene","uc001ewg.2","chr1",150969301,150980854],[["uc001ewf.2"],"knownGene","uc001ewf.2","chr1",150969301,150980225],[["uc001ewd.2"],"knownGene","uc001ewd.2","chr1",150969301,150980095],[["uc001ewe.2"],"knownGene","uc001ewe.2","chr1",150969301,150980095],[["uc001ewc.2"],"knownGene","uc001ewc.2","chr1",150969301,150979273],[["uc010pcm.1"],"knownGene","uc010pcm.1","chr1",150969301,150979273],[["uc001ewh.1"],"knownGene","uc001ewh.1","chr1",150980972,151008189],[["uc001ewi.1"],"knownGene","uc001ewi.1","chr1",150980972,151008189],[["uc010pco.1"],"knownGene","uc010pco.1","chr1",150980972,151008189],[["uc001ewj.1"],"knownGene","uc001ewj.1","chr1",150980972,151008189],[["uc001ewk.1"],"knownGene","uc001ewk.1","chr1",150997086,151008189],[["uc009wmi.2"],"knownGene","uc009wmi.2","chr1",151009028,151020076],[["uc001ewl.2"],"knownGene","uc001ewl.2","chr1",151009028,151020076],[["uc009wmj.2"],"knownGene","uc009wmj.2","chr1",151011271,151020076],[["uc001ewn.2"],"knownGene","uc001ewn.2","chr1",151020258,151023869],[["uc001ewo.2"],"knownGene","uc001ewo.2","chr1",151023448,151032125],[["uc001ewp.2"],"knownGene","uc001ewp.2","chr1",151023448,151032125],[["uc001ewq.2"],"knownGene","uc001ewq.2","chr1",151032150,151040972],[["uc001ewr.2"],"knownGene","uc001ewr.2","chr1",151043079,151091007],[["uc001ews.2"],"knownGene","uc001ews.2","chr1",151043079,151091007],[["uc010pcp.1"],"knownGene","uc010pcp.1","chr1",151043079,151076151],[["uc001ewt.2"],"knownGene","uc001ewt.2","chr1",151065667,151091007],[["uc001ewu.2"],"knownGene","uc001ewu.2","chr1",151104164,151119104],[["uc001ewv.2"],"knownGene","uc001ewv.2","chr1",151104164,151119104],[["uc001eww.2"],"knownGene","uc001eww.2","chr1",151104164,151119104],[["uc010pcq.1"],"knownGene","uc010pcq.1","chr1",151104446,151119104],[["uc009wml.1"],"knownGene","uc009wml.1","chr1",151109332,151119104],[["uc001ewx.2"],"knownGene","uc001ewx.2","chr1",151129104,151132225],[["uc010pcr.1"],"knownGene","uc010pcr.1","chr1",151132224,151138424],[["uc001ewy.2"],"knownGene","uc001ewy.2","chr1",151132224,151138370],[["uc001ewz.2"],"knownGene","uc001ewz.2","chr1",151138516,151141612],[["uc009wmn.2"],"knownGene","uc009wmn.2","chr1",151138516,151141612],[["uc010pcs.1"],"knownGene","uc010pcs.1","chr1",151138516,151140384],[["uc001exc.3"],"knownGene","uc001exc.3","chr1",151142463,151148547],[["uc010pct.1"],"knownGene","uc010pct.1","chr1",151142463,151148547],[["uc001exd.2"],"knownGene","uc001exd.2","chr1",151142463,151148457],[["uc001exb.2"],"knownGene","uc001exb.2","chr1",151142463,151144833],[["uc001exe.1"],"knownGene","uc001exe.1","chr1",151148933,151162640],[["uc001exf.1"],"knownGene","uc001exf.1","chr1",151149827,151162640],[["uc001exj.2"],"knownGene","uc001exj.2","chr1",151171020,151222006],[["uc001exi.2"],"knownGene","uc001exi.2","chr1",151171020,151222006],[["uc010pcu.1"],"knownGene","uc010pcu.1","chr1",151171020,151222006],[["uc001exk.2"],"knownGene","uc001exk.2","chr1",151171020,151222006],[["uc010pcv.1"],"knownGene","uc010pcv.1","chr1",151206672,151222006],[["uc001exl.2"],"knownGene","uc001exl.2","chr1",151227196,151239952],[["uc001exn.2"],"knownGene","uc001exn.2","chr1",151227196,151239952],[["uc001exo.2"],"knownGene","uc001exo.2","chr1",151252502,151254405],[["uc001exp.1"],"knownGene","uc001exp.1","chr1",151254093,151260882],[["uc001exq.2"],"knownGene","uc001exq.2","chr1",151254790,151264380],[["uc009wmo.2"],"knownGene","uc009wmo.2","chr1",151254790,151264380],[["uc009wmp.2"],"knownGene","uc009wmp.2","chr1",151258750,151264380],[["uc001ext.2"],"knownGene","uc001ext.2","chr1",151264412,151300133],[["uc001exu.2"],"knownGene","uc001exu.2","chr1",151264412,151300133],[["uc010pcw.1"],"knownGene","uc010pcw.1","chr1",151264412,151300133],[["uc001exr.2"],"knownGene","uc001exr.2","chr1",151264412,151298849],[["uc001exs.2"],"knownGene","uc001exs.2","chr1",151264412,151298849],[["uc009wmq.1"],"knownGene","uc009wmq.1","chr1",151288048,151300133],[["uc001exv.1"],"knownGene","uc001exv.1","chr1",151313115,151319769],[["uc001exw.1"],"knownGene","uc001exw.1","chr1",151313115,151319769],[["uc009wmr.1"],"knownGene","uc009wmr.1","chr1",151313115,151319769],[["uc010pcx.1"],"knownGene","uc010pcx.1","chr1",151313115,151319769],[["uc001exx.2"],"knownGene","uc001exx.2","chr1",151336780,151345164],[["uc010pcy.1"],"knownGene","uc010pcy.1","chr1",151336780,151345164],[["uc001exy.2"],"knownGene","uc001exy.2","chr1",151336780,151345164],[["uc001exz.2"],"knownGene","uc001exz.2","chr1",151336780,151345164],[["uc010pcz.1"],"knownGene","uc010pcz.1","chr1",151336780,151345164],[["uc009wms.2"],"knownGene","uc009wms.2","chr1",151336780,151345164],[["uc009wmt.2"],"knownGene","uc009wmt.2","chr1",151336780,151345164],[["uc001eya.2"],"knownGene","uc001eya.2","chr1",151336780,151345164],[["uc009wmu.2"],"knownGene","uc009wmu.2","chr1",151336780,151345164],[["uc001eyc.1"],"knownGene","uc001eyc.1","chr1",151372040,151374412],[["uc001eyb.1"],"knownGene","uc001eyb.1","chr1",151372040,151374382],[["uc010pda.1"],"knownGene","uc010pda.1","chr1",151372040,151373831],[["uc001eyd.1"],"knownGene","uc001eyd.1","chr1",151375199,151431932],[["uc001eye.1"],"knownGene","uc001eye.1","chr1",151375199,151431932],[["uc010pdb.1"],"knownGene","uc010pdb.1","chr1",151375199,151431932],[["uc001eyf.1"],"knownGene","uc001eyf.1","chr1",151375199,151431932],[["uc010pdc.1"],"knownGene","uc010pdc.1","chr1",151375199,151431932],[["uc009wmv.1"],"knownGene","uc009wmv.1","chr1",151375199,151431932],[["uc010pdd.1"],"knownGene","uc010pdd.1","chr1",151375199,151431932],[["uc001eyg.1"],"knownGene","uc001eyg.1","chr1",151399443,151431932],[["uc009wmw.2"],"knownGene","uc009wmw.2","chr1",151483861,151511165],[["uc010pde.1"],"knownGene","uc010pde.1","chr1",151506615,151511165],[["uc001eyl.2"],"knownGene","uc001eyl.2","chr1",151512780,151556058],[["uc001eym.2"],"knownGene","uc001eym.2","chr1",151512780,151556058],[["uc010pdf.1"],"knownGene","uc010pdf.1","chr1",151512780,151556058],[["uc010pdg.1"],"knownGene","uc010pdg.1","chr1",151512780,151556058],[["uc001eyn.1"],"knownGene","uc001eyn.1","chr1",151584661,151671559],[["uc001eyo.2"],"knownGene","uc001eyo.2","chr1",151611331,151671559],[["uc001eyp.2"],"knownGene","uc001eyp.2","chr1",151611363,151666975],[["uc001eyq.1"],"knownGene","uc001eyq.1","chr1",151670318,151670850],[["uc001eys.1"],"knownGene","uc001eys.1","chr1",151674829,151689290],[["uc009wmx.1"],"knownGene","uc009wmx.1","chr1",151674829,151689290],[["uc001eyr.2"],"knownGene","uc001eyr.2","chr1",151674829,151689059],[["uc009wmy.2"],"knownGene","uc009wmy.2","chr1",151674829,151689059],[["uc010pdh.1"],"knownGene","uc010pdh.1","chr1",151674829,151680411],[["uc001eyt.2"],"knownGene","uc001eyt.2","chr1",151679982,151689278],[["uc010pdi.1"],"knownGene","uc010pdi.1","chr1",151681473,151689278],[["uc001eyu.2"],"knownGene","uc001eyu.2","chr1",151682908,151702082],[["uc010pdj.1"],"knownGene","uc010pdj.1","chr1",151694012,151702082],[["uc001eyv.2"],"knownGene","uc001eyv.2","chr1",151732124,151736040],[["uc009wmz.2"],"knownGene","uc009wmz.2","chr1",151732124,151736040],[["uc010pdk.1"],"knownGene","uc010pdk.1","chr1",151734268,151736040],[["uc009wna.1"],"knownGene","uc009wna.1","chr1",151734705,151736040],[["uc010pdl.1"],"knownGene","uc010pdl.1","chr1",151735444,151743805],[["uc010pdm.1"],"knownGene","uc010pdm.1","chr1",151739130,151743805],[["uc001eyy.2"],"knownGene","uc001eyy.2","chr1",151742582,151763010],[["uc009wnb.1"],"knownGene","uc009wnb.1","chr1",151744040,151763010],[["uc001ezc.3"],"knownGene","uc001ezc.3","chr1",151745958,151763010],[["uc001eza.3"],"knownGene","uc001eza.3","chr1",151745958,151763010],[["uc001ezd.3"],"knownGene","uc001ezd.3","chr1",151745958,151763010],[["uc001ezb.3"],"knownGene","uc001ezb.3","chr1",151745958,151762964],[["uc010pdn.1"],"knownGene","uc010pdn.1","chr1",151746574,151763010],[["uc001eze.2"],"knownGene","uc001eze.2","chr1",151763317,151766877],[["uc001ezf.1"],"knownGene","uc001ezf.1","chr1",151772764,151777882],[["uc001ezh.2"],"knownGene","uc001ezh.2","chr1",151778547,151804348],[["uc010pdo.1"],"knownGene","uc010pdo.1","chr1",151778547,151804348],[["uc010pdp.1"],"knownGene","uc010pdp.1","chr1",151778547,151804348],[["uc001ezg.2"],"knownGene","uc001ezg.2","chr1",151778547,151798553],[["uc010pdq.1"],"knownGene","uc010pdq.1","chr1",151810338,151813033],[["uc010pdr.1"],"knownGene","uc010pdr.1","chr1",151810944,151816640],[["uc009wnd.2"],"knownGene","uc009wnd.2","chr1",151819577,151826173],[["uc001ezj.1"],"knownGene","uc001ezj.1","chr1",151846059,151882113],[["uc001ezk.1"],"knownGene","uc001ezk.1","chr1",151846059,151882113],[["uc001ezl.2"],"knownGene","uc001ezl.2","chr1",151955386,151966714],[["uc001ezm.1"],"knownGene","uc001ezm.1","chr1",151967006,152015250],[["uc001ezn.2"],"knownGene","uc001ezn.2","chr1",152004982,152009511],[["uc001ezo.1"],"knownGene","uc001ezo.1","chr1",152056619,152061540],[["uc009wne.1"],"knownGene","uc009wne.1","chr1",152078792,152117706],[["uc001ezp.2"],"knownGene","uc001ezp.2","chr1",152078792,152086587],[["uc001ezs.1"],"knownGene","uc001ezs.1","chr1",152126070,152131704],[["uc001ezt.1"],"knownGene","uc001ezt.1","chr1",152184557,152196669],[["uc001ezu.1"],"knownGene","uc001ezu.1","chr1",152274650,152297679],[["uc001ezv.2"],"knownGene","uc001ezv.2","chr1",152285934,152339166],[["uc001ezw.3"],"knownGene","uc001ezw.3","chr1",152321213,152332482],[["uc001ezx.2"],"knownGene","uc001ezx.2","chr1",152381718,152386750],[["uc001ezy.2"],"knownGene","uc001ezy.2","chr1",152483319,152484652],[["uc001ezz.2"],"knownGene","uc001ezz.2","chr1",152486977,152488480],[["uc001faa.2"],"knownGene","uc001faa.2","chr1",152538130,152539248],[["uc001fab.2"],"knownGene","uc001fab.2","chr1",152551860,152552980],[["uc001fac.2"],"knownGene","uc001fac.2","chr1",152573137,152573562],[["uc010pds.1"],"knownGene","uc010pds.1","chr1",152586286,152586573],[["uc010pdt.1"],"knownGene","uc010pdt.1","chr1",152595310,152595579],[["uc001fag.2"],"knownGene","uc001fag.2","chr1",152635871,152637134],[["uc001fah.2"],"knownGene","uc001fah.2","chr1",152647770,152649047],[["uc001fai.2"],"knownGene","uc001fai.2","chr1",152658598,152659874],[["uc001faj.2"],"knownGene","uc001faj.2","chr1",152670839,152671916],[["uc001fak.2"],"knownGene","uc001fak.2","chr1",152681522,152681910],[["uc010pdu.1"],"knownGene","uc010pdu.1","chr1",152691997,152692904],[["uc001fal.1"],"knownGene","uc001fal.1","chr1",152730505,152734529],[["uc010pdv.1"],"knownGene","uc010pdv.1","chr1",152748847,152749203],[["uc001fan.2"],"knownGene","uc001fan.2","chr1",152758752,152760898],[["uc009wnp.2"],"knownGene","uc009wnp.2","chr1",152769226,152770656],[["uc001fap.1"],"knownGene","uc001fap.1","chr1",152777310,152779107],[["uc001faq.2"],"knownGene","uc001faq.2","chr1",152784446,152785586],[["uc010pdw.1"],"knownGene","uc010pdw.1","chr1",152799948,152800280],[["uc001fas.3"],"knownGene","uc001fas.3","chr1",152815329,152816458],[["uc001fat.2"],"knownGene","uc001fat.2","chr1",152850797,152857515],[["uc001fau.2"],"knownGene","uc001fau.2","chr1",152881038,152884361],[["uc001fav.1"],"knownGene","uc001fav.1","chr1",152943127,152945069],[["uc001faw.2"],"knownGene","uc001faw.2","chr1",152956556,152958289],[["uc009wnu.1"],"knownGene","uc009wnu.1","chr1",152956556,152958010],[["uc001fay.2"],"knownGene","uc001fay.2","chr1",152974222,152976332],[["uc001fax.3"],"knownGene","uc001fax.3","chr1",152974222,152976331],[["uc001faz.3"],"knownGene","uc001faz.3","chr1",152974222,152976331],[["uc001fba.2"],"knownGene","uc001fba.2","chr1",153003678,153005375],[["uc009wnx.1"],"knownGene","uc009wnx.1","chr1",153004821,153005089],[["uc009wnz.2"],"knownGene","uc009wnz.2","chr1",153012200,153113969],[["uc001fbb.2"],"knownGene","uc001fbb.2","chr1",153012200,153013594],[["uc001fbf.2"],"knownGene","uc001fbf.2","chr1",153028596,153113969],[["uc009woa.2"],"knownGene","uc009woa.2","chr1",153028596,153085989],[["uc001fbd.2"],"knownGene","uc001fbd.2","chr1",153028596,153029988],[["uc001fbg.2"],"knownGene","uc001fbg.2","chr1",153042719,153044084],[["uc001fbh.2"],"knownGene","uc001fbh.2","chr1",153065611,153067001],[["uc001fbi.2"],"knownGene","uc001fbi.2","chr1",153084614,153085989],[["uc001fbj.2"],"knownGene","uc001fbj.2","chr1",153112594,153113969],[["uc009wod.1"],"knownGene","uc009wod.1","chr1",153122058,153123427],[["uc001fbl.2"],"knownGene","uc001fbl.2","chr1",153175918,153177594],[["uc001fbm.2"],"knownGene","uc001fbm.2","chr1",153232178,153234598],[["uc001fbn.1"],"knownGene","uc001fbn.1","chr1",153270337,153283194],[["uc001fbo.2"],"knownGene","uc001fbo.2","chr1",153302597,153321022],[["uc001fbp.2"],"knownGene","uc001fbp.2","chr1",153302597,153321022],[["uc001fbq.2"],"knownGene","uc001fbq.2","chr1",153330329,153333502],[["uc001fbr.1"],"knownGene","uc001fbr.1","chr1",153346183,153348075],[["uc001fbs.2"],"knownGene","uc001fbs.2","chr1",153362508,153363549],[["uc001fbt.1"],"knownGene","uc001fbt.1","chr1",153388999,153395701],[["uc010pdx.1"],"knownGene","uc010pdx.1","chr1",153409471,153412503],[["uc001fbv.1"],"knownGene","uc001fbv.1","chr1",153430219,153433137],[["uc001fbw.1"],"knownGene","uc001fbw.1","chr1",153507075,153508717],[["uc001fbx.2"],"knownGene","uc001fbx.2","chr1",153509623,153514241],[["uc001fby.2"],"knownGene","uc001fby.2","chr1",153516095,153518282],[["uc001fbz.2"],"knownGene","uc001fbz.2","chr1",153516095,153518282],[["uc009wog.1"],"knownGene","uc009wog.1","chr1",153518229,153524245],[["uc001fca.1"],"knownGene","uc001fca.1","chr1",153519808,153521734],[["uc001fcb.2"],"knownGene","uc001fcb.2","chr1",153533586,153538306],[["uc001fcd.1"],"knownGene","uc001fcd.1","chr1",153579366,153585514],[["uc001fcc.2"],"knownGene","uc001fcc.2","chr1",153579366,153581481],[["uc001fce.2"],"knownGene","uc001fce.2","chr1",153586733,153588790],[["uc001fcj.2"],"knownGene","uc001fcj.2","chr1",153591279,153606568],[["uc001fci.2"],"knownGene","uc001fci.2","chr1",153591279,153600713],[["uc001fch.2"],"knownGene","uc001fch.2","chr1",153591279,153600117],[["uc001fcg.2"],"knownGene","uc001fcg.2","chr1",153591279,153599744],[["uc009woh.2"],"knownGene","uc009woh.2","chr1",153591279,153599744],[["uc001fcf.3"],"knownGene","uc001fcf.3","chr1",153591279,153599539],[["uc001fck.1"],"knownGene","uc001fck.1","chr1",153600872,153604513],[["uc001fcl.1"],"knownGene","uc001fcl.1","chr1",153600872,153604513],[["uc001fcm.1"],"knownGene","uc001fcm.1","chr1",153606524,153617979],[["uc001fcn.1"],"knownGene","uc001fcn.1","chr1",153606524,153617979],[["uc009woj.1"],"knownGene","uc009woj.1","chr1",153606524,153615872],[["uc009woi.1"],"knownGene","uc009woi.1","chr1",153606524,153611374],[["uc001fco.1"],"knownGene","uc001fco.1","chr1",153609047,153617979],[["uc001fcp.2"],"knownGene","uc001fcp.2","chr1",153615953,153618775],[["uc001fcq.2"],"knownGene","uc001fcq.2","chr1",153631144,153634325],[["uc001fcr.2"],"knownGene","uc001fcr.2","chr1",153634514,153643479],[["uc010pdy.1"],"knownGene","uc010pdy.1","chr1",153634514,153643479],[["uc009wok.2"],"knownGene","uc009wok.2","chr1",153634514,153643479],[["uc009wol.1"],"knownGene","uc009wol.1","chr1",153637668,153643479],[["uc001fcs.3"],"knownGene","uc001fcs.3","chr1",153651163,153666467],[["uc010pdz.1"],"knownGene","uc010pdz.1","chr1",153652629,153666467],[["uc010pea.1"],"knownGene","uc010pea.1","chr1",153657439,153666467],[["uc009wom.2"],"knownGene","uc009wom.2","chr1",153700548,153746557],[["uc001fct.2"],"knownGene","uc001fct.2","chr1",153700566,153746557],[["uc001fcu.2"],"knownGene","uc001fcu.2","chr1",153700566,153746557],[["uc001fcv.2"],"knownGene","uc001fcv.2","chr1",153700566,153746557],[["uc010peb.1"],"knownGene","uc010peb.1","chr1",153723329,153746557],[["uc001fcw.2"],"knownGene","uc001fcw.2","chr1",153723570,153746557],[["uc010pec.1"],"knownGene","uc010pec.1","chr1",153730047,153746557],[["uc001fcy.2"],"knownGene","uc001fcy.2","chr1",153738950,153746557],[["uc001fcx.2"],"knownGene","uc001fcx.2","chr1",153738950,153746557],[["uc001fcz.2"],"knownGene","uc001fcz.2","chr1",153747767,153752632],[["uc009won.2"],"knownGene","uc009won.2","chr1",153747767,153752632],[["uc001fdb.3"],"knownGene","uc001fdb.3","chr1",153777203,153895451],[["uc001fdc.1"],"knownGene","uc001fdc.1","chr1",153895878,153907635],[["uc001fdd.1"],"knownGene","uc001fdd.1","chr1",153901976,153919154],[["uc010ped.1"],"knownGene","uc010ped.1","chr1",153920153,153931043],[["uc001fde.3"],"knownGene","uc001fde.3","chr1",153920153,153926790],[["uc001fdf.3"],"knownGene","uc001fdf.3","chr1",153920153,153926790],[["uc001fdl.2"],"knownGene","uc001fdl.2","chr1",153931588,153940188],[["uc001fdk.2"],"knownGene","uc001fdk.2","chr1",153931588,153936026],[["uc010pee.1"],"knownGene","uc010pee.1","chr1",153931588,153936026],[["uc001fdj.2"],"knownGene","uc001fdj.2","chr1",153931588,153935951],[["uc001fdi.2"],"knownGene","uc001fdi.2","chr1",153931588,153935798],[["uc001fdh.2"],"knownGene","uc001fdh.2","chr1",153931588,153935789],[["uc001fdn.3"],"knownGene","uc001fdn.3","chr1",153940378,153946832],[["uc010pef.1"],"knownGene","uc010pef.1","chr1",153940378,153946832],[["uc001fdo.3"],"knownGene","uc001fdo.3","chr1",153940378,153946832],[["uc001fdm.1"],"knownGene","uc001fdm.1","chr1",153940396,153946832],[["uc001fdp.1"],"knownGene","uc001fdp.1","chr1",153940396,153946832],[["uc001fdr.2"],"knownGene","uc001fdr.2","chr1",153940712,153946832],[["uc001fdq.2"],"knownGene","uc001fdq.2","chr1",153940712,153946832],[["uc010peg.1"],"knownGene","uc010peg.1","chr1",153940712,153942219],[["uc001fds.2"],"knownGene","uc001fds.2","chr1",153946746,153950451],[["uc001fdt.1"],"knownGene","uc001fdt.1","chr1",153954127,153958806],[["uc001fdu.1"],"knownGene","uc001fdu.1","chr1",153954129,153958806],[["uc001fdv.2"],"knownGene","uc001fdv.2","chr1",153963238,153964632],[["uc001fdw.2"],"knownGene","uc001fdw.2","chr1",153965169,154127592],[["uc010peh.1"],"knownGene","uc010peh.1","chr1",153965169,154127592],[["uc009woq.2"],"knownGene","uc009woq.2","chr1",153965169,154108448],[["uc001fdy.1"],"knownGene","uc001fdy.1","chr1",154127779,154155725],[["uc001fdz.1"],"knownGene","uc001fdz.1","chr1",154127779,154155725],[["uc001fea.1"],"knownGene","uc001fea.1","chr1",154127779,154155725],[["uc001feb.1"],"knownGene","uc001feb.1","chr1",154127779,154155725],[["uc010pej.1"],"knownGene","uc010pej.1","chr1",154127779,154155725],[["uc010pei.1"],"knownGene","uc010pei.1","chr1",154127779,154155682],[["uc001fdx.1"],"knownGene","uc001fdx.1","chr1",154127779,154145153],[["uc009wor.2"],"knownGene","uc009wor.2","chr1",154128840,154155659],[["uc001fec.1"],"knownGene","uc001fec.1","chr1",154134289,154164609],[["uc001fed.1"],"knownGene","uc001fed.1","chr1",154141780,154155725],[["uc001fee.1"],"knownGene","uc001fee.1","chr1",154171847,154178809],[["uc001fei.2"],"knownGene","uc001fei.2","chr1",154179182,154193273],[["uc001feg.2"],"knownGene","uc001feg.2","chr1",154179182,154193273],[["uc001feh.2"],"knownGene","uc001feh.2","chr1",154179182,154193273],[["uc001fej.2"],"knownGene","uc001fej.2","chr1",154179182,154193273],[["uc009wos.1"],"knownGene","uc009wos.1","chr1",154179182,154193273],[["uc001fef.1"],"knownGene","uc001fef.1","chr1",154179182,154186429],[["uc001fek.2"],"knownGene","uc001fek.2","chr1",154183853,154193273],[["uc001fel.2"],"knownGene","uc001fel.2","chr1",154183853,154193273],[["uc009wot.2"],"knownGene","uc009wot.2","chr1",154192654,154235978],[["uc010pel.1"],"knownGene","uc010pel.1","chr1",154193324,154243985],[["uc001fep.3"],"knownGene","uc001fep.3","chr1",154193324,154243328],[["uc010pek.1"],"knownGene","uc010pek.1","chr1",154193324,154235978],[["uc001fen.1"],"knownGene","uc001fen.1","chr1",154193443,154209612],[["uc010pem.1"],"knownGene","uc010pem.1","chr1",154193813,154207214],[["uc010pen.1"],"knownGene","uc010pen.1","chr1",154201090,154235978],[["uc001feq.2"],"knownGene","uc001feq.2","chr1",154227627,154243985],[["uc001fer.2"],"knownGene","uc001fer.2","chr1",154229538,154243328],[["uc001fet.2"],"knownGene","uc001fet.2","chr1",154245038,154248349],[["uc001fes.2"],"knownGene","uc001fes.2","chr1",154245038,154248349],[["uc010peo.1"],"knownGene","uc010peo.1","chr1",154245038,154248349],[["uc009wou.2"],"knownGene","uc009wou.2","chr1",154245038,154248349],[["uc009wov.2"],"knownGene","uc009wov.2","chr1",154245127,154248349],[["uc001feu.2"],"knownGene","uc001feu.2","chr1",154293591,154297800],[["uc001fev.2"],"knownGene","uc001fev.2","chr1",154293591,154297800],[["uc001few.2"],"knownGene","uc001few.2","chr1",154298035,154310320],[["uc001fex.2"],"knownGene","uc001fex.2","chr1",154300275,154323779],[["uc001fey.1"],"knownGene","uc001fey.1","chr1",154301274,154310020],[["uc001fez.1"],"knownGene","uc001fez.1","chr1",154377668,154440188],[["uc001ffa.1"],"knownGene","uc001ffa.1","chr1",154377668,154440188],[["uc001ffb.2"],"knownGene","uc001ffb.2","chr1",154451960,154474589],[["uc001ffc.2"],"knownGene","uc001ffc.2","chr1",154451960,154474589],[["uc001ffd.2"],"knownGene","uc001ffd.2","chr1",154474694,154520622],[["uc009wow.2"],"knownGene","uc009wow.2","chr1",154474694,154520622],[["uc001ffe.2"],"knownGene","uc001ffe.2","chr1",154493798,154520622],[["uc001fff.1"],"knownGene","uc001fff.1","chr1",154521050,154531120],[["uc001ffg.2"],"knownGene","uc001ffg.2","chr1",154540256,154552351],[["uc001ffk.2"],"knownGene","uc001ffk.2","chr1",154554535,154600437],[["uc001ffh.2"],"knownGene","uc001ffh.2","chr1",154554535,154580682],[["uc001ffj.2"],"knownGene","uc001ffj.2","chr1",154554535,154580682],[["uc001ffi.2"],"knownGene","uc001ffi.2","chr1",154554535,154580682],[["uc001ffl.1"],"knownGene","uc001ffl.1","chr1",154573516,154578494],[["uc001ffn.1"],"knownGene","uc001ffn.1","chr1",154574679,154580682],[["uc001ffm.1"],"knownGene","uc001ffm.1","chr1",154574679,154578494],[["uc001ffp.2"],"knownGene","uc001ffp.2","chr1",154679916,154842754],[["uc001ffo.2"],"knownGene","uc001ffo.2","chr1",154679916,154832338],[["uc009wox.1"],"knownGene","uc009wox.1","chr1",154743989,154842754],[["uc001ffq.2"],"knownGene","uc001ffq.2","chr1",154897208,154909484],[["uc001ffr.2"],"knownGene","uc001ffr.2","chr1",154916560,154928567],[["uc001ffs.2"],"knownGene","uc001ffs.2","chr1",154916560,154928567],[["uc010pep.1"],"knownGene","uc010pep.1","chr1",154916560,154928567],[["uc009woy.1"],"knownGene","uc009woy.1","chr1",154923707,154927803],[["uc001fft.2"],"knownGene","uc001fft.2","chr1",154929502,154934258],[["uc001ffx.2"],"knownGene","uc001ffx.2","chr1",154934774,154946959],[["uc001ffy.2"],"knownGene","uc001ffy.2","chr1",154934774,154946959],[["uc001ffw.2"],"knownGene","uc001ffw.2","chr1",154934774,154943223],[["uc001ffv.2"],"knownGene","uc001ffv.2","chr1",154934774,154943223],[["uc001ffz.1"],"knownGene","uc001ffz.1","chr1",154934774,154941090],[["uc001ffu.2"],"knownGene","uc001ffu.2","chr1",154934774,154938238],[["uc001fgb.2"],"knownGene","uc001fgb.2","chr1",154947117,154951724],[["uc001fga.2"],"knownGene","uc001fga.2","chr1",154947117,154951724],[["uc001fge.1"],"knownGene","uc001fge.1","chr1",154955816,154965587],[["uc001fgf.1"],"knownGene","uc001fgf.1","chr1",154955816,154965587],[["uc001fgg.1"],"knownGene","uc001fgg.1","chr1",154955816,154965587],[["uc001fgd.1"],"knownGene","uc001fgd.1","chr1",154955816,154963682],[["uc001fgc.2"],"knownGene","uc001fgc.2","chr1",154955816,154961487],[["uc001fgh.1"],"knownGene","uc001fgh.1","chr1",154960532,154965587],[["uc001fgi.2"],"knownGene","uc001fgi.2","chr1",154966061,154966790],[["uc001fgk.3"],"knownGene","uc001fgk.3","chr1",154975111,154990998],[["uc009wpa.2"],"knownGene","uc009wpa.2","chr1",154975111,154990998],[["uc001fgj.3"],"knownGene","uc001fgj.3","chr1",154975126,154990998],[["uc010peq.1"],"knownGene","uc010peq.1","chr1",154975294,154990998],[["uc001fgl.3"],"knownGene","uc001fgl.3","chr1",154986923,154990998],[["uc001fgm.2"],"knownGene","uc001fgm.2","chr1",154991004,155006257],[["uc009wpb.2"],"knownGene","uc009wpb.2","chr1",154991004,155006257],[["uc001fgn.1"],"knownGene","uc001fgn.1","chr1",155006299,155023406],[["uc010pes.1"],"knownGene","uc010pes.1","chr1",155006299,155023406],[["uc010per.1"],"knownGene","uc010per.1","chr1",155006299,155018962],[["uc001fgo.2"],"knownGene","uc001fgo.2","chr1",155017693,155023641],[["uc001fgq.1"],"knownGene","uc001fgq.1","chr1",155023421,155035252],[["uc001fgt.1"],"knownGene","uc001fgt.1","chr1",155023761,155035252],[["uc010pev.1"],"knownGene","uc010pev.1","chr1",155023761,155035252],[["uc001fgs.1"],"knownGene","uc001fgs.1","chr1",155023761,155035252],[["uc001fgr.1"],"knownGene","uc001fgr.1","chr1",155023761,155035252],[["uc001fgu.1"],"knownGene","uc001fgu.1","chr1",155023761,155035252],[["uc001fgw.1"],"knownGene","uc001fgw.1","chr1",155023761,155035252],[["uc001fgv.1"],"knownGene","uc001fgv.1","chr1",155023761,155035252],[["uc001fgx.1"],"knownGene","uc001fgx.1","chr1",155023761,155035252],[["uc001fgz.1"],"knownGene","uc001fgz.1","chr1",155023761,155035252],[["uc001fgy.1"],"knownGene","uc001fgy.1","chr1",155023761,155035252],[["uc001fha.1"],"knownGene","uc001fha.1","chr1",155023761,155035252],[["uc010peu.1"],"knownGene","uc010peu.1","chr1",155023761,155034181],[["uc010pet.1"],"knownGene","uc010pet.1","chr1",155023761,155031006],[["uc009wpc.1"],"knownGene","uc009wpc.1","chr1",155023761,155028725],[["uc001fhb.1"],"knownGene","uc001fhb.1","chr1",155030714,155035252],[["uc010pew.1"],"knownGene","uc010pew.1","chr1",155036212,155060006],[["uc001fhc.2"],"knownGene","uc001fhc.2","chr1",155036212,155042027],[["uc001fhd.2"],"knownGene","uc001fhd.2","chr1",155036212,155042027],[["uc001fhe.2"],"knownGene","uc001fhe.2","chr1",155036212,155042027],[["uc001fhf.2"],"knownGene","uc001fhf.2","chr1",155051347,155060006],[["uc010pex.1"],"knownGene","uc010pex.1","chr1",155051347,155060006],[["uc001fhg.2"],"knownGene","uc001fhg.2","chr1",155057484,155060006],[["uc001fhh.2"],"knownGene","uc001fhh.2","chr1",155100348,155107384],[["uc001fhi.2"],"knownGene","uc001fhi.2","chr1",155100348,155107384],[["uc009wpd.1"],"knownGene","uc009wpd.1","chr1",155105263,155106131],[["uc010pey.1"],"knownGene","uc010pey.1","chr1",155108287,155357080],[["uc001fhj.3"],"knownGene","uc001fhj.3","chr1",155108287,155111333],[["uc001fhk.3"],"knownGene","uc001fhk.3","chr1",155108287,155111333],[["uc001fhl.3"],"knownGene","uc001fhl.3","chr1",155108287,155111333],[["uc001fhn.2"],"knownGene","uc001fhn.2","chr1",155112368,155112996],[["uc001fhm.2"],"knownGene","uc001fhm.2","chr1",155112368,155112883],[["uc001fho.2"],"knownGene","uc001fho.2","chr1",155141884,155145804],[["uc001fhp.1"],"knownGene","uc001fhp.1","chr1",155143876,155145804],[["uc009wpe.1"],"knownGene","uc009wpe.1","chr1",155145420,155154625],[["uc001fhs.1"],"knownGene","uc001fhs.1","chr1",155146359,155157445],[["uc001fht.1"],"knownGene","uc001fht.1","chr1",155146359,155157445],[["uc010pfa.1"],"knownGene","uc010pfa.1","chr1",155146359,155157445],[["uc001fhq.2"],"knownGene","uc001fhq.2","chr1",155146359,155153085],[["uc001fhr.2"],"knownGene","uc001fhr.2","chr1",155146359,155153085],[["uc010pez.1"],"knownGene","uc010pez.1","chr1",155146359,155149766],[["uc001fhu.1"],"knownGene","uc001fhu.1","chr1",155146384,155157445],[["uc009wpg.1"],"knownGene","uc009wpg.1","chr1",155147069,155154625],[["uc001fhv.3"],"knownGene","uc001fhv.3","chr1",155147076,155153085],[["uc009wpf.2"],"knownGene","uc009wpf.2","chr1",155147076,155148927],[["uc001fhw.1"],"knownGene","uc001fhw.1","chr1",155147229,155157445],[["uc001fin.2"],"knownGene","uc001fin.2","chr1",155158301,155162700],[["uc009wpk.2"],"knownGene","uc009wpk.2","chr1",155158301,155162700],[["uc001fip.2"],"knownGene","uc001fip.2","chr1",155158301,155162700],[["uc009wqg.2"],"knownGene","uc009wqg.2","chr1",155158301,155162700],[["uc009wpo.2"],"knownGene","uc009wpo.2","chr1",155158301,155162700],[["uc009wps.2"],"knownGene","uc009wps.2","chr1",155158301,155162700],[["uc009wpt.2"],"knownGene","uc009wpt.2","chr1",155158301,155162700],[["uc001fic.2"],"knownGene","uc001fic.2","chr1",155158301,155162700],[["uc009wpu.2"],"knownGene","uc009wpu.2","chr1",155158301,155162700],[["uc009wpq.2"],"knownGene","uc009wpq.2","chr1",155158301,155162700],[["uc009wpv.2"],"knownGene","uc009wpv.2","chr1",155158301,155162700],[["uc001fim.2"],"knownGene","uc001fim.2","chr1",155158301,155162700],[["uc001fib.2"],"knownGene","uc001fib.2","chr1",155158301,155162700],[["uc009wpw.2"],"knownGene","uc009wpw.2","chr1",155158301,155162700],[["uc001fie.2"],"knownGene","uc001fie.2","chr1",155158301,155162700],[["uc009wpr.2"],"knownGene","uc009wpr.2","chr1",155158301,155162700],[["uc001fig.2"],"knownGene","uc001fig.2","chr1",155158301,155162700],[["uc001fif.2"],"knownGene","uc001fif.2","chr1",155158301,155162700],[["uc009wpx.2"],"knownGene","uc009wpx.2","chr1",155158301,155162700],[["uc001fid.2"],"knownGene","uc001fid.2","chr1",155158301,155162700],[["uc009wpj.2"],"knownGene","uc009wpj.2","chr1",155158301,155162700],[["uc001fij.2"],"knownGene","uc001fij.2","chr1",155158301,155162700],[["uc009wpy.2"],"knownGene","uc009wpy.2","chr1",155158301,155162700],[["uc010pfm.1"],"knownGene","uc010pfm.1","chr1",155158301,155162700],[["uc001fiq.2"],"knownGene","uc001fiq.2","chr1",155158301,155162700],[["uc009wpz.2"],"knownGene","uc009wpz.2","chr1",155158301,155162700],[["uc010pfn.1"],"knownGene","uc010pfn.1","chr1",155158301,155162700],[["uc009wqa.2"],"knownGene","uc009wqa.2","chr1",155158301,155162700],[["uc010pfo.1"],"knownGene","uc010pfo.1","chr1",155158301,155162700],[["uc010pfp.1"],"knownGene","uc010pfp.1","chr1",155158301,155162700],[["uc001fii.2"],"knownGene","uc001fii.2","chr1",155158301,155162700],[["uc001fih.2"],"knownGene","uc001fih.2","chr1",155158301,155162700],[["uc001fia.2"],"knownGene","uc001fia.2","chr1",155158301,155162700],[["uc009wqc.2"],"knownGene","uc009wqc.2","chr1",155158301,155162700],[["uc009wqd.2"],"knownGene","uc009wqd.2","chr1",155158301,155162700],[["uc009wqb.2"],"knownGene","uc009wqb.2","chr1",155158301,155162700],[["uc010pfq.1"],"knownGene","uc010pfq.1","chr1",155158301,155162700],[["uc010pfr.1"],"knownGene","uc010pfr.1","chr1",155158301,155162700],[["uc001fit.2"],"knownGene","uc001fit.2","chr1",155158301,155162700],[["uc009wqe.2"],"knownGene","uc009wqe.2","chr1",155158301,155162700],[["uc001fil.2"],"knownGene","uc001fil.2","chr1",155158301,155162700],[["uc009wpm.2"],"knownGene","uc009wpm.2","chr1",155158301,155162700],[["uc009wpp.2"],"knownGene","uc009wpp.2","chr1",155158301,155162700],[["uc010pfs.1"],"knownGene","uc010pfs.1","chr1",155158301,155162700],[["uc001fik.2"],"knownGene","uc001fik.2","chr1",155158301,155162700],[["uc001fio.2"],"knownGene","uc001fio.2","chr1",155158301,155162700],[["uc009wqf.2"],"knownGene","uc009wqf.2","chr1",155158301,155162700],[["uc009wpl.2"],"knownGene","uc009wpl.2","chr1",155158301,155162700],[["uc009wpn.2"],"knownGene","uc009wpn.2","chr1",155158301,155162700],[["uc010pfc.1"],"knownGene","uc010pfc.1","chr1",155158301,155162684],[["uc009wph.2"],"knownGene","uc009wph.2","chr1",155158301,155162684],[["uc010pfd.1"],"knownGene","uc010pfd.1","chr1",155158301,155162684],[["uc010pfe.1"],"knownGene","uc010pfe.1","chr1",155158301,155162684],[["uc010pff.1"],"knownGene","uc010pff.1","chr1",155158301,155162684],[["uc009wpi.2"],"knownGene","uc009wpi.2","chr1",155158301,155162684],[["uc010pfg.1"],"knownGene","uc010pfg.1","chr1",155158301,155162684],[["uc010pfh.1"],"knownGene","uc010pfh.1","chr1",155158301,155162684],[["uc010pfi.1"],"knownGene","uc010pfi.1","chr1",155158301,155162684],[["uc010pfj.1"],"knownGene","uc010pfj.1","chr1",155158301,155162684],[["uc010pfk.1"],"knownGene","uc010pfk.1","chr1",155158301,155162684],[["uc010pfl.1"],"knownGene","uc010pfl.1","chr1",155158301,155162684],[["uc010pfb.1"],"knownGene","uc010pfb.1","chr1",155158301,155162101],[["uc001fhz.2"],"knownGene","uc001fhz.2","chr1",155158301,155161398],[["uc001fhy.2"],"knownGene","uc001fhy.2","chr1",155158301,155161158],[["uc001fis.1"],"knownGene","uc001fis.1","chr1",155159930,155162700],[["uc009wqh.2"],"knownGene","uc009wqh.2","chr1",155161151,155161619],[["uc010pft.1"],"knownGene","uc010pft.1","chr1",155161501,155162700],[["uc001fiv.1"],"knownGene","uc001fiv.1","chr1",155161653,155162700],[["uc001fiw.1"],"knownGene","uc001fiw.1","chr1",155161686,155162700],[["uc001fix.2"],"knownGene","uc001fix.2","chr1",155165380,155177690],[["uc009wqi.2"],"knownGene","uc009wqi.2","chr1",155165380,155177690],[["uc001fiz.2"],"knownGene","uc001fiz.2","chr1",155165380,155177690],[["uc001fiy.2"],"knownGene","uc001fiy.2","chr1",155165380,155177690],[["uc010pfu.1"],"knownGene","uc010pfu.1","chr1",155165380,155177690],[["uc010pfv.1"],"knownGene","uc010pfv.1","chr1",155167670,155177690],[["uc001fja.2"],"knownGene","uc001fja.2","chr1",155170241,155178969],[["uc009wqj.1"],"knownGene","uc009wqj.1","chr1",155174360,155178969],[["uc001fjb.2"],"knownGene","uc001fjb.2","chr1",155178489,155183622],[["uc001fjc.2"],"knownGene","uc001fjc.2","chr1",155178489,155183622],[["uc001fjf.3"],"knownGene","uc001fjf.3","chr1",155183616,155197325],[["uc001fje.3"],"knownGene","uc001fje.3","chr1",155183616,155197325],[["uc001fjd.2"],"knownGene","uc001fjd.2","chr1",155183616,155188809],[["uc001fjg.2"],"knownGene","uc001fjg.2","chr1",155202800,155204240],[["uc001fji.2"],"knownGene","uc001fji.2","chr1",155204243,155214488],[["uc001fjj.2"],"knownGene","uc001fjj.2","chr1",155204243,155214488],[["uc001fjk.2"],"knownGene","uc001fjk.2","chr1",155204243,155214488],[["uc001fjl.2"],"knownGene","uc001fjl.2","chr1",155204243,155214488],[["uc010pfy.1"],"knownGene","uc010pfy.1","chr1",155204243,155214488],[["uc001fjh.2"],"knownGene","uc001fjh.2","chr1",155204243,155211053],[["uc010pfw.1"],"knownGene","uc010pfw.1","chr1",155204243,155211053],[["uc010pfx.1"],"knownGene","uc010pfx.1","chr1",155204243,155211053],[["uc009wqk.1"],"knownGene","uc009wqk.1","chr1",155207131,155214488],[["uc001fjm.2"],"knownGene","uc001fjm.2","chr1",155216996,155225274],[["uc001fjn.2"],"knownGene","uc001fjn.2","chr1",155216996,155225274],[["uc001fjo.2"],"knownGene","uc001fjo.2","chr1",155216996,155225274],[["uc001fjp.2"],"knownGene","uc001fjp.2","chr1",155216996,155225274],[["uc009wql.2"],"knownGene","uc009wql.2","chr1",155216996,155221696],[["uc001fjq.1"],"knownGene","uc001fjq.1","chr1",155222539,155225274],[["uc001fjs.2"],"knownGene","uc001fjs.2","chr1",155225770,155232195],[["uc001fjt.2"],"knownGene","uc001fjt.2","chr1",155225770,155232195],[["uc001fju.2"],"knownGene","uc001fju.2","chr1",155225770,155232195],[["uc001fjv.2"],"knownGene","uc001fjv.2","chr1",155225770,155232195],[["uc001fjr.2"],"knownGene","uc001fjr.2","chr1",155225770,155230335],[["uc009wqm.2"],"knownGene","uc009wqm.2","chr1",155232659,155247501],[["uc001fjw.2"],"knownGene","uc001fjw.2","chr1",155232659,155243281],[["uc001fjy.2"],"knownGene","uc001fjy.2","chr1",155232659,155243281],[["uc001fjx.2"],"knownGene","uc001fjx.2","chr1",155232659,155243281],[["uc001fjz.1"],"knownGene","uc001fjz.1","chr1",155247373,155259638],[["uc010pfz.1"],"knownGene","uc010pfz.1","chr1",155247373,155258498],[["uc001fkb.3"],"knownGene","uc001fkb.3","chr1",155259085,155271225],[["uc001fka.3"],"knownGene","uc001fka.3","chr1",155259085,155270792],[["uc010pga.1"],"knownGene","uc010pga.1","chr1",155265227,155270792],[["uc001fkc.2"],"knownGene","uc001fkc.2","chr1",155278538,155290457],[["uc001fkd.2"],"knownGene","uc001fkd.2","chr1",155278538,155290457],[["uc001fke.2"],"knownGene","uc001fke.2","chr1",155278704,155290457],[["uc001fkf.2"],"knownGene","uc001fkf.2","chr1",155278704,155290457],[["uc001fkh.1"],"knownGene","uc001fkh.1","chr1",155286653,155291335],[["uc001fki.2"],"knownGene","uc001fki.2","chr1",155290251,155293938],[["uc001fkj.2"],"knownGene","uc001fkj.2","chr1",155290639,155300909],[["uc001fkk.2"],"knownGene","uc001fkk.2","chr1",155290639,155300909],[["uc009wqn.1"],"knownGene","uc009wqn.1","chr1",155291478,155300909],[["uc009wqo.1"],"knownGene","uc009wqo.1","chr1",155293284,155300909],[["uc001fkl.2"],"knownGene","uc001fkl.2","chr1",155293727,155300909],[["uc001fkp.2"],"knownGene","uc001fkp.2","chr1",155294217,155300909],[["uc001fkq.2"],"knownGene","uc001fkq.2","chr1",155294217,155300909],[["uc010pgb.1"],"knownGene","uc010pgb.1","chr1",155294217,155300909],[["uc009wqp.1"],"knownGene","uc009wqp.1","chr1",155294217,155300909],[["uc001fkn.2"],"knownGene","uc001fkn.2","chr1",155294297,155300909],[["uc001fko.2"],"knownGene","uc001fko.2","chr1",155294297,155300909],[["uc001fkr.2"],"knownGene","uc001fkr.2","chr1",155294367,155300909],[["uc001fks.2"],"knownGene","uc001fks.2","chr1",155295357,155300909],[["uc001fkt.2"],"knownGene","uc001fkt.2","chr1",155305052,155532324],[["uc009wqq.2"],"knownGene","uc009wqq.2","chr1",155305052,155532324],[["uc010pgd.1"],"knownGene","uc010pgd.1","chr1",155403092,155403793],[["uc010pgc.1"],"knownGene","uc010pgc.1","chr1",155403092,155403473],[["uc009wqr.1"],"knownGene","uc009wqr.1","chr1",155447676,155532585],[["uc010pge.1"],"knownGene","uc010pge.1","chr1",155531771,155533732],[["uc001fkv.2"],"knownGene","uc001fkv.2","chr1",155531863,155533732],[["uc001fky.2"],"knownGene","uc001fky.2","chr1",155580006,155584757],[["uc001fla.2"],"knownGene","uc001fla.2","chr1",155580006,155584757],[["uc001fkz.2"],"knownGene","uc001fkz.2","chr1",155580006,155584757],[["uc001fld.3"],"knownGene","uc001fld.3","chr1",155580006,155584757],[["uc009wqs.2"],"knownGene","uc009wqs.2","chr1",155580006,155584757],[["uc010pgf.1"],"knownGene","uc010pgf.1","chr1",155580006,155584757],[["uc001fkw.2"],"knownGene","uc001fkw.2","chr1",155580006,155584724],[["uc001fkx.2"],"knownGene","uc001fkx.2","chr1",155580006,155584724],[["uc001flb.2"],"knownGene","uc001flb.2","chr1",155580031,155584757],[["uc001flc.2"],"knownGene","uc001flc.2","chr1",155580410,155584724],[["uc001fle.1"],"knownGene","uc001fle.1","chr1",155583674,155585496],[["uc001flf.2"],"knownGene","uc001flf.2","chr1",155596546,155618335],[["uc001fln.2"],"knownGene","uc001fln.2","chr1",155629233,155658791],[["uc001flo.2"],"knownGene","uc001flo.2","chr1",155629233,155658791],[["uc001flp.2"],"knownGene","uc001flp.2","chr1",155629233,155658791],[["uc001flk.2"],"knownGene","uc001flk.2","chr1",155629233,155658565],[["uc001fll.2"],"knownGene","uc001fll.2","chr1",155629233,155658565],[["uc009wqv.2"],"knownGene","uc009wqv.2","chr1",155629233,155658565],[["uc001flm.2"],"knownGene","uc001flm.2","chr1",155629233,155658565],[["uc001fli.2"],"knownGene","uc001fli.2","chr1",155629233,155658565],[["uc009wqu.2"],"knownGene","uc009wqu.2","chr1",155629233,155658565],[["uc001flj.2"],"knownGene","uc001flj.2","chr1",155629233,155658565],[["uc009wqw.2"],"knownGene","uc009wqw.2","chr1",155629233,155658565],[["uc010pgi.1"],"knownGene","uc010pgi.1","chr1",155629233,155658266],[["uc001flh.2"],"knownGene","uc001flh.2","chr1",155629233,155658266],[["uc009wqt.2"],"knownGene","uc009wqt.2","chr1",155629233,155658266],[["uc010pgh.1"],"knownGene","uc010pgh.1","chr1",155629233,155649598],[["uc010pgg.1"],"knownGene","uc010pgg.1","chr1",155629233,155646537],[["uc001flg.2"],"knownGene","uc001flg.2","chr1",155629233,155640882],[["uc010pgj.1"],"knownGene","uc010pgj.1","chr1",155630240,155658791],[["uc009wqx.2"],"knownGene","uc009wqx.2","chr1",155630785,155658266],[["uc010pgk.1"],"knownGene","uc010pgk.1","chr1",155638417,155658266],[["uc001flq.2"],"knownGene","uc001flq.2","chr1",155658873,155708317]] \ No newline at end of file diff --git a/tests/data/hg19_formatted/tracks/knownGene/chr1/names.txt b/tests/data/hg19_formatted/tracks/knownGene/chr1/names.txt new file mode 100644 index 0000000000..9c19f60856 --- /dev/null +++ b/tests/data/hg19_formatted/tracks/knownGene/chr1/names.txt @@ -0,0 +1,5000 @@ +[["uc001aaa.3"],"knownGene","uc001aaa.3","chr1",11873,14409] +[["uc010nxq.1"],"knownGene","uc010nxq.1","chr1",11873,14409] +[["uc010nxr.1"],"knownGene","uc010nxr.1","chr1",11873,14409] +[["uc001aah.3"],"knownGene","uc001aah.3","chr1",14362,29370] +[["uc009vir.2"],"knownGene","uc009vir.2","chr1",14362,29370] +[["uc009viq.2"],"knownGene","uc009viq.2","chr1",14362,29370] +[["uc001aac.3"],"knownGene","uc001aac.3","chr1",14362,29370] +[["uc001aab.3"],"knownGene","uc001aab.3","chr1",14362,24901] +[["uc009vit.2"],"knownGene","uc009vit.2","chr1",14362,19759] +[["uc001aae.3"],"knownGene","uc001aae.3","chr1",14362,19759] +[["uc009viu.2"],"knownGene","uc009viu.2","chr1",14362,19759] +[["uc009vis.2"],"knownGene","uc009vis.2","chr1",14362,16765] +[["uc009viv.2"],"knownGene","uc009viv.2","chr1",14406,29370] +[["uc009viw.2"],"knownGene","uc009viw.2","chr1",14406,29370] +[["uc009vix.2"],"knownGene","uc009vix.2","chr1",15602,29370] +[["uc009vjd.2"],"knownGene","uc009vjd.2","chr1",15795,18061] +[["uc009viz.2"],"knownGene","uc009viz.2","chr1",16606,29370] +[["uc009viy.2"],"knownGene","uc009viy.2","chr1",16606,29370] +[["uc009vjb.1"],"knownGene","uc009vjb.1","chr1",16857,29961] +[["uc010nxs.1"],"knownGene","uc010nxs.1","chr1",16857,29370] +[["uc001aai.1"],"knownGene","uc001aai.1","chr1",16857,19759] +[["uc009vjc.1"],"knownGene","uc009vjc.1","chr1",16857,17751] +[["uc009vje.2"],"knownGene","uc009vje.2","chr1",17232,29370] +[["uc009vjf.2"],"knownGene","uc009vjf.2","chr1",17605,29370] +[["uc001aak.2"],"knownGene","uc001aak.2","chr1",34611,36081] +[["uc001aal.1"],"knownGene","uc001aal.1","chr1",69090,70008] +[["uc010nxt.1"],"knownGene","uc010nxt.1","chr1",89294,237877] +[["uc001aam.3"],"knownGene","uc001aam.3","chr1",137838,139228] +[["uc001aaq.1"],"knownGene","uc001aaq.1","chr1",321083,321114] +[["uc001aar.1"],"knownGene","uc001aar.1","chr1",321145,321223] +[["uc009vjk.2"],"knownGene","uc009vjk.2","chr1",322036,326938] +[["uc001aav.3"],"knownGene","uc001aav.3","chr1",323891,328580] +[["uc001aau.2"],"knownGene","uc001aau.2","chr1",323891,328580] +[["uc010nxu.1"],"knownGene","uc010nxu.1","chr1",367658,368595] +[["uc001aax.1"],"knownGene","uc001aax.1","chr1",420205,421839] +[["uc001aaz.2"],"knownGene","uc001aaz.2","chr1",566461,568045] +[["uc001aba.1"],"knownGene","uc001aba.1","chr1",568148,568842] +[["uc001abb.2"],"knownGene","uc001abb.2","chr1",568843,568912] +[["uc001abc.2"],"knownGene","uc001abc.2","chr1",569326,570349] +[["uc010nxv.1"],"knownGene","uc010nxv.1","chr1",621097,622034] +[["uc002khh.2"],"knownGene","uc002khh.2","chr1",661139,679736] +[["uc009vjm.2"],"knownGene","uc009vjm.2","chr1",661139,670994] +[["uc001abe.3"],"knownGene","uc001abe.3","chr1",661139,665731] +[["uc001abi.1"],"knownGene","uc001abi.1","chr1",668401,668479] +[["uc001abj.2"],"knownGene","uc001abj.2","chr1",668510,668541] +[["uc010nxw.1"],"knownGene","uc010nxw.1","chr1",671807,671885] +[["uc001abl.2"],"knownGene","uc001abl.2","chr1",671916,671947] +[["uc001abm.2"],"knownGene","uc001abm.2","chr1",674239,679736] +[["uc001abo.2"],"knownGene","uc001abo.2","chr1",700236,714006] +[["uc010nxx.1"],"knownGene","uc010nxx.1","chr1",761586,762902] +[["uc001abr.1"],"knownGene","uc001abr.1","chr1",763063,789740] +[["uc001abp.1"],"knownGene","uc001abp.1","chr1",763063,788997] +[["uc001abq.1"],"knownGene","uc001abq.1","chr1",763063,788997] +[["uc009vjo.1"],"knownGene","uc009vjo.1","chr1",763063,788997] +[["uc009vjn.1"],"knownGene","uc009vjn.1","chr1",763063,788902] +[["uc001abs.2"],"knownGene","uc001abs.2","chr1",791897,794579] +[["uc001abt.3"],"knownGene","uc001abt.3","chr1",803452,812182] +[["uc001abu.1"],"knownGene","uc001abu.1","chr1",846814,850328] +[["uc010nxy.1"],"knownGene","uc010nxy.1","chr1",852952,854817] +[["uc010nxz.1"],"knownGene","uc010nxz.1","chr1",852952,854817] +[["uc001abv.1"],"knownGene","uc001abv.1","chr1",860529,871276] +[["uc001abw.1"],"knownGene","uc001abw.1","chr1",861120,879961] +[["uc001abx.1"],"knownGene","uc001abx.1","chr1",871151,879961] +[["uc001abz.3"],"knownGene","uc001abz.3","chr1",879583,894679] +[["uc009vjq.2"],"knownGene","uc009vjq.2","chr1",879583,894679] +[["uc001aby.3"],"knownGene","uc001aby.3","chr1",879583,893918] +[["uc009vjr.1"],"knownGene","uc009vjr.1","chr1",893650,894679] +[["uc001aca.1"],"knownGene","uc001aca.1","chr1",895966,901095] +[["uc001acb.1"],"knownGene","uc001acb.1","chr1",896828,897858] +[["uc010nya.1"],"knownGene","uc010nya.1","chr1",897008,897858] +[["uc001acc.1"],"knownGene","uc001acc.1","chr1",897460,901095] +[["uc010nyb.1"],"knownGene","uc010nyb.1","chr1",897734,899229] +[["uc001acd.2"],"knownGene","uc001acd.2","chr1",901876,910482] +[["uc001acf.2"],"knownGene","uc001acf.2","chr1",901876,910482] +[["uc001ace.2"],"knownGene","uc001ace.2","chr1",901876,910482] +[["uc001ach.2"],"knownGene","uc001ach.2","chr1",910578,917473] +[["uc001acg.2"],"knownGene","uc001acg.2","chr1",910578,912021] +[["uc001aci.2"],"knownGene","uc001aci.2","chr1",934341,935552] +[["uc010nyc.1"],"knownGene","uc010nyc.1","chr1",934341,935552] +[["uc001acj.3"],"knownGene","uc001acj.3","chr1",948846,949915] +[["uc001ack.1"],"knownGene","uc001ack.1","chr1",955502,991492] +[["uc009vjs.1"],"knownGene","uc009vjs.1","chr1",995082,997436] +[["uc001acl.1"],"knownGene","uc001acl.1","chr1",995116,1001833] +[["uc001acu.2"],"knownGene","uc001acu.2","chr1",1017197,1051736] +[["uc001act.2"],"knownGene","uc001act.2","chr1",1017197,1051736] +[["uc001acr.2"],"knownGene","uc001acr.2","chr1",1017197,1051736] +[["uc001acs.2"],"knownGene","uc001acs.2","chr1",1017197,1051736] +[["uc001acp.2"],"knownGene","uc001acp.2","chr1",1017197,1041507] +[["uc001acn.2"],"knownGene","uc001acn.2","chr1",1017197,1027554] +[["uc001acm.2"],"knownGene","uc001acm.2","chr1",1017197,1027483] +[["uc009vju.1"],"knownGene","uc009vju.1","chr1",1017197,1027483] +[["uc010nyd.1"],"knownGene","uc010nyd.1","chr1",1017197,1026945] +[["uc001acv.2"],"knownGene","uc001acv.2","chr1",1072396,1079432] +[["uc001acw.2"],"knownGene","uc001acw.2","chr1",1102483,1102578] +[["uc010nye.1"],"knownGene","uc010nye.1","chr1",1103242,1103332] +[["uc010nyf.1"],"knownGene","uc010nyf.1","chr1",1104384,1104467] +[["uc001acx.1"],"knownGene","uc001acx.1","chr1",1108435,1114935] +[["uc001acy.2"],"knownGene","uc001acy.2","chr1",1109285,1133313] +[["uc010nyg.1"],"knownGene","uc010nyg.1","chr1",1109285,1133313] +[["uc001acz.1"],"knownGene","uc001acz.1","chr1",1115076,1121241] +[["uc001adb.2"],"knownGene","uc001adb.2","chr1",1138888,1142089] +[["uc001adc.2"],"knownGene","uc001adc.2","chr1",1138888,1142089] +[["uc001add.2"],"knownGene","uc001add.2","chr1",1138888,1142089] +[["uc001ada.2"],"knownGene","uc001ada.2","chr1",1138888,1141060] +[["uc001ade.2"],"knownGene","uc001ade.2","chr1",1146706,1149512] +[["uc001adf.2"],"knownGene","uc001adf.2","chr1",1146720,1149512] +[["uc001adh.3"],"knownGene","uc001adh.3","chr1",1152288,1167447] +[["uc001adi.3"],"knownGene","uc001adi.3","chr1",1152288,1167447] +[["uc009vjv.2"],"knownGene","uc009vjv.2","chr1",1152288,1167447] +[["uc009vjw.2"],"knownGene","uc009vjw.2","chr1",1152288,1167447] +[["uc001adg.2"],"knownGene","uc001adg.2","chr1",1152288,1156731] +[["uc001adj.1"],"knownGene","uc001adj.1","chr1",1158103,1159348] +[["uc001adk.2"],"knownGene","uc001adk.2","chr1",1167628,1170418] +[["uc001adl.1"],"knownGene","uc001adl.1","chr1",1177832,1182102] +[["uc001ado.2"],"knownGene","uc001ado.2","chr1",1189293,1209234] +[["uc001adp.2"],"knownGene","uc001adp.2","chr1",1189293,1209234] +[["uc001adq.2"],"knownGene","uc001adq.2","chr1",1189293,1209234] +[["uc001adr.2"],"knownGene","uc001adr.2","chr1",1189293,1209234] +[["uc001ads.2"],"knownGene","uc001ads.2","chr1",1189293,1209234] +[["uc001adn.2"],"knownGene","uc001adn.2","chr1",1189293,1209188] +[["uc001adm.2"],"knownGene","uc001adm.2","chr1",1189293,1203372] +[["uc010nyh.1"],"knownGene","uc010nyh.1","chr1",1193437,1196954] +[["uc001adt.1"],"knownGene","uc001adt.1","chr1",1215815,1227409] +[["uc001adu.1"],"knownGene","uc001adu.1","chr1",1215815,1227409] +[["uc001adw.2"],"knownGene","uc001adw.2","chr1",1217488,1227409] +[["uc001adv.2"],"knownGene","uc001adv.2","chr1",1217488,1227409] +[["uc001adx.2"],"knownGene","uc001adx.2","chr1",1217536,1227409] +[["uc001aeb.2"],"knownGene","uc001aeb.2","chr1",1227763,1243269] +[["uc001aea.2"],"knownGene","uc001aea.2","chr1",1227763,1241309] +[["uc001ady.2"],"knownGene","uc001ady.2","chr1",1227763,1234335] +[["uc001aec.1"],"knownGene","uc001aec.1","chr1",1234123,1244989] +[["uc001aed.2"],"knownGene","uc001aed.2","chr1",1243993,1247056] +[["uc010nyi.1"],"knownGene","uc010nyi.1","chr1",1243993,1247056] +[["uc009vjx.2"],"knownGene","uc009vjx.2","chr1",1244465,1247056] +[["uc001aee.1"],"knownGene","uc001aee.1","chr1",1246964,1260046] +[["uc001aef.1"],"knownGene","uc001aef.1","chr1",1246964,1260046] +[["uc009vjz.1"],"knownGene","uc009vjz.1","chr1",1246964,1260046] +[["uc010nyj.1"],"knownGene","uc010nyj.1","chr1",1246964,1260046] +[["uc001aeg.1"],"knownGene","uc001aeg.1","chr1",1246964,1260046] +[["uc001aeh.1"],"knownGene","uc001aeh.1","chr1",1246964,1260046] +[["uc001aei.1"],"knownGene","uc001aei.1","chr1",1246964,1260046] +[["uc001aej.1"],"knownGene","uc001aej.1","chr1",1246964,1260046] +[["uc001aek.1"],"knownGene","uc001aek.1","chr1",1246964,1260046] +[["uc009vjy.1"],"knownGene","uc009vjy.1","chr1",1246964,1252830] +[["uc001aem.1"],"knownGene","uc001aem.1","chr1",1254058,1260046] +[["uc001ael.1"],"knownGene","uc001ael.1","chr1",1254058,1260046] +[["uc001aen.1"],"knownGene","uc001aen.1","chr1",1254076,1260046] +[["uc001aeo.2"],"knownGene","uc001aeo.2","chr1",1260142,1264275] +[["uc010nyk.1"],"knownGene","uc010nyk.1","chr1",1266725,1269843] +[["uc001aer.3"],"knownGene","uc001aer.3","chr1",1270658,1284492] +[["uc002quu.2"],"knownGene","uc002quu.2","chr1",1270658,1275557] +[["uc009vka.2"],"knownGene","uc009vka.2","chr1",1270658,1275557] +[["uc001aeu.1"],"knownGene","uc001aeu.1","chr1",1270663,1277504] +[["uc001afa.2"],"knownGene","uc001afa.2","chr1",1288071,1297157] +[["uc010nyl.1"],"knownGene","uc010nyl.1","chr1",1288071,1293942] +[["uc001aez.2"],"knownGene","uc001aez.2","chr1",1288071,1293942] +[["uc001aew.2"],"knownGene","uc001aew.2","chr1",1288071,1293927] +[["uc001aex.3"],"knownGene","uc001aex.3","chr1",1288071,1293927] +[["uc001aey.3"],"knownGene","uc001aey.3","chr1",1288071,1293927] +[["uc001afc.2"],"knownGene","uc001afc.2","chr1",1309109,1310818] +[["uc001afd.2"],"knownGene","uc001afd.2","chr1",1309109,1310580] +[["uc009vkb.1"],"knownGene","uc009vkb.1","chr1",1309109,1310562] +[["uc001afb.1"],"knownGene","uc001afb.1","chr1",1309109,1310246] +[["uc001afh.2"],"knownGene","uc001afh.2","chr1",1321090,1334718] +[["uc001afj.2"],"knownGene","uc001afj.2","chr1",1321090,1334718] +[["uc001afk.2"],"knownGene","uc001afk.2","chr1",1321090,1334718] +[["uc001afi.2"],"knownGene","uc001afi.2","chr1",1321090,1334718] +[["uc001afg.1"],"knownGene","uc001afg.1","chr1",1321090,1333722] +[["uc001aff.1"],"knownGene","uc001aff.1","chr1",1321090,1328183] +[["uc010nym.1"],"knownGene","uc010nym.1","chr1",1321090,1327029] +[["uc001afn.1"],"knownGene","uc001afn.1","chr1",1334909,1338075] +[["uc001afm.2"],"knownGene","uc001afm.2","chr1",1334909,1337425] +[["uc009vkd.2"],"knownGene","uc009vkd.2","chr1",1334911,1337425] +[["uc009vkc.1"],"knownGene","uc009vkc.1","chr1",1334911,1336650] +[["uc001afo.3"],"knownGene","uc001afo.3","chr1",1337276,1342693] +[["uc010nyn.1"],"knownGene","uc010nyn.1","chr1",1340412,1342693] +[["uc010nyo.1"],"knownGene","uc010nyo.1","chr1",1353801,1356650] +[["uc001afq.2"],"knownGene","uc001afq.2","chr1",1353801,1356650] +[["uc001afp.2"],"knownGene","uc001afp.2","chr1",1353801,1356650] +[["uc010nyp.1"],"knownGene","uc010nyp.1","chr1",1361507,1363166] +[["uc001afr.2"],"knownGene","uc001afr.2","chr1",1370908,1376145] +[["uc001afs.2"],"knownGene","uc001afs.2","chr1",1370908,1376145] +[["uc001aft.2"],"knownGene","uc001aft.2","chr1",1385068,1405538] +[["uc001afv.2"],"knownGene","uc001afv.2","chr1",1407163,1431581] +[["uc001afx.2"],"knownGene","uc001afx.2","chr1",1413405,1431581] +[["uc001afw.2"],"knownGene","uc001afw.2","chr1",1413405,1418847] +[["uc001afy.2"],"knownGene","uc001afy.2","chr1",1425460,1431581] +[["uc001afz.1"],"knownGene","uc001afz.1","chr1",1447554,1470064] +[["uc001aga.1"],"knownGene","uc001aga.1","chr1",1447554,1470064] +[["uc001agb.1"],"knownGene","uc001agb.1","chr1",1447909,1470064] +[["uc001agc.1"],"knownGene","uc001agc.1","chr1",1467448,1470064] +[["uc009vkf.2"],"knownGene","uc009vkf.2","chr1",1470158,1475740] +[["uc001agd.2"],"knownGene","uc001agd.2","chr1",1477053,1510262] +[["uc009vkg.1"],"knownGene","uc009vkg.1","chr1",1478559,1510262] +[["uc001age.1"],"knownGene","uc001age.1","chr1",1497731,1510262] +[["uc001agf.1"],"knownGene","uc001agf.1","chr1",1535818,1543166] +[["uc001agg.2"],"knownGene","uc001agg.2","chr1",1550883,1565984] +[["uc001agh.2"],"knownGene","uc001agh.2","chr1",1550883,1565984] +[["uc001agi.2"],"knownGene","uc001agi.2","chr1",1550883,1565984] +[["uc001agj.2"],"knownGene","uc001agj.2","chr1",1550883,1565984] +[["uc001agk.2"],"knownGene","uc001agk.2","chr1",1550883,1565984] +[["uc001agm.2"],"knownGene","uc001agm.2","chr1",1551284,1565984] +[["uc001agl.1"],"knownGene","uc001agl.1","chr1",1551284,1564946] +[["uc010nyq.1"],"knownGene","uc010nyq.1","chr1",1551689,1565984] +[["uc009vkh.2"],"knownGene","uc009vkh.2","chr1",1559153,1565984] +[["uc001agn.2"],"knownGene","uc001agn.2","chr1",1560370,1565984] +[["uc001ago.2"],"knownGene","uc001ago.2","chr1",1564485,1565984] +[["uc001agp.2"],"knownGene","uc001agp.2","chr1",1567559,1570029] +[["uc001agq.2"],"knownGene","uc001agq.2","chr1",1567559,1570029] +[["uc001agr.2"],"knownGene","uc001agr.2","chr1",1568161,1570029] +[["uc009vki.2"],"knownGene","uc009vki.2","chr1",1568566,1570029] +[["uc001aha.1"],"knownGene","uc001aha.1","chr1",1571099,1655775] +[["uc001agw.1"],"knownGene","uc001agw.1","chr1",1571099,1655775] +[["uc001agv.1"],"knownGene","uc001agv.1","chr1",1571099,1655775] +[["uc001agy.1"],"knownGene","uc001agy.1","chr1",1571099,1655775] +[["uc001agx.1"],"knownGene","uc001agx.1","chr1",1571099,1655775] +[["uc001agz.1"],"knownGene","uc001agz.1","chr1",1571099,1655775] +[["uc001ags.1"],"knownGene","uc001ags.1","chr1",1571099,1647917] +[["uc001agt.1"],"knownGene","uc001agt.1","chr1",1571099,1647917] +[["uc009vkj.2"],"knownGene","uc009vkj.2","chr1",1571099,1576737] +[["uc010nyr.1"],"knownGene","uc010nyr.1","chr1",1577746,1580625] +[["uc001ahc.1"],"knownGene","uc001ahc.1","chr1",1586822,1590469] +[["uc009vkl.1"],"knownGene","uc009vkl.1","chr1",1590989,1624243] +[["uc001ahh.3"],"knownGene","uc001ahh.3","chr1",1592939,1677431] +[["uc001ahf.3"],"knownGene","uc001ahf.3","chr1",1592939,1624243] +[["uc001ahg.3"],"knownGene","uc001ahg.3","chr1",1592939,1624243] +[["uc001ahe.3"],"knownGene","uc001ahe.3","chr1",1592939,1601578] +[["uc009vkm.1"],"knownGene","uc009vkm.1","chr1",1601213,1671143] +[["uc009vkn.1"],"knownGene","uc009vkn.1","chr1",1601878,1624243] +[["uc001ahi.1"],"knownGene","uc001ahi.1","chr1",1631377,1633247] +[["uc009vko.1"],"knownGene","uc009vko.1","chr1",1631785,1633247] +[["uc009vkr.2"],"knownGene","uc009vkr.2","chr1",1634171,1655791] +[["uc009vks.2"],"knownGene","uc009vks.2","chr1",1634171,1655791] +[["uc009vkp.2"],"knownGene","uc009vkp.2","chr1",1634171,1640391] +[["uc009vkq.2"],"knownGene","uc009vkq.2","chr1",1634171,1640391] +[["uc001ahj.3"],"knownGene","uc001ahj.3","chr1",1634171,1639684] +[["uc010nys.1"],"knownGene","uc010nys.1","chr1",1635664,1655791] +[["uc010nyt.1"],"knownGene","uc010nyt.1","chr1",1635988,1655791] +[["uc010nyu.1"],"knownGene","uc010nyu.1","chr1",1637080,1655791] +[["uc009vkt.1"],"knownGene","uc009vkt.1","chr1",1640232,1655791] +[["uc009vku.1"],"knownGene","uc009vku.1","chr1",1640232,1655791] +[["uc009vkv.1"],"knownGene","uc009vkv.1","chr1",1640232,1655791] +[["uc001aht.1"],"knownGene","uc001aht.1","chr1",1640956,1655543] +[["uc001ahw.1"],"knownGene","uc001ahw.1","chr1",1647784,1655543] +[["uc001ahu.1"],"knownGene","uc001ahu.1","chr1",1647784,1655471] +[["uc001ahv.1"],"knownGene","uc001ahv.1","chr1",1647784,1655471] +[["uc001ahx.1"],"knownGene","uc001ahx.1","chr1",1656053,1663343] +[["uc001ahy.2"],"knownGene","uc001ahy.2","chr1",1656278,1677431] +[["uc001ahz.2"],"knownGene","uc001ahz.2","chr1",1656278,1677431] +[["uc001aia.1"],"knownGene","uc001aia.1","chr1",1658824,1662665] +[["uc001aib.1"],"knownGene","uc001aib.1","chr1",1663680,1677431] +[["uc001aie.2"],"knownGene","uc001aie.2","chr1",1682677,1711508] +[["uc001aid.3"],"knownGene","uc001aid.3","chr1",1682677,1710290] +[["uc001aic.2"],"knownGene","uc001aic.2","chr1",1682677,1709909] +[["uc009vkw.2"],"knownGene","uc009vkw.2","chr1",1682677,1709888] +[["uc010nyv.1"],"knownGene","uc010nyv.1","chr1",1682677,1690081] +[["uc009vkx.1"],"knownGene","uc009vkx.1","chr1",1685548,1696885] +[["uc001aif.2"],"knownGene","uc001aif.2","chr1",1716729,1822495] +[["uc009vky.2"],"knownGene","uc009vky.2","chr1",1716729,1822495] +[["uc001aig.1"],"knownGene","uc001aig.1","chr1",1822909,1824112] +[["uc001aih.1"],"knownGene","uc001aih.1","chr1",1846265,1848733] +[["uc001aij.2"],"knownGene","uc001aij.2","chr1",1849028,1850740] +[["uc001aii.2"],"knownGene","uc001aii.2","chr1",1849028,1850236] +[["uc001ail.2"],"knownGene","uc001ail.2","chr1",1853396,1859368] +[["uc001aik.2"],"knownGene","uc001aik.2","chr1",1853396,1858842] +[["uc001aim.1"],"knownGene","uc001aim.1","chr1",1884751,1935276] +[["uc009vkz.1"],"knownGene","uc009vkz.1","chr1",1886585,1922414] +[["uc001ain.1"],"knownGene","uc001ain.1","chr1",1915109,1935276] +[["uc001aio.1"],"knownGene","uc001aio.1","chr1",1944651,1946969] +[["uc001aip.2"],"knownGene","uc001aip.2","chr1",1950767,1962192] +[["uc001aiq.2"],"knownGene","uc001aiq.2","chr1",1981908,2116832] +[["uc001air.2"],"knownGene","uc001air.2","chr1",2005085,2116832] +[["uc010nyw.1"],"knownGene","uc010nyw.1","chr1",2005511,2116832] +[["uc001ais.2"],"knownGene","uc001ais.2","chr1",2036154,2116832] +[["uc009vla.2"],"knownGene","uc009vla.2","chr1",2075889,2116832] +[["uc010nyx.1"],"knownGene","uc010nyx.1","chr1",2076795,2116832] +[["uc009vlb.2"],"knownGene","uc009vlb.2","chr1",2076795,2088166] +[["uc001ait.2"],"knownGene","uc001ait.2","chr1",2100286,2116832] +[["uc001aiu.1"],"knownGene","uc001aiu.1","chr1",2112574,2114663] +[["uc009vlc.1"],"knownGene","uc009vlc.1","chr1",2113232,2115314] +[["uc001aix.1"],"knownGene","uc001aix.1","chr1",2115916,2139172] +[["uc001aiv.1"],"knownGene","uc001aiv.1","chr1",2115916,2126214] +[["uc001aiw.1"],"knownGene","uc001aiw.1","chr1",2115916,2126214] +[["uc001aiy.2"],"knownGene","uc001aiy.2","chr1",2120988,2126214] +[["uc001aiz.1"],"knownGene","uc001aiz.1","chr1",2121236,2123179] +[["uc001aja.3"],"knownGene","uc001aja.3","chr1",2160133,2241651] +[["uc001ajb.1"],"knownGene","uc001ajb.1","chr1",2252695,2322993] +[["uc009vld.2"],"knownGene","uc009vld.2","chr1",2263565,2322993] +[["uc001ajc.3"],"knownGene","uc001ajc.3","chr1",2281852,2284100] +[["uc001ajd.1"],"knownGene","uc001ajd.1","chr1",2286615,2322993] +[["uc010nyy.1"],"knownGene","uc010nyy.1","chr1",2309494,2322993] +[["uc001aje.1"],"knownGene","uc001aje.1","chr1",2323213,2336874] +[["uc001ajf.1"],"knownGene","uc001ajf.1","chr1",2323213,2336874] +[["uc001ajg.2"],"knownGene","uc001ajg.2","chr1",2336242,2344010] +[["uc001ajh.2"],"knownGene","uc001ajh.2","chr1",2336242,2344010] +[["uc001aji.1"],"knownGene","uc001aji.1","chr1",2407753,2436964] +[["uc001ajk.1"],"knownGene","uc001ajk.1","chr1",2411622,2436969] +[["uc001ajj.1"],"knownGene","uc001ajj.1","chr1",2411622,2436965] +[["uc009vle.1"],"knownGene","uc009vle.1","chr1",2411622,2436964] +[["uc010nyz.1"],"knownGene","uc010nyz.1","chr1",2411622,2436891] +[["uc001ajl.1"],"knownGene","uc001ajl.1","chr1",2430182,2436964] +[["uc001ajm.1"],"knownGene","uc001ajm.1","chr1",2439974,2458035] +[["uc010nza.1"],"knownGene","uc010nza.1","chr1",2439974,2458035] +[["uc001ajn.2"],"knownGene","uc001ajn.2","chr1",2460184,2461684] +[["uc001ajp.2"],"knownGene","uc001ajp.2","chr1",2481358,2484284] +[["uc001ajo.2"],"knownGene","uc001ajo.2","chr1",2481358,2484284] +[["uc001ajq.2"],"knownGene","uc001ajq.2","chr1",2481721,2484284] +[["uc010nzb.1"],"knownGene","uc010nzb.1","chr1",2483213,2488450] +[["uc001ajr.2"],"knownGene","uc001ajr.2","chr1",2487804,2495265] +[["uc001ajs.2"],"knownGene","uc001ajs.2","chr1",2487804,2495265] +[["uc001ajt.1"],"knownGene","uc001ajt.1","chr1",2487804,2495188] +[["uc009vlf.1"],"knownGene","uc009vlf.1","chr1",2487804,2492974] +[["uc010nzc.1"],"knownGene","uc010nzc.1","chr1",2487804,2490438] +[["uc001aju.1"],"knownGene","uc001aju.1","chr1",2518248,2522902] +[["uc001ajw.1"],"knownGene","uc001ajw.1","chr1",2518248,2522902] +[["uc001ajv.1"],"knownGene","uc001ajv.1","chr1",2518248,2522902] +[["uc010nzd.1"],"knownGene","uc010nzd.1","chr1",2518248,2522902] +[["uc010nze.1"],"knownGene","uc010nze.1","chr1",2518248,2522902] +[["uc010nzf.1"],"knownGene","uc010nzf.1","chr1",2518248,2522902] +[["uc001ajx.1"],"knownGene","uc001ajx.1","chr1",2518516,2522902] +[["uc001ajy.2"],"knownGene","uc001ajy.2","chr1",2522080,2564481] +[["uc009vlg.1"],"knownGene","uc009vlg.1","chr1",2522080,2560960] +[["uc001ajz.2"],"knownGene","uc001ajz.2","chr1",2938045,2939465] +[["uc001aka.2"],"knownGene","uc001aka.2","chr1",2976182,2980350] +[["uc010nzg.1"],"knownGene","uc010nzg.1","chr1",2980635,2984289] +[["uc001akc.2"],"knownGene","uc001akc.2","chr1",2985743,3355183] +[["uc001akd.2"],"knownGene","uc001akd.2","chr1",2985743,3355183] +[["uc001ake.2"],"knownGene","uc001ake.2","chr1",2985743,3355183] +[["uc001akf.2"],"knownGene","uc001akf.2","chr1",2985743,3355183] +[["uc009vlh.2"],"knownGene","uc009vlh.2","chr1",2985743,3355183] +[["uc001akg.3"],"knownGene","uc001akg.3","chr1",3371146,3397675] +[["uc001aki.2"],"knownGene","uc001aki.2","chr1",3382568,3397675] +[["uc001akj.2"],"knownGene","uc001akj.2","chr1",3383534,3397675] +[["uc010nzh.1"],"knownGene","uc010nzh.1","chr1",3388170,3397675] +[["uc009vli.1"],"knownGene","uc009vli.1","chr1",3388170,3391021] +[["uc001akl.2"],"knownGene","uc001akl.2","chr1",3404512,3528059] +[["uc001akk.2"],"knownGene","uc001akk.2","chr1",3404512,3448012] +[["uc001akm.2"],"knownGene","uc001akm.2","chr1",3541555,3546692] +[["uc009vlj.2"],"knownGene","uc009vlj.2","chr1",3541555,3546692] +[["uc001ako.2"],"knownGene","uc001ako.2","chr1",3547331,3566671] +[["uc001akn.3"],"knownGene","uc001akn.3","chr1",3547336,3566671] +[["uc010nzi.1"],"knownGene","uc010nzi.1","chr1",3548458,3566671] +[["uc001akp.2"],"knownGene","uc001akp.2","chr1",3569128,3650467] +[["uc001akq.2"],"knownGene","uc001akq.2","chr1",3569128,3650456] +[["uc001akr.2"],"knownGene","uc001akr.2","chr1",3607235,3650467] +[["uc009vlk.1"],"knownGene","uc009vlk.1","chr1",3607235,3650467] +[["uc001aks.2"],"knownGene","uc001aks.2","chr1",3607235,3650467] +[["uc010nzj.1"],"knownGene","uc010nzj.1","chr1",3607235,3646314] +[["uc010nzk.1"],"knownGene","uc010nzk.1","chr1",3614609,3650467] +[["uc009vll.2"],"knownGene","uc009vll.2","chr1",3614609,3625097] +[["uc010nzl.1"],"knownGene","uc010nzl.1","chr1",3644041,3650467] +[["uc009vlm.2"],"knownGene","uc009vlm.2","chr1",3652549,3663886] +[["uc001akt.3"],"knownGene","uc001akt.3","chr1",3652549,3663335] +[["uc001akv.2"],"knownGene","uc001akv.2","chr1",3668964,3688209] +[["uc001akw.3"],"knownGene","uc001akw.3","chr1",3689351,3692545] +[["uc001akx.1"],"knownGene","uc001akx.1","chr1",3696783,3713068] +[["uc001aky.2"],"knownGene","uc001aky.2","chr1",3728644,3773797] +[["uc010nzm.1"],"knownGene","uc010nzm.1","chr1",3728652,3773797] +[["uc001akz.2"],"knownGene","uc001akz.2","chr1",3750235,3773797] +[["uc001alc.2"],"knownGene","uc001alc.2","chr1",3773844,3801992] +[["uc001ale.2"],"knownGene","uc001ale.2","chr1",3773844,3801992] +[["uc009vlp.2"],"knownGene","uc009vlp.2","chr1",3773844,3801992] +[["uc001alb.2"],"knownGene","uc001alb.2","chr1",3773844,3801992] +[["uc010nzn.1"],"knownGene","uc010nzn.1","chr1",3773844,3801992] +[["uc009vlq.2"],"knownGene","uc009vlq.2","chr1",3773844,3801992] +[["uc009vlr.2"],"knownGene","uc009vlr.2","chr1",3773844,3801992] +[["uc001ald.2"],"knownGene","uc001ald.2","chr1",3773844,3801992] +[["uc009vlo.1"],"knownGene","uc009vlo.1","chr1",3773844,3783050] +[["uc001ala.1"],"knownGene","uc001ala.1","chr1",3773844,3782962] +[["uc009vln.1"],"knownGene","uc009vln.1","chr1",3773844,3782564] +[["uc001alf.2"],"knownGene","uc001alf.2","chr1",3805702,3816857] +[["uc009vls.2"],"knownGene","uc009vls.2","chr1",3805702,3816857] +[["uc001alh.3"],"knownGene","uc001alh.3","chr1",3816967,3833877] +[["uc001alg.2"],"knownGene","uc001alg.2","chr1",3816967,3832009] +[["uc010nzo.1"],"knownGene","uc010nzo.1","chr1",3816967,3832009] +[["uc001ali.1"],"knownGene","uc001ali.1","chr1",4000676,4015322] +[["uc001alj.2"],"knownGene","uc001alj.2","chr1",4472110,4484744] +[["uc001aln.2"],"knownGene","uc001aln.2","chr1",4715104,4843850] +[["uc001alm.1"],"knownGene","uc001alm.1","chr1",4715104,4837854] +[["uc001alo.3"],"knownGene","uc001alo.3","chr1",4847557,4852182] +[["uc001alp.1"],"knownGene","uc001alp.1","chr1",5621768,5728315] +[["uc001alq.1"],"knownGene","uc001alq.1","chr1",5922869,6052531] +[["uc001alr.1"],"knownGene","uc001alr.1","chr1",5922870,5928435] +[["uc001als.1"],"knownGene","uc001als.1","chr1",5936013,6052531] +[["uc009vlt.1"],"knownGene","uc009vlt.1","chr1",5937152,6052531] +[["uc001alt.1"],"knownGene","uc001alt.1","chr1",5937152,6052531] +[["uc009vlu.1"],"knownGene","uc009vlu.1","chr1",5946556,5965543] +[["uc009vlv.1"],"knownGene","uc009vlv.1","chr1",6052765,6160523] +[["uc001alv.1"],"knownGene","uc001alv.1","chr1",6086379,6160523] +[["uc001alw.1"],"knownGene","uc001alw.1","chr1",6086379,6160523] +[["uc001alu.2"],"knownGene","uc001alu.2","chr1",6086379,6158613] +[["uc001alx.1"],"knownGene","uc001alx.1","chr1",6094342,6160523] +[["uc001aly.1"],"knownGene","uc001aly.1","chr1",6105980,6160523] +[["uc009vlw.1"],"knownGene","uc009vlw.1","chr1",6105980,6160523] +[["uc001amb.1"],"knownGene","uc001amb.1","chr1",6161852,6240183] +[["uc001ama.1"],"knownGene","uc001ama.1","chr1",6161852,6204215] +[["uc001alz.1"],"knownGene","uc001alz.1","chr1",6161852,6191808] +[["uc001amc.1"],"knownGene","uc001amc.1","chr1",6181164,6206931] +[["uc009vlx.1"],"knownGene","uc009vlx.1","chr1",6181553,6196925] +[["uc001amd.2"],"knownGene","uc001amd.2","chr1",6245080,6259679] +[["uc001ame.2"],"knownGene","uc001ame.2","chr1",6245080,6259679] +[["uc001amg.2"],"knownGene","uc001amg.2","chr1",6266188,6281351] +[["uc001amf.1"],"knownGene","uc001amf.1","chr1",6266188,6268366] +[["uc001amh.2"],"knownGene","uc001amh.2","chr1",6268677,6270959] +[["uc010nzp.1"],"knownGene","uc010nzp.1","chr1",6268940,6278429] +[["uc001amk.2"],"knownGene","uc001amk.2","chr1",6281254,6296044] +[["uc001aml.2"],"knownGene","uc001aml.2","chr1",6281254,6296044] +[["uc001amm.2"],"knownGene","uc001amm.2","chr1",6297870,6299490] +[["uc009vly.1"],"knownGene","uc009vly.1","chr1",6304261,6305638] +[["uc001amo.1"],"knownGene","uc001amo.1","chr1",6307413,6310123] +[["uc001amp.1"],"knownGene","uc001amp.1","chr1",6308855,6321035] +[["uc001amt.2"],"knownGene","uc001amt.2","chr1",6324332,6453826] +[["uc001amu.2"],"knownGene","uc001amu.2","chr1",6324332,6453826] +[["uc001amv.2"],"knownGene","uc001amv.2","chr1",6324332,6453826] +[["uc010nzq.1"],"knownGene","uc010nzq.1","chr1",6324332,6453438] +[["uc001ams.2"],"knownGene","uc001ams.2","chr1",6324332,6445883] +[["uc001amr.2"],"knownGene","uc001amr.2","chr1",6324332,6420764] +[["uc001amq.2"],"knownGene","uc001amq.2","chr1",6324332,6419004] +[["uc001amw.2"],"knownGene","uc001amw.2","chr1",6472499,6484730] +[["uc001amx.2"],"knownGene","uc001amx.2","chr1",6475294,6479979] +[["uc001amy.2"],"knownGene","uc001amy.2","chr1",6484847,6521003] +[["uc001amz.2"],"knownGene","uc001amz.2","chr1",6508102,6521003] +[["uc001ana.2"],"knownGene","uc001ana.2","chr1",6521220,6526255] +[["uc001anb.2"],"knownGene","uc001anb.2","chr1",6521220,6526255] +[["uc001anc.2"],"knownGene","uc001anc.2","chr1",6521220,6526255] +[["uc001and.2"],"knownGene","uc001and.2","chr1",6521220,6526255] +[["uc009vlz.2"],"knownGene","uc009vlz.2","chr1",6521220,6526255] +[["uc001ane.2"],"knownGene","uc001ane.2","chr1",6521220,6526255] +[["uc001anf.2"],"knownGene","uc001anf.2","chr1",6521220,6526255] +[["uc001ang.2"],"knownGene","uc001ang.2","chr1",6521220,6526255] +[["uc001anh.2"],"knownGene","uc001anh.2","chr1",6521220,6526255] +[["uc001ani.1"],"knownGene","uc001ani.1","chr1",6524170,6526255] +[["uc001anq.1"],"knownGene","uc001anq.1","chr1",6526151,6580069] +[["uc001anp.1"],"knownGene","uc001anp.1","chr1",6526151,6580069] +[["uc001ano.1"],"knownGene","uc001ano.1","chr1",6526151,6557484] +[["uc001ann.1"],"knownGene","uc001ann.1","chr1",6526151,6556756] +[["uc001anm.1"],"knownGene","uc001anm.1","chr1",6526151,6551760] +[["uc009vmb.1"],"knownGene","uc009vmb.1","chr1",6526151,6550640] +[["uc001anl.1"],"knownGene","uc001anl.1","chr1",6526151,6550640] +[["uc001ank.1"],"knownGene","uc001ank.1","chr1",6526151,6546014] +[["uc010nzr.1"],"knownGene","uc010nzr.1","chr1",6526151,6545529] +[["uc009vma.1"],"knownGene","uc009vma.1","chr1",6526151,6537718] +[["uc001anj.1"],"knownGene","uc001anj.1","chr1",6526151,6531643] +[["uc001anr.1"],"knownGene","uc001anr.1","chr1",6527298,6529301] +[["uc001ans.2"],"knownGene","uc001ans.2","chr1",6585209,6614581] +[["uc010nzs.1"],"knownGene","uc010nzs.1","chr1",6585209,6614581] +[["uc001ant.2"],"knownGene","uc001ant.2","chr1",6615433,6639816] +[["uc001anu.2"],"knownGene","uc001anu.2","chr1",6615433,6639816] +[["uc001anv.2"],"knownGene","uc001anv.2","chr1",6615433,6639816] +[["uc001anw.2"],"knownGene","uc001anw.2","chr1",6615433,6639816] +[["uc009vmc.1"],"knownGene","uc009vmc.1","chr1",6640055,6649339] +[["uc001anx.2"],"knownGene","uc001anx.2","chr1",6640062,6649339] +[["uc009vmd.1"],"knownGene","uc009vmd.1","chr1",6640068,6649339] +[["uc001any.1"],"knownGene","uc001any.1","chr1",6645361,6649339] +[["uc001anz.1"],"knownGene","uc001anz.1","chr1",6650778,6662929] +[["uc001aoa.2"],"knownGene","uc001aoa.2","chr1",6650784,6662929] +[["uc009vme.2"],"knownGene","uc009vme.2","chr1",6650784,6659871] +[["uc001aob.3"],"knownGene","uc001aob.3","chr1",6673755,6684092] +[["uc001aoc.2"],"knownGene","uc001aoc.2","chr1",6684924,6693621] +[["uc001aoe.1"],"knownGene","uc001aoe.1","chr1",6685209,6695645] +[["uc001aod.2"],"knownGene","uc001aod.2","chr1",6685209,6693621] +[["uc001aof.2"],"knownGene","uc001aof.2","chr1",6694227,6761966] +[["uc001aog.2"],"knownGene","uc001aog.2","chr1",6694227,6761966] +[["uc010nzu.1"],"knownGene","uc010nzu.1","chr1",6694227,6761966] +[["uc010nzt.1"],"knownGene","uc010nzt.1","chr1",6694227,6741097] +[["uc001aoi.2"],"knownGene","uc001aoi.2","chr1",6845383,7829763] +[["uc001aoh.2"],"knownGene","uc001aoh.2","chr1",6845383,6932097] +[["uc010nzv.1"],"knownGene","uc010nzv.1","chr1",7732053,7805082] +[["uc001aok.3"],"knownGene","uc001aok.3","chr1",7740147,7829763] +[["uc001aoj.2"],"knownGene","uc001aoj.2","chr1",7796403,7829763] +[["uc009vmf.2"],"knownGene","uc009vmf.2","chr1",7804894,7829763] +[["uc001aol.2"],"knownGene","uc001aol.2","chr1",7831328,7841491] +[["uc001aon.2"],"knownGene","uc001aon.2","chr1",7844379,7864017] +[["uc009vmg.1"],"knownGene","uc009vmg.1","chr1",7844439,7890221] +[["uc001aoo.2"],"knownGene","uc001aoo.2","chr1",7844713,7905236] +[["uc001aop.2"],"knownGene","uc001aop.2","chr1",7844713,7905236] +[["uc010nzw.1"],"knownGene","uc010nzw.1","chr1",7844713,7905236] +[["uc009vmh.1"],"knownGene","uc009vmh.1","chr1",7844713,7890221] +[["uc001aoq.2"],"knownGene","uc001aoq.2","chr1",7903143,7973294] +[["uc001aos.2"],"knownGene","uc001aos.2","chr1",7907672,7913565] +[["uc001aor.2"],"knownGene","uc001aor.2","chr1",7907672,7913178] +[["uc001aot.2"],"knownGene","uc001aot.2","chr1",7979907,8000887] +[["uc001aou.3"],"knownGene","uc001aou.3","chr1",8021713,8045341] +[["uc001aox.3"],"knownGene","uc001aox.3","chr1",8021713,8045341] +[["uc001aov.3"],"knownGene","uc001aov.3","chr1",8021713,8045341] +[["uc001aow.3"],"knownGene","uc001aow.3","chr1",8021713,8032014] +[["uc001aoy.1"],"knownGene","uc001aoy.1","chr1",8043018,8045341] +[["uc001aoz.2"],"knownGene","uc001aoz.2","chr1",8071779,8086393] +[["uc001apa.1"],"knownGene","uc001apa.1","chr1",8073486,8075752] +[["uc001apb.2"],"knownGene","uc001apb.2","chr1",8384389,8404226] +[["uc001apc.2"],"knownGene","uc001apc.2","chr1",8390197,8404226] +[["uc001ape.2"],"knownGene","uc001ape.2","chr1",8412465,8877699] +[["uc001apf.2"],"knownGene","uc001apf.2","chr1",8412465,8877699] +[["uc001apd.2"],"knownGene","uc001apd.2","chr1",8412465,8483747] +[["uc010nzx.1"],"knownGene","uc010nzx.1","chr1",8420171,8585844] +[["uc001apg.1"],"knownGene","uc001apg.1","chr1",8440651,8441235] +[["uc001aph.1"],"knownGene","uc001aph.1","chr1",8525029,8813897] +[["uc001apj.1"],"knownGene","uc001apj.1","chr1",8921062,8938780] +[["uc001apk.1"],"knownGene","uc001apk.1","chr1",8921062,8938780] +[["uc001apl.1"],"knownGene","uc001apl.1","chr1",8921062,8938780] +[["uc009vmi.1"],"knownGene","uc009vmi.1","chr1",8921062,8938780] +[["uc009vmj.1"],"knownGene","uc009vmj.1","chr1",8921062,8938780] +[["uc009vmk.1"],"knownGene","uc009vmk.1","chr1",8921062,8938780] +[["uc001api.1"],"knownGene","uc001api.1","chr1",8921062,8931356] +[["uc009vml.1"],"knownGene","uc009vml.1","chr1",8923172,8938780] +[["uc009vmm.1"],"knownGene","uc009vmm.1","chr1",8931005,8938780] +[["uc001apm.2"],"knownGene","uc001apm.2","chr1",9005921,9035146] +[["uc009vmn.2"],"knownGene","uc009vmn.2","chr1",9005921,9035146] +[["uc009vmo.1"],"knownGene","uc009vmo.1","chr1",9063358,9086404] +[["uc010oab.1"],"knownGene","uc010oab.1","chr1",9097006,9148510] +[["uc001apo.2"],"knownGene","uc001apo.2","chr1",9097006,9129887] +[["uc010oaa.1"],"knownGene","uc010oaa.1","chr1",9097006,9129887] +[["uc010nzz.1"],"knownGene","uc010nzz.1","chr1",9097006,9129653] +[["uc010nzy.1"],"knownGene","uc010nzy.1","chr1",9097006,9109319] +[["uc001app.3"],"knownGene","uc001app.3","chr1",9101427,9129887] +[["uc010oac.1"],"knownGene","uc010oac.1","chr1",9101427,9129653] +[["uc001apq.1"],"knownGene","uc001apq.1","chr1",9164475,9189229] +[["uc010oad.1"],"knownGene","uc010oad.1","chr1",9164475,9189229] +[["uc001apr.2"],"knownGene","uc001apr.2","chr1",9169161,9189229] +[["uc001aps.2"],"knownGene","uc001aps.2","chr1",9186960,9189356] +[["uc009vmq.2"],"knownGene","uc009vmq.2","chr1",9208346,9242451] +[["uc001apt.2"],"knownGene","uc001apt.2","chr1",9294862,9331392] +[["uc010oae.1"],"knownGene","uc010oae.1","chr1",9352940,9429588] +[["uc001apv.2"],"knownGene","uc001apv.2","chr1",9415765,9429588] +[["uc001apw.2"],"knownGene","uc001apw.2","chr1",9599527,9642830] +[["uc001apx.2"],"knownGene","uc001apx.2","chr1",9599527,9642830] +[["uc001apz.2"],"knownGene","uc001apz.2","chr1",9648976,9674935] +[["uc001apy.2"],"knownGene","uc001apy.2","chr1",9648976,9665006] +[["uc001aqb.3"],"knownGene","uc001aqb.3","chr1",9711789,9789171] +[["uc001aqa.2"],"knownGene","uc001aqa.2","chr1",9711789,9775827] +[["uc001aqc.3"],"knownGene","uc001aqc.3","chr1",9712668,9714644] +[["uc001aqd.2"],"knownGene","uc001aqd.2","chr1",9732485,9747627] +[["uc010oaf.1"],"knownGene","uc010oaf.1","chr1",9751524,9789171] +[["uc001aqe.3"],"knownGene","uc001aqe.3","chr1",9770162,9789171] +[["uc001aqh.2"],"knownGene","uc001aqh.2","chr1",9789079,9884550] +[["uc001aqi.2"],"knownGene","uc001aqi.2","chr1",9789079,9884550] +[["uc010oag.1"],"knownGene","uc010oag.1","chr1",9789079,9884550] +[["uc001aqf.2"],"knownGene","uc001aqf.2","chr1",9789079,9793604] +[["uc001aqk.1"],"knownGene","uc001aqk.1","chr1",9908333,9970316] +[["uc001aql.1"],"knownGene","uc001aql.1","chr1",9908333,9970316] +[["uc009vmr.2"],"knownGene","uc009vmr.2","chr1",9989777,10003427] +[["uc010oah.1"],"knownGene","uc010oah.1","chr1",9989777,10003427] +[["uc001aqo.2"],"knownGene","uc001aqo.2","chr1",9989777,10003387] +[["uc001aqm.2"],"knownGene","uc001aqm.2","chr1",9989777,10002840] +[["uc001aqn.2"],"knownGene","uc001aqn.2","chr1",9989777,10002840] +[["uc001aqp.2"],"knownGene","uc001aqp.2","chr1",10003485,10045555] +[["uc001aqq.2"],"knownGene","uc001aqq.2","chr1",10057254,10076077] +[["uc009vms.2"],"knownGene","uc009vms.2","chr1",10057254,10076077] +[["uc001aqs.3"],"knownGene","uc001aqs.3","chr1",10093015,10241294] +[["uc001aqr.3"],"knownGene","uc001aqr.3","chr1",10093015,10241294] +[["uc010oai.1"],"knownGene","uc010oai.1","chr1",10093015,10241294] +[["uc010oaj.1"],"knownGene","uc010oaj.1","chr1",10093015,10241294] +[["uc001aqt.1"],"knownGene","uc001aqt.1","chr1",10192426,10211639] +[["uc001aqu.2"],"knownGene","uc001aqu.2","chr1",10231013,10241294] +[["uc001aqw.3"],"knownGene","uc001aqw.3","chr1",10270763,10441659] +[["uc001aqv.3"],"knownGene","uc001aqv.3","chr1",10270763,10368653] +[["uc009vmt.2"],"knownGene","uc009vmt.2","chr1",10270763,10334467] +[["uc001aqx.3"],"knownGene","uc001aqx.3","chr1",10271673,10441659] +[["uc001aqy.2"],"knownGene","uc001aqy.2","chr1",10292307,10441654] +[["uc001aqz.2"],"knownGene","uc001aqz.2","chr1",10292307,10441654] +[["uc001ara.2"],"knownGene","uc001ara.2","chr1",10292307,10441654] +[["uc001arb.2"],"knownGene","uc001arb.2","chr1",10292307,10441654] +[["uc001arc.2"],"knownGene","uc001arc.2","chr1",10459084,10480200] +[["uc001ard.2"],"knownGene","uc001ard.2","chr1",10459084,10480200] +[["uc010oak.1"],"knownGene","uc010oak.1","chr1",10459084,10480200] +[["uc010oal.1"],"knownGene","uc010oal.1","chr1",10459174,10480200] +[["uc001arf.2"],"knownGene","uc001arf.2","chr1",10490158,10512208] +[["uc001arg.2"],"knownGene","uc001arg.2","chr1",10490158,10512208] +[["uc001are.2"],"knownGene","uc001are.2","chr1",10490158,10502864] +[["uc001arh.2"],"knownGene","uc001arh.2","chr1",10490799,10502864] +[["uc001ari.2"],"knownGene","uc001ari.2","chr1",10509970,10512208] +[["uc001arj.2"],"knownGene","uc001arj.2","chr1",10520604,10532613] +[["uc001ark.2"],"knownGene","uc001ark.2","chr1",10520604,10532613] +[["uc001arn.2"],"knownGene","uc001arn.2","chr1",10535002,10690813] +[["uc009vmv.2"],"knownGene","uc009vmv.2","chr1",10535002,10690813] +[["uc010oam.1"],"knownGene","uc010oam.1","chr1",10535002,10690813] +[["uc010oan.1"],"knownGene","uc010oan.1","chr1",10535002,10690813] +[["uc009vmu.1"],"knownGene","uc009vmu.1","chr1",10535002,10683924] +[["uc001arm.1"],"knownGene","uc001arm.1","chr1",10535002,10638484] +[["uc001arl.2"],"knownGene","uc001arl.2","chr1",10535002,10580063] +[["uc009vmw.2"],"knownGene","uc009vmw.2","chr1",10588311,10690813] +[["uc001aro.2"],"knownGene","uc001aro.2","chr1",10696667,10856707] +[["uc001arp.1"],"knownGene","uc001arp.1","chr1",10707269,10856707] +[["uc009vmx.2"],"knownGene","uc009vmx.2","chr1",10713040,10754507] +[["uc001arq.1"],"knownGene","uc001arq.1","chr1",10718063,10721455] +[["uc001arr.1"],"knownGene","uc001arr.1","chr1",11006532,11024258] +[["uc010oao.1"],"knownGene","uc010oao.1","chr1",11006532,11024258] +[["uc001ars.1"],"knownGene","uc001ars.1","chr1",11006532,11024258] +[["uc001art.2"],"knownGene","uc001art.2","chr1",11072678,11085548] +[["uc010oap.1"],"knownGene","uc010oap.1","chr1",11072678,11085548] +[["uc001aru.2"],"knownGene","uc001aru.2","chr1",11086580,11107285] +[["uc001arv.2"],"knownGene","uc001arv.2","chr1",11104855,11107285] +[["uc001arw.2"],"knownGene","uc001arw.2","chr1",11104855,11107285] +[["uc001arx.1"],"knownGene","uc001arx.1","chr1",11105155,11107285] +[["uc001arz.1"],"knownGene","uc001arz.1","chr1",11114648,11120091] +[["uc001ary.1"],"knownGene","uc001ary.1","chr1",11114648,11116841] +[["uc001asa.2"],"knownGene","uc001asa.2","chr1",11126677,11159938] +[["uc001asb.2"],"knownGene","uc001asb.2","chr1",11126677,11159938] +[["uc009vmy.1"],"knownGene","uc009vmy.1","chr1",11139767,11159938] +[["uc001asd.2"],"knownGene","uc001asd.2","chr1",11166588,11322608] +[["uc001asc.2"],"knownGene","uc001asc.2","chr1",11166588,11191615] +[["uc001ase.2"],"knownGene","uc001ase.2","chr1",11249397,11256037] +[["uc001asg.2"],"knownGene","uc001asg.2","chr1",11333254,11348490] +[["uc001ash.3"],"knownGene","uc001ash.3","chr1",11539294,11597639] +[["uc009vmz.1"],"knownGene","uc009vmz.1","chr1",11539294,11541938] +[["uc001asi.1"],"knownGene","uc001asi.1","chr1",11561046,11586928] +[["uc001asj.2"],"knownGene","uc001asj.2","chr1",11708449,11714739] +[["uc009vna.2"],"knownGene","uc009vna.2","chr1",11708449,11714739] +[["uc009vnb.1"],"knownGene","uc009vnb.1","chr1",11709143,11714401] +[["uc001ask.2"],"knownGene","uc001ask.2","chr1",11714431,11723383] +[["uc001asm.2"],"knownGene","uc001asm.2","chr1",11714913,11723383] +[["uc001asl.2"],"knownGene","uc001asl.2","chr1",11714913,11723383] +[["uc001asn.2"],"knownGene","uc001asn.2","chr1",11714913,11723383] +[["uc010oar.1"],"knownGene","uc010oar.1","chr1",11714913,11723383] +[["uc010oas.1"],"knownGene","uc010oas.1","chr1",11714913,11723383] +[["uc010oaq.1"],"knownGene","uc010oaq.1","chr1",11714913,11718713] +[["uc001aso.2"],"knownGene","uc001aso.2","chr1",11724149,11734407] +[["uc009vnc.2"],"knownGene","uc009vnc.2","chr1",11734537,11751678] +[["uc001asq.3"],"knownGene","uc001asq.3","chr1",11734537,11751678] +[["uc001asp.2"],"knownGene","uc001asp.2","chr1",11734537,11741495] +[["uc001asr.1"],"knownGene","uc001asr.1","chr1",11751780,11780336] +[["uc001ass.1"],"knownGene","uc001ass.1","chr1",11782186,11785914] +[["uc001ast.2"],"knownGene","uc001ast.2","chr1",11796141,11810827] +[["uc001asu.2"],"knownGene","uc001asu.2","chr1",11796141,11810827] +[["uc001asv.2"],"knownGene","uc001asv.2","chr1",11796141,11810827] +[["uc001asw.2"],"knownGene","uc001asw.2","chr1",11796141,11810827] +[["uc001asx.2"],"knownGene","uc001asx.2","chr1",11796141,11810827] +[["uc001asy.1"],"knownGene","uc001asy.1","chr1",11824461,11826573] +[["uc001asz.2"],"knownGene","uc001asz.2","chr1",11832138,11849641] +[["uc001ata.2"],"knownGene","uc001ata.2","chr1",11839858,11849641] +[["uc001atc.1"],"knownGene","uc001atc.1","chr1",11845786,11866115] +[["uc001atb.1"],"knownGene","uc001atb.1","chr1",11845786,11863440] +[["uc001atd.1"],"knownGene","uc001atd.1","chr1",11862937,11865470] +[["uc009vnd.1"],"knownGene","uc009vnd.1","chr1",11862937,11865470] +[["uc001ate.3"],"knownGene","uc001ate.3","chr1",11866206,11903200] +[["uc010oat.1"],"knownGene","uc010oat.1","chr1",11866206,11903200] +[["uc010oau.1"],"knownGene","uc010oau.1","chr1",11866206,11903200] +[["uc009vnh.1"],"knownGene","uc009vnh.1","chr1",11866206,11889379] +[["uc009vnf.1"],"knownGene","uc009vnf.1","chr1",11866206,11888276] +[["uc009vng.1"],"knownGene","uc009vng.1","chr1",11866206,11888276] +[["uc009vne.1"],"knownGene","uc009vne.1","chr1",11866206,11876844] +[["uc010oav.1"],"knownGene","uc010oav.1","chr1",11900375,11907674] +[["uc010oaw.1"],"knownGene","uc010oaw.1","chr1",11900375,11907674] +[["uc010oax.1"],"knownGene","uc010oax.1","chr1",11900375,11907674] +[["uc010oay.1"],"knownGene","uc010oay.1","chr1",11900375,11907674] +[["uc010oaz.1"],"knownGene","uc010oaz.1","chr1",11900375,11907674] +[["uc010oba.1"],"knownGene","uc010oba.1","chr1",11900375,11907674] +[["uc001ati.2"],"knownGene","uc001ati.2","chr1",11905768,11907840] +[["uc001atj.2"],"knownGene","uc001atj.2","chr1",11917521,11918992] +[["uc001atk.2"],"knownGene","uc001atk.2","chr1",11980123,11986480] +[["uc001atl.1"],"knownGene","uc001atl.1","chr1",11982231,11986480] +[["uc001atm.2"],"knownGene","uc001atm.2","chr1",11994745,12035593] +[["uc010obb.1"],"knownGene","uc010obb.1","chr1",11994745,12035593] +[["uc001atn.3"],"knownGene","uc001atn.3","chr1",12040237,12073571] +[["uc009vni.2"],"knownGene","uc009vni.2","chr1",12040237,12073571] +[["uc001ato.1"],"knownGene","uc001ato.1","chr1",12079511,12092106] +[["uc001atq.2"],"knownGene","uc001atq.2","chr1",12123433,12204262] +[["uc010obc.1"],"knownGene","uc010obc.1","chr1",12123433,12204262] +[["uc001atr.2"],"knownGene","uc001atr.2","chr1",12185957,12204262] +[["uc001ats.2"],"knownGene","uc001ats.2","chr1",12185957,12204262] +[["uc001att.2"],"knownGene","uc001att.2","chr1",12227059,12269276] +[["uc001atu.2"],"knownGene","uc001atu.2","chr1",12227059,12269276] +[["uc009vnk.2"],"knownGene","uc009vnk.2","chr1",12227059,12269276] +[["uc001atv.2"],"knownGene","uc001atv.2","chr1",12290112,12572096] +[["uc001atw.2"],"knownGene","uc001atw.2","chr1",12290112,12572096] +[["uc001atx.2"],"knownGene","uc001atx.2","chr1",12335881,12572096] +[["uc001aty.1"],"knownGene","uc001aty.1","chr1",12371510,12398045] +[["uc009vnl.2"],"knownGene","uc009vnl.2","chr1",12427724,12572096] +[["uc010obd.1"],"knownGene","uc010obd.1","chr1",12469883,12572096] +[["uc001atz.1"],"knownGene","uc001atz.1","chr1",12567299,12567451] +[["uc001auc.2"],"knownGene","uc001auc.2","chr1",12627939,12677820] +[["uc001aub.2"],"knownGene","uc001aub.2","chr1",12627939,12676788] +[["uc009vnm.2"],"knownGene","uc009vnm.2","chr1",12638984,12677820] +[["uc001aud.3"],"knownGene","uc001aud.3","chr1",12640134,12677820] +[["uc001aue.1"],"knownGene","uc001aue.1","chr1",12640550,12656106] +[["uc001auf.2"],"knownGene","uc001auf.2","chr1",12704565,12727096] +[["uc009vnn.1"],"knownGene","uc009vnn.1","chr1",12776117,12788726] +[["uc001aug.1"],"knownGene","uc001aug.1","chr1",12776117,12788726] +[["uc001auh.2"],"knownGene","uc001auh.2","chr1",12806162,12821101] +[["uc010obe.1"],"knownGene","uc010obe.1","chr1",12806162,12819698] +[["uc001aui.2"],"knownGene","uc001aui.2","chr1",12834983,12838046] +[["uc001auj.1"],"knownGene","uc001auj.1","chr1",12851545,12856223] +[["uc001auk.2"],"knownGene","uc001auk.2","chr1",12884467,12891264] +[["uc009vno.2"],"knownGene","uc009vno.2","chr1",12907235,12908237] +[["uc010obf.1"],"knownGene","uc010obf.1","chr1",12907262,12908578] +[["uc001aum.1"],"knownGene","uc001aum.1","chr1",12916940,12921764] +[["uc001aun.2"],"knownGene","uc001aun.2","chr1",12939032,12946025] +[["uc001auo.2"],"knownGene","uc001auo.2","chr1",12952727,12958094] +[["uc001aup.2"],"knownGene","uc001aup.2","chr1",12976449,12980566] +[["uc001aur.2"],"knownGene","uc001aur.2","chr1",12998301,13117751] +[["uc001auq.2"],"knownGene","uc001auq.2","chr1",12998301,13007406] +[["uc009vnq.1"],"knownGene","uc009vnq.1","chr1",13035542,13038381] +[["uc001aus.1"],"knownGene","uc001aus.1","chr1",13108513,13117751] +[["uc010obg.1"],"knownGene","uc010obg.1","chr1",13182960,13183967] +[["uc001aut.1"],"knownGene","uc001aut.1","chr1",13328195,13331692] +[["uc001auu.1"],"knownGene","uc001auu.1","chr1",13359818,13369057] +[["uc001auv.2"],"knownGene","uc001auv.2","chr1",13386648,13390765] +[["uc010obh.1"],"knownGene","uc010obh.1","chr1",13386648,13389770] +[["uc001auw.1"],"knownGene","uc001auw.1","chr1",13421175,13428191] +[["uc009vnt.1"],"knownGene","uc009vnt.1","chr1",13447413,13452656] +[["uc010obi.1"],"knownGene","uc010obi.1","chr1",13447413,13452656] +[["uc009vnu.1"],"knownGene","uc009vnu.1","chr1",13474052,13477569] +[["uc001aux.2"],"knownGene","uc001aux.2","chr1",13495253,13498257] +[["uc009vnv.1"],"knownGene","uc009vnv.1","chr1",13516065,13526943] +[["uc001auy.2"],"knownGene","uc001auy.2","chr1",13607430,13611550] +[["uc001auz.3"],"knownGene","uc001auz.3","chr1",13629937,13635298] +[["uc001ava.1"],"knownGene","uc001ava.1","chr1",13641972,13648988] +[["uc009vnw.1"],"knownGene","uc009vnw.1","chr1",13668268,13673511] +[["uc009vny.1"],"knownGene","uc009vny.1","chr1",13694888,13698405] +[["uc009vnz.1"],"knownGene","uc009vnz.1","chr1",13716087,13719064] +[["uc009voa.1"],"knownGene","uc009voa.1","chr1",13736906,13747803] +[["uc001avb.2"],"knownGene","uc001avb.2","chr1",13801446,13840242] +[["uc001avc.2"],"knownGene","uc001avc.2","chr1",13910251,13944450] +[["uc001avd.2"],"knownGene","uc001avd.2","chr1",13910251,13944450] +[["uc009vob.2"],"knownGene","uc009vob.2","chr1",13910761,13944450] +[["uc009voc.2"],"knownGene","uc009voc.2","chr1",13910761,13944450] +[["uc001ave.2"],"knownGene","uc001ave.2","chr1",13911966,13944450] +[["uc001avf.2"],"knownGene","uc001avf.2","chr1",13911966,13944450] +[["uc001avg.2"],"knownGene","uc001avg.2","chr1",14026734,14151572] +[["uc001avi.2"],"knownGene","uc001avi.2","chr1",14031349,14151572] +[["uc001avh.2"],"knownGene","uc001avh.2","chr1",14031349,14114573] +[["uc001avj.2"],"knownGene","uc001avj.2","chr1",14057494,14114573] +[["uc009voe.2"],"knownGene","uc009voe.2","chr1",14075855,14151572] +[["uc009vof.2"],"knownGene","uc009vof.2","chr1",14075855,14151572] +[["uc001avk.2"],"knownGene","uc001avk.2","chr1",14075855,14114573] +[["uc009vod.1"],"knownGene","uc009vod.1","chr1",14075855,14106820] +[["uc001avl.1"],"knownGene","uc001avl.1","chr1",14146461,14150513] +[["uc001avm.3"],"knownGene","uc001avm.3","chr1",14925212,15444543] +[["uc009vog.1"],"knownGene","uc009vog.1","chr1",14925212,15394651] +[["uc010obj.1"],"knownGene","uc010obj.1","chr1",14925212,15394651] +[["uc001avo.2"],"knownGene","uc001avo.2","chr1",15250624,15394651] +[["uc001avp.2"],"knownGene","uc001avp.2","chr1",15256295,15394651] +[["uc001avq.2"],"knownGene","uc001avq.2","chr1",15272414,15394651] +[["uc001avr.2"],"knownGene","uc001avr.2","chr1",15287179,15394651] +[["uc001avs.3"],"knownGene","uc001avs.3","chr1",15427703,15444543] +[["uc001avv.3"],"knownGene","uc001avv.3","chr1",15438311,15478960] +[["uc009voh.2"],"knownGene","uc009voh.2","chr1",15438311,15478960] +[["uc001avw.3"],"knownGene","uc001avw.3","chr1",15479027,15546973] +[["uc010obk.1"],"knownGene","uc010obk.1","chr1",15479027,15546973] +[["uc001avy.2"],"knownGene","uc001avy.2","chr1",15480228,15546973] +[["uc001avx.2"],"knownGene","uc001avx.2","chr1",15480228,15546973] +[["uc001avz.2"],"knownGene","uc001avz.2","chr1",15480228,15546872] +[["uc001awb.2"],"knownGene","uc001awb.2","chr1",15573767,15724622] +[["uc001awa.1"],"knownGene","uc001awa.1","chr1",15573767,15672019] +[["uc001awc.1"],"knownGene","uc001awc.1","chr1",15653175,15670372] +[["uc001awd.1"],"knownGene","uc001awd.1","chr1",15668231,15711054] +[["uc010obl.1"],"knownGene","uc010obl.1","chr1",15671578,15724622] +[["uc001awe.1"],"knownGene","uc001awe.1","chr1",15671911,15724622] +[["uc001awf.2"],"knownGene","uc001awf.2","chr1",15684286,15690810] +[["uc001awg.2"],"knownGene","uc001awg.2","chr1",15707196,15726776] +[["uc001awh.2"],"knownGene","uc001awh.2","chr1",15736390,15756839] +[["uc001awi.1"],"knownGene","uc001awi.1","chr1",15764937,15773153] +[["uc001awj.1"],"knownGene","uc001awj.1","chr1",15764937,15773153] +[["uc001awk.2"],"knownGene","uc001awk.2","chr1",15783222,15798585] +[["uc001awl.2"],"knownGene","uc001awl.2","chr1",15802595,15817894] +[["uc001awm.1"],"knownGene","uc001awm.1","chr1",15817323,15850790] +[["uc001awq.2"],"knownGene","uc001awq.2","chr1",15818796,15851384] +[["uc010obm.1"],"knownGene","uc010obm.1","chr1",15818796,15851221] +[["uc001awn.2"],"knownGene","uc001awn.2","chr1",15818796,15850790] +[["uc001awo.2"],"knownGene","uc001awo.2","chr1",15818796,15850790] +[["uc001awp.2"],"knownGene","uc001awp.2","chr1",15818796,15850790] +[["uc009voi.2"],"knownGene","uc009voi.2","chr1",15818796,15850790] +[["uc001aws.2"],"knownGene","uc001aws.2","chr1",15853351,15898226] +[["uc001awt.2"],"knownGene","uc001awt.2","chr1",15853351,15898226] +[["uc001awr.1"],"knownGene","uc001awr.1","chr1",15853351,15893091] +[["uc001awu.2"],"knownGene","uc001awu.2","chr1",15886020,15918872] +[["uc001awv.1"],"knownGene","uc001awv.1","chr1",15899151,15911605] +[["uc001awx.1"],"knownGene","uc001awx.1","chr1",15944069,15986748] +[["uc001aww.2"],"knownGene","uc001aww.2","chr1",15944069,15960794] +[["uc009voj.1"],"knownGene","uc009voj.1","chr1",15956819,15986748] +[["uc010obn.1"],"knownGene","uc010obn.1","chr1",15986363,15988216] +[["uc001awz.2"],"knownGene","uc001awz.2","chr1",15992765,15995535] +[["uc010obo.1"],"knownGene","uc010obo.1","chr1",16010826,16061262] +[["uc001axb.1"],"knownGene","uc001axb.1","chr1",16062808,16067884] +[["uc009vok.1"],"knownGene","uc009vok.1","chr1",16065739,16067885] +[["uc001axc.2"],"knownGene","uc001axc.2","chr1",16068916,16074475] +[["uc001axd.1"],"knownGene","uc001axd.1","chr1",16083153,16113084] +[["uc001axf.2"],"knownGene","uc001axf.2","chr1",16085254,16114431] +[["uc001axe.1"],"knownGene","uc001axe.1","chr1",16085254,16113084] +[["uc001axg.1"],"knownGene","uc001axg.1","chr1",16090990,16101715] +[["uc001axh.1"],"knownGene","uc001axh.1","chr1",16091029,16113084] +[["uc001axi.1"],"knownGene","uc001axi.1","chr1",16091458,16113084] +[["uc009vol.1"],"knownGene","uc009vol.1","chr1",16133656,16134194] +[["uc001axj.2"],"knownGene","uc001axj.2","chr1",16160709,16174642] +[["uc001axk.1"],"knownGene","uc001axk.1","chr1",16174358,16266950] +[["uc010obp.1"],"knownGene","uc010obp.1","chr1",16200609,16266950] +[["uc001axl.3"],"knownGene","uc001axl.3","chr1",16268365,16302627] +[["uc010obq.1"],"knownGene","uc010obq.1","chr1",16268365,16302627] +[["uc010obr.1"],"knownGene","uc010obr.1","chr1",16268365,16302627] +[["uc010obs.1"],"knownGene","uc010obs.1","chr1",16268365,16302627] +[["uc010obt.1"],"knownGene","uc010obt.1","chr1",16270321,16302627] +[["uc010obu.1"],"knownGene","uc010obu.1","chr1",16270365,16302627] +[["uc009vom.1"],"knownGene","uc009vom.1","chr1",16271431,16302627] +[["uc010obv.1"],"knownGene","uc010obv.1","chr1",16272256,16302627] +[["uc009von.1"],"knownGene","uc009von.1","chr1",16274237,16302627] +[["uc001axm.1"],"knownGene","uc001axm.1","chr1",16317618,16317647] +[["uc001axn.2"],"knownGene","uc001axn.2","chr1",16330730,16333180] +[["uc001axs.2"],"knownGene","uc001axs.2","chr1",16340522,16346089] +[["uc001axo.2"],"knownGene","uc001axo.2","chr1",16340522,16345285] +[["uc001axp.2"],"knownGene","uc001axp.2","chr1",16340522,16345285] +[["uc001axq.2"],"knownGene","uc001axq.2","chr1",16340522,16345285] +[["uc001axr.2"],"knownGene","uc001axr.2","chr1",16340522,16345285] +[["uc001axt.2"],"knownGene","uc001axt.2","chr1",16345369,16360544] +[["uc001axw.3"],"knownGene","uc001axw.3","chr1",16348485,16383802] +[["uc001axu.2"],"knownGene","uc001axu.2","chr1",16348485,16360544] +[["uc001axv.2"],"knownGene","uc001axv.2","chr1",16348485,16360544] +[["uc010obw.1"],"knownGene","uc010obw.1","chr1",16348485,16360544] +[["uc010oby.1"],"knownGene","uc010oby.1","chr1",16355006,16358786] +[["uc010obx.1"],"knownGene","uc010obx.1","chr1",16355006,16357169] +[["uc010obz.1"],"knownGene","uc010obz.1","chr1",16361813,16400127] +[["uc001axx.3"],"knownGene","uc001axx.3","chr1",16370246,16383802] +[["uc001axy.3"],"knownGene","uc001axy.3","chr1",16375283,16383802] +[["uc001axz.3"],"knownGene","uc001axz.3","chr1",16384264,16400127] +[["uc001aya.1"],"knownGene","uc001aya.1","chr1",16450831,16482564] +[["uc010oca.1"],"knownGene","uc010oca.1","chr1",16462083,16482564] +[["uc001ayc.1"],"knownGene","uc001ayc.1","chr1",16524598,16539104] +[["uc009voo.1"],"knownGene","uc009voo.1","chr1",16524598,16533705] +[["uc001ayb.1"],"knownGene","uc001ayb.1","chr1",16524598,16533705] +[["uc001ayd.2"],"knownGene","uc001ayd.2","chr1",16558182,16563659] +[["uc001ayg.2"],"knownGene","uc001ayg.2","chr1",16576559,16678948] +[["uc001ayf.2"],"knownGene","uc001ayf.2","chr1",16576559,16643088] +[["uc001aye.3"],"knownGene","uc001aye.3","chr1",16576559,16580226] +[["uc001ayh.2"],"knownGene","uc001ayh.2","chr1",16618833,16641930] +[["uc001aym.3"],"knownGene","uc001aym.3","chr1",16693582,16724639] +[["uc001ayi.3"],"knownGene","uc001ayi.3","chr1",16693582,16724639] +[["uc001ayk.3"],"knownGene","uc001ayk.3","chr1",16693582,16724639] +[["uc010ocb.1"],"knownGene","uc010ocb.1","chr1",16693582,16722607] +[["uc001ayl.1"],"knownGene","uc001ayl.1","chr1",16722175,16763919] +[["uc001ayn.2"],"knownGene","uc001ayn.2","chr1",16725138,16763919] +[["uc010occ.1"],"knownGene","uc010occ.1","chr1",16725138,16763919] +[["uc001ayo.2"],"knownGene","uc001ayo.2","chr1",16767166,16786582] +[["uc010ocd.1"],"knownGene","uc010ocd.1","chr1",16767166,16786582] +[["uc001ayq.2"],"knownGene","uc001ayq.2","chr1",16767166,16786582] +[["uc001ayp.3"],"knownGene","uc001ayp.3","chr1",16767166,16786572] +[["uc001ayt.2"],"knownGene","uc001ayt.2","chr1",16793930,16819196] +[["uc001ayr.3"],"knownGene","uc001ayr.3","chr1",16795417,16803569] +[["uc001ays.2"],"knownGene","uc001ays.2","chr1",16804749,16817579] +[["uc009voq.1"],"knownGene","uc009voq.1","chr1",16860385,16863483] +[["uc001ayv.1"],"knownGene","uc001ayv.1","chr1",16862254,16864669] +[["uc001ayw.2"],"knownGene","uc001ayw.2","chr1",16888922,16890082] +[["uc009vos.1"],"knownGene","uc009vos.1","chr1",16890411,16939982] +[["uc009vot.1"],"knownGene","uc009vot.1","chr1",16892902,16913756] +[["uc001ayz.1"],"knownGene","uc001ayz.1","chr1",16892902,16913756] +[["uc010oce.1"],"knownGene","uc010oce.1","chr1",16893673,16918808] +[["uc001aza.3"],"knownGene","uc001aza.3","chr1",16926097,16939982] +[["uc001azc.1"],"knownGene","uc001azc.1","chr1",16931912,16939982] +[["uc001azb.1"],"knownGene","uc001azb.1","chr1",16931912,16939752] +[["uc009vov.1"],"knownGene","uc009vov.1","chr1",16944752,16957604] +[["uc001aze.2"],"knownGene","uc001aze.2","chr1",16944752,16957604] +[["uc010ocf.1"],"knownGene","uc010ocf.1","chr1",16944752,16952994] +[["uc001azf.2"],"knownGene","uc001azf.2","chr1",16944757,16959841] +[["uc001azg.1"],"knownGene","uc001azg.1","chr1",16951872,16971178] +[["uc001azi.1"],"knownGene","uc001azi.1","chr1",16956164,16971178] +[["uc001azj.1"],"knownGene","uc001azj.1","chr1",16959589,16969640] +[["uc010och.1"],"knownGene","uc010och.1","chr1",16972068,16976914] +[["uc009vow.2"],"knownGene","uc009vow.2","chr1",16972068,16974587] +[["uc010ocg.1"],"knownGene","uc010ocg.1","chr1",16972068,16974587] +[["uc001azl.3"],"knownGene","uc001azl.3","chr1",16972863,16976914] +[["uc001azk.2"],"knownGene","uc001azk.2","chr1",16972863,16975287] +[["uc010oci.1"],"knownGene","uc010oci.1","chr1",16972863,16974587] +[["uc009vox.2"],"knownGene","uc009vox.2","chr1",16973907,16976914] +[["uc001azm.3"],"knownGene","uc001azm.3","chr1",16973907,16976914] +[["uc001azn.1"],"knownGene","uc001azn.1","chr1",17017712,17046652] +[["uc010ocj.1"],"knownGene","uc010ocj.1","chr1",17033418,17037114] +[["uc009voy.1"],"knownGene","uc009voy.1","chr1",17066767,17267729] +[["uc010ock.1"],"knownGene","uc010ock.1","chr1",17081401,17090975] +[["uc001azp.3"],"knownGene","uc001azp.3","chr1",17081401,17086552] +[["uc001azs.1"],"knownGene","uc001azs.1","chr1",17215040,17216161] +[["uc001azt.2"],"knownGene","uc001azt.2","chr1",17248444,17299474] +[["uc009voz.1"],"knownGene","uc009voz.1","chr1",17249157,17280852] +[["uc001azu.2"],"knownGene","uc001azu.2","chr1",17266388,17299474] +[["uc001azv.2"],"knownGene","uc001azv.2","chr1",17294697,17299474] +[["uc001azy.2"],"knownGene","uc001azy.2","chr1",17300999,17308081] +[["uc010ocl.1"],"knownGene","uc010ocl.1","chr1",17300999,17308081] +[["uc001azw.2"],"knownGene","uc001azw.2","chr1",17300999,17307173] +[["uc001azx.2"],"knownGene","uc001azx.2","chr1",17300999,17307173] +[["uc001baa.2"],"knownGene","uc001baa.2","chr1",17312452,17338423] +[["uc001bab.2"],"knownGene","uc001bab.2","chr1",17312452,17338423] +[["uc001bac.2"],"knownGene","uc001bac.2","chr1",17312452,17338423] +[["uc001azz.1"],"knownGene","uc001azz.1","chr1",17312452,17316498] +[["uc001bad.1"],"knownGene","uc001bad.1","chr1",17321981,17327342] +[["uc009vpa.1"],"knownGene","uc009vpa.1","chr1",17321981,17326807] +[["uc001bae.2"],"knownGene","uc001bae.2","chr1",17345226,17380665] +[["uc001baf.2"],"knownGene","uc001baf.2","chr1",17393256,17445948] +[["uc010ocm.1"],"knownGene","uc010ocm.1","chr1",17393256,17445948] +[["uc001bag.1"],"knownGene","uc001bag.1","chr1",17405525,17445948] +[["uc010ocn.1"],"knownGene","uc010ocn.1","chr1",17439786,17439808] +[["uc001bah.1"],"knownGene","uc001bah.1","chr1",17531620,17572501] +[["uc010oco.1"],"knownGene","uc010oco.1","chr1",17559775,17572501] +[["uc010ocp.1"],"knownGene","uc010ocp.1","chr1",17559775,17572501] +[["uc010ocq.1"],"knownGene","uc010ocq.1","chr1",17559775,17572501] +[["uc009vpb.1"],"knownGene","uc009vpb.1","chr1",17566189,17572501] +[["uc001bai.2"],"knownGene","uc001bai.2","chr1",17575592,17610725] +[["uc001baj.2"],"knownGene","uc001baj.2","chr1",17634689,17690495] +[["uc009vpc.2"],"knownGene","uc009vpc.2","chr1",17634689,17674911] +[["uc001bak.1"],"knownGene","uc001bak.1","chr1",17698740,17728195] +[["uc001bam.2"],"knownGene","uc001bam.2","chr1",17733251,17766220] +[["uc001bal.2"],"knownGene","uc001bal.2","chr1",17733251,17765057] +[["uc001ban.2"],"knownGene","uc001ban.2","chr1",17866329,18024369] +[["uc009vpe.1"],"knownGene","uc009vpe.1","chr1",17866329,18016673] +[["uc001bao.2"],"knownGene","uc001bao.2","chr1",17907047,18024369] +[["uc001bap.2"],"knownGene","uc001bap.2","chr1",17907047,18024369] +[["uc010ocr.1"],"knownGene","uc010ocr.1","chr1",17914910,17966476] +[["uc001baq.2"],"knownGene","uc001baq.2","chr1",17941582,18024369] +[["uc010ocs.1"],"knownGene","uc010ocs.1","chr1",17944810,18024369] +[["uc001bar.2"],"knownGene","uc001bar.2","chr1",17944810,18024369] +[["uc009vpf.2"],"knownGene","uc009vpf.2","chr1",17952450,18024369] +[["uc001bas.2"],"knownGene","uc001bas.2","chr1",18020541,18024369] +[["uc001bat.2"],"knownGene","uc001bat.2","chr1",18081807,18153556] +[["uc001bau.1"],"knownGene","uc001bau.1","chr1",18434239,18704976] +[["uc001bav.1"],"knownGene","uc001bav.1","chr1",18687860,18704976] +[["uc001baw.1"],"knownGene","uc001baw.1","chr1",18701063,18702174] +[["uc001bax.2"],"knownGene","uc001bax.2","chr1",18807423,18812478] +[["uc009vpg.2"],"knownGene","uc009vpg.2","chr1",18807664,18812539] +[["uc010oct.1"],"knownGene","uc010oct.1","chr1",18957499,19075359] +[["uc001bay.2"],"knownGene","uc001bay.2","chr1",18957499,19062631] +[["uc001baz.2"],"knownGene","uc001baz.2","chr1",18957499,19062631] +[["uc001bba.1"],"knownGene","uc001bba.1","chr1",19166092,19186155] +[["uc001bbb.2"],"knownGene","uc001bbb.2","chr1",19197925,19229293] +[["uc001bbc.2"],"knownGene","uc001bbc.2","chr1",19197925,19229293] +[["uc010ocu.1"],"knownGene","uc010ocu.1","chr1",19197925,19217385] +[["uc001bbd.2"],"knownGene","uc001bbd.2","chr1",19230773,19282826] +[["uc001bbe.1"],"knownGene","uc001bbe.1","chr1",19398603,19402005] +[["uc001bbi.2"],"knownGene","uc001bbi.2","chr1",19401001,19536746] +[["uc001bbh.2"],"knownGene","uc001bbh.2","chr1",19401001,19432336] +[["uc001bbg.2"],"knownGene","uc001bbg.2","chr1",19401001,19431410] +[["uc010ocw.1"],"knownGene","uc010ocw.1","chr1",19401001,19428129] +[["uc009vph.2"],"knownGene","uc009vph.2","chr1",19401001,19427067] +[["uc010ocv.1"],"knownGene","uc010ocv.1","chr1",19401001,19426171] +[["uc001bbf.2"],"knownGene","uc001bbf.2","chr1",19401001,19408140] +[["uc001bbj.1"],"knownGene","uc001bbj.1","chr1",19438133,19444474] +[["uc001bbk.1"],"knownGene","uc001bbk.1","chr1",19447682,19478353] +[["uc001bbm.1"],"knownGene","uc001bbm.1","chr1",19477417,19505714] +[["uc001bbl.1"],"knownGene","uc001bbl.1","chr1",19477417,19483419] +[["uc001bbo.2"],"knownGene","uc001bbo.2","chr1",19544584,19578046] +[["uc001bbp.2"],"knownGene","uc001bbp.2","chr1",19544584,19578046] +[["uc001bbq.2"],"knownGene","uc001bbq.2","chr1",19544584,19578046] +[["uc001bbr.2"],"knownGene","uc001bbr.2","chr1",19544584,19578046] +[["uc001bbn.2"],"knownGene","uc001bbn.2","chr1",19544584,19548410] +[["uc001bbs.2"],"knownGene","uc001bbs.2","chr1",19578074,19586621] +[["uc010ocx.1"],"knownGene","uc010ocx.1","chr1",19592475,19600568] +[["uc010ocy.1"],"knownGene","uc010ocy.1","chr1",19592475,19600568] +[["uc001bbv.1"],"knownGene","uc001bbv.1","chr1",19609056,19615280] +[["uc001bbw.2"],"knownGene","uc001bbw.2","chr1",19630458,19638640] +[["uc001bbx.2"],"knownGene","uc001bbx.2","chr1",19630458,19638640] +[["uc009vpi.1"],"knownGene","uc009vpi.1","chr1",19634232,19638640] +[["uc001bby.2"],"knownGene","uc001bby.2","chr1",19638739,19655793] +[["uc001bbz.2"],"knownGene","uc001bbz.2","chr1",19638739,19655793] +[["uc001bca.2"],"knownGene","uc001bca.2","chr1",19638739,19655793] +[["uc001bcb.2"],"knownGene","uc001bcb.2","chr1",19638739,19655793] +[["uc001bcc.2"],"knownGene","uc001bcc.2","chr1",19639222,19655793] +[["uc001bce.2"],"knownGene","uc001bce.2","chr1",19665273,19811992] +[["uc009vpk.2"],"knownGene","uc009vpk.2","chr1",19665273,19811992] +[["uc010ocz.1"],"knownGene","uc010ocz.1","chr1",19665273,19811201] +[["uc001bcd.2"],"knownGene","uc001bcd.2","chr1",19665273,19746253] +[["uc001bcf.1"],"knownGene","uc001bcf.1","chr1",19673334,19675427] +[["uc009vpl.1"],"knownGene","uc009vpl.1","chr1",19923466,19984945] +[["uc001bci.1"],"knownGene","uc001bci.1","chr1",19923466,19955174] +[["uc001bch.1"],"knownGene","uc001bch.1","chr1",19923466,19954804] +[["uc001bcj.1"],"knownGene","uc001bcj.1","chr1",19969725,19984945] +[["uc009vpm.1"],"knownGene","uc009vpm.1","chr1",19970248,19984945] +[["uc001bck.1"],"knownGene","uc001bck.1","chr1",19970807,19984945] +[["uc001bcl.2"],"knownGene","uc001bcl.2","chr1",19991779,20006054] +[["uc001bcn.2"],"knownGene","uc001bcn.2","chr1",20008706,20126410] +[["uc001bcm.2"],"knownGene","uc001bcm.2","chr1",20008706,20107259] +[["uc001bco.1"],"knownGene","uc001bco.1","chr1",20008734,20125837] +[["uc001bcp.1"],"knownGene","uc001bcp.1","chr1",20008734,20125837] +[["uc009vpn.1"],"knownGene","uc009vpn.1","chr1",20071536,20125837] +[["uc001bcq.1"],"knownGene","uc001bcq.1","chr1",20072024,20126758] +[["uc001bcr.2"],"knownGene","uc001bcr.2","chr1",20140522,20141771] +[["uc001bcs.3"],"knownGene","uc001bcs.3","chr1",20208887,20239429] +[["uc001bct.1"],"knownGene","uc001bct.1","chr1",20246799,20250110] +[["uc001bcv.2"],"knownGene","uc001bcv.2","chr1",20301924,20306932] +[["uc010oda.1"],"knownGene","uc010oda.1","chr1",20301924,20306932] +[["uc010odb.1"],"knownGene","uc010odb.1","chr1",20301924,20306932] +[["uc001bcu.2"],"knownGene","uc001bcu.2","chr1",20301924,20306152] +[["uc001bcw.2"],"knownGene","uc001bcw.2","chr1",20354671,20418393] +[["uc001bcx.2"],"knownGene","uc001bcx.2","chr1",20354671,20418393] +[["uc001bcy.2"],"knownGene","uc001bcy.2","chr1",20396700,20418393] +[["uc001bcz.2"],"knownGene","uc001bcz.2","chr1",20438440,20446008] +[["uc009vpo.2"],"knownGene","uc009vpo.2","chr1",20438440,20446008] +[["uc009vpp.1"],"knownGene","uc009vpp.1","chr1",20465822,20476879] +[["uc009vpq.1"],"knownGene","uc009vpq.1","chr1",20490483,20501687] +[["uc001bdb.2"],"knownGene","uc001bdb.2","chr1",20512577,20519941] +[["uc009vps.2"],"knownGene","uc009vps.2","chr1",20617411,20681387] +[["uc010odc.1"],"knownGene","uc010odc.1","chr1",20617411,20681387] +[["uc001bdd.2"],"knownGene","uc001bdd.2","chr1",20617411,20665715] +[["uc001bde.3"],"knownGene","uc001bde.3","chr1",20659258,20681387] +[["uc009vpt.2"],"knownGene","uc009vpt.2","chr1",20659258,20681387] +[["uc001bdf.1"],"knownGene","uc001bdf.1","chr1",20687597,20755275] +[["uc009vpu.1"],"knownGene","uc009vpu.1","chr1",20687597,20732187] +[["uc001bdh.2"],"knownGene","uc001bdh.2","chr1",20808884,20812728] +[["uc001bdg.2"],"knownGene","uc001bdg.2","chr1",20808884,20811138] +[["uc001bdi.3"],"knownGene","uc001bdi.3","chr1",20825942,20834674] +[["uc001bdj.2"],"knownGene","uc001bdj.2","chr1",20878931,20881512] +[["uc001bdk.2"],"knownGene","uc001bdk.2","chr1",20915443,20945398] +[["uc001bdl.2"],"knownGene","uc001bdl.2","chr1",20915443,20945398] +[["uc009vpv.2"],"knownGene","uc009vpv.2","chr1",20915443,20945398] +[["uc001bdm.2"],"knownGene","uc001bdm.2","chr1",20959947,20978003] +[["uc001bdn.2"],"knownGene","uc001bdn.2","chr1",20972000,20978003] +[["uc001bdo.1"],"knownGene","uc001bdo.1","chr1",20978259,20988037] +[["uc009vpw.1"],"knownGene","uc009vpw.1","chr1",20978259,20988037] +[["uc010odd.1"],"knownGene","uc010odd.1","chr1",20978259,20988037] +[["uc010ode.1"],"knownGene","uc010ode.1","chr1",20978259,20988037] +[["uc001bds.3"],"knownGene","uc001bds.3","chr1",20990508,21044317] +[["uc001bdr.3"],"knownGene","uc001bdr.3","chr1",20990508,21044317] +[["uc009vpx.2"],"knownGene","uc009vpx.2","chr1",20990508,21024981] +[["uc001bdq.3"],"knownGene","uc001bdq.3","chr1",20990508,21011776] +[["uc001bdp.3"],"knownGene","uc001bdp.3","chr1",20990508,21011689] +[["uc001bdu.1"],"knownGene","uc001bdu.1","chr1",21046224,21059330] +[["uc009vpy.1"],"knownGene","uc009vpy.1","chr1",21046224,21059133] +[["uc001bdt.1"],"knownGene","uc001bdt.1","chr1",21046224,21059133] +[["uc010odh.1"],"knownGene","uc010odh.1","chr1",21069170,21113799] +[["uc001bdw.1"],"knownGene","uc001bdw.1","chr1",21069170,21113181] +[["uc001bdv.1"],"knownGene","uc001bdv.1","chr1",21069170,21113124] +[["uc010odg.1"],"knownGene","uc010odg.1","chr1",21069170,21101447] +[["uc010odf.1"],"knownGene","uc010odf.1","chr1",21069170,21092024] +[["uc001bdy.1"],"knownGene","uc001bdy.1","chr1",21069622,21107033] +[["uc001bdz.2"],"knownGene","uc001bdz.2","chr1",21080550,21113799] +[["uc001bea.2"],"knownGene","uc001bea.2","chr1",21080550,21113799] +[["uc001beb.2"],"knownGene","uc001beb.2","chr1",21102148,21113133] +[["uc001bed.2"],"knownGene","uc001bed.2","chr1",21132975,21503340] +[["uc001bef.2"],"knownGene","uc001bef.2","chr1",21132975,21503340] +[["uc001bee.2"],"knownGene","uc001bee.2","chr1",21132975,21503340] +[["uc001bec.2"],"knownGene","uc001bec.2","chr1",21132975,21437876] +[["uc010odj.1"],"knownGene","uc010odj.1","chr1",21132975,21377487] +[["uc009vpz.2"],"knownGene","uc009vpz.2","chr1",21132975,21377487] +[["uc010odi.1"],"knownGene","uc010odi.1","chr1",21132975,21299592] +[["uc001beh.2"],"knownGene","uc001beh.2","chr1",21267739,21494532] +[["uc010odk.1"],"knownGene","uc010odk.1","chr1",21267739,21415706] +[["uc001beg.2"],"knownGene","uc001beg.2","chr1",21267739,21377487] +[["uc001bem.2"],"knownGene","uc001bem.2","chr1",21543739,21672034] +[["uc001bek.2"],"knownGene","uc001bek.2","chr1",21543739,21616982] +[["uc010odl.1"],"knownGene","uc010odl.1","chr1",21543739,21616982] +[["uc001bei.2"],"knownGene","uc001bei.2","chr1",21543739,21616766] +[["uc001bej.2"],"knownGene","uc001bej.2","chr1",21543739,21606183] +[["uc009vqa.1"],"knownGene","uc009vqa.1","chr1",21559597,21616982] +[["uc001ben.1"],"knownGene","uc001ben.1","chr1",21602542,21604868] +[["uc001beo.1"],"knownGene","uc001beo.1","chr1",21619782,21626225] +[["uc001bep.1"],"knownGene","uc001bep.1","chr1",21749600,21754300] +[["uc001beq.1"],"knownGene","uc001beq.1","chr1",21761832,21762609] +[["uc001ber.2"],"knownGene","uc001ber.2","chr1",21766630,21811392] +[["uc001bes.2"],"knownGene","uc001bes.2","chr1",21766630,21811392] +[["uc009vqb.2"],"knownGene","uc009vqb.2","chr1",21766630,21811392] +[["uc010odm.1"],"knownGene","uc010odm.1","chr1",21766630,21811392] +[["uc001bet.2"],"knownGene","uc001bet.2","chr1",21835857,21904904] +[["uc010odn.1"],"knownGene","uc010odn.1","chr1",21835857,21904904] +[["uc010odo.1"],"knownGene","uc010odo.1","chr1",21835857,21904904] +[["uc010odp.1"],"knownGene","uc010odp.1","chr1",21835857,21904904] +[["uc001beu.3"],"knownGene","uc001beu.3","chr1",21877806,21904904] +[["uc001bey.2"],"knownGene","uc001bey.2","chr1",21922708,21995856] +[["uc001bex.2"],"knownGene","uc001bex.2","chr1",21922708,21995856] +[["uc001bew.2"],"knownGene","uc001bew.2","chr1",21922708,21978348] +[["uc001bev.2"],"knownGene","uc001bev.2","chr1",21922708,21946543] +[["uc001bez.1"],"knownGene","uc001bez.1","chr1",21943798,21949011] +[["uc001bfb.2"],"knownGene","uc001bfb.2","chr1",22004793,22109688] +[["uc010odq.1"],"knownGene","uc010odq.1","chr1",22004793,22109688] +[["uc009vqc.2"],"knownGene","uc009vqc.2","chr1",22004793,22109688] +[["uc001bfc.2"],"knownGene","uc001bfc.2","chr1",22004793,22109688] +[["uc001bfa.2"],"knownGene","uc001bfa.2","chr1",22004793,22051612] +[["uc001bfd.1"],"knownGene","uc001bfd.1","chr1",22012384,22031108] +[["uc001bfe.1"],"knownGene","uc001bfe.1","chr1",22047528,22109688] +[["uc001bff.2"],"knownGene","uc001bff.2","chr1",22054339,22109688] +[["uc001bfg.1"],"knownGene","uc001bfg.1","chr1",22138757,22151714] +[["uc001bfh.1"],"knownGene","uc001bfh.1","chr1",22147942,22149041] +[["uc001bfj.2"],"knownGene","uc001bfj.2","chr1",22148737,22263750] +[["uc009vqd.2"],"knownGene","uc009vqd.2","chr1",22148737,22263750] +[["uc001bfi.2"],"knownGene","uc001bfi.2","chr1",22148737,22157206] +[["uc009vqe.1"],"knownGene","uc009vqe.1","chr1",22213707,22222803] +[["uc009vqf.2"],"knownGene","uc009vqf.2","chr1",22303417,22333140] +[["uc001bfk.2"],"knownGene","uc001bfk.2","chr1",22303417,22315845] +[["uc001bfl.2"],"knownGene","uc001bfl.2","chr1",22328148,22339033] +[["uc001bfm.3"],"knownGene","uc001bfm.3","chr1",22351706,22357713] +[["uc001bfn.3"],"knownGene","uc001bfn.3","chr1",22352041,22357713] +[["uc001bfq.2"],"knownGene","uc001bfq.2","chr1",22379119,22419435] +[["uc001bfr.2"],"knownGene","uc001bfr.2","chr1",22379119,22419435] +[["uc010odr.1"],"knownGene","uc010odr.1","chr1",22379119,22419435] +[["uc010ods.1"],"knownGene","uc010ods.1","chr1",22379119,22419435] +[["uc009vqh.2"],"knownGene","uc009vqh.2","chr1",22379119,22419435] +[["uc001bfp.2"],"knownGene","uc001bfp.2","chr1",22379119,22417295] +[["uc009vqg.1"],"knownGene","uc009vqg.1","chr1",22379119,22413359] +[["uc010odt.1"],"knownGene","uc010odt.1","chr1",22443799,22470385] +[["uc001bfs.3"],"knownGene","uc001bfs.3","chr1",22443799,22469519] +[["uc001bft.2"],"knownGene","uc001bft.2","chr1",22778343,22857650] +[["uc001bfu.2"],"knownGene","uc001bfu.2","chr1",22778343,22857650] +[["uc009vqi.1"],"knownGene","uc009vqi.1","chr1",22778343,22857650] +[["uc001bfv.1"],"knownGene","uc001bfv.1","chr1",22828068,22838627] +[["uc001bfx.1"],"knownGene","uc001bfx.1","chr1",22890003,22930087] +[["uc001bfw.2"],"knownGene","uc001bfw.2","chr1",22890003,22916103] +[["uc001bfy.2"],"knownGene","uc001bfy.2","chr1",22963117,22966174] +[["uc001bfz.2"],"knownGene","uc001bfz.2","chr1",22964072,22966174] +[["uc001bgc.3"],"knownGene","uc001bgc.3","chr1",22970117,22974602] +[["uc001bga.3"],"knownGene","uc001bga.3","chr1",22970117,22974602] +[["uc001bgb.2"],"knownGene","uc001bgb.2","chr1",22970145,22974602] +[["uc001bgd.2"],"knownGene","uc001bgd.2","chr1",22979681,22988028] +[["uc001bge.2"],"knownGene","uc001bge.2","chr1",23037330,23241822] +[["uc001bgf.2"],"knownGene","uc001bgf.2","chr1",23037330,23241822] +[["uc009vqj.1"],"knownGene","uc009vqj.1","chr1",23037330,23241082] +[["uc010odu.1"],"knownGene","uc010odu.1","chr1",23037331,23241822] +[["uc001bgg.1"],"knownGene","uc001bgg.1","chr1",23243782,23247347] +[["uc001bgh.1"],"knownGene","uc001bgh.1","chr1",23337326,23342343] +[["uc001bgj.2"],"knownGene","uc001bgj.2","chr1",23345940,23410184] +[["uc001bgi.2"],"knownGene","uc001bgi.2","chr1",23345940,23410184] +[["uc001bgk.2"],"knownGene","uc001bgk.2","chr1",23410515,23495517] +[["uc010odv.1"],"knownGene","uc010odv.1","chr1",23410515,23495517] +[["uc001bgl.2"],"knownGene","uc001bgl.2","chr1",23416920,23495517] +[["uc001bgm.1"],"knownGene","uc001bgm.1","chr1",23417682,23504301] +[["uc001bgn.2"],"knownGene","uc001bgn.2","chr1",23518388,23521222] +[["uc001bgp.3"],"knownGene","uc001bgp.3","chr1",23636276,23670853] +[["uc001bgr.3"],"knownGene","uc001bgr.3","chr1",23636276,23670853] +[["uc009vqk.2"],"knownGene","uc009vqk.2","chr1",23636276,23670853] +[["uc001bgs.3"],"knownGene","uc001bgs.3","chr1",23636276,23670853] +[["uc010odw.1"],"knownGene","uc010odw.1","chr1",23636276,23670853] +[["uc010odx.1"],"knownGene","uc010odx.1","chr1",23636276,23670853] +[["uc009vql.2"],"knownGene","uc009vql.2","chr1",23636276,23670853] +[["uc001bgo.2"],"knownGene","uc001bgo.2","chr1",23636276,23638386] +[["uc001bgu.2"],"knownGene","uc001bgu.2","chr1",23685941,23696357] +[["uc001bgt.2"],"knownGene","uc001bgt.2","chr1",23685941,23694879] +[["uc001bgv.2"],"knownGene","uc001bgv.2","chr1",23695463,23698278] +[["uc001bgw.2"],"knownGene","uc001bgw.2","chr1",23695463,23698278] +[["uc001bgx.1"],"knownGene","uc001bgx.1","chr1",23707554,23751261] +[["uc009vqm.1"],"knownGene","uc009vqm.1","chr1",23710670,23720524] +[["uc009vqn.1"],"knownGene","uc009vqn.1","chr1",23724035,23751261] +[["uc010ody.1"],"knownGene","uc010ody.1","chr1",23735156,23751261] +[["uc001bha.2"],"knownGene","uc001bha.2","chr1",23755055,23810750] +[["uc010oea.1"],"knownGene","uc010oea.1","chr1",23755055,23810750] +[["uc010odz.1"],"knownGene","uc010odz.1","chr1",23755055,23810677] +[["uc001bgz.1"],"knownGene","uc001bgz.1","chr1",23755055,23763537] +[["uc001bgy.1"],"knownGene","uc001bgy.1","chr1",23755055,23763170] +[["uc001bhb.2"],"knownGene","uc001bhb.2","chr1",23755059,23765723] +[["uc001bhc.1"],"knownGene","uc001bhc.1","chr1",23768993,23811057] +[["uc001bhd.2"],"knownGene","uc001bhd.2","chr1",23801094,23803135] +[["uc001bhe.1"],"knownGene","uc001bhe.1","chr1",23832921,23857713] +[["uc001bhf.1"],"knownGene","uc001bhf.1","chr1",23853364,23855542] +[["uc001bhh.3"],"knownGene","uc001bhh.3","chr1",23884409,23886322] +[["uc001bhg.1"],"knownGene","uc001bhg.1","chr1",23884431,23885978] +[["uc001bhi.3"],"knownGene","uc001bhi.3","chr1",23907984,23967056] +[["uc001bhj.3"],"knownGene","uc001bhj.3","chr1",23953225,23967056] +[["uc001bhk.2"],"knownGene","uc001bhk.2","chr1",24018293,24022913] +[["uc001bhl.2"],"knownGene","uc001bhl.2","chr1",24018293,24022913] +[["uc001bhm.2"],"knownGene","uc001bhm.2","chr1",24019085,24022913] +[["uc001bhn.1"],"knownGene","uc001bhn.1","chr1",24019101,24022869] +[["uc001bho.2"],"knownGene","uc001bho.2","chr1",24069855,24088548] +[["uc001bhp.1"],"knownGene","uc001bhp.1","chr1",24086871,24104777] +[["uc001bhq.2"],"knownGene","uc001bhq.2","chr1",24104875,24114720] +[["uc010oeb.1"],"knownGene","uc010oeb.1","chr1",24104875,24114720] +[["uc001bht.2"],"knownGene","uc001bht.2","chr1",24117645,24122027] +[["uc001bhu.2"],"knownGene","uc001bhu.2","chr1",24117645,24122027] +[["uc001bhs.1"],"knownGene","uc001bhs.1","chr1",24117645,24122025] +[["uc001bhr.2"],"knownGene","uc001bhr.2","chr1",24117645,24122010] +[["uc001bhx.1"],"knownGene","uc001bhx.1","chr1",24122088,24127294] +[["uc009vqp.1"],"knownGene","uc009vqp.1","chr1",24122088,24127294] +[["uc001bhy.1"],"knownGene","uc001bhy.1","chr1",24122088,24127294] +[["uc001bhz.1"],"knownGene","uc001bhz.1","chr1",24122088,24127294] +[["uc001bhv.1"],"knownGene","uc001bhv.1","chr1",24122088,24127034] +[["uc001bhw.1"],"knownGene","uc001bhw.1","chr1",24122088,24127034] +[["uc009vqo.1"],"knownGene","uc009vqo.1","chr1",24122088,24126060] +[["uc001bia.2"],"knownGene","uc001bia.2","chr1",24122209,24123637] +[["uc009vqq.1"],"knownGene","uc009vqq.1","chr1",24124576,24127294] +[["uc001bic.2"],"knownGene","uc001bic.2","chr1",24128367,24165110] +[["uc001bib.2"],"knownGene","uc001bib.2","chr1",24128367,24151949] +[["uc010oec.1"],"knownGene","uc010oec.1","chr1",24128367,24151949] +[["uc009vqr.2"],"knownGene","uc009vqr.2","chr1",24128367,24151949] +[["uc009vqs.1"],"knownGene","uc009vqs.1","chr1",24130077,24151949] +[["uc001bid.1"],"knownGene","uc001bid.1","chr1",24135776,24151949] +[["uc001bie.2"],"knownGene","uc001bie.2","chr1",24171573,24194821] +[["uc009vqt.1"],"knownGene","uc009vqt.1","chr1",24180849,24194821] +[["uc010oed.1"],"knownGene","uc010oed.1","chr1",24186287,24194787] +[["uc001bif.2"],"knownGene","uc001bif.2","chr1",24200460,24239817] +[["uc001big.2"],"knownGene","uc001big.2","chr1",24286300,24289947] +[["uc010oee.1"],"knownGene","uc010oee.1","chr1",24292938,24306821] +[["uc001bij.1"],"knownGene","uc001bij.1","chr1",24292938,24306821] +[["uc010oef.1"],"knownGene","uc010oef.1","chr1",24295572,24306821] +[["uc001bin.3"],"knownGene","uc001bin.3","chr1",24382531,24438665] +[["uc001bim.3"],"knownGene","uc001bim.3","chr1",24382531,24421493] +[["uc001bil.3"],"knownGene","uc001bil.3","chr1",24382531,24393069] +[["uc001bio.2"],"knownGene","uc001bio.2","chr1",24392137,24438665] +[["uc001bip.1"],"knownGene","uc001bip.1","chr1",24408038,24434929] +[["uc001biq.1"],"knownGene","uc001biq.1","chr1",24446260,24469611] +[["uc009vrb.1"],"knownGene","uc009vrb.1","chr1",24446260,24469611] +[["uc010oeh.1"],"knownGene","uc010oeh.1","chr1",24446260,24469611] +[["uc010oeg.1"],"knownGene","uc010oeg.1","chr1",24446260,24463799] +[["uc001bir.2"],"knownGene","uc001bir.2","chr1",24480647,24513751] +[["uc001bis.2"],"knownGene","uc001bis.2","chr1",24480647,24513751] +[["uc001bit.2"],"knownGene","uc001bit.2","chr1",24480647,24513751] +[["uc001biu.2"],"knownGene","uc001biu.2","chr1",24480647,24513751] +[["uc001biv.2"],"knownGene","uc001biv.2","chr1",24487868,24513751] +[["uc010oei.1"],"knownGene","uc010oei.1","chr1",24526729,24538180] +[["uc001biw.2"],"knownGene","uc001biw.2","chr1",24580829,24580859] +[["uc001bix.2"],"knownGene","uc001bix.2","chr1",24645880,24681807] +[["uc001biy.2"],"knownGene","uc001biy.2","chr1",24649529,24681807] +[["uc001biz.2"],"knownGene","uc001biz.2","chr1",24649529,24681807] +[["uc001bjd.2"],"knownGene","uc001bjd.2","chr1",24683489,24741587] +[["uc001bjb.2"],"knownGene","uc001bjb.2","chr1",24683489,24740230] +[["uc001bjc.2"],"knownGene","uc001bjc.2","chr1",24683489,24740230] +[["uc001bja.2"],"knownGene","uc001bja.2","chr1",24683489,24727946] +[["uc010oej.1"],"knownGene","uc010oej.1","chr1",24683489,24700300] +[["uc001bje.1"],"knownGene","uc001bje.1","chr1",24687340,24740230] +[["uc001bjf.2"],"knownGene","uc001bjf.2","chr1",24695212,24718169] +[["uc001bjh.2"],"knownGene","uc001bjh.2","chr1",24742244,24799472] +[["uc009vrc.2"],"knownGene","uc009vrc.2","chr1",24742244,24799472] +[["uc001bjg.2"],"knownGene","uc001bjg.2","chr1",24742244,24792797] +[["uc010oek.1"],"knownGene","uc010oek.1","chr1",24742244,24781313] +[["uc001bji.2"],"knownGene","uc001bji.2","chr1",24782627,24792862] +[["uc001bjj.2"],"knownGene","uc001bjj.2","chr1",24829386,24862425] +[["uc009vrd.2"],"knownGene","uc009vrd.2","chr1",24840803,24862425] +[["uc009vre.2"],"knownGene","uc009vre.2","chr1",24840803,24862425] +[["uc009vrf.2"],"knownGene","uc009vrf.2","chr1",24840803,24862425] +[["uc009vrg.2"],"knownGene","uc009vrg.2","chr1",24840803,24862425] +[["uc001bjk.1"],"knownGene","uc001bjk.1","chr1",24882601,24935816] +[["uc001bjm.2"],"knownGene","uc001bjm.2","chr1",24969593,24999771] +[["uc010oel.1"],"knownGene","uc010oel.1","chr1",24969593,24999771] +[["uc009vrh.1"],"knownGene","uc009vrh.1","chr1",24970049,24996078] +[["uc009vri.1"],"knownGene","uc009vri.1","chr1",24975251,24998086] +[["uc010oem.1"],"knownGene","uc010oem.1","chr1",24975349,24993416] +[["uc001bjo.2"],"knownGene","uc001bjo.2","chr1",25071759,25170815] +[["uc001bjn.2"],"knownGene","uc001bjn.2","chr1",25071759,25170758] +[["uc001bjp.1"],"knownGene","uc001bjp.1","chr1",25071877,25169078] +[["uc001bjr.2"],"knownGene","uc001bjr.2","chr1",25226002,25291501] +[["uc009vrj.2"],"knownGene","uc009vrj.2","chr1",25226002,25291475] +[["uc001bjq.2"],"knownGene","uc001bjq.2","chr1",25226002,25256770] +[["uc010oen.1"],"knownGene","uc010oen.1","chr1",25226002,25256770] +[["uc001bjs.2"],"knownGene","uc001bjs.2","chr1",25227543,25230414] +[["uc009vrk.2"],"knownGene","uc009vrk.2","chr1",25255176,25291501] +[["uc009vrl.1"],"knownGene","uc009vrl.1","chr1",25256077,25291612] +[["uc001bjt.1"],"knownGene","uc001bjt.1","chr1",25548766,25559013] +[["uc001bju.1"],"knownGene","uc001bju.1","chr1",25548766,25559013] +[["uc010oeo.1"],"knownGene","uc010oeo.1","chr1",25553283,25559013] +[["uc001bjv.1"],"knownGene","uc001bjv.1","chr1",25556799,25559013] +[["uc001bjw.2"],"knownGene","uc001bjw.2","chr1",25568740,25573985] +[["uc001bjz.2"],"knownGene","uc001bjz.2","chr1",25598980,25656935] +[["uc001bkc.2"],"knownGene","uc001bkc.2","chr1",25598980,25656935] +[["uc009vrm.2"],"knownGene","uc009vrm.2","chr1",25598980,25656935] +[["uc001bka.2"],"knownGene","uc001bka.2","chr1",25598980,25656935] +[["uc001bkb.2"],"knownGene","uc001bkb.2","chr1",25598980,25656935] +[["uc009vrn.2"],"knownGene","uc009vrn.2","chr1",25598980,25656935] +[["uc009vro.2"],"knownGene","uc009vro.2","chr1",25598980,25656935] +[["uc009vrp.2"],"knownGene","uc009vrp.2","chr1",25598980,25656935] +[["uc010oep.1"],"knownGene","uc010oep.1","chr1",25598980,25633432] +[["uc001bkd.1"],"knownGene","uc001bkd.1","chr1",25629228,25631643] +[["uc001bke.2"],"knownGene","uc001bke.2","chr1",25664810,25688850] +[["uc010oeq.1"],"knownGene","uc010oeq.1","chr1",25664810,25688850] +[["uc009vrr.2"],"knownGene","uc009vrr.2","chr1",25664810,25688850] +[["uc009vrs.2"],"knownGene","uc009vrs.2","chr1",25664810,25688850] +[["uc001bkj.2"],"knownGene","uc001bkj.2","chr1",25688740,25756683] +[["uc001bkf.2"],"knownGene","uc001bkf.2","chr1",25688740,25747363] +[["uc001bkg.2"],"knownGene","uc001bkg.2","chr1",25688740,25747363] +[["uc001bkh.2"],"knownGene","uc001bkh.2","chr1",25688740,25747363] +[["uc001bki.2"],"knownGene","uc001bki.2","chr1",25688740,25747363] +[["uc001bkk.2"],"knownGene","uc001bkk.2","chr1",25757387,25826696] +[["uc009vru.2"],"knownGene","uc009vru.2","chr1",25757387,25826696] +[["uc009vrv.2"],"knownGene","uc009vrv.2","chr1",25757387,25826696] +[["uc009vrt.2"],"knownGene","uc009vrt.2","chr1",25757387,25785383] +[["uc001bkl.3"],"knownGene","uc001bkl.3","chr1",25870075,25895375] +[["uc009vrw.2"],"knownGene","uc009vrw.2","chr1",25889284,25895375] +[["uc009vrx.2"],"knownGene","uc009vrx.2","chr1",25889297,25895375] +[["uc001bkm.2"],"knownGene","uc001bkm.2","chr1",25943958,26111258] +[["uc009vry.1"],"knownGene","uc009vry.1","chr1",25943958,26111258] +[["uc001bkn.2"],"knownGene","uc001bkn.2","chr1",26107204,26111258] +[["uc010oer.1"],"knownGene","uc010oer.1","chr1",26126666,26144713] +[["uc010oes.1"],"knownGene","uc010oes.1","chr1",26126666,26144713] +[["uc001bkq.3"],"knownGene","uc001bkq.3","chr1",26146396,26159432] +[["uc001bkr.3"],"knownGene","uc001bkr.3","chr1",26146396,26159432] +[["uc010oet.1"],"knownGene","uc010oet.1","chr1",26146396,26159432] +[["uc009vrz.2"],"knownGene","uc009vrz.2","chr1",26146396,26159432] +[["uc010oeu.1"],"knownGene","uc010oeu.1","chr1",26146444,26150097] +[["uc001bks.3"],"knownGene","uc001bks.3","chr1",26146683,26159432] +[["uc001bkt.3"],"knownGene","uc001bkt.3","chr1",26147318,26159432] +[["uc001bku.3"],"knownGene","uc001bku.3","chr1",26149020,26159432] +[["uc001bkv.3"],"knownGene","uc001bkv.3","chr1",26152122,26159432] +[["uc001bkw.1"],"knownGene","uc001bkw.1","chr1",26160496,26185848] +[["uc001bkx.2"],"knownGene","uc001bkx.2","chr1",26187975,26197744] +[["uc010oev.1"],"knownGene","uc010oev.1","chr1",26210677,26232993] +[["uc001bky.2"],"knownGene","uc001bky.2","chr1",26210677,26219098] +[["uc001blc.2"],"knownGene","uc001blc.2","chr1",26226608,26233368] +[["uc001bla.2"],"knownGene","uc001bla.2","chr1",26226608,26232993] +[["uc001blb.2"],"knownGene","uc001blb.2","chr1",26226608,26232993] +[["uc001bkz.2"],"knownGene","uc001bkz.2","chr1",26226608,26232644] +[["uc001bld.3"],"knownGene","uc001bld.3","chr1",26286259,26324648] +[["uc001ble.3"],"knownGene","uc001ble.3","chr1",26286259,26324648] +[["uc001blf.2"],"knownGene","uc001blf.2","chr1",26348270,26362952] +[["uc001blg.1"],"knownGene","uc001blg.1","chr1",26364513,26372604] +[["uc001blh.1"],"knownGene","uc001blh.1","chr1",26364513,26372604] +[["uc001bli.1"],"knownGene","uc001bli.1","chr1",26377797,26394121] +[["uc010oew.1"],"knownGene","uc010oew.1","chr1",26437655,26452024] +[["uc001blj.3"],"knownGene","uc001blj.3","chr1",26438267,26452024] +[["uc009vsb.2"],"knownGene","uc009vsb.2","chr1",26438267,26452024] +[["uc001blk.2"],"knownGene","uc001blk.2","chr1",26485510,26489118] +[["uc001bll.3"],"knownGene","uc001bll.3","chr1",26496387,26497362] +[["uc001blm.3"],"knownGene","uc001blm.3","chr1",26503980,26516373] +[["uc001bln.3"],"knownGene","uc001bln.3","chr1",26503980,26516373] +[["uc009vsd.2"],"knownGene","uc009vsd.2","chr1",26503980,26516373] +[["uc010oex.1"],"knownGene","uc010oex.1","chr1",26503980,26511677] +[["uc009vse.2"],"knownGene","uc009vse.2","chr1",26503981,26516373] +[["uc001blo.2"],"knownGene","uc001blo.2","chr1",26506786,26516373] +[["uc010oez.1"],"knownGene","uc010oez.1","chr1",26517118,26529032] +[["uc009vsf.2"],"knownGene","uc009vsf.2","chr1",26517118,26529032] +[["uc010oey.1"],"knownGene","uc010oey.1","chr1",26517118,26528094] +[["uc001blq.2"],"knownGene","uc001blq.2","chr1",26551810,26556330] +[["uc001bls.1"],"knownGene","uc001bls.1","chr1",26560692,26605299] +[["uc010ofa.1"],"knownGene","uc010ofa.1","chr1",26560692,26605299] +[["uc001blr.2"],"knownGene","uc001blr.2","chr1",26560692,26605297] +[["uc001blt.1"],"knownGene","uc001blt.1","chr1",26595780,26605299] +[["uc001blu.2"],"knownGene","uc001blu.2","chr1",26606212,26608012] +[["uc001blz.1"],"knownGene","uc001blz.1","chr1",26608772,26633195] +[["uc001bma.2"],"knownGene","uc001bma.2","chr1",26608774,26644756] +[["uc001blw.2"],"knownGene","uc001blw.2","chr1",26608774,26633195] +[["uc001bly.2"],"knownGene","uc001bly.2","chr1",26608774,26633195] +[["uc001blx.2"],"knownGene","uc001blx.2","chr1",26608774,26633195] +[["uc001blv.2"],"knownGene","uc001blv.2","chr1",26608774,26629409] +[["uc001bmb.1"],"knownGene","uc001bmb.1","chr1",26608848,26633067] +[["uc010ofb.1"],"knownGene","uc010ofb.1","chr1",26610852,26633195] +[["uc010ofc.1"],"knownGene","uc010ofc.1","chr1",26610852,26633195] +[["uc001bmc.2"],"knownGene","uc001bmc.2","chr1",26644410,26647013] +[["uc009vsg.1"],"knownGene","uc009vsg.1","chr1",26644410,26645690] +[["uc001bmd.3"],"knownGene","uc001bmd.3","chr1",26648349,26670443] +[["uc001bmf.3"],"knownGene","uc001bmf.3","chr1",26662956,26664968] +[["uc009vsi.1"],"knownGene","uc009vsi.1","chr1",26671746,26680621] +[["uc001bmh.1"],"knownGene","uc001bmh.1","chr1",26688124,26699266] +[["uc009vsj.1"],"knownGene","uc009vsj.1","chr1",26688124,26699266] +[["uc001bmg.1"],"knownGene","uc001bmg.1","chr1",26688124,26699266] +[["uc001bmj.2"],"knownGene","uc001bmj.2","chr1",26737268,26756218] +[["uc001bmi.1"],"knownGene","uc001bmi.1","chr1",26737268,26756210] +[["uc001bmk.2"],"knownGene","uc001bmk.2","chr1",26758801,26797793] +[["uc001bml.2"],"knownGene","uc001bml.2","chr1",26758801,26797793] +[["uc001bmm.2"],"knownGene","uc001bmm.2","chr1",26758801,26797793] +[["uc001bmn.2"],"knownGene","uc001bmn.2","chr1",26758801,26797793] +[["uc010ofd.1"],"knownGene","uc010ofd.1","chr1",26758801,26797793] +[["uc001bmo.1"],"knownGene","uc001bmo.1","chr1",26789254,26794028] +[["uc001bmp.3"],"knownGene","uc001bmp.3","chr1",26798901,26803131] +[["uc009vsk.2"],"knownGene","uc009vsk.2","chr1",26798901,26803131] +[["uc001bmq.3"],"knownGene","uc001bmq.3","chr1",26800193,26803131] +[["uc001bmr.1"],"knownGene","uc001bmr.1","chr1",26856248,26901520] +[["uc010ofe.1"],"knownGene","uc010ofe.1","chr1",26857818,26901520] +[["uc010off.1"],"knownGene","uc010off.1","chr1",26869652,26898724] +[["uc001bms.1"],"knownGene","uc001bms.1","chr1",26872342,26901520] +[["uc009vsl.1"],"knownGene","uc009vsl.1","chr1",26872342,26901520] +[["uc001bmu.1"],"knownGene","uc001bmu.1","chr1",27022521,27108601] +[["uc001bmv.1"],"knownGene","uc001bmv.1","chr1",27022521,27108601] +[["uc001bmt.1"],"knownGene","uc001bmt.1","chr1",27022521,27102198] +[["uc001bmw.1"],"knownGene","uc001bmw.1","chr1",27055870,27101711] +[["uc001bmx.1"],"knownGene","uc001bmx.1","chr1",27097609,27108601] +[["uc009vsm.1"],"knownGene","uc009vsm.1","chr1",27099305,27108601] +[["uc009vsn.1"],"knownGene","uc009vsn.1","chr1",27100819,27108601] +[["uc001bmy.2"],"knownGene","uc001bmy.2","chr1",27114454,27124886] +[["uc001bmz.2"],"knownGene","uc001bmz.2","chr1",27114485,27124886] +[["uc009vso.2"],"knownGene","uc009vso.2","chr1",27114485,27124886] +[["uc010ofg.1"],"knownGene","uc010ofg.1","chr1",27114678,27124886] +[["uc001bna.2"],"knownGene","uc001bna.2","chr1",27114685,27124886] +[["uc001bnb.2"],"knownGene","uc001bnb.2","chr1",27153200,27182207] +[["uc010ofh.1"],"knownGene","uc010ofh.1","chr1",27158508,27177097] +[["uc001bnc.1"],"knownGene","uc001bnc.1","chr1",27189632,27190947] +[["uc010ofi.1"],"knownGene","uc010ofi.1","chr1",27189786,27190449] +[["uc001bnd.1"],"knownGene","uc001bnd.1","chr1",27205872,27216869] +[["uc001bne.2"],"knownGene","uc001bne.2","chr1",27216979,27226962] +[["uc009vsp.1"],"knownGene","uc009vsp.1","chr1",27216979,27226956] +[["uc001bnf.2"],"knownGene","uc001bnf.2","chr1",27237975,27240567] +[["uc001bng.1"],"knownGene","uc001bng.1","chr1",27248223,27272887] +[["uc001bnh.1"],"knownGene","uc001bnh.1","chr1",27248223,27272887] +[["uc009vsq.1"],"knownGene","uc009vsq.1","chr1",27248223,27272887] +[["uc001bni.1"],"knownGene","uc001bni.1","chr1",27276060,27286897] +[["uc001bnj.3"],"knownGene","uc001bnj.3","chr1",27320194,27327376] +[["uc010ofj.1"],"knownGene","uc010ofj.1","chr1",27331512,27339333] +[["uc001bnm.2"],"knownGene","uc001bnm.2","chr1",27425300,27481451] +[["uc010ofk.1"],"knownGene","uc010ofk.1","chr1",27425300,27481451] +[["uc001bnl.2"],"knownGene","uc001bnl.2","chr1",27425300,27430513] +[["uc001bnn.2"],"knownGene","uc001bnn.2","chr1",27431941,27481451] +[["uc001bno.2"],"knownGene","uc001bno.2","chr1",27561006,27635108] +[["uc009vst.2"],"knownGene","uc009vst.2","chr1",27561006,27633934] +[["uc001bnp.1"],"knownGene","uc001bnp.1","chr1",27587446,27634732] +[["uc001bnq.2"],"knownGene","uc001bnq.2","chr1",27622816,27635108] +[["uc001bnr.3"],"knownGene","uc001bnr.3","chr1",27648635,27662890] +[["uc001bns.3"],"knownGene","uc001bns.3","chr1",27648635,27662890] +[["uc001bnt.3"],"knownGene","uc001bnt.3","chr1",27648635,27662890] +[["uc001bnu.3"],"knownGene","uc001bnu.3","chr1",27648635,27662890] +[["uc001bnv.1"],"knownGene","uc001bnv.1","chr1",27668512,27680421] +[["uc001bnw.1"],"knownGene","uc001bnw.1","chr1",27668512,27680421] +[["uc009vsu.1"],"knownGene","uc009vsu.1","chr1",27668512,27680421] +[["uc009vsv.1"],"knownGene","uc009vsv.1","chr1",27671363,27680421] +[["uc001bnx.2"],"knownGene","uc001bnx.2","chr1",27671363,27678538] +[["uc001bny.1"],"knownGene","uc001bny.1","chr1",27681669,27693337] +[["uc009vsw.1"],"knownGene","uc009vsw.1","chr1",27681669,27693337] +[["uc001bnz.1"],"knownGene","uc001bnz.1","chr1",27684646,27688358] +[["uc001boa.2"],"knownGene","uc001boa.2","chr1",27695602,27701315] +[["uc001bob.2"],"knownGene","uc001bob.2","chr1",27695602,27701315] +[["uc001boc.2"],"knownGene","uc001boc.2","chr1",27705596,27709805] +[["uc001bod.2"],"knownGene","uc001bod.2","chr1",27719151,27722315] +[["uc001boe.2"],"knownGene","uc001boe.2","chr1",27730734,27732300] +[["uc001bof.1"],"knownGene","uc001bof.1","chr1",27732125,27816669] +[["uc010ofl.1"],"knownGene","uc010ofl.1","chr1",27732125,27816669] +[["uc009vsy.2"],"knownGene","uc009vsy.2","chr1",27860793,27930143] +[["uc009vsz.1"],"knownGene","uc009vsz.1","chr1",27873771,27930143] +[["uc001boh.1"],"knownGene","uc001boh.1","chr1",27877379,27930361] +[["uc001bom.2"],"knownGene","uc001bom.2","chr1",27938802,27961727] +[["uc001bol.2"],"knownGene","uc001bol.2","chr1",27938802,27953106] +[["uc001bok.2"],"knownGene","uc001bok.2","chr1",27938802,27952751] +[["uc001boj.2"],"knownGene","uc001boj.2","chr1",27938802,27950573] +[["uc001boi.2"],"knownGene","uc001boi.2","chr1",27938802,27942174] +[["uc001bon.1"],"knownGene","uc001bon.1","chr1",27992571,27998724] +[["uc001boo.1"],"knownGene","uc001boo.1","chr1",27992571,27998724] +[["uc001bop.1"],"knownGene","uc001bop.1","chr1",27992571,27998724] +[["uc001bor.2"],"knownGene","uc001bor.2","chr1",28052489,28089421] +[["uc001boq.2"],"knownGene","uc001boq.2","chr1",28052489,28089421] +[["uc001bos.2"],"knownGene","uc001bos.2","chr1",28052489,28089421] +[["uc001bot.2"],"knownGene","uc001bot.2","chr1",28052489,28089421] +[["uc010ofm.1"],"knownGene","uc010ofm.1","chr1",28052489,28089421] +[["uc009vtb.2"],"knownGene","uc009vtb.2","chr1",28052489,28086274] +[["uc001bou.3"],"knownGene","uc001bou.3","chr1",28099693,28150962] +[["uc001bov.1"],"knownGene","uc001bov.1","chr1",28157292,28178183] +[["uc001bow.1"],"knownGene","uc001bow.1","chr1",28157292,28178183] +[["uc001box.1"],"knownGene","uc001box.1","chr1",28157292,28178183] +[["uc009vtc.1"],"knownGene","uc009vtc.1","chr1",28157292,28178183] +[["uc009vtd.1"],"knownGene","uc009vtd.1","chr1",28157292,28178183] +[["uc001boy.1"],"knownGene","uc001boy.1","chr1",28160911,28161077] +[["uc001bpc.3"],"knownGene","uc001bpc.3","chr1",28199054,28213192] +[["uc001boz.2"],"knownGene","uc001boz.2","chr1",28199054,28213192] +[["uc001bpa.2"],"knownGene","uc001bpa.2","chr1",28199054,28213192] +[["uc010ofn.1"],"knownGene","uc010ofn.1","chr1",28199054,28213192] +[["uc010ofo.1"],"knownGene","uc010ofo.1","chr1",28199054,28213192] +[["uc001bpe.1"],"knownGene","uc001bpe.1","chr1",28218048,28241236] +[["uc010ofp.1"],"knownGene","uc010ofp.1","chr1",28218048,28241236] +[["uc001bpd.1"],"knownGene","uc001bpd.1","chr1",28218048,28241231] +[["uc001bpg.2"],"knownGene","uc001bpg.2","chr1",28261503,28285662] +[["uc010ofq.1"],"knownGene","uc010ofq.1","chr1",28261503,28285662] +[["uc010ofr.1"],"knownGene","uc010ofr.1","chr1",28261503,28285662] +[["uc001bpf.2"],"knownGene","uc001bpf.2","chr1",28261503,28282990] +[["uc001bph.1"],"knownGene","uc001bph.1","chr1",28286503,28294604] +[["uc001bpi.1"],"knownGene","uc001bpi.1","chr1",28300818,28415131] +[["uc010ofs.1"],"knownGene","uc010ofs.1","chr1",28300818,28415131] +[["uc010oft.1"],"knownGene","uc010oft.1","chr1",28300818,28415131] +[["uc001bpj.2"],"knownGene","uc001bpj.2","chr1",28303785,28415131] +[["uc001bpk.1"],"knownGene","uc001bpk.1","chr1",28314993,28415131] +[["uc010ofu.1"],"knownGene","uc010ofu.1","chr1",28315045,28415131] +[["uc010ofv.1"],"knownGene","uc010ofv.1","chr1",28421445,28423069] +[["uc001bpm.3"],"knownGene","uc001bpm.3","chr1",28475863,28520447] +[["uc009vte.2"],"knownGene","uc009vte.2","chr1",28475863,28520447] +[["uc001bpl.2"],"knownGene","uc001bpl.2","chr1",28475863,28503191] +[["uc001bpn.2"],"knownGene","uc001bpn.2","chr1",28526791,28559542] +[["uc001bpo.2"],"knownGene","uc001bpo.2","chr1",28526791,28559542] +[["uc001bpp.2"],"knownGene","uc001bpp.2","chr1",28562610,28564609] +[["uc001bpq.2"],"knownGene","uc001bpq.2","chr1",28562610,28564609] +[["uc001bpr.2"],"knownGene","uc001bpr.2","chr1",28562610,28564609] +[["uc001bps.2"],"knownGene","uc001bps.2","chr1",28586005,28609001] +[["uc001bpt.3"],"knownGene","uc001bpt.3","chr1",28655512,28662477] +[["uc009vtg.2"],"knownGene","uc009vtg.2","chr1",28655512,28662477] +[["uc001bpw.2"],"knownGene","uc001bpw.2","chr1",28696092,28826880] +[["uc001bpx.2"],"knownGene","uc001bpx.2","chr1",28696092,28826880] +[["uc001bpv.1"],"knownGene","uc001bpv.1","chr1",28696092,28823783] +[["uc001bpu.2"],"knownGene","uc001bpu.2","chr1",28696092,28793723] +[["uc001bpy.2"],"knownGene","uc001bpy.2","chr1",28764660,28826880] +[["uc001bpz.2"],"knownGene","uc001bpz.2","chr1",28818161,28826874] +[["uc001bqa.1"],"knownGene","uc001bqa.1","chr1",28832495,28865607] +[["uc001bqb.1"],"knownGene","uc001bqb.1","chr1",28832495,28865607] +[["uc001bqc.1"],"knownGene","uc001bqc.1","chr1",28832495,28865607] +[["uc001bqd.2"],"knownGene","uc001bqd.2","chr1",28835901,28837381] +[["uc001bqe.1"],"knownGene","uc001bqe.1","chr1",28844744,28865607] +[["uc001bqf.1"],"knownGene","uc001bqf.1","chr1",28844744,28865607] +[["uc001bqg.1"],"knownGene","uc001bqg.1","chr1",28844744,28865607] +[["uc001bqh.2"],"knownGene","uc001bqh.2","chr1",28879528,28905056] +[["uc001bqi.2"],"knownGene","uc001bqi.2","chr1",28879528,28905056] +[["uc010ofw.1"],"knownGene","uc010ofw.1","chr1",28879528,28905056] +[["uc001bqp.2"],"knownGene","uc001bqp.2","chr1",28905051,28909495] +[["uc001bqo.2"],"knownGene","uc001bqo.2","chr1",28905051,28908383] +[["uc001bqk.2"],"knownGene","uc001bqk.2","chr1",28905051,28908366] +[["uc001bql.2"],"knownGene","uc001bql.2","chr1",28905051,28908366] +[["uc001bqm.2"],"knownGene","uc001bqm.2","chr1",28905051,28908366] +[["uc001bqn.2"],"knownGene","uc001bqn.2","chr1",28905051,28908366] +[["uc001bqq.1"],"knownGene","uc001bqq.1","chr1",28905254,28905334] +[["uc001bqr.2"],"knownGene","uc001bqr.2","chr1",28906275,28906405] +[["uc001bqs.2"],"knownGene","uc001bqs.2","chr1",28906892,28907024] +[["uc001bqt.2"],"knownGene","uc001bqt.2","chr1",28907431,28907565] +[["uc001bqu.2"],"knownGene","uc001bqu.2","chr1",28918711,28921086] +[["uc001bqv.2"],"knownGene","uc001bqv.2","chr1",28919026,28921086] +[["uc001bqx.2"],"knownGene","uc001bqx.2","chr1",28929610,28969604] +[["uc001bqy.2"],"knownGene","uc001bqy.2","chr1",28929610,28969604] +[["uc001bqw.2"],"knownGene","uc001bqw.2","chr1",28929610,28948686] +[["uc009vti.2"],"knownGene","uc009vti.2","chr1",28931450,28969604] +[["uc009vtj.1"],"knownGene","uc009vtj.1","chr1",28975111,28975246] +[["uc001bqz.2"],"knownGene","uc001bqz.2","chr1",28995243,29041385] +[["uc001bra.2"],"knownGene","uc001bra.2","chr1",28995243,29041385] +[["uc001brb.2"],"knownGene","uc001brb.2","chr1",28995243,29041385] +[["uc001brc.2"],"knownGene","uc001brc.2","chr1",29063135,29096286] +[["uc001brd.2"],"knownGene","uc001brd.2","chr1",29063135,29096286] +[["uc010ofx.1"],"knownGene","uc010ofx.1","chr1",29063135,29096286] +[["uc001bre.2"],"knownGene","uc001bre.2","chr1",29063461,29096286] +[["uc001brf.1"],"knownGene","uc001brf.1","chr1",29138653,29190208] +[["uc001brg.1"],"knownGene","uc001brg.1","chr1",29213627,29446958] +[["uc001brh.1"],"knownGene","uc001brh.1","chr1",29213627,29446958] +[["uc001bri.1"],"knownGene","uc001bri.1","chr1",29213627,29446958] +[["uc001brj.1"],"knownGene","uc001brj.1","chr1",29213627,29446958] +[["uc001brl.1"],"knownGene","uc001brl.1","chr1",29241090,29446958] +[["uc001brk.2"],"knownGene","uc001brk.2","chr1",29241090,29391731] +[["uc009vtk.1"],"knownGene","uc009vtk.1","chr1",29241090,29380164] +[["uc001brm.1"],"knownGene","uc001brm.1","chr1",29313942,29442315] +[["uc009vtl.1"],"knownGene","uc009vtl.1","chr1",29313959,29446958] +[["uc009vtm.1"],"knownGene","uc009vtm.1","chr1",29313959,29446958] +[["uc009vtn.1"],"knownGene","uc009vtn.1","chr1",29410408,29446958] +[["uc001brn.1"],"knownGene","uc001brn.1","chr1",29445939,29450407] +[["uc001bro.2"],"knownGene","uc001bro.2","chr1",29474250,29508637] +[["uc010ofy.1"],"knownGene","uc010ofy.1","chr1",29474250,29508637] +[["uc009vtp.2"],"knownGene","uc009vtp.2","chr1",29481207,29508637] +[["uc001brp.1"],"knownGene","uc001brp.1","chr1",29519384,29557454] +[["uc001brq.1"],"knownGene","uc001brq.1","chr1",29519384,29557454] +[["uc001brr.1"],"knownGene","uc001brr.1","chr1",29519384,29557454] +[["uc001brs.1"],"knownGene","uc001brs.1","chr1",29519384,29557454] +[["uc001brt.1"],"knownGene","uc001brt.1","chr1",29526148,29557454] +[["uc010ofz.1"],"knownGene","uc010ofz.1","chr1",29526148,29557454] +[["uc001bru.2"],"knownGene","uc001bru.2","chr1",29563046,29653315] +[["uc001brv.2"],"knownGene","uc001brv.2","chr1",29563046,29653315] +[["uc001brw.2"],"knownGene","uc001brw.2","chr1",29563046,29653315] +[["uc009vtq.2"],"knownGene","uc009vtq.2","chr1",29563046,29653315] +[["uc009vtr.2"],"knownGene","uc009vtr.2","chr1",29563046,29653315] +[["uc001brx.2"],"knownGene","uc001brx.2","chr1",29646721,29653315] +[["uc001bry.3"],"knownGene","uc001bry.3","chr1",30486798,30510456] +[["uc001brz.2"],"knownGene","uc001brz.2","chr1",31184125,31196432] +[["uc001bsa.1"],"knownGene","uc001bsa.1","chr1",31187093,31192099] +[["uc001bsb.1"],"knownGene","uc001bsb.1","chr1",31191618,31199593] +[["uc001bsc.2"],"knownGene","uc001bsc.2","chr1",31205314,31230683] +[["uc001bse.2"],"knownGene","uc001bse.2","chr1",31342312,31381480] +[["uc001bsd.2"],"knownGene","uc001bsd.2","chr1",31342312,31351587] +[["uc001bsk.1"],"knownGene","uc001bsk.1","chr1",31404352,31538763] +[["uc010ogb.1"],"knownGene","uc010ogb.1","chr1",31404352,31538763] +[["uc001bsh.1"],"knownGene","uc001bsh.1","chr1",31404352,31538564] +[["uc001bsi.1"],"knownGene","uc001bsi.1","chr1",31404352,31538564] +[["uc001bsj.1"],"knownGene","uc001bsj.1","chr1",31404352,31538564] +[["uc010oga.1"],"knownGene","uc010oga.1","chr1",31404352,31538564] +[["uc001bsg.1"],"knownGene","uc001bsg.1","chr1",31404352,31478878] +[["uc001bsf.1"],"knownGene","uc001bsf.1","chr1",31404352,31465507] +[["uc009vts.1"],"knownGene","uc009vts.1","chr1",31408535,31422052] +[["uc001bsl.1"],"knownGene","uc001bsl.1","chr1",31441009,31441084] +[["uc001bsm.2"],"knownGene","uc001bsm.2","chr1",31460911,31461480] +[["uc010ogd.1"],"knownGene","uc010ogd.1","chr1",31652592,31712400] +[["uc001bsn.2"],"knownGene","uc001bsn.2","chr1",31652592,31661034] +[["uc010ogc.1"],"knownGene","uc010ogc.1","chr1",31652592,31661034] +[["uc001bso.2"],"knownGene","uc001bso.2","chr1",31732416,31769644] +[["uc010oge.1"],"knownGene","uc010oge.1","chr1",31732416,31769644] +[["uc009vtt.2"],"knownGene","uc009vtt.2","chr1",31732416,31742513] +[["uc001bsp.1"],"knownGene","uc001bsp.1","chr1",31769841,31837780] +[["uc001bsq.1"],"knownGene","uc001bsq.1","chr1",31769841,31837780] +[["uc010ogf.1"],"knownGene","uc010ogf.1","chr1",31769841,31837780] +[["uc009vtu.1"],"knownGene","uc009vtu.1","chr1",31769841,31837780] +[["uc001bsr.1"],"knownGene","uc001bsr.1","chr1",31769930,31837780] +[["uc009vtv.1"],"knownGene","uc009vtv.1","chr1",31769930,31837780] +[["uc001bss.1"],"knownGene","uc001bss.1","chr1",31838099,31845923] +[["uc010ogg.1"],"knownGene","uc010ogg.1","chr1",31883047,31907524] +[["uc001bst.2"],"knownGene","uc001bst.2","chr1",31885962,31907524] +[["uc009vtw.1"],"knownGene","uc009vtw.1","chr1",31885962,31899166] +[["uc010ogh.1"],"knownGene","uc010ogh.1","chr1",31886659,31907524] +[["uc001bsu.2"],"knownGene","uc001bsu.2","chr1",31887268,31907524] +[["uc001bsv.2"],"knownGene","uc001bsv.2","chr1",31887576,31907524] +[["uc001bsx.2"],"knownGene","uc001bsx.2","chr1",31971815,31974166] +[["uc001bsw.1"],"knownGene","uc001bsw.1","chr1",31971815,31973124] +[["uc001bsy.1"],"knownGene","uc001bsy.1","chr1",31984035,31989846] +[["uc001bsz.2"],"knownGene","uc001bsz.2","chr1",32013117,32053285] +[["uc001bta.2"],"knownGene","uc001bta.2","chr1",32042085,32053285] +[["uc010ogj.1"],"knownGene","uc010ogj.1","chr1",32042085,32053285] +[["uc010ogi.1"],"knownGene","uc010ogi.1","chr1",32042085,32046561] +[["uc010ogk.1"],"knownGene","uc010ogk.1","chr1",32042734,32051869] +[["uc001btc.3"],"knownGene","uc001btc.3","chr1",32083300,32093212] +[["uc009vtx.2"],"knownGene","uc009vtx.2","chr1",32083300,32092919] +[["uc001btb.2"],"knownGene","uc001btb.2","chr1",32083300,32092919] +[["uc001btd.2"],"knownGene","uc001btd.2","chr1",32084640,32092919] +[["uc010ogl.1"],"knownGene","uc010ogl.1","chr1",32084651,32098117] +[["uc001bte.1"],"knownGene","uc001bte.1","chr1",32095467,32098435] +[["uc001bth.1"],"knownGene","uc001bth.1","chr1",32095470,32110477] +[["uc001btg.1"],"knownGene","uc001btg.1","chr1",32095470,32101144] +[["uc001btf.1"],"knownGene","uc001btf.1","chr1",32095470,32098254] +[["uc010ogm.1"],"knownGene","uc010ogm.1","chr1",32099886,32110477] +[["uc001btk.1"],"knownGene","uc001btk.1","chr1",32117847,32169768] +[["uc001btj.1"],"knownGene","uc001btj.1","chr1",32117847,32164207] +[["uc001bti.1"],"knownGene","uc001bti.1","chr1",32117847,32136007] +[["uc001btl.3"],"knownGene","uc001btl.3","chr1",32144839,32169768] +[["uc001btn.2"],"knownGene","uc001btn.2","chr1",32192718,32229648] +[["uc001bto.2"],"knownGene","uc001bto.2","chr1",32192718,32229648] +[["uc010ogq.1"],"knownGene","uc010ogq.1","chr1",32192718,32222882] +[["uc010ogp.1"],"knownGene","uc010ogp.1","chr1",32192718,32222416] +[["uc010ogo.1"],"knownGene","uc010ogo.1","chr1",32192718,32210332] +[["uc010ogn.1"],"knownGene","uc010ogn.1","chr1",32192718,32202324] +[["uc001btp.1"],"knownGene","uc001btp.1","chr1",32192718,32202280] +[["uc001btm.2"],"knownGene","uc001btm.2","chr1",32192718,32201266] +[["uc001btq.1"],"knownGene","uc001btq.1","chr1",32203800,32222416] +[["uc010ogr.1"],"knownGene","uc010ogr.1","chr1",32204908,32222416] +[["uc001bts.1"],"knownGene","uc001bts.1","chr1",32256024,32281580] +[["uc001btr.1"],"knownGene","uc001btr.1","chr1",32256024,32258424] +[["uc001btu.2"],"knownGene","uc001btu.2","chr1",32256032,32281580] +[["uc001btv.2"],"knownGene","uc001btv.2","chr1",32256032,32281580] +[["uc001btt.2"],"knownGene","uc001btt.2","chr1",32256032,32264266] +[["uc001btw.1"],"knownGene","uc001btw.1","chr1",32260096,32264232] +[["uc001btx.1"],"knownGene","uc001btx.1","chr1",32372021,32373712] +[["uc001bty.1"],"knownGene","uc001bty.1","chr1",32373792,32403988] +[["uc001btz.1"],"knownGene","uc001btz.1","chr1",32373792,32403988] +[["uc010ogs.1"],"knownGene","uc010ogs.1","chr1",32373792,32385259] +[["uc001buc.1"],"knownGene","uc001buc.1","chr1",32479490,32526450] +[["uc001bub.2"],"knownGene","uc001bub.2","chr1",32479490,32509471] +[["uc001bua.1"],"knownGene","uc001bua.1","chr1",32479490,32508320] +[["uc010ogv.1"],"knownGene","uc010ogv.1","chr1",32538502,32568465] +[["uc001bue.3"],"knownGene","uc001bue.3","chr1",32538502,32568465] +[["uc001buf.3"],"knownGene","uc001buf.3","chr1",32538502,32568465] +[["uc010ogw.1"],"knownGene","uc010ogw.1","chr1",32538502,32568465] +[["uc010ogu.1"],"knownGene","uc010ogu.1","chr1",32538502,32566804] +[["uc010ogt.1"],"knownGene","uc010ogt.1","chr1",32538502,32566163] +[["uc001bug.2"],"knownGene","uc001bug.2","chr1",32573643,32642166] +[["uc001buh.2"],"knownGene","uc001buh.2","chr1",32573643,32642166] +[["uc010ogx.1"],"knownGene","uc010ogx.1","chr1",32573888,32642166] +[["uc010ogy.1"],"knownGene","uc010ogy.1","chr1",32608579,32642166] +[["uc009vtz.2"],"knownGene","uc009vtz.2","chr1",32622453,32642166] +[["uc001bui.2"],"knownGene","uc001bui.2","chr1",32645344,32663885] +[["uc001buj.2"],"knownGene","uc001buj.2","chr1",32645665,32663885] +[["uc001bul.1"],"knownGene","uc001bul.1","chr1",32666201,32670991] +[["uc001buk.2"],"knownGene","uc001buk.2","chr1",32666201,32670986] +[["uc001bum.2"],"knownGene","uc001bum.2","chr1",32671235,32674288] +[["uc009vua.2"],"knownGene","uc009vua.2","chr1",32671235,32674288] +[["uc010ogz.1"],"knownGene","uc010ogz.1","chr1",32671235,32674288] +[["uc001bun.2"],"knownGene","uc001bun.2","chr1",32674694,32681797] +[["uc001buo.3"],"knownGene","uc001buo.3","chr1",32680077,32687926] +[["uc001bup.3"],"knownGene","uc001bup.3","chr1",32680077,32687926] +[["uc009vub.1"],"knownGene","uc009vub.1","chr1",32681273,32687926] +[["uc010oha.1"],"knownGene","uc010oha.1","chr1",32681697,32687926] +[["uc001buq.3"],"knownGene","uc001buq.3","chr1",32681799,32687926] +[["uc001bur.3"],"knownGene","uc001bur.3","chr1",32687184,32697204] +[["uc009vuc.2"],"knownGene","uc009vuc.2","chr1",32687958,32697204] +[["uc001bus.2"],"knownGene","uc001bus.2","chr1",32688037,32697204] +[["uc010ohb.1"],"knownGene","uc010ohb.1","chr1",32697261,32707311] +[["uc001buv.3"],"knownGene","uc001buv.3","chr1",32697261,32707311] +[["uc001but.2"],"knownGene","uc001but.2","chr1",32697261,32706265] +[["uc001buw.2"],"knownGene","uc001buw.2","chr1",32712817,32714459] +[["uc001bux.2"],"knownGene","uc001bux.2","chr1",32716839,32751765] +[["uc001buy.2"],"knownGene","uc001buy.2","chr1",32739711,32751765] +[["uc001buz.2"],"knownGene","uc001buz.2","chr1",32739711,32751765] +[["uc010ohc.1"],"knownGene","uc010ohc.1","chr1",32739740,32745811] +[["uc001bva.2"],"knownGene","uc001bva.2","chr1",32739925,32751765] +[["uc001bvb.1"],"knownGene","uc001bvb.1","chr1",32757707,32799224] +[["uc010ohd.1"],"knownGene","uc010ohd.1","chr1",32757707,32793590] +[["uc010ohe.1"],"knownGene","uc010ohe.1","chr1",32757707,32793590] +[["uc010ohf.1"],"knownGene","uc010ohf.1","chr1",32757992,32799224] +[["uc001bvc.1"],"knownGene","uc001bvc.1","chr1",32795080,32799224] +[["uc001bvd.2"],"knownGene","uc001bvd.2","chr1",32799440,32801834] +[["uc001bve.1"],"knownGene","uc001bve.1","chr1",32826871,32829158] +[["uc001bvf.2"],"knownGene","uc001bvf.2","chr1",32827861,32829922] +[["uc001bvh.3"],"knownGene","uc001bvh.3","chr1",32830706,32860062] +[["uc010ohg.1"],"knownGene","uc010ohg.1","chr1",32830706,32860062] +[["uc010ohh.1"],"knownGene","uc010ohh.1","chr1",32830706,32860062] +[["uc010ohi.1"],"knownGene","uc010ohi.1","chr1",32830706,32860062] +[["uc001bvg.3"],"knownGene","uc001bvg.3","chr1",32830706,32860062] +[["uc001bvj.2"],"knownGene","uc001bvj.2","chr1",32830788,32860062] +[["uc001bvi.2"],"knownGene","uc001bvi.2","chr1",32830788,32860062] +[["uc001bvk.2"],"knownGene","uc001bvk.2","chr1",32930657,33071541] +[["uc001bvl.3"],"knownGene","uc001bvl.3","chr1",32930657,32953457] +[["uc001bvn.2"],"knownGene","uc001bvn.2","chr1",33004771,33071541] +[["uc001bvm.2"],"knownGene","uc001bvm.2","chr1",33004771,33066224] +[["uc001bvo.1"],"knownGene","uc001bvo.1","chr1",33065772,33116185] +[["uc001bvp.2"],"knownGene","uc001bvp.2","chr1",33087308,33116185] +[["uc001bvq.2"],"knownGene","uc001bvq.2","chr1",33087308,33116185] +[["uc001bvr.2"],"knownGene","uc001bvr.2","chr1",33116748,33151810] +[["uc001bvs.2"],"knownGene","uc001bvs.2","chr1",33116748,33151810] +[["uc010ohj.1"],"knownGene","uc010ohj.1","chr1",33116748,33151810] +[["uc010ohk.1"],"knownGene","uc010ohk.1","chr1",33116958,33151810] +[["uc001bvt.2"],"knownGene","uc001bvt.2","chr1",33145506,33168361] +[["uc010ohl.1"],"knownGene","uc010ohl.1","chr1",33145506,33168361] +[["uc001bvu.1"],"knownGene","uc001bvu.1","chr1",33207511,33240571] +[["uc010ohm.1"],"knownGene","uc010ohm.1","chr1",33219686,33240571] +[["uc001bvv.2"],"knownGene","uc001bvv.2","chr1",33231234,33240571] +[["uc010ohn.1"],"knownGene","uc010ohn.1","chr1",33231234,33240571] +[["uc001bvy.1"],"knownGene","uc001bvy.1","chr1",33240839,33283633] +[["uc001bvx.1"],"knownGene","uc001bvx.1","chr1",33240839,33249356] +[["uc001bvw.1"],"knownGene","uc001bvw.1","chr1",33240839,33247704] +[["uc001bvz.2"],"knownGene","uc001bvz.2","chr1",33283042,33324475] +[["uc001bwc.2"],"knownGene","uc001bwc.2","chr1",33283175,33324475] +[["uc001bwa.1"],"knownGene","uc001bwa.1","chr1",33283175,33300665] +[["uc001bwb.1"],"knownGene","uc001bwb.1","chr1",33283175,33300665] +[["uc001bwd.2"],"knownGene","uc001bwd.2","chr1",33291698,33324475] +[["uc001bwe.2"],"knownGene","uc001bwe.2","chr1",33327869,33330398] +[["uc001bwf.1"],"knownGene","uc001bwf.1","chr1",33327876,33336347] +[["uc001bwg.2"],"knownGene","uc001bwg.2","chr1",33330056,33338082] +[["uc001bwh.2"],"knownGene","uc001bwh.2","chr1",33352097,33360246] +[["uc001bwi.1"],"knownGene","uc001bwi.1","chr1",33360195,33366953] +[["uc001bwj.1"],"knownGene","uc001bwj.1","chr1",33360195,33366953] +[["uc001bwk.1"],"knownGene","uc001bwk.1","chr1",33360195,33366953] +[["uc010oho.1"],"knownGene","uc010oho.1","chr1",33402051,33430286] +[["uc001bwm.3"],"knownGene","uc001bwm.3","chr1",33402051,33430286] +[["uc010ohp.1"],"knownGene","uc010ohp.1","chr1",33402051,33430286] +[["uc001bwn.2"],"knownGene","uc001bwn.2","chr1",33452675,33498069] +[["uc001bwo.1"],"knownGene","uc001bwo.1","chr1",33473585,33502492] +[["uc010ohq.1"],"knownGene","uc010ohq.1","chr1",33473585,33502492] +[["uc009vud.1"],"knownGene","uc009vud.1","chr1",33473585,33502492] +[["uc001bwp.1"],"knownGene","uc001bwp.1","chr1",33478582,33502492] +[["uc010ohr.1"],"knownGene","uc010ohr.1","chr1",33478582,33502492] +[["uc001bwq.1"],"knownGene","uc001bwq.1","chr1",33478807,33502492] +[["uc001bwt.1"],"knownGene","uc001bwt.1","chr1",33546713,33586131] +[["uc001bwr.2"],"knownGene","uc001bwr.2","chr1",33546713,33585994] +[["uc001bws.2"],"knownGene","uc001bws.2","chr1",33546713,33585994] +[["uc009vue.2"],"knownGene","uc009vue.2","chr1",33546713,33585994] +[["uc001bwu.2"],"knownGene","uc001bwu.2","chr1",33546748,33585994] +[["uc001bwv.2"],"knownGene","uc001bwv.2","chr1",33546748,33585994] +[["uc001bww.2"],"knownGene","uc001bww.2","chr1",33546793,33585994] +[["uc001bwx.1"],"knownGene","uc001bwx.1","chr1",33547259,33586131] +[["uc009vug.2"],"knownGene","uc009vug.2","chr1",33547778,33585994] +[["uc001bwz.1"],"knownGene","uc001bwz.1","chr1",33547778,33567493] +[["uc009vuf.1"],"knownGene","uc009vuf.1","chr1",33547778,33567493] +[["uc001bwy.1"],"knownGene","uc001bwy.1","chr1",33547778,33567493] +[["uc001bxa.1"],"knownGene","uc001bxa.1","chr1",33607471,33608831] +[["uc001bxb.2"],"knownGene","uc001bxb.2","chr1",33611003,33647671] +[["uc001bxc.1"],"knownGene","uc001bxc.1","chr1",33722173,33766320] +[["uc001bxd.1"],"knownGene","uc001bxd.1","chr1",33772366,33786699] +[["uc009vuh.1"],"knownGene","uc009vuh.1","chr1",33789223,33896216] +[["uc001bxg.1"],"knownGene","uc001bxg.1","chr1",33789223,33841194] +[["uc001bxh.1"],"knownGene","uc001bxh.1","chr1",33789223,33841194] +[["uc001bxe.1"],"knownGene","uc001bxe.1","chr1",33789223,33815499] +[["uc001bxf.1"],"knownGene","uc001bxf.1","chr1",33789223,33815499] +[["uc001bxi.1"],"knownGene","uc001bxi.1","chr1",33832716,33896615] +[["uc001bxj.3"],"knownGene","uc001bxj.3","chr1",33938231,33961993] +[["uc009vui.2"],"knownGene","uc009vui.2","chr1",33938251,33961993] +[["uc001bxk.2"],"knownGene","uc001bxk.2","chr1",33938251,33958212] +[["uc001bxn.1"],"knownGene","uc001bxn.1","chr1",33979608,34631443] +[["uc001bxm.1"],"knownGene","uc001bxm.1","chr1",33979608,34630875] +[["uc001bxo.1"],"knownGene","uc001bxo.1","chr1",34057406,34175104] +[["uc001bxp.2"],"knownGene","uc001bxp.2","chr1",34326075,34330391] +[["uc001bxq.2"],"knownGene","uc001bxq.2","chr1",34329630,34330391] +[["uc001bxr.2"],"knownGene","uc001bxr.2","chr1",34334556,34351058] +[["uc001bxs.3"],"knownGene","uc001bxs.3","chr1",34632623,34684729] +[["uc001bxt.2"],"knownGene","uc001bxt.2","chr1",34642552,34684729] +[["uc001bxu.2"],"knownGene","uc001bxu.2","chr1",35220720,35224113] +[["uc001bxv.1"],"knownGene","uc001bxv.1","chr1",35225341,35229325] +[["uc001bxw.3"],"knownGene","uc001bxw.3","chr1",35226777,35227927] +[["uc001bxx.2"],"knownGene","uc001bxx.2","chr1",35246789,35251966] +[["uc001bxy.2"],"knownGene","uc001bxy.2","chr1",35247910,35251966] +[["uc001bxz.3"],"knownGene","uc001bxz.3","chr1",35249171,35252849] +[["uc010ohs.1"],"knownGene","uc010ohs.1","chr1",35250363,35251175] +[["uc009vul.2"],"knownGene","uc009vul.2","chr1",35258170,35261346] +[["uc001bya.2"],"knownGene","uc001bya.2","chr1",35258598,35261346] +[["uc009vum.1"],"knownGene","uc009vum.1","chr1",35258599,35260816] +[["uc001byb.2"],"knownGene","uc001byb.2","chr1",35319123,35325392] +[["uc001byc.2"],"knownGene","uc001byc.2","chr1",35331037,35370984] +[["uc001byd.3"],"knownGene","uc001byd.3","chr1",35439959,35450920] +[["uc001bye.2"],"knownGene","uc001bye.2","chr1",35447177,35450920] +[["uc001byf.1"],"knownGene","uc001byf.1","chr1",35449367,35497291] +[["uc001byh.2"],"knownGene","uc001byh.2","chr1",35451768,35497569] +[["uc010oht.1"],"knownGene","uc010oht.1","chr1",35451768,35497569] +[["uc009vup.2"],"knownGene","uc009vup.2","chr1",35455581,35497569] +[["uc009vuq.1"],"knownGene","uc009vuq.1","chr1",35457412,35497569] +[["uc009vur.1"],"knownGene","uc009vur.1","chr1",35470732,35497291] +[["uc001byk.2"],"knownGene","uc001byk.2","chr1",35482850,35497569] +[["uc001byj.2"],"knownGene","uc001byj.2","chr1",35482850,35497291] +[["uc001byi.2"],"knownGene","uc001byi.2","chr1",35482850,35497291] +[["uc001bym.2"],"knownGene","uc001bym.2","chr1",35544971,35581454] +[["uc001byn.2"],"knownGene","uc001byn.2","chr1",35544971,35581454] +[["uc010ohu.1"],"knownGene","uc010ohu.1","chr1",35544971,35581454] +[["uc001byo.2"],"knownGene","uc001byo.2","chr1",35544971,35581454] +[["uc009vut.2"],"knownGene","uc009vut.2","chr1",35544971,35581454] +[["uc009vus.1"],"knownGene","uc009vus.1","chr1",35544971,35570370] +[["uc001byl.1"],"knownGene","uc001byl.1","chr1",35544971,35566700] +[["uc001byr.2"],"knownGene","uc001byr.2","chr1",35641981,35656194] +[["uc001byq.2"],"knownGene","uc001byq.2","chr1",35641981,35646083] +[["uc001byp.2"],"knownGene","uc001byp.2","chr1",35641981,35646083] +[["uc001bys.2"],"knownGene","uc001bys.2","chr1",35649202,35658743] +[["uc001byt.2"],"knownGene","uc001byt.2","chr1",35734567,35887544] +[["uc009vuu.2"],"knownGene","uc009vuu.2","chr1",35734567,35887544] +[["uc001byu.2"],"knownGene","uc001byu.2","chr1",35734567,35887544] +[["uc009vuv.2"],"knownGene","uc009vuv.2","chr1",35824525,35887544] +[["uc001byv.2"],"knownGene","uc001byv.2","chr1",35833689,35835012] +[["uc001byx.2"],"knownGene","uc001byx.2","chr1",35899091,36023037] +[["uc001byw.2"],"knownGene","uc001byw.2","chr1",35899091,35920237] +[["uc010ohv.1"],"knownGene","uc010ohv.1","chr1",35904142,35936561] +[["uc010ohw.1"],"knownGene","uc010ohw.1","chr1",35925975,36023551] +[["uc001byz.2"],"knownGene","uc001byz.2","chr1",35930145,36023037] +[["uc010ohx.1"],"knownGene","uc010ohx.1","chr1",35932208,36023003] +[["uc001bza.2"],"knownGene","uc001bza.2","chr1",36023392,36032378] +[["uc001bzb.2"],"knownGene","uc001bzb.2","chr1",36023392,36032378] +[["uc001bzc.2"],"knownGene","uc001bzc.2","chr1",36023392,36032378] +[["uc001bzd.1"],"knownGene","uc001bzd.1","chr1",36035412,36107143] +[["uc010ohy.1"],"knownGene","uc010ohy.1","chr1",36038970,36060925] +[["uc001bzf.1"],"knownGene","uc001bzf.1","chr1",36067743,36107143] +[["uc010ohz.1"],"knownGene","uc010ohz.1","chr1",36067743,36107127] +[["uc001bzg.1"],"knownGene","uc001bzg.1","chr1",36068623,36107143] +[["uc001bzh.1"],"knownGene","uc001bzh.1","chr1",36179476,36184790] +[["uc001bzi.2"],"knownGene","uc001bzi.2","chr1",36201819,36235551] +[["uc009vux.2"],"knownGene","uc009vux.2","chr1",36201819,36235551] +[["uc001bzj.1"],"knownGene","uc001bzj.1","chr1",36273827,36321188] +[["uc001bzk.2"],"knownGene","uc001bzk.2","chr1",36335408,36389897] +[["uc001bzl.2"],"knownGene","uc001bzl.2","chr1",36348809,36389897] +[["uc009vuy.2"],"knownGene","uc009vuy.2","chr1",36360722,36389897] +[["uc001bzm.1"],"knownGene","uc001bzm.1","chr1",36391432,36395210] +[["uc001bzn.1"],"knownGene","uc001bzn.1","chr1",36396318,36449010] +[["uc001bzp.2"],"knownGene","uc001bzp.2","chr1",36396771,36522062] +[["uc001bzq.2"],"knownGene","uc001bzq.2","chr1",36396771,36522062] +[["uc001bzo.2"],"knownGene","uc001bzo.2","chr1",36396771,36450379] +[["uc001bzr.2"],"knownGene","uc001bzr.2","chr1",36549675,36553875] +[["uc001bzs.2"],"knownGene","uc001bzs.2","chr1",36549944,36553875] +[["uc001bzt.2"],"knownGene","uc001bzt.2","chr1",36554452,36559532] +[["uc001bzu.2"],"knownGene","uc001bzu.2","chr1",36554452,36559532] +[["uc001bzv.1"],"knownGene","uc001bzv.1","chr1",36560845,36565850] +[["uc001bzw.1"],"knownGene","uc001bzw.1","chr1",36560845,36565850] +[["uc001bzy.2"],"knownGene","uc001bzy.2","chr1",36602174,36615098] +[["uc001bzx.2"],"knownGene","uc001bzx.2","chr1",36602174,36615067] +[["uc001bzz.2"],"knownGene","uc001bzz.2","chr1",36621802,36646436] +[["uc001caa.2"],"knownGene","uc001caa.2","chr1",36621802,36646436] +[["uc001cab.2"],"knownGene","uc001cab.2","chr1",36621802,36646436] +[["uc001cac.2"],"knownGene","uc001cac.2","chr1",36638064,36646436] +[["uc001cad.2"],"knownGene","uc001cad.2","chr1",36643069,36646436] +[["uc001cae.3"],"knownGene","uc001cae.3","chr1",36690016,36770955] +[["uc001caf.3"],"knownGene","uc001caf.3","chr1",36690016,36770955] +[["uc001cag.1"],"knownGene","uc001cag.1","chr1",36704347,36755365] +[["uc010oia.1"],"knownGene","uc010oia.1","chr1",36771993,36787379] +[["uc010oic.1"],"knownGene","uc010oic.1","chr1",36772707,36790484] +[["uc010oib.1"],"knownGene","uc010oib.1","chr1",36772707,36787379] +[["uc009vuz.1"],"knownGene","uc009vuz.1","chr1",36784671,36786399] +[["uc001caj.1"],"knownGene","uc001caj.1","chr1",36787631,36789755] +[["uc001cai.1"],"knownGene","uc001cai.1","chr1",36787631,36788849] +[["uc001cak.1"],"knownGene","uc001cak.1","chr1",36805224,36851485] +[["uc001cal.1"],"knownGene","uc001cal.1","chr1",36805224,36851485] +[["uc001cam.1"],"knownGene","uc001cam.1","chr1",36805224,36851485] +[["uc009vva.1"],"knownGene","uc009vva.1","chr1",36805224,36851485] +[["uc001can.1"],"knownGene","uc001can.1","chr1",36805230,36826941] +[["uc001cao.1"],"knownGene","uc001cao.1","chr1",36859030,36863493] +[["uc001cap.2"],"knownGene","uc001cap.2","chr1",36883507,36916052] +[["uc001caq.2"],"knownGene","uc001caq.2","chr1",36883507,36916052] +[["uc001car.2"],"knownGene","uc001car.2","chr1",36893902,36916052] +[["uc001cas.2"],"knownGene","uc001cas.2","chr1",36921361,36930040] +[["uc001cav.1"],"knownGene","uc001cav.1","chr1",36931643,36948509] +[["uc001caw.1"],"knownGene","uc001caw.1","chr1",36931643,36948509] +[["uc001cax.1"],"knownGene","uc001cax.1","chr1",36931643,36948509] +[["uc001cay.1"],"knownGene","uc001cay.1","chr1",36931643,36948509] +[["uc001cau.1"],"knownGene","uc001cau.1","chr1",36931643,36937992] +[["uc009vvc.1"],"knownGene","uc009vvc.1","chr1",36931643,36937247] +[["uc001cat.1"],"knownGene","uc001cat.1","chr1",36931643,36935441] +[["uc001caz.2"],"knownGene","uc001caz.2","chr1",37261127,37499844] +[["uc001cba.1"],"knownGene","uc001cba.1","chr1",37270218,37499844] +[["uc001cbb.3"],"knownGene","uc001cbb.3","chr1",37940118,37949976] +[["uc001cbc.1"],"knownGene","uc001cbc.1","chr1",37945750,37949976] +[["uc001cbe.1"],"knownGene","uc001cbe.1","chr1",37958175,37980364] +[["uc009vvd.1"],"knownGene","uc009vvd.1","chr1",37958175,37980364] +[["uc001cbf.1"],"knownGene","uc001cbf.1","chr1",37958175,37980364] +[["uc001cbg.1"],"knownGene","uc001cbg.1","chr1",37958175,37980364] +[["uc001cbd.1"],"knownGene","uc001cbd.1","chr1",37958175,37979867] +[["uc001cbh.1"],"knownGene","uc001cbh.1","chr1",37961485,37980364] +[["uc001cbi.2"],"knownGene","uc001cbi.2","chr1",38002144,38019903] +[["uc010oid.1"],"knownGene","uc010oid.1","chr1",38002144,38019903] +[["uc001cbj.2"],"knownGene","uc001cbj.2","chr1",38022519,38032457] +[["uc010oie.1"],"knownGene","uc010oie.1","chr1",38022519,38032457] +[["uc001cbk.2"],"knownGene","uc001cbk.2","chr1",38032413,38061586] +[["uc010oif.1"],"knownGene","uc010oif.1","chr1",38042028,38061586] +[["uc009vve.2"],"knownGene","uc009vve.2","chr1",38049175,38061586] +[["uc001cbl.1"],"knownGene","uc001cbl.1","chr1",38076950,38100491] +[["uc001cbm.1"],"knownGene","uc001cbm.1","chr1",38077420,38100491] +[["uc009vvf.1"],"knownGene","uc009vvf.1","chr1",38077420,38100491] +[["uc009vvg.1"],"knownGene","uc009vvg.1","chr1",38077420,38100491] +[["uc001cbp.2"],"knownGene","uc001cbp.2","chr1",38147249,38156192] +[["uc010oig.1"],"knownGene","uc010oig.1","chr1",38147249,38156175] +[["uc001cbo.2"],"knownGene","uc001cbo.2","chr1",38147249,38156175] +[["uc001cbn.2"],"knownGene","uc001cbn.2","chr1",38147249,38149148] +[["uc001cbq.1"],"knownGene","uc001cbq.1","chr1",38151944,38157888] +[["uc001cbr.2"],"knownGene","uc001cbr.2","chr1",38158158,38175389] +[["uc001cbs.2"],"knownGene","uc001cbs.2","chr1",38158158,38175389] +[["uc010oih.1"],"knownGene","uc010oih.1","chr1",38158525,38171239] +[["uc009vvh.1"],"knownGene","uc009vvh.1","chr1",38179554,38197254] +[["uc001cbt.2"],"knownGene","uc001cbt.2","chr1",38179554,38186226] +[["uc001cbv.1"],"knownGene","uc001cbv.1","chr1",38179560,38222363] +[["uc001cbu.2"],"knownGene","uc001cbu.2","chr1",38179560,38218898] +[["uc009vvi.2"],"knownGene","uc009vvi.2","chr1",38181646,38230824] +[["uc001cbw.3"],"knownGene","uc001cbw.3","chr1",38225946,38230824] +[["uc001cby.2"],"knownGene","uc001cby.2","chr1",38259773,38267278] +[["uc001cbx.2"],"knownGene","uc001cbx.2","chr1",38259773,38267278] +[["uc001cbz.2"],"knownGene","uc001cbz.2","chr1",38261159,38267278] +[["uc001cca.1"],"knownGene","uc001cca.1","chr1",38268613,38273865] +[["uc001ccb.1"],"knownGene","uc001ccb.1","chr1",38272650,38275126] +[["uc001ccd.2"],"knownGene","uc001ccd.2","chr1",38273472,38275126] +[["uc010oii.1"],"knownGene","uc010oii.1","chr1",38273472,38275126] +[["uc001cce.1"],"knownGene","uc001cce.1","chr1",38275238,38325292] +[["uc009vvj.1"],"knownGene","uc009vvj.1","chr1",38287792,38325292] +[["uc001ccg.1"],"knownGene","uc001ccg.1","chr1",38326368,38412729] +[["uc009vvk.1"],"knownGene","uc009vvk.1","chr1",38326368,38411522] +[["uc001ccf.1"],"knownGene","uc001ccf.1","chr1",38326368,38397421] +[["uc010oij.1"],"knownGene","uc010oij.1","chr1",38339664,38355396] +[["uc001cch.2"],"knownGene","uc001cch.2","chr1",38394213,38411522] +[["uc001cci.2"],"knownGene","uc001cci.2","chr1",38422653,38455761] +[["uc010oik.1"],"knownGene","uc010oik.1","chr1",38422653,38455761] +[["uc001cck.2"],"knownGene","uc001cck.2","chr1",38462443,38471234] +[["uc001ccl.2"],"knownGene","uc001ccl.2","chr1",38462443,38471234] +[["uc001ccm.2"],"knownGene","uc001ccm.2","chr1",38462443,38471234] +[["uc001ccj.2"],"knownGene","uc001ccj.2","chr1",38462443,38471177] +[["uc009vvl.1"],"knownGene","uc009vvl.1","chr1",38463408,38471177] +[["uc001ccn.3"],"knownGene","uc001ccn.3","chr1",38478383,38490496] +[["uc009vvm.2"],"knownGene","uc009vvm.2","chr1",38478383,38490496] +[["uc010oil.1"],"knownGene","uc010oil.1","chr1",38478383,38490496] +[["uc001cco.3"],"knownGene","uc001cco.3","chr1",38482254,38490496] +[["uc001ccp.1"],"knownGene","uc001ccp.1","chr1",38509522,38512450] +[["uc001ccr.2"],"knownGene","uc001ccr.2","chr1",39305014,39340166] +[["uc001ccq.2"],"knownGene","uc001ccq.2","chr1",39305014,39325340] +[["uc010oim.1"],"knownGene","uc010oim.1","chr1",39305014,39325340] +[["uc001ccs.2"],"knownGene","uc001ccs.2","chr1",39328636,39339050] +[["uc001cct.1"],"knownGene","uc001cct.1","chr1",39339266,39347289] +[["uc001ccu.1"],"knownGene","uc001ccu.1","chr1",39351478,39407456] +[["uc010oio.1"],"knownGene","uc010oio.1","chr1",39351478,39395185] +[["uc010oin.1"],"knownGene","uc010oin.1","chr1",39351478,39385009] +[["uc001ccv.2"],"knownGene","uc001ccv.2","chr1",39381176,39407456] +[["uc001ccw.2"],"knownGene","uc001ccw.2","chr1",39456915,39471735] +[["uc010oip.1"],"knownGene","uc010oip.1","chr1",39456915,39471735] +[["uc010oiq.1"],"knownGene","uc010oiq.1","chr1",39456915,39471735] +[["uc001ccx.2"],"knownGene","uc001ccx.2","chr1",39492005,39500286] +[["uc001ccy.2"],"knownGene","uc001ccy.2","chr1",39492044,39500286] +[["uc010ois.1"],"knownGene","uc010ois.1","chr1",39547117,39952789] +[["uc010oir.1"],"knownGene","uc010oir.1","chr1",39547117,39568889] +[["uc001cda.1"],"knownGene","uc001cda.1","chr1",39587984,39901433] +[["uc010oit.1"],"knownGene","uc010oit.1","chr1",39670422,39748740] +[["uc001cdc.1"],"knownGene","uc001cdc.1","chr1",39765881,39901433] +[["uc001cdb.1"],"knownGene","uc001cdb.1","chr1",39765881,39839145] +[["uc009vvq.1"],"knownGene","uc009vvq.1","chr1",39765881,39790406] +[["uc010oiu.1"],"knownGene","uc010oiu.1","chr1",39796809,39952789] +[["uc009vvt.1"],"knownGene","uc009vvt.1","chr1",39875175,39882154] +[["uc001cde.1"],"knownGene","uc001cde.1","chr1",39927554,39952789] +[["uc001cdf.1"],"knownGene","uc001cdf.1","chr1",39927554,39952789] +[["uc001cdg.2"],"knownGene","uc001cdg.2","chr1",39934268,39952654] +[["uc001cdh.2"],"knownGene","uc001cdh.2","chr1",39934286,39952654] +[["uc001cdi.2"],"knownGene","uc001cdi.2","chr1",39957317,39995537] +[["uc001cdk.2"],"knownGene","uc001cdk.2","chr1",39987952,40025370] +[["uc001cdj.1"],"knownGene","uc001cdj.1","chr1",39987952,39991357] +[["uc001cdl.2"],"knownGene","uc001cdl.2","chr1",40026484,40042521] +[["uc010oiv.1"],"knownGene","uc010oiv.1","chr1",40026484,40042521] +[["uc001cdm.2"],"knownGene","uc001cdm.2","chr1",40026484,40042521] +[["uc001cdo.1"],"knownGene","uc001cdo.1","chr1",40033045,40033182] +[["uc001cdp.2"],"knownGene","uc001cdp.2","chr1",40089103,40105348] +[["uc010oiw.1"],"knownGene","uc010oiw.1","chr1",40089103,40098672] +[["uc001cdq.1"],"knownGene","uc001cdq.1","chr1",40124792,40137710] +[["uc001cdr.2"],"knownGene","uc001cdr.2","chr1",40144651,40157089] +[["uc010oix.1"],"knownGene","uc010oix.1","chr1",40144651,40157089] +[["uc001cdv.2"],"knownGene","uc001cdv.2","chr1",40204529,40229585] +[["uc001cdw.2"],"knownGene","uc001cdw.2","chr1",40204529,40229585] +[["uc001cds.1"],"knownGene","uc001cds.1","chr1",40204529,40219378] +[["uc001cdt.1"],"knownGene","uc001cdt.1","chr1",40204529,40219378] +[["uc010oiy.1"],"knownGene","uc010oiy.1","chr1",40204529,40219378] +[["uc001cdu.1"],"knownGene","uc001cdu.1","chr1",40204529,40219378] +[["uc001cdx.1"],"knownGene","uc001cdx.1","chr1",40208176,40219378] +[["uc001cdz.1"],"knownGene","uc001cdz.1","chr1",40223902,40254533] +[["uc001cea.1"],"knownGene","uc001cea.1","chr1",40229222,40254533] +[["uc001ceb.1"],"knownGene","uc001ceb.1","chr1",40235196,40237020] +[["uc009vvu.1"],"knownGene","uc009vvu.1","chr1",40235202,40237017] +[["uc010oiz.1"],"knownGene","uc010oiz.1","chr1",40306707,40349177] +[["uc001ceq.2"],"knownGene","uc001ceq.2","chr1",40306707,40349177] +[["uc001cek.2"],"knownGene","uc001cek.2","chr1",40306707,40349177] +[["uc009vvx.2"],"knownGene","uc009vvx.2","chr1",40306707,40349177] +[["uc001cel.2"],"knownGene","uc001cel.2","chr1",40306707,40349177] +[["uc001cem.2"],"knownGene","uc001cem.2","chr1",40306707,40349177] +[["uc001cen.2"],"knownGene","uc001cen.2","chr1",40306707,40349177] +[["uc001ceo.2"],"knownGene","uc001ceo.2","chr1",40306707,40349177] +[["uc001cep.2"],"knownGene","uc001cep.2","chr1",40306707,40349177] +[["uc001cec.3"],"knownGene","uc001cec.3","chr1",40306707,40319738] +[["uc001ced.3"],"knownGene","uc001ced.3","chr1",40306707,40319738] +[["uc001cee.3"],"knownGene","uc001cee.3","chr1",40306707,40319738] +[["uc001cef.3"],"knownGene","uc001cef.3","chr1",40306707,40319738] +[["uc001ceg.3"],"knownGene","uc001ceg.3","chr1",40306707,40319738] +[["uc001ceh.3"],"knownGene","uc001ceh.3","chr1",40306707,40319738] +[["uc009vvv.2"],"knownGene","uc009vvv.2","chr1",40306707,40319738] +[["uc001cei.3"],"knownGene","uc001cei.3","chr1",40306707,40319738] +[["uc010oja.1"],"knownGene","uc010oja.1","chr1",40319464,40319738] +[["uc001cer.1"],"knownGene","uc001cer.1","chr1",40361097,40367687] +[["uc001ces.1"],"knownGene","uc001ces.1","chr1",40361097,40367687] +[["uc001cet.1"],"knownGene","uc001cet.1","chr1",40365285,40367687] +[["uc001cev.2"],"knownGene","uc001cev.2","chr1",40420783,40435627] +[["uc001ceu.2"],"knownGene","uc001ceu.2","chr1",40420783,40435627] +[["uc010ojc.1"],"knownGene","uc010ojc.1","chr1",40420783,40435627] +[["uc009vvy.2"],"knownGene","uc009vvy.2","chr1",40420783,40435627] +[["uc010ojb.1"],"knownGene","uc010ojb.1","chr1",40420783,40434417] +[["uc001cew.1"],"knownGene","uc001cew.1","chr1",40420819,40422587] +[["uc001cex.2"],"knownGene","uc001cex.2","chr1",40432749,40435627] +[["uc001cfa.3"],"knownGene","uc001cfa.3","chr1",40506254,40538323] +[["uc001cey.3"],"knownGene","uc001cey.3","chr1",40506254,40538323] +[["uc001cez.3"],"knownGene","uc001cez.3","chr1",40506254,40538323] +[["uc009vvz.2"],"knownGene","uc009vvz.2","chr1",40506254,40538323] +[["uc010oje.1"],"knownGene","uc010oje.1","chr1",40506254,40538323] +[["uc010ojd.1"],"knownGene","uc010ojd.1","chr1",40506254,40525833] +[["uc001cfb.2"],"knownGene","uc001cfb.2","chr1",40538381,40563142] +[["uc010ojg.1"],"knownGene","uc010ojg.1","chr1",40538381,40563142] +[["uc009vwa.2"],"knownGene","uc009vwa.2","chr1",40538381,40563142] +[["uc010ojf.1"],"knownGene","uc010ojf.1","chr1",40538381,40558179] +[["uc001cfc.3"],"knownGene","uc001cfc.3","chr1",40627040,40706592] +[["uc001cfd.3"],"knownGene","uc001cfd.3","chr1",40696475,40706592] +[["uc001cfe.2"],"knownGene","uc001cfe.2","chr1",40713572,40717365] +[["uc001cff.2"],"knownGene","uc001cff.2","chr1",40722099,40723658] +[["uc001cfg.2"],"knownGene","uc001cfg.2","chr1",40723732,40759855] +[["uc001cfi.1"],"knownGene","uc001cfi.1","chr1",40766162,40783060] +[["uc001cfh.1"],"knownGene","uc001cfh.1","chr1",40766162,40782981] +[["uc001cfj.2"],"knownGene","uc001cfj.2","chr1",40839727,40888992] +[["uc010ojh.1"],"knownGene","uc010ojh.1","chr1",40839727,40882027] +[["uc001cfk.2"],"knownGene","uc001cfk.2","chr1",40840316,40888992] +[["uc010oji.1"],"knownGene","uc010oji.1","chr1",40862471,40888992] +[["uc010ojj.1"],"knownGene","uc010ojj.1","chr1",40879644,40888992] +[["uc001cfl.1"],"knownGene","uc001cfl.1","chr1",40915778,40929352] +[["uc001cfm.1"],"knownGene","uc001cfm.1","chr1",40915778,40929352] +[["uc001cfn.1"],"knownGene","uc001cfn.1","chr1",40916336,40929352] +[["uc001cfo.2"],"knownGene","uc001cfo.2","chr1",40943301,40962014] +[["uc009vwb.2"],"knownGene","uc009vwb.2","chr1",40943301,40962014] +[["uc010ojk.1"],"knownGene","uc010ojk.1","chr1",40943301,40962014] +[["uc001cfp.2"],"knownGene","uc001cfp.2","chr1",40974432,40982212] +[["uc001cfq.2"],"knownGene","uc001cfq.2","chr1",40974432,40982212] +[["uc001cfr.2"],"knownGene","uc001cfr.2","chr1",40974460,40982212] +[["uc001cfs.2"],"knownGene","uc001cfs.2","chr1",40974469,40982212] +[["uc001cft.1"],"knownGene","uc001cft.1","chr1",40997232,41013839] +[["uc001cfu.1"],"knownGene","uc001cfu.1","chr1",41086351,41131324] +[["uc001cfv.1"],"knownGene","uc001cfv.1","chr1",41086351,41131324] +[["uc010ojl.1"],"knownGene","uc010ojl.1","chr1",41154751,41157933] +[["uc001cfx.3"],"knownGene","uc001cfx.3","chr1",41157241,41237273] +[["uc009vwd.2"],"knownGene","uc009vwd.2","chr1",41157241,41237273] +[["uc001cfz.2"],"knownGene","uc001cfz.2","chr1",41157241,41237273] +[["uc010ojn.1"],"knownGene","uc010ojn.1","chr1",41157241,41237273] +[["uc001cfy.3"],"knownGene","uc001cfy.3","chr1",41157241,41237273] +[["uc010ojm.1"],"knownGene","uc010ojm.1","chr1",41157241,41232915] +[["uc001cgc.2"],"knownGene","uc001cgc.2","chr1",41157679,41237273] +[["uc001cgb.2"],"knownGene","uc001cgb.2","chr1",41175037,41237273] +[["uc001cgd.3"],"knownGene","uc001cgd.3","chr1",41201296,41237273] +[["uc001cge.2"],"knownGene","uc001cge.2","chr1",41204507,41237273] +[["uc001cgf.1"],"knownGene","uc001cgf.1","chr1",41220041,41220105] +[["uc001cgg.2"],"knownGene","uc001cgg.2","chr1",41222955,41223043] +[["uc001cgh.1"],"knownGene","uc001cgh.1","chr1",41249683,41304360] +[["uc001cgi.1"],"knownGene","uc001cgi.1","chr1",41249683,41304360] +[["uc001cgj.2"],"knownGene","uc001cgj.2","chr1",41326728,41328018] +[["uc001cgk.3"],"knownGene","uc001cgk.3","chr1",41445006,41478231] +[["uc010ojo.1"],"knownGene","uc010ojo.1","chr1",41445006,41478231] +[["uc010ojp.1"],"knownGene","uc010ojp.1","chr1",41447600,41462029] +[["uc001cgl.3"],"knownGene","uc001cgl.3","chr1",41448832,41478231] +[["uc010ojq.1"],"knownGene","uc010ojq.1","chr1",41454190,41478231] +[["uc009vwe.2"],"knownGene","uc009vwe.2","chr1",41461588,41478231] +[["uc009vwg.1"],"knownGene","uc009vwg.1","chr1",41481268,41487397] +[["uc001cgm.1"],"knownGene","uc001cgm.1","chr1",41481268,41487387] +[["uc001cgn.1"],"knownGene","uc001cgn.1","chr1",41481268,41487387] +[["uc009vwf.1"],"knownGene","uc009vwf.1","chr1",41481268,41486458] +[["uc001cgq.2"],"knownGene","uc001cgq.2","chr1",41492874,41707788] +[["uc001cgr.2"],"knownGene","uc001cgr.2","chr1",41492874,41707788] +[["uc001cgs.2"],"knownGene","uc001cgs.2","chr1",41492874,41707788] +[["uc001cgt.2"],"knownGene","uc001cgt.2","chr1",41492874,41707788] +[["uc001cgp.2"],"knownGene","uc001cgp.2","chr1",41492874,41628689] +[["uc001cgo.2"],"knownGene","uc001cgo.2","chr1",41492874,41627104] +[["uc010ojr.1"],"knownGene","uc010ojr.1","chr1",41492874,41625605] +[["uc010ojs.1"],"knownGene","uc010ojs.1","chr1",41494255,41625605] +[["uc001cgx.2"],"knownGene","uc001cgx.2","chr1",41944448,41950344] +[["uc001cgu.2"],"knownGene","uc001cgu.2","chr1",41944448,41949874] +[["uc001cgv.2"],"knownGene","uc001cgv.2","chr1",41944448,41949874] +[["uc009vwh.2"],"knownGene","uc009vwh.2","chr1",41944448,41949874] +[["uc001cgw.2"],"knownGene","uc001cgw.2","chr1",41944448,41949874] +[["uc009vwi.2"],"knownGene","uc009vwi.2","chr1",41944448,41949874] +[["uc009vwj.2"],"knownGene","uc009vwj.2","chr1",41944448,41949874] +[["uc001cgz.3"],"knownGene","uc001cgz.3","chr1",41975684,42384496] +[["uc001cha.3"],"knownGene","uc001cha.3","chr1",41975684,42384496] +[["uc001cgy.2"],"knownGene","uc001cgy.2","chr1",41975684,42050989] +[["uc001chb.1"],"knownGene","uc001chb.1","chr1",42312861,42501596] +[["uc001chc.1"],"knownGene","uc001chc.1","chr1",42619091,42621495] +[["uc001chd.1"],"knownGene","uc001chd.1","chr1",42628361,42630395] +[["uc001chg.2"],"knownGene","uc001chg.2","chr1",42642210,42801548] +[["uc001chf.2"],"knownGene","uc001chf.2","chr1",42642210,42800903] +[["uc001che.2"],"knownGene","uc001che.2","chr1",42642210,42800636] +[["uc001chh.1"],"knownGene","uc001chh.1","chr1",42656973,42800903] +[["uc001chi.2"],"knownGene","uc001chi.2","chr1",42846467,42889900] +[["uc001chj.2"],"knownGene","uc001chj.2","chr1",42896002,42921938] +[["uc010ojt.1"],"knownGene","uc010ojt.1","chr1",42896002,42921938] +[["uc001chk.2"],"knownGene","uc001chk.2","chr1",42922172,42926085] +[["uc001chl.2"],"knownGene","uc001chl.2","chr1",42922172,42926085] +[["uc001chm.2"],"knownGene","uc001chm.2","chr1",42929024,43120335] +[["uc001chn.2"],"knownGene","uc001chn.2","chr1",42955599,43120335] +[["uc010oju.1"],"knownGene","uc010oju.1","chr1",42962768,43047185] +[["uc009vwk.1"],"knownGene","uc009vwk.1","chr1",43000559,43120335] +[["uc001chp.2"],"knownGene","uc001chp.2","chr1",43002146,43061217] +[["uc001chq.2"],"knownGene","uc001chq.2","chr1",43124047,43142428] +[["uc009vwl.2"],"knownGene","uc009vwl.2","chr1",43124047,43133568] +[["uc001chr.2"],"knownGene","uc001chr.2","chr1",43144356,43147329] +[["uc001chs.2"],"knownGene","uc001chs.2","chr1",43148065,43168017] +[["uc001cht.1"],"knownGene","uc001cht.1","chr1",43198763,43205925] +[["uc001chu.2"],"knownGene","uc001chu.2","chr1",43198763,43205925] +[["uc010ojv.1"],"knownGene","uc010ojv.1","chr1",43198763,43205925] +[["uc001chv.2"],"knownGene","uc001chv.2","chr1",43212005,43232755] +[["uc001chw.2"],"knownGene","uc001chw.2","chr1",43212005,43232755] +[["uc001chx.3"],"knownGene","uc001chx.3","chr1",43212045,43232755] +[["uc001chy.3"],"knownGene","uc001chy.3","chr1",43225667,43232755] +[["uc001chz.2"],"knownGene","uc001chz.2","chr1",43231122,43232696] +[["uc001cia.3"],"knownGene","uc001cia.3","chr1",43232915,43241414] +[["uc001cib.2"],"knownGene","uc001cib.2","chr1",43272722,43283059] +[["uc001cic.1"],"knownGene","uc001cic.1","chr1",43282775,43310660] +[["uc001cid.1"],"knownGene","uc001cid.1","chr1",43282775,43310660] +[["uc010ojw.1"],"knownGene","uc010ojw.1","chr1",43282775,43305384] +[["uc001cie.1"],"knownGene","uc001cie.1","chr1",43291248,43310660] +[["uc001cif.1"],"knownGene","uc001cif.1","chr1",43295585,43310660] +[["uc001cig.2"],"knownGene","uc001cig.2","chr1",43312279,43318144] +[["uc009vwm.2"],"knownGene","uc009vwm.2","chr1",43312279,43318144] +[["uc001cih.2"],"knownGene","uc001cih.2","chr1",43314961,43318144] +[["uc001cij.1"],"knownGene","uc001cij.1","chr1",43323292,43354460] +[["uc001cik.2"],"knownGene","uc001cik.2","chr1",43391045,43424847] +[["uc001cil.2"],"knownGene","uc001cil.2","chr1",43424774,43448990] +[["uc009vwn.1"],"knownGene","uc009vwn.1","chr1",43585818,43611958] +[["uc009vwo.2"],"knownGene","uc009vwo.2","chr1",43613593,43622064] +[["uc001cio.2"],"knownGene","uc001cio.2","chr1",43629845,43736607] +[["uc010ojx.1"],"knownGene","uc010ojx.1","chr1",43629845,43638241] +[["uc001cin.2"],"knownGene","uc001cin.2","chr1",43629845,43637986] +[["uc001cim.2"],"knownGene","uc001cim.2","chr1",43629845,43637649] +[["uc010ojy.1"],"knownGene","uc010ojy.1","chr1",43637279,43637416] +[["uc001cip.1"],"knownGene","uc001cip.1","chr1",43638025,43676549] +[["uc001ciq.1"],"knownGene","uc001ciq.1","chr1",43638025,43676549] +[["uc010ojz.1"],"knownGene","uc010ojz.1","chr1",43638025,43675788] +[["uc001cir.2"],"knownGene","uc001cir.2","chr1",43735695,43739672] +[["uc001cis.2"],"knownGene","uc001cis.2","chr1",43736256,43739672] +[["uc001cit.3"],"knownGene","uc001cit.3","chr1",43747558,43751250] +[["uc001ciu.2"],"knownGene","uc001ciu.2","chr1",43766663,43788778] +[["uc010oke.1"],"knownGene","uc010oke.1","chr1",43766663,43788778] +[["uc009vwq.2"],"knownGene","uc009vwq.2","chr1",43766663,43788778] +[["uc010okd.1"],"knownGene","uc010okd.1","chr1",43766663,43779133] +[["uc010okc.1"],"knownGene","uc010okc.1","chr1",43766663,43775203] +[["uc010okb.1"],"knownGene","uc010okb.1","chr1",43766663,43772781] +[["uc010oka.1"],"knownGene","uc010oka.1","chr1",43766663,43770948] +[["uc010okf.1"],"knownGene","uc010okf.1","chr1",43770604,43779817] +[["uc010okg.1"],"knownGene","uc010okg.1","chr1",43772812,43788778] +[["uc001ciw.2"],"knownGene","uc001ciw.2","chr1",43803474,43820134] +[["uc009vwr.2"],"knownGene","uc009vwr.2","chr1",43803474,43820134] +[["uc001civ.2"],"knownGene","uc001civ.2","chr1",43803474,43815206] +[["uc001cix.2"],"knownGene","uc001cix.2","chr1",43824625,43828871] +[["uc001ciy.2"],"knownGene","uc001ciy.2","chr1",43824691,43828871] +[["uc001cjb.2"],"knownGene","uc001cjb.2","chr1",43829072,43833699] +[["uc001cjc.2"],"knownGene","uc001cjc.2","chr1",43829072,43833699] +[["uc010okh.1"],"knownGene","uc010okh.1","chr1",43829072,43833699] +[["uc001cja.2"],"knownGene","uc001cja.2","chr1",43829072,43833361] +[["uc001ciz.2"],"knownGene","uc001ciz.2","chr1",43829072,43833087] +[["uc001cje.1"],"knownGene","uc001cje.1","chr1",43849587,43855483] +[["uc001cjg.3"],"knownGene","uc001cjg.3","chr1",43850397,43855483] +[["uc001cjf.3"],"knownGene","uc001cjf.3","chr1",43850397,43855483] +[["uc009vws.1"],"knownGene","uc009vws.1","chr1",43855555,43892209] +[["uc001cji.1"],"knownGene","uc001cji.1","chr1",43855555,43878462] +[["uc001cjh.2"],"knownGene","uc001cjh.2","chr1",43855555,43872564] +[["uc001cjk.1"],"knownGene","uc001cjk.1","chr1",43888769,43918304] +[["uc001cjl.1"],"knownGene","uc001cjl.1","chr1",43910922,43918304] +[["uc001cjp.2"],"knownGene","uc001cjp.2","chr1",43916830,43919918] +[["uc001cjn.2"],"knownGene","uc001cjn.2","chr1",43916830,43919634] +[["uc001cjo.2"],"knownGene","uc001cjo.2","chr1",43916830,43919634] +[["uc001cjm.2"],"knownGene","uc001cjm.2","chr1",43916830,43919176] +[["uc001cjr.2"],"knownGene","uc001cjr.2","chr1",43996546,44089342] +[["uc001cjs.2"],"knownGene","uc001cjs.2","chr1",43996546,44089342] +[["uc001cjq.3"],"knownGene","uc001cjq.3","chr1",43996546,44045732] +[["uc001cjt.3"],"knownGene","uc001cjt.3","chr1",44003868,44045732] +[["uc001cju.2"],"knownGene","uc001cju.2","chr1",44056642,44089342] +[["uc009vwt.2"],"knownGene","uc009vwt.2","chr1",44056642,44089342] +[["uc001cjv.2"],"knownGene","uc001cjv.2","chr1",44056642,44089342] +[["uc001cjw.2"],"knownGene","uc001cjw.2","chr1",44063744,44089342] +[["uc001cjx.2"],"knownGene","uc001cjx.2","chr1",44115796,44171188] +[["uc010oki.1"],"knownGene","uc010oki.1","chr1",44115796,44171188] +[["uc001cjy.2"],"knownGene","uc001cjy.2","chr1",44165357,44173012] +[["uc009vwu.1"],"knownGene","uc009vwu.1","chr1",44171494,44360149] +[["uc001cjz.2"],"knownGene","uc001cjz.2","chr1",44173217,44396830] +[["uc001cka.2"],"knownGene","uc001cka.2","chr1",44173217,44396830] +[["uc001ckb.2"],"knownGene","uc001ckb.2","chr1",44173217,44396830] +[["uc001ckc.2"],"knownGene","uc001ckc.2","chr1",44173217,44396830] +[["uc001ckd.2"],"knownGene","uc001ckd.2","chr1",44173217,44396830] +[["uc001cke.2"],"knownGene","uc001cke.2","chr1",44173217,44396830] +[["uc001ckf.2"],"knownGene","uc001ckf.2","chr1",44173217,44396830] +[["uc001ckg.2"],"knownGene","uc001ckg.2","chr1",44173217,44396830] +[["uc001ckh.2"],"knownGene","uc001ckh.2","chr1",44173217,44396830] +[["uc001cki.2"],"knownGene","uc001cki.2","chr1",44173217,44396830] +[["uc010okj.1"],"knownGene","uc010okj.1","chr1",44173217,44385889] +[["uc009vwv.2"],"knownGene","uc009vwv.2","chr1",44201903,44396830] +[["uc001ckj.2"],"knownGene","uc001ckj.2","chr1",44201903,44396830] +[["uc009vww.2"],"knownGene","uc009vww.2","chr1",44201903,44396830] +[["uc001ckk.2"],"knownGene","uc001ckk.2","chr1",44201903,44396830] +[["uc009vwy.2"],"knownGene","uc009vwy.2","chr1",44201903,44396830] +[["uc009vwx.2"],"knownGene","uc009vwx.2","chr1",44201903,44396830] +[["uc001ckm.2"],"knownGene","uc001ckm.2","chr1",44201903,44396830] +[["uc001ckl.2"],"knownGene","uc001ckl.2","chr1",44201903,44396830] +[["uc009vwz.2"],"knownGene","uc009vwz.2","chr1",44201903,44396830] +[["uc001ckn.2"],"knownGene","uc001ckn.2","chr1",44201903,44396830] +[["uc001ckp.2"],"knownGene","uc001ckp.2","chr1",44201903,44396830] +[["uc001cko.2"],"knownGene","uc001cko.2","chr1",44201903,44396830] +[["uc009vxa.2"],"knownGene","uc009vxa.2","chr1",44201903,44396830] +[["uc001ckq.2"],"knownGene","uc001ckq.2","chr1",44201903,44396830] +[["uc001ckr.2"],"knownGene","uc001ckr.2","chr1",44201903,44396830] +[["uc009vxb.2"],"knownGene","uc009vxb.2","chr1",44201903,44396830] +[["uc001cks.2"],"knownGene","uc001cks.2","chr1",44398991,44402911] +[["uc001ckv.2"],"knownGene","uc001ckv.2","chr1",44398991,44402911] +[["uc001ckt.2"],"knownGene","uc001ckt.2","chr1",44398991,44402911] +[["uc001cku.2"],"knownGene","uc001cku.2","chr1",44401030,44402911] +[["uc001ckw.2"],"knownGene","uc001ckw.2","chr1",44401653,44402911] +[["uc001ckx.2"],"knownGene","uc001ckx.2","chr1",44412477,44433693] +[["uc001cky.2"],"knownGene","uc001cky.2","chr1",44431610,44433693] +[["uc001ckz.2"],"knownGene","uc001ckz.2","chr1",44435652,44439044] +[["uc001cla.2"],"knownGene","uc001cla.2","chr1",44435652,44439044] +[["uc010okk.1"],"knownGene","uc010okk.1","chr1",44435652,44439044] +[["uc001clb.2"],"knownGene","uc001clb.2","chr1",44435681,44439044] +[["uc001cld.2"],"knownGene","uc001cld.2","chr1",44440601,44443971] +[["uc001cle.2"],"knownGene","uc001cle.2","chr1",44440601,44443971] +[["uc001clc.2"],"knownGene","uc001clc.2","chr1",44440601,44443966] +[["uc001clf.2"],"knownGene","uc001clf.2","chr1",44440642,44443966] +[["uc001clg.2"],"knownGene","uc001clg.2","chr1",44444865,44456839] +[["uc001clh.2"],"knownGene","uc001clh.2","chr1",44444865,44456839] +[["uc010okl.1"],"knownGene","uc010okl.1","chr1",44445658,44456839] +[["uc001cli.2"],"knownGene","uc001cli.2","chr1",44446182,44456839] +[["uc010okm.1"],"knownGene","uc010okm.1","chr1",44457171,44497134] +[["uc009vxe.2"],"knownGene","uc009vxe.2","chr1",44457171,44482228] +[["uc001clj.2"],"knownGene","uc001clj.2","chr1",44457279,44462196] +[["uc001clk.2"],"knownGene","uc001clk.2","chr1",44457473,44462196] +[["uc009vxc.2"],"knownGene","uc009vxc.2","chr1",44457518,44462196] +[["uc001cln.2"],"knownGene","uc001cln.2","chr1",44462155,44497134] +[["uc010oko.1"],"knownGene","uc010oko.1","chr1",44462155,44497134] +[["uc001cll.2"],"knownGene","uc001cll.2","chr1",44462155,44482997] +[["uc001clm.2"],"knownGene","uc001clm.2","chr1",44462155,44482997] +[["uc009vxd.2"],"knownGene","uc009vxd.2","chr1",44462155,44482997] +[["uc010okn.1"],"knownGene","uc010okn.1","chr1",44462155,44482997] +[["uc010okp.1"],"knownGene","uc010okp.1","chr1",44466438,44497134] +[["uc009vxf.1"],"knownGene","uc009vxf.1","chr1",44514029,44595868] +[["uc001clp.2"],"knownGene","uc001clp.2","chr1",44584521,44600807] +[["uc001clq.1"],"knownGene","uc001clq.1","chr1",44679124,44686351] +[["uc001clr.1"],"knownGene","uc001clr.1","chr1",44679124,44686351] +[["uc001cls.1"],"knownGene","uc001cls.1","chr1",44679124,44686351] +[["uc010oku.1"],"knownGene","uc010oku.1","chr1",44679124,44686351] +[["uc010okt.1"],"knownGene","uc010okt.1","chr1",44679124,44684427] +[["uc010oks.1"],"knownGene","uc010oks.1","chr1",44679124,44681440] +[["uc010okq.1"],"knownGene","uc010okq.1","chr1",44679124,44681197] +[["uc010okr.1"],"knownGene","uc010okr.1","chr1",44679124,44681197] +[["uc001clt.2"],"knownGene","uc001clt.2","chr1",44686742,44820939] +[["uc009vxg.2"],"knownGene","uc009vxg.2","chr1",44686742,44820939] +[["uc010okw.1"],"knownGene","uc010okw.1","chr1",44686742,44820939] +[["uc001clu.2"],"knownGene","uc001clu.2","chr1",44686742,44820939] +[["uc010okv.1"],"knownGene","uc010okv.1","chr1",44686742,44818597] +[["uc001clv.1"],"knownGene","uc001clv.1","chr1",44870959,45117396] +[["uc001clw.1"],"knownGene","uc001clw.1","chr1",44871049,45117396] +[["uc010oky.1"],"knownGene","uc010oky.1","chr1",44889495,45117396] +[["uc010okx.1"],"knownGene","uc010okx.1","chr1",44889495,45110466] +[["uc001clx.1"],"knownGene","uc001clx.1","chr1",45097651,45117396] +[["uc010okz.1"],"knownGene","uc010okz.1","chr1",45097651,45117395] +[["uc001cly.1"],"knownGene","uc001cly.1","chr1",45097663,45117396] +[["uc001clz.1"],"knownGene","uc001clz.1","chr1",45097926,45117396] +[["uc001cma.1"],"knownGene","uc001cma.1","chr1",45098014,45117395] +[["uc001cmb.1"],"knownGene","uc001cmb.1","chr1",45100938,45140099] +[["uc001cmc.2"],"knownGene","uc001cmc.2","chr1",45119501,45140099] +[["uc001cmd.2"],"knownGene","uc001cmd.2","chr1",45119501,45140099] +[["uc009vxh.1"],"knownGene","uc009vxh.1","chr1",45119653,45139750] +[["uc010ola.1"],"knownGene","uc010ola.1","chr1",45119908,45125967] +[["uc001cmf.2"],"knownGene","uc001cmf.2","chr1",45140393,45191263] +[["uc001cmg.3"],"knownGene","uc001cmg.3","chr1",45205489,45233436] +[["uc010olb.1"],"knownGene","uc010olb.1","chr1",45205489,45233436] +[["uc010olc.1"],"knownGene","uc010olc.1","chr1",45212065,45233436] +[["uc001cmh.3"],"knownGene","uc001cmh.3","chr1",45212084,45233436] +[["uc001cmi.2"],"knownGene","uc001cmi.2","chr1",45241245,45244411] +[["uc001cmj.1"],"knownGene","uc001cmj.1","chr1",45241536,45241610] +[["uc001cmk.1"],"knownGene","uc001cmk.1","chr1",45242163,45242261] +[["uc009vxi.2"],"knownGene","uc009vxi.2","chr1",45243513,45243582] +[["uc001cml.2"],"knownGene","uc001cml.2","chr1",45244061,45244129] +[["uc001cmm.2"],"knownGene","uc001cmm.2","chr1",45249258,45253426] +[["uc001cmn.2"],"knownGene","uc001cmn.2","chr1",45266035,45271666] +[["uc001cmo.2"],"knownGene","uc001cmo.2","chr1",45266707,45271666] +[["uc001cmp.2"],"knownGene","uc001cmp.2","chr1",45271589,45272957] +[["uc010ole.1"],"knownGene","uc010ole.1","chr1",45274153,45279801] +[["uc010old.1"],"knownGene","uc010old.1","chr1",45274153,45279171] +[["uc010olf.1"],"knownGene","uc010olf.1","chr1",45288087,45308616] +[["uc010olg.1"],"knownGene","uc010olg.1","chr1",45288087,45308616] +[["uc001cmt.1"],"knownGene","uc001cmt.1","chr1",45316449,45452282] +[["uc001cmu.1"],"knownGene","uc001cmu.1","chr1",45316449,45452282] +[["uc001cmv.1"],"knownGene","uc001cmv.1","chr1",45316449,45452282] +[["uc001cmw.2"],"knownGene","uc001cmw.2","chr1",45340224,45452282] +[["uc009vxk.2"],"knownGene","uc009vxk.2","chr1",45468220,45477027] +[["uc010olh.1"],"knownGene","uc010olh.1","chr1",45468220,45477027] +[["uc001cmy.3"],"knownGene","uc001cmy.3","chr1",45468220,45474223] +[["uc001cmx.3"],"knownGene","uc001cmx.3","chr1",45468220,45471260] +[["uc001cna.1"],"knownGene","uc001cna.1","chr1",45477829,45481341] +[["uc001cnb.1"],"knownGene","uc001cnb.1","chr1",45477829,45481341] +[["uc010oli.1"],"knownGene","uc010oli.1","chr1",45477829,45479662] +[["uc010olj.1"],"knownGene","uc010olj.1","chr1",45478480,45480508] +[["uc001cnc.1"],"knownGene","uc001cnc.1","chr1",45478528,45481341] +[["uc001cnd.2"],"knownGene","uc001cnd.2","chr1",45482075,45672250] +[["uc010olk.1"],"knownGene","uc010olk.1","chr1",45769581,45771290] +[["uc001cne.2"],"knownGene","uc001cne.2","chr1",45792544,45794344] +[["uc001cno.2"],"knownGene","uc001cno.2","chr1",45794914,45806142] +[["uc001cnk.2"],"knownGene","uc001cnk.2","chr1",45794914,45806142] +[["uc010oll.1"],"knownGene","uc010oll.1","chr1",45794914,45806142] +[["uc001cnm.2"],"knownGene","uc001cnm.2","chr1",45794914,45806142] +[["uc001cnl.2"],"knownGene","uc001cnl.2","chr1",45794914,45806142] +[["uc009vxp.2"],"knownGene","uc009vxp.2","chr1",45794914,45806142] +[["uc001cnn.2"],"knownGene","uc001cnn.2","chr1",45794914,45806142] +[["uc001cnj.2"],"knownGene","uc001cnj.2","chr1",45794914,45805787] +[["uc001cni.2"],"knownGene","uc001cni.2","chr1",45794914,45805787] +[["uc001cnh.2"],"knownGene","uc001cnh.2","chr1",45794914,45805787] +[["uc001cnf.2"],"knownGene","uc001cnf.2","chr1",45794914,45805629] +[["uc009vxo.2"],"knownGene","uc009vxo.2","chr1",45794914,45805629] +[["uc001cng.2"],"knownGene","uc001cng.2","chr1",45794914,45805629] +[["uc009vxn.2"],"knownGene","uc009vxn.2","chr1",45794914,45800183] +[["uc009vxq.2"],"knownGene","uc009vxq.2","chr1",45805341,45809649] +[["uc001cnq.3"],"knownGene","uc001cnq.3","chr1",45805341,45809649] +[["uc010olm.1"],"knownGene","uc010olm.1","chr1",45805341,45809649] +[["uc010oln.1"],"knownGene","uc010oln.1","chr1",45805883,45808674] +[["uc001cnr.3"],"knownGene","uc001cnr.3","chr1",45805892,45809649] +[["uc001cns.1"],"knownGene","uc001cns.1","chr1",45809554,45956840] +[["uc010olo.1"],"knownGene","uc010olo.1","chr1",45809554,45956840] +[["uc009vxs.1"],"knownGene","uc009vxs.1","chr1",45809554,45956840] +[["uc009vxr.1"],"knownGene","uc009vxr.1","chr1",45809554,45923543] +[["uc010olp.1"],"knownGene","uc010olp.1","chr1",45864143,45956840] +[["uc001cnw.2"],"knownGene","uc001cnw.2","chr1",45960580,45965646] +[["uc001cnu.2"],"knownGene","uc001cnu.2","chr1",45960580,45965646] +[["uc009vxt.1"],"knownGene","uc009vxt.1","chr1",45960580,45965646] +[["uc001cnv.2"],"knownGene","uc001cnv.2","chr1",45960580,45965646] +[["uc009vxu.1"],"knownGene","uc009vxu.1","chr1",45960580,45965646] +[["uc001cnt.2"],"knownGene","uc001cnt.2","chr1",45960580,45964294] +[["uc009vxv.2"],"knownGene","uc009vxv.2","chr1",45965855,45976737] +[["uc001cny.2"],"knownGene","uc001cny.2","chr1",45965855,45976737] +[["uc001coa.2"],"knownGene","uc001coa.2","chr1",45976707,45987609] +[["uc001cob.2"],"knownGene","uc001cob.2","chr1",45976707,45987609] +[["uc001coc.2"],"knownGene","uc001coc.2","chr1",45976707,45987609] +[["uc001cnz.2"],"knownGene","uc001cnz.2","chr1",45976707,45984747] +[["uc001cod.2"],"knownGene","uc001cod.2","chr1",46016497,46035720] +[["uc001coe.2"],"knownGene","uc001coe.2","chr1",46016497,46035720] +[["uc009vxw.2"],"knownGene","uc009vxw.2","chr1",46016497,46033753] +[["uc001cof.2"],"knownGene","uc001cof.2","chr1",46033220,46035720] +[["uc001cog.2"],"knownGene","uc001cog.2","chr1",46033653,46035720] +[["uc001coh.1"],"knownGene","uc001coh.1","chr1",46049716,46084567] +[["uc001coi.1"],"knownGene","uc001coi.1","chr1",46049716,46084567] +[["uc001coj.1"],"knownGene","uc001coj.1","chr1",46049716,46084567] +[["uc010olr.1"],"knownGene","uc010olr.1","chr1",46049716,46084567] +[["uc010olq.1"],"knownGene","uc010olq.1","chr1",46049716,46078920] +[["uc001cok.1"],"knownGene","uc001cok.1","chr1",46067732,46075186] +[["uc001col.1"],"knownGene","uc001col.1","chr1",46077134,46084567] +[["uc009vxy.2"],"knownGene","uc009vxy.2","chr1",46085716,46089729] +[["uc010ols.1"],"knownGene","uc010ols.1","chr1",46085716,46089729] +[["uc010olt.1"],"knownGene","uc010olt.1","chr1",46085716,46089729] +[["uc001com.3"],"knownGene","uc001com.3","chr1",46085716,46089729] +[["uc001con.3"],"knownGene","uc001con.3","chr1",46085716,46089729] +[["uc009vxz.2"],"knownGene","uc009vxz.2","chr1",46085716,46089729] +[["uc001coq.2"],"knownGene","uc001coq.2","chr1",46092977,46152302] +[["uc001coo.2"],"knownGene","uc001coo.2","chr1",46092977,46101396] +[["uc010olu.1"],"knownGene","uc010olu.1","chr1",46111451,46112357] +[["uc001cor.1"],"knownGene","uc001cor.1","chr1",46153846,46160108] +[["uc001cos.3"],"knownGene","uc001cos.3","chr1",46159999,46216485] +[["uc001cou.2"],"knownGene","uc001cou.2","chr1",46164408,46216485] +[["uc001cov.2"],"knownGene","uc001cov.2","chr1",46269284,46501797] +[["uc001cow.2"],"knownGene","uc001cow.2","chr1",46269284,46501797] +[["uc001coy.1"],"knownGene","uc001coy.1","chr1",46330049,46496962] +[["uc001cox.1"],"knownGene","uc001cox.1","chr1",46330049,46472067] +[["uc001coz.1"],"knownGene","uc001coz.1","chr1",46379259,46496433] +[["uc009vya.2"],"knownGene","uc009vya.2","chr1",46379264,46489943] +[["uc001cpa.2"],"knownGene","uc001cpa.2","chr1",46471912,46501793] +[["uc010olw.1"],"knownGene","uc010olw.1","chr1",46505812,46642160] +[["uc001cpc.3"],"knownGene","uc001cpc.3","chr1",46505812,46598708] +[["uc009vyc.2"],"knownGene","uc009vyc.2","chr1",46505812,46598467] +[["uc001cpb.3"],"knownGene","uc001cpb.3","chr1",46505812,46598380] +[["uc009vyb.2"],"knownGene","uc009vyb.2","chr1",46505812,46598380] +[["uc010olv.1"],"knownGene","uc010olv.1","chr1",46505812,46527810] +[["uc001cpd.2"],"knownGene","uc001cpd.2","chr1",46640758,46651630] +[["uc009vyd.1"],"knownGene","uc009vyd.1","chr1",46646197,46651630] +[["uc001cpg.2"],"knownGene","uc001cpg.2","chr1",46654353,46685977] +[["uc001cpf.2"],"knownGene","uc001cpf.2","chr1",46654353,46685977] +[["uc001cpe.2"],"knownGene","uc001cpe.2","chr1",46654353,46664121] +[["uc010olz.1"],"knownGene","uc010olz.1","chr1",46654353,46663171] +[["uc010olx.1"],"knownGene","uc010olx.1","chr1",46654353,46663145] +[["uc010oly.1"],"knownGene","uc010oly.1","chr1",46654353,46663145] +[["uc001cpi.1"],"knownGene","uc001cpi.1","chr1",46655788,46659597] +[["uc001cph.1"],"knownGene","uc001cph.1","chr1",46655788,46658237] +[["uc001cpj.2"],"knownGene","uc001cpj.2","chr1",46661158,46663779] +[["uc010oma.1"],"knownGene","uc010oma.1","chr1",46669005,46686927] +[["uc009vye.2"],"knownGene","uc009vye.2","chr1",46713366,46744145] +[["uc001cpl.2"],"knownGene","uc001cpl.2","chr1",46713366,46744145] +[["uc001cpm.1"],"knownGene","uc001cpm.1","chr1",46724357,46744145] +[["uc001cpn.2"],"knownGene","uc001cpn.2","chr1",46744072,46769038] +[["uc010omb.1"],"knownGene","uc010omb.1","chr1",46744679,46769038] +[["uc001cpo.1"],"knownGene","uc001cpo.1","chr1",46750676,46769038] +[["uc001cpp.2"],"knownGene","uc001cpp.2","chr1",46769379,46782445] +[["uc001cpq.2"],"knownGene","uc001cpq.2","chr1",46769379,46782445] +[["uc001cpr.1"],"knownGene","uc001cpr.1","chr1",46806389,46830690] +[["uc010omc.1"],"knownGene","uc010omc.1","chr1",46806389,46830690] +[["uc009vyf.1"],"knownGene","uc009vyf.1","chr1",46806389,46830690] +[["uc009vyg.1"],"knownGene","uc009vyg.1","chr1",46806875,46830690] +[["uc001cpt.1"],"knownGene","uc001cpt.1","chr1",46807507,46830690] +[["uc001cps.1"],"knownGene","uc001cps.1","chr1",46807507,46830690] +[["uc001cpu.2"],"knownGene","uc001cpu.2","chr1",46859938,46879520] +[["uc001cpv.2"],"knownGene","uc001cpv.2","chr1",46871259,46879520] +[["uc001cpx.2"],"knownGene","uc001cpx.2","chr1",46972667,46979884] +[["uc001cpw.2"],"knownGene","uc001cpw.2","chr1",46972667,46979884] +[["uc009vyh.1"],"knownGene","uc009vyh.1","chr1",47011315,47016887] +[["uc001cpy.2"],"knownGene","uc001cpy.2","chr1",47011315,47015678] +[["uc001cqb.2"],"knownGene","uc001cqb.2","chr1",47023090,47069966] +[["uc010omd.1"],"knownGene","uc010omd.1","chr1",47023090,47069966] +[["uc001cqc.2"],"knownGene","uc001cqc.2","chr1",47023090,47069966] +[["uc009vyi.2"],"knownGene","uc009vyi.2","chr1",47023090,47069966] +[["uc010ome.1"],"knownGene","uc010ome.1","chr1",47023090,47069966] +[["uc009vyj.2"],"knownGene","uc009vyj.2","chr1",47027154,47069966] +[["uc001cqd.2"],"knownGene","uc001cqd.2","chr1",47034114,47069966] +[["uc010omf.1"],"knownGene","uc010omf.1","chr1",47040146,47082563] +[["uc001cqf.3"],"knownGene","uc001cqf.3","chr1",47073387,47082563] +[["uc001cqe.3"],"knownGene","uc001cqe.3","chr1",47073387,47080805] +[["uc001cqh.2"],"knownGene","uc001cqh.2","chr1",47098412,47134099] +[["uc001cqi.2"],"knownGene","uc001cqi.2","chr1",47098412,47134099] +[["uc009vyk.2"],"knownGene","uc009vyk.2","chr1",47098412,47131527] +[["uc010omg.1"],"knownGene","uc010omg.1","chr1",47098412,47131527] +[["uc001cqg.2"],"knownGene","uc001cqg.2","chr1",47098412,47131044] +[["uc010omh.1"],"knownGene","uc010omh.1","chr1",47124358,47184736] +[["uc001cqj.2"],"knownGene","uc001cqj.2","chr1",47137499,47139249] +[["uc010omi.1"],"knownGene","uc010omi.1","chr1",47137499,47139166] +[["uc001cqk.3"],"knownGene","uc001cqk.3","chr1",47140831,47184736] +[["uc010omj.1"],"knownGene","uc010omj.1","chr1",47140831,47173723] +[["uc001cql.1"],"knownGene","uc001cql.1","chr1",47149834,47184736] +[["uc001cqn.3"],"knownGene","uc001cqn.3","chr1",47264669,47285020] +[["uc001cqm.3"],"knownGene","uc001cqm.3","chr1",47264669,47285020] +[["uc009vym.2"],"knownGene","uc009vym.2","chr1",47264669,47285020] +[["uc010omk.1"],"knownGene","uc010omk.1","chr1",47264669,47285020] +[["uc009vyl.1"],"knownGene","uc009vyl.1","chr1",47264669,47281083] +[["uc010oml.1"],"knownGene","uc010oml.1","chr1",47276744,47279987] +[["uc001cqo.1"],"knownGene","uc001cqo.1","chr1",47323905,47366147] +[["uc009vyn.1"],"knownGene","uc009vyn.1","chr1",47333618,47366147] +[["uc001cqp.3"],"knownGene","uc001cqp.3","chr1",47394847,47407156] +[["uc001cqq.2"],"knownGene","uc001cqq.2","chr1",47397180,47407156] +[["uc010omm.1"],"knownGene","uc010omm.1","chr1",47399624,47407156] +[["uc001cqr.2"],"knownGene","uc001cqr.2","chr1",47427035,47516422] +[["uc001cqs.2"],"knownGene","uc001cqs.2","chr1",47469911,47516422] +[["uc001cqt.2"],"knownGene","uc001cqt.2","chr1",47489239,47516422] +[["uc001cqu.1"],"knownGene","uc001cqu.1","chr1",47533159,47583992] +[["uc001cqv.1"],"knownGene","uc001cqv.1","chr1",47603106,47614526] +[["uc009vyo.2"],"knownGene","uc009vyo.2","chr1",47603106,47613151] +[["uc009vyp.2"],"knownGene","uc009vyp.2","chr1",47603106,47613151] +[["uc001cqw.2"],"knownGene","uc001cqw.2","chr1",47649261,47655771] +[["uc001cqy.2"],"knownGene","uc001cqy.2","chr1",47681962,47697387] +[["uc001cqx.2"],"knownGene","uc001cqx.2","chr1",47681962,47695443] +[["uc009vyq.2"],"knownGene","uc009vyq.2","chr1",47681962,47689770] +[["uc001cra.1"],"knownGene","uc001cra.1","chr1",47689675,47697892] +[["uc001cqz.1"],"knownGene","uc001cqz.1","chr1",47689675,47697892] +[["uc001crb.1"],"knownGene","uc001crb.1","chr1",47694867,47779819] +[["uc001crc.1"],"knownGene","uc001crc.1","chr1",47715810,47779819] +[["uc001crd.1"],"knownGene","uc001crd.1","chr1",47715810,47779819] +[["uc001cre.1"],"knownGene","uc001cre.1","chr1",47715810,47779819] +[["uc010omn.1"],"knownGene","uc010omn.1","chr1",47715810,47778828] +[["uc010omo.1"],"knownGene","uc010omo.1","chr1",47715810,47778828] +[["uc001crg.1"],"knownGene","uc001crg.1","chr1",47725960,47779819] +[["uc001crf.1"],"knownGene","uc001crf.1","chr1",47725960,47749745] +[["uc001cri.2"],"knownGene","uc001cri.2","chr1",47799468,47844510] +[["uc010omp.1"],"knownGene","uc010omp.1","chr1",47799468,47844510] +[["uc010omq.1"],"knownGene","uc010omq.1","chr1",47799468,47844510] +[["uc001crh.2"],"knownGene","uc001crh.2","chr1",47799468,47824547] +[["uc001crj.1"],"knownGene","uc001crj.1","chr1",47859449,47861215] +[["uc001crk.2"],"knownGene","uc001crk.2","chr1",47881743,47883723] +[["uc001crl.2"],"knownGene","uc001crl.2","chr1",47897807,47900313] +[["uc001crm.2"],"knownGene","uc001crm.2","chr1",47901688,47906362] +[["uc010omr.1"],"knownGene","uc010omr.1","chr1",48567386,48648100] +[["uc001crn.2"],"knownGene","uc001crn.2","chr1",48688356,48714316] +[["uc001cro.2"],"knownGene","uc001cro.2","chr1",48688356,48714316] +[["uc010omt.1"],"knownGene","uc010omt.1","chr1",48688356,48714316] +[["uc001crp.2"],"knownGene","uc001crp.2","chr1",48688356,48714316] +[["uc010omu.1"],"knownGene","uc010omu.1","chr1",48688356,48714316] +[["uc010oms.1"],"knownGene","uc010oms.1","chr1",48688356,48703519] +[["uc009vyt.1"],"knownGene","uc009vyt.1","chr1",48704993,48714316] +[["uc001crr.1"],"knownGene","uc001crr.1","chr1",48764277,48937845] +[["uc001crs.1"],"knownGene","uc001crs.1","chr1",48764277,48937845] +[["uc010omv.1"],"knownGene","uc010omv.1","chr1",48764277,48937845] +[["uc001crt.2"],"knownGene","uc001crt.2","chr1",48862818,48937845] +[["uc001cru.2"],"knownGene","uc001cru.2","chr1",48998526,50489626] +[["uc010omw.1"],"knownGene","uc010omw.1","chr1",48998526,50489626] +[["uc010omx.1"],"knownGene","uc010omx.1","chr1",48998526,50489626] +[["uc001crv.1"],"knownGene","uc001crv.1","chr1",49049541,49511472] +[["uc010omy.1"],"knownGene","uc010omy.1","chr1",49049541,49511472] +[["uc001crx.3"],"knownGene","uc001crx.3","chr1",49193541,49242547] +[["uc001crw.3"],"knownGene","uc001crw.3","chr1",49193541,49242547] +[["uc001cry.3"],"knownGene","uc001cry.3","chr1",50513685,50667540] +[["uc001crz.3"],"knownGene","uc001crz.3","chr1",50569581,50667540] +[["uc001csa.3"],"knownGene","uc001csa.3","chr1",50571963,50667540] +[["uc001csb.2"],"knownGene","uc001csb.2","chr1",50574593,50667540] +[["uc001csc.3"],"knownGene","uc001csc.3","chr1",50574593,50667540] +[["uc010omz.1"],"knownGene","uc010omz.1","chr1",50575287,50667540] +[["uc009vyu.2"],"knownGene","uc009vyu.2","chr1",50575287,50663232] +[["uc010onb.1"],"knownGene","uc010onb.1","chr1",50883228,50889141] +[["uc010ona.1"],"knownGene","uc010ona.1","chr1",50883228,50887304] +[["uc001cse.1"],"knownGene","uc001cse.1","chr1",50906934,51425936] +[["uc009vyx.1"],"knownGene","uc009vyx.1","chr1",50906934,51425833] +[["uc009vyw.1"],"knownGene","uc009vyw.1","chr1",50906934,51425525] +[["uc010onc.1"],"knownGene","uc010onc.1","chr1",50906934,51078170] +[["uc001csf.2"],"knownGene","uc001csf.2","chr1",51433607,51440307] +[["uc001csg.2"],"knownGene","uc001csg.2","chr1",51435641,51440307] +[["uc001csh.2"],"knownGene","uc001csh.2","chr1",51567905,51613752] +[["uc001csi.3"],"knownGene","uc001csi.3","chr1",51701944,51739117] +[["uc010onf.1"],"knownGene","uc010onf.1","chr1",51752930,51810785] +[["uc010one.1"],"knownGene","uc010one.1","chr1",51752930,51796234] +[["uc010ond.1"],"knownGene","uc010ond.1","chr1",51752930,51795845] +[["uc001csk.2"],"knownGene","uc001csk.2","chr1",51752930,51787938] +[["uc001csl.2"],"knownGene","uc001csl.2","chr1",51752930,51787938] +[["uc001csj.2"],"knownGene","uc001csj.2","chr1",51752930,51763594] +[["uc001csn.2"],"knownGene","uc001csn.2","chr1",51761211,51796234] +[["uc001cso.1"],"knownGene","uc001cso.1","chr1",51762902,51796999] +[["uc009vyy.1"],"knownGene","uc009vyy.1","chr1",51767243,51796617] +[["uc001csq.1"],"knownGene","uc001csq.1","chr1",51819934,51984995] +[["uc009vyz.1"],"knownGene","uc009vyz.1","chr1",51819934,51984995] +[["uc001csp.3"],"knownGene","uc001csp.3","chr1",51819934,51887793] +[["uc001csr.1"],"knownGene","uc001csr.1","chr1",51968781,51984995] +[["uc001css.2"],"knownGene","uc001css.2","chr1",52042850,52254136] +[["uc001cst.2"],"knownGene","uc001cst.2","chr1",52082545,52254136] +[["uc001csx.2"],"knownGene","uc001csx.2","chr1",52082545,52254136] +[["uc001csu.2"],"knownGene","uc001csu.2","chr1",52082545,52254136] +[["uc001csv.2"],"knownGene","uc001csv.2","chr1",52082545,52254136] +[["uc001csw.2"],"knownGene","uc001csw.2","chr1",52082545,52254136] +[["uc009vza.2"],"knownGene","uc009vza.2","chr1",52082545,52254136] +[["uc001csy.2"],"knownGene","uc001csy.2","chr1",52195492,52254136] +[["uc001csz.2"],"knownGene","uc001csz.2","chr1",52195492,52254136] +[["uc001cta.2"],"knownGene","uc001cta.2","chr1",52195522,52254136] +[["uc001ctb.2"],"knownGene","uc001ctb.2","chr1",52225295,52254136] +[["uc001ctc.3"],"knownGene","uc001ctc.3","chr1",52254867,52344609] +[["uc001ctd.3"],"knownGene","uc001ctd.3","chr1",52254867,52344609] +[["uc009vzb.2"],"knownGene","uc009vzb.2","chr1",52254867,52306186] +[["uc001cte.2"],"knownGene","uc001cte.2","chr1",52255239,52343712] +[["uc001ctf.2"],"knownGene","uc001ctf.2","chr1",52257249,52344609] +[["uc010ong.1"],"knownGene","uc010ong.1","chr1",52260143,52344420] +[["uc009vzc.1"],"knownGene","uc009vzc.1","chr1",52280222,52343712] +[["uc001ctg.1"],"knownGene","uc001ctg.1","chr1",52302636,52305398] +[["uc001cth.2"],"knownGene","uc001cth.2","chr1",52384836,52456348] +[["uc001cti.2"],"knownGene","uc001cti.2","chr1",52485806,52521047] +[["uc001ctj.1"],"knownGene","uc001ctj.1","chr1",52497776,52499472] +[["uc001ctk.2"],"knownGene","uc001ctk.2","chr1",52521856,52554090] +[["uc001ctl.2"],"knownGene","uc001ctl.2","chr1",52521856,52554090] +[["uc010onh.1"],"knownGene","uc010onh.1","chr1",52521856,52554090] +[["uc001ctm.2"],"knownGene","uc001ctm.2","chr1",52525495,52554090] +[["uc001cto.2"],"knownGene","uc001cto.2","chr1",52608045,52812357] +[["uc001ctp.2"],"knownGene","uc001ctp.2","chr1",52608045,52812357] +[["uc001ctn.2"],"knownGene","uc001ctn.2","chr1",52608045,52729718] +[["uc001ctq.1"],"knownGene","uc001ctq.1","chr1",52816266,52831864] +[["uc001cts.2"],"knownGene","uc001cts.2","chr1",52818204,52825905] +[["uc001ctr.2"],"knownGene","uc001ctr.2","chr1",52818204,52824133] +[["uc001ctt.2"],"knownGene","uc001ctt.2","chr1",52838501,52870131] +[["uc010oni.1"],"knownGene","uc010oni.1","chr1",52838501,52870131] +[["uc001ctu.2"],"knownGene","uc001ctu.2","chr1",52838501,52870131] +[["uc009vzd.2"],"knownGene","uc009vzd.2","chr1",52838501,52870131] +[["uc001ctv.3"],"knownGene","uc001ctv.3","chr1",52870218,52883991] +[["uc001ctw.3"],"knownGene","uc001ctw.3","chr1",52870218,52883991] +[["uc001ctx.2"],"knownGene","uc001ctx.2","chr1",52888947,53018762] +[["uc001cty.2"],"knownGene","uc001cty.2","chr1",52888947,53018762] +[["uc001ctz.2"],"knownGene","uc001ctz.2","chr1",52888947,53018762] +[["uc001cua.1"],"knownGene","uc001cua.1","chr1",52896675,52927288] +[["uc009vze.1"],"knownGene","uc009vze.1","chr1",52903891,53018772] +[["uc009vzf.1"],"knownGene","uc009vzf.1","chr1",52911936,53019130] +[["uc001cub.2"],"knownGene","uc001cub.2","chr1",52927875,52992045] +[["uc001cuc.2"],"knownGene","uc001cuc.2","chr1",52943379,53018762] +[["uc001cud.2"],"knownGene","uc001cud.2","chr1",52980467,53018762] +[["uc001cue.2"],"knownGene","uc001cue.2","chr1",53068042,53074722] +[["uc001cuh.2"],"knownGene","uc001cuh.2","chr1",53099065,53135337] +[["uc001cug.1"],"knownGene","uc001cug.1","chr1",53099065,53134793] +[["uc001cuf.2"],"knownGene","uc001cuf.2","chr1",53099065,53122736] +[["uc001cui.1"],"knownGene","uc001cui.1","chr1",53152513,53164038] +[["uc001cuj.2"],"knownGene","uc001cuj.2","chr1",53192130,53293011] +[["uc010onj.1"],"knownGene","uc010onj.1","chr1",53192130,53293011] +[["uc009vzg.2"],"knownGene","uc009vzg.2","chr1",53192130,53282310] +[["uc009vzh.2"],"knownGene","uc009vzh.2","chr1",53262405,53293011] +[["uc001cuk.2"],"knownGene","uc001cuk.2","chr1",53308182,53360247] +[["uc001cul.2"],"knownGene","uc001cul.2","chr1",53308182,53360247] +[["uc010onk.1"],"knownGene","uc010onk.1","chr1",53361903,53392851] +[["uc001cuo.3"],"knownGene","uc001cuo.3","chr1",53361903,53387591] +[["uc001cup.3"],"knownGene","uc001cup.3","chr1",53361903,53387591] +[["uc001cun.2"],"knownGene","uc001cun.2","chr1",53361903,53387375] +[["uc010onn.1"],"knownGene","uc010onn.1","chr1",53370705,53387591] +[["uc010onm.1"],"knownGene","uc010onm.1","chr1",53370705,53387375] +[["uc010onl.1"],"knownGene","uc010onl.1","chr1",53370705,53387258] +[["uc001cur.1"],"knownGene","uc001cur.1","chr1",53392947,53517282] +[["uc001cus.1"],"knownGene","uc001cus.1","chr1",53392947,53517282] +[["uc010ono.1"],"knownGene","uc010ono.1","chr1",53392947,53517282] +[["uc010onp.1"],"knownGene","uc010onp.1","chr1",53392947,53517282] +[["uc009vzi.1"],"knownGene","uc009vzi.1","chr1",53392947,53517282] +[["uc001cuq.1"],"knownGene","uc001cuq.1","chr1",53392947,53461672] +[["uc001cut.1"],"knownGene","uc001cut.1","chr1",53480561,53517282] +[["uc001cuu.1"],"knownGene","uc001cuu.1","chr1",53480561,53517282] +[["uc010onq.1"],"knownGene","uc010onq.1","chr1",53480561,53517282] +[["uc001cuv.2"],"knownGene","uc001cuv.2","chr1",53527884,53551173] +[["uc001cuw.2"],"knownGene","uc001cuw.2","chr1",53527884,53551173] +[["uc010onr.1"],"knownGene","uc010onr.1","chr1",53527884,53551173] +[["uc010ons.1"],"knownGene","uc010ons.1","chr1",53527884,53551173] +[["uc001cuy.2"],"knownGene","uc001cuy.2","chr1",53552855,53608289] +[["uc001cux.2"],"knownGene","uc001cux.2","chr1",53552855,53556654] +[["uc001cuz.3"],"knownGene","uc001cuz.3","chr1",53573607,53608289] +[["uc001cva.1"],"knownGene","uc001cva.1","chr1",53580247,53584281] +[["uc001cvb.3"],"knownGene","uc001cvb.3","chr1",53662100,53679867] +[["uc001cvd.2"],"knownGene","uc001cvd.2","chr1",53679773,53686289] +[["uc001cve.2"],"knownGene","uc001cve.2","chr1",53679773,53686289] +[["uc001cvc.2"],"knownGene","uc001cvc.2","chr1",53679773,53684238] +[["uc001cvf.1"],"knownGene","uc001cvf.1","chr1",53692563,53704207] +[["uc010ont.1"],"knownGene","uc010ont.1","chr1",53692563,53704207] +[["uc001cvg.2"],"knownGene","uc001cvg.2","chr1",53704281,53708454] +[["uc001cvi.1"],"knownGene","uc001cvi.1","chr1",53711211,53793821] +[["uc001cvj.1"],"knownGene","uc001cvj.1","chr1",53711211,53793821] +[["uc001cvk.1"],"knownGene","uc001cvk.1","chr1",53711211,53793821] +[["uc001cvl.1"],"knownGene","uc001cvl.1","chr1",53711211,53793821] +[["uc001cvh.1"],"knownGene","uc001cvh.1","chr1",53711211,53793071] +[["uc001cvm.1"],"knownGene","uc001cvm.1","chr1",53716361,53734270] +[["uc001cvn.1"],"knownGene","uc001cvn.1","chr1",53793904,53802889] +[["uc009vzj.1"],"knownGene","uc009vzj.1","chr1",53904043,53905693] +[["uc001cvq.1"],"knownGene","uc001cvq.1","chr1",53925071,53933158] +[["uc001cvr.1"],"knownGene","uc001cvr.1","chr1",53971905,54199877] +[["uc001cvs.2"],"knownGene","uc001cvs.2","chr1",54233389,54304175] +[["uc010onu.1"],"knownGene","uc010onu.1","chr1",54233389,54304175] +[["uc001cvt.2"],"knownGene","uc001cvt.2","chr1",54233389,54304175] +[["uc009vzk.2"],"knownGene","uc009vzk.2","chr1",54233389,54304175] +[["uc010onv.1"],"knownGene","uc010onv.1","chr1",54233389,54304175] +[["uc001cvu.2"],"knownGene","uc001cvu.2","chr1",54317406,54355453] +[["uc001cvv.2"],"knownGene","uc001cvv.2","chr1",54317406,54355453] +[["uc001cvw.2"],"knownGene","uc001cvw.2","chr1",54317406,54355453] +[["uc001cvx.2"],"knownGene","uc001cvx.2","chr1",54317406,54355453] +[["uc001cvy.2"],"knownGene","uc001cvy.2","chr1",54317406,54355453] +[["uc010onw.1"],"knownGene","uc010onw.1","chr1",54359860,54376758] +[["uc009vzl.2"],"knownGene","uc009vzl.2","chr1",54359860,54376758] +[["uc010onx.1"],"knownGene","uc010onx.1","chr1",54359860,54376758] +[["uc001cwb.2"],"knownGene","uc001cwb.2","chr1",54359860,54376758] +[["uc010ony.1"],"knownGene","uc010ony.1","chr1",54359860,54376758] +[["uc001cwd.2"],"knownGene","uc001cwd.2","chr1",54359860,54376758] +[["uc001cwe.2"],"knownGene","uc001cwe.2","chr1",54359860,54376758] +[["uc001cwf.2"],"knownGene","uc001cwf.2","chr1",54359861,54376758] +[["uc001cwg.2"],"knownGene","uc001cwg.2","chr1",54359861,54376758] +[["uc001cwi.1"],"knownGene","uc001cwi.1","chr1",54387233,54411288] +[["uc001cwh.2"],"knownGene","uc001cwh.2","chr1",54387235,54411288] +[["uc001cwj.1"],"knownGene","uc001cwj.1","chr1",54412036,54433839] +[["uc001cwl.1"],"knownGene","uc001cwl.1","chr1",54412036,54433839] +[["uc001cwk.1"],"knownGene","uc001cwk.1","chr1",54412036,54433839] +[["uc009vzm.1"],"knownGene","uc009vzm.1","chr1",54412036,54433839] +[["uc001cwm.1"],"knownGene","uc001cwm.1","chr1",54474505,54483803] +[["uc010onz.1"],"knownGene","uc010onz.1","chr1",54474505,54483803] +[["uc010ooa.1"],"knownGene","uc010ooa.1","chr1",54474505,54483803] +[["uc009vzn.1"],"knownGene","uc009vzn.1","chr1",54474505,54483803] +[["uc001cwp.2"],"knownGene","uc001cwp.2","chr1",54497350,54519111] +[["uc001cwq.2"],"knownGene","uc001cwq.2","chr1",54497350,54519111] +[["uc001cwr.2"],"knownGene","uc001cwr.2","chr1",54497350,54519111] +[["uc001cwo.2"],"knownGene","uc001cwo.2","chr1",54497350,54513686] +[["uc001cwn.2"],"knownGene","uc001cwn.2","chr1",54497350,54510014] +[["uc001cws.1"],"knownGene","uc001cws.1","chr1",54502282,54519111] +[["uc001cwu.1"],"knownGene","uc001cwu.1","chr1",54519273,54578192] +[["uc001cwt.1"],"knownGene","uc001cwt.1","chr1",54519273,54565416] +[["uc001cwv.1"],"knownGene","uc001cwv.1","chr1",54604667,54619443] +[["uc009vzo.2"],"knownGene","uc009vzo.2","chr1",54638028,54665746] +[["uc001cwx.3"],"knownGene","uc001cwx.3","chr1",54638028,54665746] +[["uc001cwy.3"],"knownGene","uc001cwy.3","chr1",54638028,54665746] +[["uc001cww.2"],"knownGene","uc001cww.2","chr1",54638028,54661388] +[["uc001cxb.1"],"knownGene","uc001cxb.1","chr1",54665839,54691137] +[["uc001cxa.3"],"knownGene","uc001cxa.3","chr1",54665839,54684054] +[["uc009vzp.2"],"knownGene","uc009vzp.2","chr1",54665839,54684054] +[["uc001cxc.3"],"knownGene","uc001cxc.3","chr1",54665863,54684054] +[["uc010oob.1"],"knownGene","uc010oob.1","chr1",54665874,54684054] +[["uc001cxe.2"],"knownGene","uc001cxe.2","chr1",54692195,54872092] +[["uc001cxf.2"],"knownGene","uc001cxf.2","chr1",54692195,54872092] +[["uc001cxg.2"],"knownGene","uc001cxg.2","chr1",54692195,54872092] +[["uc001cxd.2"],"knownGene","uc001cxd.2","chr1",54692195,54694507] +[["uc001cxi.1"],"knownGene","uc001cxi.1","chr1",54751085,54753827] +[["uc001cxj.1"],"knownGene","uc001cxj.1","chr1",55007929,55076000] +[["uc001cxm.1"],"knownGene","uc001cxm.1","chr1",55013900,55100417] +[["uc001cxl.1"],"knownGene","uc001cxl.1","chr1",55013900,55076000] +[["uc001cxk.2"],"knownGene","uc001cxk.2","chr1",55013900,55064513] +[["uc001cxn.2"],"knownGene","uc001cxn.2","chr1",55074850,55089200] +[["uc001cxq.2"],"knownGene","uc001cxq.2","chr1",55107426,55207980] +[["uc001cxs.2"],"knownGene","uc001cxs.2","chr1",55107426,55175939] +[["uc010ood.1"],"knownGene","uc010ood.1","chr1",55107426,55175939] +[["uc010ooe.1"],"knownGene","uc010ooe.1","chr1",55107426,55175939] +[["uc010oof.1"],"knownGene","uc010oof.1","chr1",55107426,55175939] +[["uc010ooc.1"],"knownGene","uc010ooc.1","chr1",55107426,55166134] +[["uc001cxo.2"],"knownGene","uc001cxo.2","chr1",55107426,55129728] +[["uc001cxr.1"],"knownGene","uc001cxr.1","chr1",55117460,55175939] +[["uc009vzq.1"],"knownGene","uc009vzq.1","chr1",55118525,55175939] +[["uc001cxt.1"],"knownGene","uc001cxt.1","chr1",55118525,55175939] +[["uc010oog.1"],"knownGene","uc010oog.1","chr1",55118525,55165896] +[["uc010ooh.1"],"knownGene","uc010ooh.1","chr1",55118525,55165896] +[["uc009vzr.1"],"knownGene","uc009vzr.1","chr1",55148328,55175939] +[["uc001cxu.2"],"knownGene","uc001cxu.2","chr1",55151930,55161454] +[["uc001cxw.3"],"knownGene","uc001cxw.3","chr1",55181528,55207980] +[["uc001cxx.3"],"knownGene","uc001cxx.3","chr1",55181528,55207980] +[["uc001cxv.2"],"knownGene","uc001cxv.2","chr1",55181540,55207980] +[["uc001cxy.2"],"knownGene","uc001cxy.2","chr1",55222572,55230187] +[["uc009vzt.1"],"knownGene","uc009vzt.1","chr1",55246751,55266941] +[["uc001cxz.3"],"knownGene","uc001cxz.3","chr1",55250224,55266941] +[["uc001cya.3"],"knownGene","uc001cya.3","chr1",55271735,55307936] +[["uc001cyb.3"],"knownGene","uc001cyb.3","chr1",55271735,55307936] +[["uc001cyc.1"],"knownGene","uc001cyc.1","chr1",55315299,55352921] +[["uc010ook.1"],"knownGene","uc010ook.1","chr1",55315299,55352481] +[["uc010ooj.1"],"knownGene","uc010ooj.1","chr1",55315299,55341720] +[["uc010ooi.1"],"knownGene","uc010ooi.1","chr1",55315299,55331353] +[["uc001cyd.2"],"knownGene","uc001cyd.2","chr1",55446464,55457965] +[["uc001cye.2"],"knownGene","uc001cye.2","chr1",55464616,55474464] +[["uc001cyf.1"],"knownGene","uc001cyf.1","chr1",55505219,55530523] +[["uc010ool.1"],"knownGene","uc010ool.1","chr1",55505219,55518464] +[["uc010oom.1"],"knownGene","uc010oom.1","chr1",55505894,55530523] +[["uc001cyg.3"],"knownGene","uc001cyg.3","chr1",55532038,55680762] +[["uc001cyi.1"],"knownGene","uc001cyi.1","chr1",56046709,56200675] +[["uc001cyj.1"],"knownGene","uc001cyj.1","chr1",56960432,57045257] +[["uc001cyk.3"],"knownGene","uc001cyk.3","chr1",57110989,57181007] +[["uc001cym.3"],"knownGene","uc001cym.3","chr1",57184477,57285369] +[["uc001cyl.2"],"knownGene","uc001cyl.2","chr1",57184477,57227686] +[["uc009vzu.1"],"knownGene","uc009vzu.1","chr1",57192169,57285369] +[["uc009vzv.1"],"knownGene","uc009vzv.1","chr1",57253991,57285369] +[["uc001cyn.2"],"knownGene","uc001cyn.2","chr1",57289360,57292593] +[["uc001cyo.2"],"knownGene","uc001cyo.2","chr1",57320442,57383894] +[["uc001cyp.2"],"knownGene","uc001cyp.2","chr1",57394884,57431688] +[["uc010oon.1"],"knownGene","uc010oon.1","chr1",57394884,57431688] +[["uc010ooo.1"],"knownGene","uc010ooo.1","chr1",57394884,57431688] +[["uc001cyt.1"],"knownGene","uc001cyt.1","chr1",57463578,59012446] +[["uc001cys.1"],"knownGene","uc001cys.1","chr1",57463578,58716211] +[["uc009vzw.1"],"knownGene","uc009vzw.1","chr1",57463578,57773037] +[["uc001cyq.1"],"knownGene","uc001cyq.1","chr1",57463578,57756838] +[["uc001cyr.1"],"knownGene","uc001cyr.1","chr1",57463578,57756838] +[["uc009vzx.1"],"knownGene","uc009vzx.1","chr1",57476352,57888872] +[["uc001cyu.1"],"knownGene","uc001cyu.1","chr1",58326214,58328786] +[["uc001cyv.1"],"knownGene","uc001cyv.1","chr1",58326265,58328786] +[["uc001cyw.1"],"knownGene","uc001cyw.1","chr1",58933598,58934677] +[["uc001cyx.1"],"knownGene","uc001cyx.1","chr1",58939503,59004982] +[["uc001cyy.2"],"knownGene","uc001cyy.2","chr1",58946391,59012446] +[["uc009vzz.2"],"knownGene","uc009vzz.2","chr1",58999094,59012446] +[["uc001cyz.3"],"knownGene","uc001cyz.3","chr1",59041096,59043166] +[["uc001cza.2"],"knownGene","uc001cza.2","chr1",59120411,59124660] +[["uc009wab.1"],"knownGene","uc009wab.1","chr1",59125589,59165747] +[["uc001czc.2"],"knownGene","uc001czc.2","chr1",59125589,59156089] +[["uc009waa.1"],"knownGene","uc009waa.1","chr1",59125589,59134578] +[["uc001czd.2"],"knownGene","uc001czd.2","chr1",59151777,59165747] +[["uc001cze.2"],"knownGene","uc001cze.2","chr1",59246463,59249785] +[["uc001czf.2"],"knownGene","uc001czf.2","chr1",59250822,59365384] +[["uc010oop.1"],"knownGene","uc010oop.1","chr1",59250822,59365384] +[["uc010ooq.1"],"knownGene","uc010ooq.1","chr1",59597609,59612479] +[["uc009wac.2"],"knownGene","uc009wac.2","chr1",59762624,60228400] +[["uc001czi.3"],"knownGene","uc001czi.3","chr1",59762624,60228400] +[["uc001czj.3"],"knownGene","uc001czj.3","chr1",59762624,60228400] +[["uc001czk.3"],"knownGene","uc001czk.3","chr1",59762624,60228400] +[["uc001czh.2"],"knownGene","uc001czh.2","chr1",59762624,60165066] +[["uc001czg.2"],"knownGene","uc001czg.2","chr1",59762624,60092526] +[["uc001czl.3"],"knownGene","uc001czl.3","chr1",59775758,60228400] +[["uc001czm.3"],"knownGene","uc001czm.3","chr1",59981325,60228400] +[["uc001czn.2"],"knownGene","uc001czn.2","chr1",60238466,60254499] +[["uc009wad.2"],"knownGene","uc009wad.2","chr1",60280462,60342049] +[["uc001czo.2"],"knownGene","uc001czo.2","chr1",60280532,60342049] +[["uc001czp.2"],"knownGene","uc001czp.2","chr1",60280843,60342049] +[["uc010oor.1"],"knownGene","uc010oor.1","chr1",60282303,60342049] +[["uc001czq.2"],"knownGene","uc001czq.2","chr1",60358980,60392423] +[["uc001czs.1"],"knownGene","uc001czs.1","chr1",60454823,60539426] +[["uc001czr.1"],"knownGene","uc001czr.1","chr1",60454823,60474495] +[["uc001czt.1"],"knownGene","uc001czt.1","chr1",61125302,61291256] +[["uc001czu.2"],"knownGene","uc001czu.2","chr1",61405916,61436448] +[["uc001czy.2"],"knownGene","uc001czy.2","chr1",61542945,61928459] +[["uc010oos.1"],"knownGene","uc010oos.1","chr1",61547533,61928459] +[["uc001czw.2"],"knownGene","uc001czw.2","chr1",61547979,61928459] +[["uc001czv.2"],"knownGene","uc001czv.2","chr1",61547979,61928459] +[["uc001czx.2"],"knownGene","uc001czx.2","chr1",61869747,61928459] +[["uc009wae.2"],"knownGene","uc009wae.2","chr1",61872233,61928459] +[["uc001czz.1"],"knownGene","uc001czz.1","chr1",62146718,62191095] +[["uc001dab.2"],"knownGene","uc001dab.2","chr1",62208148,62629589] +[["uc001daa.2"],"knownGene","uc001daa.2","chr1",62208148,62580582] +[["uc009waf.1"],"knownGene","uc009waf.1","chr1",62208148,62579918] +[["uc001dad.3"],"knownGene","uc001dad.3","chr1",62237102,62580582] +[["uc001dac.2"],"knownGene","uc001dac.2","chr1",62271119,62629174] +[["uc009wag.2"],"knownGene","uc009wag.2","chr1",62417925,62644346] +[["uc010oot.1"],"knownGene","uc010oot.1","chr1",62417925,62583005] +[["uc010oou.1"],"knownGene","uc010oou.1","chr1",62439039,62580582] +[["uc001dae.3"],"knownGene","uc001dae.3","chr1",62660495,62677998] +[["uc001dah.3"],"knownGene","uc001dah.3","chr1",62701837,62785083] +[["uc001dai.3"],"knownGene","uc001dai.3","chr1",62701837,62785083] +[["uc001dag.3"],"knownGene","uc001dag.3","chr1",62701837,62738463] +[["uc001daf.3"],"knownGene","uc001daf.3","chr1",62701837,62729096] +[["uc001daj.1"],"knownGene","uc001daj.1","chr1",62901974,62917915] +[["uc001dak.1"],"knownGene","uc001dak.1","chr1",62901974,62917915] +[["uc001dal.1"],"knownGene","uc001dal.1","chr1",62902382,62917915] +[["uc001dap.2"],"knownGene","uc001dap.2","chr1",62920397,63153969] +[["uc001daq.2"],"knownGene","uc001daq.2","chr1",62920397,63153969] +[["uc001dan.2"],"knownGene","uc001dan.2","chr1",62920397,63119464] +[["uc001dao.2"],"knownGene","uc001dao.2","chr1",62920397,63119464] +[["uc001dam.2"],"knownGene","uc001dam.2","chr1",62920397,63021660] +[["uc010oov.1"],"knownGene","uc010oov.1","chr1",62923208,63001303] +[["uc001dar.1"],"knownGene","uc001dar.1","chr1",62939652,62944675] +[["uc009wah.1"],"knownGene","uc009wah.1","chr1",63049776,63153969] +[["uc001das.1"],"knownGene","uc001das.1","chr1",63063186,63071180] +[["uc001dat.2"],"knownGene","uc001dat.2","chr1",63249802,63330049] +[["uc001dau.2"],"knownGene","uc001dau.2","chr1",63249802,63330049] +[["uc001dav.2"],"knownGene","uc001dav.2","chr1",63624754,63630026] +[["uc001daw.1"],"knownGene","uc001daw.1","chr1",63635822,63782901] +[["uc001dax.2"],"knownGene","uc001dax.2","chr1",63788729,63790797] +[["uc010oow.1"],"knownGene","uc010oow.1","chr1",63833260,63904232] +[["uc001daz.2"],"knownGene","uc001daz.2","chr1",63836441,63904232] +[["uc009waj.2"],"knownGene","uc009waj.2","chr1",63836441,63904232] +[["uc010oox.1"],"knownGene","uc010oox.1","chr1",63876810,63904232] +[["uc001dba.1"],"knownGene","uc001dba.1","chr1",63906461,63988835] +[["uc001dbb.1"],"knownGene","uc001dbb.1","chr1",63906461,63988835] +[["uc001dbc.1"],"knownGene","uc001dbc.1","chr1",63906461,63988835] +[["uc001dbd.1"],"knownGene","uc001dbd.1","chr1",63906461,63988835] +[["uc001dbe.1"],"knownGene","uc001dbe.1","chr1",63913649,63920639] +[["uc009wak.1"],"knownGene","uc009wak.1","chr1",63919111,63988812] +[["uc001dbf.2"],"knownGene","uc001dbf.2","chr1",63989012,64038363] +[["uc001dbg.1"],"knownGene","uc001dbg.1","chr1",64014650,64016307] +[["uc001dbh.2"],"knownGene","uc001dbh.2","chr1",64058946,64125914] +[["uc010ooy.1"],"knownGene","uc010ooy.1","chr1",64059479,64125914] +[["uc010ooz.1"],"knownGene","uc010ooz.1","chr1",64088900,64125914] +[["uc001dbj.2"],"knownGene","uc001dbj.2","chr1",64239689,64644707] +[["uc001dbi.3"],"knownGene","uc001dbi.3","chr1",64239689,64609041] +[["uc001dbk.2"],"knownGene","uc001dbk.2","chr1",64560125,64577888] +[["uc001dbl.2"],"knownGene","uc001dbl.2","chr1",64571007,64636980] +[["uc001dbm.2"],"knownGene","uc001dbm.2","chr1",64645310,64647177] +[["uc001dbn.1"],"knownGene","uc001dbn.1","chr1",64669489,64710027] +[["uc001dbo.1"],"knownGene","uc001dbo.1","chr1",64936475,65158741] +[["uc001dbp.1"],"knownGene","uc001dbp.1","chr1",64971596,65158741] +[["uc001dbq.1"],"knownGene","uc001dbq.1","chr1",65029359,65158741] +[["uc010opa.1"],"knownGene","uc010opa.1","chr1",65130348,65158741] +[["uc001dbs.1"],"knownGene","uc001dbs.1","chr1",65210777,65298912] +[["uc001dbt.1"],"knownGene","uc001dbt.1","chr1",65243305,65298912] +[["uc010opb.1"],"knownGene","uc010opb.1","chr1",65243305,65298912] +[["uc009wam.1"],"knownGene","uc009wam.1","chr1",65298905,65432619] +[["uc001dbu.1"],"knownGene","uc001dbu.1","chr1",65298905,65432187] +[["uc009wal.1"],"knownGene","uc009wal.1","chr1",65298905,65311323] +[["uc001dbv.2"],"knownGene","uc001dbv.2","chr1",65338384,65343856] +[["uc001dbw.2"],"knownGene","uc001dbw.2","chr1",65445260,65468159] +[["uc001dbx.2"],"knownGene","uc001dbx.2","chr1",65524117,65524191] +[["uc001dby.2"],"knownGene","uc001dby.2","chr1",65613231,65693173] +[["uc009wan.2"],"knownGene","uc009wan.2","chr1",65613352,65693173] +[["uc001dbz.2"],"knownGene","uc001dbz.2","chr1",65613512,65693173] +[["uc001dca.2"],"knownGene","uc001dca.2","chr1",65613885,65693173] +[["uc001dcb.1"],"knownGene","uc001dcb.1","chr1",65720144,65721848] +[["uc001dcc.1"],"knownGene","uc001dcc.1","chr1",65720147,65858548] +[["uc001dcd.1"],"knownGene","uc001dcd.1","chr1",65730429,65881552] +[["uc010opc.1"],"knownGene","uc010opc.1","chr1",65730429,65881552] +[["uc001dce.1"],"knownGene","uc001dce.1","chr1",65775227,65881552] +[["uc001dci.2"],"knownGene","uc001dci.2","chr1",65886317,66102820] +[["uc009waq.2"],"knownGene","uc009waq.2","chr1",65886317,66102820] +[["uc001dch.2"],"knownGene","uc001dch.2","chr1",65886317,66101110] +[["uc001dcg.2"],"knownGene","uc001dcg.2","chr1",65886317,66096093] +[["uc001dcf.2"],"knownGene","uc001dcf.2","chr1",65886317,65898249] +[["uc009wap.2"],"knownGene","uc009wap.2","chr1",65886317,65898249] +[["uc009wao.2"],"knownGene","uc009wao.2","chr1",65886317,65893689] +[["uc001dck.2"],"knownGene","uc001dck.2","chr1",65991424,66101110] +[["uc001dcj.2"],"knownGene","uc001dcj.2","chr1",65991424,66096093] +[["uc001dcn.2"],"knownGene","uc001dcn.2","chr1",66258192,66840261] +[["uc009war.2"],"knownGene","uc009war.2","chr1",66258192,66840261] +[["uc001dco.2"],"knownGene","uc001dco.2","chr1",66258855,66840261] +[["uc001dcp.2"],"knownGene","uc001dcp.2","chr1",66458389,66840261] +[["uc001dcq.2"],"knownGene","uc001dcq.2","chr1",66797792,66840261] +[["uc009was.2"],"knownGene","uc009was.2","chr1",66820069,66840261] +[["uc001dcr.2"],"knownGene","uc001dcr.2","chr1",66999824,67210767] +[["uc010opd.1"],"knownGene","uc010opd.1","chr1",67109226,67210767] +[["uc001dcs.2"],"knownGene","uc001dcs.2","chr1",67109226,67210767] +[["uc001dct.2"],"knownGene","uc001dct.2","chr1",67109226,67210767] +[["uc010ope.1"],"knownGene","uc010ope.1","chr1",67132271,67142710] +[["uc009wat.2"],"knownGene","uc009wat.2","chr1",67136677,67210767] +[["uc001dcu.2"],"knownGene","uc001dcu.2","chr1",67160376,67210767] +[["uc001dcv.2"],"knownGene","uc001dcv.2","chr1",67218139,67244729] +[["uc009wau.2"],"knownGene","uc009wau.2","chr1",67218139,67244729] +[["uc009wav.2"],"knownGene","uc009wav.2","chr1",67218139,67244729] +[["uc001dcw.2"],"knownGene","uc001dcw.2","chr1",67263424,67266939] +[["uc001dcx.2"],"knownGene","uc001dcx.2","chr1",67278573,67390570] +[["uc009wax.2"],"knownGene","uc009wax.2","chr1",67278573,67356505] +[["uc009waw.2"],"knownGene","uc009waw.2","chr1",67278573,67340620] +[["uc001dcy.2"],"knownGene","uc001dcy.2","chr1",67303287,67390570] +[["uc001dcz.2"],"knownGene","uc001dcz.2","chr1",67336930,67390570] +[["uc010opf.1"],"knownGene","uc010opf.1","chr1",67390577,67454302] +[["uc009way.2"],"knownGene","uc009way.2","chr1",67390577,67454302] +[["uc001ddc.2"],"knownGene","uc001ddc.2","chr1",67390577,67454302] +[["uc001ddh.2"],"knownGene","uc001ddh.2","chr1",67390577,67454302] +[["uc001ddf.2"],"knownGene","uc001ddf.2","chr1",67390577,67454302] +[["uc001ddg.2"],"knownGene","uc001ddg.2","chr1",67390577,67454302] +[["uc010opg.1"],"knownGene","uc010opg.1","chr1",67390577,67454302] +[["uc001dde.2"],"knownGene","uc001dde.2","chr1",67390577,67454302] +[["uc001dda.3"],"knownGene","uc001dda.3","chr1",67390577,67413922] +[["uc001ddj.1"],"knownGene","uc001ddj.1","chr1",67395925,67454302] +[["uc001ddi.2"],"knownGene","uc001ddi.2","chr1",67395925,67454302] +[["uc001ddk.2"],"knownGene","uc001ddk.2","chr1",67465014,67520080] +[["uc010oph.1"],"knownGene","uc010oph.1","chr1",67473197,67518730] +[["uc001ddm.1"],"knownGene","uc001ddm.1","chr1",67557858,67600653] +[["uc001ddn.1"],"knownGene","uc001ddn.1","chr1",67557858,67600653] +[["uc001ddl.1"],"knownGene","uc001ddl.1","chr1",67557858,67594220] +[["uc009waz.2"],"knownGene","uc009waz.2","chr1",67604589,67725648] +[["uc001ddo.2"],"knownGene","uc001ddo.2","chr1",67632168,67725648] +[["uc010opi.1"],"knownGene","uc010opi.1","chr1",67635024,67725648] +[["uc010opj.1"],"knownGene","uc010opj.1","chr1",67635024,67725648] +[["uc010opk.1"],"knownGene","uc010opk.1","chr1",67635024,67725648] +[["uc010opl.1"],"knownGene","uc010opl.1","chr1",67635024,67725648] +[["uc010opm.1"],"knownGene","uc010opm.1","chr1",67635024,67725648] +[["uc001ddq.2"],"knownGene","uc001ddq.2","chr1",67635024,67725648] +[["uc010opn.1"],"knownGene","uc010opn.1","chr1",67635024,67725648] +[["uc001ddr.2"],"knownGene","uc001ddr.2","chr1",67635024,67725648] +[["uc001ddp.2"],"knownGene","uc001ddp.2","chr1",67635024,67724260] +[["uc010ops.1"],"knownGene","uc010ops.1","chr1",67648518,67725648] +[["uc010opt.1"],"knownGene","uc010opt.1","chr1",67648518,67725648] +[["uc010opu.1"],"knownGene","uc010opu.1","chr1",67648518,67725648] +[["uc010opv.1"],"knownGene","uc010opv.1","chr1",67648518,67725648] +[["uc010opw.1"],"knownGene","uc010opw.1","chr1",67648518,67725648] +[["uc010opx.1"],"knownGene","uc010opx.1","chr1",67648518,67725648] +[["uc010opy.1"],"knownGene","uc010opy.1","chr1",67648518,67725648] +[["uc010opz.1"],"knownGene","uc010opz.1","chr1",67648518,67725648] +[["uc010oqa.1"],"knownGene","uc010oqa.1","chr1",67648518,67725648] +[["uc010oqb.1"],"knownGene","uc010oqb.1","chr1",67648518,67725648] +[["uc010oqc.1"],"knownGene","uc010oqc.1","chr1",67648518,67725648] +[["uc010oqd.1"],"knownGene","uc010oqd.1","chr1",67648518,67725648] +[["uc010oqe.1"],"knownGene","uc010oqe.1","chr1",67648518,67725648] +[["uc010oqf.1"],"knownGene","uc010oqf.1","chr1",67648518,67725648] +[["uc010oqg.1"],"knownGene","uc010oqg.1","chr1",67648518,67725648] +[["uc010oqh.1"],"knownGene","uc010oqh.1","chr1",67648518,67725648] +[["uc010opo.1"],"knownGene","uc010opo.1","chr1",67648518,67724260] +[["uc010opp.1"],"knownGene","uc010opp.1","chr1",67648518,67724260] +[["uc010opq.1"],"knownGene","uc010opq.1","chr1",67648518,67724260] +[["uc010opr.1"],"knownGene","uc010opr.1","chr1",67648518,67724260] +[["uc001dds.2"],"knownGene","uc001dds.2","chr1",67673298,67725648] +[["uc001ddt.2"],"knownGene","uc001ddt.2","chr1",67673298,67725648] +[["uc001ddu.2"],"knownGene","uc001ddu.2","chr1",67773046,67862582] +[["uc010oqi.1"],"knownGene","uc010oqi.1","chr1",67773046,67862582] +[["uc010oqj.1"],"knownGene","uc010oqj.1","chr1",67773046,67862582] +[["uc010oqk.1"],"knownGene","uc010oqk.1","chr1",67786015,67862582] +[["uc010oql.1"],"knownGene","uc010oql.1","chr1",67786015,67862582] +[["uc010oqm.1"],"knownGene","uc010oqm.1","chr1",67786015,67862582] +[["uc010oqn.1"],"knownGene","uc010oqn.1","chr1",67786015,67862582] +[["uc001ddx.2"],"knownGene","uc001ddx.2","chr1",67873494,67896123] +[["uc001ddy.2"],"knownGene","uc001ddy.2","chr1",67873494,67896123] +[["uc001ddv.2"],"knownGene","uc001ddv.2","chr1",67873494,67896123] +[["uc001ddw.2"],"knownGene","uc001ddw.2","chr1",67873494,67896123] +[["uc001ddz.1"],"knownGene","uc001ddz.1","chr1",68150882,68154019] +[["uc009wbb.1"],"knownGene","uc009wbb.1","chr1",68150882,68154019] +[["uc009wbc.1"],"knownGene","uc009wbc.1","chr1",68150882,68154019] +[["uc009wbd.1"],"knownGene","uc009wbd.1","chr1",68150882,68154019] +[["uc001dea.1"],"knownGene","uc001dea.1","chr1",68167148,68299142] +[["uc001deb.1"],"knownGene","uc001deb.1","chr1",68297985,68668670] +[["uc001dec.1"],"knownGene","uc001dec.1","chr1",68297985,68668670] +[["uc001ded.2"],"knownGene","uc001ded.2","chr1",68511646,68516481] +[["uc001dee.2"],"knownGene","uc001dee.2","chr1",68564151,68698253] +[["uc001def.1"],"knownGene","uc001def.1","chr1",68591040,68698253] +[["uc001deg.1"],"knownGene","uc001deg.1","chr1",68591040,68698253] +[["uc009wbf.1"],"knownGene","uc009wbf.1","chr1",68591040,68659904] +[["uc001deh.1"],"knownGene","uc001deh.1","chr1",68659538,68698253] +[["uc001dei.1"],"knownGene","uc001dei.1","chr1",68894506,68915642] +[["uc001dem.3"],"knownGene","uc001dem.3","chr1",68939836,68962799] +[["uc001del.3"],"knownGene","uc001del.3","chr1",68939836,68962799] +[["uc001dek.3"],"knownGene","uc001dek.3","chr1",68939836,68960378] +[["uc001dej.3"],"knownGene","uc001dej.3","chr1",68939836,68947921] +[["uc001den.2"],"knownGene","uc001den.2","chr1",68962358,69004308] +[["uc001deo.1"],"knownGene","uc001deo.1","chr1",70032867,70340687] +[["uc001dep.2"],"knownGene","uc001dep.2","chr1",70225857,70589169] +[["uc009wbg.2"],"knownGene","uc009wbg.2","chr1",70225873,70589169] +[["uc009wbh.1"],"knownGene","uc009wbh.1","chr1",70385004,70386000] +[["uc001deq.2"],"knownGene","uc001deq.2","chr1",70502126,70589169] +[["uc001der.1"],"knownGene","uc001der.1","chr1",70610496,70671275] +[["uc001des.2"],"knownGene","uc001des.2","chr1",70671364,70717683] +[["uc001det.2"],"knownGene","uc001det.2","chr1",70671364,70717683] +[["uc009wbj.1"],"knownGene","uc009wbj.1","chr1",70671364,70697511] +[["uc010oqo.1"],"knownGene","uc010oqo.1","chr1",70671364,70697511] +[["uc009wbi.2"],"knownGene","uc009wbi.2","chr1",70671364,70695716] +[["uc001deu.2"],"knownGene","uc001deu.2","chr1",70687144,70716186] +[["uc001dev.2"],"knownGene","uc001dev.2","chr1",70695960,70717683] +[["uc001dew.2"],"knownGene","uc001dew.2","chr1",70697230,70717683] +[["uc001dex.3"],"knownGene","uc001dex.3","chr1",70724685,70820417] +[["uc009wbk.2"],"knownGene","uc009wbk.2","chr1",70724685,70820417] +[["uc001dey.3"],"knownGene","uc001dey.3","chr1",70818494,70820399] +[["uc010oqp.1"],"knownGene","uc010oqp.1","chr1",70820492,70833703] +[["uc001dfa.2"],"knownGene","uc001dfa.2","chr1",70820492,70833703] +[["uc001dfb.2"],"knownGene","uc001dfb.2","chr1",70820492,70833703] +[["uc001dfc.2"],"knownGene","uc001dfc.2","chr1",70820492,70833703] +[["uc001dfd.2"],"knownGene","uc001dfd.2","chr1",70876954,70905252] +[["uc001dfe.2"],"knownGene","uc001dfe.2","chr1",70876954,70905252] +[["uc010oqq.1"],"knownGene","uc010oqq.1","chr1",70876954,70905252] +[["uc009wbl.1"],"knownGene","uc009wbl.1","chr1",70876954,70897918] +[["uc001dff.2"],"knownGene","uc001dff.2","chr1",71172135,71252149] +[["uc001dfh.1"],"knownGene","uc001dfh.1","chr1",71318035,71513491] +[["uc001dfg.1"],"knownGene","uc001dfg.1","chr1",71318035,71513491] +[["uc001dfi.1"],"knownGene","uc001dfi.1","chr1",71318035,71513491] +[["uc001dfj.1"],"knownGene","uc001dfj.1","chr1",71318035,71513491] +[["uc001dfk.1"],"knownGene","uc001dfk.1","chr1",71318035,71513491] +[["uc001dfl.1"],"knownGene","uc001dfl.1","chr1",71318035,71513491] +[["uc009wbm.1"],"knownGene","uc009wbm.1","chr1",71327987,71513491] +[["uc001dfm.1"],"knownGene","uc001dfm.1","chr1",71349400,71513491] +[["uc001dfn.2"],"knownGene","uc001dfn.2","chr1",71349439,71513491] +[["uc009wbn.1"],"knownGene","uc009wbn.1","chr1",71349439,71513491] +[["uc009wbo.2"],"knownGene","uc009wbo.2","chr1",71418115,71513491] +[["uc001dfo.2"],"knownGene","uc001dfo.2","chr1",71418115,71513491] +[["uc001dfp.1"],"knownGene","uc001dfp.1","chr1",71436463,71513491] +[["uc001dfq.2"],"knownGene","uc001dfq.2","chr1",71471537,71513491] +[["uc001dfr.2"],"knownGene","uc001dfr.2","chr1",71512188,71532861] +[["uc001dfs.2"],"knownGene","uc001dfs.2","chr1",71528974,71546745] +[["uc001dft.2"],"knownGene","uc001dft.2","chr1",71528974,71546745] +[["uc010oqr.1"],"knownGene","uc010oqr.1","chr1",71533313,71533399] +[["uc001dfu.1"],"knownGene","uc001dfu.1","chr1",71547049,71703406] +[["uc001dfw.2"],"knownGene","uc001dfw.2","chr1",71868625,72748405] +[["uc010oqs.1"],"knownGene","uc010oqs.1","chr1",71868625,72748405] +[["uc001dfv.2"],"knownGene","uc001dfv.2","chr1",71868625,72566614] +[["uc001dfx.2"],"knownGene","uc001dfx.2","chr1",73771852,73804559] +[["uc001dfy.3"],"knownGene","uc001dfy.3","chr1",74491703,74663871] +[["uc001dfz.3"],"knownGene","uc001dfz.3","chr1",74491703,74663871] +[["uc001dge.1"],"knownGene","uc001dge.1","chr1",74663925,75010108] +[["uc001dgd.2"],"knownGene","uc001dgd.2","chr1",74663925,74930605] +[["uc001dgc.1"],"knownGene","uc001dgc.1","chr1",74663925,74837776] +[["uc010oqv.1"],"knownGene","uc010oqv.1","chr1",74663925,74699770] +[["uc001dgb.1"],"knownGene","uc001dgb.1","chr1",74663925,74673120] +[["uc010oqu.1"],"knownGene","uc010oqu.1","chr1",74663925,74671907] +[["uc010oqt.1"],"knownGene","uc010oqt.1","chr1",74663925,74671889] +[["uc001dgf.1"],"knownGene","uc001dgf.1","chr1",74701084,75010108] +[["uc001dgg.2"],"knownGene","uc001dgg.2","chr1",75033795,75139422] +[["uc001dgh.2"],"knownGene","uc001dgh.2","chr1",75043113,75091781] +[["uc001dgi.3"],"knownGene","uc001dgi.3","chr1",75055012,75100538] +[["uc001dgk.2"],"knownGene","uc001dgk.2","chr1",75171174,75199092] +[["uc001dgj.2"],"knownGene","uc001dgj.2","chr1",75171174,75199092] +[["uc001dgl.2"],"knownGene","uc001dgl.2","chr1",75171174,75199092] +[["uc001dgm.2"],"knownGene","uc001dgm.2","chr1",75171174,75199092] +[["uc001dgn.2"],"knownGene","uc001dgn.2","chr1",75198835,75232358] +[["uc010oqw.1"],"knownGene","uc010oqw.1","chr1",75198835,75232358] +[["uc010oqx.1"],"knownGene","uc010oqx.1","chr1",75198835,75232358] +[["uc010oqy.1"],"knownGene","uc010oqy.1","chr1",75198861,75232358] +[["uc001dgo.2"],"knownGene","uc001dgo.2","chr1",75594118,75627216] +[["uc001dgp.1"],"knownGene","uc001dgp.1","chr1",75595658,75598261] +[["uc001dgq.2"],"knownGene","uc001dgq.2","chr1",75600566,75627216] +[["uc010oqz.1"],"knownGene","uc010oqz.1","chr1",75667815,76143610] +[["uc001dgt.2"],"knownGene","uc001dgt.2","chr1",75667815,76076799] +[["uc001dgs.2"],"knownGene","uc001dgs.2","chr1",75667815,76076799] +[["uc001dgr.2"],"knownGene","uc001dgr.2","chr1",75667815,76076799] +[["uc010orb.1"],"knownGene","uc010orb.1","chr1",75672075,76143610] +[["uc010ora.1"],"knownGene","uc010ora.1","chr1",75672075,76081694] +[["uc001dgu.2"],"knownGene","uc001dgu.2","chr1",75672075,76076799] +[["uc001dgv.2"],"knownGene","uc001dgv.2","chr1",76103851,76188721] +[["uc001dgw.3"],"knownGene","uc001dgw.3","chr1",76190042,76229353] +[["uc009wbp.2"],"knownGene","uc009wbp.2","chr1",76190042,76229353] +[["uc009wbr.2"],"knownGene","uc009wbr.2","chr1",76190042,76229353] +[["uc010ore.1"],"knownGene","uc010ore.1","chr1",76190042,76229353] +[["uc010orf.1"],"knownGene","uc010orf.1","chr1",76190042,76229353] +[["uc010ord.1"],"knownGene","uc010ord.1","chr1",76190042,76227299] +[["uc010orc.1"],"knownGene","uc010orc.1","chr1",76190042,76205795] +[["uc001dgx.3"],"knownGene","uc001dgx.3","chr1",76192603,76229353] +[["uc010org.1"],"knownGene","uc010org.1","chr1",76198200,76229353] +[["uc009wbs.1"],"knownGene","uc009wbs.1","chr1",76211490,76227055] +[["uc001dgy.1"],"knownGene","uc001dgy.1","chr1",76251885,76260764] +[["uc009wbt.1"],"knownGene","uc009wbt.1","chr1",76251885,76260764] +[["uc001dgz.2"],"knownGene","uc001dgz.2","chr1",76252756,76252834] +[["uc001dha.1"],"knownGene","uc001dha.1","chr1",76253181,76260764] +[["uc009wbu.1"],"knownGene","uc009wbu.1","chr1",76253573,76253657] +[["uc009wbv.1"],"knownGene","uc009wbv.1","chr1",76255161,76255232] +[["uc001dhc.1"],"knownGene","uc001dhc.1","chr1",76259715,76260764] +[["uc001dhd.1"],"knownGene","uc001dhd.1","chr1",76262629,76378923] +[["uc001dhe.1"],"knownGene","uc001dhe.1","chr1",76384559,76398116] +[["uc001dhf.1"],"knownGene","uc001dhf.1","chr1",76384559,76398116] +[["uc001dhh.2"],"knownGene","uc001dhh.2","chr1",76540388,77096669] +[["uc010orh.1"],"knownGene","uc010orh.1","chr1",76540388,77096669] +[["uc001dhg.3"],"knownGene","uc001dhg.3","chr1",76540388,77042890] +[["uc001dhi.2"],"knownGene","uc001dhi.2","chr1",77333185,77529735] +[["uc010ori.1"],"knownGene","uc010ori.1","chr1",77333185,77529735] +[["uc009wbw.2"],"knownGene","uc009wbw.2","chr1",77334181,77529735] +[["uc001dhj.2"],"knownGene","uc001dhj.2","chr1",77529660,77531392] +[["uc001dhk.2"],"knownGene","uc001dhk.2","chr1",77554668,77685132] +[["uc010orj.1"],"knownGene","uc010orj.1","chr1",77554668,77685132] +[["uc009wbx.2"],"knownGene","uc009wbx.2","chr1",77554668,77685132] +[["uc001dhl.1"],"knownGene","uc001dhl.1","chr1",77619220,77685132] +[["uc001dhn.2"],"knownGene","uc001dhn.2","chr1",77747741,78025652] +[["uc001dhm.1"],"knownGene","uc001dhm.1","chr1",77747741,77780745] +[["uc001dho.2"],"knownGene","uc001dho.2","chr1",77748286,78025652] +[["uc001dhr.2"],"knownGene","uc001dhr.2","chr1",78030190,78149104] +[["uc001dhq.2"],"knownGene","uc001dhq.2","chr1",78030190,78148343] +[["uc001dhp.2"],"knownGene","uc001dhp.2","chr1",78030190,78099090] +[["uc009wbz.1"],"knownGene","uc009wbz.1","chr1",78050201,78148343] +[["uc001dht.2"],"knownGene","uc001dht.2","chr1",78161675,78225537] +[["uc001dhu.2"],"knownGene","uc001dhu.2","chr1",78161675,78225537] +[["uc001dhs.2"],"knownGene","uc001dhs.2","chr1",78161675,78194397] +[["uc009wca.1"],"knownGene","uc009wca.1","chr1",78161675,78163616] +[["uc001dhw.2"],"knownGene","uc001dhw.2","chr1",78177339,78225537] +[["uc001dhv.2"],"knownGene","uc001dhv.2","chr1",78177339,78207114] +[["uc001dhx.2"],"knownGene","uc001dhx.2","chr1",78245308,78344077] +[["uc010ork.1"],"knownGene","uc010ork.1","chr1",78245308,78344077] +[["uc010orl.1"],"knownGene","uc010orl.1","chr1",78245308,78344077] +[["uc001dhy.1"],"knownGene","uc001dhy.1","chr1",78268954,78327860] +[["uc001dic.3"],"knownGene","uc001dic.3","chr1",78354199,78409576] +[["uc001dib.3"],"knownGene","uc001dib.3","chr1",78354199,78409576] +[["uc001dia.3"],"knownGene","uc001dia.3","chr1",78354199,78407893] +[["uc009wcb.1"],"knownGene","uc009wcb.1","chr1",78354199,78407893] +[["uc001did.1"],"knownGene","uc001did.1","chr1",78383644,78409576] +[["uc001dif.1"],"knownGene","uc001dif.1","chr1",78383809,78409576] +[["uc001dig.3"],"knownGene","uc001dig.3","chr1",78398726,78409576] +[["uc001dih.3"],"knownGene","uc001dih.3","chr1",78412168,78444777] +[["uc001dii.2"],"knownGene","uc001dii.2","chr1",78413592,78444777] +[["uc010orm.1"],"knownGene","uc010orm.1","chr1",78413592,78444777] +[["uc010orn.1"],"knownGene","uc010orn.1","chr1",78444933,78482993] +[["uc001dij.2"],"knownGene","uc001dij.2","chr1",78470635,78482993] +[["uc001dik.2"],"knownGene","uc001dik.2","chr1",78511588,78603111] +[["uc009wcc.2"],"knownGene","uc009wcc.2","chr1",78695282,78835145] +[["uc001dil.1"],"knownGene","uc001dil.1","chr1",78695282,78759574] +[["uc001dim.2"],"knownGene","uc001dim.2","chr1",78956727,79006385] +[["uc001din.2"],"knownGene","uc001din.2","chr1",78956727,79006385] +[["uc010oro.1"],"knownGene","uc010oro.1","chr1",79086087,79111828] +[["uc010orp.1"],"knownGene","uc010orp.1","chr1",79086087,79111828] +[["uc010orq.1"],"knownGene","uc010orq.1","chr1",79086087,79111828] +[["uc001dip.3"],"knownGene","uc001dip.3","chr1",79115476,79129761] +[["uc010orr.1"],"knownGene","uc010orr.1","chr1",79115476,79127139] +[["uc010ors.1"],"knownGene","uc010ors.1","chr1",79115476,79127139] +[["uc001diq.3"],"knownGene","uc001diq.3","chr1",79355450,79472495] +[["uc001dis.2"],"knownGene","uc001dis.2","chr1",81771844,82458106] +[["uc001dit.3"],"knownGene","uc001dit.3","chr1",82165454,82458106] +[["uc001diu.2"],"knownGene","uc001diu.2","chr1",82266081,82458106] +[["uc001div.2"],"knownGene","uc001div.2","chr1",82266081,82458106] +[["uc009wcd.2"],"knownGene","uc009wcd.2","chr1",82266081,82458106] +[["uc001diw.2"],"knownGene","uc001diw.2","chr1",82415872,82458106] +[["uc009wce.1"],"knownGene","uc009wce.1","chr1",82435997,82447660] +[["uc001dix.3"],"knownGene","uc001dix.3","chr1",83439566,83451891] +[["uc001diy.2"],"knownGene","uc001diy.2","chr1",83911736,83920453] +[["uc001diz.3"],"knownGene","uc001diz.3","chr1",84041473,84326679] +[["uc001dja.1"],"knownGene","uc001dja.1","chr1",84267442,84326229] +[["uc001djc.2"],"knownGene","uc001djc.2","chr1",84335058,84464833] +[["uc001djd.2"],"knownGene","uc001djd.2","chr1",84335058,84464833] +[["uc001dje.2"],"knownGene","uc001dje.2","chr1",84335058,84464833] +[["uc001djf.2"],"knownGene","uc001djf.2","chr1",84335058,84464833] +[["uc001djb.2"],"knownGene","uc001djb.2","chr1",84335058,84418070] +[["uc001djg.2"],"knownGene","uc001djg.2","chr1",84335383,84464833] +[["uc001djh.1"],"knownGene","uc001djh.1","chr1",84543635,84546350] +[["uc001djj.2"],"knownGene","uc001djj.2","chr1",84543744,84704179] +[["uc001dji.2"],"knownGene","uc001dji.2","chr1",84543744,84670977] +[["uc001djl.2"],"knownGene","uc001djl.2","chr1",84609951,84704179] +[["uc001djk.2"],"knownGene","uc001djk.2","chr1",84609951,84670977] +[["uc010ort.1"],"knownGene","uc010ort.1","chr1",84630064,84704179] +[["uc001djn.2"],"knownGene","uc001djn.2","chr1",84630064,84704179] +[["uc010oru.1"],"knownGene","uc010oru.1","chr1",84630064,84704179] +[["uc001djp.2"],"knownGene","uc001djp.2","chr1",84630386,84704179] +[["uc001djq.2"],"knownGene","uc001djq.2","chr1",84630386,84704179] +[["uc009wcf.1"],"knownGene","uc009wcf.1","chr1",84630386,84670977] +[["uc001djo.1"],"knownGene","uc001djo.1","chr1",84630386,84644921] +[["uc010orv.1"],"knownGene","uc010orv.1","chr1",84647342,84704179] +[["uc001djr.2"],"knownGene","uc001djr.2","chr1",84764048,84816480] +[["uc010orw.1"],"knownGene","uc010orw.1","chr1",84767288,84816480] +[["uc010orx.1"],"knownGene","uc010orx.1","chr1",84768333,84816480] +[["uc001djs.2"],"knownGene","uc001djs.2","chr1",84810360,84816480] +[["uc009wcg.2"],"knownGene","uc009wcg.2","chr1",84830647,84863576] +[["uc001djt.1"],"knownGene","uc001djt.1","chr1",84864214,84880691] +[["uc001dju.1"],"knownGene","uc001dju.1","chr1",84874033,84880691] +[["uc009wch.1"],"knownGene","uc009wch.1","chr1",84874119,84880691] +[["uc001djv.3"],"knownGene","uc001djv.3","chr1",84944919,84964032] +[["uc001djw.3"],"knownGene","uc001djw.3","chr1",84964006,84972262] +[["uc001djz.1"],"knownGene","uc001djz.1","chr1",84971973,85031875] +[["uc001djy.1"],"knownGene","uc001djy.1","chr1",84971973,85018807] +[["uc001djx.2"],"knownGene","uc001djx.2","chr1",84971973,84992550] +[["uc001dka.2"],"knownGene","uc001dka.2","chr1",85018803,85040163] +[["uc001dkb.2"],"knownGene","uc001dkb.2","chr1",85018803,85040163] +[["uc001dkc.2"],"knownGene","uc001dkc.2","chr1",85018803,85040113] +[["uc001dkd.2"],"knownGene","uc001dkd.2","chr1",85018803,85040113] +[["uc001dke.1"],"knownGene","uc001dke.1","chr1",85093912,85100703] +[["uc010ory.1"],"knownGene","uc010ory.1","chr1",85093912,85097429] +[["uc001dki.2"],"knownGene","uc001dki.2","chr1",85109597,85156180] +[["uc010osa.1"],"knownGene","uc010osa.1","chr1",85109597,85156180] +[["uc001dkj.2"],"knownGene","uc001dkj.2","chr1",85109597,85156180] +[["uc001dkg.2"],"knownGene","uc001dkg.2","chr1",85109597,85155972] +[["uc001dkh.2"],"knownGene","uc001dkh.2","chr1",85109597,85155972] +[["uc010orz.1"],"knownGene","uc010orz.1","chr1",85109597,85155972] +[["uc001dkf.2"],"knownGene","uc001dkf.2","chr1",85109597,85136498] +[["uc009wci.2"],"knownGene","uc009wci.2","chr1",85115312,85155972] +[["uc001dkk.1"],"knownGene","uc001dkk.1","chr1",85121147,85156440] +[["uc009wcj.1"],"knownGene","uc009wcj.1","chr1",85279085,85358896] +[["uc001dkl.2"],"knownGene","uc001dkl.2","chr1",85279085,85331842] +[["uc001dkm.2"],"knownGene","uc001dkm.2","chr1",85391266,85462796] +[["uc001dkn.2"],"knownGene","uc001dkn.2","chr1",85391266,85462796] +[["uc001dkp.2"],"knownGene","uc001dkp.2","chr1",85483765,85514169] +[["uc001dkq.2"],"knownGene","uc001dkq.2","chr1",85483765,85514169] +[["uc001dko.2"],"knownGene","uc001dko.2","chr1",85483765,85489203] +[["uc001dkr.2"],"knownGene","uc001dkr.2","chr1",85490233,85514169] +[["uc001dks.3"],"knownGene","uc001dks.3","chr1",85490241,85514169] +[["uc001dkt.2"],"knownGene","uc001dkt.2","chr1",85527992,85598820] +[["uc009wcl.2"],"knownGene","uc009wcl.2","chr1",85527992,85598820] +[["uc009wcm.2"],"knownGene","uc009wcm.2","chr1",85623356,85666728] +[["uc001dku.3"],"knownGene","uc001dku.3","chr1",85646848,85666728] +[["uc001dkw.2"],"knownGene","uc001dkw.2","chr1",85715638,85725355] +[["uc001dkv.2"],"knownGene","uc001dkv.2","chr1",85715638,85725355] +[["uc001dkx.3"],"knownGene","uc001dkx.3","chr1",85723126,85725355] +[["uc009wcn.2"],"knownGene","uc009wcn.2","chr1",85723126,85725355] +[["uc001dkz.2"],"knownGene","uc001dkz.2","chr1",85731460,85743583] +[["uc001dla.1"],"knownGene","uc001dla.1","chr1",85742397,85865646] +[["uc001dlc.2"],"knownGene","uc001dlc.2","chr1",85784168,86044046] +[["uc001dlb.2"],"knownGene","uc001dlb.2","chr1",85784168,85930889] +[["uc009wco.2"],"knownGene","uc009wco.2","chr1",85784168,85930267] +[["uc010osb.1"],"knownGene","uc010osb.1","chr1",85784168,85870180] +[["uc001dle.2"],"knownGene","uc001dle.2","chr1",86046443,86049646] +[["uc001dlg.2"],"knownGene","uc001dlg.2","chr1",86047597,86049646] +[["uc009wcp.1"],"knownGene","uc009wcp.1","chr1",86048984,86049386] +[["uc010osc.1"],"knownGene","uc010osc.1","chr1",86118491,86174116] +[["uc001dlh.2"],"knownGene","uc001dlh.2","chr1",86118491,86174101] +[["uc001dlj.2"],"knownGene","uc001dlj.2","chr1",86194917,86622154] +[["uc010osd.1"],"knownGene","uc010osd.1","chr1",86194917,86622154] +[["uc001dlk.2"],"knownGene","uc001dlk.2","chr1",86194917,86622154] +[["uc010ose.1"],"knownGene","uc010ose.1","chr1",86194917,86622154] +[["uc010osf.1"],"knownGene","uc010osf.1","chr1",86194917,86622154] +[["uc001dli.2"],"knownGene","uc001dli.2","chr1",86194917,86428932] +[["uc009wcq.2"],"knownGene","uc009wcq.2","chr1",86510811,86622446] +[["uc001dll.1"],"knownGene","uc001dll.1","chr1",86814411,86862003] +[["uc001dlm.1"],"knownGene","uc001dlm.1","chr1",86814411,86862003] +[["uc001dln.2"],"knownGene","uc001dln.2","chr1",86814420,86862003] +[["uc001dlo.2"],"knownGene","uc001dlo.2","chr1",86814420,86862003] +[["uc001dlp.2"],"knownGene","uc001dlp.2","chr1",86814420,86862003] +[["uc010osg.1"],"knownGene","uc010osg.1","chr1",86814420,86862003] +[["uc001dlq.1"],"knownGene","uc001dlq.1","chr1",86824469,86862003] +[["uc009wcr.1"],"knownGene","uc009wcr.1","chr1",86826108,86862003] +[["uc001dlr.3"],"knownGene","uc001dlr.3","chr1",86889768,86922238] +[["uc001dlt.2"],"knownGene","uc001dlt.2","chr1",86934394,86965972] +[["uc001dls.1"],"knownGene","uc001dls.1","chr1",86934394,86960131] +[["uc009wcs.2"],"knownGene","uc009wcs.2","chr1",87012758,87046430] +[["uc009wct.2"],"knownGene","uc009wct.2","chr1",87012758,87046430] +[["uc009wcu.2"],"knownGene","uc009wcu.2","chr1",87012758,87046430] +[["uc010osh.1"],"knownGene","uc010osh.1","chr1",87099958,87121058] +[["uc001dlw.2"],"knownGene","uc001dlw.2","chr1",87170256,87213866] +[["uc001dlx.2"],"knownGene","uc001dlx.2","chr1",87170256,87213866] +[["uc001dly.2"],"knownGene","uc001dly.2","chr1",87170256,87213866] +[["uc001dlz.2"],"knownGene","uc001dlz.2","chr1",87170256,87213866] +[["uc010osi.1"],"knownGene","uc010osi.1","chr1",87328129,87380107] +[["uc010osj.1"],"knownGene","uc010osj.1","chr1",87328129,87380107] +[["uc010osk.1"],"knownGene","uc010osk.1","chr1",87380334,87575680] +[["uc001dmc.3"],"knownGene","uc001dmc.3","chr1",87380334,87564124] +[["uc001dme.1"],"knownGene","uc001dme.1","chr1",87458689,87634884] +[["uc001dmf.2"],"knownGene","uc001dmf.2","chr1",87595447,87634884] +[["uc010osl.1"],"knownGene","uc010osl.1","chr1",87595447,87602350] +[["uc010osm.1"],"knownGene","uc010osm.1","chr1",87597608,87602350] +[["uc010osn.1"],"knownGene","uc010osn.1","chr1",87597608,87602350] +[["uc010oso.1"],"knownGene","uc010oso.1","chr1",87597608,87602350] +[["uc001dmg.3"],"knownGene","uc001dmg.3","chr1",87597608,87602350] +[["uc001dmi.2"],"knownGene","uc001dmi.2","chr1",87794150,87814603] +[["uc001dmj.2"],"knownGene","uc001dmj.2","chr1",87797350,87814603] +[["uc001dmk.2"],"knownGene","uc001dmk.2","chr1",87819211,87837338] +[["uc001dml.1"],"knownGene","uc001dml.1","chr1",89004735,89036543] +[["uc001dmn.2"],"knownGene","uc001dmn.2","chr1",89149921,89301937] +[["uc010osp.1"],"knownGene","uc010osp.1","chr1",89149921,89301937] +[["uc010osq.1"],"knownGene","uc010osq.1","chr1",89149921,89301937] +[["uc009wcv.2"],"knownGene","uc009wcv.2","chr1",89149921,89301937] +[["uc001dmm.1"],"knownGene","uc001dmm.1","chr1",89149921,89271951] +[["uc010osr.1"],"knownGene","uc010osr.1","chr1",89246721,89301937] +[["uc001dmo.3"],"knownGene","uc001dmo.3","chr1",89318321,89357301] +[["uc009wcw.1"],"knownGene","uc009wcw.1","chr1",89325822,89357301] +[["uc001dmp.2"],"knownGene","uc001dmp.2","chr1",89401455,89458643] +[["uc001dmq.2"],"knownGene","uc001dmq.2","chr1",89401455,89458643] +[["uc001dmr.2"],"knownGene","uc001dmr.2","chr1",89401455,89458643] +[["uc009wcx.2"],"knownGene","uc009wcx.2","chr1",89445139,89458643] +[["uc001dms.2"],"knownGene","uc001dms.2","chr1",89445139,89458643] +[["uc001dmt.2"],"knownGene","uc001dmt.2","chr1",89472366,89488549] +[["uc010oss.1"],"knownGene","uc010oss.1","chr1",89472366,89488549] +[["uc001dmu.2"],"knownGene","uc001dmu.2","chr1",89472366,89488549] +[["uc001dmv.2"],"knownGene","uc001dmv.2","chr1",89472366,89488549] +[["uc001dmx.2"],"knownGene","uc001dmx.2","chr1",89517986,89531043] +[["uc001dmy.1"],"knownGene","uc001dmy.1","chr1",89571842,89616258] +[["uc001dmz.1"],"knownGene","uc001dmz.1","chr1",89573309,89591799] +[["uc001dna.2"],"knownGene","uc001dna.2","chr1",89597433,89641723] +[["uc001dnb.2"],"knownGene","uc001dnb.2","chr1",89646831,89664633] +[["uc001dnc.2"],"knownGene","uc001dnc.2","chr1",89724635,89738544] +[["uc001dnd.2"],"knownGene","uc001dnd.2","chr1",89724635,89738544] +[["uc001dne.1"],"knownGene","uc001dne.1","chr1",89728365,89738487] +[["uc001dnf.2"],"knownGene","uc001dnf.2","chr1",89829435,89853719] +[["uc010ost.1"],"knownGene","uc010ost.1","chr1",89829435,89853719] +[["uc009wcy.1"],"knownGene","uc009wcy.1","chr1",89873237,89890493] +[["uc001dni.2"],"knownGene","uc001dni.2","chr1",89990396,90063418] +[["uc001dnh.2"],"knownGene","uc001dnh.2","chr1",89990396,90063418] +[["uc001dnj.2"],"knownGene","uc001dnj.2","chr1",90024269,90063418] +[["uc001dnk.1"],"knownGene","uc001dnk.1","chr1",90090407,90098453] +[["uc001dnl.3"],"knownGene","uc001dnl.3","chr1",90098643,90185093] +[["uc001dnm.2"],"knownGene","uc001dnm.2","chr1",90286572,90401987] +[["uc001dnn.2"],"knownGene","uc001dnn.2","chr1",90287479,90401987] +[["uc001dno.2"],"knownGene","uc001dno.2","chr1",90458825,90460525] +[["uc001dnq.2"],"knownGene","uc001dnq.2","chr1",90460677,90494094] +[["uc009wda.1"],"knownGene","uc009wda.1","chr1",90460677,90494094] +[["uc001dnr.2"],"knownGene","uc001dnr.2","chr1",90460677,90494094] +[["uc001dnp.3"],"knownGene","uc001dnp.3","chr1",90460677,90471999] +[["uc001dns.2"],"knownGene","uc001dns.2","chr1",91177579,91182794] +[["uc001dnu.1"],"knownGene","uc001dnu.1","chr1",91295103,91317175] +[["uc001dnt.1"],"knownGene","uc001dnt.1","chr1",91295103,91301718] +[["uc001dnw.2"],"knownGene","uc001dnw.2","chr1",91380859,91487671] +[["uc001dnx.2"],"knownGene","uc001dnx.2","chr1",91380859,91487671] +[["uc001dnv.2"],"knownGene","uc001dnv.2","chr1",91380859,91487030] +[["uc001dny.1"],"knownGene","uc001dny.1","chr1",91403828,91487030] +[["uc001doa.3"],"knownGene","uc001doa.3","chr1",91726323,91870426] +[["uc010osu.1"],"knownGene","uc010osu.1","chr1",91726323,91870426] +[["uc009wdb.2"],"knownGene","uc009wdb.2","chr1",91726323,91818208] +[["uc001dob.3"],"knownGene","uc001dob.3","chr1",91727745,91813033] +[["uc010osv.1"],"knownGene","uc010osv.1","chr1",91733301,91870426] +[["uc001doc.1"],"knownGene","uc001doc.1","chr1",91842999,91866666] +[["uc001doe.2"],"knownGene","uc001doe.2","chr1",91966403,91991320] +[["uc001dof.2"],"knownGene","uc001dof.2","chr1",91966403,91991320] +[["uc010osw.1"],"knownGene","uc010osw.1","chr1",91966403,91991320] +[["uc009wdc.2"],"knownGene","uc009wdc.2","chr1",91966664,91991320] +[["uc009wdd.2"],"knownGene","uc009wdd.2","chr1",91980375,91991320] +[["uc010osx.1"],"knownGene","uc010osx.1","chr1",92100567,92109334] +[["uc001doj.2"],"knownGene","uc001doj.2","chr1",92145901,92371559] +[["uc001doh.2"],"knownGene","uc001doh.2","chr1",92145901,92351787] +[["uc010osy.1"],"knownGene","uc010osy.1","chr1",92145901,92351787] +[["uc001doi.2"],"knownGene","uc001doi.2","chr1",92145901,92351787] +[["uc009wde.2"],"knownGene","uc009wde.2","chr1",92145901,92327603] +[["uc001dok.3"],"knownGene","uc001dok.3","chr1",92414927,92479983] +[["uc001dol.3"],"knownGene","uc001dol.3","chr1",92414927,92479983] +[["uc010osz.1"],"knownGene","uc010osz.1","chr1",92414927,92479983] +[["uc009wdf.2"],"knownGene","uc009wdf.2","chr1",92414927,92479983] +[["uc010ota.1"],"knownGene","uc010ota.1","chr1",92414927,92479983] +[["uc010otb.1"],"knownGene","uc010otb.1","chr1",92414928,92479983] +[["uc001dom.3"],"knownGene","uc001dom.3","chr1",92417708,92479983] +[["uc001don.2"],"knownGene","uc001don.2","chr1",92495532,92529093] +[["uc001doo.2"],"knownGene","uc001doo.2","chr1",92545861,92613395] +[["uc010otc.1"],"knownGene","uc010otc.1","chr1",92545861,92613395] +[["uc010otd.1"],"knownGene","uc010otd.1","chr1",92632608,92650279] +[["uc001dop.2"],"knownGene","uc001dop.2","chr1",92634414,92650279] +[["uc001doq.2"],"knownGene","uc001doq.2","chr1",92683572,92711366] +[["uc010ote.1"],"knownGene","uc010ote.1","chr1",92683572,92711366] +[["uc001dor.2"],"knownGene","uc001dor.2","chr1",92711956,92764566] +[["uc009wdg.2"],"knownGene","uc009wdg.2","chr1",92711956,92764566] +[["uc001dos.2"],"knownGene","uc001dos.2","chr1",92711956,92764566] +[["uc001dot.2"],"knownGene","uc001dot.2","chr1",92764521,92853732] +[["uc009wdh.2"],"knownGene","uc009wdh.2","chr1",92764521,92853732] +[["uc001dow.3"],"knownGene","uc001dow.3","chr1",92940318,92952433] +[["uc001dov.3"],"knownGene","uc001dov.3","chr1",92940318,92951628] +[["uc001dou.3"],"knownGene","uc001dou.3","chr1",92940318,92949356] +[["uc001dox.2"],"knownGene","uc001dox.2","chr1",92974254,93257961] +[["uc010otf.1"],"knownGene","uc010otf.1","chr1",92974254,93257961] +[["uc001doy.1"],"knownGene","uc001doy.1","chr1",93029198,93159945] +[["uc001doz.2"],"knownGene","uc001doz.2","chr1",93297593,93307480] +[["uc001dpa.2"],"knownGene","uc001dpa.2","chr1",93297593,93307480] +[["uc001dpb.2"],"knownGene","uc001dpb.2","chr1",93297916,93307480] +[["uc001dpc.2"],"knownGene","uc001dpc.2","chr1",93298452,93427079] +[["uc001dpd.2"],"knownGene","uc001dpd.2","chr1",93301783,93306626] +[["uc001dpe.2"],"knownGene","uc001dpe.2","chr1",93302845,93302940] +[["uc009wdi.1"],"knownGene","uc009wdi.1","chr1",93306275,93306408] +[["uc001dpg.2"],"knownGene","uc001dpg.2","chr1",93307720,93427079] +[["uc010otg.1"],"knownGene","uc010otg.1","chr1",93307720,93342152] +[["uc009wdj.2"],"knownGene","uc009wdj.2","chr1",93544791,93604636] +[["uc010oth.1"],"knownGene","uc010oth.1","chr1",93544791,93604636] +[["uc009wdk.2"],"knownGene","uc009wdk.2","chr1",93544791,93604636] +[["uc001dpi.3"],"knownGene","uc001dpi.3","chr1",93544791,93604636] +[["uc010oti.1"],"knownGene","uc010oti.1","chr1",93544791,93604636] +[["uc001dpj.3"],"knownGene","uc001dpj.3","chr1",93544791,93604636] +[["uc001dph.2"],"knownGene","uc001dph.2","chr1",93544791,93585831] +[["uc001dpl.3"],"knownGene","uc001dpl.3","chr1",93575786,93604636] +[["uc001dpm.3"],"knownGene","uc001dpm.3","chr1",93594351,93604636] +[["uc001dpn.2"],"knownGene","uc001dpn.2","chr1",93617410,93646246] +[["uc001dpo.2"],"knownGene","uc001dpo.2","chr1",93617410,93646246] +[["uc001dpp.2"],"knownGene","uc001dpp.2","chr1",93617410,93646246] +[["uc001dpq.2"],"knownGene","uc001dpq.2","chr1",93645919,93744266] +[["uc009wdl.1"],"knownGene","uc009wdl.1","chr1",93671066,93712511] +[["uc001dpr.1"],"knownGene","uc001dpr.1","chr1",93720027,93730500] +[["uc001dps.2"],"knownGene","uc001dps.2","chr1",93730202,93811374] +[["uc001dpt.1"],"knownGene","uc001dpt.1","chr1",93775665,93811374] +[["uc001dpu.2"],"knownGene","uc001dpu.2","chr1",93811477,93828146] +[["uc010otj.1"],"knownGene","uc010otj.1","chr1",93811491,93828146] +[["uc001dpv.2"],"knownGene","uc001dpv.2","chr1",93913838,94020216] +[["uc001dpw.2"],"knownGene","uc001dpw.2","chr1",93913838,94020216] +[["uc010otk.1"],"knownGene","uc010otk.1","chr1",93995208,94020216] +[["uc010otl.1"],"knownGene","uc010otl.1","chr1",94009663,94020216] +[["uc001dqb.2"],"knownGene","uc001dqb.2","chr1",94027350,94312706] +[["uc001dqa.2"],"knownGene","uc001dqa.2","chr1",94027350,94147385] +[["uc001dpz.2"],"knownGene","uc001dpz.2","chr1",94027350,94146926] +[["uc001dpy.2"],"knownGene","uc001dpy.2","chr1",94027350,94079654] +[["uc001dpx.3"],"knownGene","uc001dpx.3","chr1",94027350,94050719] +[["uc009wdm.1"],"knownGene","uc009wdm.1","chr1",94036888,94050719] +[["uc009wdn.2"],"knownGene","uc009wdn.2","chr1",94057524,94065586] +[["uc001dqd.1"],"knownGene","uc001dqd.1","chr1",94219111,94240930] +[["uc001dqe.1"],"knownGene","uc001dqe.1","chr1",94317792,94319887] +[["uc001dqf.2"],"knownGene","uc001dqf.2","chr1",94335337,94344742] +[["uc010otm.1"],"knownGene","uc010otm.1","chr1",94335337,94344742] +[["uc009wdo.1"],"knownGene","uc009wdo.1","chr1",94342004,94344742] +[["uc001dqg.1"],"knownGene","uc001dqg.1","chr1",94352589,94375012] +[["uc001dqh.2"],"knownGene","uc001dqh.2","chr1",94458395,94586705] +[["uc001dqi.1"],"knownGene","uc001dqi.1","chr1",94467113,94476485] +[["uc009wdp.1"],"knownGene","uc009wdp.1","chr1",94475932,94484228] +[["uc010otn.1"],"knownGene","uc010otn.1","chr1",94511192,94586705] +[["uc009wdq.1"],"knownGene","uc009wdq.1","chr1",94615402,94740624] +[["uc001dqj.3"],"knownGene","uc001dqj.3","chr1",94634463,94703307] +[["uc001dqk.2"],"knownGene","uc001dqk.2","chr1",94642178,94661497] +[["uc001dql.2"],"knownGene","uc001dql.2","chr1",94667455,94703307] +[["uc001dqn.3"],"knownGene","uc001dqn.3","chr1",94883932,94984218] +[["uc010oto.1"],"knownGene","uc010oto.1","chr1",94883932,94984218] +[["uc010otp.1"],"knownGene","uc010otp.1","chr1",94883932,94984218] +[["uc009wdr.2"],"knownGene","uc009wdr.2","chr1",94883932,94984218] +[["uc001dqm.3"],"knownGene","uc001dqm.3","chr1",94883932,94944259] +[["uc001dqo.3"],"knownGene","uc001dqo.3","chr1",94947048,94984218] +[["uc001dqr.2"],"knownGene","uc001dqr.2","chr1",94994731,95007371] +[["uc001dqs.2"],"knownGene","uc001dqs.2","chr1",94994731,95007371] +[["uc001dqp.2"],"knownGene","uc001dqp.2","chr1",94994731,95006622] +[["uc001dqq.2"],"knownGene","uc001dqq.2","chr1",94994731,95006622] +[["uc001dqt.2"],"knownGene","uc001dqt.2","chr1",95005812,95007371] +[["uc001dqu.2"],"knownGene","uc001dqu.2","chr1",95123089,95285834] +[["uc001dqv.3"],"knownGene","uc001dqv.3","chr1",95285900,95360801] +[["uc001dqx.3"],"knownGene","uc001dqx.3","chr1",95285900,95360801] +[["uc010otq.1"],"knownGene","uc010otq.1","chr1",95285900,95360801] +[["uc010otr.1"],"knownGene","uc010otr.1","chr1",95285900,95360801] +[["uc001dqw.3"],"knownGene","uc001dqw.3","chr1",95286099,95360801] +[["uc010ots.1"],"knownGene","uc010ots.1","chr1",95286099,95360801] +[["uc009wds.2"],"knownGene","uc009wds.2","chr1",95290048,95360801] +[["uc010ott.1"],"knownGene","uc010ott.1","chr1",95290048,95360801] +[["uc010otu.1"],"knownGene","uc010otu.1","chr1",95292994,95356823] +[["uc001dqz.3"],"knownGene","uc001dqz.3","chr1",95362508,95392735] +[["uc010otx.1"],"knownGene","uc010otx.1","chr1",95362508,95392735] +[["uc010otw.1"],"knownGene","uc010otw.1","chr1",95362508,95392638] +[["uc010otv.1"],"knownGene","uc010otv.1","chr1",95362508,95391337] +[["uc001dra.2"],"knownGene","uc001dra.2","chr1",95448278,95538507] +[["uc001drb.2"],"knownGene","uc001drb.2","chr1",95582893,95663159] +[["uc001drc.2"],"knownGene","uc001drc.2","chr1",95582994,95663159] +[["uc001drd.3"],"knownGene","uc001drd.3","chr1",95583478,95710916] +[["uc001dre.1"],"knownGene","uc001dre.1","chr1",95628774,95699538] +[["uc009wdu.2"],"knownGene","uc009wdu.2","chr1",95699710,95712773] +[["uc001drf.3"],"knownGene","uc001drf.3","chr1",95699710,95712773] +[["uc001drh.3"],"knownGene","uc001drh.3","chr1",95699710,95712773] +[["uc009wdv.2"],"knownGene","uc009wdv.2","chr1",95699710,95712773] +[["uc001drg.3"],"knownGene","uc001drg.3","chr1",95699710,95712773] +[["uc001dri.3"],"knownGene","uc001dri.3","chr1",95699710,95712773] +[["uc010oty.1"],"knownGene","uc010oty.1","chr1",95699710,95710916] +[["uc009wdt.2"],"knownGene","uc009wdt.2","chr1",95699710,95710916] +[["uc001drj.1"],"knownGene","uc001drj.1","chr1",95820944,95846556] +[["uc001drk.1"],"knownGene","uc001drk.1","chr1",95820944,95846556] +[["uc001drl.2"],"knownGene","uc001drl.2","chr1",95975895,95981019] +[["uc001drq.2"],"knownGene","uc001drq.2","chr1",97187174,97280599] +[["uc001drr.2"],"knownGene","uc001drr.2","chr1",97187174,97280599] +[["uc001drn.2"],"knownGene","uc001drn.2","chr1",97187174,97279217] +[["uc001dro.2"],"knownGene","uc001dro.2","chr1",97187174,97279217] +[["uc010otz.1"],"knownGene","uc010otz.1","chr1",97187174,97279217] +[["uc001drp.2"],"knownGene","uc001drp.2","chr1",97187174,97279217] +[["uc009wdw.2"],"knownGene","uc009wdw.2","chr1",97187174,97279217] +[["uc001drm.2"],"knownGene","uc001drm.2","chr1",97187174,97239518] +[["uc010oua.1"],"knownGene","uc010oua.1","chr1",97187346,97279217] +[["uc001dru.2"],"knownGene","uc001dru.2","chr1",97188272,97280599] +[["uc001drt.2"],"knownGene","uc001drt.2","chr1",97250614,97280599] +[["uc001drs.1"],"knownGene","uc001drs.1","chr1",97250614,97279217] +[["uc001drv.2"],"knownGene","uc001drv.2","chr1",97543301,98386615] +[["uc010oub.1"],"knownGene","uc010oub.1","chr1",98157272,98386615] +[["uc001drw.2"],"knownGene","uc001drw.2","chr1",98185314,98386615] +[["uc001drx.1"],"knownGene","uc001drx.1","chr1",98453555,98515161] +[["uc001dry.1"],"knownGene","uc001dry.1","chr1",98508912,98511014] +[["uc009wdx.2"],"knownGene","uc009wdx.2","chr1",98509852,98511952] +[["uc010ouc.1"],"knownGene","uc010ouc.1","chr1",99127235,99226054] +[["uc001dsa.2"],"knownGene","uc001dsa.2","chr1",99127235,99226054] +[["uc010oud.1"],"knownGene","uc010oud.1","chr1",99127235,99226054] +[["uc001dsb.2"],"knownGene","uc001dsb.2","chr1",99355802,99470449] +[["uc001dsc.2"],"knownGene","uc001dsc.2","chr1",99355802,99470449] +[["uc001dsd.1"],"knownGene","uc001dsd.1","chr1",99469831,99614408] +[["uc001dse.2"],"knownGene","uc001dse.2","chr1",99729899,99775136] +[["uc010oue.1"],"knownGene","uc010oue.1","chr1",99729899,99775136] +[["uc001dsg.2"],"knownGene","uc001dsg.2","chr1",100111430,100160096] +[["uc001dsf.2"],"knownGene","uc001dsf.2","chr1",100111430,100155632] +[["uc001dsh.1"],"knownGene","uc001dsh.1","chr1",100174258,100231349] +[["uc001dsi.1"],"knownGene","uc001dsi.1","chr1",100315639,100389579] +[["uc001dsj.1"],"knownGene","uc001dsj.1","chr1",100316044,100389579] +[["uc001dsk.1"],"knownGene","uc001dsk.1","chr1",100316044,100389579] +[["uc001dsl.1"],"knownGene","uc001dsl.1","chr1",100316044,100389579] +[["uc001dsm.1"],"knownGene","uc001dsm.1","chr1",100316530,100389579] +[["uc001dsn.1"],"knownGene","uc001dsn.1","chr1",100326765,100389579] +[["uc001dso.1"],"knownGene","uc001dso.1","chr1",100434000,100435404] +[["uc001dsp.1"],"knownGene","uc001dsp.1","chr1",100435539,100489006] +[["uc001dsq.1"],"knownGene","uc001dsq.1","chr1",100435539,100489006] +[["uc009wdy.1"],"knownGene","uc009wdy.1","chr1",100435539,100489006] +[["uc001dsr.1"],"knownGene","uc001dsr.1","chr1",100435991,100489006] +[["uc001dss.1"],"knownGene","uc001dss.1","chr1",100459157,100489006] +[["uc001dst.2"],"knownGene","uc001dst.2","chr1",100503788,100548927] +[["uc001dsu.2"],"knownGene","uc001dsu.2","chr1",100549103,100598511] +[["uc009wdz.2"],"knownGene","uc009wdz.2","chr1",100549103,100598511] +[["uc001dsv.2"],"knownGene","uc001dsv.2","chr1",100598705,100616053] +[["uc010ouf.1"],"knownGene","uc010ouf.1","chr1",100598705,100616053] +[["uc009wea.2"],"knownGene","uc009wea.2","chr1",100598705,100616053] +[["uc001dsy.1"],"knownGene","uc001dsy.1","chr1",100614412,100643800] +[["uc001dsz.1"],"knownGene","uc001dsz.1","chr1",100614412,100643800] +[["uc001dsw.1"],"knownGene","uc001dsw.1","chr1",100614412,100643771] +[["uc001dsx.1"],"knownGene","uc001dsx.1","chr1",100614412,100643771] +[["uc001dta.2"],"knownGene","uc001dta.2","chr1",100652478,100715409] +[["uc010oug.1"],"knownGene","uc010oug.1","chr1",100652478,100715409] +[["uc001dtd.2"],"knownGene","uc001dtd.2","chr1",100731713,100758323] +[["uc001dtc.2"],"knownGene","uc001dtc.2","chr1",100731713,100758323] +[["uc010ouh.1"],"knownGene","uc010ouh.1","chr1",100731713,100739511] +[["uc010oui.1"],"knownGene","uc010oui.1","chr1",100810583,100965021] +[["uc009web.2"],"knownGene","uc009web.2","chr1",100810583,100963763] +[["uc001dtg.3"],"knownGene","uc001dtg.3","chr1",100818022,100985832] +[["uc009wee.2"],"knownGene","uc009wee.2","chr1",100818022,100985832] +[["uc001dtf.2"],"knownGene","uc001dtf.2","chr1",100818022,100965021] +[["uc009wed.1"],"knownGene","uc009wed.1","chr1",100818022,100965021] +[["uc001dte.3"],"knownGene","uc001dte.3","chr1",100818022,100950925] +[["uc009wec.1"],"knownGene","uc009wec.1","chr1",100818022,100856616] +[["uc001dth.2"],"knownGene","uc001dth.2","chr1",101003727,101007582] +[["uc001dti.2"],"knownGene","uc001dti.2","chr1",101185296,101204599] +[["uc001dtj.2"],"knownGene","uc001dtj.2","chr1",101185296,101204599] +[["uc010ouj.1"],"knownGene","uc010ouj.1","chr1",101185296,101204599] +[["uc001dtk.1"],"knownGene","uc001dtk.1","chr1",101337940,101360418] +[["uc001dtl.1"],"knownGene","uc001dtl.1","chr1",101337940,101360418] +[["uc010ouk.1"],"knownGene","uc010ouk.1","chr1",101337940,101360418] +[["uc001dtm.1"],"knownGene","uc001dtm.1","chr1",101337940,101360418] +[["uc001dtn.2"],"knownGene","uc001dtn.2","chr1",101361631,101447311] +[["uc001dto.2"],"knownGene","uc001dto.2","chr1",101361631,101447311] +[["uc001dtz.2"],"knownGene","uc001dtz.2","chr1",101455179,101491644] +[["uc001dtr.2"],"knownGene","uc001dtr.2","chr1",101455179,101491362] +[["uc001dtq.2"],"knownGene","uc001dtq.2","chr1",101455179,101491362] +[["uc001dts.2"],"knownGene","uc001dts.2","chr1",101455179,101491362] +[["uc001dtt.2"],"knownGene","uc001dtt.2","chr1",101455179,101491362] +[["uc001dtu.2"],"knownGene","uc001dtu.2","chr1",101455179,101491362] +[["uc001dtv.2"],"knownGene","uc001dtv.2","chr1",101455179,101491362] +[["uc001dtw.2"],"knownGene","uc001dtw.2","chr1",101455179,101491362] +[["uc001dtx.2"],"knownGene","uc001dtx.2","chr1",101455179,101491362] +[["uc001dty.2"],"knownGene","uc001dty.2","chr1",101455179,101491362] +[["uc001dua.2"],"knownGene","uc001dua.2","chr1",101491408,101552817] +[["uc001dub.2"],"knownGene","uc001dub.2","chr1",101491408,101552817] +[["uc001duc.2"],"knownGene","uc001duc.2","chr1",101538215,101552817] +[["uc001dud.2"],"knownGene","uc001dud.2","chr1",101702304,101707076] +[["uc009weg.2"],"knownGene","uc009weg.2","chr1",101702458,101707076] +[["uc001dug.2"],"knownGene","uc001dug.2","chr1",102268126,102462790] +[["uc001duh.2"],"knownGene","uc001duh.2","chr1",102268126,102462790] +[["uc001dui.2"],"knownGene","uc001dui.2","chr1",102268126,102462790] +[["uc001duj.2"],"knownGene","uc001duj.2","chr1",102268126,102462790] +[["uc001due.2"],"knownGene","uc001due.2","chr1",102268126,102312600] +[["uc001duf.2"],"knownGene","uc001duf.2","chr1",102268126,102312600] +[["uc001dul.2"],"knownGene","uc001dul.2","chr1",103342023,103574052] +[["uc001dum.2"],"knownGene","uc001dum.2","chr1",103342023,103574052] +[["uc001dun.2"],"knownGene","uc001dun.2","chr1",103342023,103574052] +[["uc009weh.2"],"knownGene","uc009weh.2","chr1",103342023,103574052] +[["uc001duk.2"],"knownGene","uc001duk.2","chr1",103342023,103496800] +[["uc010oun.1"],"knownGene","uc010oun.1","chr1",104068577,104097857] +[["uc010oul.1"],"knownGene","uc010oul.1","chr1",104068577,104096306] +[["uc010oum.1"],"knownGene","uc010oum.1","chr1",104068577,104096306] +[["uc010ouo.1"],"knownGene","uc010ouo.1","chr1",104078747,104122147] +[["uc001duq.2"],"knownGene","uc001duq.2","chr1",104095895,104122147] +[["uc010oup.1"],"knownGene","uc010oup.1","chr1",104112025,104114006] +[["uc001dur.2"],"knownGene","uc001dur.2","chr1",104112334,104122147] +[["uc001dus.1"],"knownGene","uc001dus.1","chr1",104118062,104153092] +[["uc001dut.2"],"knownGene","uc001dut.2","chr1",104159998,104168393] +[["uc010ouq.1"],"knownGene","uc010ouq.1","chr1",104159998,104162543] +[["uc001duu.2"],"knownGene","uc001duu.2","chr1",104198140,104207172] +[["uc001duv.2"],"knownGene","uc001duv.2","chr1",104198301,104207172] +[["uc001dux.1"],"knownGene","uc001dux.1","chr1",104230039,104239073] +[["uc001duw.1"],"knownGene","uc001duw.1","chr1",104230039,104238912] +[["uc010our.1"],"knownGene","uc010our.1","chr1",104257374,104262492] +[["uc001duy.2"],"knownGene","uc001duy.2","chr1",104292278,104301310] +[["uc001duz.2"],"knownGene","uc001duz.2","chr1",104292439,104301310] +[["uc001dva.2"],"knownGene","uc001dva.2","chr1",106144775,106161557] +[["uc010ous.1"],"knownGene","uc010ous.1","chr1",107599266,107601907] +[["uc001dvh.3"],"knownGene","uc001dvh.3","chr1",107682628,108024471] +[["uc001dvf.3"],"knownGene","uc001dvf.3","chr1",107682628,108024471] +[["uc001dvc.3"],"knownGene","uc001dvc.3","chr1",107682628,108024471] +[["uc010out.1"],"knownGene","uc010out.1","chr1",107682628,108024471] +[["uc001dvd.1"],"knownGene","uc001dvd.1","chr1",107683548,107953207] +[["uc001dvi.2"],"knownGene","uc001dvi.2","chr1",107937775,108024471] +[["uc001dve.2"],"knownGene","uc001dve.2","chr1",107937775,108024471] +[["uc009wek.2"],"knownGene","uc009wek.2","chr1",107937775,108024471] +[["uc001dvg.2"],"knownGene","uc001dvg.2","chr1",107937775,108024471] +[["uc009wem.2"],"knownGene","uc009wem.2","chr1",107937775,108024471] +[["uc001dvk.1"],"knownGene","uc001dvk.1","chr1",108113781,108507545] +[["uc010ouw.1"],"knownGene","uc010ouw.1","chr1",108113781,108507545] +[["uc001dvj.1"],"knownGene","uc001dvj.1","chr1",108113781,108231126] +[["uc010ouv.1"],"knownGene","uc010ouv.1","chr1",108113781,108231126] +[["uc010ouu.1"],"knownGene","uc010ouu.1","chr1",108113781,108220631] +[["uc010oux.1"],"knownGene","uc010oux.1","chr1",108211462,108507545] +[["uc001dvl.1"],"knownGene","uc001dvl.1","chr1",108211462,108506218] +[["uc001dvn.3"],"knownGene","uc001dvn.3","chr1",108677448,108742974] +[["uc001dvm.2"],"knownGene","uc001dvm.2","chr1",108677448,108735363] +[["uc009weo.2"],"knownGene","uc009weo.2","chr1",108765962,108786703] +[["uc001dvo.2"],"knownGene","uc001dvo.2","chr1",108765962,108786703] +[["uc009wen.2"],"knownGene","uc009wen.2","chr1",108771541,108786703] +[["uc001dvp.1"],"knownGene","uc001dvp.1","chr1",108803726,108816311] +[["uc001dvq.2"],"knownGene","uc001dvq.2","chr1",108918459,108953432] +[["uc001dvr.1"],"knownGene","uc001dvr.1","chr1",108963310,108975897] +[["uc009wep.2"],"knownGene","uc009wep.2","chr1",108992903,109013259] +[["uc009weq.2"],"knownGene","uc009weq.2","chr1",108992903,109013259] +[["uc010ouy.1"],"knownGene","uc010ouy.1","chr1",109102970,109181948] +[["uc001dvu.3"],"knownGene","uc001dvu.3","chr1",109190911,109204148] +[["uc009wer.2"],"knownGene","uc009wer.2","chr1",109190911,109204148] +[["uc001dvt.3"],"knownGene","uc001dvt.3","chr1",109190911,109203744] +[["uc001dvv.3"],"knownGene","uc001dvv.3","chr1",109234931,109244420] +[["uc001dvw.3"],"knownGene","uc001dvw.3","chr1",109234931,109244420] +[["uc010ouz.1"],"knownGene","uc010ouz.1","chr1",109234931,109244420] +[["uc001dvx.2"],"knownGene","uc001dvx.2","chr1",109255555,109285365] +[["uc010ova.1"],"knownGene","uc010ova.1","chr1",109264956,109285365] +[["uc001dvy.2"],"knownGene","uc001dvy.2","chr1",109289284,109352139] +[["uc001dvz.2"],"knownGene","uc001dvz.2","chr1",109289284,109352139] +[["uc001dwb.2"],"knownGene","uc001dwb.2","chr1",109358531,109400850] +[["uc001dwa.2"],"knownGene","uc001dwa.2","chr1",109358531,109399716] +[["uc010ovb.1"],"knownGene","uc010ovb.1","chr1",109365461,109506111] +[["uc001dwc.2"],"knownGene","uc001dwc.2","chr1",109399838,109401144] +[["uc010ove.1"],"knownGene","uc010ove.1","chr1",109419602,109476957] +[["uc010ovc.1"],"knownGene","uc010ovc.1","chr1",109419602,109473043] +[["uc010ovd.1"],"knownGene","uc010ovd.1","chr1",109419602,109473043] +[["uc001dwf.1"],"knownGene","uc001dwf.1","chr1",109472129,109506111] +[["uc001dwg.1"],"knownGene","uc001dwg.1","chr1",109472129,109506111] +[["uc001dwe.1"],"knownGene","uc001dwe.1","chr1",109472129,109506099] +[["uc009wes.1"],"knownGene","uc009wes.1","chr1",109477246,109493070] +[["uc009wet.1"],"knownGene","uc009wet.1","chr1",109477246,109493070] +[["uc001dwh.1"],"knownGene","uc001dwh.1","chr1",109486096,109506111] +[["uc001dwl.2"],"knownGene","uc001dwl.2","chr1",109512839,109584850] +[["uc001dwi.2"],"knownGene","uc001dwi.2","chr1",109512839,109584850] +[["uc001dwj.2"],"knownGene","uc001dwj.2","chr1",109512839,109584850] +[["uc010ovf.1"],"knownGene","uc010ovf.1","chr1",109512839,109560223] +[["uc001dwk.2"],"knownGene","uc001dwk.2","chr1",109525903,109584850] +[["uc001dwm.1"],"knownGene","uc001dwm.1","chr1",109606997,109618624] +[["uc001dwn.2"],"knownGene","uc001dwn.2","chr1",109633402,109639553] +[["uc009weu.2"],"knownGene","uc009weu.2","chr1",109633402,109639553] +[["uc001dwo.1"],"knownGene","uc001dwo.1","chr1",109642814,109643234] +[["uc009wew.2"],"knownGene","uc009wew.2","chr1",109648573,109656479] +[["uc009wev.2"],"knownGene","uc009wev.2","chr1",109648573,109655369] +[["uc001dwp.3"],"knownGene","uc001dwp.3","chr1",109648573,109655369] +[["uc001dwq.2"],"knownGene","uc001dwq.2","chr1",109656532,109745853] +[["uc010ovg.1"],"knownGene","uc010ovg.1","chr1",109656718,109749401] +[["uc009wey.2"],"knownGene","uc009wey.2","chr1",109656718,109745853] +[["uc009wex.1"],"knownGene","uc009wex.1","chr1",109656718,109743522] +[["uc001dwr.2"],"knownGene","uc001dwr.2","chr1",109730600,109745853] +[["uc001dws.1"],"knownGene","uc001dws.1","chr1",109740095,109742859] +[["uc009wez.1"],"knownGene","uc009wez.1","chr1",109740095,109742859] +[["uc001dwu.1"],"knownGene","uc001dwu.1","chr1",109756539,109780785] +[["uc001dwv.1"],"knownGene","uc001dwv.1","chr1",109756539,109780785] +[["uc001dww.1"],"knownGene","uc001dww.1","chr1",109756539,109780785] +[["uc001dwx.1"],"knownGene","uc001dwx.1","chr1",109756539,109780785] +[["uc009wfa.1"],"knownGene","uc009wfa.1","chr1",109756539,109780785] +[["uc001dwt.1"],"knownGene","uc001dwt.1","chr1",109756539,109778831] +[["uc001dwy.1"],"knownGene","uc001dwy.1","chr1",109756600,109780785] +[["uc001dwz.1"],"knownGene","uc001dwz.1","chr1",109772013,109780785] +[["uc001dxa.3"],"knownGene","uc001dxa.3","chr1",109792640,109818377] +[["uc001dxh.2"],"knownGene","uc001dxh.2","chr1",109822178,109825808] +[["uc001dxi.2"],"knownGene","uc001dxi.2","chr1",109822178,109825808] +[["uc001dxj.2"],"knownGene","uc001dxj.2","chr1",109822178,109825808] +[["uc001dxd.2"],"knownGene","uc001dxd.2","chr1",109822178,109825771] +[["uc001dxe.2"],"knownGene","uc001dxe.2","chr1",109822178,109825771] +[["uc001dxf.2"],"knownGene","uc001dxf.2","chr1",109822178,109825771] +[["uc001dxg.2"],"knownGene","uc001dxg.2","chr1",109822178,109825771] +[["uc001dxc.2"],"knownGene","uc001dxc.2","chr1",109822178,109825747] +[["uc001dxb.2"],"knownGene","uc001dxb.2","chr1",109822178,109825041] +[["uc001dxk.1"],"knownGene","uc001dxk.1","chr1",109834986,109849663] +[["uc010ovh.1"],"knownGene","uc010ovh.1","chr1",109834986,109849663] +[["uc001dxl.2"],"knownGene","uc001dxl.2","chr1",109834990,109849663] +[["uc001dxm.1"],"knownGene","uc001dxm.1","chr1",109852191,109940563] +[["uc010ovi.1"],"knownGene","uc010ovi.1","chr1",109852191,109935979] +[["uc009wfb.2"],"knownGene","uc009wfb.2","chr1",109888372,109935979] +[["uc001dxn.2"],"knownGene","uc001dxn.2","chr1",109944477,109969037] +[["uc010ovj.1"],"knownGene","uc010ovj.1","chr1",109944477,109969037] +[["uc001dxp.2"],"knownGene","uc001dxp.2","chr1",110009099,110024763] +[["uc010ovk.1"],"knownGene","uc010ovk.1","chr1",110009099,110024763] +[["uc001dxo.2"],"knownGene","uc001dxo.2","chr1",110009099,110021304] +[["uc001dxq.2"],"knownGene","uc001dxq.2","chr1",110019390,110021304] +[["uc001dxr.2"],"knownGene","uc001dxr.2","chr1",110026560,110035418] +[["uc001dxs.2"],"knownGene","uc001dxs.2","chr1",110031468,110035418] +[["uc001dxt.2"],"knownGene","uc001dxt.2","chr1",110033543,110035418] +[["uc010ovl.1"],"knownGene","uc010ovl.1","chr1",110036657,110043062] +[["uc010ovm.1"],"knownGene","uc010ovm.1","chr1",110036657,110043062] +[["uc001dxu.2"],"knownGene","uc001dxu.2","chr1",110036700,110043062] +[["uc001dxw.2"],"knownGene","uc001dxw.2","chr1",110036700,110043062] +[["uc010ovn.1"],"knownGene","uc010ovn.1","chr1",110036700,110043062] +[["uc010ovo.1"],"knownGene","uc010ovo.1","chr1",110036700,110043062] +[["uc009wfd.2"],"knownGene","uc009wfd.2","chr1",110036700,110043062] +[["uc010ovp.1"],"knownGene","uc010ovp.1","chr1",110036700,110043062] +[["uc001dxx.3"],"knownGene","uc001dxx.3","chr1",110049446,110052336] +[["uc001dxy.2"],"knownGene","uc001dxy.2","chr1",110082493,110088455] +[["uc001dxz.2"],"knownGene","uc001dxz.2","chr1",110091185,110138452] +[["uc010ovq.1"],"knownGene","uc010ovq.1","chr1",110141514,110141589] +[["uc001dya.2"],"knownGene","uc001dya.2","chr1",110145889,110155705] +[["uc009wfg.1"],"knownGene","uc009wfg.1","chr1",110162125,110173028] +[["uc001dyb.1"],"knownGene","uc001dyb.1","chr1",110162458,110174677] +[["uc009wfh.1"],"knownGene","uc009wfh.1","chr1",110162458,110174677] +[["uc001dyc.1"],"knownGene","uc001dyc.1","chr1",110163275,110174677] +[["uc010ovr.1"],"knownGene","uc010ovr.1","chr1",110163535,110174677] +[["uc010ovs.1"],"knownGene","uc010ovs.1","chr1",110166653,110171117] +[["uc001dyd.1"],"knownGene","uc001dyd.1","chr1",110168048,110174677] +[["uc001dye.1"],"knownGene","uc001dye.1","chr1",110171948,110174677] +[["uc001dyi.2"],"knownGene","uc001dyi.2","chr1",110198697,110217907] +[["uc001dyh.2"],"knownGene","uc001dyh.2","chr1",110198697,110208123] +[["uc001dyf.2"],"knownGene","uc001dyf.2","chr1",110198697,110204330] +[["uc001dyg.2"],"knownGene","uc001dyg.2","chr1",110198697,110204330] +[["uc009wfj.2"],"knownGene","uc009wfj.2","chr1",110198697,110204330] +[["uc009wfi.2"],"knownGene","uc009wfi.2","chr1",110198697,110199958] +[["uc010ovt.1"],"knownGene","uc010ovt.1","chr1",110210643,110226618] +[["uc009wfk.2"],"knownGene","uc009wfk.2","chr1",110210643,110226618] +[["uc001dyj.2"],"knownGene","uc001dyj.2","chr1",110210643,110217907] +[["uc001dyk.2"],"knownGene","uc001dyk.2","chr1",110230417,110236366] +[["uc001dyl.2"],"knownGene","uc001dyl.2","chr1",110230417,110236366] +[["uc001dyn.2"],"knownGene","uc001dyn.2","chr1",110254863,110260888] +[["uc010ovu.1"],"knownGene","uc010ovu.1","chr1",110254863,110260883] +[["uc001dyo.2"],"knownGene","uc001dyo.2","chr1",110276553,110283660] +[["uc001dyp.2"],"knownGene","uc001dyp.2","chr1",110276553,110283660] +[["uc010ovv.1"],"knownGene","uc010ovv.1","chr1",110280037,110283133] +[["uc001dys.1"],"knownGene","uc001dys.1","chr1",110292701,110306564] +[["uc001dyq.1"],"knownGene","uc001dyq.1","chr1",110292701,110306564] +[["uc001dyr.1"],"knownGene","uc001dyr.1","chr1",110292701,110306564] +[["uc009wfm.1"],"knownGene","uc009wfm.1","chr1",110292701,110306564] +[["uc009wfn.1"],"knownGene","uc009wfn.1","chr1",110294154,110306564] +[["uc009wfo.1"],"knownGene","uc009wfo.1","chr1",110295307,110306564] +[["uc001dyv.3"],"knownGene","uc001dyv.3","chr1",110453232,110472354] +[["uc001dyw.3"],"knownGene","uc001dyw.3","chr1",110453232,110472354] +[["uc001dyu.2"],"knownGene","uc001dyu.2","chr1",110453232,110469365] +[["uc001dyt.2"],"knownGene","uc001dyt.2","chr1",110453232,110467824] +[["uc001dyx.2"],"knownGene","uc001dyx.2","chr1",110527307,110566363] +[["uc010ovw.1"],"knownGene","uc010ovw.1","chr1",110528109,110566363] +[["uc001dyy.2"],"knownGene","uc001dyy.2","chr1",110546752,110566363] +[["uc010ovx.1"],"knownGene","uc010ovx.1","chr1",110546754,110566363] +[["uc001dyz.1"],"knownGene","uc001dyz.1","chr1",110574198,110597424] +[["uc001dza.1"],"knownGene","uc001dza.1","chr1",110577240,110597424] +[["uc009wfp.1"],"knownGene","uc009wfp.1","chr1",110577240,110597424] +[["uc001dzb.2"],"knownGene","uc001dzb.2","chr1",110602997,110613322] +[["uc001dzc.2"],"knownGene","uc001dzc.2","chr1",110655061,110656568] +[["uc009wfq.2"],"knownGene","uc009wfq.2","chr1",110693131,110744821] +[["uc001dze.1"],"knownGene","uc001dze.1","chr1",110735127,110737566] +[["uc001dzg.2"],"knownGene","uc001dzg.2","chr1",110754064,110776665] +[["uc001dzh.2"],"knownGene","uc001dzh.2","chr1",110754064,110776665] +[["uc001dzi.2"],"knownGene","uc001dzi.2","chr1",110754064,110776665] +[["uc009wfr.2"],"knownGene","uc009wfr.2","chr1",110754064,110769165] +[["uc001dzf.2"],"knownGene","uc001dzf.2","chr1",110754064,110766704] +[["uc001dzj.2"],"knownGene","uc001dzj.2","chr1",110829000,110881793] +[["uc001dzl.1"],"knownGene","uc001dzl.1","chr1",110881944,110889303] +[["uc001dzm.1"],"knownGene","uc001dzm.1","chr1",110881944,110889303] +[["uc001dzn.1"],"knownGene","uc001dzn.1","chr1",110887099,110888734] +[["uc001dzo.1"],"knownGene","uc001dzo.1","chr1",110905504,110933636] +[["uc009wfs.1"],"knownGene","uc009wfs.1","chr1",110905504,110933636] +[["uc001dzp.1"],"knownGene","uc001dzp.1","chr1",110905504,110933636] +[["uc010ovy.1"],"knownGene","uc010ovy.1","chr1",110905504,110933636] +[["uc001dzq.1"],"knownGene","uc001dzq.1","chr1",110905504,110933636] +[["uc010ovz.1"],"knownGene","uc010ovz.1","chr1",110906247,110933636] +[["uc001dzr.2"],"knownGene","uc001dzr.2","chr1",110943878,110950546] +[["uc001dzs.2"],"knownGene","uc001dzs.2","chr1",110993787,110999974] +[["uc009wft.1"],"knownGene","uc009wft.1","chr1",111016377,111031285] +[["uc009wfu.1"],"knownGene","uc009wfu.1","chr1",111023387,111033891] +[["uc001dzt.1"],"knownGene","uc001dzt.1","chr1",111059838,111061797] +[["uc009wfv.1"],"knownGene","uc009wfv.1","chr1",111136202,111174096] +[["uc009wfw.2"],"knownGene","uc009wfw.2","chr1",111145776,111148975] +[["uc001dzu.2"],"knownGene","uc001dzu.2","chr1",111145776,111148344] +[["uc001dzv.1"],"knownGene","uc001dzv.1","chr1",111214309,111217655] +[["uc001dzw.2"],"knownGene","uc001dzw.2","chr1",111413820,111442557] +[["uc001dzx.2"],"knownGene","uc001dzx.2","chr1",111415721,111442557] +[["uc010owa.1"],"knownGene","uc010owa.1","chr1",111415777,111442557] +[["uc001dzy.2"],"knownGene","uc001dzy.2","chr1",111415777,111442557] +[["uc001eaa.2"],"knownGene","uc001eaa.2","chr1",111489812,111506566] +[["uc001eab.2"],"knownGene","uc001eab.2","chr1",111489812,111506566] +[["uc001dzz.2"],"knownGene","uc001dzz.2","chr1",111489812,111495583] +[["uc001eac.1"],"knownGene","uc001eac.1","chr1",111489844,111506566] +[["uc001ead.3"],"knownGene","uc001ead.3","chr1",111659954,111682838] +[["uc001eae.3"],"knownGene","uc001eae.3","chr1",111659954,111682838] +[["uc009wfy.2"],"knownGene","uc009wfy.2","chr1",111659954,111682838] +[["uc001eaf.3"],"knownGene","uc001eaf.3","chr1",111659954,111682838] +[["uc001eah.1"],"knownGene","uc001eah.1","chr1",111682248,111727724] +[["uc001eag.2"],"knownGene","uc001eag.2","chr1",111682248,111703575] +[["uc001eai.1"],"knownGene","uc001eai.1","chr1",111682832,111727724] +[["uc001eaj.1"],"knownGene","uc001eaj.1","chr1",111682832,111727724] +[["uc009wfz.1"],"knownGene","uc009wfz.1","chr1",111717500,111727724] +[["uc001eal.1"],"knownGene","uc001eal.1","chr1",111729800,111747031] +[["uc001eak.1"],"knownGene","uc001eak.1","chr1",111729800,111743281] +[["uc001eam.2"],"knownGene","uc001eam.2","chr1",111770280,111786060] +[["uc001ean.2"],"knownGene","uc001ean.2","chr1",111770280,111786060] +[["uc001eao.2"],"knownGene","uc001eao.2","chr1",111772332,111786060] +[["uc009wga.2"],"knownGene","uc009wga.2","chr1",111772332,111786060] +[["uc009wgb.2"],"knownGene","uc009wgb.2","chr1",111823145,111828729] +[["uc001eas.2"],"knownGene","uc001eas.2","chr1",111833483,111863184] +[["uc001ear.2"],"knownGene","uc001ear.2","chr1",111833483,111863184] +[["uc001eaq.2"],"knownGene","uc001eaq.2","chr1",111833483,111863184] +[["uc009wgc.2"],"knownGene","uc009wgc.2","chr1",111833483,111863184] +[["uc001eat.2"],"knownGene","uc001eat.2","chr1",111833483,111863184] +[["uc001eav.2"],"knownGene","uc001eav.2","chr1",111853021,111863184] +[["uc001eau.2"],"knownGene","uc001eau.2","chr1",111853021,111863184] +[["uc009wgd.2"],"knownGene","uc009wgd.2","chr1",111853021,111863184] +[["uc001eaw.2"],"knownGene","uc001eaw.2","chr1",111889194,111895639] +[["uc001eax.2"],"knownGene","uc001eax.2","chr1",111889194,111895639] +[["uc009wge.1"],"knownGene","uc009wge.1","chr1",111889194,111895639] +[["uc001eay.2"],"knownGene","uc001eay.2","chr1",111890962,111895639] +[["uc001eba.2"],"knownGene","uc001eba.2","chr1",111956937,111970399] +[["uc010owb.1"],"knownGene","uc010owb.1","chr1",111956937,111970134] +[["uc001eaz.2"],"knownGene","uc001eaz.2","chr1",111956937,111969690] +[["uc010owc.1"],"knownGene","uc010owc.1","chr1",111966164,111970399] +[["uc001ebb.2"],"knownGene","uc001ebb.2","chr1",111982512,111991830] +[["uc010owd.1"],"knownGene","uc010owd.1","chr1",111982512,111991830] +[["uc010owe.1"],"knownGene","uc010owe.1","chr1",111982512,111991830] +[["uc009wgf.1"],"knownGene","uc009wgf.1","chr1",111991461,112002258] +[["uc001ebc.2"],"knownGene","uc001ebc.2","chr1",111991742,112004523] +[["uc001ebd.3"],"knownGene","uc001ebd.3","chr1",111991816,112004523] +[["uc001ebe.2"],"knownGene","uc001ebe.2","chr1",112016603,112021133] +[["uc001ebg.3"],"knownGene","uc001ebg.3","chr1",112025970,112106597] +[["uc001ebf.2"],"knownGene","uc001ebf.2","chr1",112025970,112046743] +[["uc001ebh.3"],"knownGene","uc001ebh.3","chr1",112042052,112046743] +[["uc001ebi.2"],"knownGene","uc001ebi.2","chr1",112085054,112256100] +[["uc001ebj.1"],"knownGene","uc001ebj.1","chr1",112141628,112150946] +[["uc001ebk.2"],"knownGene","uc001ebk.2","chr1",112162404,112256100] +[["uc001ebl.2"],"knownGene","uc001ebl.2","chr1",112162404,112256100] +[["uc001ebm.2"],"knownGene","uc001ebm.2","chr1",112170091,112256100] +[["uc001ebn.1"],"knownGene","uc001ebn.1","chr1",112256829,112259310] +[["uc001ebp.1"],"knownGene","uc001ebp.1","chr1",112268369,112298419] +[["uc001ebo.1"],"knownGene","uc001ebo.1","chr1",112268369,112282022] +[["uc001ebq.1"],"knownGene","uc001ebq.1","chr1",112282462,112290420] +[["uc001ebr.2"],"knownGene","uc001ebr.2","chr1",112287938,112298131] +[["uc001ebs.2"],"knownGene","uc001ebs.2","chr1",112298189,112310198] +[["uc010owf.1"],"knownGene","uc010owf.1","chr1",112298189,112310198] +[["uc001ebt.2"],"knownGene","uc001ebt.2","chr1",112303018,112310198] +[["uc001ebu.1"],"knownGene","uc001ebu.1","chr1",112318453,112531777] +[["uc001ebv.1"],"knownGene","uc001ebv.1","chr1",112318453,112531777] +[["uc001ebw.2"],"knownGene","uc001ebw.2","chr1",112533157,112541461] +[["uc001ebx.2"],"knownGene","uc001ebx.2","chr1",112938799,113003785] +[["uc001eby.1"],"knownGene","uc001eby.1","chr1",112938880,112941439] +[["uc001ebz.2"],"knownGene","uc001ebz.2","chr1",112999439,113006063] +[["uc001eca.2"],"knownGene","uc001eca.2","chr1",113010039,113063908] +[["uc009wgg.2"],"knownGene","uc009wgg.2","chr1",113010039,113063908] +[["uc001ecb.2"],"knownGene","uc001ecb.2","chr1",113051369,113063908] +[["uc001ecg.2"],"knownGene","uc001ecg.2","chr1",113066141,113162405] +[["uc001ecd.2"],"knownGene","uc001ecd.2","chr1",113066141,113162040] +[["uc001ece.2"],"knownGene","uc001ece.2","chr1",113066141,113162040] +[["uc001ecf.2"],"knownGene","uc001ecf.2","chr1",113066141,113162040] +[["uc010owg.1"],"knownGene","uc010owg.1","chr1",113066141,113161761] +[["uc010owh.1"],"knownGene","uc010owh.1","chr1",113066141,113161761] +[["uc001ecc.2"],"knownGene","uc001ecc.2","chr1",113066141,113161550] +[["uc009wgh.2"],"knownGene","uc009wgh.2","chr1",113066141,113153625] +[["uc001eci.2"],"knownGene","uc001eci.2","chr1",113084416,113162040] +[["uc001ech.2"],"knownGene","uc001ech.2","chr1",113084416,113161761] +[["uc010owi.1"],"knownGene","uc010owi.1","chr1",113084416,113160839] +[["uc009wgi.1"],"knownGene","uc009wgi.1","chr1",113084572,113161761] +[["uc010owj.1"],"knownGene","uc010owj.1","chr1",113093222,113161761] +[["uc001ecj.1"],"knownGene","uc001ecj.1","chr1",113162074,113214241] +[["uc001eck.2"],"knownGene","uc001eck.2","chr1",113217047,113243367] +[["uc001ecn.2"],"knownGene","uc001ecn.2","chr1",113217047,113243367] +[["uc001ecm.2"],"knownGene","uc001ecm.2","chr1",113217047,113243367] +[["uc001ecl.2"],"knownGene","uc001ecl.2","chr1",113217047,113243357] +[["uc009wgj.1"],"knownGene","uc009wgj.1","chr1",113217469,113239156] +[["uc001ecq.1"],"knownGene","uc001ecq.1","chr1",113243748,113250025] +[["uc001ecr.1"],"knownGene","uc001ecr.1","chr1",113243748,113250025] +[["uc009wgk.1"],"knownGene","uc009wgk.1","chr1",113243748,113250025] +[["uc001ecp.1"],"knownGene","uc001ecp.1","chr1",113243748,113249678] +[["uc001ect.1"],"knownGene","uc001ect.1","chr1",113252615,113257950] +[["uc001ecs.1"],"knownGene","uc001ecs.1","chr1",113252615,113257913] +[["uc009wgl.1"],"knownGene","uc009wgl.1","chr1",113252615,113255079] +[["uc001ecu.2"],"knownGene","uc001ecu.2","chr1",113263188,113269854] +[["uc001ecv.2"],"knownGene","uc001ecv.2","chr1",113263188,113269854] +[["uc010owk.1"],"knownGene","uc010owk.1","chr1",113263188,113269854] +[["uc010owl.1"],"knownGene","uc010owl.1","chr1",113263188,113269854] +[["uc001ecw.1"],"knownGene","uc001ecw.1","chr1",113362795,113393265] +[["uc001ecy.2"],"knownGene","uc001ecy.2","chr1",113454471,113498975] +[["uc001ecx.2"],"knownGene","uc001ecx.2","chr1",113454471,113498685] +[["uc001ecz.2"],"knownGene","uc001ecz.2","chr1",113458817,113498685] +[["uc001eda.1"],"knownGene","uc001eda.1","chr1",113465971,113467295] +[["uc001edc.1"],"knownGene","uc001edc.1","chr1",113499036,113542118] +[["uc001edb.2"],"knownGene","uc001edb.2","chr1",113499036,113506688] +[["uc001edd.2"],"knownGene","uc001edd.2","chr1",113499070,113511596] +[["uc001ede.1"],"knownGene","uc001ede.1","chr1",113554308,113615724] +[["uc001edf.1"],"knownGene","uc001edf.1","chr1",113615830,113667342] +[["uc009wgn.1"],"knownGene","uc009wgn.1","chr1",113615830,113667342] +[["uc001edg.1"],"knownGene","uc001edg.1","chr1",113739503,113748875] +[["uc001edk.2"],"knownGene","uc001edk.2","chr1",113933474,114228535] +[["uc001edi.3"],"knownGene","uc001edi.3","chr1",113933474,114228535] +[["uc010owm.1"],"knownGene","uc010owm.1","chr1",113933474,114228535] +[["uc001edh.3"],"knownGene","uc001edh.3","chr1",113933474,114224924] +[["uc001edj.2"],"knownGene","uc001edj.2","chr1",114133105,114228535] +[["uc009wgo.2"],"knownGene","uc009wgo.2","chr1",114223532,114228535] +[["uc009wgp.1"],"knownGene","uc009wgp.1","chr1",114239823,114301777] +[["uc001edm.2"],"knownGene","uc001edm.2","chr1",114239823,114257834] +[["uc001edn.2"],"knownGene","uc001edn.2","chr1",114246448,114302098] +[["uc001edo.1"],"knownGene","uc001edo.1","chr1",114248388,114256060] +[["uc010own.1"],"knownGene","uc010own.1","chr1",114255891,114301355] +[["uc001edp.2"],"knownGene","uc001edp.2","chr1",114267957,114302098] +[["uc001edq.2"],"knownGene","uc001edq.2","chr1",114304454,114355070] +[["uc001edr.2"],"knownGene","uc001edr.2","chr1",114304454,114355070] +[["uc001eds.2"],"knownGene","uc001eds.2","chr1",114356439,114414375] +[["uc009wgq.2"],"knownGene","uc009wgq.2","chr1",114356439,114414375] +[["uc010owo.1"],"knownGene","uc010owo.1","chr1",114356439,114414375] +[["uc001edt.2"],"knownGene","uc001edt.2","chr1",114356439,114414375] +[["uc009wgr.2"],"knownGene","uc009wgr.2","chr1",114361920,114414375] +[["uc009wgs.2"],"knownGene","uc009wgs.2","chr1",114361920,114414375] +[["uc001edu.2"],"knownGene","uc001edu.2","chr1",114375568,114414375] +[["uc001edv.1"],"knownGene","uc001edv.1","chr1",114399256,114443859] +[["uc001edw.2"],"knownGene","uc001edw.2","chr1",114419436,114430169] +[["uc001edx.2"],"knownGene","uc001edx.2","chr1",114419436,114430169] +[["uc001edy.2"],"knownGene","uc001edy.2","chr1",114419436,114430169] +[["uc001edz.1"],"knownGene","uc001edz.1","chr1",114424394,114430169] +[["uc001eed.2"],"knownGene","uc001eed.2","chr1",114437676,114447741] +[["uc010owp.1"],"knownGene","uc010owp.1","chr1",114437676,114447741] +[["uc001eeb.2"],"knownGene","uc001eeb.2","chr1",114437676,114447482] +[["uc001eec.2"],"knownGene","uc001eec.2","chr1",114437676,114447482] +[["uc001eea.1"],"knownGene","uc001eea.1","chr1",114437677,114443022] +[["uc001eee.1"],"knownGene","uc001eee.1","chr1",114437681,114439764] +[["uc010owq.1"],"knownGene","uc010owq.1","chr1",114442030,114447482] +[["uc001eeg.2"],"knownGene","uc001eeg.2","chr1",114448037,114456692] +[["uc001eeh.2"],"knownGene","uc001eeh.2","chr1",114448037,114456692] +[["uc001eei.2"],"knownGene","uc001eei.2","chr1",114448037,114456692] +[["uc001eek.2"],"knownGene","uc001eek.2","chr1",114466623,114471880] +[["uc001eej.2"],"knownGene","uc001eej.2","chr1",114466623,114471854] +[["uc001eem.2"],"knownGene","uc001eem.2","chr1",114471995,114520421] +[["uc001eel.2"],"knownGene","uc001eel.2","chr1",114471995,114514693] +[["uc001een.2"],"knownGene","uc001een.2","chr1",114472438,114520421] +[["uc001eeo.2"],"knownGene","uc001eeo.2","chr1",114493766,114520421] +[["uc001eep.2"],"knownGene","uc001eep.2","chr1",114496498,114520421] +[["uc001eeq.2"],"knownGene","uc001eeq.2","chr1",114506008,114520421] +[["uc001eet.1"],"knownGene","uc001eet.1","chr1",114522029,114524876] +[["uc001eer.1"],"knownGene","uc001eer.1","chr1",114522029,114524875] +[["uc001ees.1"],"knownGene","uc001ees.1","chr1",114522029,114524875] +[["uc001eev.2"],"knownGene","uc001eev.2","chr1",114631914,114696472] +[["uc001eeu.2"],"knownGene","uc001eeu.2","chr1",114631914,114641887] +[["uc001eew.2"],"knownGene","uc001eew.2","chr1",114935400,115053781] +[["uc001eex.2"],"knownGene","uc001eex.2","chr1",114935400,115053781] +[["uc010ows.1"],"knownGene","uc010ows.1","chr1",114935400,115006178] +[["uc010owr.1"],"knownGene","uc010owr.1","chr1",114935400,114970516] +[["uc001eey.1"],"knownGene","uc001eey.1","chr1",114946947,114949722] +[["uc001eez.2"],"knownGene","uc001eez.2","chr1",115064017,115213044] +[["uc001efa.2"],"knownGene","uc001efa.2","chr1",115110182,115124265] +[["uc001efc.1"],"knownGene","uc001efc.1","chr1",115127195,115212732] +[["uc001efd.1"],"knownGene","uc001efd.1","chr1",115127195,115212732] +[["uc001efe.1"],"knownGene","uc001efe.1","chr1",115215721,115238176] +[["uc001eff.1"],"knownGene","uc001eff.1","chr1",115215721,115238176] +[["uc009wgu.2"],"knownGene","uc009wgu.2","chr1",115247078,115259515] +[["uc001efh.3"],"knownGene","uc001efh.3","chr1",115247078,115252391] +[["uc001efk.2"],"knownGene","uc001efk.2","chr1",115259537,115300671] +[["uc001efm.2"],"knownGene","uc001efm.2","chr1",115259537,115300671] +[["uc001efl.2"],"knownGene","uc001efl.2","chr1",115259537,115300671] +[["uc009wgv.2"],"knownGene","uc009wgv.2","chr1",115259537,115300671] +[["uc001efn.2"],"knownGene","uc001efn.2","chr1",115259537,115300671] +[["uc001efi.2"],"knownGene","uc001efi.2","chr1",115259537,115292828] +[["uc001efj.2"],"knownGene","uc001efj.2","chr1",115259537,115292828] +[["uc001efp.3"],"knownGene","uc001efp.3","chr1",115312106,115323308] +[["uc001efo.3"],"knownGene","uc001efo.3","chr1",115312106,115323308] +[["uc001efr.2"],"knownGene","uc001efr.2","chr1",115397454,115537988] +[["uc010owt.1"],"knownGene","uc010owt.1","chr1",115397454,115537988] +[["uc001efq.2"],"knownGene","uc001efq.2","chr1",115397454,115537988] +[["uc009wgw.2"],"knownGene","uc009wgw.2","chr1",115397454,115537988] +[["uc001efs.1"],"knownGene","uc001efs.1","chr1",115572414,115576941] +[["uc001eft.2"],"knownGene","uc001eft.2","chr1",115590634,115632115] +[["uc001efu.1"],"knownGene","uc001efu.1","chr1",115828536,115880857] +[["uc001efv.1"],"knownGene","uc001efv.1","chr1",116184573,116240845] +[["uc009wgy.1"],"knownGene","uc009wgy.1","chr1",116184573,116240845] +[["uc001efw.1"],"knownGene","uc001efw.1","chr1",116193897,116207386] +[["uc001efx.3"],"knownGene","uc001efx.3","chr1",116242627,116311426] +[["uc010owu.1"],"knownGene","uc010owu.1","chr1",116242627,116311426] +[["uc001efy.2"],"knownGene","uc001efy.2","chr1",116379000,116383747] +[["uc009wgz.2"],"knownGene","uc009wgz.2","chr1",116379000,116383333] +[["uc001efz.2"],"knownGene","uc001efz.2","chr1",116461996,116468528] +[["uc001egb.3"],"knownGene","uc001egb.3","chr1",116519118,116612672] +[["uc001ega.2"],"knownGene","uc001ega.2","chr1",116519118,116574511] +[["uc001egc.1"],"knownGene","uc001egc.1","chr1",116654375,116677861] +[["uc010owv.1"],"knownGene","uc010owv.1","chr1",116915003,116946597] +[["uc001ege.2"],"knownGene","uc001ege.2","chr1",116915794,116947394] +[["uc001egd.2"],"knownGene","uc001egd.2","chr1",116915794,116928766] +[["uc010oww.1"],"knownGene","uc010oww.1","chr1",116916488,116947394] +[["uc010owx.1"],"knownGene","uc010owx.1","chr1",116925991,116947394] +[["uc009whb.2"],"knownGene","uc009whb.2","chr1",116935486,116961244] +[["uc001egg.3"],"knownGene","uc001egg.3","chr1",116941621,116961244] +[["uc001egh.2"],"knownGene","uc001egh.2","chr1",116943469,116947394] +[["uc001egi.3"],"knownGene","uc001egi.3","chr1",116947335,116961244] +[["uc001egj.3"],"knownGene","uc001egj.3","chr1",116947335,116961244] +[["uc001egk.3"],"knownGene","uc001egk.3","chr1",116947335,116961244] +[["uc001egl.1"],"knownGene","uc001egl.1","chr1",117035644,117041834] +[["uc001egm.2"],"knownGene","uc001egm.2","chr1",117057156,117113715] +[["uc001egn.2"],"knownGene","uc001egn.2","chr1",117057156,117113715] +[["uc010owy.1"],"knownGene","uc010owy.1","chr1",117061322,117113715] +[["uc001ego.1"],"knownGene","uc001ego.1","chr1",117061852,117087226] +[["uc001egp.3"],"knownGene","uc001egp.3","chr1",117064424,117113715] +[["uc001egq.1"],"knownGene","uc001egq.1","chr1",117117030,117210314] +[["uc001egr.1"],"knownGene","uc001egr.1","chr1",117117030,117210314] +[["uc001egs.1"],"knownGene","uc001egs.1","chr1",117127160,117150953] +[["uc001egu.3"],"knownGene","uc001egu.3","chr1",117297085,117311850] +[["uc010owz.1"],"knownGene","uc010owz.1","chr1",117297085,117308084] +[["uc010oxa.1"],"knownGene","uc010oxa.1","chr1",117297085,117308084] +[["uc001egv.1"],"knownGene","uc001egv.1","chr1",117452688,117532972] +[["uc010oxc.1"],"knownGene","uc010oxc.1","chr1",117544381,117579173] +[["uc010oxd.1"],"knownGene","uc010oxd.1","chr1",117544381,117579173] +[["uc009whd.2"],"knownGene","uc009whd.2","chr1",117544381,117579166] +[["uc010oxb.1"],"knownGene","uc010oxb.1","chr1",117544381,117578874] +[["uc001egy.2"],"knownGene","uc001egy.2","chr1",117602948,117645489] +[["uc001egx.1"],"knownGene","uc001egx.1","chr1",117602948,117624997] +[["uc001eha.2"],"knownGene","uc001eha.2","chr1",117653676,117664414] +[["uc001egz.2"],"knownGene","uc001egz.2","chr1",117653676,117664411] +[["uc009whe.2"],"knownGene","uc009whe.2","chr1",117653676,117664411] +[["uc001ehb.2"],"knownGene","uc001ehb.2","chr1",117686209,117753549] +[["uc001ehc.2"],"knownGene","uc001ehc.2","chr1",117686209,117753549] +[["uc009whf.1"],"knownGene","uc009whf.1","chr1",117690234,117753549] +[["uc001ehd.1"],"knownGene","uc001ehd.1","chr1",117910084,118068320] +[["uc009whg.1"],"knownGene","uc009whg.1","chr1",117910084,118042176] +[["uc001ehe.2"],"knownGene","uc001ehe.2","chr1",118148603,118171010] +[["uc001ehf.2"],"knownGene","uc001ehf.2","chr1",118406107,118472302] +[["uc001ehg.2"],"knownGene","uc001ehg.2","chr1",118419845,118472302] +[["uc010oxe.1"],"knownGene","uc010oxe.1","chr1",118472371,118503049] +[["uc001ehi.2"],"knownGene","uc001ehi.2","chr1",118472371,118502221] +[["uc001ehh.2"],"knownGene","uc001ehh.2","chr1",118472371,118484470] +[["uc001ehk.2"],"knownGene","uc001ehk.2","chr1",118496287,118727848] +[["uc001ehl.1"],"knownGene","uc001ehl.1","chr1",119425665,119532179] +[["uc009whj.1"],"knownGene","uc009whj.1","chr1",119425665,119441748] +[["uc001ehm.2"],"knownGene","uc001ehm.2","chr1",119573840,119683295] +[["uc001ehn.2"],"knownGene","uc001ehn.2","chr1",119573840,119683295] +[["uc010oxg.1"],"knownGene","uc010oxg.1","chr1",119573840,119683295] +[["uc010oxh.1"],"knownGene","uc010oxh.1","chr1",119573840,119683295] +[["uc010oxf.1"],"knownGene","uc010oxf.1","chr1",119573840,119682973] +[["uc010oxi.1"],"knownGene","uc010oxi.1","chr1",119576164,119682973] +[["uc001ehp.1"],"knownGene","uc001ehp.1","chr1",119683047,119818596] +[["uc009whk.1"],"knownGene","uc009whk.1","chr1",119683047,119726444] +[["uc001eho.1"],"knownGene","uc001eho.1","chr1",119683047,119694031] +[["uc001ehq.1"],"knownGene","uc001ehq.1","chr1",119911401,119936751] +[["uc001ehr.1"],"knownGene","uc001ehr.1","chr1",119911401,119936751] +[["uc001ehs.2"],"knownGene","uc001ehs.2","chr1",119957269,119965649] +[["uc001ehu.2"],"knownGene","uc001ehu.2","chr1",119957772,119989120] +[["uc001eht.2"],"knownGene","uc001eht.2","chr1",119957772,119965649] +[["uc001ehv.1"],"knownGene","uc001ehv.1","chr1",120049825,120057681] +[["uc001ehw.2"],"knownGene","uc001ehw.2","chr1",120049940,120057681] +[["uc001ehx.1"],"knownGene","uc001ehx.1","chr1",120076170,120076936] +[["uc001ehy.1"],"knownGene","uc001ehy.1","chr1",120161999,120190390] +[["uc001ehz.2"],"knownGene","uc001ehz.2","chr1",120254418,120286848] +[["uc009whm.2"],"knownGene","uc009whm.2","chr1",120254418,120286848] +[["uc001eia.2"],"knownGene","uc001eia.2","chr1",120254418,120286848] +[["uc009whn.2"],"knownGene","uc009whn.2","chr1",120254418,120286848] +[["uc009whl.2"],"knownGene","uc009whl.2","chr1",120254418,120277603] +[["uc001eib.2"],"knownGene","uc001eib.2","chr1",120262249,120286848] +[["uc001eic.2"],"knownGene","uc001eic.2","chr1",120285421,120286848] +[["uc001eid.2"],"knownGene","uc001eid.2","chr1",120291004,120311518] +[["uc010oxj.1"],"knownGene","uc010oxj.1","chr1",120291004,120311518] +[["uc001eie.2"],"knownGene","uc001eie.2","chr1",120291025,120307249] +[["uc001eig.2"],"knownGene","uc001eig.2","chr1",120336641,120354203] +[["uc001eif.2"],"knownGene","uc001eif.2","chr1",120336641,120354203] +[["uc001eih.1"],"knownGene","uc001eih.1","chr1",120344945,120354203] +[["uc010oxk.1"],"knownGene","uc010oxk.1","chr1",120377388,120387779] +[["uc001eij.2"],"knownGene","uc001eij.2","chr1",120436156,120439113] +[["uc001eik.2"],"knownGene","uc001eik.2","chr1",120454177,120612276] +[["uc001eil.2"],"knownGene","uc001eil.2","chr1",120477736,120612276] +[["uc001eim.3"],"knownGene","uc001eim.3","chr1",120492743,120612276] +[["uc009whp.2"],"knownGene","uc009whp.2","chr1",120839004,120855680] +[["uc001ein.3"],"knownGene","uc001ein.3","chr1",120839411,120855680] +[["uc001eio.2"],"knownGene","uc001eio.2","chr1",120906033,120914842] +[["uc001eip.2"],"knownGene","uc001eip.2","chr1",120926908,120935944] +[["uc001eiq.2"],"knownGene","uc001eiq.2","chr1",120926908,120935944] +[["uc010oxl.1"],"knownGene","uc010oxl.1","chr1",120926908,120935944] +[["uc009whr.2"],"knownGene","uc009whr.2","chr1",120927646,120935944] +[["uc009whs.2"],"knownGene","uc009whs.2","chr1",120929487,120935944] +[["uc001eis.2"],"knownGene","uc001eis.2","chr1",121107151,121131151] +[["uc001eiu.1"],"knownGene","uc001eiu.1","chr1",121260909,121313686] +[["uc009wht.1"],"knownGene","uc009wht.1","chr1",121306423,121313686] +[["uc001eiw.1"],"knownGene","uc001eiw.1","chr1",142618798,143257763] +[["uc001eix.1"],"knownGene","uc001eix.1","chr1",142620644,142714605] +[["uc001eiy.2"],"knownGene","uc001eiy.2","chr1",142660105,142660135] +[["uc001eiz.1"],"knownGene","uc001eiz.1","chr1",142672191,142672219] +[["uc001ejb.2"],"knownGene","uc001ejb.2","chr1",142803224,142888797] +[["uc001ejc.2"],"knownGene","uc001ejc.2","chr1",142803530,142826641] +[["uc001ejd.1"],"knownGene","uc001ejd.1","chr1",142804898,142890670] +[["uc001eje.2"],"knownGene","uc001eje.2","chr1",142851396,142851424] +[["uc009whu.1"],"knownGene","uc009whu.1","chr1",142853227,142855999] +[["uc001ejf.1"],"knownGene","uc001ejf.1","chr1",143119060,143163748] +[["uc001ejg.1"],"knownGene","uc001ejg.1","chr1",143168647,143168675] +[["uc001ejh.1"],"knownGene","uc001ejh.1","chr1",143184707,143184737] +[["uc001eji.1"],"knownGene","uc001eji.1","chr1",143185662,143185692] +[["uc001ejj.2"],"knownGene","uc001ejj.2","chr1",143185981,143186010] +[["uc001ejk.2"],"knownGene","uc001ejk.2","chr1",143289064,143289092] +[["uc001ejl.1"],"knownGene","uc001ejl.1","chr1",143402283,143402313] +[["uc001ejm.1"],"knownGene","uc001ejm.1","chr1",143402601,143402631] +[["uc002zkn.1"],"knownGene","uc002zkn.1","chr1",143403553,143403583] +[["uc001ejn.1"],"knownGene","uc001ejn.1","chr1",143424332,143467651] +[["uc001ejo.2"],"knownGene","uc001ejo.2","chr1",143431367,143431397] +[["uc001ejp.3"],"knownGene","uc001ejp.3","chr1",143647638,143744587] +[["uc001ejq.2"],"knownGene","uc001ejq.2","chr1",143687145,143714180] +[["uc009whw.1"],"knownGene","uc009whw.1","chr1",143687145,143705973] +[["uc001ejr.3"],"knownGene","uc001ejr.3","chr1",143717588,143744587] +[["uc009whx.2"],"knownGene","uc009whx.2","chr1",143718512,143744587] +[["uc009why.2"],"knownGene","uc009why.2","chr1",143719238,143744587] +[["uc001ejt.2"],"knownGene","uc001ejt.2","chr1",143767145,143767881] +[["uc002qvn.1"],"knownGene","uc002qvn.1","chr1",143896451,143913143] +[["uc010evy.1"],"knownGene","uc010evy.1","chr1",143896451,143913143] +[["uc010oxm.1"],"knownGene","uc010oxm.1","chr1",143915747,144094477] +[["uc001eju.1"],"knownGene","uc001eju.1","chr1",144044034,144044079] +[["uc010oxn.1"],"knownGene","uc010oxn.1","chr1",144146806,144828810] +[["uc010oxo.1"],"knownGene","uc010oxo.1","chr1",144146806,144828810] +[["uc010oxp.1"],"knownGene","uc010oxp.1","chr1",144150981,144172451] +[["uc010oxq.1"],"knownGene","uc010oxq.1","chr1",144151506,144186823] +[["uc010oxr.1"],"knownGene","uc010oxr.1","chr1",144151518,144828810] +[["uc001ejx.1"],"knownGene","uc001ejx.1","chr1",144160410,144191577] +[["uc001ejz.1"],"knownGene","uc001ejz.1","chr1",144162000,144167711] +[["uc010oxs.1"],"knownGene","uc010oxs.1","chr1",144166563,144167711] +[["uc010oxt.1"],"knownGene","uc010oxt.1","chr1",144169908,144828810] +[["uc010oxv.1"],"knownGene","uc010oxv.1","chr1",144174494,144204294] +[["uc010oxu.1"],"knownGene","uc010oxu.1","chr1",144174494,144175642] +[["uc010oxw.1"],"knownGene","uc010oxw.1","chr1",144175658,144212182] +[["uc010oxx.1"],"knownGene","uc010oxx.1","chr1",144179473,144209011] +[["uc010oxy.1"],"knownGene","uc010oxy.1","chr1",144181950,144204294] +[["uc001ekg.1"],"knownGene","uc001ekg.1","chr1",144183587,144828810] +[["uc010oxz.1"],"knownGene","uc010oxz.1","chr1",144184251,144223323] +[["uc001ekk.1"],"knownGene","uc001ekk.1","chr1",144190581,144828810] +[["uc010oya.1"],"knownGene","uc010oya.1","chr1",144190581,144201053] +[["uc010oyb.1"],"knownGene","uc010oyb.1","chr1",144196230,144204294] +[["uc001ekl.1"],"knownGene","uc001ekl.1","chr1",144196230,144201053] +[["uc010oyc.1"],"knownGene","uc010oyc.1","chr1",144199908,144201053] +[["uc009wir.2"],"knownGene","uc009wir.2","chr1",144201704,145334792] +[["uc009wid.2"],"knownGene","uc009wid.2","chr1",144204185,144212182] +[["uc001ekn.2"],"knownGene","uc001ekn.2","chr1",144204185,144209011] +[["uc001ekp.3"],"knownGene","uc001ekp.3","chr1",144212642,144215424] +[["uc010oyd.1"],"knownGene","uc010oyd.1","chr1",144218498,144828810] +[["uc001ekq.1"],"knownGene","uc001ekq.1","chr1",144275887,144290006] +[["uc001eks.2"],"knownGene","uc001eks.2","chr1",144300513,144341755] +[["uc001ekr.3"],"knownGene","uc001ekr.3","chr1",144300513,144340773] +[["uc001ekt.3"],"knownGene","uc001ekt.3","chr1",144300513,144340773] +[["uc001ekv.2"],"knownGene","uc001ekv.2","chr1",144339562,144340773] +[["uc001ekw.2"],"knownGene","uc001ekw.2","chr1",144363463,144364246] +[["uc001ekz.3"],"knownGene","uc001ekz.3","chr1",144480747,144521969] +[["uc001eky.3"],"knownGene","uc001eky.3","chr1",144480747,144520993] +[["uc001ela.3"],"knownGene","uc001ela.3","chr1",144480747,144520993] +[["uc001elb.3"],"knownGene","uc001elb.3","chr1",144514873,144519720] +[["uc009wif.1"],"knownGene","uc009wif.1","chr1",144593695,144615303] +[["uc001elc.2"],"knownGene","uc001elc.2","chr1",144593695,144597732] +[["uc010oye.1"],"knownGene","uc010oye.1","chr1",144594403,145368682] +[["uc001ele.2"],"knownGene","uc001ele.2","chr1",144596310,144604296] +[["uc001elf.3"],"knownGene","uc001elf.3","chr1",144612023,144612727] +[["uc009wig.1"],"knownGene","uc009wig.1","chr1",144614839,144828810] +[["uc010oyf.1"],"knownGene","uc010oyf.1","chr1",144614958,145311154] +[["uc010oyg.1"],"knownGene","uc010oyg.1","chr1",144614958,145311154] +[["uc001eli.3"],"knownGene","uc001eli.3","chr1",144614958,144828810] +[["uc009wii.1"],"knownGene","uc009wii.1","chr1",144615095,144822084] +[["uc001elo.2"],"knownGene","uc001elo.2","chr1",144676872,145076079] +[["uc001elm.3"],"knownGene","uc001elm.3","chr1",144676872,145039944] +[["uc001eln.3"],"knownGene","uc001eln.3","chr1",144676872,145039944] +[["uc001ell.1"],"knownGene","uc001ell.1","chr1",144676872,144995082] +[["uc001elk.1"],"knownGene","uc001elk.1","chr1",144676872,144995022] +[["uc001elp.2"],"knownGene","uc001elp.2","chr1",144811942,144828810] +[["uc001elr.3"],"knownGene","uc001elr.3","chr1",144828972,144830389] +[["uc001els.1"],"knownGene","uc001els.1","chr1",144832199,144833038] +[["uc001elt.1"],"knownGene","uc001elt.1","chr1",144833046,144833912] +[["uc001elu.1"],"knownGene","uc001elu.1","chr1",144833912,144834808] +[["uc001elx.3"],"knownGene","uc001elx.3","chr1",144851427,145039944] +[["uc001elw.3"],"knownGene","uc001elw.3","chr1",144851427,144995022] +[["uc001elv.3"],"knownGene","uc001elv.3","chr1",144851427,144894125] +[["uc001ema.2"],"knownGene","uc001ema.2","chr1",144862711,144868172] +[["uc001emc.1"],"knownGene","uc001emc.1","chr1",144890590,144995022] +[["uc001emd.1"],"knownGene","uc001emd.1","chr1",144890590,144995022] +[["uc001emb.1"],"knownGene","uc001emb.1","chr1",144890590,144932032] +[["uc001eme.1"],"knownGene","uc001eme.1","chr1",144895121,144922047] +[["uc001emf.1"],"knownGene","uc001emf.1","chr1",144902727,144932447] +[["uc001emh.2"],"knownGene","uc001emh.2","chr1",144951760,145076079] +[["uc001emg.1"],"knownGene","uc001emg.1","chr1",144951760,144995022] +[["uc001emi.3"],"knownGene","uc001emi.3","chr1",145004780,145005286] +[["uc001emj.2"],"knownGene","uc001emj.2","chr1",145013718,145018393] +[["uc001emk.2"],"knownGene","uc001emk.2","chr1",145074846,145076079] +[["uc001eml.1"],"knownGene","uc001eml.1","chr1",145096406,145116922] +[["uc001emp.3"],"knownGene","uc001emp.3","chr1",145209110,146424095] +[["uc010oyh.1"],"knownGene","uc010oyh.1","chr1",145209110,145295525] +[["uc001emo.2"],"knownGene","uc001emo.2","chr1",145209110,145291654] +[["uc001emn.3"],"knownGene","uc001emn.3","chr1",145209110,145285911] +[["uc001emm.3"],"knownGene","uc001emm.3","chr1",145209110,145285911] +[["uc001emq.1"],"knownGene","uc001emq.1","chr1",145293232,145311154] +[["uc001end.3"],"knownGene","uc001end.3","chr1",145293370,145368682] +[["uc010oyi.1"],"knownGene","uc010oyi.1","chr1",145302653,145368682] +[["uc010oyk.1"],"knownGene","uc010oyk.1","chr1",145311785,145368682] +[["uc010oyl.1"],"knownGene","uc010oyl.1","chr1",145311785,145368682] +[["uc010oyj.1"],"knownGene","uc010oyj.1","chr1",145311785,145320619] +[["uc010oym.1"],"knownGene","uc010oym.1","chr1",145314903,145344236] +[["uc010oyn.1"],"knownGene","uc010oyn.1","chr1",145318053,145353680] +[["uc010oyo.1"],"knownGene","uc010oyo.1","chr1",145319623,145339512] +[["uc001enc.2"],"knownGene","uc001enc.2","chr1",145322771,145364674] +[["uc010oyp.1"],"knownGene","uc010oyp.1","chr1",145324347,145353680] +[["uc010oyq.1"],"knownGene","uc010oyq.1","chr1",145344127,145364674] +[["uc010oyr.1"],"knownGene","uc010oyr.1","chr1",145346372,145364674] +[["uc001eng.1"],"knownGene","uc001eng.1","chr1",145372087,145373798] +[["uc001enh.1"],"knownGene","uc001enh.1","chr1",145373798,145374694] +[["uc001eni.2"],"knownGene","uc001eni.2","chr1",145413190,145417545] +[["uc001enj.2"],"knownGene","uc001enj.2","chr1",145413190,145417545] +[["uc001enk.2"],"knownGene","uc001enk.2","chr1",145413190,145417545] +[["uc001enl.2"],"knownGene","uc001enl.2","chr1",145413190,145417545] +[["uc001enn.3"],"knownGene","uc001enn.3","chr1",145438461,145442626] +[["uc001enm.1"],"knownGene","uc001enm.1","chr1",145438510,145442592] +[["uc010oys.1"],"knownGene","uc010oys.1","chr1",145439346,145442626] +[["uc001enp.1"],"knownGene","uc001enp.1","chr1",145456235,145470387] +[["uc001enq.1"],"knownGene","uc001enq.1","chr1",145470507,145475647] +[["uc001enr.2"],"knownGene","uc001enr.2","chr1",145477084,145499090] +[["uc009wiu.1"],"knownGene","uc009wiu.1","chr1",145499072,145501636] +[["uc001ent.1"],"knownGene","uc001ent.1","chr1",145507637,145511444] +[["uc001enu.1"],"knownGene","uc001enu.1","chr1",145507637,145511444] +[["uc009wiv.1"],"knownGene","uc009wiv.1","chr1",145509752,145515899] +[["uc010oyt.1"],"knownGene","uc010oyt.1","chr1",145509819,145516076] +[["uc001enw.1"],"knownGene","uc001enw.1","chr1",145510431,145512878] +[["uc001enx.2"],"knownGene","uc001enx.2","chr1",145514195,145515899] +[["uc001eny.1"],"knownGene","uc001eny.1","chr1",145516382,145523731] +[["uc010oyu.1"],"knownGene","uc010oyu.1","chr1",145516599,145523731] +[["uc001eoa.2"],"knownGene","uc001eoa.2","chr1",145524989,145543867] +[["uc010oyv.1"],"knownGene","uc010oyv.1","chr1",145524989,145543867] +[["uc009wiw.2"],"knownGene","uc009wiw.2","chr1",145524989,145543867] +[["uc001enz.1"],"knownGene","uc001enz.1","chr1",145524989,145529319] +[["uc010oyw.1"],"knownGene","uc010oyw.1","chr1",145527927,145543867] +[["uc001eob.1"],"knownGene","uc001eob.1","chr1",145549208,145568526] +[["uc010oyx.1"],"knownGene","uc010oyx.1","chr1",145549208,145563099] +[["uc010oyy.1"],"knownGene","uc010oyy.1","chr1",145575289,145580662] +[["uc001eoc.1"],"knownGene","uc001eoc.1","chr1",145575987,145586546] +[["uc001eod.1"],"knownGene","uc001eod.1","chr1",145580403,145586546] +[["uc001eoe.2"],"knownGene","uc001eoe.2","chr1",145586493,145589435] +[["uc001eof.1"],"knownGene","uc001eof.1","chr1",145588587,145590461] +[["uc001eoh.2"],"knownGene","uc001eoh.2","chr1",145592605,145610884] +[["uc001eoi.2"],"knownGene","uc001eoi.2","chr1",145592605,145610884] +[["uc009wix.2"],"knownGene","uc009wix.2","chr1",145592605,145610884] +[["uc001eog.2"],"knownGene","uc001eog.2","chr1",145592605,145610627] +[["uc001eoj.2"],"knownGene","uc001eoj.2","chr1",145611035,145688774] +[["uc001eok.2"],"knownGene","uc001eok.2","chr1",145611035,145688774] +[["uc009wiy.2"],"knownGene","uc009wiy.2","chr1",145611035,145688774] +[["uc001eol.1"],"knownGene","uc001eol.1","chr1",145695797,145715565] +[["uc001eom.1"],"knownGene","uc001eom.1","chr1",145695932,145715565] +[["uc010oyz.1"],"knownGene","uc010oyz.1","chr1",145698952,145706827] +[["uc001eon.1"],"knownGene","uc001eon.1","chr1",145727725,145764073] +[["uc001eoo.1"],"knownGene","uc001eoo.1","chr1",145727725,145764073] +[["uc010oza.1"],"knownGene","uc010oza.1","chr1",145727725,145764073] +[["uc001eos.2"],"knownGene","uc001eos.2","chr1",145764594,145827103] +[["uc001eot.2"],"knownGene","uc001eot.2","chr1",145764594,145827103] +[["uc010ozc.1"],"knownGene","uc010ozc.1","chr1",145764594,145827103] +[["uc010ozd.1"],"knownGene","uc010ozd.1","chr1",145764594,145827103] +[["uc010ozb.1"],"knownGene","uc010ozb.1","chr1",145764594,145826450] +[["uc001eor.2"],"knownGene","uc001eor.2","chr1",145764594,145812027] +[["uc001eoq.2"],"knownGene","uc001eoq.2","chr1",145764594,145790953] +[["uc001eop.2"],"knownGene","uc001eop.2","chr1",145764594,145788795] +[["uc010oze.1"],"knownGene","uc010oze.1","chr1",145765142,145827103] +[["uc001eou.3"],"knownGene","uc001eou.3","chr1",145883867,145924048] +[["uc009wiz.2"],"knownGene","uc009wiz.2","chr1",145897301,145924048] +[["uc001eov.1"],"knownGene","uc001eov.1","chr1",145924387,145942619] +[["uc010ozf.1"],"knownGene","uc010ozf.1","chr1",145924387,145932040] +[["uc010ozh.1"],"knownGene","uc010ozh.1","chr1",146032542,146082765] +[["uc001epa.2"],"knownGene","uc001epa.2","chr1",146032542,146082765] +[["uc001eoz.2"],"knownGene","uc001eoz.2","chr1",146032542,146082431] +[["uc001eoy.2"],"knownGene","uc001eoy.2","chr1",146032542,146068252] +[["uc010ozg.1"],"knownGene","uc010ozg.1","chr1",146032542,146057734] +[["uc009wjc.2"],"knownGene","uc009wjc.2","chr1",146032542,146057734] +[["uc001eox.2"],"knownGene","uc001eox.2","chr1",146032542,146057622] +[["uc010ozi.1"],"knownGene","uc010ozi.1","chr1",146215990,146221509] +[["uc010ozj.1"],"knownGene","uc010ozj.1","chr1",146231025,146240540] +[["uc010ozk.1"],"knownGene","uc010ozk.1","chr1",146334189,146460430] +[["uc010ozl.1"],"knownGene","uc010ozl.1","chr1",146404588,146467638] +[["uc001epd.2"],"knownGene","uc001epd.2","chr1",146490894,146514599] +[["uc001epe.2"],"knownGene","uc001epe.2","chr1",146626686,146644129] +[["uc010ozm.1"],"knownGene","uc010ozm.1","chr1",146626686,146644129] +[["uc010ozn.1"],"knownGene","uc010ozn.1","chr1",146626686,146644129] +[["uc009wjf.1"],"knownGene","uc009wjf.1","chr1",146633092,146644129] +[["uc001epf.1"],"knownGene","uc001epf.1","chr1",146644349,146646784] +[["uc001epg.1"],"knownGene","uc001epg.1","chr1",146649429,146651528] +[["uc001eph.3"],"knownGene","uc001eph.3","chr1",146655884,146697230] +[["uc001epi.2"],"knownGene","uc001epi.2","chr1",146657837,146697230] +[["uc001epj.2"],"knownGene","uc001epj.2","chr1",146657837,146697230] +[["uc001epk.3"],"knownGene","uc001epk.3","chr1",146680025,146697230] +[["uc001epm.3"],"knownGene","uc001epm.3","chr1",146714290,146767441] +[["uc001epn.3"],"knownGene","uc001epn.3","chr1",146714290,146767441] +[["uc010ozo.1"],"knownGene","uc010ozo.1","chr1",146714290,146767441] +[["uc009wjg.2"],"knownGene","uc009wjg.2","chr1",146714290,146767441] +[["uc009wjh.2"],"knownGene","uc009wjh.2","chr1",146714290,146767441] +[["uc010ozp.1"],"knownGene","uc010ozp.1","chr1",146714290,146767441] +[["uc001epo.3"],"knownGene","uc001epo.3","chr1",146714290,146767441] +[["uc001epp.2"],"knownGene","uc001epp.2","chr1",146730539,146989699] +[["uc009wji.2"],"knownGene","uc009wji.2","chr1",146736038,146767441] +[["uc010ozq.1"],"knownGene","uc010ozq.1","chr1",146736038,146757164] +[["uc001epq.2"],"knownGene","uc001epq.2","chr1",147013181,147098013] +[["uc010ozr.1"],"knownGene","uc010ozr.1","chr1",147083376,147096757] +[["uc001epr.2"],"knownGene","uc001epr.2","chr1",147119167,147142634] +[["uc009wjj.1"],"knownGene","uc009wjj.1","chr1",147121945,147142634] +[["uc001ept.1"],"knownGene","uc001ept.1","chr1",147228331,147245484] +[["uc001eps.1"],"knownGene","uc001eps.1","chr1",147228331,147232714] +[["uc001epu.1"],"knownGene","uc001epu.1","chr1",147374935,147381393] +[["uc001epv.3"],"knownGene","uc001epv.3","chr1",147400505,147465754] +[["uc010ozt.1"],"knownGene","uc010ozt.1","chr1",147400505,147465754] +[["uc010ozu.1"],"knownGene","uc010ozu.1","chr1",147400505,147465754] +[["uc001epw.3"],"knownGene","uc001epw.3","chr1",147400505,147465754] +[["uc010ozs.1"],"knownGene","uc010ozs.1","chr1",147400505,147465025] +[["uc010ozv.1"],"knownGene","uc010ozv.1","chr1",147401128,147465754] +[["uc001epx.3"],"knownGene","uc001epx.3","chr1",147415526,147465754] +[["uc009wjm.2"],"knownGene","uc009wjm.2","chr1",147425566,147465754] +[["uc001epy.3"],"knownGene","uc001epy.3","chr1",147440589,147465754] +[["uc001epz.1"],"knownGene","uc001epz.1","chr1",147466093,147484331] +[["uc010ozw.1"],"knownGene","uc010ozw.1","chr1",147466093,147473747] +[["uc001eqg.2"],"knownGene","uc001eqg.2","chr1",147574323,148346929] +[["uc001eqe.2"],"knownGene","uc001eqe.2","chr1",147574323,148346791] +[["uc001eqf.2"],"knownGene","uc001eqf.2","chr1",147574323,148346791] +[["uc010ozz.1"],"knownGene","uc010ozz.1","chr1",147574323,148005511] +[["uc010ozy.1"],"knownGene","uc010ozy.1","chr1",147574323,147624601] +[["uc001eqd.2"],"knownGene","uc001eqd.2","chr1",147574323,147624601] +[["uc001eqc.2"],"knownGene","uc001eqc.2","chr1",147574323,147624267] +[["uc001eqb.2"],"knownGene","uc001eqb.2","chr1",147574323,147610088] +[["uc010ozx.1"],"knownGene","uc010ozx.1","chr1",147574323,147599571] +[["uc009wjr.2"],"knownGene","uc009wjr.2","chr1",147574323,147599571] +[["uc001eqa.2"],"knownGene","uc001eqa.2","chr1",147574323,147599459] +[["uc001eqh.1"],"knownGene","uc001eqh.1","chr1",147680370,147691166] +[["uc001eqi.1"],"knownGene","uc001eqi.1","chr1",147751385,147763966] +[["uc001eqj.1"],"knownGene","uc001eqj.1","chr1",147751388,147760170] +[["uc001eqk.1"],"knownGene","uc001eqk.1","chr1",147801123,147816764] +[["uc001eql.2"],"knownGene","uc001eql.2","chr1",147835126,147931980] +[["uc010paa.1"],"knownGene","uc010paa.1","chr1",147874654,147893482] +[["uc001eqn.2"],"knownGene","uc001eqn.2","chr1",147905097,147931904] +[["uc009wjx.1"],"knownGene","uc009wjx.1","chr1",147906021,147931980] +[["uc009wjy.1"],"knownGene","uc009wjy.1","chr1",147906747,147931980] +[["uc009wjz.1"],"knownGene","uc009wjz.1","chr1",147907097,147931980] +[["uc009wka.1"],"knownGene","uc009wka.1","chr1",147925824,147930669] +[["uc001eqo.1"],"knownGene","uc001eqo.1","chr1",147930760,148176401] +[["uc001eqp.2"],"knownGene","uc001eqp.2","chr1",147954636,147955419] +[["uc010pac.1"],"knownGene","uc010pac.1","chr1",148003642,148319619] +[["uc010pab.1"],"knownGene","uc010pab.1","chr1",148003642,148257602] +[["uc001eqq.2"],"knownGene","uc001eqq.2","chr1",148003642,148025863] +[["uc001eqx.2"],"knownGene","uc001eqx.2","chr1",148005402,148269609] +[["uc001eqs.1"],"knownGene","uc001eqs.1","chr1",148005402,148023669] +[["uc010pad.1"],"knownGene","uc010pad.1","chr1",148005402,148011788] +[["uc010paf.1"],"knownGene","uc010paf.1","chr1",148011679,148303022] +[["uc010pae.1"],"knownGene","uc010pae.1","chr1",148011679,148271900] +[["uc009wkf.1"],"knownGene","uc009wkf.1","chr1",148017501,148346791] +[["uc010pag.1"],"knownGene","uc010pag.1","chr1",148201753,148202536] +[["uc001erd.3"],"knownGene","uc001erd.3","chr1",148251112,148346929] +[["uc001erc.3"],"knownGene","uc001erc.3","chr1",148251112,148346929] +[["uc010paj.1"],"knownGene","uc010paj.1","chr1",148251112,148346929] +[["uc001erb.2"],"knownGene","uc001erb.2","chr1",148251112,148337532] +[["uc001eqz.2"],"knownGene","uc001eqz.2","chr1",148251112,148288722] +[["uc010pah.1"],"knownGene","uc010pah.1","chr1",148251112,148267126] +[["uc010pai.1"],"knownGene","uc010pai.1","chr1",148251112,148267126] +[["uc010pal.1"],"knownGene","uc010pal.1","chr1",148252729,148301438] +[["uc001erg.1"],"knownGene","uc001erg.1","chr1",148252729,148280742] +[["uc010pak.1"],"knownGene","uc010pak.1","chr1",148252729,148276664] +[["uc001erf.1"],"knownGene","uc001erf.1","chr1",148252729,148274381] +[["uc010pam.1"],"knownGene","uc010pam.1","chr1",148257493,148325254] +[["uc001erh.2"],"knownGene","uc001erh.2","chr1",148257493,148279343] +[["uc001eri.1"],"knownGene","uc001eri.1","chr1",148257493,148267126] +[["uc001erm.1"],"knownGene","uc001erm.1","chr1",148267017,148324367] +[["uc001erl.1"],"knownGene","uc001erl.1","chr1",148267017,148317326] +[["uc010pan.1"],"knownGene","uc010pan.1","chr1",148267017,148271900] +[["uc001erz.2"],"knownGene","uc001erz.2","chr1",148271791,148326848] +[["uc010pao.1"],"knownGene","uc010pao.1","chr1",148276555,148314847] +[["uc010pap.1"],"knownGene","uc010pap.1","chr1",148279746,148295781] +[["uc001erq.1"],"knownGene","uc001erq.1","chr1",148279746,148282340] +[["uc010pau.1"],"knownGene","uc010pau.1","chr1",148282939,148342006] +[["uc010pat.1"],"knownGene","uc010pat.1","chr1",148282939,148335752] +[["uc010pas.1"],"knownGene","uc010pas.1","chr1",148282939,148322078] +[["uc010par.1"],"knownGene","uc010par.1","chr1",148282939,148319619] +[["uc010paq.1"],"knownGene","uc010paq.1","chr1",148282939,148310071] +[["uc001eru.1"],"knownGene","uc001eru.1","chr1",148282939,148285533] +[["uc010pav.1"],"knownGene","uc010pav.1","chr1",148305264,148347506] +[["uc010paw.1"],"knownGene","uc010paw.1","chr1",148305264,148347506] +[["uc001esa.1"],"knownGene","uc001esa.1","chr1",148314738,148336277] +[["uc010pax.1"],"knownGene","uc010pax.1","chr1",148327470,148338469] +[["uc010pay.1"],"knownGene","uc010pay.1","chr1",148556107,148556132] +[["uc001esb.1"],"knownGene","uc001esb.1","chr1",148558268,148593783] +[["uc001esc.2"],"knownGene","uc001esc.2","chr1",148560846,148596267] +[["uc001esd.2"],"knownGene","uc001esd.2","chr1",148574411,148575140] +[["uc010paz.1"],"knownGene","uc010paz.1","chr1",148644010,148644793] +[["uc001ese.2"],"knownGene","uc001ese.2","chr1",148736447,148737176] +[["uc010pba.1"],"knownGene","uc010pba.1","chr1",148739441,148758311] +[["uc009wkt.1"],"knownGene","uc009wkt.1","chr1",148739561,148758311] +[["uc010pbb.1"],"knownGene","uc010pbb.1","chr1",148806014,148806797] +[["uc009wkv.1"],"knownGene","uc009wkv.1","chr1",148876039,148902123] +[["uc010pbc.1"],"knownGene","uc010pbc.1","chr1",148928285,148951595] +[["uc010pbd.1"],"knownGene","uc010pbd.1","chr1",148928285,148951595] +[["uc009wkw.1"],"knownGene","uc009wkw.1","chr1",148930404,148953054] +[["uc010pbe.1"],"knownGene","uc010pbe.1","chr1",149230715,149232553] +[["uc010pbf.1"],"knownGene","uc010pbf.1","chr1",149279475,149291742] +[["uc001esg.3"],"knownGene","uc001esg.3","chr1",149287450,149291742] +[["uc010pbh.1"],"knownGene","uc010pbh.1","chr1",149369293,149378295] +[["uc010pbg.1"],"knownGene","uc010pbg.1","chr1",149369293,149370314] +[["uc009wkz.1"],"knownGene","uc009wkz.1","chr1",149370546,149375252] +[["uc010pbi.1"],"knownGene","uc010pbi.1","chr1",149397113,149399229] +[["uc001esj.2"],"knownGene","uc001esj.2","chr1",149553002,149553785] +[["uc009wlb.1"],"knownGene","uc009wlb.1","chr1",149576160,149576700] +[["uc009wlc.2"],"knownGene","uc009wlc.2","chr1",149576452,149672983] +[["uc009wld.2"],"knownGene","uc009wld.2","chr1",149576452,149672983] +[["uc001esk.3"],"knownGene","uc001esk.3","chr1",149576452,149616784] +[["uc001esl.3"],"knownGene","uc001esl.3","chr1",149576452,149616784] +[["uc009wle.1"],"knownGene","uc009wle.1","chr1",149577754,149582602] +[["uc001eso.1"],"knownGene","uc001eso.1","chr1",149627308,149651107] +[["uc001esn.1"],"knownGene","uc001esn.1","chr1",149627308,149641425] +[["uc010pbj.1"],"knownGene","uc010pbj.1","chr1",149754245,149783928] +[["uc001esp.3"],"knownGene","uc001esp.3","chr1",149754249,149764073] +[["uc009wlg.2"],"knownGene","uc009wlg.2","chr1",149754256,149764073] +[["uc009wlh.1"],"knownGene","uc009wlh.1","chr1",149755502,149760173] +[["uc001esq.1"],"knownGene","uc001esq.1","chr1",149763335,149765367] +[["uc010pbk.1"],"knownGene","uc010pbk.1","chr1",149765021,149783928] +[["uc001esr.2"],"knownGene","uc001esr.2","chr1",149782118,149783928] +[["uc010pbl.1"],"knownGene","uc010pbl.1","chr1",149784827,149785236] +[["uc001ess.2"],"knownGene","uc001ess.2","chr1",149804220,149804615] +[["uc001est.1"],"knownGene","uc001est.1","chr1",149804231,149806194] +[["uc001esu.1"],"knownGene","uc001esu.1","chr1",149804241,149806194] +[["uc001esv.2"],"knownGene","uc001esv.2","chr1",149812259,149812765] +[["uc001esw.2"],"knownGene","uc001esw.2","chr1",149813785,149814318] +[["uc001esx.2"],"knownGene","uc001esx.2","chr1",149822627,149823160] +[["uc001esy.2"],"knownGene","uc001esy.2","chr1",149824180,149824686] +[["uc001eta.1"],"knownGene","uc001eta.1","chr1",149830751,149832714] +[["uc001esz.1"],"knownGene","uc001esz.1","chr1",149830751,149832704] +[["uc001etb.2"],"knownGene","uc001etb.2","chr1",149832330,149832725] +[["uc001etc.2"],"knownGene","uc001etc.2","chr1",149856011,149858232] +[["uc001etd.2"],"knownGene","uc001etd.2","chr1",149858524,149858960] +[["uc001ete.2"],"knownGene","uc001ete.2","chr1",149859019,149859466] +[["uc001etf.2"],"knownGene","uc001etf.2","chr1",149871154,149872347] +[["uc001etg.2"],"knownGene","uc001etg.2","chr1",149874875,149889434] +[["uc009wlk.2"],"knownGene","uc009wlk.2","chr1",149874875,149878523] +[["uc001eth.2"],"knownGene","uc001eth.2","chr1",149877023,149889434] +[["uc001etk.1"],"knownGene","uc001etk.1","chr1",149895210,149900236] +[["uc001etj.1"],"knownGene","uc001etj.1","chr1",149895210,149899962] +[["uc001eti.1"],"knownGene","uc001eti.1","chr1",149895210,149897945] +[["uc009wll.1"],"knownGene","uc009wll.1","chr1",149897437,149899962] +[["uc001etl.3"],"knownGene","uc001etl.3","chr1",149900543,149908791] +[["uc001etm.1"],"knownGene","uc001etm.1","chr1",149900543,149908266] +[["uc010pbm.1"],"knownGene","uc010pbm.1","chr1",149902256,149908278] +[["uc010pbn.1"],"knownGene","uc010pbn.1","chr1",149902683,149907028] +[["uc010pbo.1"],"knownGene","uc010pbo.1","chr1",149907191,149908791] +[["uc001etn.2"],"knownGene","uc001etn.2","chr1",149912232,149982686] +[["uc001eto.2"],"knownGene","uc001eto.2","chr1",149932868,149943179] +[["uc001etp.2"],"knownGene","uc001etp.2","chr1",150039341,150117504] +[["uc010pbq.1"],"knownGene","uc010pbq.1","chr1",150039341,150117504] +[["uc010pbp.1"],"knownGene","uc010pbp.1","chr1",150039341,150082742] +[["uc009wlm.1"],"knownGene","uc009wlm.1","chr1",150039341,150065744] +[["uc010pbs.1"],"knownGene","uc010pbs.1","chr1",150039399,150117504] +[["uc010pbr.1"],"knownGene","uc010pbr.1","chr1",150039399,150054079] +[["uc001etq.2"],"knownGene","uc001etq.2","chr1",150049266,150117504] +[["uc001etr.2"],"knownGene","uc001etr.2","chr1",150121654,150131816] +[["uc001ets.2"],"knownGene","uc001ets.2","chr1",150121654,150131816] +[["uc001ett.2"],"knownGene","uc001ett.2","chr1",150122169,150131816] +[["uc001etu.2"],"knownGene","uc001etu.2","chr1",150127086,150131816] +[["uc001etw.2"],"knownGene","uc001etw.2","chr1",150190717,150208504] +[["uc010pbv.1"],"knownGene","uc010pbv.1","chr1",150190717,150208504] +[["uc010pbu.1"],"knownGene","uc010pbu.1","chr1",150190717,150207026] +[["uc010pbt.1"],"knownGene","uc010pbt.1","chr1",150190717,150199127] +[["uc001etv.3"],"knownGene","uc001etv.3","chr1",150190724,150208504] +[["uc010pbw.1"],"knownGene","uc010pbw.1","chr1",150198939,150208504] +[["uc001etx.2"],"knownGene","uc001etx.2","chr1",150230217,150237476] +[["uc009wln.2"],"knownGene","uc009wln.2","chr1",150230217,150233729] +[["uc001ety.1"],"knownGene","uc001ety.1","chr1",150237798,150241532] +[["uc010pbx.1"],"knownGene","uc010pbx.1","chr1",150237798,150241532] +[["uc001etz.1"],"knownGene","uc001etz.1","chr1",150237798,150241532] +[["uc001eua.1"],"knownGene","uc001eua.1","chr1",150237798,150241532] +[["uc010pby.1"],"knownGene","uc010pby.1","chr1",150237798,150241532] +[["uc001eub.1"],"knownGene","uc001eub.1","chr1",150237798,150241532] +[["uc010pbz.1"],"knownGene","uc010pbz.1","chr1",150237798,150241532] +[["uc001euc.2"],"knownGene","uc001euc.2","chr1",150244772,150253325] +[["uc001eud.2"],"knownGene","uc001eud.2","chr1",150245182,150253325] +[["uc001eue.2"],"knownGene","uc001eue.2","chr1",150245182,150253325] +[["uc001euf.2"],"knownGene","uc001euf.2","chr1",150245201,150253325] +[["uc001eug.2"],"knownGene","uc001eug.2","chr1",150245201,150253325] +[["uc001euh.2"],"knownGene","uc001euh.2","chr1",150254952,150259502] +[["uc001eui.2"],"knownGene","uc001eui.2","chr1",150254952,150259502] +[["uc001euj.2"],"knownGene","uc001euj.2","chr1",150255228,150259502] +[["uc001euk.2"],"knownGene","uc001euk.2","chr1",150266268,150280818] +[["uc001eul.2"],"knownGene","uc001eul.2","chr1",150266268,150280818] +[["uc001eum.3"],"knownGene","uc001eum.3","chr1",150293927,150325703] +[["uc010pca.1"],"knownGene","uc010pca.1","chr1",150293927,150325703] +[["uc010pcb.1"],"knownGene","uc010pcb.1","chr1",150293927,150325703] +[["uc009wlp.2"],"knownGene","uc009wlp.2","chr1",150293927,150318612] +[["uc009wlo.2"],"knownGene","uc009wlo.2","chr1",150293927,150301343] +[["uc009wlq.1"],"knownGene","uc009wlq.1","chr1",150305449,150318612] +[["uc009wlr.2"],"knownGene","uc009wlr.2","chr1",150336989,150449039] +[["uc001eup.3"],"knownGene","uc001eup.3","chr1",150336989,150449039] +[["uc010pcc.1"],"knownGene","uc010pcc.1","chr1",150336989,150446032] +[["uc001euq.2"],"knownGene","uc001euq.2","chr1",150459919,150479747] +[["uc001eur.2"],"knownGene","uc001eur.2","chr1",150459919,150479747] +[["uc009wlt.2"],"knownGene","uc009wlt.2","chr1",150459919,150479747] +[["uc009wls.2"],"knownGene","uc009wls.2","chr1",150459919,150479747] +[["uc010pcd.1"],"knownGene","uc010pcd.1","chr1",150459919,150471769] +[["uc001eus.2"],"knownGene","uc001eus.2","chr1",150480486,150486264] +[["uc001eut.2"],"knownGene","uc001eut.2","chr1",150480486,150486264] +[["uc001euu.2"],"knownGene","uc001euu.2","chr1",150480486,150486264] +[["uc001euv.2"],"knownGene","uc001euv.2","chr1",150480486,150486264] +[["uc009wlu.2"],"knownGene","uc009wlu.2","chr1",150480486,150486264] +[["uc010pce.1"],"knownGene","uc010pce.1","chr1",150480486,150484218] +[["uc010pcf.1"],"knownGene","uc010pcf.1","chr1",150480486,150484218] +[["uc001eux.2"],"knownGene","uc001eux.2","chr1",150521897,150533410] +[["uc001euw.2"],"knownGene","uc001euw.2","chr1",150521897,150531221] +[["uc009wlv.1"],"knownGene","uc009wlv.1","chr1",150521897,150524367] +[["uc009wlw.2"],"knownGene","uc009wlw.2","chr1",150522297,150533410] +[["uc010pcg.1"],"knownGene","uc010pcg.1","chr1",150522297,150533410] +[["uc009wlx.2"],"knownGene","uc009wlx.2","chr1",150530420,150533410] +[["uc001euz.2"],"knownGene","uc001euz.2","chr1",150547036,150552136] +[["uc001eva.2"],"knownGene","uc001eva.2","chr1",150547036,150552136] +[["uc010pch.1"],"knownGene","uc010pch.1","chr1",150547036,150552086] +[["uc001evd.2"],"knownGene","uc001evd.2","chr1",150594603,150602098] +[["uc001eve.2"],"knownGene","uc001eve.2","chr1",150594603,150602098] +[["uc001evb.2"],"knownGene","uc001evb.2","chr1",150594603,150601609] +[["uc001evc.2"],"knownGene","uc001evc.2","chr1",150594603,150601609] +[["uc009wly.2"],"knownGene","uc009wly.2","chr1",150595754,150602098] +[["uc001evg.2"],"knownGene","uc001evg.2","chr1",150595754,150602098] +[["uc001evh.2"],"knownGene","uc001evh.2","chr1",150595754,150602098] +[["uc001evf.2"],"knownGene","uc001evf.2","chr1",150595754,150601609] +[["uc009wlz.1"],"knownGene","uc009wlz.1","chr1",150598117,150602098] +[["uc001evi.2"],"knownGene","uc001evi.2","chr1",150599523,150602098] +[["uc001evj.2"],"knownGene","uc001evj.2","chr1",150618700,150669672] +[["uc010pci.1"],"knownGene","uc010pci.1","chr1",150618700,150669672] +[["uc001evk.1"],"knownGene","uc001evk.1","chr1",150670541,150693352] +[["uc001evl.1"],"knownGene","uc001evl.1","chr1",150670541,150693352] +[["uc001evm.1"],"knownGene","uc001evm.1","chr1",150670541,150693352] +[["uc001evn.2"],"knownGene","uc001evn.2","chr1",150702553,150738305] +[["uc010pcj.1"],"knownGene","uc010pcj.1","chr1",150702553,150738305] +[["uc001evo.1"],"knownGene","uc001evo.1","chr1",150722344,150738305] +[["uc001evp.1"],"knownGene","uc001evp.1","chr1",150768686,150780812] +[["uc001evq.1"],"knownGene","uc001evq.1","chr1",150768686,150780812] +[["uc009wma.1"],"knownGene","uc009wma.1","chr1",150778336,150780812] +[["uc001evr.1"],"knownGene","uc001evr.1","chr1",150782185,150849186] +[["uc001evs.1"],"knownGene","uc001evs.1","chr1",150782185,150849186] +[["uc001evt.1"],"knownGene","uc001evt.1","chr1",150782185,150849186] +[["uc009wmb.1"],"knownGene","uc009wmb.1","chr1",150782185,150849186] +[["uc009wmc.1"],"knownGene","uc009wmc.1","chr1",150782185,150849186] +[["uc009wmd.1"],"knownGene","uc009wmd.1","chr1",150782185,150849186] +[["uc010pck.1"],"knownGene","uc010pck.1","chr1",150782185,150789924] +[["uc009wme.1"],"knownGene","uc009wme.1","chr1",150790395,150849186] +[["uc010pcl.1"],"knownGene","uc010pcl.1","chr1",150795669,150849186] +[["uc001evv.2"],"knownGene","uc001evv.2","chr1",150898814,150937220] +[["uc001evu.2"],"knownGene","uc001evu.2","chr1",150898814,150937220] +[["uc009wmf.2"],"knownGene","uc009wmf.2","chr1",150898814,150923566] +[["uc001evw.3"],"knownGene","uc001evw.3","chr1",150898824,150917794] +[["uc009wmg.1"],"knownGene","uc009wmg.1","chr1",150898956,150936321] +[["uc001evy.2"],"knownGene","uc001evy.2","chr1",150937649,150947440] +[["uc001evz.2"],"knownGene","uc001evz.2","chr1",150937649,150947440] +[["uc009wmh.2"],"knownGene","uc009wmh.2","chr1",150937649,150947440] +[["uc001ewa.2"],"knownGene","uc001ewa.2","chr1",150954498,150968114] +[["uc010pcn.1"],"knownGene","uc010pcn.1","chr1",150969301,150980854] +[["uc001ewg.2"],"knownGene","uc001ewg.2","chr1",150969301,150980854] +[["uc001ewf.2"],"knownGene","uc001ewf.2","chr1",150969301,150980225] +[["uc001ewd.2"],"knownGene","uc001ewd.2","chr1",150969301,150980095] +[["uc001ewe.2"],"knownGene","uc001ewe.2","chr1",150969301,150980095] +[["uc001ewc.2"],"knownGene","uc001ewc.2","chr1",150969301,150979273] +[["uc010pcm.1"],"knownGene","uc010pcm.1","chr1",150969301,150979273] +[["uc001ewh.1"],"knownGene","uc001ewh.1","chr1",150980972,151008189] +[["uc001ewi.1"],"knownGene","uc001ewi.1","chr1",150980972,151008189] +[["uc010pco.1"],"knownGene","uc010pco.1","chr1",150980972,151008189] +[["uc001ewj.1"],"knownGene","uc001ewj.1","chr1",150980972,151008189] +[["uc001ewk.1"],"knownGene","uc001ewk.1","chr1",150997086,151008189] +[["uc009wmi.2"],"knownGene","uc009wmi.2","chr1",151009028,151020076] +[["uc001ewl.2"],"knownGene","uc001ewl.2","chr1",151009028,151020076] +[["uc009wmj.2"],"knownGene","uc009wmj.2","chr1",151011271,151020076] +[["uc001ewn.2"],"knownGene","uc001ewn.2","chr1",151020258,151023869] +[["uc001ewo.2"],"knownGene","uc001ewo.2","chr1",151023448,151032125] +[["uc001ewp.2"],"knownGene","uc001ewp.2","chr1",151023448,151032125] +[["uc001ewq.2"],"knownGene","uc001ewq.2","chr1",151032150,151040972] +[["uc001ewr.2"],"knownGene","uc001ewr.2","chr1",151043079,151091007] +[["uc001ews.2"],"knownGene","uc001ews.2","chr1",151043079,151091007] +[["uc010pcp.1"],"knownGene","uc010pcp.1","chr1",151043079,151076151] +[["uc001ewt.2"],"knownGene","uc001ewt.2","chr1",151065667,151091007] +[["uc001ewu.2"],"knownGene","uc001ewu.2","chr1",151104164,151119104] +[["uc001ewv.2"],"knownGene","uc001ewv.2","chr1",151104164,151119104] +[["uc001eww.2"],"knownGene","uc001eww.2","chr1",151104164,151119104] +[["uc010pcq.1"],"knownGene","uc010pcq.1","chr1",151104446,151119104] +[["uc009wml.1"],"knownGene","uc009wml.1","chr1",151109332,151119104] +[["uc001ewx.2"],"knownGene","uc001ewx.2","chr1",151129104,151132225] +[["uc010pcr.1"],"knownGene","uc010pcr.1","chr1",151132224,151138424] +[["uc001ewy.2"],"knownGene","uc001ewy.2","chr1",151132224,151138370] +[["uc001ewz.2"],"knownGene","uc001ewz.2","chr1",151138516,151141612] +[["uc009wmn.2"],"knownGene","uc009wmn.2","chr1",151138516,151141612] +[["uc010pcs.1"],"knownGene","uc010pcs.1","chr1",151138516,151140384] +[["uc001exc.3"],"knownGene","uc001exc.3","chr1",151142463,151148547] +[["uc010pct.1"],"knownGene","uc010pct.1","chr1",151142463,151148547] +[["uc001exd.2"],"knownGene","uc001exd.2","chr1",151142463,151148457] +[["uc001exb.2"],"knownGene","uc001exb.2","chr1",151142463,151144833] +[["uc001exe.1"],"knownGene","uc001exe.1","chr1",151148933,151162640] +[["uc001exf.1"],"knownGene","uc001exf.1","chr1",151149827,151162640] +[["uc001exj.2"],"knownGene","uc001exj.2","chr1",151171020,151222006] +[["uc001exi.2"],"knownGene","uc001exi.2","chr1",151171020,151222006] +[["uc010pcu.1"],"knownGene","uc010pcu.1","chr1",151171020,151222006] +[["uc001exk.2"],"knownGene","uc001exk.2","chr1",151171020,151222006] +[["uc010pcv.1"],"knownGene","uc010pcv.1","chr1",151206672,151222006] +[["uc001exl.2"],"knownGene","uc001exl.2","chr1",151227196,151239952] +[["uc001exn.2"],"knownGene","uc001exn.2","chr1",151227196,151239952] +[["uc001exo.2"],"knownGene","uc001exo.2","chr1",151252502,151254405] +[["uc001exp.1"],"knownGene","uc001exp.1","chr1",151254093,151260882] +[["uc001exq.2"],"knownGene","uc001exq.2","chr1",151254790,151264380] +[["uc009wmo.2"],"knownGene","uc009wmo.2","chr1",151254790,151264380] +[["uc009wmp.2"],"knownGene","uc009wmp.2","chr1",151258750,151264380] +[["uc001ext.2"],"knownGene","uc001ext.2","chr1",151264412,151300133] +[["uc001exu.2"],"knownGene","uc001exu.2","chr1",151264412,151300133] +[["uc010pcw.1"],"knownGene","uc010pcw.1","chr1",151264412,151300133] +[["uc001exr.2"],"knownGene","uc001exr.2","chr1",151264412,151298849] +[["uc001exs.2"],"knownGene","uc001exs.2","chr1",151264412,151298849] +[["uc009wmq.1"],"knownGene","uc009wmq.1","chr1",151288048,151300133] +[["uc001exv.1"],"knownGene","uc001exv.1","chr1",151313115,151319769] +[["uc001exw.1"],"knownGene","uc001exw.1","chr1",151313115,151319769] +[["uc009wmr.1"],"knownGene","uc009wmr.1","chr1",151313115,151319769] +[["uc010pcx.1"],"knownGene","uc010pcx.1","chr1",151313115,151319769] +[["uc001exx.2"],"knownGene","uc001exx.2","chr1",151336780,151345164] +[["uc010pcy.1"],"knownGene","uc010pcy.1","chr1",151336780,151345164] +[["uc001exy.2"],"knownGene","uc001exy.2","chr1",151336780,151345164] +[["uc001exz.2"],"knownGene","uc001exz.2","chr1",151336780,151345164] +[["uc010pcz.1"],"knownGene","uc010pcz.1","chr1",151336780,151345164] +[["uc009wms.2"],"knownGene","uc009wms.2","chr1",151336780,151345164] +[["uc009wmt.2"],"knownGene","uc009wmt.2","chr1",151336780,151345164] +[["uc001eya.2"],"knownGene","uc001eya.2","chr1",151336780,151345164] +[["uc009wmu.2"],"knownGene","uc009wmu.2","chr1",151336780,151345164] +[["uc001eyc.1"],"knownGene","uc001eyc.1","chr1",151372040,151374412] +[["uc001eyb.1"],"knownGene","uc001eyb.1","chr1",151372040,151374382] +[["uc010pda.1"],"knownGene","uc010pda.1","chr1",151372040,151373831] +[["uc001eyd.1"],"knownGene","uc001eyd.1","chr1",151375199,151431932] +[["uc001eye.1"],"knownGene","uc001eye.1","chr1",151375199,151431932] +[["uc010pdb.1"],"knownGene","uc010pdb.1","chr1",151375199,151431932] +[["uc001eyf.1"],"knownGene","uc001eyf.1","chr1",151375199,151431932] +[["uc010pdc.1"],"knownGene","uc010pdc.1","chr1",151375199,151431932] +[["uc009wmv.1"],"knownGene","uc009wmv.1","chr1",151375199,151431932] +[["uc010pdd.1"],"knownGene","uc010pdd.1","chr1",151375199,151431932] +[["uc001eyg.1"],"knownGene","uc001eyg.1","chr1",151399443,151431932] +[["uc009wmw.2"],"knownGene","uc009wmw.2","chr1",151483861,151511165] +[["uc010pde.1"],"knownGene","uc010pde.1","chr1",151506615,151511165] +[["uc001eyl.2"],"knownGene","uc001eyl.2","chr1",151512780,151556058] +[["uc001eym.2"],"knownGene","uc001eym.2","chr1",151512780,151556058] +[["uc010pdf.1"],"knownGene","uc010pdf.1","chr1",151512780,151556058] +[["uc010pdg.1"],"knownGene","uc010pdg.1","chr1",151512780,151556058] +[["uc001eyn.1"],"knownGene","uc001eyn.1","chr1",151584661,151671559] +[["uc001eyo.2"],"knownGene","uc001eyo.2","chr1",151611331,151671559] +[["uc001eyp.2"],"knownGene","uc001eyp.2","chr1",151611363,151666975] +[["uc001eyq.1"],"knownGene","uc001eyq.1","chr1",151670318,151670850] +[["uc001eys.1"],"knownGene","uc001eys.1","chr1",151674829,151689290] +[["uc009wmx.1"],"knownGene","uc009wmx.1","chr1",151674829,151689290] +[["uc001eyr.2"],"knownGene","uc001eyr.2","chr1",151674829,151689059] +[["uc009wmy.2"],"knownGene","uc009wmy.2","chr1",151674829,151689059] +[["uc010pdh.1"],"knownGene","uc010pdh.1","chr1",151674829,151680411] +[["uc001eyt.2"],"knownGene","uc001eyt.2","chr1",151679982,151689278] +[["uc010pdi.1"],"knownGene","uc010pdi.1","chr1",151681473,151689278] +[["uc001eyu.2"],"knownGene","uc001eyu.2","chr1",151682908,151702082] +[["uc010pdj.1"],"knownGene","uc010pdj.1","chr1",151694012,151702082] +[["uc001eyv.2"],"knownGene","uc001eyv.2","chr1",151732124,151736040] +[["uc009wmz.2"],"knownGene","uc009wmz.2","chr1",151732124,151736040] +[["uc010pdk.1"],"knownGene","uc010pdk.1","chr1",151734268,151736040] +[["uc009wna.1"],"knownGene","uc009wna.1","chr1",151734705,151736040] +[["uc010pdl.1"],"knownGene","uc010pdl.1","chr1",151735444,151743805] +[["uc010pdm.1"],"knownGene","uc010pdm.1","chr1",151739130,151743805] +[["uc001eyy.2"],"knownGene","uc001eyy.2","chr1",151742582,151763010] +[["uc009wnb.1"],"knownGene","uc009wnb.1","chr1",151744040,151763010] +[["uc001ezc.3"],"knownGene","uc001ezc.3","chr1",151745958,151763010] +[["uc001eza.3"],"knownGene","uc001eza.3","chr1",151745958,151763010] +[["uc001ezd.3"],"knownGene","uc001ezd.3","chr1",151745958,151763010] +[["uc001ezb.3"],"knownGene","uc001ezb.3","chr1",151745958,151762964] +[["uc010pdn.1"],"knownGene","uc010pdn.1","chr1",151746574,151763010] +[["uc001eze.2"],"knownGene","uc001eze.2","chr1",151763317,151766877] +[["uc001ezf.1"],"knownGene","uc001ezf.1","chr1",151772764,151777882] +[["uc001ezh.2"],"knownGene","uc001ezh.2","chr1",151778547,151804348] +[["uc010pdo.1"],"knownGene","uc010pdo.1","chr1",151778547,151804348] +[["uc010pdp.1"],"knownGene","uc010pdp.1","chr1",151778547,151804348] +[["uc001ezg.2"],"knownGene","uc001ezg.2","chr1",151778547,151798553] +[["uc010pdq.1"],"knownGene","uc010pdq.1","chr1",151810338,151813033] +[["uc010pdr.1"],"knownGene","uc010pdr.1","chr1",151810944,151816640] +[["uc009wnd.2"],"knownGene","uc009wnd.2","chr1",151819577,151826173] +[["uc001ezj.1"],"knownGene","uc001ezj.1","chr1",151846059,151882113] +[["uc001ezk.1"],"knownGene","uc001ezk.1","chr1",151846059,151882113] +[["uc001ezl.2"],"knownGene","uc001ezl.2","chr1",151955386,151966714] +[["uc001ezm.1"],"knownGene","uc001ezm.1","chr1",151967006,152015250] +[["uc001ezn.2"],"knownGene","uc001ezn.2","chr1",152004982,152009511] +[["uc001ezo.1"],"knownGene","uc001ezo.1","chr1",152056619,152061540] +[["uc009wne.1"],"knownGene","uc009wne.1","chr1",152078792,152117706] +[["uc001ezp.2"],"knownGene","uc001ezp.2","chr1",152078792,152086587] +[["uc001ezs.1"],"knownGene","uc001ezs.1","chr1",152126070,152131704] +[["uc001ezt.1"],"knownGene","uc001ezt.1","chr1",152184557,152196669] +[["uc001ezu.1"],"knownGene","uc001ezu.1","chr1",152274650,152297679] +[["uc001ezv.2"],"knownGene","uc001ezv.2","chr1",152285934,152339166] +[["uc001ezw.3"],"knownGene","uc001ezw.3","chr1",152321213,152332482] +[["uc001ezx.2"],"knownGene","uc001ezx.2","chr1",152381718,152386750] +[["uc001ezy.2"],"knownGene","uc001ezy.2","chr1",152483319,152484652] +[["uc001ezz.2"],"knownGene","uc001ezz.2","chr1",152486977,152488480] +[["uc001faa.2"],"knownGene","uc001faa.2","chr1",152538130,152539248] +[["uc001fab.2"],"knownGene","uc001fab.2","chr1",152551860,152552980] +[["uc001fac.2"],"knownGene","uc001fac.2","chr1",152573137,152573562] +[["uc010pds.1"],"knownGene","uc010pds.1","chr1",152586286,152586573] +[["uc010pdt.1"],"knownGene","uc010pdt.1","chr1",152595310,152595579] +[["uc001fag.2"],"knownGene","uc001fag.2","chr1",152635871,152637134] +[["uc001fah.2"],"knownGene","uc001fah.2","chr1",152647770,152649047] +[["uc001fai.2"],"knownGene","uc001fai.2","chr1",152658598,152659874] +[["uc001faj.2"],"knownGene","uc001faj.2","chr1",152670839,152671916] +[["uc001fak.2"],"knownGene","uc001fak.2","chr1",152681522,152681910] +[["uc010pdu.1"],"knownGene","uc010pdu.1","chr1",152691997,152692904] +[["uc001fal.1"],"knownGene","uc001fal.1","chr1",152730505,152734529] +[["uc010pdv.1"],"knownGene","uc010pdv.1","chr1",152748847,152749203] +[["uc001fan.2"],"knownGene","uc001fan.2","chr1",152758752,152760898] +[["uc009wnp.2"],"knownGene","uc009wnp.2","chr1",152769226,152770656] +[["uc001fap.1"],"knownGene","uc001fap.1","chr1",152777310,152779107] +[["uc001faq.2"],"knownGene","uc001faq.2","chr1",152784446,152785586] +[["uc010pdw.1"],"knownGene","uc010pdw.1","chr1",152799948,152800280] +[["uc001fas.3"],"knownGene","uc001fas.3","chr1",152815329,152816458] +[["uc001fat.2"],"knownGene","uc001fat.2","chr1",152850797,152857515] +[["uc001fau.2"],"knownGene","uc001fau.2","chr1",152881038,152884361] +[["uc001fav.1"],"knownGene","uc001fav.1","chr1",152943127,152945069] +[["uc001faw.2"],"knownGene","uc001faw.2","chr1",152956556,152958289] +[["uc009wnu.1"],"knownGene","uc009wnu.1","chr1",152956556,152958010] +[["uc001fay.2"],"knownGene","uc001fay.2","chr1",152974222,152976332] +[["uc001fax.3"],"knownGene","uc001fax.3","chr1",152974222,152976331] +[["uc001faz.3"],"knownGene","uc001faz.3","chr1",152974222,152976331] +[["uc001fba.2"],"knownGene","uc001fba.2","chr1",153003678,153005375] +[["uc009wnx.1"],"knownGene","uc009wnx.1","chr1",153004821,153005089] +[["uc009wnz.2"],"knownGene","uc009wnz.2","chr1",153012200,153113969] +[["uc001fbb.2"],"knownGene","uc001fbb.2","chr1",153012200,153013594] +[["uc001fbf.2"],"knownGene","uc001fbf.2","chr1",153028596,153113969] +[["uc009woa.2"],"knownGene","uc009woa.2","chr1",153028596,153085989] +[["uc001fbd.2"],"knownGene","uc001fbd.2","chr1",153028596,153029988] +[["uc001fbg.2"],"knownGene","uc001fbg.2","chr1",153042719,153044084] +[["uc001fbh.2"],"knownGene","uc001fbh.2","chr1",153065611,153067001] +[["uc001fbi.2"],"knownGene","uc001fbi.2","chr1",153084614,153085989] +[["uc001fbj.2"],"knownGene","uc001fbj.2","chr1",153112594,153113969] +[["uc009wod.1"],"knownGene","uc009wod.1","chr1",153122058,153123427] +[["uc001fbl.2"],"knownGene","uc001fbl.2","chr1",153175918,153177594] +[["uc001fbm.2"],"knownGene","uc001fbm.2","chr1",153232178,153234598] +[["uc001fbn.1"],"knownGene","uc001fbn.1","chr1",153270337,153283194] +[["uc001fbo.2"],"knownGene","uc001fbo.2","chr1",153302597,153321022] +[["uc001fbp.2"],"knownGene","uc001fbp.2","chr1",153302597,153321022] +[["uc001fbq.2"],"knownGene","uc001fbq.2","chr1",153330329,153333502] +[["uc001fbr.1"],"knownGene","uc001fbr.1","chr1",153346183,153348075] +[["uc001fbs.2"],"knownGene","uc001fbs.2","chr1",153362508,153363549] +[["uc001fbt.1"],"knownGene","uc001fbt.1","chr1",153388999,153395701] +[["uc010pdx.1"],"knownGene","uc010pdx.1","chr1",153409471,153412503] +[["uc001fbv.1"],"knownGene","uc001fbv.1","chr1",153430219,153433137] +[["uc001fbw.1"],"knownGene","uc001fbw.1","chr1",153507075,153508717] +[["uc001fbx.2"],"knownGene","uc001fbx.2","chr1",153509623,153514241] +[["uc001fby.2"],"knownGene","uc001fby.2","chr1",153516095,153518282] +[["uc001fbz.2"],"knownGene","uc001fbz.2","chr1",153516095,153518282] +[["uc009wog.1"],"knownGene","uc009wog.1","chr1",153518229,153524245] +[["uc001fca.1"],"knownGene","uc001fca.1","chr1",153519808,153521734] +[["uc001fcb.2"],"knownGene","uc001fcb.2","chr1",153533586,153538306] +[["uc001fcd.1"],"knownGene","uc001fcd.1","chr1",153579366,153585514] +[["uc001fcc.2"],"knownGene","uc001fcc.2","chr1",153579366,153581481] +[["uc001fce.2"],"knownGene","uc001fce.2","chr1",153586733,153588790] +[["uc001fcj.2"],"knownGene","uc001fcj.2","chr1",153591279,153606568] +[["uc001fci.2"],"knownGene","uc001fci.2","chr1",153591279,153600713] +[["uc001fch.2"],"knownGene","uc001fch.2","chr1",153591279,153600117] +[["uc001fcg.2"],"knownGene","uc001fcg.2","chr1",153591279,153599744] +[["uc009woh.2"],"knownGene","uc009woh.2","chr1",153591279,153599744] +[["uc001fcf.3"],"knownGene","uc001fcf.3","chr1",153591279,153599539] +[["uc001fck.1"],"knownGene","uc001fck.1","chr1",153600872,153604513] +[["uc001fcl.1"],"knownGene","uc001fcl.1","chr1",153600872,153604513] +[["uc001fcm.1"],"knownGene","uc001fcm.1","chr1",153606524,153617979] +[["uc001fcn.1"],"knownGene","uc001fcn.1","chr1",153606524,153617979] +[["uc009woj.1"],"knownGene","uc009woj.1","chr1",153606524,153615872] +[["uc009woi.1"],"knownGene","uc009woi.1","chr1",153606524,153611374] +[["uc001fco.1"],"knownGene","uc001fco.1","chr1",153609047,153617979] +[["uc001fcp.2"],"knownGene","uc001fcp.2","chr1",153615953,153618775] +[["uc001fcq.2"],"knownGene","uc001fcq.2","chr1",153631144,153634325] +[["uc001fcr.2"],"knownGene","uc001fcr.2","chr1",153634514,153643479] +[["uc010pdy.1"],"knownGene","uc010pdy.1","chr1",153634514,153643479] +[["uc009wok.2"],"knownGene","uc009wok.2","chr1",153634514,153643479] +[["uc009wol.1"],"knownGene","uc009wol.1","chr1",153637668,153643479] +[["uc001fcs.3"],"knownGene","uc001fcs.3","chr1",153651163,153666467] +[["uc010pdz.1"],"knownGene","uc010pdz.1","chr1",153652629,153666467] +[["uc010pea.1"],"knownGene","uc010pea.1","chr1",153657439,153666467] +[["uc009wom.2"],"knownGene","uc009wom.2","chr1",153700548,153746557] +[["uc001fct.2"],"knownGene","uc001fct.2","chr1",153700566,153746557] +[["uc001fcu.2"],"knownGene","uc001fcu.2","chr1",153700566,153746557] +[["uc001fcv.2"],"knownGene","uc001fcv.2","chr1",153700566,153746557] +[["uc010peb.1"],"knownGene","uc010peb.1","chr1",153723329,153746557] +[["uc001fcw.2"],"knownGene","uc001fcw.2","chr1",153723570,153746557] +[["uc010pec.1"],"knownGene","uc010pec.1","chr1",153730047,153746557] +[["uc001fcy.2"],"knownGene","uc001fcy.2","chr1",153738950,153746557] +[["uc001fcx.2"],"knownGene","uc001fcx.2","chr1",153738950,153746557] +[["uc001fcz.2"],"knownGene","uc001fcz.2","chr1",153747767,153752632] +[["uc009won.2"],"knownGene","uc009won.2","chr1",153747767,153752632] +[["uc001fdb.3"],"knownGene","uc001fdb.3","chr1",153777203,153895451] +[["uc001fdc.1"],"knownGene","uc001fdc.1","chr1",153895878,153907635] +[["uc001fdd.1"],"knownGene","uc001fdd.1","chr1",153901976,153919154] +[["uc010ped.1"],"knownGene","uc010ped.1","chr1",153920153,153931043] +[["uc001fde.3"],"knownGene","uc001fde.3","chr1",153920153,153926790] +[["uc001fdf.3"],"knownGene","uc001fdf.3","chr1",153920153,153926790] +[["uc001fdl.2"],"knownGene","uc001fdl.2","chr1",153931588,153940188] +[["uc001fdk.2"],"knownGene","uc001fdk.2","chr1",153931588,153936026] +[["uc010pee.1"],"knownGene","uc010pee.1","chr1",153931588,153936026] +[["uc001fdj.2"],"knownGene","uc001fdj.2","chr1",153931588,153935951] +[["uc001fdi.2"],"knownGene","uc001fdi.2","chr1",153931588,153935798] +[["uc001fdh.2"],"knownGene","uc001fdh.2","chr1",153931588,153935789] +[["uc001fdn.3"],"knownGene","uc001fdn.3","chr1",153940378,153946832] +[["uc010pef.1"],"knownGene","uc010pef.1","chr1",153940378,153946832] +[["uc001fdo.3"],"knownGene","uc001fdo.3","chr1",153940378,153946832] +[["uc001fdm.1"],"knownGene","uc001fdm.1","chr1",153940396,153946832] +[["uc001fdp.1"],"knownGene","uc001fdp.1","chr1",153940396,153946832] +[["uc001fdr.2"],"knownGene","uc001fdr.2","chr1",153940712,153946832] +[["uc001fdq.2"],"knownGene","uc001fdq.2","chr1",153940712,153946832] +[["uc010peg.1"],"knownGene","uc010peg.1","chr1",153940712,153942219] +[["uc001fds.2"],"knownGene","uc001fds.2","chr1",153946746,153950451] +[["uc001fdt.1"],"knownGene","uc001fdt.1","chr1",153954127,153958806] +[["uc001fdu.1"],"knownGene","uc001fdu.1","chr1",153954129,153958806] +[["uc001fdv.2"],"knownGene","uc001fdv.2","chr1",153963238,153964632] +[["uc001fdw.2"],"knownGene","uc001fdw.2","chr1",153965169,154127592] +[["uc010peh.1"],"knownGene","uc010peh.1","chr1",153965169,154127592] +[["uc009woq.2"],"knownGene","uc009woq.2","chr1",153965169,154108448] +[["uc001fdy.1"],"knownGene","uc001fdy.1","chr1",154127779,154155725] +[["uc001fdz.1"],"knownGene","uc001fdz.1","chr1",154127779,154155725] +[["uc001fea.1"],"knownGene","uc001fea.1","chr1",154127779,154155725] +[["uc001feb.1"],"knownGene","uc001feb.1","chr1",154127779,154155725] +[["uc010pej.1"],"knownGene","uc010pej.1","chr1",154127779,154155725] +[["uc010pei.1"],"knownGene","uc010pei.1","chr1",154127779,154155682] +[["uc001fdx.1"],"knownGene","uc001fdx.1","chr1",154127779,154145153] +[["uc009wor.2"],"knownGene","uc009wor.2","chr1",154128840,154155659] +[["uc001fec.1"],"knownGene","uc001fec.1","chr1",154134289,154164609] +[["uc001fed.1"],"knownGene","uc001fed.1","chr1",154141780,154155725] +[["uc001fee.1"],"knownGene","uc001fee.1","chr1",154171847,154178809] +[["uc001fei.2"],"knownGene","uc001fei.2","chr1",154179182,154193273] +[["uc001feg.2"],"knownGene","uc001feg.2","chr1",154179182,154193273] +[["uc001feh.2"],"knownGene","uc001feh.2","chr1",154179182,154193273] +[["uc001fej.2"],"knownGene","uc001fej.2","chr1",154179182,154193273] +[["uc009wos.1"],"knownGene","uc009wos.1","chr1",154179182,154193273] +[["uc001fef.1"],"knownGene","uc001fef.1","chr1",154179182,154186429] +[["uc001fek.2"],"knownGene","uc001fek.2","chr1",154183853,154193273] +[["uc001fel.2"],"knownGene","uc001fel.2","chr1",154183853,154193273] +[["uc009wot.2"],"knownGene","uc009wot.2","chr1",154192654,154235978] +[["uc010pel.1"],"knownGene","uc010pel.1","chr1",154193324,154243985] +[["uc001fep.3"],"knownGene","uc001fep.3","chr1",154193324,154243328] +[["uc010pek.1"],"knownGene","uc010pek.1","chr1",154193324,154235978] +[["uc001fen.1"],"knownGene","uc001fen.1","chr1",154193443,154209612] +[["uc010pem.1"],"knownGene","uc010pem.1","chr1",154193813,154207214] +[["uc010pen.1"],"knownGene","uc010pen.1","chr1",154201090,154235978] +[["uc001feq.2"],"knownGene","uc001feq.2","chr1",154227627,154243985] +[["uc001fer.2"],"knownGene","uc001fer.2","chr1",154229538,154243328] +[["uc001fet.2"],"knownGene","uc001fet.2","chr1",154245038,154248349] +[["uc001fes.2"],"knownGene","uc001fes.2","chr1",154245038,154248349] +[["uc010peo.1"],"knownGene","uc010peo.1","chr1",154245038,154248349] +[["uc009wou.2"],"knownGene","uc009wou.2","chr1",154245038,154248349] +[["uc009wov.2"],"knownGene","uc009wov.2","chr1",154245127,154248349] +[["uc001feu.2"],"knownGene","uc001feu.2","chr1",154293591,154297800] +[["uc001fev.2"],"knownGene","uc001fev.2","chr1",154293591,154297800] +[["uc001few.2"],"knownGene","uc001few.2","chr1",154298035,154310320] +[["uc001fex.2"],"knownGene","uc001fex.2","chr1",154300275,154323779] +[["uc001fey.1"],"knownGene","uc001fey.1","chr1",154301274,154310020] +[["uc001fez.1"],"knownGene","uc001fez.1","chr1",154377668,154440188] +[["uc001ffa.1"],"knownGene","uc001ffa.1","chr1",154377668,154440188] +[["uc001ffb.2"],"knownGene","uc001ffb.2","chr1",154451960,154474589] +[["uc001ffc.2"],"knownGene","uc001ffc.2","chr1",154451960,154474589] +[["uc001ffd.2"],"knownGene","uc001ffd.2","chr1",154474694,154520622] +[["uc009wow.2"],"knownGene","uc009wow.2","chr1",154474694,154520622] +[["uc001ffe.2"],"knownGene","uc001ffe.2","chr1",154493798,154520622] +[["uc001fff.1"],"knownGene","uc001fff.1","chr1",154521050,154531120] +[["uc001ffg.2"],"knownGene","uc001ffg.2","chr1",154540256,154552351] +[["uc001ffk.2"],"knownGene","uc001ffk.2","chr1",154554535,154600437] +[["uc001ffh.2"],"knownGene","uc001ffh.2","chr1",154554535,154580682] +[["uc001ffj.2"],"knownGene","uc001ffj.2","chr1",154554535,154580682] +[["uc001ffi.2"],"knownGene","uc001ffi.2","chr1",154554535,154580682] +[["uc001ffl.1"],"knownGene","uc001ffl.1","chr1",154573516,154578494] +[["uc001ffn.1"],"knownGene","uc001ffn.1","chr1",154574679,154580682] +[["uc001ffm.1"],"knownGene","uc001ffm.1","chr1",154574679,154578494] +[["uc001ffp.2"],"knownGene","uc001ffp.2","chr1",154679916,154842754] +[["uc001ffo.2"],"knownGene","uc001ffo.2","chr1",154679916,154832338] +[["uc009wox.1"],"knownGene","uc009wox.1","chr1",154743989,154842754] +[["uc001ffq.2"],"knownGene","uc001ffq.2","chr1",154897208,154909484] +[["uc001ffr.2"],"knownGene","uc001ffr.2","chr1",154916560,154928567] +[["uc001ffs.2"],"knownGene","uc001ffs.2","chr1",154916560,154928567] +[["uc010pep.1"],"knownGene","uc010pep.1","chr1",154916560,154928567] +[["uc009woy.1"],"knownGene","uc009woy.1","chr1",154923707,154927803] +[["uc001fft.2"],"knownGene","uc001fft.2","chr1",154929502,154934258] +[["uc001ffx.2"],"knownGene","uc001ffx.2","chr1",154934774,154946959] +[["uc001ffy.2"],"knownGene","uc001ffy.2","chr1",154934774,154946959] +[["uc001ffw.2"],"knownGene","uc001ffw.2","chr1",154934774,154943223] +[["uc001ffv.2"],"knownGene","uc001ffv.2","chr1",154934774,154943223] +[["uc001ffz.1"],"knownGene","uc001ffz.1","chr1",154934774,154941090] +[["uc001ffu.2"],"knownGene","uc001ffu.2","chr1",154934774,154938238] +[["uc001fgb.2"],"knownGene","uc001fgb.2","chr1",154947117,154951724] +[["uc001fga.2"],"knownGene","uc001fga.2","chr1",154947117,154951724] +[["uc001fge.1"],"knownGene","uc001fge.1","chr1",154955816,154965587] +[["uc001fgf.1"],"knownGene","uc001fgf.1","chr1",154955816,154965587] +[["uc001fgg.1"],"knownGene","uc001fgg.1","chr1",154955816,154965587] +[["uc001fgd.1"],"knownGene","uc001fgd.1","chr1",154955816,154963682] +[["uc001fgc.2"],"knownGene","uc001fgc.2","chr1",154955816,154961487] +[["uc001fgh.1"],"knownGene","uc001fgh.1","chr1",154960532,154965587] +[["uc001fgi.2"],"knownGene","uc001fgi.2","chr1",154966061,154966790] +[["uc001fgk.3"],"knownGene","uc001fgk.3","chr1",154975111,154990998] +[["uc009wpa.2"],"knownGene","uc009wpa.2","chr1",154975111,154990998] +[["uc001fgj.3"],"knownGene","uc001fgj.3","chr1",154975126,154990998] +[["uc010peq.1"],"knownGene","uc010peq.1","chr1",154975294,154990998] +[["uc001fgl.3"],"knownGene","uc001fgl.3","chr1",154986923,154990998] +[["uc001fgm.2"],"knownGene","uc001fgm.2","chr1",154991004,155006257] +[["uc009wpb.2"],"knownGene","uc009wpb.2","chr1",154991004,155006257] +[["uc001fgn.1"],"knownGene","uc001fgn.1","chr1",155006299,155023406] +[["uc010pes.1"],"knownGene","uc010pes.1","chr1",155006299,155023406] +[["uc010per.1"],"knownGene","uc010per.1","chr1",155006299,155018962] +[["uc001fgo.2"],"knownGene","uc001fgo.2","chr1",155017693,155023641] +[["uc001fgq.1"],"knownGene","uc001fgq.1","chr1",155023421,155035252] +[["uc001fgt.1"],"knownGene","uc001fgt.1","chr1",155023761,155035252] +[["uc010pev.1"],"knownGene","uc010pev.1","chr1",155023761,155035252] +[["uc001fgs.1"],"knownGene","uc001fgs.1","chr1",155023761,155035252] +[["uc001fgr.1"],"knownGene","uc001fgr.1","chr1",155023761,155035252] +[["uc001fgu.1"],"knownGene","uc001fgu.1","chr1",155023761,155035252] +[["uc001fgw.1"],"knownGene","uc001fgw.1","chr1",155023761,155035252] +[["uc001fgv.1"],"knownGene","uc001fgv.1","chr1",155023761,155035252] +[["uc001fgx.1"],"knownGene","uc001fgx.1","chr1",155023761,155035252] +[["uc001fgz.1"],"knownGene","uc001fgz.1","chr1",155023761,155035252] +[["uc001fgy.1"],"knownGene","uc001fgy.1","chr1",155023761,155035252] +[["uc001fha.1"],"knownGene","uc001fha.1","chr1",155023761,155035252] +[["uc010peu.1"],"knownGene","uc010peu.1","chr1",155023761,155034181] +[["uc010pet.1"],"knownGene","uc010pet.1","chr1",155023761,155031006] +[["uc009wpc.1"],"knownGene","uc009wpc.1","chr1",155023761,155028725] +[["uc001fhb.1"],"knownGene","uc001fhb.1","chr1",155030714,155035252] +[["uc010pew.1"],"knownGene","uc010pew.1","chr1",155036212,155060006] +[["uc001fhc.2"],"knownGene","uc001fhc.2","chr1",155036212,155042027] +[["uc001fhd.2"],"knownGene","uc001fhd.2","chr1",155036212,155042027] +[["uc001fhe.2"],"knownGene","uc001fhe.2","chr1",155036212,155042027] +[["uc001fhf.2"],"knownGene","uc001fhf.2","chr1",155051347,155060006] +[["uc010pex.1"],"knownGene","uc010pex.1","chr1",155051347,155060006] +[["uc001fhg.2"],"knownGene","uc001fhg.2","chr1",155057484,155060006] +[["uc001fhh.2"],"knownGene","uc001fhh.2","chr1",155100348,155107384] +[["uc001fhi.2"],"knownGene","uc001fhi.2","chr1",155100348,155107384] +[["uc009wpd.1"],"knownGene","uc009wpd.1","chr1",155105263,155106131] +[["uc010pey.1"],"knownGene","uc010pey.1","chr1",155108287,155357080] +[["uc001fhj.3"],"knownGene","uc001fhj.3","chr1",155108287,155111333] +[["uc001fhk.3"],"knownGene","uc001fhk.3","chr1",155108287,155111333] +[["uc001fhl.3"],"knownGene","uc001fhl.3","chr1",155108287,155111333] +[["uc001fhn.2"],"knownGene","uc001fhn.2","chr1",155112368,155112996] +[["uc001fhm.2"],"knownGene","uc001fhm.2","chr1",155112368,155112883] +[["uc001fho.2"],"knownGene","uc001fho.2","chr1",155141884,155145804] +[["uc001fhp.1"],"knownGene","uc001fhp.1","chr1",155143876,155145804] +[["uc009wpe.1"],"knownGene","uc009wpe.1","chr1",155145420,155154625] +[["uc001fhs.1"],"knownGene","uc001fhs.1","chr1",155146359,155157445] +[["uc001fht.1"],"knownGene","uc001fht.1","chr1",155146359,155157445] +[["uc010pfa.1"],"knownGene","uc010pfa.1","chr1",155146359,155157445] +[["uc001fhq.2"],"knownGene","uc001fhq.2","chr1",155146359,155153085] +[["uc001fhr.2"],"knownGene","uc001fhr.2","chr1",155146359,155153085] +[["uc010pez.1"],"knownGene","uc010pez.1","chr1",155146359,155149766] +[["uc001fhu.1"],"knownGene","uc001fhu.1","chr1",155146384,155157445] +[["uc009wpg.1"],"knownGene","uc009wpg.1","chr1",155147069,155154625] +[["uc001fhv.3"],"knownGene","uc001fhv.3","chr1",155147076,155153085] +[["uc009wpf.2"],"knownGene","uc009wpf.2","chr1",155147076,155148927] +[["uc001fhw.1"],"knownGene","uc001fhw.1","chr1",155147229,155157445] +[["uc001fin.2"],"knownGene","uc001fin.2","chr1",155158301,155162700] +[["uc009wpk.2"],"knownGene","uc009wpk.2","chr1",155158301,155162700] +[["uc001fip.2"],"knownGene","uc001fip.2","chr1",155158301,155162700] +[["uc009wqg.2"],"knownGene","uc009wqg.2","chr1",155158301,155162700] +[["uc009wpo.2"],"knownGene","uc009wpo.2","chr1",155158301,155162700] +[["uc009wps.2"],"knownGene","uc009wps.2","chr1",155158301,155162700] +[["uc009wpt.2"],"knownGene","uc009wpt.2","chr1",155158301,155162700] +[["uc001fic.2"],"knownGene","uc001fic.2","chr1",155158301,155162700] +[["uc009wpu.2"],"knownGene","uc009wpu.2","chr1",155158301,155162700] +[["uc009wpq.2"],"knownGene","uc009wpq.2","chr1",155158301,155162700] +[["uc009wpv.2"],"knownGene","uc009wpv.2","chr1",155158301,155162700] +[["uc001fim.2"],"knownGene","uc001fim.2","chr1",155158301,155162700] +[["uc001fib.2"],"knownGene","uc001fib.2","chr1",155158301,155162700] +[["uc009wpw.2"],"knownGene","uc009wpw.2","chr1",155158301,155162700] +[["uc001fie.2"],"knownGene","uc001fie.2","chr1",155158301,155162700] +[["uc009wpr.2"],"knownGene","uc009wpr.2","chr1",155158301,155162700] +[["uc001fig.2"],"knownGene","uc001fig.2","chr1",155158301,155162700] +[["uc001fif.2"],"knownGene","uc001fif.2","chr1",155158301,155162700] +[["uc009wpx.2"],"knownGene","uc009wpx.2","chr1",155158301,155162700] +[["uc001fid.2"],"knownGene","uc001fid.2","chr1",155158301,155162700] +[["uc009wpj.2"],"knownGene","uc009wpj.2","chr1",155158301,155162700] +[["uc001fij.2"],"knownGene","uc001fij.2","chr1",155158301,155162700] +[["uc009wpy.2"],"knownGene","uc009wpy.2","chr1",155158301,155162700] +[["uc010pfm.1"],"knownGene","uc010pfm.1","chr1",155158301,155162700] +[["uc001fiq.2"],"knownGene","uc001fiq.2","chr1",155158301,155162700] +[["uc009wpz.2"],"knownGene","uc009wpz.2","chr1",155158301,155162700] +[["uc010pfn.1"],"knownGene","uc010pfn.1","chr1",155158301,155162700] +[["uc009wqa.2"],"knownGene","uc009wqa.2","chr1",155158301,155162700] +[["uc010pfo.1"],"knownGene","uc010pfo.1","chr1",155158301,155162700] +[["uc010pfp.1"],"knownGene","uc010pfp.1","chr1",155158301,155162700] +[["uc001fii.2"],"knownGene","uc001fii.2","chr1",155158301,155162700] +[["uc001fih.2"],"knownGene","uc001fih.2","chr1",155158301,155162700] +[["uc001fia.2"],"knownGene","uc001fia.2","chr1",155158301,155162700] +[["uc009wqc.2"],"knownGene","uc009wqc.2","chr1",155158301,155162700] +[["uc009wqd.2"],"knownGene","uc009wqd.2","chr1",155158301,155162700] +[["uc009wqb.2"],"knownGene","uc009wqb.2","chr1",155158301,155162700] +[["uc010pfq.1"],"knownGene","uc010pfq.1","chr1",155158301,155162700] +[["uc010pfr.1"],"knownGene","uc010pfr.1","chr1",155158301,155162700] +[["uc001fit.2"],"knownGene","uc001fit.2","chr1",155158301,155162700] +[["uc009wqe.2"],"knownGene","uc009wqe.2","chr1",155158301,155162700] +[["uc001fil.2"],"knownGene","uc001fil.2","chr1",155158301,155162700] +[["uc009wpm.2"],"knownGene","uc009wpm.2","chr1",155158301,155162700] +[["uc009wpp.2"],"knownGene","uc009wpp.2","chr1",155158301,155162700] +[["uc010pfs.1"],"knownGene","uc010pfs.1","chr1",155158301,155162700] +[["uc001fik.2"],"knownGene","uc001fik.2","chr1",155158301,155162700] +[["uc001fio.2"],"knownGene","uc001fio.2","chr1",155158301,155162700] +[["uc009wqf.2"],"knownGene","uc009wqf.2","chr1",155158301,155162700] +[["uc009wpl.2"],"knownGene","uc009wpl.2","chr1",155158301,155162700] +[["uc009wpn.2"],"knownGene","uc009wpn.2","chr1",155158301,155162700] +[["uc010pfc.1"],"knownGene","uc010pfc.1","chr1",155158301,155162684] +[["uc009wph.2"],"knownGene","uc009wph.2","chr1",155158301,155162684] +[["uc010pfd.1"],"knownGene","uc010pfd.1","chr1",155158301,155162684] +[["uc010pfe.1"],"knownGene","uc010pfe.1","chr1",155158301,155162684] +[["uc010pff.1"],"knownGene","uc010pff.1","chr1",155158301,155162684] +[["uc009wpi.2"],"knownGene","uc009wpi.2","chr1",155158301,155162684] +[["uc010pfg.1"],"knownGene","uc010pfg.1","chr1",155158301,155162684] +[["uc010pfh.1"],"knownGene","uc010pfh.1","chr1",155158301,155162684] +[["uc010pfi.1"],"knownGene","uc010pfi.1","chr1",155158301,155162684] +[["uc010pfj.1"],"knownGene","uc010pfj.1","chr1",155158301,155162684] +[["uc010pfk.1"],"knownGene","uc010pfk.1","chr1",155158301,155162684] +[["uc010pfl.1"],"knownGene","uc010pfl.1","chr1",155158301,155162684] +[["uc010pfb.1"],"knownGene","uc010pfb.1","chr1",155158301,155162101] +[["uc001fhz.2"],"knownGene","uc001fhz.2","chr1",155158301,155161398] +[["uc001fhy.2"],"knownGene","uc001fhy.2","chr1",155158301,155161158] +[["uc001fis.1"],"knownGene","uc001fis.1","chr1",155159930,155162700] +[["uc009wqh.2"],"knownGene","uc009wqh.2","chr1",155161151,155161619] +[["uc010pft.1"],"knownGene","uc010pft.1","chr1",155161501,155162700] +[["uc001fiv.1"],"knownGene","uc001fiv.1","chr1",155161653,155162700] +[["uc001fiw.1"],"knownGene","uc001fiw.1","chr1",155161686,155162700] +[["uc001fix.2"],"knownGene","uc001fix.2","chr1",155165380,155177690] +[["uc009wqi.2"],"knownGene","uc009wqi.2","chr1",155165380,155177690] +[["uc001fiz.2"],"knownGene","uc001fiz.2","chr1",155165380,155177690] +[["uc001fiy.2"],"knownGene","uc001fiy.2","chr1",155165380,155177690] +[["uc010pfu.1"],"knownGene","uc010pfu.1","chr1",155165380,155177690] +[["uc010pfv.1"],"knownGene","uc010pfv.1","chr1",155167670,155177690] +[["uc001fja.2"],"knownGene","uc001fja.2","chr1",155170241,155178969] +[["uc009wqj.1"],"knownGene","uc009wqj.1","chr1",155174360,155178969] +[["uc001fjb.2"],"knownGene","uc001fjb.2","chr1",155178489,155183622] +[["uc001fjc.2"],"knownGene","uc001fjc.2","chr1",155178489,155183622] +[["uc001fjf.3"],"knownGene","uc001fjf.3","chr1",155183616,155197325] +[["uc001fje.3"],"knownGene","uc001fje.3","chr1",155183616,155197325] +[["uc001fjd.2"],"knownGene","uc001fjd.2","chr1",155183616,155188809] +[["uc001fjg.2"],"knownGene","uc001fjg.2","chr1",155202800,155204240] +[["uc001fji.2"],"knownGene","uc001fji.2","chr1",155204243,155214488] +[["uc001fjj.2"],"knownGene","uc001fjj.2","chr1",155204243,155214488] +[["uc001fjk.2"],"knownGene","uc001fjk.2","chr1",155204243,155214488] +[["uc001fjl.2"],"knownGene","uc001fjl.2","chr1",155204243,155214488] +[["uc010pfy.1"],"knownGene","uc010pfy.1","chr1",155204243,155214488] +[["uc001fjh.2"],"knownGene","uc001fjh.2","chr1",155204243,155211053] +[["uc010pfw.1"],"knownGene","uc010pfw.1","chr1",155204243,155211053] +[["uc010pfx.1"],"knownGene","uc010pfx.1","chr1",155204243,155211053] +[["uc009wqk.1"],"knownGene","uc009wqk.1","chr1",155207131,155214488] +[["uc001fjm.2"],"knownGene","uc001fjm.2","chr1",155216996,155225274] +[["uc001fjn.2"],"knownGene","uc001fjn.2","chr1",155216996,155225274] +[["uc001fjo.2"],"knownGene","uc001fjo.2","chr1",155216996,155225274] +[["uc001fjp.2"],"knownGene","uc001fjp.2","chr1",155216996,155225274] +[["uc009wql.2"],"knownGene","uc009wql.2","chr1",155216996,155221696] +[["uc001fjq.1"],"knownGene","uc001fjq.1","chr1",155222539,155225274] +[["uc001fjs.2"],"knownGene","uc001fjs.2","chr1",155225770,155232195] +[["uc001fjt.2"],"knownGene","uc001fjt.2","chr1",155225770,155232195] +[["uc001fju.2"],"knownGene","uc001fju.2","chr1",155225770,155232195] +[["uc001fjv.2"],"knownGene","uc001fjv.2","chr1",155225770,155232195] +[["uc001fjr.2"],"knownGene","uc001fjr.2","chr1",155225770,155230335] +[["uc009wqm.2"],"knownGene","uc009wqm.2","chr1",155232659,155247501] +[["uc001fjw.2"],"knownGene","uc001fjw.2","chr1",155232659,155243281] +[["uc001fjy.2"],"knownGene","uc001fjy.2","chr1",155232659,155243281] +[["uc001fjx.2"],"knownGene","uc001fjx.2","chr1",155232659,155243281] +[["uc001fjz.1"],"knownGene","uc001fjz.1","chr1",155247373,155259638] +[["uc010pfz.1"],"knownGene","uc010pfz.1","chr1",155247373,155258498] +[["uc001fkb.3"],"knownGene","uc001fkb.3","chr1",155259085,155271225] +[["uc001fka.3"],"knownGene","uc001fka.3","chr1",155259085,155270792] +[["uc010pga.1"],"knownGene","uc010pga.1","chr1",155265227,155270792] +[["uc001fkc.2"],"knownGene","uc001fkc.2","chr1",155278538,155290457] +[["uc001fkd.2"],"knownGene","uc001fkd.2","chr1",155278538,155290457] +[["uc001fke.2"],"knownGene","uc001fke.2","chr1",155278704,155290457] +[["uc001fkf.2"],"knownGene","uc001fkf.2","chr1",155278704,155290457] +[["uc001fkh.1"],"knownGene","uc001fkh.1","chr1",155286653,155291335] +[["uc001fki.2"],"knownGene","uc001fki.2","chr1",155290251,155293938] +[["uc001fkj.2"],"knownGene","uc001fkj.2","chr1",155290639,155300909] +[["uc001fkk.2"],"knownGene","uc001fkk.2","chr1",155290639,155300909] +[["uc009wqn.1"],"knownGene","uc009wqn.1","chr1",155291478,155300909] +[["uc009wqo.1"],"knownGene","uc009wqo.1","chr1",155293284,155300909] +[["uc001fkl.2"],"knownGene","uc001fkl.2","chr1",155293727,155300909] +[["uc001fkp.2"],"knownGene","uc001fkp.2","chr1",155294217,155300909] +[["uc001fkq.2"],"knownGene","uc001fkq.2","chr1",155294217,155300909] +[["uc010pgb.1"],"knownGene","uc010pgb.1","chr1",155294217,155300909] +[["uc009wqp.1"],"knownGene","uc009wqp.1","chr1",155294217,155300909] +[["uc001fkn.2"],"knownGene","uc001fkn.2","chr1",155294297,155300909] +[["uc001fko.2"],"knownGene","uc001fko.2","chr1",155294297,155300909] +[["uc001fkr.2"],"knownGene","uc001fkr.2","chr1",155294367,155300909] +[["uc001fks.2"],"knownGene","uc001fks.2","chr1",155295357,155300909] +[["uc001fkt.2"],"knownGene","uc001fkt.2","chr1",155305052,155532324] +[["uc009wqq.2"],"knownGene","uc009wqq.2","chr1",155305052,155532324] +[["uc010pgd.1"],"knownGene","uc010pgd.1","chr1",155403092,155403793] +[["uc010pgc.1"],"knownGene","uc010pgc.1","chr1",155403092,155403473] +[["uc009wqr.1"],"knownGene","uc009wqr.1","chr1",155447676,155532585] +[["uc010pge.1"],"knownGene","uc010pge.1","chr1",155531771,155533732] +[["uc001fkv.2"],"knownGene","uc001fkv.2","chr1",155531863,155533732] +[["uc001fky.2"],"knownGene","uc001fky.2","chr1",155580006,155584757] +[["uc001fla.2"],"knownGene","uc001fla.2","chr1",155580006,155584757] +[["uc001fkz.2"],"knownGene","uc001fkz.2","chr1",155580006,155584757] +[["uc001fld.3"],"knownGene","uc001fld.3","chr1",155580006,155584757] +[["uc009wqs.2"],"knownGene","uc009wqs.2","chr1",155580006,155584757] +[["uc010pgf.1"],"knownGene","uc010pgf.1","chr1",155580006,155584757] +[["uc001fkw.2"],"knownGene","uc001fkw.2","chr1",155580006,155584724] +[["uc001fkx.2"],"knownGene","uc001fkx.2","chr1",155580006,155584724] +[["uc001flb.2"],"knownGene","uc001flb.2","chr1",155580031,155584757] +[["uc001flc.2"],"knownGene","uc001flc.2","chr1",155580410,155584724] +[["uc001fle.1"],"knownGene","uc001fle.1","chr1",155583674,155585496] +[["uc001flf.2"],"knownGene","uc001flf.2","chr1",155596546,155618335] +[["uc001fln.2"],"knownGene","uc001fln.2","chr1",155629233,155658791] +[["uc001flo.2"],"knownGene","uc001flo.2","chr1",155629233,155658791] +[["uc001flp.2"],"knownGene","uc001flp.2","chr1",155629233,155658791] +[["uc001flk.2"],"knownGene","uc001flk.2","chr1",155629233,155658565] +[["uc001fll.2"],"knownGene","uc001fll.2","chr1",155629233,155658565] +[["uc009wqv.2"],"knownGene","uc009wqv.2","chr1",155629233,155658565] +[["uc001flm.2"],"knownGene","uc001flm.2","chr1",155629233,155658565] +[["uc001fli.2"],"knownGene","uc001fli.2","chr1",155629233,155658565] +[["uc009wqu.2"],"knownGene","uc009wqu.2","chr1",155629233,155658565] +[["uc001flj.2"],"knownGene","uc001flj.2","chr1",155629233,155658565] +[["uc009wqw.2"],"knownGene","uc009wqw.2","chr1",155629233,155658565] +[["uc010pgi.1"],"knownGene","uc010pgi.1","chr1",155629233,155658266] +[["uc001flh.2"],"knownGene","uc001flh.2","chr1",155629233,155658266] +[["uc009wqt.2"],"knownGene","uc009wqt.2","chr1",155629233,155658266] +[["uc010pgh.1"],"knownGene","uc010pgh.1","chr1",155629233,155649598] +[["uc010pgg.1"],"knownGene","uc010pgg.1","chr1",155629233,155646537] +[["uc001flg.2"],"knownGene","uc001flg.2","chr1",155629233,155640882] +[["uc010pgj.1"],"knownGene","uc010pgj.1","chr1",155630240,155658791] +[["uc009wqx.2"],"knownGene","uc009wqx.2","chr1",155630785,155658266] +[["uc010pgk.1"],"knownGene","uc010pgk.1","chr1",155638417,155658266] +[["uc001flq.2"],"knownGene","uc001flq.2","chr1",155658873,155708317] diff --git a/tests/data/redundant.gff3 b/tests/data/redundant.gff3 new file mode 100644 index 0000000000..2b545948ae --- /dev/null +++ b/tests/data/redundant.gff3 @@ -0,0 +1,2 @@ +##gff-version 3 +Group1.36 AU9 gene 176975 180744 0.84 + . ID=au9.g1002;Name=au9.g1002,foobar;score=20;start=99839;Alias=noggin diff --git a/tests/data/volvox_formatted_names/names/0.json b/tests/data/volvox_formatted_names/names/0.json new file mode 100644 index 0000000000..e0348c96bb --- /dev/null +++ b/tests/data/volvox_formatted_names/names/0.json @@ -0,0 +1 @@ +{"seg04":{"exact":[["seg04",4,"seg04","ctgA",5232,5302],["seg04",4,"seg04","ctgA",5799,6101],["seg04",4,"seg04","ctgA",6441,6854],["seg04",4,"seg04","ctgA",7105,7211],["seg04",4,"seg04","ctgA",7694,8177],["seg04",4,"seg04","ctgA",8544,8783],["seg04",4,"seg04","ctgA",8868,8935],["seg04",4,"seg04","ctgA",9403,9825]],"prefix":[]},"protein:hgb":{"exact":[["Protein:HGB",1,"Protein:HGB","ctgA",1799,2900]],"prefix":[]},"apple":{"exact":[],"prefix":["Apple1","Apple2","Apple3"]},"eden.2":{"exact":[["EDEN.2",6,"EDEN.2","ctgA",1049,9000]],"prefix":[]},"m15":{"exact":[["m15",3,"m15","ctgA",37496,40559]],"prefix":[]},"f05":{"exact":[["f05",0,"f05","ctgB",4714,5968],["f05",0,"f05","ctgA",4714,5968]],"prefix":[]},"fa":{"exact":[],"prefix":["FakeSNP"]},"protein:h":{"exact":[],"prefix":["Protein:HGB","Protein:HGA"]},"b1":{"exact":[],"prefix":["b101.2"]},"f":{"exact":[],"prefix":["f05","f15","f12","f02","f13","f03","f04","f14","f11","f01","f06","f09","f07","f08","f10",{"name":"too many matches","hitLimit":1}]},"agt":{"exact":[],"prefix":["agt767.5","agt221.3","agt830.3","agt221.5","agt767.3","agt830.5"]}} \ No newline at end of file diff --git a/tests/data/volvox_formatted_names/names/1.json b/tests/data/volvox_formatted_names/names/1.json new file mode 100644 index 0000000000..720dcb034b --- /dev/null +++ b/tests/data/volvox_formatted_names/names/1.json @@ -0,0 +1 @@ +{"f15":{"exact":[["f15",0,"f15","ctgA",22131,24633]],"prefix":[]},"ctgB":{"exact":[[6079,"ctgB",null,0,6079,20000]],"prefix":[]},"p":{"exact":[],"prefix":["Protein:HGB","Protein:HGA"]},"agt767.5":{"exact":[["agt767.5",10,"agt767.5","ctgA",1149,7200]],"prefix":[]},"seg14":{"exact":[["seg14",4,"seg14","ctgA",41136,41318],["seg14",4,"seg14","ctgA",41753,41948],["seg14",4,"seg14","ctgA",42056,42474],["seg14",4,"seg14","ctgA",42889,43270],["seg14",4,"seg14","ctgA",43394,43811],["seg14",4,"seg14","ctgA",44064,44556],["seg14",4,"seg14","ctgA",44762,45030],["seg14",4,"seg14","ctgA",45230,45488],["seg14",4,"seg14","ctgA",45789,46022],["seg14",4,"seg14","ctgA",46091,46318],["seg14",4,"seg14","ctgA",46815,46992],["seg14",4,"seg14","ctgA",47448,47829]],"prefix":[]},"m05":{"exact":[["m05",3,"m05","ctgA",13800,14007]],"prefix":[]},"agt221.3":{"exact":[["agt221.3",10,"agt221.3","ctgA",7499,8000]],"prefix":[]}} \ No newline at end of file diff --git a/tests/data/volvox_formatted_names/names/2.json b/tests/data/volvox_formatted_names/names/2.json new file mode 100644 index 0000000000..4f4d122043 --- /dev/null +++ b/tests/data/volvox_formatted_names/names/2.json @@ -0,0 +1 @@ +{"f0":{"exact":[],"prefix":["f05","f02","f03","f04","f01","f06","f09","f07","f08"]},"ctg":{"exact":[],"prefix":["6079","50001"]},"ag":{"exact":[],"prefix":["agt767.5","agt221.3","agt830.3","agt221.5","agt767.3","agt830.5"]},"protein":{"exact":[],"prefix":["Protein:HGB","Protein:HGA"]},"f12":{"exact":[["f12",0,"f12","ctgA",49757,50000]],"prefix":[]},"m02":{"exact":[["m02",3,"m02","ctgA",28331,30033]],"prefix":[]},"b10":{"exact":[],"prefix":["b101.2"]},"seg":{"exact":[],"prefix":["seg04","seg14","seg13","seg03","seg12","seg02","seg05","seg15","seg10","seg07","seg08","seg06","seg09","seg11","seg01"]},"agt830.3":{"exact":[["agt830.3",10,"agt830.3","ctgA",5409,7503]],"prefix":[]},"seg13":{"exact":[["seg13",4,"seg13","ctgA",49405,49476],["seg13",4,"seg13","ctgA",49761,50000]],"prefix":[]},"agt7":{"exact":[],"prefix":["agt767.5","agt767.3"]}} \ No newline at end of file diff --git a/tests/data/volvox_formatted_names/names/3.json b/tests/data/volvox_formatted_names/names/3.json new file mode 100644 index 0000000000..8e76e1fc2a --- /dev/null +++ b/tests/data/volvox_formatted_names/names/3.json @@ -0,0 +1 @@ +{"fakes":{"exact":[],"prefix":["FakeSNP"]},"a":{"exact":[],"prefix":["agt767.5","agt221.3","agt830.3","Apple1","agt221.5","agt767.3","agt830.5","Apple2","Apple3"]},"f02":{"exact":[["f02",0,"f02","ctgA",24561,28338]],"prefix":[]},"gene":{"exact":[],"prefix":["Gene:hgb","Gene:hga"]},"prot":{"exact":[],"prefix":["Protein:HGB","Protein:HGA"]},"apple1":{"exact":[["Apple1",7,"Apple1","ctgA",9999,11500]],"prefix":[]},"agt767.":{"exact":[],"prefix":["agt767.5","agt767.3"]},"agt8":{"exact":[],"prefix":["agt830.3","agt830.5"]},"m12":{"exact":[["m12",3,"m12","ctgA",21747,25612]],"prefix":[]},"gene:hg":{"exact":[],"prefix":["Gene:hgb","Gene:hga"]},"seg03":{"exact":[["seg03",4,"seg03","ctgA",6884,7241],["seg03",4,"seg03","ctgA",7409,7737],["seg03",4,"seg03","ctgA",8054,8080],["seg03",4,"seg03","ctgA",8305,8999]],"prefix":[]}} \ No newline at end of file diff --git a/tests/data/volvox_formatted_names/names/4.json b/tests/data/volvox_formatted_names/names/4.json new file mode 100644 index 0000000000..36a23a1d6d --- /dev/null +++ b/tests/data/volvox_formatted_names/names/4.json @@ -0,0 +1 @@ +{"f13":{"exact":[["f13",0,"f13","ctgA",19156,22915]],"prefix":[]},"agt221.5":{"exact":[["agt221.5",10,"agt221.5","ctgA",1049,7300]],"prefix":[]},"seg12":{"exact":[["seg12",4,"seg12","ctgA",12530,12895],["seg12",4,"seg12","ctgA",13121,13449],["seg12",4,"seg12","ctgA",13451,13745],["seg12",4,"seg12","ctgA",13907,13965],["seg12",4,"seg12","ctgA",13997,14488],["seg12",4,"seg12","ctgA",14563,14899],["seg12",4,"seg12","ctgA",15184,15276],["seg12",4,"seg12","ctgA",15638,15736],["seg12",4,"seg12","ctgA",15744,15870]],"prefix":[]},"f1":{"exact":[],"prefix":["f15","f12","f13","f14","f11","f10"]},"gene:h":{"exact":[],"prefix":["Gene:hgb","Gene:hga"]},"hga":{"exact":[["hga",0,"Remark:hga","ctgA",999,2000],["hga",1,"Gene:hga","ctgA",1099,2000],["hga",1,"Protein:HGA","ctgA",1199,1900]],"prefix":[]},"agt767.3":{"exact":[["agt767.3",10,"agt767.3","ctgA",7999,9000]],"prefix":[]},"rema":{"exact":[],"prefix":["Remark:hga"]},"m03":{"exact":[["m03",3,"m03","ctgA",15395,16159]],"prefix":[]}} \ No newline at end of file diff --git a/tests/data/volvox_formatted_names/names/5.json b/tests/data/volvox_formatted_names/names/5.json new file mode 100644 index 0000000000..b0af4e2250 --- /dev/null +++ b/tests/data/volvox_formatted_names/names/5.json @@ -0,0 +1 @@ +{"seg02":{"exact":[["seg02",4,"seg02","ctgA",26121,26126],["seg02",4,"seg02","ctgA",26496,26869],["seg02",4,"seg02","ctgA",27200,27325],["seg02",4,"seg02","ctgA",27371,27433],["seg02",4,"seg02","ctgA",27564,27565],["seg02",4,"seg02","ctgA",27812,28091],["seg02",4,"seg02","ctgA",28092,28201],["seg02",4,"seg02","ctgA",28328,28377],["seg02",4,"seg02","ctgA",28828,29194],["seg02",4,"seg02","ctgA",29516,29702],["seg02",4,"seg02","ctgA",29712,30061],["seg02",4,"seg02","ctgA",30328,30774],["seg02",4,"seg02","ctgA",30807,31306],["seg02",4,"seg02","ctgA",31515,31729],["seg02",4,"seg02","ctgA",31752,32154],["seg02",4,"seg02","ctgA",32594,32696],["seg02",4,"seg02","ctgA",32891,32901],["seg02",4,"seg02","ctgA",33126,33388],["seg02",4,"seg02","ctgA",33438,33443],["seg02",4,"seg02","ctgA",33758,34209],["seg02",4,"seg02","ctgA",34400,34466]],"prefix":[]},"m13":{"exact":[["m13",3,"m13","ctgA",17666,17690]],"prefix":[]},"ap":{"exact":[],"prefix":["Apple1","Apple2","Apple3"]},"protein:hg":{"exact":[],"prefix":["Protein:HGB","Protein:HGA"]},"f03":{"exact":[["f03",0,"f03","ctgA",36648,40440]],"prefix":[]},"agt767":{"exact":[],"prefix":["agt767.5","agt767.3"]}} \ No newline at end of file diff --git a/tests/data/volvox_formatted_names/names/6.json b/tests/data/volvox_formatted_names/names/6.json new file mode 100644 index 0000000000..1c9549f320 --- /dev/null +++ b/tests/data/volvox_formatted_names/names/6.json @@ -0,0 +1 @@ +{"m14":{"exact":[["m14",3,"m14","ctgA",14730,17239]],"prefix":[]},"remar":{"exact":[],"prefix":["Remark:hga"]},"fak":{"exact":[],"prefix":["FakeSNP"]},"eden.3":{"exact":[["EDEN.3",6,"EDEN.3","ctgA",1299,9000]],"prefix":[]},"remark:hga":{"exact":[["Remark:hga",0,"Remark:hga","ctgA",999,2000]],"prefix":[]},"g":{"exact":[],"prefix":["Gene:hgb","Gene:hga"]},"seg05":{"exact":[["seg05",4,"seg05","ctgA",26502,26799],["seg05",4,"seg05","ctgA",27171,27185],["seg05",4,"seg05","ctgA",27447,27860],["seg05",4,"seg05","ctgA",27886,28076],["seg05",4,"seg05","ctgA",28224,28316],["seg05",4,"seg05","ctgA",28776,29058],["seg05",4,"seg05","ctgA",29512,29647],["seg05",4,"seg05","ctgA",30107,30216],["seg05",4,"seg05","ctgA",30464,30798],["seg05",4,"seg05","ctgA",31231,31236],["seg05",4,"seg05","ctgA",31420,31817],["seg05",4,"seg05","ctgA",32009,32057],["seg05",4,"seg05","ctgA",32207,32680],["seg05",4,"seg05","ctgA",33052,33325],["seg05",4,"seg05","ctgA",33437,33868],["seg05",4,"seg05","ctgA",34243,34313],["seg05",4,"seg05","ctgA",34604,34983],["seg05",4,"seg05","ctgA",35332,35507],["seg05",4,"seg05","ctgA",35641,35904]],"prefix":[]},"f04":{"exact":[["f04",0,"f04","ctgA",37241,38653]],"prefix":[]}} \ No newline at end of file diff --git a/tests/data/volvox_formatted_names/names/7.json b/tests/data/volvox_formatted_names/names/7.json new file mode 100644 index 0000000000..d49b8e3972 --- /dev/null +++ b/tests/data/volvox_formatted_names/names/7.json @@ -0,0 +1 @@ +{"agt830.5":{"exact":[["agt830.5",10,"agt830.5","ctgA",1049,3202]],"prefix":[]},"agt22":{"exact":[],"prefix":["agt221.3","agt221.5"]},"f14":{"exact":[["f14",0,"f14","ctgA",23071,23185]],"prefix":[]},"seg15":{"exact":[["seg15",4,"seg15","ctgA",39264,39361],["seg15",4,"seg15","ctgA",39752,40034],["seg15",4,"seg15","ctgA",40514,40954],["seg15",4,"seg15","ctgA",41251,41365],["seg15",4,"seg15","ctgA",41491,41504],["seg15",4,"seg15","ctgA",41940,42377],["seg15",4,"seg15","ctgA",42747,42954],["seg15",4,"seg15","ctgA",43400,43897],["seg15",4,"seg15","ctgA",44042,44113],["seg15",4,"seg15","ctgA",44398,44888],["seg15",4,"seg15","ctgA",45280,45375],["seg15",4,"seg15","ctgA",45710,46041],["seg15",4,"seg15","ctgA",46424,46564],["seg15",4,"seg15","ctgA",46737,47087],["seg15",4,"seg15","ctgA",47328,47595],["seg15",4,"seg15","ctgA",47857,47979],["seg15",4,"seg15","ctgA",48168,48453]],"prefix":[]},"h":{"exact":[],"prefix":["hga","hgb"]},"gene:hgb":{"exact":[["Gene:hgb",1,"Gene:hgb","ctgA",1599,3000]],"prefix":[]},"remark:hg":{"exact":[],"prefix":["Remark:hga"]},"m04":{"exact":[["m04",3,"m04","ctgA",33324,35791]],"prefix":[]}} \ No newline at end of file diff --git a/tests/data/volvox_formatted_names/names/8.json b/tests/data/volvox_formatted_names/names/8.json new file mode 100644 index 0000000000..95231cdb17 --- /dev/null +++ b/tests/data/volvox_formatted_names/names/8.json @@ -0,0 +1 @@ +{"seg10":{"exact":[["seg10",4,"seg10","ctgA",29770,29942],["seg10",4,"seg10","ctgA",30041,30340],["seg10",4,"seg10","ctgA",30809,31307],["seg10",4,"seg10","ctgA",31760,31984],["seg10",4,"seg10","ctgA",32373,32937]],"prefix":[]},"m":{"exact":[],"prefix":["m15","m05","m02","m12","m03","m13","m14","m04","m01","m11","m09","m06","m08","m07","m10"]},"m01":{"exact":[["m01",3,"m01","ctgA",48252,48366]],"prefix":[]},"f11":{"exact":[["f11",0,"f11","ctgA",46989,48410]],"prefix":[]},"ge":{"exact":[],"prefix":["Gene:hgb","Gene:hga"]}} \ No newline at end of file diff --git a/tests/data/volvox_formatted_names/names/9.json b/tests/data/volvox_formatted_names/names/9.json new file mode 100644 index 0000000000..e1510aa312 --- /dev/null +++ b/tests/data/volvox_formatted_names/names/9.json @@ -0,0 +1 @@ +{"remark":{"exact":[],"prefix":["Remark:hga"]},"agt830.":{"exact":[],"prefix":["agt830.3","agt830.5"]},"eden.":{"exact":[],"prefix":["EDEN.2","EDEN.3","EDEN.1"]},"apple2":{"exact":[["Apple2",6,"Apple2","ctgA",12999,17200],["Apple2",7,"Apple2","ctgA",12999,17200]],"prefix":[]},"seg0":{"exact":[],"prefix":["seg04","seg03","seg02","seg05","seg07","seg08","seg06","seg09","seg01"]},"m11":{"exact":[["m11",3,"m11","ctgA",11910,15561]],"prefix":[]},"b":{"exact":[],"prefix":["b101.2"]},"pr":{"exact":[],"prefix":["Protein:HGB","Protein:HGA"]},"m0":{"exact":[],"prefix":["m05","m02","m03","m04","m01","m09","m06","m08","m07"]},"b101.":{"exact":[],"prefix":["b101.2"]},"f01":{"exact":[["f01",0,"f01","ctgA",44704,47713]],"prefix":[]}} \ No newline at end of file diff --git a/tests/data/volvox_formatted_names/names/a.json b/tests/data/volvox_formatted_names/names/a.json new file mode 100644 index 0000000000..0facca0512 --- /dev/null +++ b/tests/data/volvox_formatted_names/names/a.json @@ -0,0 +1 @@ +{"e":{"exact":[],"prefix":["EDEN.2","EDEN.3","EDEN.1","EDEN"]},"fakesn":{"exact":[],"prefix":["FakeSNP"]},"seg07":{"exact":[["seg07",4,"seg07","ctgA",44190,44514],["seg07",4,"seg07","ctgA",44551,45043],["seg07",4,"seg07","ctgA",45372,45600],["seg07",4,"seg07","ctgA",45896,46315],["seg07",4,"seg07","ctgA",46490,46890],["seg07",4,"seg07","ctgA",47125,47297],["seg07",4,"seg07","ctgA",47734,47983],["seg07",4,"seg07","ctgA",48446,48709],["seg07",4,"seg07","ctgA",48930,49186],["seg07",4,"seg07","ctgA",49471,49699],["seg07",4,"seg07","ctgA",49956,50000]],"prefix":[]},"f06":{"exact":[["f06",0,"f06","ctgB",3013,6130],["f06",0,"f06","ctgA",3013,6130]],"prefix":[]},"eden.1":{"exact":[["EDEN.1",6,"EDEN.1","ctgA",1049,9000]],"prefix":[]},"remark:h":{"exact":[],"prefix":["Remark:hga"]},"protei":{"exact":[],"prefix":["Protein:HGB","Protein:HGA"]},"protein:hga":{"exact":[["Protein:HGA",1,"Protein:HGA","ctgA",1199,1900]],"prefix":[]},"m09":{"exact":[["m09",3,"m09","ctgA",46011,48851]],"prefix":[]},"b101":{"exact":[],"prefix":["b101.2"]},"gen":{"exact":[],"prefix":["Gene:hgb","Gene:hga"]}} \ No newline at end of file diff --git a/tests/data/volvox_formatted_names/names/b.json b/tests/data/volvox_formatted_names/names/b.json new file mode 100644 index 0000000000..3470ee9fd2 --- /dev/null +++ b/tests/data/volvox_formatted_names/names/b.json @@ -0,0 +1 @@ +{"m06":{"exact":[["m06",3,"m06","ctgA",30577,31748]],"prefix":[]},"gene:":{"exact":[],"prefix":["Gene:hgb","Gene:hga"]},"seg08":{"exact":[["seg08",4,"seg08","ctgA",18508,18985],["seg08",4,"seg08","ctgA",18988,19388],["seg08",4,"seg08","ctgA",19495,19962],["seg08",4,"seg08","ctgA",20092,20580],["seg08",4,"seg08","ctgA",20969,21052],["seg08",4,"seg08","ctgA",21269,21277],["seg08",4,"seg08","ctgA",21684,22168],["seg08",4,"seg08","ctgA",22563,22869],["seg08",4,"seg08","ctgA",22957,23298],["seg08",4,"seg08","ctgA",23411,23469],["seg08",4,"seg08","ctgA",23931,23932],["seg08",4,"seg08","ctgA",24327,24787],["seg08",4,"seg08","ctgA",25227,25367]],"prefix":[]},"agt83":{"exact":[],"prefix":["agt830.3","agt830.5"]},"agt76":{"exact":[],"prefix":["agt767.5","agt767.3"]},"ctgA":{"exact":[[50001,"ctgA",null,0,50001,20000]],"prefix":[]},"hg":{"exact":[],"prefix":["hga","hgb"]},"s":{"exact":[],"prefix":["seg04","seg14","seg13","seg03","seg12","seg02","seg05","seg15","seg10","seg07","seg08","seg06","seg09","seg11","seg01"]},"f09":{"exact":[["f09",0,"f09","ctgA",36033,38167]],"prefix":[]},"agt221.":{"exact":[],"prefix":["agt221.3","agt221.5"]},"rem":{"exact":[],"prefix":["Remark:hga"]}} \ No newline at end of file diff --git a/tests/data/volvox_formatted_names/names/c.json b/tests/data/volvox_formatted_names/names/c.json new file mode 100644 index 0000000000..8a357bd16c --- /dev/null +++ b/tests/data/volvox_formatted_names/names/c.json @@ -0,0 +1 @@ +{"m08":{"exact":[["m08",3,"m08","ctgA",17022,17675]],"prefix":[]},"ed":{"exact":[],"prefix":["EDEN.2","EDEN.3","EDEN.1","EDEN"]},"eden":{"exact":[["EDEN",5,"EDEN","ctgA",1049,9000]],"prefix":["EDEN.2","EDEN.3","EDEN.1"]},"re":{"exact":[],"prefix":["Remark:hga"]},"seg06":{"exact":[["seg06",4,"seg06","ctgA",19248,19559],["seg06",4,"seg06","ctgA",19974,20260],["seg06",4,"seg06","ctgA",20378,20491],["seg06",4,"seg06","ctgA",20532,21005],["seg06",4,"seg06","ctgA",21121,21331],["seg06",4,"seg06","ctgA",21681,22176],["seg06",4,"seg06","ctgA",22373,22570],["seg06",4,"seg06","ctgA",23024,23427]],"prefix":[]},"f07":{"exact":[["f07",0,"f07","ctgB",1658,1984],["f07",0,"f07","ctgA",1658,1984]],"prefix":[]}} \ No newline at end of file diff --git a/tests/data/volvox_formatted_names/names/d.json b/tests/data/volvox_formatted_names/names/d.json new file mode 100644 index 0000000000..9108c1fb15 --- /dev/null +++ b/tests/data/volvox_formatted_names/names/d.json @@ -0,0 +1 @@ +{"m07":{"exact":[["m07",3,"m07","ctgA",18047,18552]],"prefix":[]},"r":{"exact":[],"prefix":["Remark:hga"]},"f08":{"exact":[["f08",0,"f08","ctgA",13279,16394]],"prefix":[]},"gene:hga":{"exact":[["Gene:hga",1,"Gene:hga","ctgA",1099,2000]],"prefix":[]},"seg09":{"exact":[["seg09",4,"seg09","ctgA",36615,37057],["seg09",4,"seg09","ctgA",37207,37227]],"prefix":[]},"se":{"exact":[],"prefix":["seg04","seg14","seg13","seg03","seg12","seg02","seg05","seg15","seg10","seg07","seg08","seg06","seg09","seg11","seg01"]},"ede":{"exact":[],"prefix":["EDEN.2","EDEN.3","EDEN.1","EDEN"]},"prote":{"exact":[],"prefix":["Protein:HGB","Protein:HGA"]},"agt2":{"exact":[],"prefix":["agt221.3","agt221.5"]}} \ No newline at end of file diff --git a/tests/data/volvox_formatted_names/names/e.json b/tests/data/volvox_formatted_names/names/e.json new file mode 100644 index 0000000000..f8fdf090c9 --- /dev/null +++ b/tests/data/volvox_formatted_names/names/e.json @@ -0,0 +1 @@ +{"b101.2":{"exact":[["b101.2",9,"b101.2","ctgA",999,20000]],"prefix":[]},"hgb":{"exact":[["hgb",1,"Gene:hgb","ctgA",1599,3000],["hgb",1,"Protein:HGB","ctgA",1799,2900]],"prefix":[]},"agt830":{"exact":[],"prefix":["agt830.3","agt830.5"]},"f10":{"exact":[["f10",0,"f10","ctgA",15328,15533]],"prefix":[]},"protein:":{"exact":[],"prefix":["Protein:HGB","Protein:HGA"]},"seg11":{"exact":[["seg11",4,"seg11","ctgA",24227,24510],["seg11",4,"seg11","ctgA",24867,25012],["seg11",4,"seg11","ctgA",25211,25426],["seg11",4,"seg11","ctgA",25793,25874],["seg11",4,"seg11","ctgA",26074,26519],["seg11",4,"seg11","ctgA",26929,26940],["seg11",4,"seg11","ctgA",26974,27063],["seg11",4,"seg11","ctgA",27414,27799],["seg11",4,"seg11","ctgA",27879,27943],["seg11",4,"seg11","ctgA",28224,28346],["seg11",4,"seg11","ctgA",28374,28570],["seg11",4,"seg11","ctgA",28757,29041],["seg11",4,"seg11","ctgA",29100,29302],["seg11",4,"seg11","ctgA",29603,29702],["seg11",4,"seg11","ctgA",29866,29885],["seg11",4,"seg11","ctgA",30240,30246],["seg11",4,"seg11","ctgA",30574,30738]],"prefix":[]},"ct":{"exact":[],"prefix":["6079","50001"]}} \ No newline at end of file diff --git a/tests/data/volvox_formatted_names/names/f.json b/tests/data/volvox_formatted_names/names/f.json new file mode 100644 index 0000000000..0cc287fe55 --- /dev/null +++ b/tests/data/volvox_formatted_names/names/f.json @@ -0,0 +1 @@ +{"pro":{"exact":[],"prefix":["Protein:HGB","Protein:HGA"]},"app":{"exact":[],"prefix":["Apple1","Apple2","Apple3"]},"seg01":{"exact":[["seg01",4,"seg01","ctgA",32328,32359]],"prefix":[]},"remark:":{"exact":[],"prefix":["Remark:hga"]},"seg1":{"exact":[],"prefix":["seg14","seg13","seg12","seg15","seg10","seg11"]},"agt221":{"exact":[],"prefix":["agt221.3","agt221.5"]},"c":{"exact":[],"prefix":["6079","50001"]},"appl":{"exact":[],"prefix":["Apple1","Apple2","Apple3"]},"m1":{"exact":[],"prefix":["m15","m12","m13","m14","m11","m10"]},"apple3":{"exact":[["Apple3",6,"Apple3","ctgA",17399,23000],["Apple3",7,"Apple3","ctgA",17399,23000],["Apple3",8,"Apple3","ctgA",17399,23000]],"prefix":[]},"fakesnp":{"exact":[["FakeSNP",2,"FakeSNP","ctgA",999,1000]],"prefix":[]},"fake":{"exact":[],"prefix":["FakeSNP"]},"m10":{"exact":[["m10",3,"m10","ctgA",28341,28447]],"prefix":[]}} \ No newline at end of file diff --git a/tests/data/volvox_formatted_names/names/meta.json b/tests/data/volvox_formatted_names/names/meta.json new file mode 100644 index 0000000000..10d2afaef8 --- /dev/null +++ b/tests/data/volvox_formatted_names/names/meta.json @@ -0,0 +1 @@ +{"lowercase_keys":1,"track_names":["ExampleFeatures","NameTest","snps","Motifs","Alignments","Genes","ReadingFrame","CDS","Transcript","Clones","EST"],"hash_bits":"4","last_changed_entry":"apple3"} \ No newline at end of file diff --git a/tests/data/volvox_formatted_names/names/root.json b/tests/data/volvox_formatted_names/names/root.json deleted file mode 100644 index 9bc33f0cd0..0000000000 --- a/tests/data/volvox_formatted_names/names/root.json +++ /dev/null @@ -1 +0,0 @@ -[["ExampleFeatures","NameTest","snps","Motifs","Alignments","Genes","ReadingFrame","CDS","Transcript","Clones","EST"],null,["a",null,["gt",null,["221.",null,["3",[["agt221.3",10,"agt221.3","ctgA",7499,8000,null]]],["5",[["agt221.5",10,"agt221.5","ctgA",1049,7300,null]]]],["767.",null,["3",[["agt767.3",10,"agt767.3","ctgA",7999,9000,null]]],["5",[["agt767.5",10,"agt767.5","ctgA",1149,7200,null]]]],["830.",null,["3",[["agt830.3",10,"agt830.3","ctgA",5409,7503,null]]],["5",[["agt830.5",10,"agt830.5","ctgA",1049,3202,null]]]]],["pple",null,["1",[["Apple1",7,"Apple1","ctgA",9999,11500,null]]],["2",[["Apple2",6,"Apple2","ctgA",12999,17200,null],["Apple2",7,"Apple2","ctgA",12999,17200,null]]],["3",[["Apple3",6,"Apple3","ctgA",17399,23000,null],["Apple3",7,"Apple3","ctgA",17399,23000,null],["Apple3",8,"Apple3","ctgA",17399,23000,null]]]]],["b101.2",[["b101.2",9,"b101.2","ctgA",999,20000,null]]],["ctg",null,["a",[["ctgA",50001,"ctgA","seq/ctgA",0,50001,20000]]],["b",[["ctgB",6079,"ctgB","seq/ctgB",0,6079,20000]]]],["eden",[["EDEN",5,"EDEN","ctgA",1049,9000,null]],[".",null,["1",[["EDEN.1",6,"EDEN.1","ctgA",1049,9000,null]]],["2",[["EDEN.2",6,"EDEN.2","ctgA",1049,9000,null]]],["3",[["EDEN.3",6,"EDEN.3","ctgA",1299,9000,null]]]]],["f",null,["0",null,["1",[["f01",0,"f01","ctgA",44704,47713,null]]],["2",[["f02",0,"f02","ctgA",24561,28338,null]]],["3",[["f03",0,"f03","ctgA",36648,40440,null]]],["4",[["f04",0,"f04","ctgA",37241,38653,null]]],["5",[["f05",0,"f05","ctgB",4714,5968,null],["f05",0,"f05","ctgA",4714,5968,null]]],["6",[["f06",0,"f06","ctgB",3013,6130,null],["f06",0,"f06","ctgA",3013,6130,null]]],["7",[["f07",0,"f07","ctgB",1658,1984,null],["f07",0,"f07","ctgA",1658,1984,null]]],["8",[["f08",0,"f08","ctgA",13279,16394,null]]],["9",[["f09",0,"f09","ctgA",36033,38167,null]]]],["1",null,["0",[["f10",0,"f10","ctgA",15328,15533,null]]],["1",[["f11",0,"f11","ctgA",46989,48410,null]]],["2",[["f12",0,"f12","ctgA",49757,50000,null]]],["3",[["f13",0,"f13","ctgA",19156,22915,null]]],["4",[["f14",0,"f14","ctgA",23071,23185,null]]],["5",[["f15",0,"f15","ctgA",22131,24633,null]]]],["akesnp",[["FakeSNP",2,"FakeSNP","ctgA",999,1000,null]]]],["gene:hg",null,["a",[["Gene:hga",1,"Gene:hga","ctgA",1099,2000,null]]],["b",[["Gene:hgb",1,"Gene:hgb","ctgA",1599,3000,null]]]],["hg",null,["a",[["hga",0,"Remark:hga","ctgA",999,2000,null],["hga",1,"Gene:hga","ctgA",1099,2000,null],["hga",1,"Protein:HGA","ctgA",1199,1900,null]]],["b",[["hgb",1,"Gene:hgb","ctgA",1599,3000,null],["hgb",1,"Protein:HGB","ctgA",1799,2900,null]]]],["m",null,["0",null,["1",[["m01",3,"m01","ctgA",48252,48366,null]]],["2",[["m02",3,"m02","ctgA",28331,30033,null]]],["3",[["m03",3,"m03","ctgA",15395,16159,null]]],["4",[["m04",3,"m04","ctgA",33324,35791,null]]],["5",[["m05",3,"m05","ctgA",13800,14007,null]]],["6",[["m06",3,"m06","ctgA",30577,31748,null]]],["7",[["m07",3,"m07","ctgA",18047,18552,null]]],["8",[["m08",3,"m08","ctgA",17022,17675,null]]],["9",[["m09",3,"m09","ctgA",46011,48851,null]]]],["1",null,["0",[["m10",3,"m10","ctgA",28341,28447,null]]],["1",[["m11",3,"m11","ctgA",11910,15561,null]]],["2",[["m12",3,"m12","ctgA",21747,25612,null]]],["3",[["m13",3,"m13","ctgA",17666,17690,null]]],["4",[["m14",3,"m14","ctgA",14730,17239,null]]],["5",[["m15",3,"m15","ctgA",37496,40559,null]]]]],["protein:hg",null,["a",[["Protein:HGA",1,"Protein:HGA","ctgA",1199,1900,null]]],["b",[["Protein:HGB",1,"Protein:HGB","ctgA",1799,2900,null]]]],["remark:hga",[["Remark:hga",0,"Remark:hga","ctgA",999,2000,null]]],["seg",null,["0",null,["1",[["seg01",4,"seg01","ctgA",32328,32359,null]]],["2",[["seg02",4,"seg02","ctgA",26121,26126,null],["seg02",4,"seg02","ctgA",26496,26869,null],["seg02",4,"seg02","ctgA",27200,27325,null],["seg02",4,"seg02","ctgA",27371,27433,null],["seg02",4,"seg02","ctgA",27564,27565,null],["seg02",4,"seg02","ctgA",27812,28091,null],["seg02",4,"seg02","ctgA",28092,28201,null],["seg02",4,"seg02","ctgA",28328,28377,null],["seg02",4,"seg02","ctgA",28828,29194,null],["seg02",4,"seg02","ctgA",29516,29702,null],["seg02",4,"seg02","ctgA",29712,30061,null],["seg02",4,"seg02","ctgA",30328,30774,null],["seg02",4,"seg02","ctgA",30807,31306,null],["seg02",4,"seg02","ctgA",31515,31729,null],["seg02",4,"seg02","ctgA",31752,32154,null],["seg02",4,"seg02","ctgA",32594,32696,null],["seg02",4,"seg02","ctgA",32891,32901,null],["seg02",4,"seg02","ctgA",33126,33388,null],["seg02",4,"seg02","ctgA",33438,33443,null],["seg02",4,"seg02","ctgA",33758,34209,null],["seg02",4,"seg02","ctgA",34400,34466,null]]],["3",[["seg03",4,"seg03","ctgA",6884,7241,null],["seg03",4,"seg03","ctgA",7409,7737,null],["seg03",4,"seg03","ctgA",8054,8080,null],["seg03",4,"seg03","ctgA",8305,8999,null]]],["4",[["seg04",4,"seg04","ctgA",5232,5302,null],["seg04",4,"seg04","ctgA",5799,6101,null],["seg04",4,"seg04","ctgA",6441,6854,null],["seg04",4,"seg04","ctgA",7105,7211,null],["seg04",4,"seg04","ctgA",7694,8177,null],["seg04",4,"seg04","ctgA",8544,8783,null],["seg04",4,"seg04","ctgA",8868,8935,null],["seg04",4,"seg04","ctgA",9403,9825,null]]],["5",[["seg05",4,"seg05","ctgA",26502,26799,null],["seg05",4,"seg05","ctgA",27171,27185,null],["seg05",4,"seg05","ctgA",27447,27860,null],["seg05",4,"seg05","ctgA",27886,28076,null],["seg05",4,"seg05","ctgA",28224,28316,null],["seg05",4,"seg05","ctgA",28776,29058,null],["seg05",4,"seg05","ctgA",29512,29647,null],["seg05",4,"seg05","ctgA",30107,30216,null],["seg05",4,"seg05","ctgA",30464,30798,null],["seg05",4,"seg05","ctgA",31231,31236,null],["seg05",4,"seg05","ctgA",31420,31817,null],["seg05",4,"seg05","ctgA",32009,32057,null],["seg05",4,"seg05","ctgA",32207,32680,null],["seg05",4,"seg05","ctgA",33052,33325,null],["seg05",4,"seg05","ctgA",33437,33868,null],["seg05",4,"seg05","ctgA",34243,34313,null],["seg05",4,"seg05","ctgA",34604,34983,null],["seg05",4,"seg05","ctgA",35332,35507,null],["seg05",4,"seg05","ctgA",35641,35904,null]]],["6",[["seg06",4,"seg06","ctgA",19248,19559,null],["seg06",4,"seg06","ctgA",19974,20260,null],["seg06",4,"seg06","ctgA",20378,20491,null],["seg06",4,"seg06","ctgA",20532,21005,null],["seg06",4,"seg06","ctgA",21121,21331,null],["seg06",4,"seg06","ctgA",21681,22176,null],["seg06",4,"seg06","ctgA",22373,22570,null],["seg06",4,"seg06","ctgA",23024,23427,null]]],["7",[["seg07",4,"seg07","ctgA",44190,44514,null],["seg07",4,"seg07","ctgA",44551,45043,null],["seg07",4,"seg07","ctgA",45372,45600,null],["seg07",4,"seg07","ctgA",45896,46315,null],["seg07",4,"seg07","ctgA",46490,46890,null],["seg07",4,"seg07","ctgA",47125,47297,null],["seg07",4,"seg07","ctgA",47734,47983,null],["seg07",4,"seg07","ctgA",48446,48709,null],["seg07",4,"seg07","ctgA",48930,49186,null],["seg07",4,"seg07","ctgA",49471,49699,null],["seg07",4,"seg07","ctgA",49956,50000,null]]],["8",[["seg08",4,"seg08","ctgA",18508,18985,null],["seg08",4,"seg08","ctgA",18988,19388,null],["seg08",4,"seg08","ctgA",19495,19962,null],["seg08",4,"seg08","ctgA",20092,20580,null],["seg08",4,"seg08","ctgA",20969,21052,null],["seg08",4,"seg08","ctgA",21269,21277,null],["seg08",4,"seg08","ctgA",21684,22168,null],["seg08",4,"seg08","ctgA",22563,22869,null],["seg08",4,"seg08","ctgA",22957,23298,null],["seg08",4,"seg08","ctgA",23411,23469,null],["seg08",4,"seg08","ctgA",23931,23932,null],["seg08",4,"seg08","ctgA",24327,24787,null],["seg08",4,"seg08","ctgA",25227,25367,null]]],["9",[["seg09",4,"seg09","ctgA",36615,37057,null],["seg09",4,"seg09","ctgA",37207,37227,null]]]],["1",null,["0",[["seg10",4,"seg10","ctgA",29770,29942,null],["seg10",4,"seg10","ctgA",30041,30340,null],["seg10",4,"seg10","ctgA",30809,31307,null],["seg10",4,"seg10","ctgA",31760,31984,null],["seg10",4,"seg10","ctgA",32373,32937,null]]],["1",[["seg11",4,"seg11","ctgA",24227,24510,null],["seg11",4,"seg11","ctgA",24867,25012,null],["seg11",4,"seg11","ctgA",25211,25426,null],["seg11",4,"seg11","ctgA",25793,25874,null],["seg11",4,"seg11","ctgA",26074,26519,null],["seg11",4,"seg11","ctgA",26929,26940,null],["seg11",4,"seg11","ctgA",26974,27063,null],["seg11",4,"seg11","ctgA",27414,27799,null],["seg11",4,"seg11","ctgA",27879,27943,null],["seg11",4,"seg11","ctgA",28224,28346,null],["seg11",4,"seg11","ctgA",28374,28570,null],["seg11",4,"seg11","ctgA",28757,29041,null],["seg11",4,"seg11","ctgA",29100,29302,null],["seg11",4,"seg11","ctgA",29603,29702,null],["seg11",4,"seg11","ctgA",29866,29885,null],["seg11",4,"seg11","ctgA",30240,30246,null],["seg11",4,"seg11","ctgA",30574,30738,null]]],["2",[["seg12",4,"seg12","ctgA",12530,12895,null],["seg12",4,"seg12","ctgA",13121,13449,null],["seg12",4,"seg12","ctgA",13451,13745,null],["seg12",4,"seg12","ctgA",13907,13965,null],["seg12",4,"seg12","ctgA",13997,14488,null],["seg12",4,"seg12","ctgA",14563,14899,null],["seg12",4,"seg12","ctgA",15184,15276,null],["seg12",4,"seg12","ctgA",15638,15736,null],["seg12",4,"seg12","ctgA",15744,15870,null]]],["3",[["seg13",4,"seg13","ctgA",49405,49476,null],["seg13",4,"seg13","ctgA",49761,50000,null]]],["4",[["seg14",4,"seg14","ctgA",41136,41318,null],["seg14",4,"seg14","ctgA",41753,41948,null],["seg14",4,"seg14","ctgA",42056,42474,null],["seg14",4,"seg14","ctgA",42889,43270,null],["seg14",4,"seg14","ctgA",43394,43811,null],["seg14",4,"seg14","ctgA",44064,44556,null],["seg14",4,"seg14","ctgA",44762,45030,null],["seg14",4,"seg14","ctgA",45230,45488,null],["seg14",4,"seg14","ctgA",45789,46022,null],["seg14",4,"seg14","ctgA",46091,46318,null],["seg14",4,"seg14","ctgA",46815,46992,null],["seg14",4,"seg14","ctgA",47448,47829,null]]],["5",[["seg15",4,"seg15","ctgA",39264,39361,null],["seg15",4,"seg15","ctgA",39752,40034,null],["seg15",4,"seg15","ctgA",40514,40954,null],["seg15",4,"seg15","ctgA",41251,41365,null],["seg15",4,"seg15","ctgA",41491,41504,null],["seg15",4,"seg15","ctgA",41940,42377,null],["seg15",4,"seg15","ctgA",42747,42954,null],["seg15",4,"seg15","ctgA",43400,43897,null],["seg15",4,"seg15","ctgA",44042,44113,null],["seg15",4,"seg15","ctgA",44398,44888,null],["seg15",4,"seg15","ctgA",45280,45375,null],["seg15",4,"seg15","ctgA",45710,46041,null],["seg15",4,"seg15","ctgA",46424,46564,null],["seg15",4,"seg15","ctgA",46737,47087,null],["seg15",4,"seg15","ctgA",47328,47595,null],["seg15",4,"seg15","ctgA",47857,47979,null],["seg15",4,"seg15","ctgA",48168,48453,null]]]]]] \ No newline at end of file diff --git a/tests/data/volvox_formatted_names/seq/refSeqs.json b/tests/data/volvox_formatted_names/seq/refSeqs.json index d81f682315..ad615488d3 100644 --- a/tests/data/volvox_formatted_names/seq/refSeqs.json +++ b/tests/data/volvox_formatted_names/seq/refSeqs.json @@ -1 +1 @@ -[{"length":6079,"name":"ctgB","seqDir":"seq/ctgB","seqChunkSize":20000,"end":6079,"start":0},{"length":50001,"name":"ctgA","seqDir":"seq/ctgA","seqChunkSize":20000,"end":50001,"start":0}] \ No newline at end of file +[{"length":6079,"name":"ctgB","seqChunkSize":20000,"end":6079,"start":0},{"length":50001,"name":"ctgA","seqChunkSize":20000,"end":50001,"start":0}] \ No newline at end of file diff --git a/tests/data/volvox_formatted_names/trackList.json b/tests/data/volvox_formatted_names/trackList.json index e4dc083af4..7709170c81 100644 --- a/tests/data/volvox_formatted_names/trackList.json +++ b/tests/data/volvox_formatted_names/trackList.json @@ -2,9 +2,9 @@ "tracks" : [ { "chunkSize" : 20000, - "urlTemplate" : "seq/{refseq}/", - "label" : "DNA", + "urlTemplate" : "seq/{refseq_dirpath}/{refseq}-", "type" : "SequenceTrack", + "label" : "DNA", "key" : "DNA" }, { @@ -66,8 +66,8 @@ ], "urlTemplate" : "tracks/Motifs/{refseq}/trackData.json", "compress" : 0, - "label" : "Motifs", - "type" : "FeatureTrack" + "type" : "FeatureTrack", + "label" : "Motifs" }, { "autocomplete" : "all", @@ -75,20 +75,15 @@ "style" : { "className" : "feature4" }, - "hooks" : { - "modify" : "function( track, feature, div ) { div.style.height = (Math.random()*10+8)+'px'; div.style.backgroundColor = ['green','blue','red','orange','purple'][Math.round(Math.random()*5)];}" - }, "menuTemplate" : [ { - "label" : "Item with submenu", "children" : [ { - "label" : "Check gene on databases", "children" : [ { "iconClass" : "dijitIconBookmark", - "action" : "newWindow", "url" : "http://wiki.trin.org.au/{name}-{start}-{end}", + "action" : "newWindow", "label" : "Query trin for {name}" }, { @@ -96,7 +91,8 @@ "url" : "http://example.com/{name}-{start}-{end}", "label" : "Query example.com for {name}" } - ] + ], + "label" : "Check gene on databases" }, { "label" : "2nd child of demo" @@ -104,35 +100,36 @@ { "label" : "3rd child: this is a track" } - ] + ], + "label" : "Item with submenu" }, { "iconClass" : "dijitIconDatabase", - "action" : "iframeDialog", "url" : "http://www.example.com?featurename={name}", - "label" : "Open example.com in an iframe popup", - "title" : "The magnificent example.com (feature {name})" + "action" : "iframeDialog", + "title" : "The magnificent example.com (feature {name})", + "label" : "Open example.com in an iframe popup" }, { "iconClass" : "dijitIconDatabase", - "action" : "xhrDialog", "url" : "sample_data/test_snippet.html?featurename={name}:{start}-{end}", - "label" : "Open popup with XHR HTML snippet (btw this is feature {name})", - "title" : "function(track,feature,div) { return 'Random XHR HTML '+Math.random()+' title!'; }" + "action" : "xhrDialog", + "title" : "function(track,feature,div) { return 'Random XHR HTML '+Math.random()+' title!'; }", + "label" : "Open popup with XHR HTML snippet (btw this is feature {name})" }, { "iconClass" : "dijitIconDatabase", - "action" : "contentDialog", "content" : "function(track,feature,div) { return '

'+feature.get('name')+'

This is some test content!

This message brought to you by the number '+Math.round(Math.random()*100)+'.

';} ", - "label" : "Popup with content snippet from a function (feature {name})", - "title" : "function(track,feature,div) { return 'Random content snippet '+Math.random()+' title!'; }" + "action" : "contentDialog", + "title" : "function(track,feature,div) { return 'Random content snippet '+Math.random()+' title!'; }", + "label" : "Popup with content snippet from a function (feature {name})" }, { "iconClass" : "dijitIconDatabase", - "action" : "contentDialog", "content" : "

{name}

This is some test content about {name}, which goes from {start} to {end} on the {strand} strand.

", - "label" : "Popup with content snippet from string (feature {name})", - "title" : "function(track,feature,div) { return 'Random content snippet '+Math.random()+' title!'; }" + "action" : "contentDialog", + "title" : "function(track,feature,div) { return 'Random content snippet '+Math.random()+' title!'; }", + "label" : "Popup with content snippet from string (feature {name})" }, { "iconClass" : "dijitIconDatabase", @@ -140,15 +137,18 @@ "label" : "function(track,feature,div) { return 'Run a JS callback '+Math.random()+' title!'; }" } ], + "hooks" : { + "modify" : "function( track, feature, div ) { div.style.height = (Math.random()*10+8)+'px'; div.style.backgroundColor = ['green','blue','red','orange','purple'][Math.round(Math.random()*5)];}" + }, "key" : "Example alignments", "feature" : [ "match" ], "urlTemplate" : "tracks/Alignments/{refseq}/trackData.json", "compress" : 0, - "type" : "FeatureTrack", + "category" : "Alignments", "label" : "Alignments", - "category" : "Alignments" + "type" : "FeatureTrack" }, { "autocomplete" : "all", @@ -156,15 +156,15 @@ "style" : { "className" : "feature5" }, - "key" : "Protein-coding genes", "onClick" : "http://www.ncbi.nlm.nih.gov/gquery/?term={name}", + "key" : "Protein-coding genes", "feature" : [ "gene" ], "urlTemplate" : "tracks/Genes/{refseq}/trackData.json", "compress" : 0, - "label" : "Genes", - "type" : "FeatureTrack" + "type" : "FeatureTrack", + "label" : "Genes" }, { "autocomplete" : "all", @@ -172,19 +172,19 @@ "style" : { "className" : "dblhelix" }, + "key" : "Frame usage", "onClick" : { "url" : "http://www.ncbi.nlm.nih.gov/gquery/?term={name}", "label" : "search at NCBI" }, - "key" : "Frame usage", "feature" : [ "mRNA" ], "urlTemplate" : "tracks/ReadingFrame/{refseq}/trackData.json", "compress" : 0, - "type" : "FeatureTrack", + "category" : "Genes", "label" : "ReadingFrame", - "category" : "Genes" + "type" : "FeatureTrack" }, { "autocomplete" : "all", @@ -202,9 +202,9 @@ "urlTemplate" : "tracks/CDS/{refseq}/trackData.json", "phase" : 1, "compress" : 0, - "category" : "Genes", + "type" : "FeatureTrack", "label" : "CDS", - "type" : "FeatureTrack" + "category" : "Genes" }, { "autocomplete" : "all", @@ -218,16 +218,16 @@ "arrowheadClass" : "transcript-arrowhead" }, "description" : 1, - "onClick" : "function() { alert('Ran arbitrary JavaScript!'); };", "key" : "Exonerate predictions", + "onClick" : "function() { alert('This is a user-configurable JavaScript action!'); };", "feature" : [ "mRNA:exonerate" ], "urlTemplate" : "tracks/Transcript/{refseq}/trackData.json", "compress" : 0, - "type" : "FeatureTrack", - "label" : "Transcript", "category" : "Genes", + "label" : "Transcript", + "type" : "FeatureTrack", "subfeatures" : true }, { @@ -243,8 +243,8 @@ ], "urlTemplate" : "tracks/Clones/{refseq}/trackData.json", "compress" : 0, - "label" : "Clones", - "type" : "FeatureTrack" + "type" : "FeatureTrack", + "label" : "Clones" }, { "autocomplete" : "all", @@ -264,33 +264,85 @@ { "storeClass" : "JBrowse/Store/BigWig", "urlTemplate" : "../../raw/volvox/volvox_microarray.bw", - "type" : "JBrowse/View/Track/Wiggle", - "label" : "volvox_microarray.bw", - "key" : "volvox_microarray.bw" + "type" : "JBrowse/View/Track/Wiggle/Density", + "label" : "volvox_microarray.bw_density", + "bicolor_pivot" : "mean", + "key" : "BigWig Density - volvox_microarray" + }, + { + "storeClass" : "JBrowse/Store/BigWig", + "urlTemplate" : "../../raw/volvox/volvox_microarray.bw", + "type" : "JBrowse/View/Track/Wiggle/XYPlot", + "label" : "volvox_microarray.bw_xyplot", + "variance_band" : "true", + "key" : "BigWig XY - volvox_microarray" + }, + { + "storeClass" : "JBrowse/Store/BigWig", + "urlTemplate" : "../../raw/volvox/volvox_sine.bw", + "label" : "volvox_sine_density", + "type" : "JBrowse/View/Track/Wiggle/Density", + "bicolor_pivot" : "mean", + "key" : "BigWig Density - volvox_sine" + }, + { + "storeClass" : "JBrowse/Store/BigWig", + "urlTemplate" : "../../raw/volvox/volvox_sine.bw", + "style" : { + "bg_color" : "#ccc" + }, + "label" : "volvox_sine_xyplot", + "type" : "JBrowse/View/Track/Wiggle/XYPlot", + "key" : "BigWig XY - volvox_sine" + }, + { + "storeClass" : "JBrowse/Store/SeqFeature/BAM", + "urlTemplate" : "../../raw/volvox/volvox-sorted.bam", + "style" : { + "className" : "alignment", + "arrowheadClass" : "arrowhead", + "labelScale" : 100 + }, + "label" : "volvox-sorted.bam", + "type" : "JBrowse/View/Track/Alignments", + "key" : "volvox-sorted.bam" + }, + { + "storeClass" : "JBrowse/Store/SeqFeature/BAM", + "urlTemplate" : "../../raw/volvox/volvox-sorted.bam", + "max_score" : 35, + "label" : "volvox-sorted.bam_coverage", + "type" : "JBrowse/View/Track/FeatureCoverage", + "min_score" : 0, + "key" : "volvox-sorted Coverage" }, { "urlTemplate" : "tracks/volvox_microarray.wig/{refseq}/trackData.json", - "compress" : 0, "style" : { "className" : "image" }, - "label" : "volvox_microarray.wig", + "compress" : 0, "type" : "ImageTrack.Wiggle", + "label" : "volvox_microarray.wig", "key" : "volvox_microarray.wig" }, { "urlTemplate" : "tracks/bam_simulated/{refseq}/trackData.json", + "compress" : 0, "style" : { "className" : "basic", "histScale" : 2, "featureCss" : "background-color: #66F; height: 8px", "histCss" : "background-color: #88F" }, - "compress" : 0, - "type" : "FeatureTrack", "label" : "bam_simulated", + "type" : "FeatureTrack", "key" : "Simulated next-gen reads" } ], + "names" : { + "url" : "names/", + "type" : "Hash" + }, "formatVersion" : 1 } diff --git a/tests/data/volvox_formatted_names/tracks/Alignments/ctgA/names.json b/tests/data/volvox_formatted_names/tracks/Alignments/ctgA/names.json deleted file mode 100644 index 5d6c0cab49..0000000000 --- a/tests/data/volvox_formatted_names/tracks/Alignments/ctgA/names.json +++ /dev/null @@ -1 +0,0 @@ -[[["seg04"],"Alignments","seg04","ctgA",5232,5302,null],[["seg04"],"Alignments","seg04","ctgA",5799,6101,null],[["seg04"],"Alignments","seg04","ctgA",6441,6854,null],[["seg03"],"Alignments","seg03","ctgA",6884,7241,null],[["seg04"],"Alignments","seg04","ctgA",7105,7211,null],[["seg03"],"Alignments","seg03","ctgA",7409,7737,null],[["seg04"],"Alignments","seg04","ctgA",7694,8177,null],[["seg03"],"Alignments","seg03","ctgA",8054,8080,null],[["seg03"],"Alignments","seg03","ctgA",8305,8999,null],[["seg04"],"Alignments","seg04","ctgA",8544,8783,null],[["seg04"],"Alignments","seg04","ctgA",8868,8935,null],[["seg04"],"Alignments","seg04","ctgA",9403,9825,null],[["seg12"],"Alignments","seg12","ctgA",12530,12895,null],[["seg12"],"Alignments","seg12","ctgA",13121,13449,null],[["seg12"],"Alignments","seg12","ctgA",13451,13745,null],[["seg12"],"Alignments","seg12","ctgA",13907,13965,null],[["seg12"],"Alignments","seg12","ctgA",13997,14488,null],[["seg12"],"Alignments","seg12","ctgA",14563,14899,null],[["seg12"],"Alignments","seg12","ctgA",15184,15276,null],[["seg12"],"Alignments","seg12","ctgA",15638,15736,null],[["seg12"],"Alignments","seg12","ctgA",15744,15870,null],[["seg08"],"Alignments","seg08","ctgA",18508,18985,null],[["seg08"],"Alignments","seg08","ctgA",18988,19388,null],[["seg06"],"Alignments","seg06","ctgA",19248,19559,null],[["seg08"],"Alignments","seg08","ctgA",19495,19962,null],[["seg06"],"Alignments","seg06","ctgA",19974,20260,null],[["seg08"],"Alignments","seg08","ctgA",20092,20580,null],[["seg06"],"Alignments","seg06","ctgA",20378,20491,null],[["seg06"],"Alignments","seg06","ctgA",20532,21005,null],[["seg08"],"Alignments","seg08","ctgA",20969,21052,null],[["seg06"],"Alignments","seg06","ctgA",21121,21331,null],[["seg08"],"Alignments","seg08","ctgA",21269,21277,null],[["seg06"],"Alignments","seg06","ctgA",21681,22176,null],[["seg08"],"Alignments","seg08","ctgA",21684,22168,null],[["seg06"],"Alignments","seg06","ctgA",22373,22570,null],[["seg08"],"Alignments","seg08","ctgA",22563,22869,null],[["seg08"],"Alignments","seg08","ctgA",22957,23298,null],[["seg06"],"Alignments","seg06","ctgA",23024,23427,null],[["seg08"],"Alignments","seg08","ctgA",23411,23469,null],[["seg08"],"Alignments","seg08","ctgA",23931,23932,null],[["seg11"],"Alignments","seg11","ctgA",24227,24510,null],[["seg08"],"Alignments","seg08","ctgA",24327,24787,null],[["seg11"],"Alignments","seg11","ctgA",24867,25012,null],[["seg11"],"Alignments","seg11","ctgA",25211,25426,null],[["seg08"],"Alignments","seg08","ctgA",25227,25367,null],[["seg11"],"Alignments","seg11","ctgA",25793,25874,null],[["seg11"],"Alignments","seg11","ctgA",26074,26519,null],[["seg02"],"Alignments","seg02","ctgA",26121,26126,null],[["seg02"],"Alignments","seg02","ctgA",26496,26869,null],[["seg05"],"Alignments","seg05","ctgA",26502,26799,null],[["seg11"],"Alignments","seg11","ctgA",26929,26940,null],[["seg11"],"Alignments","seg11","ctgA",26974,27063,null],[["seg05"],"Alignments","seg05","ctgA",27171,27185,null],[["seg02"],"Alignments","seg02","ctgA",27200,27325,null],[["seg02"],"Alignments","seg02","ctgA",27371,27433,null],[["seg11"],"Alignments","seg11","ctgA",27414,27799,null],[["seg05"],"Alignments","seg05","ctgA",27447,27860,null],[["seg02"],"Alignments","seg02","ctgA",27564,27565,null],[["seg02"],"Alignments","seg02","ctgA",27812,28091,null],[["seg11"],"Alignments","seg11","ctgA",27879,27943,null],[["seg05"],"Alignments","seg05","ctgA",27886,28076,null],[["seg02"],"Alignments","seg02","ctgA",28092,28201,null],[["seg11"],"Alignments","seg11","ctgA",28224,28346,null],[["seg05"],"Alignments","seg05","ctgA",28224,28316,null],[["seg02"],"Alignments","seg02","ctgA",28328,28377,null],[["seg11"],"Alignments","seg11","ctgA",28374,28570,null],[["seg11"],"Alignments","seg11","ctgA",28757,29041,null],[["seg05"],"Alignments","seg05","ctgA",28776,29058,null],[["seg02"],"Alignments","seg02","ctgA",28828,29194,null],[["seg11"],"Alignments","seg11","ctgA",29100,29302,null],[["seg05"],"Alignments","seg05","ctgA",29512,29647,null],[["seg02"],"Alignments","seg02","ctgA",29516,29702,null],[["seg11"],"Alignments","seg11","ctgA",29603,29702,null],[["seg02"],"Alignments","seg02","ctgA",29712,30061,null],[["seg10"],"Alignments","seg10","ctgA",29770,29942,null],[["seg11"],"Alignments","seg11","ctgA",29866,29885,null],[["seg10"],"Alignments","seg10","ctgA",30041,30340,null],[["seg05"],"Alignments","seg05","ctgA",30107,30216,null],[["seg11"],"Alignments","seg11","ctgA",30240,30246,null],[["seg02"],"Alignments","seg02","ctgA",30328,30774,null],[["seg05"],"Alignments","seg05","ctgA",30464,30798,null],[["seg11"],"Alignments","seg11","ctgA",30574,30738,null],[["seg02"],"Alignments","seg02","ctgA",30807,31306,null],[["seg10"],"Alignments","seg10","ctgA",30809,31307,null],[["seg05"],"Alignments","seg05","ctgA",31231,31236,null],[["seg05"],"Alignments","seg05","ctgA",31420,31817,null],[["seg02"],"Alignments","seg02","ctgA",31515,31729,null],[["seg02"],"Alignments","seg02","ctgA",31752,32154,null],[["seg10"],"Alignments","seg10","ctgA",31760,31984,null],[["seg05"],"Alignments","seg05","ctgA",32009,32057,null],[["seg05"],"Alignments","seg05","ctgA",32207,32680,null],[["seg01"],"Alignments","seg01","ctgA",32328,32359,null],[["seg10"],"Alignments","seg10","ctgA",32373,32937,null],[["seg02"],"Alignments","seg02","ctgA",32594,32696,null],[["seg02"],"Alignments","seg02","ctgA",32891,32901,null],[["seg05"],"Alignments","seg05","ctgA",33052,33325,null],[["seg02"],"Alignments","seg02","ctgA",33126,33388,null],[["seg05"],"Alignments","seg05","ctgA",33437,33868,null],[["seg02"],"Alignments","seg02","ctgA",33438,33443,null],[["seg02"],"Alignments","seg02","ctgA",33758,34209,null],[["seg05"],"Alignments","seg05","ctgA",34243,34313,null],[["seg02"],"Alignments","seg02","ctgA",34400,34466,null],[["seg05"],"Alignments","seg05","ctgA",34604,34983,null],[["seg05"],"Alignments","seg05","ctgA",35332,35507,null],[["seg05"],"Alignments","seg05","ctgA",35641,35904,null],[["seg09"],"Alignments","seg09","ctgA",36615,37057,null],[["seg09"],"Alignments","seg09","ctgA",37207,37227,null],[["seg15"],"Alignments","seg15","ctgA",39264,39361,null],[["seg15"],"Alignments","seg15","ctgA",39752,40034,null],[["seg15"],"Alignments","seg15","ctgA",40514,40954,null],[["seg14"],"Alignments","seg14","ctgA",41136,41318,null],[["seg15"],"Alignments","seg15","ctgA",41251,41365,null],[["seg15"],"Alignments","seg15","ctgA",41491,41504,null],[["seg14"],"Alignments","seg14","ctgA",41753,41948,null],[["seg15"],"Alignments","seg15","ctgA",41940,42377,null],[["seg14"],"Alignments","seg14","ctgA",42056,42474,null],[["seg15"],"Alignments","seg15","ctgA",42747,42954,null],[["seg14"],"Alignments","seg14","ctgA",42889,43270,null],[["seg14"],"Alignments","seg14","ctgA",43394,43811,null],[["seg15"],"Alignments","seg15","ctgA",43400,43897,null],[["seg15"],"Alignments","seg15","ctgA",44042,44113,null],[["seg14"],"Alignments","seg14","ctgA",44064,44556,null],[["seg07"],"Alignments","seg07","ctgA",44190,44514,null],[["seg15"],"Alignments","seg15","ctgA",44398,44888,null],[["seg07"],"Alignments","seg07","ctgA",44551,45043,null],[["seg14"],"Alignments","seg14","ctgA",44762,45030,null],[["seg14"],"Alignments","seg14","ctgA",45230,45488,null],[["seg15"],"Alignments","seg15","ctgA",45280,45375,null],[["seg07"],"Alignments","seg07","ctgA",45372,45600,null],[["seg15"],"Alignments","seg15","ctgA",45710,46041,null],[["seg14"],"Alignments","seg14","ctgA",45789,46022,null],[["seg07"],"Alignments","seg07","ctgA",45896,46315,null],[["seg14"],"Alignments","seg14","ctgA",46091,46318,null],[["seg15"],"Alignments","seg15","ctgA",46424,46564,null],[["seg07"],"Alignments","seg07","ctgA",46490,46890,null],[["seg15"],"Alignments","seg15","ctgA",46737,47087,null],[["seg14"],"Alignments","seg14","ctgA",46815,46992,null],[["seg07"],"Alignments","seg07","ctgA",47125,47297,null],[["seg15"],"Alignments","seg15","ctgA",47328,47595,null],[["seg14"],"Alignments","seg14","ctgA",47448,47829,null],[["seg07"],"Alignments","seg07","ctgA",47734,47983,null],[["seg15"],"Alignments","seg15","ctgA",47857,47979,null],[["seg15"],"Alignments","seg15","ctgA",48168,48453,null],[["seg07"],"Alignments","seg07","ctgA",48446,48709,null],[["seg07"],"Alignments","seg07","ctgA",48930,49186,null],[["seg13"],"Alignments","seg13","ctgA",49405,49476,null],[["seg07"],"Alignments","seg07","ctgA",49471,49699,null],[["seg13"],"Alignments","seg13","ctgA",49761,50000,null],[["seg07"],"Alignments","seg07","ctgA",49956,50000,null]] \ No newline at end of file diff --git a/tests/data/volvox_formatted_names/tracks/Alignments/ctgA/names.txt b/tests/data/volvox_formatted_names/tracks/Alignments/ctgA/names.txt new file mode 100644 index 0000000000..ef50af29ac --- /dev/null +++ b/tests/data/volvox_formatted_names/tracks/Alignments/ctgA/names.txt @@ -0,0 +1,149 @@ +[["seg04"],"Alignments","seg04","ctgA",5232,5302] +[["seg04"],"Alignments","seg04","ctgA",5799,6101] +[["seg04"],"Alignments","seg04","ctgA",6441,6854] +[["seg03"],"Alignments","seg03","ctgA",6884,7241] +[["seg04"],"Alignments","seg04","ctgA",7105,7211] +[["seg03"],"Alignments","seg03","ctgA",7409,7737] +[["seg04"],"Alignments","seg04","ctgA",7694,8177] +[["seg03"],"Alignments","seg03","ctgA",8054,8080] +[["seg03"],"Alignments","seg03","ctgA",8305,8999] +[["seg04"],"Alignments","seg04","ctgA",8544,8783] +[["seg04"],"Alignments","seg04","ctgA",8868,8935] +[["seg04"],"Alignments","seg04","ctgA",9403,9825] +[["seg12"],"Alignments","seg12","ctgA",12530,12895] +[["seg12"],"Alignments","seg12","ctgA",13121,13449] +[["seg12"],"Alignments","seg12","ctgA",13451,13745] +[["seg12"],"Alignments","seg12","ctgA",13907,13965] +[["seg12"],"Alignments","seg12","ctgA",13997,14488] +[["seg12"],"Alignments","seg12","ctgA",14563,14899] +[["seg12"],"Alignments","seg12","ctgA",15184,15276] +[["seg12"],"Alignments","seg12","ctgA",15638,15736] +[["seg12"],"Alignments","seg12","ctgA",15744,15870] +[["seg08"],"Alignments","seg08","ctgA",18508,18985] +[["seg08"],"Alignments","seg08","ctgA",18988,19388] +[["seg06"],"Alignments","seg06","ctgA",19248,19559] +[["seg08"],"Alignments","seg08","ctgA",19495,19962] +[["seg06"],"Alignments","seg06","ctgA",19974,20260] +[["seg08"],"Alignments","seg08","ctgA",20092,20580] +[["seg06"],"Alignments","seg06","ctgA",20378,20491] +[["seg06"],"Alignments","seg06","ctgA",20532,21005] +[["seg08"],"Alignments","seg08","ctgA",20969,21052] +[["seg06"],"Alignments","seg06","ctgA",21121,21331] +[["seg08"],"Alignments","seg08","ctgA",21269,21277] +[["seg06"],"Alignments","seg06","ctgA",21681,22176] +[["seg08"],"Alignments","seg08","ctgA",21684,22168] +[["seg06"],"Alignments","seg06","ctgA",22373,22570] +[["seg08"],"Alignments","seg08","ctgA",22563,22869] +[["seg08"],"Alignments","seg08","ctgA",22957,23298] +[["seg06"],"Alignments","seg06","ctgA",23024,23427] +[["seg08"],"Alignments","seg08","ctgA",23411,23469] +[["seg08"],"Alignments","seg08","ctgA",23931,23932] +[["seg11"],"Alignments","seg11","ctgA",24227,24510] +[["seg08"],"Alignments","seg08","ctgA",24327,24787] +[["seg11"],"Alignments","seg11","ctgA",24867,25012] +[["seg11"],"Alignments","seg11","ctgA",25211,25426] +[["seg08"],"Alignments","seg08","ctgA",25227,25367] +[["seg11"],"Alignments","seg11","ctgA",25793,25874] +[["seg11"],"Alignments","seg11","ctgA",26074,26519] +[["seg02"],"Alignments","seg02","ctgA",26121,26126] +[["seg02"],"Alignments","seg02","ctgA",26496,26869] +[["seg05"],"Alignments","seg05","ctgA",26502,26799] +[["seg11"],"Alignments","seg11","ctgA",26929,26940] +[["seg11"],"Alignments","seg11","ctgA",26974,27063] +[["seg05"],"Alignments","seg05","ctgA",27171,27185] +[["seg02"],"Alignments","seg02","ctgA",27200,27325] +[["seg02"],"Alignments","seg02","ctgA",27371,27433] +[["seg11"],"Alignments","seg11","ctgA",27414,27799] +[["seg05"],"Alignments","seg05","ctgA",27447,27860] +[["seg02"],"Alignments","seg02","ctgA",27564,27565] +[["seg02"],"Alignments","seg02","ctgA",27812,28091] +[["seg11"],"Alignments","seg11","ctgA",27879,27943] +[["seg05"],"Alignments","seg05","ctgA",27886,28076] +[["seg02"],"Alignments","seg02","ctgA",28092,28201] +[["seg11"],"Alignments","seg11","ctgA",28224,28346] +[["seg05"],"Alignments","seg05","ctgA",28224,28316] +[["seg02"],"Alignments","seg02","ctgA",28328,28377] +[["seg11"],"Alignments","seg11","ctgA",28374,28570] +[["seg11"],"Alignments","seg11","ctgA",28757,29041] +[["seg05"],"Alignments","seg05","ctgA",28776,29058] +[["seg02"],"Alignments","seg02","ctgA",28828,29194] +[["seg11"],"Alignments","seg11","ctgA",29100,29302] +[["seg05"],"Alignments","seg05","ctgA",29512,29647] +[["seg02"],"Alignments","seg02","ctgA",29516,29702] +[["seg11"],"Alignments","seg11","ctgA",29603,29702] +[["seg02"],"Alignments","seg02","ctgA",29712,30061] +[["seg10"],"Alignments","seg10","ctgA",29770,29942] +[["seg11"],"Alignments","seg11","ctgA",29866,29885] +[["seg10"],"Alignments","seg10","ctgA",30041,30340] +[["seg05"],"Alignments","seg05","ctgA",30107,30216] +[["seg11"],"Alignments","seg11","ctgA",30240,30246] +[["seg02"],"Alignments","seg02","ctgA",30328,30774] +[["seg05"],"Alignments","seg05","ctgA",30464,30798] +[["seg11"],"Alignments","seg11","ctgA",30574,30738] +[["seg02"],"Alignments","seg02","ctgA",30807,31306] +[["seg10"],"Alignments","seg10","ctgA",30809,31307] +[["seg05"],"Alignments","seg05","ctgA",31231,31236] +[["seg05"],"Alignments","seg05","ctgA",31420,31817] +[["seg02"],"Alignments","seg02","ctgA",31515,31729] +[["seg02"],"Alignments","seg02","ctgA",31752,32154] +[["seg10"],"Alignments","seg10","ctgA",31760,31984] +[["seg05"],"Alignments","seg05","ctgA",32009,32057] +[["seg05"],"Alignments","seg05","ctgA",32207,32680] +[["seg01"],"Alignments","seg01","ctgA",32328,32359] +[["seg10"],"Alignments","seg10","ctgA",32373,32937] +[["seg02"],"Alignments","seg02","ctgA",32594,32696] +[["seg02"],"Alignments","seg02","ctgA",32891,32901] +[["seg05"],"Alignments","seg05","ctgA",33052,33325] +[["seg02"],"Alignments","seg02","ctgA",33126,33388] +[["seg05"],"Alignments","seg05","ctgA",33437,33868] +[["seg02"],"Alignments","seg02","ctgA",33438,33443] +[["seg02"],"Alignments","seg02","ctgA",33758,34209] +[["seg05"],"Alignments","seg05","ctgA",34243,34313] +[["seg02"],"Alignments","seg02","ctgA",34400,34466] +[["seg05"],"Alignments","seg05","ctgA",34604,34983] +[["seg05"],"Alignments","seg05","ctgA",35332,35507] +[["seg05"],"Alignments","seg05","ctgA",35641,35904] +[["seg09"],"Alignments","seg09","ctgA",36615,37057] +[["seg09"],"Alignments","seg09","ctgA",37207,37227] +[["seg15"],"Alignments","seg15","ctgA",39264,39361] +[["seg15"],"Alignments","seg15","ctgA",39752,40034] +[["seg15"],"Alignments","seg15","ctgA",40514,40954] +[["seg14"],"Alignments","seg14","ctgA",41136,41318] +[["seg15"],"Alignments","seg15","ctgA",41251,41365] +[["seg15"],"Alignments","seg15","ctgA",41491,41504] +[["seg14"],"Alignments","seg14","ctgA",41753,41948] +[["seg15"],"Alignments","seg15","ctgA",41940,42377] +[["seg14"],"Alignments","seg14","ctgA",42056,42474] +[["seg15"],"Alignments","seg15","ctgA",42747,42954] +[["seg14"],"Alignments","seg14","ctgA",42889,43270] +[["seg14"],"Alignments","seg14","ctgA",43394,43811] +[["seg15"],"Alignments","seg15","ctgA",43400,43897] +[["seg15"],"Alignments","seg15","ctgA",44042,44113] +[["seg14"],"Alignments","seg14","ctgA",44064,44556] +[["seg07"],"Alignments","seg07","ctgA",44190,44514] +[["seg15"],"Alignments","seg15","ctgA",44398,44888] +[["seg07"],"Alignments","seg07","ctgA",44551,45043] +[["seg14"],"Alignments","seg14","ctgA",44762,45030] +[["seg14"],"Alignments","seg14","ctgA",45230,45488] +[["seg15"],"Alignments","seg15","ctgA",45280,45375] +[["seg07"],"Alignments","seg07","ctgA",45372,45600] +[["seg15"],"Alignments","seg15","ctgA",45710,46041] +[["seg14"],"Alignments","seg14","ctgA",45789,46022] +[["seg07"],"Alignments","seg07","ctgA",45896,46315] +[["seg14"],"Alignments","seg14","ctgA",46091,46318] +[["seg15"],"Alignments","seg15","ctgA",46424,46564] +[["seg07"],"Alignments","seg07","ctgA",46490,46890] +[["seg15"],"Alignments","seg15","ctgA",46737,47087] +[["seg14"],"Alignments","seg14","ctgA",46815,46992] +[["seg07"],"Alignments","seg07","ctgA",47125,47297] +[["seg15"],"Alignments","seg15","ctgA",47328,47595] +[["seg14"],"Alignments","seg14","ctgA",47448,47829] +[["seg07"],"Alignments","seg07","ctgA",47734,47983] +[["seg15"],"Alignments","seg15","ctgA",47857,47979] +[["seg15"],"Alignments","seg15","ctgA",48168,48453] +[["seg07"],"Alignments","seg07","ctgA",48446,48709] +[["seg07"],"Alignments","seg07","ctgA",48930,49186] +[["seg13"],"Alignments","seg13","ctgA",49405,49476] +[["seg07"],"Alignments","seg07","ctgA",49471,49699] +[["seg13"],"Alignments","seg13","ctgA",49761,50000] +[["seg07"],"Alignments","seg07","ctgA",49956,50000] diff --git a/tests/data/volvox_formatted_names/tracks/CDS/ctgA/names.json b/tests/data/volvox_formatted_names/tracks/CDS/ctgA/names.json deleted file mode 100644 index f23a9c1dbf..0000000000 --- a/tests/data/volvox_formatted_names/tracks/CDS/ctgA/names.json +++ /dev/null @@ -1 +0,0 @@ -[[["Apple1"],"CDS","Apple1","ctgA",9999,11500,null],[["Apple2"],"CDS","Apple2","ctgA",12999,17200,null],[[],"CDS",null,"ctgA",12999,13800,null],[[],"CDS",null,"ctgA",14999,15500,null],[[],"CDS",null,"ctgA",16999,17200,null],[["Apple3"],"CDS","Apple3","ctgA",17399,23000,null]] \ No newline at end of file diff --git a/tests/data/volvox_formatted_names/tracks/CDS/ctgA/names.txt b/tests/data/volvox_formatted_names/tracks/CDS/ctgA/names.txt new file mode 100644 index 0000000000..45698915be --- /dev/null +++ b/tests/data/volvox_formatted_names/tracks/CDS/ctgA/names.txt @@ -0,0 +1,6 @@ +[["Apple1"],"CDS","Apple1","ctgA",9999,11500] +[["Apple2"],"CDS","Apple2","ctgA",12999,17200] +[[],"CDS",null,"ctgA",12999,13800] +[[],"CDS",null,"ctgA",14999,15500] +[[],"CDS",null,"ctgA",16999,17200] +[["Apple3"],"CDS","Apple3","ctgA",17399,23000] diff --git a/tests/data/volvox_formatted_names/tracks/Clones/ctgA/names.json b/tests/data/volvox_formatted_names/tracks/Clones/ctgA/names.json deleted file mode 100644 index f6eac1d15f..0000000000 --- a/tests/data/volvox_formatted_names/tracks/Clones/ctgA/names.json +++ /dev/null @@ -1 +0,0 @@ -[[["b101.2"],"Clones","b101.2","ctgA",999,20000,null]] \ No newline at end of file diff --git a/tests/data/volvox_formatted_names/tracks/Clones/ctgA/names.txt b/tests/data/volvox_formatted_names/tracks/Clones/ctgA/names.txt new file mode 100644 index 0000000000..50d0014aad --- /dev/null +++ b/tests/data/volvox_formatted_names/tracks/Clones/ctgA/names.txt @@ -0,0 +1 @@ +[["b101.2"],"Clones","b101.2","ctgA",999,20000] diff --git a/tests/data/volvox_formatted_names/tracks/EST/ctgA/names.json b/tests/data/volvox_formatted_names/tracks/EST/ctgA/names.json deleted file mode 100644 index be061bc90a..0000000000 --- a/tests/data/volvox_formatted_names/tracks/EST/ctgA/names.json +++ /dev/null @@ -1 +0,0 @@ -[[["agt221.5"],"EST","agt221.5","ctgA",1049,7300,null],[["agt830.5"],"EST","agt830.5","ctgA",1049,3202,null],[["agt767.5"],"EST","agt767.5","ctgA",1149,7200,null],[["agt830.3"],"EST","agt830.3","ctgA",5409,7503,null],[["agt221.3"],"EST","agt221.3","ctgA",7499,8000,null],[["agt767.3"],"EST","agt767.3","ctgA",7999,9000,null]] \ No newline at end of file diff --git a/tests/data/volvox_formatted_names/tracks/EST/ctgA/names.txt b/tests/data/volvox_formatted_names/tracks/EST/ctgA/names.txt new file mode 100644 index 0000000000..06786fe56b --- /dev/null +++ b/tests/data/volvox_formatted_names/tracks/EST/ctgA/names.txt @@ -0,0 +1,6 @@ +[["agt221.5"],"EST","agt221.5","ctgA",1049,7300] +[["agt830.5"],"EST","agt830.5","ctgA",1049,3202] +[["agt767.5"],"EST","agt767.5","ctgA",1149,7200] +[["agt830.3"],"EST","agt830.3","ctgA",5409,7503] +[["agt221.3"],"EST","agt221.3","ctgA",7499,8000] +[["agt767.3"],"EST","agt767.3","ctgA",7999,9000] diff --git a/tests/data/volvox_formatted_names/tracks/ExampleFeatures/ctgA/names.json b/tests/data/volvox_formatted_names/tracks/ExampleFeatures/ctgA/names.json deleted file mode 100644 index a894630e03..0000000000 --- a/tests/data/volvox_formatted_names/tracks/ExampleFeatures/ctgA/names.json +++ /dev/null @@ -1 +0,0 @@ -[[["Remark:hga","hga"],"ExampleFeatures","Remark:hga","ctgA",999,2000,null],[["f07"],"ExampleFeatures","f07","ctgA",1658,1984,null],[["f06"],"ExampleFeatures","f06","ctgA",3013,6130,null],[["f05"],"ExampleFeatures","f05","ctgA",4714,5968,null],[["f08"],"ExampleFeatures","f08","ctgA",13279,16394,null],[["f10"],"ExampleFeatures","f10","ctgA",15328,15533,null],[["f13"],"ExampleFeatures","f13","ctgA",19156,22915,null],[["f15"],"ExampleFeatures","f15","ctgA",22131,24633,null],[["f14"],"ExampleFeatures","f14","ctgA",23071,23185,null],[["f02"],"ExampleFeatures","f02","ctgA",24561,28338,null],[["f09"],"ExampleFeatures","f09","ctgA",36033,38167,null],[["f03"],"ExampleFeatures","f03","ctgA",36648,40440,null],[["f04"],"ExampleFeatures","f04","ctgA",37241,38653,null],[["f01"],"ExampleFeatures","f01","ctgA",44704,47713,null],[["f11"],"ExampleFeatures","f11","ctgA",46989,48410,null],[["f12"],"ExampleFeatures","f12","ctgA",49757,50000,null]] \ No newline at end of file diff --git a/tests/data/volvox_formatted_names/tracks/ExampleFeatures/ctgA/names.txt b/tests/data/volvox_formatted_names/tracks/ExampleFeatures/ctgA/names.txt new file mode 100644 index 0000000000..ef5afac54a --- /dev/null +++ b/tests/data/volvox_formatted_names/tracks/ExampleFeatures/ctgA/names.txt @@ -0,0 +1,16 @@ +[["Remark:hga","hga"],"ExampleFeatures","Remark:hga","ctgA",999,2000] +[["f07"],"ExampleFeatures","f07","ctgA",1658,1984] +[["f06"],"ExampleFeatures","f06","ctgA",3013,6130] +[["f05"],"ExampleFeatures","f05","ctgA",4714,5968] +[["f08"],"ExampleFeatures","f08","ctgA",13279,16394] +[["f10"],"ExampleFeatures","f10","ctgA",15328,15533] +[["f13"],"ExampleFeatures","f13","ctgA",19156,22915] +[["f15"],"ExampleFeatures","f15","ctgA",22131,24633] +[["f14"],"ExampleFeatures","f14","ctgA",23071,23185] +[["f02"],"ExampleFeatures","f02","ctgA",24561,28338] +[["f09"],"ExampleFeatures","f09","ctgA",36033,38167] +[["f03"],"ExampleFeatures","f03","ctgA",36648,40440] +[["f04"],"ExampleFeatures","f04","ctgA",37241,38653] +[["f01"],"ExampleFeatures","f01","ctgA",44704,47713] +[["f11"],"ExampleFeatures","f11","ctgA",46989,48410] +[["f12"],"ExampleFeatures","f12","ctgA",49757,50000] diff --git a/tests/data/volvox_formatted_names/tracks/ExampleFeatures/ctgB/names.json b/tests/data/volvox_formatted_names/tracks/ExampleFeatures/ctgB/names.json deleted file mode 100644 index cfcc1d26fa..0000000000 --- a/tests/data/volvox_formatted_names/tracks/ExampleFeatures/ctgB/names.json +++ /dev/null @@ -1 +0,0 @@ -[[["f07"],"ExampleFeatures","f07","ctgB",1658,1984,null],[["f06"],"ExampleFeatures","f06","ctgB",3013,6130,null],[["f05"],"ExampleFeatures","f05","ctgB",4714,5968,null]] \ No newline at end of file diff --git a/tests/data/volvox_formatted_names/tracks/ExampleFeatures/ctgB/names.txt b/tests/data/volvox_formatted_names/tracks/ExampleFeatures/ctgB/names.txt new file mode 100644 index 0000000000..33caf6fae4 --- /dev/null +++ b/tests/data/volvox_formatted_names/tracks/ExampleFeatures/ctgB/names.txt @@ -0,0 +1,3 @@ +[["f07"],"ExampleFeatures","f07","ctgB",1658,1984] +[["f06"],"ExampleFeatures","f06","ctgB",3013,6130] +[["f05"],"ExampleFeatures","f05","ctgB",4714,5968] diff --git a/tests/data/volvox_formatted_names/tracks/Genes/ctgA/names.json b/tests/data/volvox_formatted_names/tracks/Genes/ctgA/names.json deleted file mode 100644 index 4d71184db7..0000000000 --- a/tests/data/volvox_formatted_names/tracks/Genes/ctgA/names.json +++ /dev/null @@ -1 +0,0 @@ -[[["EDEN"],"Genes","EDEN","ctgA",1049,9000,null]] \ No newline at end of file diff --git a/tests/data/volvox_formatted_names/tracks/Genes/ctgA/names.txt b/tests/data/volvox_formatted_names/tracks/Genes/ctgA/names.txt new file mode 100644 index 0000000000..0ef799b5f7 --- /dev/null +++ b/tests/data/volvox_formatted_names/tracks/Genes/ctgA/names.txt @@ -0,0 +1 @@ +[["EDEN"],"Genes","EDEN","ctgA",1049,9000] diff --git a/tests/data/volvox_formatted_names/tracks/Motifs/ctgA/names.json b/tests/data/volvox_formatted_names/tracks/Motifs/ctgA/names.json deleted file mode 100644 index 86425bc804..0000000000 --- a/tests/data/volvox_formatted_names/tracks/Motifs/ctgA/names.json +++ /dev/null @@ -1 +0,0 @@ -[[["m11"],"Motifs","m11","ctgA",11910,15561,null],[["m05"],"Motifs","m05","ctgA",13800,14007,null],[["m14"],"Motifs","m14","ctgA",14730,17239,null],[["m03"],"Motifs","m03","ctgA",15395,16159,null],[["m08"],"Motifs","m08","ctgA",17022,17675,null],[["m13"],"Motifs","m13","ctgA",17666,17690,null],[["m07"],"Motifs","m07","ctgA",18047,18552,null],[["m12"],"Motifs","m12","ctgA",21747,25612,null],[["m02"],"Motifs","m02","ctgA",28331,30033,null],[["m10"],"Motifs","m10","ctgA",28341,28447,null],[["m06"],"Motifs","m06","ctgA",30577,31748,null],[["m04"],"Motifs","m04","ctgA",33324,35791,null],[["m15"],"Motifs","m15","ctgA",37496,40559,null],[["m09"],"Motifs","m09","ctgA",46011,48851,null],[["m01"],"Motifs","m01","ctgA",48252,48366,null]] \ No newline at end of file diff --git a/tests/data/volvox_formatted_names/tracks/Motifs/ctgA/names.txt b/tests/data/volvox_formatted_names/tracks/Motifs/ctgA/names.txt new file mode 100644 index 0000000000..a8adbb70c4 --- /dev/null +++ b/tests/data/volvox_formatted_names/tracks/Motifs/ctgA/names.txt @@ -0,0 +1,15 @@ +[["m11"],"Motifs","m11","ctgA",11910,15561] +[["m05"],"Motifs","m05","ctgA",13800,14007] +[["m14"],"Motifs","m14","ctgA",14730,17239] +[["m03"],"Motifs","m03","ctgA",15395,16159] +[["m08"],"Motifs","m08","ctgA",17022,17675] +[["m13"],"Motifs","m13","ctgA",17666,17690] +[["m07"],"Motifs","m07","ctgA",18047,18552] +[["m12"],"Motifs","m12","ctgA",21747,25612] +[["m02"],"Motifs","m02","ctgA",28331,30033] +[["m10"],"Motifs","m10","ctgA",28341,28447] +[["m06"],"Motifs","m06","ctgA",30577,31748] +[["m04"],"Motifs","m04","ctgA",33324,35791] +[["m15"],"Motifs","m15","ctgA",37496,40559] +[["m09"],"Motifs","m09","ctgA",46011,48851] +[["m01"],"Motifs","m01","ctgA",48252,48366] diff --git a/tests/data/volvox_formatted_names/tracks/NameTest/ctgA/names.json b/tests/data/volvox_formatted_names/tracks/NameTest/ctgA/names.json deleted file mode 100644 index 77bcf1fe0c..0000000000 --- a/tests/data/volvox_formatted_names/tracks/NameTest/ctgA/names.json +++ /dev/null @@ -1 +0,0 @@ -[[["Gene:hga","hga"],"NameTest","Gene:hga","ctgA",1099,2000,null],[["Protein:HGA","hga"],"NameTest","Protein:HGA","ctgA",1199,1900,null],[["Gene:hgb","hgb"],"NameTest","Gene:hgb","ctgA",1599,3000,null],[["Protein:HGB","hgb"],"NameTest","Protein:HGB","ctgA",1799,2900,null]] \ No newline at end of file diff --git a/tests/data/volvox_formatted_names/tracks/NameTest/ctgA/names.txt b/tests/data/volvox_formatted_names/tracks/NameTest/ctgA/names.txt new file mode 100644 index 0000000000..0f3974403b --- /dev/null +++ b/tests/data/volvox_formatted_names/tracks/NameTest/ctgA/names.txt @@ -0,0 +1,4 @@ +[["Gene:hga","hga"],"NameTest","Gene:hga","ctgA",1099,2000] +[["Protein:HGA","hga"],"NameTest","Protein:HGA","ctgA",1199,1900] +[["Gene:hgb","hgb"],"NameTest","Gene:hgb","ctgA",1599,3000] +[["Protein:HGB","hgb"],"NameTest","Protein:HGB","ctgA",1799,2900] diff --git a/tests/data/volvox_formatted_names/tracks/ReadingFrame/ctgA/names.json b/tests/data/volvox_formatted_names/tracks/ReadingFrame/ctgA/names.json deleted file mode 100644 index 7472ba8fed..0000000000 --- a/tests/data/volvox_formatted_names/tracks/ReadingFrame/ctgA/names.json +++ /dev/null @@ -1 +0,0 @@ -[[["EDEN.2"],"ReadingFrame","EDEN.2","ctgA",1049,9000,null],[["EDEN.1"],"ReadingFrame","EDEN.1","ctgA",1049,9000,null],[["EDEN.3"],"ReadingFrame","EDEN.3","ctgA",1299,9000,null],[["Apple2"],"ReadingFrame","Apple2","ctgA",12999,17200,null],[["Apple3"],"ReadingFrame","Apple3","ctgA",17399,23000,null]] \ No newline at end of file diff --git a/tests/data/volvox_formatted_names/tracks/ReadingFrame/ctgA/names.txt b/tests/data/volvox_formatted_names/tracks/ReadingFrame/ctgA/names.txt new file mode 100644 index 0000000000..0ef7e0eaa5 --- /dev/null +++ b/tests/data/volvox_formatted_names/tracks/ReadingFrame/ctgA/names.txt @@ -0,0 +1,5 @@ +[["EDEN.2"],"ReadingFrame","EDEN.2","ctgA",1049,9000] +[["EDEN.1"],"ReadingFrame","EDEN.1","ctgA",1049,9000] +[["EDEN.3"],"ReadingFrame","EDEN.3","ctgA",1299,9000] +[["Apple2"],"ReadingFrame","Apple2","ctgA",12999,17200] +[["Apple3"],"ReadingFrame","Apple3","ctgA",17399,23000] diff --git a/tests/data/volvox_formatted_names/tracks/Transcript/ctgA/names.json b/tests/data/volvox_formatted_names/tracks/Transcript/ctgA/names.json deleted file mode 100644 index 9cee801812..0000000000 --- a/tests/data/volvox_formatted_names/tracks/Transcript/ctgA/names.json +++ /dev/null @@ -1 +0,0 @@ -[[["Apple3"],"Transcript","Apple3","ctgA",17399,23000,null]] \ No newline at end of file diff --git a/tests/data/volvox_formatted_names/tracks/Transcript/ctgA/names.txt b/tests/data/volvox_formatted_names/tracks/Transcript/ctgA/names.txt new file mode 100644 index 0000000000..3816bbd057 --- /dev/null +++ b/tests/data/volvox_formatted_names/tracks/Transcript/ctgA/names.txt @@ -0,0 +1 @@ +[["Apple3"],"Transcript","Apple3","ctgA",17399,23000] diff --git a/tests/data/volvox_formatted_names/tracks/snps/ctgA/names.json b/tests/data/volvox_formatted_names/tracks/snps/ctgA/names.json deleted file mode 100644 index e78d32f0aa..0000000000 --- a/tests/data/volvox_formatted_names/tracks/snps/ctgA/names.json +++ /dev/null @@ -1 +0,0 @@ -[[["FakeSNP"],"snps","FakeSNP","ctgA",999,1000,null]] \ No newline at end of file diff --git a/tests/data/volvox_formatted_names/tracks/snps/ctgA/names.txt b/tests/data/volvox_formatted_names/tracks/snps/ctgA/names.txt new file mode 100644 index 0000000000..7cd8600f1b --- /dev/null +++ b/tests/data/volvox_formatted_names/tracks/snps/ctgA/names.txt @@ -0,0 +1 @@ +[["FakeSNP"],"snps","FakeSNP","ctgA",999,1000] diff --git a/tests/data/volvox_formatted_refseqs/seq/refSeqs.json b/tests/data/volvox_formatted_refseqs/seq/refSeqs.json index f877745c20..cc1b002d6e 100644 --- a/tests/data/volvox_formatted_refseqs/seq/refSeqs.json +++ b/tests/data/volvox_formatted_refseqs/seq/refSeqs.json @@ -1,16 +1,16 @@ [ { - "length" : 6079, - "name" : "ctgB", + "length" : 50001, + "name" : "ctgA", "seqChunkSize" : 20000, - "end" : 6079, + "end" : 50001, "start" : 0 }, { - "length" : 50001, - "name" : "ctgA", + "length" : 6079, + "name" : "ctgB", "seqChunkSize" : 20000, - "end" : 50001, + "end" : 6079, "start" : 0 } ] diff --git a/tests/install_selenium.sh b/tests/install_selenium.sh new file mode 100755 index 0000000000..f4a0d6ebfe --- /dev/null +++ b/tests/install_selenium.sh @@ -0,0 +1,15 @@ +#!/bin/bash +set -e; + +# try to install pip if we don't have it +if ! ( which pip >/dev/null 2>&1 ); then + if ( which apt-get ); then + sudo apt-get install python-pip + else if ( which easy_install >/dev/null 2>&1 ); then + easy_install pip + fi; + fi; +fi; + +# install selenium and nose with pip +pip install selenium nose diff --git a/tests/js_tests/index.html b/tests/js_tests/index.html index 4e5173e093..baa97ac67a 100644 --- a/tests/js_tests/index.html +++ b/tests/js_tests/index.html @@ -1,7 +1,8 @@ - + Jasmine Spec Runner @@ -20,6 +21,12 @@ + + + + + +