galaxy-commits
Threads by month
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
May 2012
- 1 participants
- 61 discussions
2 new commits in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/changeset/98cf8f250649/
changeset: 98cf8f250649
user: jgoecks
date: 2012-05-12 00:43:51
summary: Fix bug so that reference track cannot be resized.
affected #: 1 file
diff -r 1744124f8ee4fa3441642823b96c21262d219b14 -r 98cf8f2506493a468135f3d00e92233f5bfbf387 static/scripts/trackster.js
--- a/static/scripts/trackster.js
+++ b/static/scripts/trackster.js
@@ -4334,7 +4334,7 @@
});
var ReferenceTrack = function (view) {
- TiledTrack.call(this, view, { content_div: view.top_labeltrack, resize: false }, {});
+ TiledTrack.call(this, view, { content_div: view.top_labeltrack }, { resize: false });
view.reference_track = this;
this.left_offset = 200;
https://bitbucket.org/galaxy/galaxy-central/changeset/c22bb0df586a/
changeset: c22bb0df586a
user: jgoecks
date: 2012-05-12 01:27:30
summary: Refactor genome build status and information out of tracks controllers and into own object.
affected #: 2 files
diff -r 98cf8f2506493a468135f3d00e92233f5bfbf387 -r c22bb0df586a95eae52701a7b44a678aed002b8e lib/galaxy/visualization/tracks/genomes.py
--- /dev/null
+++ b/lib/galaxy/visualization/tracks/genomes.py
@@ -0,0 +1,268 @@
+import os, re
+from bx.seq.twobit import TwoBitFile
+from galaxy.util.json import from_json_string
+from galaxy import model
+from galaxy.util.bunch import Bunch
+
+# FIXME: copied from tracks.py
+# Message strings returned to browser
+messages = Bunch(
+ PENDING = "pending",
+ NO_DATA = "no data",
+ NO_CHROMOSOME = "no chromosome",
+ NO_CONVERTER = "no converter",
+ NO_TOOL = "no tool",
+ DATA = "data",
+ ERROR = "error",
+ OK = "ok"
+)
+
+def decode_dbkey( dbkey ):
+ """ Decodes dbkey and returns tuple ( username, dbkey )"""
+ if ':' in dbkey:
+ return dbkey.split( ':' )
+ else:
+ return None, dbkey
+
+
+class Genomes( object ):
+ """
+ Provides information about available genome data and methods for manipulating that data.
+ """
+
+ def __init__( self, app ):
+ # Create list of available genomes.
+ self.available_genomes = None
+ avail_genomes = {}
+ for line in open( os.path.join( app.config.tool_data_path, "twobit.loc" ) ):
+ if line.startswith("#"): continue
+ val = line.split()
+ if len( val ) == 2:
+ key, path = val
+ avail_genomes[ key ] = path
+ self.available_genomes = avail_genomes
+
+ def chroms( self, trans, dbkey=None, num=None, chrom=None, low=None ):
+ """
+ Returns a naturally sorted list of chroms/contigs for a given dbkey.
+ Use either chrom or low to specify the starting chrom in the return list.
+ """
+ def check_int(s):
+ if s.isdigit():
+ return int(s)
+ else:
+ return s
+
+ def split_by_number(s):
+ return [ check_int(c) for c in re.split('([0-9]+)', s) ]
+
+ #
+ # Parameter check, setting.
+ #
+ if num:
+ num = int( num )
+ else:
+ num = sys.maxint
+
+ if low:
+ low = int( low )
+ if low < 0:
+ low = 0
+ else:
+ low = 0
+
+ # If there is no dbkey owner, default to current user.
+ dbkey_owner, dbkey = decode_dbkey( dbkey )
+ if dbkey_owner:
+ dbkey_user = trans.sa_session.query( trans.app.model.User ).filter_by( username=dbkey_owner ).first()
+ else:
+ dbkey_user = trans.user
+
+ #
+ # Get len file.
+ #
+ len_file = None
+ len_ds = None
+ user_keys = {}
+ if dbkey_user and 'dbkeys' in dbkey_user.preferences:
+ user_keys = from_json_string( dbkey_user.preferences['dbkeys'] )
+ if dbkey in user_keys:
+ dbkey_attributes = user_keys[ dbkey ]
+ if 'fasta' in dbkey_attributes:
+ build_fasta = trans.sa_session.query( trans.app.model.HistoryDatasetAssociation ).get( dbkey_attributes[ 'fasta' ] )
+ len_file = build_fasta.get_converted_dataset( trans, 'len' ).file_name
+ # Backwards compatibility: look for len file directly.
+ elif 'len' in dbkey_attributes:
+ len_file = trans.sa_session.query( trans.app.model.HistoryDatasetAssociation ).get( user_keys[ dbkey ][ 'len' ] ).file_name
+
+ if not len_file:
+ len_ds = trans.db_dataset_for( dbkey )
+ if not len_ds:
+ len_file = os.path.join( trans.app.config.len_file_path, "%s.len" % dbkey )
+ else:
+ len_file = len_ds.file_name
+
+ #
+ # Get chroms data:
+ # (a) chrom name, len;
+ # (b) whether there are previous, next chroms;
+ # (c) index of start chrom.
+ #
+ len_file_enumerate = enumerate( open( len_file ) )
+ chroms = {}
+ prev_chroms = False
+ start_index = 0
+ if chrom:
+ # Use starting chrom to start list.
+ found = False
+ count = 0
+ for line_num, line in len_file_enumerate:
+ if line.startswith("#"):
+ continue
+ name, len = line.split("\t")
+ if found:
+ chroms[ name ] = int( len )
+ count += 1
+ elif name == chrom:
+ # Found starting chrom.
+ chroms[ name ] = int ( len )
+ count += 1
+ found = True
+ start_index = line_num
+ if line_num != 0:
+ prev_chroms = True
+ if count >= num:
+ break
+ else:
+ # Use low to start list.
+ high = low + int( num )
+ prev_chroms = ( low != 0 )
+ start_index = low
+
+ # Read chrom data from len file.
+ # TODO: this may be too slow for very large numbers of chroms/contigs,
+ # but try it out for now.
+ if not os.path.exists( len_file ):
+ return None
+
+ for line_num, line in len_file_enumerate:
+ if line_num < low:
+ continue
+ if line_num >= high:
+ break
+ if line.startswith("#"):
+ continue
+ # LEN files have format:
+ # <chrom_name><tab><chrom_length>
+ fields = line.split("\t")
+ chroms[ fields[0] ] = int( fields[1] )
+
+ # Set flag to indicate whether there are more chroms after list.
+ next_chroms = False
+ try:
+ len_file_enumerate.next()
+ next_chroms = True
+ except:
+ # No more chroms to read.
+ pass
+
+ to_sort = [{ 'chrom': chrom, 'len': length } for chrom, length in chroms.iteritems()]
+ to_sort.sort(lambda a,b: cmp( split_by_number(a['chrom']), split_by_number(b['chrom']) ))
+ return { 'reference': self.has_reference_data( trans, dbkey, dbkey_user ), 'chrom_info': to_sort,
+ 'prev_chroms' : prev_chroms, 'next_chroms' : next_chroms, 'start_index' : start_index }
+
+ def has_reference_data( self, trans, dbkey, dbkey_owner=None ):
+ """
+ Returns true if there is reference data for the specified dbkey. If dbkey is custom,
+ dbkey_owner is needed to determine if there is reference data.
+ """
+ # Initialize built-in builds if necessary.
+ if not self.available_genomes:
+ self._init_references( trans )
+
+ # Look for key in built-in builds.
+ if dbkey in self.available_genomes:
+ # There is built-in reference data.
+ return True
+
+ # Look for key in owner's custom builds.
+ if dbkey_owner and 'dbkeys' in dbkey_owner.preferences:
+ user_keys = from_json_string( dbkey_owner.preferences[ 'dbkeys' ] )
+ if dbkey in user_keys:
+ dbkey_attributes = user_keys[ dbkey ]
+ if 'fasta' in dbkey_attributes:
+ # Fasta + converted datasets can provide reference data.
+ return True
+
+ return False
+
+ def reference( self, trans, dbkey, chrom, low, high, **kwargs ):
+ """
+ Return reference data for a build.
+ """
+
+ # If there is no dbkey owner, default to current user.
+ dbkey_owner, dbkey = decode_dbkey( dbkey )
+ if dbkey_owner:
+ dbkey_user = trans.sa_session.query( trans.app.model.User ).filter_by( username=dbkey_owner ).first()
+ else:
+ dbkey_user = trans.user
+
+ if not self.has_reference_data( trans, dbkey, dbkey_user ):
+ return None
+
+ #
+ # Get twobit file with reference data.
+ #
+ twobit_file_name = None
+ if dbkey in self.available_genomes:
+ # Built-in twobit.
+ twobit_file_name = self.available_genomes[dbkey]
+ else:
+ user_keys = from_json_string( dbkey_user.preferences['dbkeys'] )
+ dbkey_attributes = user_keys[ dbkey ]
+ fasta_dataset = trans.app.model.HistoryDatasetAssociation.get( dbkey_attributes[ 'fasta' ] )
+ error = self._convert_dataset( trans, fasta_dataset, 'twobit' )
+ if error:
+ return error
+ else:
+ twobit_dataset = fasta_dataset.get_converted_dataset( trans, 'twobit' )
+ twobit_file_name = twobit_dataset.file_name
+
+ # Read and return reference data.
+ try:
+ twobit = TwoBitFile( open( twobit_file_name ) )
+ if chrom in twobit:
+ seq_data = twobit[chrom].get( int(low), int(high) )
+ return { 'dataset_type': 'refseq', 'data': seq_data }
+ except IOError:
+ return None
+
+ ## FIXME: copied from tracks.py (tracks controller) - this should be consolidated when possible.
+ def _convert_dataset( self, trans, dataset, target_type ):
+ """
+ Converts a dataset to the target_type and returns a message indicating
+ status of the conversion. None is returned to indicate that dataset
+ was converted successfully.
+ """
+
+ # Get converted dataset; this will start the conversion if necessary.
+ try:
+ converted_dataset = dataset.get_converted_dataset( trans, target_type )
+ except NoConverterException:
+ return messages.NO_CONVERTER
+ except ConverterDependencyException, dep_error:
+ return { 'kind': messages.ERROR, 'message': dep_error.value }
+
+ # Check dataset state and return any messages.
+ msg = None
+ if converted_dataset and converted_dataset.state == model.Dataset.states.ERROR:
+ job_id = trans.sa_session.query( trans.app.model.JobToOutputDatasetAssociation ) \
+ .filter_by( dataset_id=converted_dataset.id ).first().job_id
+ job = trans.sa_session.query( trans.app.model.Job ).get( job_id )
+ msg = { 'kind': messages.ERROR, 'message': job.stderr }
+ elif not converted_dataset or converted_dataset.state != model.Dataset.states.OK:
+ msg = messages.PENDING
+
+ return msg
+
\ No newline at end of file
diff -r 98cf8f2506493a468135f3d00e92233f5bfbf387 -r c22bb0df586a95eae52701a7b44a678aed002b8e lib/galaxy/web/controllers/tracks.py
--- a/lib/galaxy/web/controllers/tracks.py
+++ b/lib/galaxy/web/controllers/tracks.py
@@ -5,7 +5,6 @@
import re, pkg_resources
pkg_resources.require( "bx-python" )
-from bx.seq.twobit import TwoBitFile
from galaxy import model
from galaxy.util.json import to_json_string, from_json_string
from galaxy.web.base.controller import *
@@ -16,6 +15,7 @@
from galaxy.datatypes.interval import Gff, Bed
from galaxy.model import NoConverterException, ConverterDependencyException
from galaxy.visualization.tracks.data_providers import *
+from galaxy.visualization.tracks.genomes import decode_dbkey, Genomes
from galaxy.visualization.tracks.visual_analytics import get_tool_def, get_dataset_job
# Message strings returned to browser
@@ -30,13 +30,6 @@
OK = "ok"
)
-def _decode_dbkey( dbkey ):
- """ Decodes dbkey and returns tuple ( username, dbkey )"""
- if ':' in dbkey:
- return dbkey.split( ':' )
- else:
- return None, dbkey
-
class NameColumn( grids.TextColumn ):
def get_value( self, trans, grid, history ):
return history.get_display_name()
@@ -99,7 +92,7 @@
def filter( self, trans, user, query, dbkey ):
""" Filter by dbkey; datasets without a dbkey are returned as well. """
# use raw SQL b/c metadata is a BLOB
- dbkey_user, dbkey = _decode_dbkey( dbkey )
+ dbkey_user, dbkey = decode_dbkey( dbkey )
dbkey = dbkey.replace("'", "\\'")
return query.filter( or_( \
or_( "metadata like '%%\"dbkey\": [\"%s\"]%%'" % dbkey, "metadata like '%%\"dbkey\": \"%s\"%%'" % dbkey ), \
@@ -180,48 +173,11 @@
histories_grid = HistorySelectionGrid()
history_datasets_grid = HistoryDatasetsSelectionGrid()
tracks_grid = TracksterSelectionGrid()
-
- available_tracks = None
- available_genomes = None
- def _init_references( self, trans ):
- """
- Create a list of builds that have reference data specified in twobit.loc file.
- """
- avail_genomes = {}
- for line in open( os.path.join( trans.app.config.tool_data_path, "twobit.loc" ) ):
- if line.startswith("#"): continue
- val = line.split()
- if len(val) == 2:
- key, path = val
- avail_genomes[key] = path
- self.available_genomes = avail_genomes
-
- def _has_reference_data( self, trans, dbkey, dbkey_owner=None ):
- """
- Returns true if there is reference data for the specified dbkey. If dbkey is custom,
- dbkey_owner is needed to determine if there is reference data.
- """
- # Initialize built-in builds if necessary.
- if not self.available_genomes:
- self._init_references( trans )
-
- # Look for key in built-in builds.
- if dbkey in self.available_genomes:
- # There is built-in reference data.
- return True
-
- # Look for key in owner's custom builds.
- if dbkey_owner and 'dbkeys' in dbkey_owner.preferences:
- user_keys = from_json_string( dbkey_owner.preferences[ 'dbkeys' ] )
- if dbkey in user_keys:
- dbkey_attributes = user_keys[ dbkey ]
- if 'fasta' in dbkey_attributes:
- # Fasta + converted datasets can provide reference data.
- return True
-
- return False
-
+ def __init__(self, app ):
+ BaseUIController.__init__( self, app )
+ self.genomes = Genomes( self.app )
+
@web.expose
@web.require_login()
def index( self, trans, **kwargs ):
@@ -296,177 +252,11 @@
@web.json
def chroms( self, trans, dbkey=None, num=None, chrom=None, low=None ):
- """
- Returns a naturally sorted list of chroms/contigs for either a given visualization or a given dbkey.
- Use either chrom or low to specify the starting chrom in the return list.
- """
- def check_int(s):
- if s.isdigit():
- return int(s)
- else:
- return s
-
- def split_by_number(s):
- return [ check_int(c) for c in re.split('([0-9]+)', s) ]
-
- #
- # Parameter check, setting.
- #
- if num:
- num = int( num )
- else:
- num = sys.maxint
-
- if low:
- low = int( low )
- if low < 0:
- low = 0
- else:
- low = 0
-
- # If there is no dbkey owner, default to current user.
- dbkey_owner, dbkey = _decode_dbkey( dbkey )
- if dbkey_owner:
- dbkey_user = trans.sa_session.query( trans.app.model.User ).filter_by( username=dbkey_owner ).first()
- else:
- dbkey_user = trans.user
-
- #
- # Get len file.
- #
- len_file = None
- len_ds = None
- user_keys = {}
- if dbkey_user and 'dbkeys' in dbkey_user.preferences:
- user_keys = from_json_string( dbkey_user.preferences['dbkeys'] )
- if dbkey in user_keys:
- dbkey_attributes = user_keys[ dbkey ]
- if 'fasta' in dbkey_attributes:
- build_fasta = trans.sa_session.query( trans.app.model.HistoryDatasetAssociation ).get( dbkey_attributes[ 'fasta' ] )
- len_file = build_fasta.get_converted_dataset( trans, 'len' ).file_name
- # Backwards compatibility: look for len file directly.
- elif 'len' in dbkey_attributes:
- len_file = trans.sa_session.query( trans.app.model.HistoryDatasetAssociation ).get( user_keys[ dbkey ][ 'len' ] ).file_name
-
- if not len_file:
- len_ds = trans.db_dataset_for( dbkey )
- if not len_ds:
- len_file = os.path.join( trans.app.config.len_file_path, "%s.len" % dbkey )
- else:
- len_file = len_ds.file_name
-
- #
- # Get chroms data:
- # (a) chrom name, len;
- # (b) whether there are previous, next chroms;
- # (c) index of start chrom.
- #
- len_file_enumerate = enumerate( open( len_file ) )
- chroms = {}
- prev_chroms = False
- start_index = 0
- if chrom:
- # Use starting chrom to start list.
- found = False
- count = 0
- for line_num, line in len_file_enumerate:
- if line.startswith("#"):
- continue
- name, len = line.split("\t")
- if found:
- chroms[ name ] = int( len )
- count += 1
- elif name == chrom:
- # Found starting chrom.
- chroms[ name ] = int ( len )
- count += 1
- found = True
- start_index = line_num
- if line_num != 0:
- prev_chroms = True
- if count >= num:
- break
- else:
- # Use low to start list.
- high = low + int( num )
- prev_chroms = ( low != 0 )
- start_index = low
-
- # Read chrom data from len file.
- # TODO: this may be too slow for very large numbers of chroms/contigs,
- # but try it out for now.
- if not os.path.exists( len_file ):
- return None
-
- for line_num, line in len_file_enumerate:
- if line_num < low:
- continue
- if line_num >= high:
- break
- if line.startswith("#"):
- continue
- # LEN files have format:
- # <chrom_name><tab><chrom_length>
- fields = line.split("\t")
- chroms[ fields[0] ] = int( fields[1] )
-
- # Set flag to indicate whether there are more chroms after list.
- next_chroms = False
- try:
- len_file_enumerate.next()
- next_chroms = True
- except:
- # No more chroms to read.
- pass
-
- to_sort = [{ 'chrom': chrom, 'len': length } for chrom, length in chroms.iteritems()]
- to_sort.sort(lambda a,b: cmp( split_by_number(a['chrom']), split_by_number(b['chrom']) ))
- return { 'reference': self._has_reference_data( trans, dbkey, dbkey_user ), 'chrom_info': to_sort,
- 'prev_chroms' : prev_chroms, 'next_chroms' : next_chroms, 'start_index' : start_index }
+ return self.genomes.chroms( trans, dbkey=dbkey, num=num, chrom=chrom, low=low )
@web.json
def reference( self, trans, dbkey, chrom, low, high, **kwargs ):
- """
- Return reference data for a build.
- """
-
- # If there is no dbkey owner, default to current user.
- dbkey_owner, dbkey = _decode_dbkey( dbkey )
- if dbkey_owner:
- dbkey_user = trans.sa_session.query( trans.app.model.User ).filter_by( username=dbkey_owner ).first()
- else:
- dbkey_user = trans.user
-
- if not self._has_reference_data( trans, dbkey, dbkey_user ):
- return None
-
- #
- # Get twobit file with reference data.
- #
- twobit_file_name = None
- if dbkey in self.available_genomes:
- # Built-in twobit.
- twobit_file_name = self.available_genomes[dbkey]
- else:
- # From custom build.
- user_keys = from_json_string( dbkey_user.preferences['dbkeys'] )
- dbkey_attributes = user_keys[ dbkey ]
- fasta_dataset = trans.app.model.HistoryDatasetAssociation.get( dbkey_attributes[ 'fasta' ] )
- error = self._convert_dataset( trans, fasta_dataset, 'twobit' )
- if error:
- return error
- else:
- twobit_dataset = fasta_dataset.get_converted_dataset( trans, 'twobit' )
- twobit_file_name = twobit_dataset.file_name
-
- # Read and return reference data.
- try:
- twobit = TwoBitFile( open( twobit_file_name ) )
- if chrom in twobit:
- seq_data = twobit[chrom].get( int(low), int(high) )
- return { 'dataset_type': 'refseq', 'data': seq_data }
- except IOError:
- return None
+ return self.genomes.reference( trans, dbkey, chrom, low, high, **kwargs )
@web.json
def raw_data( self, trans, dataset_id, chrom, low, high, **kwargs ):
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
10 new commits in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/changeset/955d18fc07d5/
changeset: 955d18fc07d5
user: fbacall
date: 2012-03-26 14:40:42
summary: Made myExperiment URL configurable
affected #: 2 files
diff -r 4a23e38b7a12d65b50ff274272305f89fb5d0309 -r 955d18fc07d52cb38b6d4e34992112527c2a4f52 lib/galaxy/web/controllers/workflow.py
--- a/lib/galaxy/web/controllers/workflow.py
+++ b/lib/galaxy/web/controllers/workflow.py
@@ -986,7 +986,7 @@
"""
# Get workflow XML.
# Get workflow content.
- conn = httplib.HTTPConnection( self.__myexp_url )
+ conn = httplib.HTTPConnection( trans.app.config.get( "myexperiment_url", self.__myexp_url ) )
# NOTE: blocks web thread.
headers = {}
if myexp_username and myexp_password:
@@ -1055,7 +1055,7 @@
# Do request and get result.
auth_header = base64.b64encode( '%s:%s' % ( myexp_username, myexp_password ))
headers = { "Content-type": "text/xml", "Accept": "text/xml", "Authorization" : "Basic %s" % auth_header }
- conn = httplib.HTTPConnection( self.__myexp_url )
+ conn = httplib.HTTPConnection( trans.app.config.get( "myexperiment_url", self.__myexp_url ) )
# NOTE: blocks web thread.
conn.request("POST", "/workflow.xml", request, headers)
response = conn.getresponse()
diff -r 4a23e38b7a12d65b50ff274272305f89fb5d0309 -r 955d18fc07d52cb38b6d4e34992112527c2a4f52 universe_wsgi.ini.sample
--- a/universe_wsgi.ini.sample
+++ b/universe_wsgi.ini.sample
@@ -653,6 +653,9 @@
#pbs_stage_path =
#pbs_dataset_server =
+# The URL to the myExperiment instance being used (omit scheme but include port)
+myexperiment_url = www.myexperiment.org:80
+
# ---- Tool Job Runners -----------------------------------------------------
# Individual per-tool job runner overrides. Parameters can be included to define
https://bitbucket.org/galaxy/galaxy-central/changeset/3ac664d53a15/
changeset: 3ac664d53a15
user: fbacall
date: 2012-03-26 14:47:06
summary: Added link to myExperiment on the import_workflow page
affected #: 2 files
diff -r 955d18fc07d52cb38b6d4e34992112527c2a4f52 -r 3ac664d53a15f1ea0995b9277a783990cd739220 lib/galaxy/web/controllers/workflow.py
--- a/lib/galaxy/web/controllers/workflow.py
+++ b/lib/galaxy/web/controllers/workflow.py
@@ -1124,6 +1124,9 @@
message = kwd.get( 'message', '' )
status = kwd.get( 'status', 'done' )
import_button = kwd.get( 'import_button', False )
+ # The special Galaxy integration landing page's URL on myExperiment
+ myexperiment_target_url = 'http://%s/galaxy?galaxy_url=%s' % \
+ ( trans.app.config.get( "myexperiment_url", "www.myexperiment.org" ), trans.request.base )
# The following parameters will have values only if the workflow
# id being imported from a Galaxy tool shed repository.
tool_shed_url = kwd.get( 'tool_shed_url', '' )
@@ -1269,7 +1272,8 @@
url=url,
message=message,
status=status,
- use_panels=True )
+ use_panels=True,
+ myexperiment_target_url=myexperiment_target_url )
@web.json
def get_datatypes( self, trans ):
ext_to_class_name = dict()
diff -r 955d18fc07d52cb38b6d4e34992112527c2a4f52 -r 3ac664d53a15f1ea0995b9277a783990cd739220 templates/workflow/import.mako
--- a/templates/workflow/import.mako
+++ b/templates/workflow/import.mako
@@ -48,6 +48,18 @@
<div style="clear: both"></div></div><div class="form-row">
+ <label>Import a Galaxy workflow from myExperiment:</label>
+ <div class="form-row-input">
+ <a href="${h.url_for( myexperiment_target_url )}">
+ Visit myExperiment
+ </a>
+ </div>
+ <div class="toolParamHelp" style="clear: both;">
+ Click the link above to visit myExperiment and browse for Galaxy workflows.
+ </div>
+ <div style="clear: both"></div>
+ </div>
+ <div class="form-row"><input type="submit" class="primary-button" name="import_button" value="Import"></div></form>
https://bitbucket.org/galaxy/galaxy-central/changeset/f02a38f851cc/
changeset: f02a38f851cc
user: fbacall
date: 2012-03-26 14:50:35
summary: Changed export feature to export workflow in pure JSON format rather than a XML/JSON hybrid
affected #: 1 file
diff -r 3ac664d53a15f1ea0995b9277a783990cd739220 -r f02a38f851cc7a5e19538471ff3b782359a1be55 lib/galaxy/web/controllers/workflow.py
--- a/lib/galaxy/web/controllers/workflow.py
+++ b/lib/galaxy/web/controllers/workflow.py
@@ -1037,11 +1037,8 @@
# Create and submit workflow myExperiment request.
#
- # Create workflow content XML.
- workflow_dict_packed = simplejson.dumps( workflow_dict, indent=4, sort_keys=True )
- workflow_content = trans.fill_template( "workflow/myexp_export_content.mako", \
- workflow_dict_packed=workflow_dict_packed, \
- workflow_steps=workflow_dict['steps'] )
+ # Create workflow content JSON.
+ workflow_content = simplejson.dumps( workflow_dict, indent=4, sort_keys=True )
# Create myExperiment request.
request_raw = trans.fill_template( "workflow/myexp_export.mako", \
https://bitbucket.org/galaxy/galaxy-central/changeset/2ac9b8cced40/
changeset: 2ac9b8cced40
user: fbacall
date: 2012-03-26 14:53:33
summary: Change import_from_myexp feature to understand pure JSON, but have not tested and am not sure this is even used...
affected #: 1 file
diff -r f02a38f851cc7a5e19538471ff3b782359a1be55 -r 2ac9b8cced40c3f18bc8eb71e03fdf583a7be3db lib/galaxy/web/controllers/workflow.py
--- a/lib/galaxy/web/controllers/workflow.py
+++ b/lib/galaxy/web/controllers/workflow.py
@@ -999,10 +999,8 @@
parser = SingleTagContentsParser( "content" )
parser.feed( workflow_xml )
workflow_content = base64.b64decode( parser.tag_content )
- # Process workflow XML and create workflow.
- parser = SingleTagContentsParser( "galaxy_json" )
- parser.feed( workflow_content )
- workflow_dict = from_json_string( parser.tag_content )
+ # Process workflow JSON and create workflow.
+ workflow_dict = from_json_string( workflow_content )
# Create workflow.
workflow, missing_tool_tups = self._workflow_from_dict( trans, workflow_dict, source="myExperiment" ).latest_workflow
if missing_tool_tups:
https://bitbucket.org/galaxy/galaxy-central/changeset/cf086646b83a/
changeset: cf086646b83a
user: fbacall
date: 2012-03-26 15:14:58
summary: Added extra optional parameter to allow the source of a workflow to be declared on import
affected #: 1 file
diff -r 2ac9b8cced40c3f18bc8eb71e03fdf583a7be3db -r cf086646b83a6100555f3cc779214db02f98d2b3 lib/galaxy/web/controllers/workflow.py
--- a/lib/galaxy/web/controllers/workflow.py
+++ b/lib/galaxy/web/controllers/workflow.py
@@ -1122,6 +1122,8 @@
# The special Galaxy integration landing page's URL on myExperiment
myexperiment_target_url = 'http://%s/galaxy?galaxy_url=%s' % \
( trans.app.config.get( "myexperiment_url", "www.myexperiment.org" ), trans.request.base )
+ # The source of the workflow, used by myExperiment to indicate the workflow came from there.
+ workflow_source = kwd.get( 'workflow_source', 'uploaded file' )
# The following parameters will have values only if the workflow
# id being imported from a Galaxy tool shed repository.
tool_shed_url = kwd.get( 'tool_shed_url', '' )
@@ -1192,7 +1194,7 @@
# Galaxy instance, the tool information will be available in the step_dict.
src = None
if cntrller != 'api':
- src="uploaded file"
+ src = workflow_source
workflow, missing_tool_tups = self._workflow_from_dict( trans, data, source=src, add_to_menu=add_to_menu )
workflow = workflow.latest_workflow
if workflow_name:
https://bitbucket.org/galaxy/galaxy-central/changeset/a6572ba77912/
changeset: a6572ba77912
user: fbacall
date: 2012-03-26 15:15:32
summary: Moved link to myExperiment to under the regular import form
affected #: 1 file
diff -r cf086646b83a6100555f3cc779214db02f98d2b3 -r a6572ba7791208ec23c12c065dbf6a1f461e4320 templates/workflow/import.mako
--- a/templates/workflow/import.mako
+++ b/templates/workflow/import.mako
@@ -48,21 +48,22 @@
<div style="clear: both"></div></div><div class="form-row">
- <label>Import a Galaxy workflow from myExperiment:</label>
- <div class="form-row-input">
- <a href="${h.url_for( myexperiment_target_url )}">
- Visit myExperiment
- </a>
- </div>
- <div class="toolParamHelp" style="clear: both;">
- Click the link above to visit myExperiment and browse for Galaxy workflows.
- </div>
- <div style="clear: both"></div>
- </div>
- <div class="form-row"><input type="submit" class="primary-button" name="import_button" value="Import"></div></form>
+ <hr/>
+ <div class="form-row">
+ <label>Import a Galaxy workflow from myExperiment:</label>
+ <div class="form-row-input">
+ <a href="${h.url_for( myexperiment_target_url )}">
+ Visit myExperiment
+ </a>
+ </div>
+ <div class="toolParamHelp" style="clear: both;">
+ Click the link above to visit myExperiment and browse for Galaxy workflows.
+ </div>
+ <div style="clear: both"></div>
+ </div></div></div></%def>
https://bitbucket.org/galaxy/galaxy-central/changeset/822594759b14/
changeset: 822594759b14
user: fbacall
date: 2012-03-26 15:27:58
summary: Changed method of getting current Galaxy instance URL
affected #: 1 file
diff -r a6572ba7791208ec23c12c065dbf6a1f461e4320 -r 822594759b1413101bb6e72b04e928570222bdbb lib/galaxy/web/controllers/workflow.py
--- a/lib/galaxy/web/controllers/workflow.py
+++ b/lib/galaxy/web/controllers/workflow.py
@@ -1121,7 +1121,7 @@
import_button = kwd.get( 'import_button', False )
# The special Galaxy integration landing page's URL on myExperiment
myexperiment_target_url = 'http://%s/galaxy?galaxy_url=%s' % \
- ( trans.app.config.get( "myexperiment_url", "www.myexperiment.org" ), trans.request.base )
+ ( trans.app.config.get( "myexperiment_url", "www.myexperiment.org" ), url_for('/', qualified=True) )
# The source of the workflow, used by myExperiment to indicate the workflow came from there.
workflow_source = kwd.get( 'workflow_source', 'uploaded file' )
# The following parameters will have values only if the workflow
https://bitbucket.org/galaxy/galaxy-central/changeset/6ad275d3dea8/
changeset: 6ad275d3dea8
user: fbacall
date: 2012-03-28 13:40:47
summary: Added ability to auth with myExperiment using a cookie. Improved some error messages
affected #: 1 file
diff -r 822594759b1413101bb6e72b04e928570222bdbb -r 6ad275d3dea8dc55bfe4df8af5a3709590a04924 lib/galaxy/web/controllers/workflow.py
--- a/lib/galaxy/web/controllers/workflow.py
+++ b/lib/galaxy/web/controllers/workflow.py
@@ -980,11 +980,15 @@
return trans.fill_template( "/workflow/export.mako", item=stored, use_panels=True )
@web.expose
@web.require_login( "use workflows" )
- def import_from_myexp( self, trans, myexp_id, myexp_username=None, myexp_password=None ):
+ def import_from_myexp( self, trans, myexp_id, **kwd ):
"""
Imports a workflow from the myExperiment website.
+ Authenticates either by using HTTP basic, or with a cookie.
"""
- # Get workflow XML.
+ # Parse parameters
+ myexp_username = kwd.get( 'myexp_username', None )
+ myexp_password = kwd.get( 'myexp_password', None )
+ myexp_cookie = kwd.get( 'myexp_cookie', None )
# Get workflow content.
conn = httplib.HTTPConnection( trans.app.config.get( "myexperiment_url", self.__myexp_url ) )
# NOTE: blocks web thread.
@@ -992,28 +996,36 @@
if myexp_username and myexp_password:
auth_header = base64.b64encode( '%s:%s' % ( myexp_username, myexp_password ))
headers = { "Authorization" : "Basic %s" % auth_header }
+ elif myexp_cookie:
+ headers = { "Cookie" : "myexperiment_session=%s" % myexp_cookie }
conn.request( "GET", "/workflow.xml?id=%s&elements=content" % myexp_id, headers=headers )
response = conn.getresponse()
- workflow_xml = response.read()
+ response_data = response.read()
conn.close()
- parser = SingleTagContentsParser( "content" )
- parser.feed( workflow_xml )
- workflow_content = base64.b64decode( parser.tag_content )
- # Process workflow JSON and create workflow.
- workflow_dict = from_json_string( workflow_content )
- # Create workflow.
- workflow, missing_tool_tups = self._workflow_from_dict( trans, workflow_dict, source="myExperiment" ).latest_workflow
- if missing_tool_tups:
- # TODO: handle the case where the imported workflow requires tools that are not available in
- # the local Galaxy instance.
- pass
+ if response.status == 200:
+ parser = SingleTagContentsParser( "content" )
+ parser.feed( response_data )
+ workflow_content = base64.b64decode( parser.tag_content )
+ # Process workflow JSON and create workflow.
+ workflow_dict = from_json_string( workflow_content )
+ # Create workflow.
+ workflow, missing_tool_tups = self._workflow_from_dict( trans, workflow_dict, source="myExperiment" )
+ workflow = workflow.latest_workflow
+ if missing_tool_tups:
+ # TODO: handle the case where the imported workflow requires tools that are not available in
+ # the local Galaxy instance.
+ pass
+
# Provide user feedback.
+ workflow_list_str = " <br>Return to <a href='%s'>workflow list." % url_for( action='list' )
+ if response.status != 200:
+ return trans.show_error_message( "There was a problem importing the workflow. Error: %s %s" % (response_data, workflow_list_str) )
if workflow.has_errors:
- return trans.show_warn_message( "Imported, but some steps in this workflow have validation errors" )
+ return trans.show_warn_message( "Imported, but some steps in this workflow have validation errors. %s" % workflow_list_str )
if workflow.has_cycles:
- return trans.show_warn_message( "Imported, but this workflow contains cycles" )
+ return trans.show_warn_message( "Imported, but this workflow contains cycles. %s" % workflow_list_str )
else:
- return trans.show_message( "Workflow '%s' imported" % workflow.name )
+ return trans.show_message( "Workflow '%s' imported. %s" % (workflow.name, workflow_list_str) )
@web.expose
@web.require_login( "use workflows" )
def export_to_myexp( self, trans, id, myexp_username, myexp_password ):
@@ -1050,7 +1062,8 @@
# Do request and get result.
auth_header = base64.b64encode( '%s:%s' % ( myexp_username, myexp_password ))
headers = { "Content-type": "text/xml", "Accept": "text/xml", "Authorization" : "Basic %s" % auth_header }
- conn = httplib.HTTPConnection( trans.app.config.get( "myexperiment_url", self.__myexp_url ) )
+ myexp_url = trans.app.config.get( "myexperiment_url", self.__myexp_url )
+ conn = httplib.HTTPConnection( myexp_url )
# NOTE: blocks web thread.
conn.request("POST", "/workflow.xml", request, headers)
response = conn.getresponse()
@@ -1064,12 +1077,13 @@
workflow_list_str = " <br>Return to <a href='%s'>workflow list." % url_for( action='list' )
if myexp_workflow_id:
return trans.show_message( \
- "Workflow '%s' successfully exported to myExperiment. %s" % \
- ( stored.name, workflow_list_str ),
+ """Workflow '%s' successfully exported to myExperiment. <br/>
+ <a href="http://%s/workflows/%s">Click here to view the workflow on myExperiment</a> %s
+ """ % ( stored.name, myexp_url, myexp_workflow_id, workflow_list_str ),
use_panels=True )
else:
return trans.show_error_message( \
- "Workflow '%s' could not be exported to myExperiment. Error: %s. %s" % \
+ "Workflow '%s' could not be exported to myExperiment. Error: %s %s" % \
( stored.name, response_data, workflow_list_str ), use_panels=True )
@web.json_pretty
https://bitbucket.org/galaxy/galaxy-central/changeset/1187e46dfbdf/
changeset: 1187e46dfbdf
user: fbacall
date: 2012-03-28 14:15:05
summary: Decided to post actual workflow across to avoid security issues#
affected #: 1 file
diff -r 6ad275d3dea8dc55bfe4df8af5a3709590a04924 -r 1187e46dfbdfea72208abd5a9129ed3dce66fafa lib/galaxy/web/controllers/workflow.py
--- a/lib/galaxy/web/controllers/workflow.py
+++ b/lib/galaxy/web/controllers/workflow.py
@@ -984,6 +984,7 @@
"""
Imports a workflow from the myExperiment website.
Authenticates either by using HTTP basic, or with a cookie.
+ !!! This isn't currently used. MyExperiment uses the generic import_workflow method !!!
"""
# Parse parameters
myexp_username = kwd.get( 'myexp_username', None )
https://bitbucket.org/galaxy/galaxy-central/changeset/1744124f8ee4/
changeset: 1744124f8ee4
user: jgoecks
date: 2012-05-10 22:27:33
summary: Merged in fbacall/galaxy-central-myexp-integration (pull request #45)
affected #: 294 files
Diff too large to display.
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: jgoecks: Support UnvalidatedValues when exporting histories.
by Bitbucket 10 May '12
by Bitbucket 10 May '12
10 May '12
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/changeset/cc70c3dcd6f7/
changeset: cc70c3dcd6f7
user: jgoecks
date: 2012-05-10 20:08:48
summary: Support UnvalidatedValues when exporting histories.
affected #: 1 file
diff -r 67b5abaaf8bc702529a91a5d1d69318a2aaf6c75 -r cc70c3dcd6f7088d9d1b73e70602162d44172328 lib/galaxy/tools/imp_exp/__init__.py
--- a/lib/galaxy/tools/imp_exp/__init__.py
+++ b/lib/galaxy/tools/imp_exp/__init__.py
@@ -1,5 +1,6 @@
import os, shutil, logging, tempfile, simplejson
from galaxy import model
+from galaxy.tools.parameters.basic import UnvalidatedValue
from galaxy.web.framework.helpers import to_unicode
from galaxy.model.item_attrs import UsesAnnotations
from galaxy.util.json import *
@@ -324,6 +325,8 @@
"annotation" : to_unicode( getattr( obj, 'annotation', '' ) ),
"tags" : get_item_tag_dict( obj ),
}
+ if isinstance( obj, UnvalidatedValue ):
+ return obj.__str__()
return simplejson.JSONEncoder.default( self, obj )
#
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: inithello: Add admin tool to download and index a reference genome.
by Bitbucket 10 May '12
by Bitbucket 10 May '12
10 May '12
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/changeset/67b5abaaf8bc/
changeset: 67b5abaaf8bc
user: inithello
date: 2012-05-10 18:55:29
summary: Add admin tool to download and index a reference genome.
affected #: 19 files
diff -r b5090cb8044469b7f5d3136cedbe80f009745f0b -r 67b5abaaf8bc702529a91a5d1d69318a2aaf6c75 lib/galaxy/app.py
--- a/lib/galaxy/app.py
+++ b/lib/galaxy/app.py
@@ -12,6 +12,7 @@
import galaxy.quota
from galaxy.tags.tag_handler import GalaxyTagHandler
from galaxy.tools.imp_exp import load_history_imp_exp_tools
+from galaxy.tools.genome_index import load_genome_index_tools
from galaxy.sample_tracking import external_service_types
from galaxy.openid.providers import OpenIDProviders
@@ -90,6 +91,8 @@
self.datatypes_registry.load_external_metadata_tool( self.toolbox )
# Load history import/export tools.
load_history_imp_exp_tools( self.toolbox )
+ # Load genome indexer tool.
+ load_genome_index_tools( self.toolbox )
# Load security policy.
self.security_agent = self.model.security_agent
self.host_security_agent = galaxy.security.HostAgent( model=self.security_agent.model, permitted_actions=self.security_agent.permitted_actions )
diff -r b5090cb8044469b7f5d3136cedbe80f009745f0b -r 67b5abaaf8bc702529a91a5d1d69318a2aaf6c75 lib/galaxy/config.py
--- a/lib/galaxy/config.py
+++ b/lib/galaxy/config.py
@@ -42,6 +42,7 @@
tempfile.tempdir = self.new_file_path
self.openid_consumer_cache_path = resolve_path( kwargs.get( "openid_consumer_cache_path", "database/openid_consumer_cache" ), self.root )
self.cookie_path = kwargs.get( "cookie_path", "/" )
+ self.genome_data_path = kwargs.get( "genome_data_path", "tool-data/genome" )
# Galaxy OpenID settings
self.enable_openid = string_as_bool( kwargs.get( 'enable_openid', False ) )
self.openid_config = kwargs.get( 'openid_config_file', 'openid_conf.xml' )
diff -r b5090cb8044469b7f5d3136cedbe80f009745f0b -r 67b5abaaf8bc702529a91a5d1d69318a2aaf6c75 lib/galaxy/jobs/__init__.py
--- a/lib/galaxy/jobs/__init__.py
+++ b/lib/galaxy/jobs/__init__.py
@@ -144,9 +144,12 @@
self.file_name = dataset.file_name
self.metadata = dict()
self.children = []
- jeha = self.sa_session.query( model.JobExportHistoryArchive ).filter_by( job=job ).first()
- if jeha:
- out_data[ "output_file" ] = FakeDatasetAssociation( dataset=jeha.dataset )
+ special = self.sa_session.query( model.JobExportHistoryArchive ).filter_by( job=job ).first()
+ if not special:
+ special = self.sa_session.query( model.GenomeIndexToolData ).filter_by( job=job ).first()
+ if special:
+ out_data[ "output_file" ] = FakeDatasetAssociation( dataset=special.dataset )
+
# These can be passed on the command line if wanted as $userId $userEmail
if job.history and job.history.user: # check for anonymous user!
userId = '%d' % job.history.user.id
@@ -442,6 +445,9 @@
param_dict = self.tool.params_from_strings( param_dict, self.app )
# Check for and move associated_files
self.tool.collect_associated_files(out_data, self.working_directory)
+ gitd = self.sa_session.query( model.GenomeIndexToolData ).filter_by( job=job ).first()
+ if gitd:
+ self.tool.collect_associated_files({'' : gitd}, self.working_directory)
# Create generated output children and primary datasets and add to param_dict
collected_datasets = {'children':self.tool.collect_child_datasets(out_data, self.working_directory),'primary':self.tool.collect_primary_datasets(out_data, self.working_directory)}
param_dict.update({'__collected_datasets__':collected_datasets})
@@ -480,6 +486,7 @@
self.external_output_metadata.cleanup_external_metadata( self.sa_session )
galaxy.tools.imp_exp.JobExportHistoryArchiveWrapper( self.job_id ).cleanup_after_job( self.sa_session )
galaxy.tools.imp_exp.JobImportHistoryArchiveWrapper( self.job_id ).cleanup_after_job( self.sa_session )
+ galaxy.tools.genome_index.GenomeIndexToolWrapper( self.job_id ).postprocessing( self.sa_session, self.app )
self.app.object_store.delete(self.get_job(), base_dir='job_work', entire_dir=True, dir_only=True, extra_dir=str(self.job_id))
except:
log.exception( "Unable to cleanup job %d" % self.job_id )
@@ -535,9 +542,11 @@
else:
return self.false_path
job = self.get_job()
- # Job output datasets are combination of output datasets, library datasets, and jeha datasets.
- jeha = self.sa_session.query( model.JobExportHistoryArchive ).filter_by( job=job ).first()
- jeha_false_path = None
+ # Job output datasets are combination of history, library, jeha and gitd datasets.
+ special = self.sa_session.query( model.JobExportHistoryArchive ).filter_by( job=job ).first()
+ if not special:
+ special = self.sa_session.query( model.GenomeIndexToolData ).filter_by( job=job ).first()
+ false_path = None
if self.app.config.outputs_to_working_directory:
self.output_paths = []
self.output_hdas_and_paths = {}
@@ -546,14 +555,14 @@
dsp = DatasetPath( hda.dataset.id, hda.dataset.file_name, false_path )
self.output_paths.append( dsp )
self.output_hdas_and_paths[name] = hda, dsp
- if jeha:
- jeha_false_path = os.path.abspath( os.path.join( self.working_directory, "galaxy_dataset_%d.dat" % jeha.dataset.id ) )
+ if special:
+ false_path = os.path.abspath( os.path.join( self.working_directory, "galaxy_dataset_%d.dat" % special.dataset.id ) )
else:
results = [ ( da.name, da.dataset, DatasetPath( da.dataset.dataset.id, da.dataset.file_name ) ) for da in job.output_datasets + job.output_library_datasets ]
self.output_paths = [t[2] for t in results]
self.output_hdas_and_paths = dict([(t[0], t[1:]) for t in results])
- if jeha:
- dsp = DatasetPath( jeha.dataset.id, jeha.dataset.file_name, jeha_false_path )
+ if special:
+ dsp = DatasetPath( special.dataset.id, special.dataset.file_name, false_path )
self.output_paths.append( dsp )
return self.output_paths
diff -r b5090cb8044469b7f5d3136cedbe80f009745f0b -r 67b5abaaf8bc702529a91a5d1d69318a2aaf6c75 lib/galaxy/jobs/deferred/genome_transfer.py
--- /dev/null
+++ b/lib/galaxy/jobs/deferred/genome_transfer.py
@@ -0,0 +1,250 @@
+"""
+Module for managing genome transfer jobs.
+"""
+import logging, shutil, gzip, bz2, zipfile, tempfile, tarfile, sys
+
+from galaxy import eggs
+from sqlalchemy import and_
+
+from galaxy.util.odict import odict
+from galaxy.workflow.modules import module_factory
+from galaxy.jobs.actions.post import ActionBox
+
+from galaxy.tools.parameters import visit_input_values
+from galaxy.tools.parameters.basic import DataToolParameter
+from galaxy.tools.data import ToolDataTableManager
+
+from galaxy.datatypes.checkers import *
+from galaxy.datatypes.sequence import Fasta
+from data_transfer import *
+
+log = logging.getLogger( __name__ )
+
+__all__ = [ 'GenomeTransferPlugin' ]
+
+class GenomeTransferPlugin( DataTransfer ):
+
+ locations = {}
+
+ def __init__( self, app ):
+ super( GenomeTransferPlugin, self ).__init__( app )
+ self.app = app
+ self.tool = app.toolbox.tools_by_id['__GENOME_INDEX__']
+ self.sa_session = app.model.context.current
+ tdtman = ToolDataTableManager()
+ xmltree = tdtman.load_from_config_file(app.config.tool_data_table_config_path)
+ for node in xmltree:
+ table = node.get('name')
+ location = node.findall('file')[0].get('path')
+ self.locations[table] = location
+
+ def create_job( self, trans, url, dbkey, intname, indexes ):
+ job = trans.app.transfer_manager.new( protocol='http', url=url )
+ params = dict( user=trans.user.id, transfer_job_id=job.id, protocol='http', type='init_transfer', url=url, dbkey=dbkey, indexes=indexes, intname=intname, liftover=None )
+ deferred = trans.app.model.DeferredJob( state = self.app.model.DeferredJob.states.NEW, plugin = 'GenomeTransferPlugin', params = params )
+ self.sa_session.add( deferred )
+ self.sa_session.flush()
+ return deferred.id
+
+ def check_job( self, job ):
+ if job.params['type'] == 'init_transfer':
+ if not hasattr(job, 'transfer_job'):
+ job.transfer_job = self.sa_session.query( self.app.model.TransferJob ).get( int( job.params[ 'transfer_job_id' ] ) )
+ else:
+ self.sa_session.refresh( job.transfer_job )
+ if job.transfer_job.state == 'done':
+ transfer = job.transfer_job
+ transfer.state = 'downloaded'
+ job.params['type'] = 'extract_transfer'
+ self.sa_session.add( job )
+ self.sa_session.add( transfer )
+ self.sa_session.flush()
+ return self.job_states.READY
+ elif job.transfer_job.state == 'running':
+ return self.job_states.WAIT
+ elif job.transfer_job.state == 'new':
+ assert job.params[ 'protocol' ] in [ 'http', 'ftp', 'https' ], 'Unknown protocol %s' % job.params[ 'protocol' ]
+ self.app.transfer_manager.run( job.transfer_job )
+ self.sa_session.add( job.transfer_job )
+ self.sa_session.flush()
+ return self.job_states.WAIT
+ else:
+ log.error( "An error occurred while downloading from %s" % job.params[ 'url' ] )
+ return self.job_states.INVALID
+ elif job.params[ 'type' ] == 'extract_transfer':
+ return self.job_states.READY
+
+ def get_job_status( self, jobid ):
+ job = self.sa_session.query( self.app.model.DeferredJob ).get( int( jobid ) )
+ if not hasattr( job, 'transfer_job' ):
+ job.transfer_job = self.sa_session.query( self.app.model.TransferJob ).get( int( job.params[ 'transfer_job_id' ] ) )
+ else:
+ self.sa_session.refresh( job.transfer_job )
+ return job
+
+ def run_job( self, job ):
+ params = job.params
+ dbkey = params[ 'dbkey' ]
+ if not hasattr( job, 'transfer_job' ):
+ job.transfer_job = self.sa_session.query( self.app.model.TransferJob ).get( int( job.params[ 'transfer_job_id' ] ) )
+ else:
+ self.sa_session.refresh( job.transfer_job )
+ transfer = job.transfer_job
+ if params[ 'type' ] == 'extract_transfer':
+ CHUNK_SIZE = 2**20
+ destpath = os.path.join( self.app.config.get( 'genome_data_path', 'tool-data/genome' ), job.params[ 'dbkey' ], 'seq' )
+ destfile = '%s.fa' % job.params[ 'dbkey' ]
+ destfilepath = os.path.join( destpath, destfile )
+ tmpprefix = '%s_%s_download_unzip_' % ( job.params['dbkey'], job.params[ 'transfer_job_id' ] )
+ tmppath = os.path.dirname( os.path.abspath( transfer.path ) )
+ if not os.path.exists( destpath ):
+ os.makedirs( destpath )
+ protocol = job.params[ 'protocol' ]
+ data_type = self._check_compress( transfer.path )
+ if data_type is None:
+ sniffer = Fasta()
+ if sniffer.sniff( transfer.path ):
+ data_type = 'fasta'
+ fd, uncompressed = tempfile.mkstemp( prefix=tmpprefix, dir=tmppath, text=False )
+ if data_type in [ 'tar.gzip', 'tar.bzip' ]:
+ fp = open( transfer.path, 'r' )
+ tar = tarfile.open( mode = 'r:*', bufsize = CHUNK_SIZE, fileobj = fp )
+ files = tar.getmembers()
+ for filename in files:
+ z = tar.extractfile(filename)
+ try:
+ chunk = z.read( CHUNK_SIZE )
+ except IOError:
+ os.close( fd )
+ log.error( 'Problem decompressing compressed data' )
+ exit()
+ if not chunk:
+ break
+ os.write( fd, chunk )
+ os.write( fd, '\n' )
+ os.close( fd )
+ tar.close()
+ fp.close()
+ elif data_type == 'gzip':
+ compressed = gzip.open( transfer.path, mode = 'rb' )
+ while 1:
+ try:
+ chunk = compressed.read( CHUNK_SIZE )
+ except IOError:
+ compressed.close()
+ log.error( 'Problem decompressing compressed data' )
+ exit()
+ if not chunk:
+ break
+ os.write( fd, chunk )
+ os.write( fd, '\n' )
+ os.close( fd )
+ compressed.close()
+ elif data_type == 'bzip':
+ compressed = bz2.BZ2File( transfer.path, mode = 'r' )
+ while 1:
+ try:
+ chunk = compressed.read( CHUNK_SIZE )
+ except IOError:
+ compressed.close()
+ log.error( 'Problem decompressing compressed data' )
+ exit()
+ if not chunk:
+ break
+ os.write( fd, chunk )
+ os.write( fd, '\n' )
+ os.close( fd )
+ compressed.close()
+ elif data_type == 'zip':
+ uncompressed_name = None
+ unzipped = False
+ z = zipfile.ZipFile( transfer.path )
+ z.debug = 3
+ for name in z.namelist():
+ if name.endswith('/'):
+ continue
+ if sys.version_info[:2] >= ( 2, 6 ):
+ zipped_file = z.open( name )
+ while 1:
+ try:
+ chunk = zipped_file.read( CHUNK_SIZE )
+ except IOError:
+ os.close( fd )
+ log.error( 'Problem decompressing zipped data' )
+ return self.app.model.DeferredJob.states.INVALID
+ if not chunk:
+ break
+ os.write( fd, chunk )
+ os.write( fd, '\n' )
+ zipped_file.close()
+ else:
+ try:
+ outfile = open( fd, 'wb' )
+ outfile.write( z.read( name ) )
+ outfile.close()
+ except IOError:
+ os.close( fd )
+ log.error( 'Problem decompressing zipped data' )
+ return
+ os.close( fd )
+ z.close()
+ elif data_type == 'fasta':
+ uncompressed = transfer.path
+ else:
+ job.state = self.app.model.DeferredJob.states.INVALID
+ log.error( "Unrecognized compression format for file %s." % transfer.path )
+ self.sa_session.add( job )
+ self.sa_session.flush()
+ return
+ shutil.move( uncompressed, destfilepath )
+ if os.path.exists( transfer.path ):
+ os.remove( transfer.path )
+ os.chmod( destfilepath, 0644 )
+ fastaline = '\t'.join( [ dbkey, dbkey, params[ 'intname' ], os.path.abspath( destfilepath ) ] )
+ self._add_line( 'all_fasta', fastaline )
+ job.state = self.app.model.DeferredJob.states.OK
+ job.params[ 'type' ] = 'finish_transfer'
+ transfer.path = os.path.abspath(destfilepath)
+ transfer.state = 'done'
+ self.sa_session.add( job )
+ self.sa_session.add( transfer )
+ self.sa_session.flush()
+ if transfer.state == 'done' and params[ 'indexes' ] is not None:
+ for indexer in params[ 'indexes' ]:
+ incoming = dict(indexer=indexer, dbkey=params[ 'dbkey' ], intname=params[ 'intname' ], path=transfer.path, user=params['user'] )
+ deferred = self.tool.execute( self, set_output_hid=False, history=None, incoming=incoming, transfer=transfer, deferred=job )
+ return self.app.model.DeferredJob.states.OK
+
+ def _check_compress( self, filepath ):
+ retval = ''
+ if tarfile.is_tarfile( filepath ):
+ retval = 'tar.'
+ if check_zip( filepath ):
+ return 'zip'
+ is_bzipped, is_valid = check_bz2( filepath )
+ if is_bzipped and is_valid:
+ return retval + 'bzip'
+ is_gzipped, is_valid = check_gzip( filepath )
+ if is_gzipped and is_valid:
+ return retval + 'gzip'
+ return None
+
+ def _add_line( self, locfile, newline ):
+ filepath = self.locations[ locfile ]
+ origlines = []
+ output = []
+ comments = []
+ with open( filepath, 'r' ) as destfile:
+ for line in destfile:
+ if line.startswith( '#' ):
+ comments.append( line.strip() )
+ else:
+ origlines.append( line.strip() )
+ if newline not in origlines:
+ origlines.append( newline )
+ output.extend( comments )
+ origlines.sort()
+ output.extend( origlines )
+ with open( filepath, 'w+' ) as destfile:
+ destfile.write( '\n'.join( output ) )
+
diff -r b5090cb8044469b7f5d3136cedbe80f009745f0b -r 67b5abaaf8bc702529a91a5d1d69318a2aaf6c75 lib/galaxy/jobs/deferred/liftover_transfer.py
--- /dev/null
+++ b/lib/galaxy/jobs/deferred/liftover_transfer.py
@@ -0,0 +1,134 @@
+"""
+Module for managing genome transfer jobs.
+"""
+import logging, shutil, gzip, tempfile, sys
+
+from galaxy import eggs
+from sqlalchemy import and_
+
+from galaxy.util.odict import odict
+from galaxy.workflow.modules import module_factory
+from galaxy.jobs.actions.post import ActionBox
+
+from galaxy.tools.parameters import visit_input_values
+from galaxy.tools.parameters.basic import DataToolParameter
+from galaxy.tools.data import ToolDataTableManager
+
+from galaxy.datatypes.checkers import *
+
+from data_transfer import *
+
+log = logging.getLogger( __name__ )
+
+__all__ = [ 'LiftOverTransferPlugin' ]
+
+class LiftOverTransferPlugin( DataTransfer ):
+
+ locations = {}
+
+ def __init__( self, app ):
+ super( LiftOverTransferPlugin, self ).__init__( app )
+ self.app = app
+ self.sa_session = app.model.context.current
+
+ def create_job( self, trans, url, dbkey, from_genome, to_genome, destfile ):
+ job = trans.app.transfer_manager.new( protocol='http', url=url )
+ params = dict( user=trans.user.id, transfer_job_id=job.id, protocol='http',
+ type='init_transfer', dbkey=dbkey, from_genome=from_genome,
+ to_genome=to_genome, destfile=destfile )
+ deferred = trans.app.model.DeferredJob( state = self.app.model.DeferredJob.states.NEW, plugin = 'LiftOverTransferPlugin', params = params )
+ self.sa_session.add( deferred )
+ self.sa_session.flush()
+ return deferred.id
+
+ def check_job( self, job ):
+ if job.params['type'] == 'init_transfer':
+ if not hasattr(job, 'transfer_job'):
+ job.transfer_job = self.sa_session.query( self.app.model.TransferJob ).get( int( job.params[ 'transfer_job_id' ] ) )
+ else:
+ self.sa_session.refresh( job.transfer_job )
+ if job.transfer_job.state == 'done':
+ transfer = job.transfer_job
+ transfer.state = 'downloaded'
+ job.params['type'] = 'extract_transfer'
+ self.sa_session.add( job )
+ self.sa_session.add( transfer )
+ self.sa_session.flush()
+ return self.job_states.READY
+ elif job.transfer_job.state == 'running':
+ return self.job_states.WAIT
+ elif job.transfer_job.state == 'new':
+ assert job.params[ 'protocol' ] in [ 'http', 'ftp', 'https' ], 'Unknown protocol %s' % job.params[ 'protocol' ]
+ self.app.transfer_manager.run( job.transfer_job )
+ self.sa_session.add( job.transfer_job )
+ self.sa_session.flush()
+ return self.job_states.WAIT
+ else:
+ log.error( "An error occurred while downloading from %s" % job.params[ 'url' ] )
+ return self.job_states.INVALID
+ elif job.params[ 'type' ] == 'extract_transfer':
+ return self.job_states.READY
+
+ def get_job_status( self, jobid ):
+ job = self.sa_session.query( self.app.model.DeferredJob ).get( int( jobid ) )
+ return job
+
+ def run_job( self, job ):
+ params = job.params
+ dbkey = params[ 'dbkey' ]
+ source = params[ 'from_genome' ]
+ target = params[ 'to_genome' ]
+ if not hasattr( job, 'transfer_job' ):
+ job.transfer_job = self.sa_session.query( self.app.model.TransferJob ).get( int( job.params[ 'transfer_job_id' ] ) )
+ else:
+ self.sa_session.refresh( job.transfer_job )
+ transfer = job.transfer_job
+ if params[ 'type' ] == 'extract_transfer':
+ CHUNK_SIZE = 2**20
+ destpath = os.path.join( self.app.config.get( 'genome_data_path', 'tool-data/genome' ), job.params[ 'dbkey' ], 'liftOver' )
+ destfile = job.params[ 'destfile' ]
+ destfilepath = os.path.join( destpath, destfile )
+ tmpprefix = '%s_%s_download_unzip_' % ( job.params['dbkey'], job.params[ 'transfer_job_id' ] )
+ tmppath = os.path.dirname( os.path.abspath( transfer.path ) )
+ if not os.path.exists( destpath ):
+ os.makedirs( destpath )
+ fd, uncompressed = tempfile.mkstemp( prefix=tmpprefix, dir=tmppath, text=False )
+ chain = gzip.open( transfer.path, 'rb' )
+ while 1:
+ try:
+ chunk = chain.read( CHUNK_SIZE )
+ except IOError:
+ os.close( fd )
+ log.error( 'Problem decompressing compressed data' )
+ exit()
+ if not chunk:
+ break
+ os.write( fd, chunk )
+ os.close( fd )
+ chain.close()
+ # Replace the gzipped file with the decompressed file if it's safe to do so
+ shutil.move( uncompressed, destfilepath )
+ os.remove( transfer.path )
+ os.chmod( destfilepath, 0644 )
+ locline = '\t'.join( [ source, target, os.path.abspath( destfilepath ) ] )
+ self._add_line( locline )
+ job.state = self.app.model.DeferredJob.states.OK
+ job.params[ 'type' ] = 'finish_transfer'
+ transfer.path = os.path.abspath(destfilepath)
+ transfer.state = 'done'
+ self.sa_session.add( job )
+ self.sa_session.add( transfer )
+ self.sa_session.flush()
+ return self.app.model.DeferredJob.states.OK
+
+ def _add_line( self, newline ):
+ filepath = 'tool-data/liftOver.loc'
+ origlines = []
+ with open( filepath, 'r' ) as destfile:
+ for line in destfile:
+ origlines.append( line.strip() )
+ if newline not in origlines:
+ origlines.append( newline )
+ with open( filepath, 'w+' ) as destfile:
+ destfile.write( '\n'.join( origlines ) )
+
diff -r b5090cb8044469b7f5d3136cedbe80f009745f0b -r 67b5abaaf8bc702529a91a5d1d69318a2aaf6c75 lib/galaxy/model/__init__.py
--- a/lib/galaxy/model/__init__.py
+++ b/lib/galaxy/model/__init__.py
@@ -301,6 +301,20 @@
self.history = history
self.archive_dir=archive_dir
+class GenomeIndexToolData( object ):
+ def __init__( self, job=None, params=None, dataset=None, deferred_job=None, \
+ transfer_job=None, fasta_path=None, created_time=None, modified_time=None, \
+ dbkey=None, user=None, indexer=None ):
+ self.job = job
+ self.dataset = dataset
+ self.fasta_path = fasta_path
+ self.user = user
+ self.indexer = indexer
+ self.created_time = created_time
+ self.modified_time = modified_time
+ self.deferred = deferred_job
+ self.transfer = transfer_job
+
class DeferredJob( object ):
states = Bunch( NEW = 'new',
WAITING = 'waiting',
diff -r b5090cb8044469b7f5d3136cedbe80f009745f0b -r 67b5abaaf8bc702529a91a5d1d69318a2aaf6c75 lib/galaxy/model/mapping.py
--- a/lib/galaxy/model/mapping.py
+++ b/lib/galaxy/model/mapping.py
@@ -492,6 +492,19 @@
Column( "archive_dir", TEXT )
)
+GenomeIndexToolData.table = Table( "genome_index_tool_data", metadata,
+ Column( "id", Integer, primary_key=True ),
+ Column( "job_id", Integer, ForeignKey( "job.id" ), index=True ),
+ Column( "deferred_job_id", Integer, ForeignKey( "deferred_job.id" ), index=True ),
+ Column( "transfer_job_id", Integer, ForeignKey( "transfer_job.id" ), index=True ),
+ Column( "dataset_id", Integer, ForeignKey( "dataset.id" ), index=True ),
+ Column( "fasta_path", String( 255 ) ),
+ Column( "created_time", DateTime, default=now ),
+ Column( "modified_time", DateTime, default=now, onupdate=now ),
+ Column( "indexer", String( 64 ) ),
+ Column( "user_id", Integer, ForeignKey( "galaxy_user.id" ), index=True ),
+ )
+
Task.table = Table( "task", metadata,
Column( "id", Integer, primary_key=True ),
Column( "create_time", DateTime, default=now ),
@@ -1512,6 +1525,13 @@
assign_mapper( context, JobImportHistoryArchive, JobImportHistoryArchive.table,
properties=dict( job = relation( Job ), history = relation( History ) ) )
+assign_mapper( context, GenomeIndexToolData, GenomeIndexToolData.table,
+ properties=dict( job = relation( Job ),
+ dataset = relation( Dataset ),
+ user = relation( User ),
+ deferred = relation( DeferredJob, backref='deferred_job' ),
+ transfer = relation( TransferJob, backref='transfer_job' ) ) )
+
assign_mapper( context, PostJobAction, PostJobAction.table,
properties=dict(workflow_step = relation( WorkflowStep, backref='post_job_actions', primaryjoin=(WorkflowStep.table.c.id == PostJobAction.table.c.workflow_step_id))))
diff -r b5090cb8044469b7f5d3136cedbe80f009745f0b -r 67b5abaaf8bc702529a91a5d1d69318a2aaf6c75 lib/galaxy/model/migrate/versions/0098_genome_index_tool_data_table.py
--- /dev/null
+++ b/lib/galaxy/model/migrate/versions/0098_genome_index_tool_data_table.py
@@ -0,0 +1,53 @@
+"""
+Migration script to create the genome_index_tool_data table.
+"""
+
+from sqlalchemy import *
+from migrate import *
+
+import datetime
+now = datetime.datetime.utcnow
+
+# Need our custom types, but don't import anything else from model
+from galaxy.model.custom_types import *
+
+import sys, logging
+log = logging.getLogger( __name__ )
+log.setLevel(logging.DEBUG)
+handler = logging.StreamHandler( sys.stdout )
+format = "%(name)s %(levelname)s %(asctime)s %(message)s"
+formatter = logging.Formatter( format )
+handler.setFormatter( formatter )
+log.addHandler( handler )
+
+metadata = MetaData( migrate_engine )
+
+# New table in changeset TODO:TODO
+GenomeIndexToolData_table = Table( "genome_index_tool_data", metadata,
+ Column( "id", Integer, primary_key=True ),
+ Column( "job_id", Integer, ForeignKey( "job.id" ), index=True ),
+ Column( "dataset_id", Integer, ForeignKey( "dataset.id" ), index=True ),
+ Column( "deferred_job_id", Integer, ForeignKey( "deferred_job.id" ), index=True ),
+ Column( "transfer_job_id", Integer, ForeignKey( "transfer_job.id" ), index=True ),
+ Column( "fasta_path", String( 255 ) ),
+ Column( "created_time", DateTime, default=now ),
+ Column( "modified_time", DateTime, default=now, onupdate=now ),
+ Column( "indexer", String( 64 ) ),
+ Column( "user_id", Integer, ForeignKey( "galaxy_user.id" ), index=True ),
+ )
+
+def upgrade():
+ print __doc__
+
+ metadata.reflect()
+ try:
+ GenomeIndexToolData_table.create()
+ except Exception, e:
+ log.debug( "Creating genome_index_tool_data table failed: %s" % str( e ) )
+
+def downgrade():
+ metadata.reflect()
+ try:
+ GenomeIndexToolData_table.drop()
+ except Exception, e:
+ log.debug( "Dropping genome_index_tool_data table failed: %s" % str( e ) )
diff -r b5090cb8044469b7f5d3136cedbe80f009745f0b -r 67b5abaaf8bc702529a91a5d1d69318a2aaf6c75 lib/galaxy/tools/__init__.py
--- a/lib/galaxy/tools/__init__.py
+++ b/lib/galaxy/tools/__init__.py
@@ -2556,6 +2556,9 @@
class ImportHistoryTool( Tool ):
tool_type = 'import_history'
+class GenomeIndexTool( Tool ):
+ tool_type = 'index_genome'
+
# Populate tool_type to ToolClass mappings
tool_types = {}
for tool_class in [ Tool, DataDestinationTool, SetMetadataTool, DataSourceTool, AsyncDataSourceTool ]:
diff -r b5090cb8044469b7f5d3136cedbe80f009745f0b -r 67b5abaaf8bc702529a91a5d1d69318a2aaf6c75 lib/galaxy/tools/actions/index_genome.py
--- /dev/null
+++ b/lib/galaxy/tools/actions/index_genome.py
@@ -0,0 +1,65 @@
+import tempfile
+from __init__ import ToolAction
+from galaxy.util.odict import odict
+from galaxy.tools.genome_index import *
+
+import logging
+log = logging.getLogger( __name__ )
+
+class GenomeIndexToolAction( ToolAction ):
+ """Tool action used for exporting a history to an archive. """
+
+ def execute( self, tool, trans, *args, **kwargs ):
+ #
+ # Get genome to index.
+ #
+ incoming = kwargs['incoming']
+ #
+ # Create the job and output dataset objects
+ #
+ job = trans.app.model.Job()
+ job.tool_id = tool.id
+ job.user_id = incoming['user']
+ start_job_state = job.state # should be job.states.NEW
+ job.state = job.states.WAITING # we need to set job state to something other than NEW, or else when tracking jobs in db it will be picked up before we have added input / output parameters
+ trans.sa_session.add( job )
+
+ # Create dataset that will serve as archive.
+ temp_dataset = trans.app.model.Dataset( state=trans.app.model.Dataset.states.NEW )
+ trans.sa_session.add( temp_dataset )
+
+ trans.sa_session.flush() # ensure job.id and archive_dataset.id are available
+ trans.app.object_store.create( temp_dataset ) # set the object store id, create dataset (because galaxy likes having datasets)
+
+ #
+ # Setup job and job wrapper.
+ #
+
+ # Add association for keeping track of job, history, archive relationship.
+ user = trans.sa_session.query( trans.app.model.User ).get( int( incoming['user'] ) )
+ assoc = trans.app.model.GenomeIndexToolData( job=job, dataset=temp_dataset, fasta_path=incoming['path'], \
+ indexer=incoming['indexer'], user=user, \
+ deferred_job=kwargs['deferred'], transfer_job=kwargs['transfer'] )
+ trans.sa_session.add( assoc )
+
+ job_wrapper = GenomeIndexToolWrapper( job )
+ cmd_line = job_wrapper.setup_job( assoc )
+ #
+ # Add parameters to job_parameter table.
+ #
+
+ # Set additional parameters.
+ incoming[ '__GENOME_INDEX_COMMAND__' ] = cmd_line
+ for name, value in tool.params_to_strings( incoming, trans.app ).iteritems():
+ job.add_parameter( name, value )
+
+ job.state = start_job_state # job inputs have been configured, restore initial job state
+ trans.sa_session.flush()
+
+
+ # Queue the job for execution
+ trans.app.job_queue.put( job.id, tool )
+ log.info( "Added genome index job to the job queue, id: %s" % str( job.id ) )
+
+ return job, odict()
+
diff -r b5090cb8044469b7f5d3136cedbe80f009745f0b -r 67b5abaaf8bc702529a91a5d1d69318a2aaf6c75 lib/galaxy/tools/genome_index/__init__.py
--- /dev/null
+++ b/lib/galaxy/tools/genome_index/__init__.py
@@ -0,0 +1,184 @@
+import os, shutil, logging, tempfile, json, tarfile
+from galaxy import model, util
+from galaxy.web.framework.helpers import to_unicode
+from galaxy.model.item_attrs import UsesAnnotations
+from galaxy.util.json import *
+from galaxy.web.base.controller import UsesHistory
+from galaxy.tools.data import ToolDataTableManager
+
+log = logging.getLogger(__name__)
+
+def load_genome_index_tools( toolbox ):
+ """ Adds tools for indexing genomes via the main job runner. """
+ # Use same process as that used in load_external_metadata_tool; see that
+ # method for why create tool description files on the fly.
+ tool_xml_text = """
+ <tool id="__GENOME_INDEX__" name="Index Genome" version="0.1" tool_type="genome_index">
+ <type class="GenomeIndexTool" module="galaxy.tools"/>
+ <action module="galaxy.tools.actions.index_genome" class="GenomeIndexToolAction"/>
+ <command>$__GENOME_INDEX_COMMAND__ $output_file $output_file.files_path</command>
+ <inputs>
+ <param name="__GENOME_INDEX_COMMAND__" type="hidden"/>
+ </inputs>
+ <outputs>
+ <data format="txt" name="output_file"/>
+ </outputs>
+ </tool>
+ """
+
+ # Load export tool.
+ tmp_name = tempfile.NamedTemporaryFile()
+ tmp_name.write( tool_xml_text )
+ tmp_name.flush()
+ genome_index_tool = toolbox.load_tool( tmp_name.name )
+ toolbox.tools_by_id[ genome_index_tool.id ] = genome_index_tool
+ log.debug( "Loaded genome index tool: %s", genome_index_tool.id )
+
+class GenomeIndexToolWrapper( object ):
+ """ Provides support for performing jobs that index a genome. """
+ def __init__( self, job_id ):
+ self.locations = dict()
+ self.job_id = job_id
+
+ def setup_job( self, genobj ):
+ """ Perform setup for job to index a genome and return an archive. Method generates
+ attribute files, sets the corresponding attributes in the associated database
+ object, and returns a command line for running the job. The command line
+ includes the command, inputs, and options; it does not include the output
+ file because it must be set at runtime. """
+
+ #
+ # Create and return command line for running tool.
+ #
+ scriptpath = os.path.join( os.path.abspath( os.getcwd() ), "lib/galaxy/tools/genome_index/index_genome.py" )
+ return "python %s %s %s" % ( scriptpath, genobj.indexer, genobj.fasta_path )
+
+ def postprocessing( self, sa_session, app ):
+ """ Finish the job, move the finished indexes to their final resting place,
+ and update the .loc files where applicable. """
+ gitd = sa_session.query( model.GenomeIndexToolData ).filter_by( job_id=self.job_id ).first()
+ indexdirs = dict( bfast='bfast_index', bowtie='bowtie_index', bowtie2='bowtie2_index',
+ bwa='bwa_index', perm='perm_%s_index', picard='srma_index', sam='sam_index' )
+
+
+ if gitd:
+ destination = None
+ tdtman = ToolDataTableManager()
+ xmltree = tdtman.load_from_config_file(app.config.tool_data_table_config_path)
+ for node in xmltree:
+ table = node.get('name')
+ location = node.findall('file')[0].get('path')
+ self.locations[table] = os.path.abspath( location )
+ locbase = os.path.abspath( os.path.split( self.locations['all_fasta'] )[0] )
+ deferred = sa_session.query( model.DeferredJob ).filter_by( id=gitd.deferred_job_id ).first()
+ params = deferred.params
+ dbkey = params[ 'dbkey' ]
+ basepath = os.path.join( os.path.abspath( app.config.genome_data_path ), dbkey )
+ intname = params[ 'intname' ]
+ indexer = gitd.indexer
+ workingdir = os.path.abspath( gitd.dataset.extra_files_path )
+ fp = open( gitd.dataset.get_file_name(), 'r' )
+ logloc = json.load( fp )
+ fp.close()
+ location = []
+ indexdata = gitd.dataset.extra_files_path
+ if indexer == '2bit':
+ indexdata = os.path.join( workingdir, '%s.2bit' % dbkey )
+ destination = os.path.join( basepath, 'seq', '%s.2bit' % dbkey )
+ location.append( dict( line='\t'.join( [ 'seq', dbkey, os.path.join( destination, '%s.2bit' % dbkey ) ] ), file= os.path.join( locbase, 'alignseq.loc' ) ) )
+ elif indexer == 'bowtie':
+ self._ex_tar( workingdir, 'cs.tar' )
+ destination = os.path.join( basepath, 'bowtie_index' )
+ for var in [ 'nt', 'cs' ]:
+ for line in logloc[ var ]:
+ idx = line
+ if var == 'nt':
+ locfile = self.locations[ 'bowtie_indexes' ]
+ locdir = os.path.join( destination, idx )
+ else:
+ locfile = self.locations[ 'bowtie_indexes_color' ]
+ locdir = os.path.join( destination, var, idx )
+ location.append( dict( line='\t'.join( [ dbkey, dbkey, intname, locdir ] ), file=locfile ) )
+ elif indexer == 'bowtie2':
+ destination = os.path.join( basepath, 'bowtie2_index' )
+ for line in logloc[ 'nt' ]:
+ idx = line
+ locfile = self.locations[ 'bowtie2_indexes' ]
+ locdir = os.path.join( destination, idx )
+ location.append( dict( line='\t'.join( [ dbkey, dbkey, intname, locdir ] ), file=locfile ) )
+ elif indexer == 'bwa':
+ self._ex_tar( workingdir, 'cs.tar' )
+ destination = os.path.join( basepath, 'bwa_index' )
+ for var in [ 'nt', 'cs' ]:
+ for line in logloc[ var ]:
+ idx = line
+ if var == 'nt':
+ locfile = self.locations[ 'bwa_indexes' ]
+ locdir = os.path.join( destination, idx )
+ else:
+ locfile = self.locations[ 'bwa_indexes_color' ]
+ locdir = os.path.join( destination, var, idx )
+ location.append( dict( line='\t'.join( [ dbkey, dbkey, intname, locdir ] ), file=locfile ) )
+ elif indexer == 'perm':
+ self._ex_tar( workingdir, 'cs.tar' )
+ destination = os.path.join( basepath, 'perm_index' )
+ for var in [ 'nt', 'cs' ]:
+ for line in logloc[ var ]:
+ idx = line.pop()
+ if var == 'nt':
+ locfile = self.locations[ 'perm_base_indexes' ]
+ locdir = os.path.join( destination, idx )
+ else:
+ locfile = self.locations[ 'perm_color_indexes' ]
+ locdir = os.path.join( destination, var, idx )
+ line.append( locdir )
+ location.append( dict( line='\t'.join( line ), file=locfile ) )
+ elif indexer == 'picard':
+ destination = os.path.join( basepath, 'srma_index' )
+ for var in [ 'nt' ]:
+ for line in logloc[ var ]:
+ idx = line
+ locfile = self.locations[ 'picard_indexes' ]
+ locdir = os.path.join( destination, idx )
+ location.append( dict( line='\t'.join( [ dbkey, dbkey, intname, locdir ] ), file=locfile ) )
+ elif indexer == 'sam':
+ destination = os.path.join( basepath, 'sam_index' )
+ for var in [ 'nt' ]:
+ for line in logloc[ var ]:
+ locfile = self.locations[ 'sam_fa_indexes' ]
+ locdir = os.path.join( destination, line )
+ location.append( dict( line='\t'.join( [ 'index', dbkey, locdir ] ), file=locfile ) )
+
+ if destination is not None and os.path.exists( os.path.split( destination )[0] ) and not os.path.exists( destination ):
+ log.debug( 'Moving %s to %s' % ( indexdata, destination ) )
+ shutil.move( indexdata, destination )
+ if indexer not in [ '2bit' ]:
+ genome = '%s.fa'
+ target = os.path.join( destination, genome )
+ farel = os.path.relpath( os.path.join( basepath, 'seq', genome ), destination )
+ os.symlink( farel, target )
+ if os.path.exists( os.path.join( destination, 'cs' ) ):
+ target = os.path.join( destination, 'cs', genome )
+ farel = os.path.relpath( os.path.join( basepath, 'seq', genome ), os.path.join( destination, 'cs' ) )
+ os.symlink( os.path.join( farel, target ) )
+ for line in location:
+ self._add_line( line[ 'file' ], line[ 'line' ] )
+
+ def _ex_tar( self, directory, filename ):
+ fh = tarfile.open( os.path.join( directory, filename ) )
+ fh.extractall( path=directory )
+ fh.close()
+ os.remove( os.path.join( directory, filename ) )
+
+ def _add_line( self, locfile, newline ):
+ filepath = locfile
+ origlines = []
+ output = []
+ comments = []
+ with open( filepath, 'r' ) as destfile:
+ for line in destfile:
+ origlines.append( line.strip() )
+ if newline not in origlines:
+ origlines.append( newline )
+ with open( filepath, 'w+' ) as destfile:
+ destfile.write( '\n'.join( origlines ) )
diff -r b5090cb8044469b7f5d3136cedbe80f009745f0b -r 67b5abaaf8bc702529a91a5d1d69318a2aaf6c75 lib/galaxy/tools/genome_index/index_genome.py
--- /dev/null
+++ b/lib/galaxy/tools/genome_index/index_genome.py
@@ -0,0 +1,315 @@
+#!/usr/bin/env python
+"""
+Export a history to an archive file using attribute files.
+
+usage: %prog history_attrs dataset_attrs job_attrs out_file
+ -G, --gzip: gzip archive file
+"""
+import optparse, sys, os, tempfile, time, subprocess, shlex, json, tarfile, shutil
+
+class ManagedIndexer():
+ def __init__( self, output_file, infile, workingdir ):
+ self.workingdir = os.path.abspath( workingdir )
+ self.outfile = open( os.path.abspath( output_file ), 'w' )
+ self.basedir = os.path.split( self.workingdir )[0]
+ self.fasta = os.path.abspath( infile )
+ self.locations = dict( nt=[], cs=[] )
+ self.log = []
+ self.indexers = {
+ 'bwa': '_bwa',
+ 'bowtie': '_bowtie',
+ 'bowtie2': '_bowtie2',
+ '2bit': '_twobit',
+ 'perm': '_perm',
+ 'bfast': '_bfast',
+ 'picard': '_picard',
+ 'sam': '_sam'
+ }
+ if not os.path.exists( self.workingdir ):
+ os.makedirs( self.workingdir )
+ self.logfile = open( os.path.join( self.workingdir, 'ManagedIndexer.log' ), 'w+' )
+
+ def run_indexer( self, indexer ):
+ self.fapath = self.fasta
+ self.fafile = os.path.basename( self.fapath )
+ with WithChDir( self.basedir ):
+ if indexer not in self.indexers:
+ raise KeyError, 'The requested indexing function does not exist'
+ else:
+ with WithChDir( self.workingdir ):
+ self._log( 'Running indexer %s.' % indexer )
+ result = getattr( self, self.indexers[ indexer ] )()
+ if result is None:
+ self._log( 'Error running indexer %s.' % indexer )
+ self._flush_files()
+ raise Exception
+ else:
+ self._log( 'Indexer %s completed successfully.' % indexer )
+ self._flush_files()
+
+ def _flush_files( self ):
+ json.dump( self.locations, self.outfile )
+ self.outfile.close()
+ self.logfile.close()
+
+ def _log( self, stuff ):
+ timestamp = time.strftime('%Y-%m-%d %H:%M:%S %z')
+ self.logfile.write( "[%s] %s\n" % (timestamp, stuff) )
+
+ def _bwa( self ):
+ with WithChDir( self.workingdir ):
+ if not os.path.exists( self.fafile ):
+ os.symlink( os.path.relpath( self.fapath ), self.fafile )
+ command = shlex.split( 'bwa index -a bwtsw %s' % self.fafile )
+ result = subprocess.call( command, stderr=self.logfile, stdout=self.logfile )
+ if result != 0:
+ newcommand = shlex.split( 'bwa index -c %s' % self.fafile )
+ result = call( newcommand, stderr=self.logfile, stdout=self.logfile )
+ if result == 0:
+ self.locations[ 'nt' ].append( self.fafile )
+ os.remove( self.fafile )
+ os.makedirs( 'cs' )
+ with WithChDir( 'cs' ):
+ if not os.path.exists( self.fafile ):
+ os.symlink( os.path.relpath( self.fapath ), self.fafile )
+ command = shlex.split( 'bwa index -a bwtsw -c %s' % self.fafile )
+ result = subprocess.call( command, stderr=self.logfile, stdout=self.logfile )
+ if result != 0:
+ newcommand = shlex.split( 'bwa index -c %s' % self.fafile )
+ result = call( newcommand, stderr=self.logfile, stdout=self.logfile )
+ if result == 0:
+ self.locations[ 'cs' ].append( self.fafile )
+ os.remove( self.fafile )
+ else:
+ return False
+ else:
+ self.locations[ 'cs' ].append( self.fafile )
+ os.remove( self.fafile )
+ temptar = tarfile.open( 'cs.tar', 'w' )
+ temptar.add( 'cs' )
+ temptar.close()
+ shutil.rmtree( 'cs' )
+ return True
+ else:
+ return False
+
+ def _bowtie( self ):
+ ref_base = os.path.splitext(self.fafile)[0]
+ if not os.path.exists( self.fafile ):
+ os.symlink( os.path.relpath( self.fapath ), self.fafile )
+ command = shlex.split( 'bowtie-build -f %s %s' % ( self.fafile, ref_base ) )
+ result = subprocess.call( command, stderr=self.logfile, stdout=self.logfile )
+ if result == 0:
+ self.locations[ 'nt' ].append( ref_base )
+ os.remove( self.fafile )
+ indexdir = os.path.join( os.getcwd(), 'cs' )
+ os.makedirs( indexdir )
+ with WithChDir( indexdir ):
+ ref_base = os.path.splitext(self.fafile)[0]
+ if not os.path.exists( self.fafile ):
+ os.symlink( os.path.relpath( self.fapath ), self.fafile )
+ command = shlex.split( 'bowtie-build -C -f %s %s' % ( self.fafile, ref_base ) )
+ result = subprocess.call( command, stderr=self.logfile, stdout=self.logfile )
+ if result == 0:
+ self.locations[ 'cs' ].append( ref_base )
+ else:
+ return False
+ os.remove( os.path.join( indexdir, self.fafile ) )
+ temptar = tarfile.open( 'cs.tar', 'w' )
+ temptar.add( 'cs' )
+ temptar.close()
+ shutil.rmtree( 'cs' )
+ return True
+ else:
+ return False
+
+ def _bowtie2( self ):
+ ref_base = os.path.splitext(self.fafile)[0]
+ if not os.path.exists( self.fafile ):
+ os.symlink( os.path.relpath( self.fapath ), self.fafile )
+ command = shlex.split( 'bowtie2-build %s %s' % ( self.fafile, ref_base ) )
+ result = subprocess.call( command, stderr=self.logfile, stdout=self.logfile )
+ if result == 0:
+ self.locations[ 'nt' ].append( ref_base )
+ os.remove( self.fafile )
+ return True
+ else:
+ return False
+
+ def _twobit( self ):
+ """Index reference files using 2bit for random access.
+ """
+ ref_base = os.path.splitext(self.fafile)[0]
+ out_file = "%s.2bit" % ref_base
+ if not os.path.exists( self.fafile ):
+ os.symlink( os.path.relpath( self.fapath ), self.fafile )
+ command = shlex.split( 'faToTwoBit %s %s' % ( self.fafile, out_file ) )
+ result = subprocess.call( command, stderr=self.logfile, stdout=self.logfile )
+ if result == 0:
+ self.locations['nt'].append( out_file )
+ os.remove( self.fafile )
+ return True
+ else:
+ return False
+
+ def _perm( self ):
+ local_ref = self.fafile
+ if not os.path.exists( local_ref ):
+ os.symlink( os.path.relpath( self.fapath ), self.fafile )
+ genome = os.path.splitext( local_ref )[0]
+ read_length = 50
+ for seed in [ 'F3', 'F4' ]:
+ key = '%s_%s_%s' % (genome, seed, read_length)
+ desc = '%s: seed=%s, read length=%s' % (genome, seed, read_length)
+ index = "%s_base_%s_%s.index" % (genome, seed, read_length)
+ command = shlex.split("PerM %s %s --readFormat fastq --seed %s -m -s %s" % (local_ref, read_length, seed, index))
+ result = subprocess.call( command )
+ if result == 0:
+ self.locations[ 'nt' ].append( [ key, desc, index ] )
+ else:
+ return False
+ os.remove( local_ref )
+ os.makedirs( 'cs' )
+ with WithChDir( 'cs' ):
+ if not os.path.exists( local_ref ):
+ os.symlink( os.path.relpath( self.fapath ), self.fafile )
+ for seed in [ 'F3', 'F4' ]:
+ key = '%s_%s_%s' % (genome, seed, read_length)
+ desc = '%s: seed=%s, read length=%s' % (genome, seed, read_length)
+ index = "%s_color_%s_%s.index" % (genome, seed, read_length)
+ command = shlex.split("PerM %s %s --readFormat csfastq --seed %s -m -s %s" % (local_ref, read_length, seed, index))
+ result = subprocess.call( command, stderr=self.logfile, stdout=self.logfile )
+ if result == 0:
+ self.locations[ 'cs' ].append( [ key, desc, index ] )
+ else:
+ return False
+ os.remove( local_ref )
+ temptar = tarfile.open( 'cs.tar', 'w' )
+ temptar.add( 'cs' )
+ temptar.close()
+ shutil.rmtree( 'cs' )
+ return True
+
+ def _bfast( self ):
+ """Indexes bfast in color and nucleotide space for longer reads.
+
+ This preps for 40+bp sized reads, which is bfast's strength.
+ """
+ dir_name_nt = 'nt'
+ dir_name_cs = 'cs'
+ window_size = 14
+ bfast_nt_masks = [
+ "1111111111111111111111",
+ "1111101110111010100101011011111",
+ "1011110101101001011000011010001111111",
+ "10111001101001100100111101010001011111",
+ "11111011011101111011111111",
+ "111111100101001000101111101110111",
+ "11110101110010100010101101010111111",
+ "111101101011011001100000101101001011101",
+ "1111011010001000110101100101100110100111",
+ "1111010010110110101110010110111011",
+ ]
+ bfast_color_masks = [
+ "1111111111111111111111",
+ "111110100111110011111111111",
+ "10111111011001100011111000111111",
+ "1111111100101111000001100011111011",
+ "111111110001111110011111111",
+ "11111011010011000011000110011111111",
+ "1111111111110011101111111",
+ "111011000011111111001111011111",
+ "1110110001011010011100101111101111",
+ "111111001000110001011100110001100011111",
+ ]
+ local_ref = self.fafile
+ os.makedirs( dir_name_nt )
+ os.makedirs( dir_name_cs )
+ if not os.path.exists( self.fafile ):
+ os.symlink( os.path.relpath( self.fapath ), self.fafile )
+ with WithChDir( dir_name_nt ):
+ if not os.path.exists( self.fafile ):
+ os.symlink( os.path.relpath( self.fapath ), self.fafile )
+ # nucleotide space
+ command = shlex.split( "bfast fasta2brg -f %s -A 0" % local_ref )
+ result = subprocess.call( command, stderr=self.logfile )
+ for i, mask in enumerate( bfast_nt_masks ):
+ command = shlex.split("bfast index -d 1 -n 4 -f %s -A 0 -m %s -w %s -i %s" %
+ ( local_ref, mask, window_size, i + 1 ) )
+ result = subprocess.call( command, stderr=self.logfile, stdout=self.logfile )
+ os.remove( self.fafile )
+ if result != 0:
+ return False
+ else:
+ os.remove( self.fafile )
+ with WithChDir( dir_name_cs ):
+ if not os.path.exists( self.fafile ):
+ os.symlink( os.path.relpath( self.fapath ), self.fafile )
+ # colorspace
+ command = shlex.split( "bfast fasta2brg -f %s -A 1" % local_ref )
+ result = subprocess.call( command, stderr=self.logfile, stdout=self.logfile )
+ for i, mask in enumerate( bfast_color_masks ):
+ command = shlex.split( "bfast index -d 1 -n 4 -f %s -A 1 -m %s -w %s -i %s" %
+ ( local_ref, mask, window_size, i + 1 ) )
+ result = subprocess.call( command, stderr=self.logfile, stdout=self.logfile )
+ if result != 0:
+ return False
+ else:
+ os.remove( self.fafile )
+ self.locations = None
+ return True
+
+ def _picard( self ):
+ local_ref = self.fafile
+ srma = '/Users/dave/srma.jar'
+ genome = os.path.splitext( self.fafile )[0]
+ if not os.path.exists( self.fafile ):
+ os.symlink( os.path.relpath( self.fapath ), self.fafile )
+ command = shlex.split( 'samtools faidx %s' % self.fafile )
+ subprocess.call( command, stderr=self.logfile )
+ os.rename( '%s.fai' % self.fafile, '%s.fai' % genome )
+ command = shlex.split( "java -cp %s net.sf.picard.sam.CreateSequenceDictionary R=%s O=%s/%s.dict URI=%s" \
+ % ( srma, local_ref, os.curdir, genome, local_ref ) )
+ result = subprocess.call( command, stderr=self.logfile, stdout=self.logfile )
+ if result != 0:
+ return False
+ else:
+ self.locations[ 'nt' ].append( self.fafile )
+ #os.remove( '%s.fai' % genome )
+ os.remove( self.fafile )
+ return True
+
+ def _sam( self ):
+ local_ref = self.fafile
+ local_file = os.path.splitext( self.fafile )[ 0 ]
+ if not os.path.exists( local_ref ):
+ os.symlink( os.path.relpath( self.fapath ), self.fafile )
+ command = shlex.split("samtools faidx %s" % local_ref)
+ result = subprocess.call( command, stderr=self.logfile )
+ if result != 0:
+ return False
+ else:
+ self.locations[ 'nt' ].append( local_ref )
+ os.remove( local_ref )
+ return True
+
+class WithChDir():
+ def __init__( self, target ):
+ self.working = target
+ self.previous = os.getcwd()
+ def __enter__( self ):
+ os.chdir( self.working )
+ def __exit__( self, *args ):
+ os.chdir( self.previous )
+
+
+if __name__ == "__main__":
+ # Parse command line.
+ parser = optparse.OptionParser()
+ (options, args) = parser.parse_args()
+ indexer, infile, outfile, working_dir = args
+
+ # Create archive.
+ idxobj = ManagedIndexer( outfile, infile, working_dir )
+ idxobj.run_indexer( indexer )
+
\ No newline at end of file
diff -r b5090cb8044469b7f5d3136cedbe80f009745f0b -r 67b5abaaf8bc702529a91a5d1d69318a2aaf6c75 lib/galaxy/web/controllers/data_admin.py
--- /dev/null
+++ b/lib/galaxy/web/controllers/data_admin.py
@@ -0,0 +1,175 @@
+import sys, ftplib, json
+from galaxy import model, util
+from galaxy.jobs import transfer_manager
+from galaxy.web.base.controller import *
+from galaxy.web.framework.helpers import time_ago, iff, grids
+from galaxy.model.orm import *
+from library_common import get_comptypes, lucene_search, whoosh_search
+
+# Older py compatibility
+try:
+ set()
+except:
+ from sets import Set as set
+
+import logging
+log = logging.getLogger( __name__ )
+
+class DataAdmin( BaseUIController ):
+ jobstyles = dict(
+ done='panel-done-message',
+ waiting='state-color-waiting',
+ running='state-color-running',
+ downloaded='state-color-running',
+ new='state-color-new',
+ ok='panel-done-message',
+ error='panel-error-message'
+ )
+
+ @web.expose
+ @web.require_admin
+ def manage_data( self, trans, **kwd ):
+ dbkeys = trans.db_builds
+ return trans.fill_template( '/admin/data_admin/data_form.mako', dbkeys=dbkeys )
+
+ @web.expose
+ @web.require_admin
+ def download_build( self, trans, **kwd ):
+ """Download a genome from a remote source and add it to the library."""
+ params = util.Params( kwd )
+ source = params.get('source', '')
+ longname = params.get('longname', None)
+ if not isinstance( params.get( 'indexers', None ), list ):
+ indexers = [ params.get( 'indexers', None ) ]
+ else:
+ indexers = params.get( 'indexers', None )
+ if indexers is not None:
+ if indexers == [None]:
+ indexers = None
+ url = None
+ liftover = None
+ newlift = []
+ dbkey = params.get( 'dbkey', None )
+ dbkeys = dict()
+ protocol = 'http'
+
+ if source == 'NCBI':
+ dbkey = params.get('dbkey', '')[0]
+ url = 'http://togows.dbcls.jp/entry/ncbi-nucleotide/%s.fasta' % dbkey
+ elif source == 'Broad':
+ dbkey = params.get('dbkey', '')[0]
+ url = 'ftp://ftp.broadinstitute.org/pub/seq/references/%s.fasta' % dbkey
+ elif source == 'UCSC':
+ longname = None
+ for build in trans.db_builds:
+ if dbkey[1] == build[0]:
+ dbkey = build[0]
+ longname = build[1]
+ break
+ assert dbkey is not '?', 'That build was not found'
+ ftp = ftplib.FTP('hgdownload.cse.ucsc.edu')
+ ftp.login('anonymous', 'user(a)example.com')
+ checker = []
+ liftover = []
+ newlift = []
+ try:
+ ftp.retrlines('NLST /goldenPath/%s/liftOver/*.chain.gz' % dbkey, liftover.append)
+ for chain in liftover:
+ fname = chain.split( '/' )[-1]
+ target = fname.replace( '.over.chain.gz', '' ).split( 'To' )[1]
+ target = target[0].lower() + target[1:]
+ newlift.append( [ chain, dbkey, target ] )
+ current = dbkey[0].upper() + dbkey[1:]
+ targetfile = '%sTo%s.over.chain.gz' % ( target, current )
+ newlift.append( [ '/goldenPath/%s/liftOver/%s' % ( target, targetfile ), target, dbkey ] )
+ except:
+ newlift = None
+ pass
+ ftp.retrlines('NLST /goldenPath/%s/bigZips/' % dbkey, checker.append)
+ for filename in [ dbkey, 'chromFa' ]:
+ for extension in [ '.tar.gz', '.tar.bz2', '.zip', '.fa.gz', '.fa.bz2' ]:
+ testfile = '/goldenPath/%s/bigZips/%s%s' % ( dbkey, filename, extension )
+ if testfile in checker:
+ url = 'ftp://hgdownload.cse.ucsc.edu%s' % testfile
+ break;
+ else:
+ continue
+ if url is None:
+ message = u'The genome %s was not found on the UCSC server.' % dbkey
+ status = u'error'
+ return trans.fill_template( '/admin/data_admin/data_form.mako',
+ message=message,
+ status=status )
+ elif source == 'Ensembl':
+ section = params.get('ensembl_section', '')
+ release1 = params.get('release_number', '')
+ organism = params.get('organism', '')
+ name = params.get('name', '')
+ longname = organism
+ dbkey = name
+ release2 = params.get('release2', '')
+ release2 = ".%s" % release2 if release2 else ""
+ if section == 'standard':
+ url = 'ftp://ftp.ensembl.org/pub/release-%s/fasta/%s/dna/%s.%s%s.dna.toplevel.fa.gz' % \
+ (release1, organism.lower(), organism, name, release2)
+ else:
+ url = 'ftp://ftp.ensemblgenomes.org/pub/%s/release-%s/fasta/%s/dna/%s.%s%s.dna.top…' % \
+ (section, release1, organism.lower(), organism, name, release2)
+ elif source == 'local':
+ url = 'http://127.0.0.1/%s.tar.gz' % dbkey
+ else:
+ raise ValueError
+ params = dict( protocol='http', name=dbkey, datatype='fasta', url=url, user=trans.user.id )
+ jobid = trans.app.job_manager.deferred_job_queue.plugins['GenomeTransferPlugin'].create_job( trans, url, dbkey, longname, indexers )
+ chainjob = []
+ if newlift is not None:
+ for chain in newlift:
+ liftover_url = u'ftp://hgdownload.cse.ucsc.edu%s' % chain[0]
+ from_genome = chain[1]
+ to_genome = chain[2]
+ destfile = liftover_url.split('/')[-1].replace('.gz', '')
+ chainjob.append( trans.app.job_manager.deferred_job_queue.plugins['LiftOverTransferPlugin'].create_job( trans, liftover_url, dbkey, from_genome, to_genome, destfile ) )
+ job = trans.app.job_manager.deferred_job_queue.plugins['GenomeTransferPlugin'].get_job_status( jobid )
+ job.params['liftover'] = chainjob
+ trans.app.model.context.current.add( job )
+ trans.app.model.context.current.flush()
+ return trans.response.send_redirect( web.url_for( controller='data_admin',
+ action='monitor_status',
+ job=jobid ) )
+
+ @web.expose
+ @web.require_admin
+ def monitor_status( self, trans, **kwd ):
+ params = util.Params( kwd )
+ jobid = params.get( 'job', '' )
+ chains = params.get( 'chains', [] )
+ jobs = self._get_jobs( jobid, trans )
+ return trans.fill_template( '/admin/data_admin/download_status.mako', mainjob=jobid, jobs=jobs )
+
+ @web.expose
+ @web.require_admin
+ def ajax_statusupdate( self, trans, **kwd ):
+ sa_session = trans.app.model.context.current
+ jobs = []
+ params = util.Params( kwd )
+ jobid = params.get( 'jobid', '' )
+ jobs = self._get_jobs( jobid, trans )
+ return trans.fill_template( '/admin/data_admin/ajax_statusupdate.mako', mainjob=jobid, jobs=jobs )
+
+ def _get_jobs( self, jobid, trans ):
+ jobs = []
+ job = trans.app.job_manager.deferred_job_queue.plugins['GenomeTransferPlugin'].get_job_status( jobid )
+ sa_session = trans.app.model.context.current
+ idxjobs = sa_session.query( model.GenomeIndexToolData ).filter_by( deferred_job_id=job.id, transfer_job_id=job.transfer_job.id ).all()
+ if job.params[ 'liftover' ] is not None:
+ for jobid in job.params[ 'liftover' ]:
+ lo_job = trans.app.job_manager.deferred_job_queue.plugins['LiftOverTransferPlugin'].get_job_status( jobid )
+ jobs.append( dict( jobid=lo_job.id, state=lo_job.state, type='Download liftOver' ) )
+ for idxjob in idxjobs:
+ jobentry = sa_session.query( model.Job ).filter_by( id=idxjob.job_id ).first()
+ jobs.append( dict( jobid=jobentry.id, state=jobentry.state, type='Index Genome' ) )
+ jobs.append( dict ( jobid=job.id, state=job.state, type='Main Job' ) )
+ jobs.append( dict ( jobid=job.transfer_job.id, state=job.transfer_job.state, type='Download Genome' ) )
+ for je in jobs:
+ je[ 'style' ] = self.jobstyles[ je[ 'state' ] ]
+ return jobs
diff -r b5090cb8044469b7f5d3136cedbe80f009745f0b -r 67b5abaaf8bc702529a91a5d1d69318a2aaf6c75 templates/admin/data_admin/ajax_statusupdate.mako
--- /dev/null
+++ b/templates/admin/data_admin/ajax_statusupdate.mako
@@ -0,0 +1,5 @@
+%for jobentry in jobs:
+ <div class="${jobentry['style']} dialog-box" id="job${jobentry['jobid']}" data-state="${jobentry['state']}" data-jobid="${jobentry['jobid']}" data-type="${jobentry['type']}">
+ <span class="inline">${jobentry['type']}</span>
+ </div>
+%endfor
diff -r b5090cb8044469b7f5d3136cedbe80f009745f0b -r 67b5abaaf8bc702529a91a5d1d69318a2aaf6c75 templates/admin/data_admin/data_form.mako
--- /dev/null
+++ b/templates/admin/data_admin/data_form.mako
@@ -0,0 +1,190 @@
+<%inherit file="/base.mako"/>
+<%namespace file="/message.mako" import="render_msg" />
+<%namespace file="/library/common/common.mako" import="common_javascripts" />
+
+<%!
+ def inherit(context):
+ if context.get('use_panels'):
+ return '/webapps/galaxy/base_panels.mako'
+ else:
+ return '/base.mako'
+%>
+<%inherit file="${inherit(context)}"/>
+
+<%def name="init()">
+<%
+ self.has_left_panel=False
+ self.has_right_panel=False
+ self.message_box_visible=False
+ self.active_view="user"
+ self.overlay_visible=False
+ self.has_accessible_datasets = False
+%>
+</%def>
+<%def name="stylesheets()">
+ ${parent.stylesheets()}
+ ${h.css( "autocomplete_tagging" )}
+</%def>
+<%def name="javascripts()">
+ ${parent.javascripts()}
+ ${h.js("jquery.autocomplete", "autocomplete_tagging" )}
+</%def>
+##
+## Override methods from base.mako and base_panels.mako
+##
+<%def name="center_panel()">
+ <div style="overflow: auto; height: 100%;">
+ <div class="page-container" style="padding: 10px;">
+ ${render_content()}
+ </div>
+ </div>
+</%def>
+<style type="text/css">
+ .params-block { display: none; }
+</style>
+<div class="toolForm">
+ %if message:
+ <div class="${status}">${message}</div>
+ %endif
+ <div class="toolFormTitle">Get build from a remote server</div>
+ <div class="toolFormBody">
+ <form name="download_build" action="${h.url_for( controller='data_admin', action='download_build' )}" enctype="multipart/form-data" method="post">
+ <div class="form-row">
+ <label for="source">Data Source</label>
+ <select id="datasource" name="source" label="Data Source">
+ <option value="local">localhost</option>
+ <option value="UCSC">UCSC</option>
+ <option value="Broad">Broad Institute</option>
+ <option value="NCBI">NCBI</option>
+ <option value="Ensembl">EnsemblGenome</option>
+ </select>
+ <div style="clear: both;"> </div>
+ </div>
+ <div class="form-row">
+ <label for="indexers">Indexers</label>
+ <select name="indexers" multiple style="width: 200px; height: 125px;">
+ <option value="2bit">TwoBit</option>
+ <option value="bowtie">Bowtie</option>
+ <option value="bowtie2">Bowtie 2</option>
+ <option value="bwa">BWA</option>
+ <option value="perm">PerM</option>
+ <option value="picard">Picard</option>
+ <option value="sam">sam</option>
+ </select>
+ <div class="toolParamHelp" style="clear: both;">
+ Select the indexers you want to run on the FASTA file after downloading.
+ </div>
+ </div>
+ <h2>Parameters</h2>
+ <div id="params_generic" class="params-block" style="display: block;">
+ <div class="form-row">
+ <label for="longname">Internal Name</label>
+ <input name="longname" type="text" label="Internal Name" />
+ <div style="clear: both;"> </div>
+ </div>
+ <div class="form-row">
+ <label for="uniqid">Internal Unique Identifier</label>
+ <input name="uniqid" type="text" label="Internal Identifier" />
+ <div style="clear: both;"> </div>
+ </div>
+ <div id="dlparams">
+ <div class="form-row">
+ <label for="dbkey">External Name</label>
+ <input name="dbkey" type="text" label="Genome Unique Name" />
+ <div style="clear: both;"> </div>
+ </div>
+ </div>
+ </div>
+ <div id="params_ensembl" class="params-block">
+ <div class="form-row">
+ <label for="ensembl_section">Section</label>
+ <input name="ensembl_section" type="text" label="Section" />
+ <div style="clear: both;"> </div>
+ <div class="toolParamHelp" style="clear: both;">
+ Ensembl section, either standard or one of plants, protists, metazoa, fungi, bacteria.
+ </div>
+ </div>
+ <div class="form-row">
+ <label for="release_number">Release Number</label>
+ <input name="release_number" type="text" label="Release" />
+ <div style="clear: both;"> </div>
+ <div class="toolParamHelp" style="clear: both;">
+ Release number, e.g. ftp://ftp.ensembl.org/pub/release-<strong style="color: red;">56</strong>/fasta/callithrix_jacchus/dna/Callithrix_jacchus.calJac3.56.dna.toplevel.fa.gz
+ </div>
+ </div>
+ <div class="form-row">
+ <label for="organism">Organism</label>
+ <input name="organism" type="text" label="Organism" />
+ <div style="clear: both;"> </div>
+ <div class="toolParamHelp" style="clear: both;">
+ Organism long name, e.g. ftp://ftp.ensembl.org/pub/release-56/fasta/callithrix_jacchus/dna/<strong style="color: red;">Callithrix_jacchus</strong>.calJac3.56.dna.toplevel.fa.gz
+ </div>
+ </div>
+ <div class="form-row">
+ <label for="name">Name</label>
+ <input name="name" type="text" label="name" />
+ <div style="clear: both;"> </div>
+ <div class="toolParamHelp" style="clear: both;">
+ Organism short name, e.g. ftp://ftp.ensembl.org/pub/release-56/fasta/callithrix_jacchus/dna/Callithri….<strong style="color: red;">calJac3</strong>.56.dna.toplevel.fa.gz
+ </div>
+ </div>
+ <div class="form-row">
+ <label for="release2">Release ID</label>
+ <input name="release2" type="text" label="Release ID" />
+ <div style="clear: both;"> </div>
+ <div class="toolParamHelp" style="clear: both;">
+ Release ID, e.g. ftp://ftp.ensembl.org/pub/release-56/fasta/callithrix_jacchus/dna/Callithri….<strong style="color: red;">56</strong>.dna.toplevel.fa.gz
+ </div>
+ </div>
+ </div>
+ <div id="params_ucsc" class="params-block">
+ <div class="form-row">
+ <label>Genome:</label>
+ <div class="form-row-input">
+ <select name="dbkey" last_selected_value="?">
+ %for dbkey in dbkeys:
+ %if dbkey[0] == last_used_build:
+ <option value="${dbkey[0]}" selected>${dbkey[1]}</option>
+ %else:
+ <option value="${dbkey[0]}">${dbkey[1]}</option>
+ %endif
+ %endfor
+ </select>
+ </div>
+ <div class="toolParamHelp" style="clear: both;">
+ If you can't find the build you want in this list, <insert link to instructions here>
+ </div>
+ </div>
+ </div>
+ <div class="form-row">
+ <input type="submit" class="primary-button" name="runtool_btn" value="Download and index"/>
+ </div>
+ <script type="text/javascript">
+ $(document).ready(function() {
+ checkDataSource();
+ });
+ $('#datasource').change(function() {
+ checkDataSource();
+ });
+ function checkDataSource() {
+ var ds = $('#datasource').val()
+ $('.params-block').each(function() {
+ $(this).hide();
+ });
+ switch (ds) {
+ case 'UCSC':
+ $('#params_ucsc').show();
+ break;
+ case 'Ensembl':
+ $('#params_ensembl').show();
+ break;
+ case 'NCBI':
+ case 'Broad':
+ default:
+ $('#params_generic').show();
+ break;
+ }
+ };
+ </script>
+ </form>
+</div>
diff -r b5090cb8044469b7f5d3136cedbe80f009745f0b -r 67b5abaaf8bc702529a91a5d1d69318a2aaf6c75 templates/admin/data_admin/download_status.mako
--- /dev/null
+++ b/templates/admin/data_admin/download_status.mako
@@ -0,0 +1,65 @@
+<%namespace file="/library/common/library_item_info.mako" import="render_library_item_info" />
+<%namespace file="/library/common/common.mako" import="render_actions_on_multiple_items" />
+<%namespace file="/library/common/common.mako" import="render_compression_types_help" />
+<%namespace file="/library/common/common.mako" import="common_javascripts" />
+
+<%!
+ def inherit(context):
+ if context.get('use_panels'):
+ return '/webapps/galaxy/base_panels.mako'
+ else:
+ return '/base.mako'
+%>
+<%inherit file="${inherit(context)}"/>
+
+<%def name="init()">
+<%
+ self.has_left_panel=False
+ self.has_right_panel=False
+ self.message_box_visible=False
+ self.active_view="user"
+ self.overlay_visible=False
+ self.has_accessible_datasets = False
+%>
+</%def>
+
+##
+## Override methods from base.mako and base_panels.mako
+##
+<%def name="center_panel()">
+ <div style="overflow: auto; height: 100%;">
+ <div class="page-container" style="padding: 10px;">
+ ${render_content()}
+ </div>
+ </div>
+</%def>
+<p>The genome build and any selected indexers have been added to the job queue. Below you will see the status of each job.</p>
+<div id="jobStatus" data-job="${mainjob}">
+%for jobentry in jobs:
+ <div class="${jobentry['style']} dialog-box" id="job${jobentry['jobid']}" data-state="${jobentry['state']}" data-jobid="${jobentry['jobid']}" data-type="${jobentry['type']}">
+ <span class="inline">${jobentry['type']}</span>
+ </div>
+%endfor
+</div>
+<a href="${h.url_for( controller='data_admin', action='manage_data' )}">Return to the download form</a>
+<script type="text/javascript">
+ function getNewHtml(jobid) {
+ $.get('${h.url_for( controller='data_admin', action='ajax_statusupdate' )}', { jobid: jobid }, function(data) {
+ $('#jobStatus').html(data);
+ });
+ $('#jobStatus').children().each(function() {
+ state = $(this).attr('class');
+ //alert(state);
+ if (state != 'panel-done-message dialog-box' && state != 'panel-error-message dialog-box') {
+ setJobRefreshers();
+ return;
+ }
+ });
+ }
+ function setJobRefreshers() {
+ $('#jobStatus').delay(3000).queue(function(n) { getNewHtml($(this).attr('data-job')); n(); }).fadeIn(750);
+ }
+ $(document).ready(function() {
+ setJobRefreshers();
+ });
+</script>
\ No newline at end of file
diff -r b5090cb8044469b7f5d3136cedbe80f009745f0b -r 67b5abaaf8bc702529a91a5d1d69318a2aaf6c75 templates/webapps/galaxy/admin/index.mako
--- a/templates/webapps/galaxy/admin/index.mako
+++ b/templates/webapps/galaxy/admin/index.mako
@@ -57,6 +57,7 @@
<div class="toolSectionBg"><div class="toolTitle"><a href="${h.url_for( controller='admin', action='quotas', webapp=webapp )}" target="galaxy_main">Manage quotas</a></div><div class="toolTitle"><a href="${h.url_for( controller='library_admin', action='browse_libraries' )}" target="galaxy_main">Manage data libraries</a></div>
+ <div class="toolTitle"><a href="${h.url_for( controller='data_admin', action='manage_data' )}" target="galaxy_main">Manage local data</a></div></div></div><div class="toolSectionPad"></div>
diff -r b5090cb8044469b7f5d3136cedbe80f009745f0b -r 67b5abaaf8bc702529a91a5d1d69318a2aaf6c75 universe_wsgi.ini.sample
--- a/universe_wsgi.ini.sample
+++ b/universe_wsgi.ini.sample
@@ -117,6 +117,9 @@
# -- Files and directories
+# Path where genome builds are stored. This defaults to tool-data/genome
+#genome_data_path = tool-data/genome
+
# Dataset files are stored in this directory.
#file_path = database/files
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: greg: Fixes for handling errors when uploading a tarball to a tool shed repository that contains problematic contents. A bit of code cleanup is included as well.
by Bitbucket 10 May '12
by Bitbucket 10 May '12
10 May '12
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/changeset/b5090cb80444/
changeset: b5090cb80444
user: greg
date: 2012-05-10 02:19:01
summary: Fixes for handling errors when uploading a tarball to a tool shed repository that contains problematic contents. A bit of code cleanup is included as well.
affected #: 1 file
diff -r a722c37dee3fb167c47c6f4b93e74518237f7d28 -r b5090cb8044469b7f5d3136cedbe80f009745f0b lib/galaxy/webapps/community/controllers/upload.py
--- a/lib/galaxy/webapps/community/controllers/upload.py
+++ b/lib/galaxy/webapps/community/controllers/upload.py
@@ -123,15 +123,8 @@
content_alert_str = ''
commands.add( repo.ui, repo, full_path )
# Convert from unicode to prevent "TypeError: array item must be char"
- full_path = full_path.encode('ascii', 'replace')
- try:
- commands.commit( repo.ui, repo, full_path, user=trans.user.username, message=commit_message )
- except Exception, e:
- # I never have a problem with commands.commit on a Mac, but in the test/production
- # tool shed environment, it occasionally throws a "TypeError: array item must be char"
- # exception. If this happens, we'll try the following.
- repo.dirstate.write()
- repo.commit( user=trans.user.username, text=commit_message )
+ full_path = full_path.encode( 'ascii', 'replace' )
+ commands.commit( repo.ui, repo, full_path, user=trans.user.username, message=commit_message )
if full_path.endswith( 'tool_data_table_conf.xml.sample' ):
# Handle the special case where a tool_data_table_conf.xml.sample
# file is being uploaded by parsing the file and adding new entries
@@ -205,18 +198,18 @@
repo = hg.repository( get_configured_ui(), repo_dir )
files_to_remove = []
content_alert_str = ''
+ undesirable_dirs_removed = 0
+ undesirable_files_removed = 0
ok, message = self.__check_archive( tar )
if not ok:
tar.close()
uploaded_file.close()
- return ok, message, files_to_remove, content_alert_str
+ return ok, message, files_to_remove, content_alert_str, undesirable_dirs_removed, undesirable_files_removed
else:
if upload_point is not None:
full_path = os.path.abspath( os.path.join( repo_dir, upload_point ) )
else:
full_path = os.path.abspath( repo_dir )
- undesirable_dirs_removed = 0
- undesirable_files_removed = 0
filenames_in_archive = []
for tarinfo_obj in tar.getmembers():
ok = os.path.basename( tarinfo_obj.name ) not in undesirable_files
@@ -253,14 +246,11 @@
if full_name not in filenames_in_archive:
files_to_remove.append( full_name )
for repo_file in files_to_remove:
- # Remove files in the repository (relative to the upload point)
- # that are not in the uploaded archive.
+ # Remove files in the repository (relative to the upload point) that are not in the uploaded archive.
try:
commands.remove( repo.ui, repo, repo_file, force=True )
except Exception, e:
- # I never have a problem with commands.remove on a Mac, but in the test/production
- # tool shed environment, it throws an exception whenever I delete all files from a
- # repository. If this happens, we'll try the following.
+ log.debug( "Error removing files using the mercurial API, so trying a different approach, the error was: %s" % str( e ))
relative_selected_file = selected_file.split( 'repo_%d' % repository.id )[1].lstrip( '/' )
repo.dirstate.remove( relative_selected_file )
repo.dirstate.write()
@@ -294,18 +284,11 @@
# appending them to the shed's tool_data_table_conf.xml file on disk.
error, message = handle_sample_tool_data_table_conf_file( trans.app, filename_in_archive )
if error:
- return False, message, files_to_remove, content_alert_str
+ return False, message, files_to_remove, content_alert_str, undesirable_dirs_removed, undesirable_files_removed
if filename_in_archive.endswith( '.loc.sample' ):
# Handle the special case where a xxx.loc.sample file is being uploaded by copying it to ~/tool-data/xxx.loc.
copy_sample_file( trans.app, filename_in_archive )
- try:
- commands.commit( repo.ui, repo, full_path, user=trans.user.username, message=commit_message )
- except Exception, e:
- # I never have a problem with commands.commit on a Mac, but in the test/production
- # tool shed environment, it occasionally throws a "TypeError: array item must be char"
- # exception. If this happens, we'll try the following.
- repo.dirstate.write()
- repo.commit( user=trans.user.username, text=commit_message )
+ commands.commit( repo.ui, repo, full_path, user=trans.user.username, message=commit_message )
# See if the content of the change set was valid.
admin_only = len( repository.downloadable_revisions ) != 1
handle_email_alerts( trans, repository, content_alert_str=content_alert_str, new_repo_alert=new_repo_alert, admin_only=admin_only )
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: dan: Fix for clearing implicitly converted dataset association when converted dataset is deleted.
by Bitbucket 09 May '12
by Bitbucket 09 May '12
09 May '12
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/changeset/a722c37dee3f/
changeset: a722c37dee3f
user: dan
date: 2012-05-09 21:36:15
summary: Fix for clearing implicitly converted dataset association when converted dataset is deleted.
affected #: 1 file
diff -r 17d57db9a7c04467dbd82eaa66027e3fa5e38bc2 -r a722c37dee3fb167c47c6f4b93e74518237f7d28 lib/galaxy/model/__init__.py
--- a/lib/galaxy/model/__init__.py
+++ b/lib/galaxy/model/__init__.py
@@ -1126,8 +1126,10 @@
def clear_associated_files( self, metadata_safe = False, purge = False ):
# metadata_safe = True means to only clear when assoc.metadata_safe == False
for assoc in self.implicitly_converted_datasets:
- if not metadata_safe or not assoc.metadata_safe:
+ if not assoc.deleted and ( not metadata_safe or not assoc.metadata_safe ):
assoc.clear( purge = purge )
+ for assoc in self.implicitly_converted_parent_datasets:
+ assoc.clear( purge = purge, delete_dataset = False )
def get_display_name( self ):
## Name can be either a string or a unicode object. If string, convert to unicode object assuming 'utf-8' format.
hda_name = self.name
@@ -1626,12 +1628,14 @@
self.purged = purged
self.metadata_safe = metadata_safe
- def clear( self, purge = False ):
+ def clear( self, purge = False, delete_dataset = True ):
self.deleted = True
if self.dataset:
- self.dataset.deleted = True
- self.dataset.purged = purge
- if purge: #do something with purging
+ if delete_dataset:
+ self.dataset.deleted = True
+ if purge:
+ self.dataset.purged = True
+ if purge and self.dataset.deleted: #do something with purging
self.purged = True
try: os.unlink( self.file_name )
except Exception, e: print "Failed to purge associated file (%s) from disk: %s" % ( self.file_name, e )
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
09 May '12
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/changeset/17d57db9a7c0/
changeset: 17d57db9a7c0
user: dannon
date: 2012-05-09 15:12:42
summary: Fix for history_contents API file display.
affected #: 1 file
diff -r 317e326803d42db705c93d4c59e92c1eb764fa36 -r 17d57db9a7c04467dbd82eaa66027e3fa5e38bc2 lib/galaxy/web/api/history_contents.py
--- a/lib/galaxy/web/api/history_contents.py
+++ b/lib/galaxy/web/api/history_contents.py
@@ -55,7 +55,7 @@
try:
item = content.get_api_value( view='element' )
if trans.user_is_admin() or trans.app.config.expose_dataset_path:
- item['file_name'] = hda.file_name
+ item['file_name'] = content.file_name
if not item['deleted']:
# Problem: Method url_for cannot use the dataset controller
# Get the environment from DefaultWebTransaction and use default webapp mapper instead of webapp API mapper
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
2 new commits in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/changeset/db93ba1751de/
changeset: db93ba1751de
user: jgoecks
date: 2012-05-08 23:26:14
summary: Fix display bugs associated with c5da9bd8bbfc. Pack script.
affected #: 2 files
diff -r 1c196b8747e4d976cbc1d294457b64a7e27fb26c -r db93ba1751de1c39e0c1febbdb946ce326197187 static/scripts/packed/trackster.js
--- a/static/scripts/packed/trackster.js
+++ b/static/scripts/packed/trackster.js
@@ -1,1 +1,1 @@
-var class_module=function(b,a){var c=function(){var f=arguments[0];for(var e=1;e<arguments.length;e++){var d=arguments[e];for(key in d){f[key]=d[key]}}return f};a.extend=c};var server_state_deferred=function(d,a,c,f){var b=$.Deferred(),e=function(){$.getJSON(d,a,function(g){if(f(g)){b.resolve(g)}else{setTimeout(e,c)}})};e();return b};var requestAnimationFrame=(function(){return window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.oRequestAnimationFrame||window.msRequestAnimationFrame||function(b,a){window.setTimeout(b,1000/60)}})();var BEFORE=1001,CONTAINS=1002,OVERLAP_START=1003,OVERLAP_END=1004,CONTAINED_BY=1005,AFTER=1006;var compute_overlap=function(e,b){var g=e[0],f=e[1],d=b[0],c=b[1],a;if(g<d){if(f<d){a=BEFORE}else{if(f<=c){a=OVERLAP_START}else{a=CONTAINS}}}else{if(g>c){a=AFTER}else{if(f<=c){a=CONTAINED_BY}else{a=OVERLAP_END}}}return a};var is_overlap=function(c,b){var a=compute_overlap(c,b);return(a!==BEFORE&&a!==AFTER)};var is_deferred=function(a){return("isResolved" in a)};var get_random_color=function(a){if(!a){a="#ffffff"}if(typeof(a)==="string"){a=[a]}for(var j=0;j<a.length;j++){a[j]=parseInt(a[j].slice(1),16)}var n=function(t,s,i){return((t*299)+(s*587)+(i*114))/1000};var e=function(v,u,w,s,i,t){return(Math.max(v,s)-Math.min(v,s))+(Math.max(u,i)-Math.min(u,i))+(Math.max(w,t)-Math.min(w,t))};var g,o,f,k,q,h,r,c,d,b,p,m=false,l=0;do{g=Math.round(Math.random()*16777215);o=(g&16711680)>>16;f=(g&65280)>>8;k=g&255;d=n(o,f,k);m=true;for(var j=0;j<a.length;j++){q=a[j];h=(q&16711680)>>16;r=(q&65280)>>8;c=q&255;b=n(h,r,c);p=e(o,f,k,h,r,c);if((Math.abs(d-b)<40)||(p<200)){m=false;break}}l++}while(!m&&l<=10);return"#"+(16777216+g).toString(16).substr(1,6)};var create_action_icon=function(c,b,a){return $("<a/>").attr("href","javascript:void(0);").attr("title",c).addClass("icon-button").addClass(b).tipsy({gravity:"s"}).click(a)};var trackster_module=function(e,U){var p=e("class").extend,s=e("slotting"),J=e("painters");var ab=function(ac,ad){this.document=ac;this.default_font=ad!==undefined?ad:"9px Monaco, Lucida Console, monospace";this.dummy_canvas=this.new_canvas();this.dummy_context=this.dummy_canvas.getContext("2d");this.dummy_context.font=this.default_font;this.char_width_px=this.dummy_context.measureText("A").width;this.patterns={};this.load_pattern("right_strand","/visualization/strand_right.png");this.load_pattern("left_strand","/visualization/strand_left.png");this.load_pattern("right_strand_inv","/visualization/strand_right_inv.png");this.load_pattern("left_strand_inv","/visualization/strand_left_inv.png")};p(ab.prototype,{load_pattern:function(ac,ag){var ad=this.patterns,ae=this.dummy_context,af=new Image();af.src=galaxy_paths.attributes.image_path+ag;af.onload=function(){ad[ac]=ae.createPattern(af,"repeat")}},get_pattern:function(ac){return this.patterns[ac]},new_canvas:function(){var ac=this.document.createElement("canvas");if(window.G_vmlCanvasManager){G_vmlCanvasManager.initElement(ac)}ac.manager=this;return ac}});var n={};var l=function(ac,ad){n[ac.attr("id")]=ad};var m=function(ac,ae,ag,af){ag=".group";var ad={};n[ac.attr("id")]=af;ac.bind("drag",{handle:"."+ae,relative:true},function(ao,ap){var an=$(this);var at=$(this).parent(),ak=at.children(),am=n[$(this).attr("id")],aj,ai,aq,ah,al;ai=$(this).parents(ag);if(ai.length!==0){aq=ai.position().top;ah=aq+ai.outerHeight();if(ap.offsetY<aq){$(this).insertBefore(ai);var ar=n[ai.attr("id")];ar.remove_drawable(am);ar.container.add_drawable_before(am,ar);return}else{if(ap.offsetY>ah){$(this).insertAfter(ai);var ar=n[ai.attr("id")];ar.remove_drawable(am);ar.container.add_drawable(am);return}}}ai=null;for(al=0;al<ak.length;al++){aj=$(ak.get(al));aq=aj.position().top;ah=aq+aj.outerHeight();if(aj.is(ag)&&this!==aj.get(0)&&ap.offsetY>=aq&&ap.offsetY<=ah){if(ap.offsetY-aq<ah-ap.offsetY){aj.find(".content-div").prepend(this)}else{aj.find(".content-div").append(this)}if(am.container){am.container.remove_drawable(am)}n[aj.attr("id")].add_drawable(am);return}}var aj;for(al=0;al<ak.length;al++){aj=$(ak.get(al));if(ap.offsetY<aj.position().top&&!(aj.hasClass("reference-track")||aj.hasClass("intro"))){break}}if(al===ak.length){if(this!==ak.get(al-1)){at.append(this);n[at.attr("id")].move_drawable(am,al)}}else{if(this!==ak.get(al)){$(this).insertBefore(ak.get(al));n[at.attr("id")].move_drawable(am,(ap.deltaY>0?al-1:al))}}}).bind("dragstart",function(){ad["border-top"]=ac.css("border-top");ad["border-bottom"]=ac.css("border-bottom");$(this).css({"border-top":"1px solid blue","border-bottom":"1px solid blue"})}).bind("dragend",function(){$(this).css(ad)})};U.moveable=m;var aa=16,D=9,A=20,x=100,G=12000,R=400,I=5000,u=100,o="There was an error in indexing this dataset. ",H="A converter for this dataset is not installed. Please check your datatypes_conf.xml file.",B="No data for this chrom/contig.",t="Preparing data. This is very fast for a small dataset but can take a long time for a large dataset. If visualization is saved and closed, preparation will continue in the background.",v="Tool cannot be rerun: ",a="Loading data...",V="Ready for display",O=10,F=20;function W(ad,ac){if(!ac){ac=0}var ae=Math.pow(10,ac);return Math.round(ad*ae)/ae}var c=function(ac){this.num_elements=ac;this.clear()};p(c.prototype,{get:function(ad){var ac=this.key_ary.indexOf(ad);if(ac!==-1){if(this.obj_cache[ad].stale){this.key_ary.splice(ac,1);delete this.obj_cache[ad]}else{this.move_key_to_end(ad,ac)}}return this.obj_cache[ad]},set:function(ad,ae){if(!this.obj_cache[ad]){if(this.key_ary.length>=this.num_elements){var ac=this.key_ary.shift();delete this.obj_cache[ac]}this.key_ary.push(ad)}this.obj_cache[ad]=ae;return ae},move_key_to_end:function(ad,ac){this.key_ary.splice(ac,1);this.key_ary.push(ad)},clear:function(){this.obj_cache={};this.key_ary=[]},size:function(){return this.key_ary.length}});var P=function(ad,ac){c.call(this,ad);this.track=ac};p(P.prototype,c.prototype,{load_data:function(al,ag,aj,ad,ai){var ak=this.track.view.chrom,af={chrom:ak,low:al,high:ag,mode:aj,resolution:ad,dataset_id:this.track.dataset_id,hda_ldda:this.track.hda_ldda};$.extend(af,ai);if(this.track.filters_manager){var am=[];var ac=this.track.filters_manager.filters;for(var ah=0;ah<ac.length;ah++){am.push(ac[ah].name)}af.filter_cols=JSON.stringify(am)}var ae=this;return $.getJSON(this.track.data_url,af,function(an){ae.set_data(al,ag,an)})},get_data:function(ak,ae,ai,ad,ah){var al=this.get(ak,ae);if(al&&(is_deferred(al)||this.track.data_and_mode_compatible(al,ai))){return al}var am,aj,ac,ag,ai,al;for(var af=0;af<this.key_ary.length;af++){am=this.key_ary[af];aj=this.split_key(am);ac=aj[0];ag=aj[1];if(ak>=ac&&ae<=ag){var al=this.obj_cache[am];if(is_deferred(al)||(this.track.data_and_mode_compatible(al,ai)&&this.track.can_subset(al))){this.move_key_to_end(am,af);return al}}}al=this.load_data(ak,ae,ai,ad,ah);this.set_data(ak,ae,al);return al},DEEP_DATA_REQ:"deep",BROAD_DATA_REQ:"breadth",get_more_data:function(ak,af,aj,ae,ai,ag){var al=this.get(ak,af);if(!(al&&this.track.data_and_mode_compatible(al,aj))){console.log("ERROR: no current data for: ",this.track,ak,af,aj,ae,ai);return}al.stale=true;var ad=ak;if(ag===this.DEEP_DATA_REQ){$.extend(ai,{start_val:al.data.length+1})}else{if(ag===this.BROAD_DATA_REQ){ad=(al.max_high?al.max_high:al.data[al.data.length-1][2])+1}}var ac=this,ah=this.load_data(ad,af,aj,ae,ai);new_data_available=$.Deferred();this.set_data(ak,af,new_data_available);$.when(ah).then(function(am){if(am.data){am.data=al.data.concat(am.data);if(am.max_low){am.max_low=al.max_low}if(am.message){am.message=am.message.replace(/[0-9]+/,am.data.length)}}ac.set_data(ak,af,am);new_data_available.resolve(am)});return new_data_available},get:function(ac,ad){return c.prototype.get.call(this,this.gen_key(ac,ad))},set_data:function(ad,ae,ac){return this.set(this.gen_key(ad,ae),ac)},gen_key:function(ac,ae){var ad=ac+"_"+ae;return ad},split_key:function(ac){return ac.split("_")}});var E=function(ad,ac,ae){P.call(this,ad,ac,ae)};p(E.prototype,P.prototype,c.prototype,{get:P.prototype.get,load_data:function(ac,af,ag,ad,ae){if(ad>1){return{data:null}}return P.prototype.load_data.call(this,ac,af,ag,ad,ae)}});var q=function(ad,ac,af){if(!q.id_counter){q.id_counter=0}this.id=q.id_counter++;this.name=af.name;this.view=ad;this.container=ac;this.config=new C({track:this,params:[{key:"name",label:"Name",type:"text",default_value:this.name}],saved_values:af.prefs,onchange:function(){this.track.set_name(this.track.config.values.name)}});this.prefs=this.config.values;this.drag_handle_class=af.drag_handle_class;this.is_overview=false;this.action_icons={};this.content_visible=true;this.container_div=this.build_container_div();this.header_div=this.build_header_div();if(this.header_div){this.container_div.append(this.header_div);this.icons_div=$("<div/>").css("float","left").hide().appendTo(this.header_div);this.build_action_icons(this.action_icons_def);this.header_div.append($("<div style='clear: both'/>"));this.header_div.dblclick(function(ag){ag.stopPropagation()});var ae=this;this.container_div.hover(function(){ae.icons_div.show()},function(){ae.icons_div.hide()});$("<div style='clear: both'/>").appendTo(this.container_div)}};q.prototype.action_icons_def=[{name:"toggle_icon",title:"Hide/show content",css_class:"toggle",on_click_fn:function(ac){if(ac.content_visible){ac.action_icons.toggle_icon.addClass("toggle-expand").removeClass("toggle");ac.hide_contents();ac.content_visible=false}else{ac.action_icons.toggle_icon.addClass("toggle").removeClass("toggle-expand");ac.content_visible=true;ac.show_contents()}}},{name:"settings_icon",title:"Edit settings",css_class:"settings-icon",on_click_fn:function(ad){var af=function(){hide_modal();$(window).unbind("keypress.check_enter_esc")},ac=function(){ad.config.update_from_form($(".dialog-box"));hide_modal();$(window).unbind("keypress.check_enter_esc")},ae=function(ag){if((ag.keyCode||ag.which)===27){af()}else{if((ag.keyCode||ag.which)===13){ac()}}};$(window).bind("keypress.check_enter_esc",ae);show_modal("Configure",ad.config.build_form(),{Cancel:af,OK:ac})}},{name:"remove_icon",title:"Remove",css_class:"remove-icon",on_click_fn:function(ac){$(".tipsy").remove();ac.remove()}}];p(q.prototype,{init:function(){},changed:function(){this.view.changed()},can_draw:function(){if(this.enabled&&this.content_visible){return true}return false},request_draw:function(){},_draw:function(){},to_dict:function(){},update_icons:function(){},set_name:function(ac){this.old_name=this.name;this.name=ac;this.name_div.text(this.name)},revert_name:function(){if(this.old_name){this.name=this.old_name;this.name_div.text(this.name)}},remove:function(){this.changed();this.container.remove_drawable(this);var ac=this.view;this.container_div.hide(0,function(){$(this).remove();ac.update_intro_div()})},build_container_div:function(){},build_header_div:function(){},add_action_icon:function(ad,ai,ah,ag,ac,af){var ae=this;this.action_icons[ad]=$("<a/>").attr("href","javascript:void(0);").attr("title",ai).addClass("icon-button").addClass(ah).tipsy({gravity:"s"}).click(function(){ag(ae)}).appendTo(this.icons_div);if(af){this.action_icons[ad].hide()}},build_action_icons:function(ac){var ae;for(var ad=0;ad<ac.length;ad++){ae=ac[ad];this.add_action_icon(ae.name,ae.title,ae.css_class,ae.on_click_fn,ae.prepend,ae.hide)}},update_icons:function(){},hide_contents:function(){},show_contents:function(){}});var w=function(ad,ac,ae){q.call(this,ad,ac,ae);this.obj_type=ae.obj_type;this.drawables=[]};p(w.prototype,q.prototype,{unpack_drawables:function(ae){this.drawables=[];var ad;for(var ac=0;ac<ae.length;ac++){ad=object_from_template(ae[ac],this);this.add_drawable(ad)}},init:function(){for(var ac=0;ac<this.drawables.length;ac++){this.drawables[ac].init()}},_draw:function(){for(var ac=0;ac<this.drawables.length;ac++){this.drawables[ac]._draw()}},to_dict:function(){var ad=[];for(var ac=0;ac<this.drawables.length;ac++){ad.push(this.drawables[ac].to_dict())}return{name:this.name,prefs:this.prefs,obj_type:this.obj_type,drawables:ad}},add_drawable:function(ac){this.drawables.push(ac);ac.container=this;this.changed()},add_drawable_before:function(ae,ac){this.changed();var ad=this.drawables.indexOf(ac);if(ad!==-1){this.drawables.splice(ad,0,ae);return true}return false},replace_drawable:function(ae,ac,ad){var af=this.drawables.indexOf(ae);if(af!==-1){this.drawables[af]=ac;if(ad){ae.container_div.replaceWith(ac.container_div)}this.changed()}return af},remove_drawable:function(ad){var ac=this.drawables.indexOf(ad);if(ac!==-1){this.drawables.splice(ac,1);ad.container=null;this.changed();return true}return false},move_drawable:function(ad,ae){var ac=this.drawables.indexOf(ad);if(ac!==-1){this.drawables.splice(ac,1);this.drawables.splice(ae,0,ad);this.changed();return true}return false}});var N=function(ad,ac,af){p(af,{obj_type:"DrawableGroup",drag_handle_class:"group-handle"});w.call(this,ad,ac,af);this.content_div=$("<div/>").addClass("content-div").attr("id","group_"+this.id+"_content_div").appendTo(this.container_div);l(this.container_div,this);l(this.content_div,this);m(this.container_div,this.drag_handle_class,".group",this);this.filters_manager=new X(this);this.header_div.after(this.filters_manager.parent_div);this.saved_filters_managers=[];if("drawables" in af){this.unpack_drawables(af.drawables)}if("filters" in af){var ae=this.filters_manager;this.filters_manager=new X(this,af.filters);ae.parent_div.replaceWith(this.filters_manager.parent_div);if(af.filters.visible){this.setup_multitrack_filtering()}}};p(N.prototype,q.prototype,w.prototype,{action_icons_def:[q.prototype.action_icons_def[0],q.prototype.action_icons_def[1],{name:"composite_icon",title:"Show composite track",css_class:"layers-stack",on_click_fn:function(ac){$(".tipsy").remove();ac.show_composite_track()}},{name:"filters_icon",title:"Filters",css_class:"filters-icon",on_click_fn:function(ac){if(ac.filters_manager.visible()){ac.filters_manager.clear_filters();ac._restore_filter_managers()}else{ac.setup_multitrack_filtering();ac.request_draw(true)}ac.filters_manager.toggle()}},q.prototype.action_icons_def[2]],build_container_div:function(){var ac=$("<div/>").addClass("group").attr("id","group_"+this.id);if(this.container){this.container.content_div.append(ac)}return ac},build_header_div:function(){var ac=$("<div/>").addClass("track-header");ac.append($("<div/>").addClass(this.drag_handle_class));this.name_div=$("<div/>").addClass("track-name").text(this.name).appendTo(ac);return ac},hide_contents:function(){this.tiles_div.hide()},show_contents:function(){this.tiles_div.show();this.request_draw()},update_icons:function(){var ae=this.drawables.length;if(ae===0){this.action_icons.composite_icon.hide();this.action_icons.filters_icon.hide()}else{if(ae===1){if(this.drawables[0] instanceof h){this.action_icons.composite_icon.show()}this.action_icons.filters_icon.hide()}else{var ai,ao=true,ag=this.drawables[0].get_type(),ac=0;for(var al=0;al<ae;al++){ai=this.drawables[al];if(ai.get_type()!==ag){can_composite=false;break}if(ai instanceof d){ac++}}if(ao||ac===1){this.action_icons.composite_icon.show()}else{this.action_icons.composite_icon.hide();$(".tipsy").remove()}if(ac>1&&ac===this.drawables.length){var ap={},ad;ai=this.drawables[0];for(var ak=0;ak<ai.filters_manager.filters.length;ak++){ad=ai.filters_manager.filters[ak];ap[ad.name]=[ad]}for(var al=1;al<this.drawables.length;al++){ai=this.drawables[al];for(var ak=0;ak<ai.filters_manager.filters.length;ak++){ad=ai.filters_manager.filters[ak];if(ad.name in ap){ap[ad.name].push(ad)}}}this.filters_manager.remove_all();var af,ah,aj,am;for(var an in ap){af=ap[an];if(af.length===ac){ah=new S({name:af[0].name,index:af[0].index});this.filters_manager.add_filter(ah)}}if(this.filters_manager.filters.length>0){this.action_icons.filters_icon.show()}else{this.action_icons.filters_icon.hide()}}else{this.action_icons.filters_icon.hide()}}}},_restore_filter_managers:function(){for(var ac=0;ac<this.drawables.length;ac++){this.drawables[ac].filters_manager=this.saved_filters_managers[ac]}this.saved_filters_managers=[]},setup_multitrack_filtering:function(){if(this.filters_manager.filters.length>0){this.saved_filters_managers=[];for(var ac=0;ac<this.drawables.length;ac++){drawable=this.drawables[ac];this.saved_filters_managers.push(drawable.filters_manager);drawable.filters_manager=this.filters_manager}}this.filters_manager.init_filters()},show_composite_track:function(){var ag=[];for(var ad=0;ad<this.drawables.length;ad++){ag.push(this.drawables[ad].name)}var ae="Composite Track of "+this.drawables.length+" tracks ("+ag.join(", ")+")";var af=new h(this.view,this.view,{name:ae,drawables:this.drawables});var ac=this.container.replace_drawable(this,af,true);af.request_draw()},add_drawable:function(ac){w.prototype.add_drawable.call(this,ac);this.update_icons()},remove_drawable:function(ac){w.prototype.remove_drawable.call(this,ac);this.update_icons()},to_dict:function(){if(this.filters_manager.visible()){this._restore_filter_managers()}var ac=p(w.prototype.to_dict.call(this),{filters:this.filters_manager.to_dict()});if(this.filters_manager.visible()){this.setup_multitrack_filtering()}return ac},request_draw:function(ac,ae){for(var ad=0;ad<this.drawables.length;ad++){this.drawables[ad].request_draw(ac,ae)}}});var Z=function(ac){p(ac,{obj_type:"View"});w.call(this,"View",ac.container,ac);this.chrom=null;this.vis_id=ac.vis_id;this.dbkey=ac.dbkey;this.label_tracks=[];this.tracks_to_be_redrawn=[];this.max_low=0;this.max_high=0;this.zoom_factor=3;this.min_separation=30;this.has_changes=false;this.load_chroms_deferred=null;this.init();this.canvas_manager=new ab(this.container.get(0).ownerDocument);this.reset()};_.extend(Z.prototype,Backbone.Events);p(Z.prototype,w.prototype,{init:function(){this.requested_redraw=false;var ae=this.container,ac=this;this.top_container=$("<div/>").addClass("top-container").appendTo(ae);this.browser_content_div=$("<div/>").addClass("content").css("position","relative").appendTo(ae);this.bottom_container=$("<div/>").addClass("bottom-container").appendTo(ae);this.top_labeltrack=$("<div/>").addClass("top-labeltrack").appendTo(this.top_container);this.viewport_container=$("<div/>").addClass("viewport-container").attr("id","viewport-container").appendTo(this.browser_content_div);this.content_div=this.viewport_container;l(this.viewport_container,ac);this.intro_div=$("<div/>").addClass("intro").appendTo(this.viewport_container).hide();var af=$("<div/>").text("Add Datasets to Visualization").addClass("action-button").appendTo(this.intro_div).click(function(){add_tracks()});this.nav_labeltrack=$("<div/>").addClass("nav-labeltrack").appendTo(this.bottom_container);this.nav_container=$("<div/>").addClass("trackster-nav-container").prependTo(this.top_container);this.nav=$("<div/>").addClass("trackster-nav").appendTo(this.nav_container);this.overview=$("<div/>").addClass("overview").appendTo(this.bottom_container);this.overview_viewport=$("<div/>").addClass("overview-viewport").appendTo(this.overview);this.overview_close=$("<a/>").attr("href","javascript:void(0);").attr("title","Close overview").addClass("icon-button overview-close tooltip").hide().appendTo(this.overview_viewport);this.overview_highlight=$("<div/>").addClass("overview-highlight").hide().appendTo(this.overview_viewport);this.overview_box_background=$("<div/>").addClass("overview-boxback").appendTo(this.overview_viewport);this.overview_box=$("<div/>").addClass("overview-box").appendTo(this.overview_viewport);this.default_overview_height=this.overview_box.height();this.nav_controls=$("<div/>").addClass("nav-controls").appendTo(this.nav);this.chrom_select=$("<select/>").attr({name:"chrom"}).css("width","15em").addClass("no-autocomplete").append("<option value=''>Loading</option>").appendTo(this.nav_controls);var ad=function(ag){if(ag.type==="focusout"||(ag.keyCode||ag.which)===13||(ag.keyCode||ag.which)===27){if((ag.keyCode||ag.which)!==27){ac.go_to($(this).val())}$(this).hide();$(this).val("");ac.location_span.show();ac.chrom_select.show()}};this.nav_input=$("<input/>").addClass("nav-input").hide().bind("keyup focusout",ad).appendTo(this.nav_controls);this.location_span=$("<span/>").addClass("location").attr("original-title","Click to change location").tipsy({gravity:"n"}).appendTo(this.nav_controls);this.location_span.click(function(){ac.location_span.hide();ac.chrom_select.hide();ac.nav_input.val(ac.chrom+":"+ac.low+"-"+ac.high);ac.nav_input.css("display","inline-block");ac.nav_input.select();ac.nav_input.focus()});if(this.vis_id!==undefined){this.hidden_input=$("<input/>").attr("type","hidden").val(this.vis_id).appendTo(this.nav_controls)}this.zo_link=$("<a/>").attr("id","zoom-out").attr("title","Zoom out").tipsy({gravity:"n"}).click(function(){ac.zoom_out();ac.request_redraw()}).appendTo(this.nav_controls);this.zi_link=$("<a/>").attr("id","zoom-in").attr("title","Zoom in").tipsy({gravity:"n"}).click(function(){ac.zoom_in();ac.request_redraw()}).appendTo(this.nav_controls);this.load_chroms_deferred=this.load_chroms({low:0});this.chrom_select.bind("change",function(){ac.change_chrom(ac.chrom_select.val())});this.browser_content_div.click(function(ag){$(this).find("input").trigger("blur")});this.browser_content_div.bind("dblclick",function(ag){ac.zoom_in(ag.pageX,this.viewport_container)});this.overview_box.bind("dragstart",function(ag,ah){this.current_x=ah.offsetX}).bind("drag",function(ag,ai){var aj=ai.offsetX-this.current_x;this.current_x=ai.offsetX;var ah=Math.round(aj/ac.viewport_container.width()*(ac.max_high-ac.max_low));ac.move_delta(-ah)});this.overview_close.click(function(){ac.reset_overview()});this.viewport_container.bind("draginit",function(ag,ah){if(ag.clientX>ac.viewport_container.width()-16){return false}}).bind("dragstart",function(ag,ah){ah.original_low=ac.low;ah.current_height=ag.clientY;ah.current_x=ah.offsetX}).bind("drag",function(ai,ak){var ag=$(this);var al=ak.offsetX-ak.current_x;var ah=ag.scrollTop()-(ai.clientY-ak.current_height);ag.scrollTop(ah);ak.current_height=ai.clientY;ak.current_x=ak.offsetX;var aj=Math.round(al/ac.viewport_container.width()*(ac.high-ac.low));ac.move_delta(aj)}).bind("mousewheel",function(ai,ak,ah,ag){if(ah){ah*=50;var aj=Math.round(-ah/ac.viewport_container.width()*(ac.high-ac.low));ac.move_delta(aj)}});this.top_labeltrack.bind("dragstart",function(ag,ah){return $("<div />").css({height:ac.browser_content_div.height()+ac.top_labeltrack.height()+ac.nav_labeltrack.height()+1,top:"0px",position:"absolute","background-color":"#ccf",opacity:0.5,"z-index":1000}).appendTo($(this))}).bind("drag",function(ak,al){$(al.proxy).css({left:Math.min(ak.pageX,al.startX)-ac.container.offset().left,width:Math.abs(ak.pageX-al.startX)});var ah=Math.min(ak.pageX,al.startX)-ac.container.offset().left,ag=Math.max(ak.pageX,al.startX)-ac.container.offset().left,aj=(ac.high-ac.low),ai=ac.viewport_container.width();ac.update_location(Math.round(ah/ai*aj)+ac.low,Math.round(ag/ai*aj)+ac.low)}).bind("dragend",function(al,am){var ah=Math.min(al.pageX,am.startX),ag=Math.max(al.pageX,am.startX),aj=(ac.high-ac.low),ai=ac.viewport_container.width(),ak=ac.low;ac.low=Math.round(ah/ai*aj)+ak;ac.high=Math.round(ag/ai*aj)+ak;$(am.proxy).remove();ac.request_redraw()});this.add_label_track(new Y(this,{content_div:this.top_labeltrack}));this.add_label_track(new Y(this,{content_div:this.nav_labeltrack}));$(window).bind("resize",function(){if(this.resize_timer){clearTimeout(this.resize_timer)}this.resize_timer=setTimeout(function(){ac.resize_window()},500)});$(document).bind("redraw",function(){ac.redraw()});this.reset();$(window).trigger("resize")},changed:function(){this.has_changes=true},update_intro_div:function(){if(this.drawables.length===0){this.intro_div.show()}else{this.intro_div.hide()}},trigger_navigate:function(ad,af,ac,ag){if(this.timer){clearTimeout(this.timer)}if(ag){var ae=this;this.timer=setTimeout(function(){ae.trigger("navigate",ad+":"+af+"-"+ac)},500)}else{view.trigger("navigate",ad+":"+af+"-"+ac)}},update_location:function(ac,ae){this.location_span.text(commatize(ac)+" - "+commatize(ae));this.nav_input.val(this.chrom+":"+commatize(ac)+"-"+commatize(ae));var ad=view.chrom_select.val();if(ad!==""){this.trigger_navigate(ad,view.low,view.high,true)}},load_chroms:function(ae){ae.num=u;ae.dbkey=this.dbkey;var ac=this,ad=$.Deferred();$.ajax({url:chrom_url,data:ae,dataType:"json",success:function(ag){if(ag.chrom_info.length===0){alert("Invalid chromosome: "+ae.chrom);return}if(ag.reference){ac.add_label_track(new y(ac))}ac.chrom_data=ag.chrom_info;var aj='<option value="">Select Chrom/Contig</option>';for(var ai=0,af=ac.chrom_data.length;ai<af;ai++){var ah=ac.chrom_data[ai].chrom;aj+='<option value="'+ah+'">'+ah+"</option>"}if(ag.prev_chroms){aj+='<option value="previous">Previous '+u+"</option>"}if(ag.next_chroms){aj+='<option value="next">Next '+u+"</option>"}ac.chrom_select.html(aj);ac.chrom_start_index=ag.start_index;ad.resolve(ag)},error:function(){alert("Could not load chroms for this dbkey:",ac.dbkey)}});return ad},change_chrom:function(ah,ad,aj){var ae=this;if(!ae.chrom_data){ae.load_chroms_deferred.then(function(){ae.change_chrom(ah,ad,aj)});return}if(!ah||ah==="None"){return}var ae=this;if(ah==="previous"){ae.load_chroms({low:this.chrom_start_index-u});return}if(ah==="next"){ae.load_chroms({low:this.chrom_start_index+u});return}var ai=$.grep(ae.chrom_data,function(ak,al){return ak.chrom===ah})[0];if(ai===undefined){ae.load_chroms({chrom:ah},function(){ae.change_chrom(ah,ad,aj)});return}else{if(ah!==ae.chrom){ae.chrom=ah;ae.chrom_select.val(ae.chrom);ae.max_high=ai.len-1;ae.reset();ae.request_redraw(true);for(var ag=0,ac=ae.drawables.length;ag<ac;ag++){var af=ae.drawables[ag];if(af.init){af.init()}}if(ae.reference_track){ae.reference_track.init()}}if(ad!==undefined&&aj!==undefined){ae.low=Math.max(ad,0);ae.high=Math.min(aj,ae.max_high)}else{ae.low=0;ae.high=ae.max_high}ae.reset_overview();ae.request_redraw()}},go_to:function(ag){ag=ag.replace(/ |,/g,"");var ak=this,ac,af,ad=ag.split(":"),ai=ad[0],aj=ad[1];if(aj!==undefined){try{var ah=aj.split("-");ac=parseInt(ah[0],10);af=parseInt(ah[1],10)}catch(ae){return false}}ak.change_chrom(ai,ac,af)},move_fraction:function(ae){var ac=this;var ad=ac.high-ac.low;this.move_delta(ae*ad)},move_delta:function(af){var ac=this;var ae=ac.high-ac.low;if(ac.low-af<ac.max_low){ac.low=ac.max_low;ac.high=ac.max_low+ae}else{if(ac.high-af>ac.max_high){ac.high=ac.max_high;ac.low=ac.max_high-ae}else{ac.high-=af;ac.low-=af}}ac.request_redraw();var ad=ac.chrom_select.val();this.trigger_navigate(ad,ac.low,ac.high,true)},add_drawable:function(ac){w.prototype.add_drawable.call(this,ac);ac.init();this.changed();this.update_intro_div()},add_label_track:function(ac){ac.view=this;ac.init();this.label_tracks.push(ac)},remove_drawable:function(ae,ad){w.prototype.remove_drawable.call(this,ae);if(ad){var ac=this;ae.container_div.hide(0,function(){$(this).remove();ac.update_intro_div()})}},reset:function(){this.low=this.max_low;this.high=this.max_high;this.viewport_container.find(".yaxislabel").remove()},request_redraw:function(ak,ac,aj,ad){var ai=this,ag=(ad?[ad]:ai.drawables),ae;var ad;for(var ah=0;ah<ag.length;ah++){ad=ag[ah];ae=-1;for(var af=0;af<ai.tracks_to_be_redrawn.length;af++){if(ai.tracks_to_be_redrawn[af][0]===ad){ae=af;break}}if(ae<0){ai.tracks_to_be_redrawn.push([ad,ac,aj])}else{ai.tracks_to_be_redrawn[ah][1]=ac;ai.tracks_to_be_redrawn[ah][2]=aj}}if(!this.requested_redraw){requestAnimationFrame(function(){ai._redraw(ak)});this.requested_redraw=true}},_redraw:function(am){this.requested_redraw=false;var aj=this.low,af=this.high;if(aj<this.max_low){aj=this.max_low}if(af>this.max_high){af=this.max_high}var al=this.high-this.low;if(this.high!==0&&al<this.min_separation){af=aj+this.min_separation}this.low=Math.floor(aj);this.high=Math.ceil(af);this.update_location(this.low,this.high);this.resolution_b_px=(this.high-this.low)/this.viewport_container.width();this.resolution_px_b=this.viewport_container.width()/(this.high-this.low);var ac=(this.low/(this.max_high-this.max_low)*this.overview_viewport.width())||0;var ai=((this.high-this.low)/(this.max_high-this.max_low)*this.overview_viewport.width())||0;var an=13;this.overview_box.css({left:ac,width:Math.max(an,ai)}).show();if(ai<an){this.overview_box.css("left",ac-(an-ai)/2)}if(this.overview_highlight){this.overview_highlight.css({left:ac,width:ai})}if(!am){var ae,ad,ak;for(var ag=0,ah=this.tracks_to_be_redrawn.length;ag<ah;ag++){ae=this.tracks_to_be_redrawn[ag][0];ad=this.tracks_to_be_redrawn[ag][1];ak=this.tracks_to_be_redrawn[ag][2];if(ae){ae._draw(ad,ak)}}this.tracks_to_be_redrawn=[];for(ag=0,ah=this.label_tracks.length;ag<ah;ag++){this.label_tracks[ag]._draw()}}},zoom_in:function(ad,ae){if(this.max_high===0||this.high-this.low<=this.min_separation){return}var af=this.high-this.low,ag=af/2+this.low,ac=(af/this.zoom_factor)/2;if(ad){ag=ad/this.viewport_container.width()*(this.high-this.low)+this.low}this.low=Math.round(ag-ac);this.high=Math.round(ag+ac);this.changed();this.request_redraw()},zoom_out:function(){if(this.max_high===0){return}var ad=this.high-this.low,ae=ad/2+this.low,ac=(ad*this.zoom_factor)/2;this.low=Math.round(ae-ac);this.high=Math.round(ae+ac);this.changed();this.request_redraw()},resize_window:function(){this.viewport_container.height(this.container.height()-this.top_container.height()-this.bottom_container.height());this.request_redraw()},set_overview:function(ae){if(this.overview_drawable){if(this.overview_drawable.dataset_id===ae.dataset_id){return}this.overview_viewport.find(".track").remove()}var ad=ae.copy({content_div:this.overview_viewport}),ac=this;ad.header_div.hide();ad.is_overview=true;ac.overview_drawable=ad;this.overview_drawable.postdraw_actions=function(){ac.overview_highlight.show().height(ac.overview_drawable.content_div.height());ac.overview_viewport.height(ac.overview_drawable.content_div.height()+ac.overview_box.outerHeight());ac.overview_close.show();ac.resize_window()};ac.overview_drawable.request_draw();this.changed()},reset_overview:function(){$(".tipsy").remove();this.overview_viewport.find(".track-tile").remove();this.overview_viewport.height(this.default_overview_height);this.overview_box.height(this.default_overview_height);this.overview_close.hide();this.overview_highlight.hide();view.resize_window();view.overview_drawable=null}});var r=function(ae,aj,af){this.track=ae;this.name=aj.name;this.params=[];var aq=aj.params;for(var ag=0;ag<aq.length;ag++){var al=aq[ag],ad=al.name,ap=al.label,ah=unescape(al.html),ar=al.value,an=al.type;if(an==="number"){this.params.push(new f(ad,ap,ah,(ad in af?af[ad]:ar),al.min,al.max))}else{if(an==="select"){this.params.push(new L(ad,ap,ah,(ad in af?af[ad]:ar)))}else{console.log("WARNING: unrecognized tool parameter type:",ad,an)}}}this.parent_div=$("<div/>").addClass("dynamic-tool").hide();this.parent_div.bind("drag",function(au){au.stopPropagation()}).click(function(au){au.stopPropagation()}).bind("dblclick",function(au){au.stopPropagation()});var ao=$("<div class='tool-name'>").appendTo(this.parent_div).text(this.name);var am=this.params;var ak=this;$.each(this.params,function(av,ay){var ax=$("<div>").addClass("param-row").appendTo(ak.parent_div);var au=$("<div>").addClass("param-label").text(ay.label).appendTo(ax);var aw=$("<div/>").addClass("param-input").html(ay.html).appendTo(ax);aw.find(":input").val(ay.value);$("<div style='clear: both;'/>").appendTo(ax)});this.parent_div.find("input").click(function(){$(this).select()});var at=$("<div>").addClass("param-row").appendTo(this.parent_div);var ai=$("<input type='submit'>").attr("value","Run on complete dataset").appendTo(at);var ac=$("<input type='submit'>").attr("value","Run on visible region").css("margin-left","3em").appendTo(at);var ak=this;ac.click(function(){ak.run_on_region()});ai.click(function(){ak.run_on_dataset()});if("visible" in af&&af.visible){this.parent_div.show()}};p(r.prototype,{update_params:function(){for(var ac=0;ac<this.params.length;ac++){this.params[ac].update_value()}},state_dict:function(){var ad={};for(var ac=0;ac<this.params.length;ac++){ad[this.params[ac].name]=this.params[ac].value}ad.visible=this.parent_div.is(":visible");return ad},get_param_values_dict:function(){var ac={};this.parent_div.find(":input").each(function(){var ad=$(this).attr("name"),ae=$(this).val();ac[ad]=JSON.stringify(ae)});return ac},get_param_values:function(){var ad=[];var ac={};this.parent_div.find(":input").each(function(){var ae=$(this).attr("name"),af=$(this).val();if(ae){ad[ad.length]=af}});return ad},run_on_dataset:function(){var ac=this;ac.run({dataset_id:this.track.original_dataset_id,tool_id:ac.name},null,function(ad){show_modal(ac.name+" is Running",ac.name+" is running on the complete dataset. Tool outputs are in dataset's history.",{Close:hide_modal})})},run_on_region:function(){var ad={dataset_id:this.track.original_dataset_id,chrom:this.track.view.chrom,low:this.track.view.low,high:this.track.view.high,tool_id:this.name},ah=this.track,ae=ad.tool_id+ah.tool_region_and_parameters_str(ad.chrom,ad.low,ad.high),ac;if(ah.container===view){var ag=new N(view,view,{name:this.name});var af=ah.container.replace_drawable(ah,ag,false);ag.container_div.insertBefore(ah.view.content_div.children()[af]);ag.add_drawable(ah);ah.container_div.appendTo(ag.content_div);ac=ag}else{ac=ah.container}var ai=new ah.constructor(view,ac,{name:ae,hda_ldda:"hda"});ai.init_for_tool_data();ai.change_mode(ah.mode);ai.set_filters_manager(ah.filters_manager.copy(ai));ai.update_icons();ac.add_drawable(ai);ai.tiles_div.text("Starting job.");this.update_params();this.run(ad,ai,function(aj){ai.dataset_id=aj.dataset_id;ai.tiles_div.text("Running job.");ai.init()})},run:function(ad,ae,af){$.extend(ad,this.get_param_values_dict());var ac=function(){$.getJSON(rerun_tool_url,ad,function(ag){if(ag==="no converter"){ae.container_div.addClass("error");ae.content_div.text(H)}else{if(ag.error){ae.container_div.addClass("error");ae.content_div.text(v+ag.message)}else{if(ag==="pending"){ae.container_div.addClass("pending");ae.content_div.text("Converting input data so that it can be used quickly with tool.");setTimeout(ac,2000)}else{af(ag)}}}})};ac()}});var L=function(ad,ac,ae,af){this.name=ad;this.label=ac;this.html=$(ae);this.value=af};p(L.prototype,{update_value:function(){this.value=$(this.html).val()}});var f=function(ae,ad,ag,ah,af,ac){L.call(this,ae,ad,ag,ah);this.min=af;this.max=ac};p(f.prototype,L.prototype,{update_value:function(){L.prototype.update_value.call(this);this.value=parseFloat(this.value)}});var g=function(ac){this.manager=null;this.name=ac.name;this.index=ac.index;this.tool_id=ac.tool_id;this.tool_exp_name=ac.tool_exp_name};p(g.prototype,{to_dict:function(){return{name:this.name,index:this.index,tool_id:this.tool_id,tool_exp_name:this.tool_exp_name}}});var S=function(al){g.call(this,al);this.low=("low" in al?al.low:-Number.MAX_VALUE);this.high=("high" in al?al.high:Number.MAX_VALUE);this.min=("min" in al?al.min:Number.MAX_VALUE);this.max=("max" in al?al.max:-Number.MAX_VALUE);this.container=null;this.slider=null;this.slider_label=null;var ah=function(am,an,ao){am.click(function(){var au=an.text(),ar=parseFloat(ao.slider("option","max")),aq=(ar<=1?4:ar<=1000000?ar.toString().length:6),at=false,ap=$(this).parents(".slider-row");ap.addClass("input");if(ao.slider("option","values")){aq=2*aq+1;at=true}an.text("");$("<input type='text'/>").attr("size",aq).attr("maxlength",aq).attr("value",au).appendTo(an).focus().select().click(function(av){av.stopPropagation()}).blur(function(){$(this).remove();an.text(au);ap.removeClass("input")}).keyup(function(az){if(az.keyCode===27){$(this).trigger("blur")}else{if(az.keyCode===13){var ax=ao.slider("option","min"),av=ao.slider("option","max"),ay=function(aA){return(isNaN(aA)||aA>av||aA<ax)},aw=$(this).val();if(!at){aw=parseFloat(aw);if(ay(aw)){alert("Parameter value must be in the range ["+ax+"-"+av+"]");return $(this)}}else{aw=aw.split("-");aw=[parseFloat(aw[0]),parseFloat(aw[1])];if(ay(aw[0])||ay(aw[1])){alert("Parameter value must be in the range ["+ax+"-"+av+"]");return $(this)}}ao.slider((at?"values":"value"),aw);ap.removeClass("input")}}})})};var ad=this;ad.parent_div=$("<div/>").addClass("filter-row slider-row");var ac=$("<div/>").addClass("elt-label").appendTo(ad.parent_div),aj=$("<span/>").addClass("slider-name").text(ad.name+" ").appendTo(ac),ae=$("<span/>").text(this.low+"-"+this.high),af=$("<span/>").addClass("slider-value").appendTo(ac).append("[").append(ae).append("]");ad.values_span=ae;var ai=$("<div/>").addClass("slider").appendTo(ad.parent_div);ad.control_element=$("<div/>").attr("id",ad.name+"-filter-control").appendTo(ai);var ag=[0,0];ad.control_element.slider({range:true,min:this.min,max:this.max,step:this.get_slider_step(this.min,this.max),values:[this.low,this.high],slide:function(am,an){ad.slide(am,an)},change:function(am,an){ad.control_element.slider("option","slide").call(ad.control_element,am,an)}});ad.slider=ad.control_element;ad.slider_label=ae;ah(af,ae,ad.control_element);var ak=$("<div/>").addClass("display-controls").appendTo(ad.parent_div);this.transparency_icon=create_action_icon("Use filter for data transparency","layer-transparent",function(){if(ad.manager.alpha_filter!==ad){ad.manager.alpha_filter=ad;ad.manager.parent_div.find(".layer-transparent").removeClass("active").hide();ad.transparency_icon.addClass("active").show()}else{ad.manager.alpha_filter=null;ad.transparency_icon.removeClass("active")}ad.manager.track.request_draw(true,true)}).appendTo(ak).hide();this.height_icon=create_action_icon("Use filter for data height","arrow-resize-090",function(){if(ad.manager.height_filter!==ad){ad.manager.height_filter=ad;ad.manager.parent_div.find(".arrow-resize-090").removeClass("active").hide();ad.height_icon.addClass("active").show()}else{ad.manager.height_filter=null;ad.height_icon.removeClass("active")}ad.manager.track.request_draw(true,true)}).appendTo(ak).hide();ad.parent_div.hover(function(){ad.transparency_icon.show();ad.height_icon.show()},function(){if(ad.manager.alpha_filter!==ad){ad.transparency_icon.hide()}if(ad.manager.height_filter!==ad){ad.height_icon.hide()}});$("<div style='clear: both;'/>").appendTo(ad.parent_div)};p(S.prototype,{to_dict:function(){var ac=g.prototype.to_dict.call(this);return p(ac,{type:"number",min:this.min,max:this.max,low:this.low,high:this.high})},copy:function(){return new S({name:this.name,index:this.index,tool_id:this.tool_id,tool_exp_name:this.tool_exp_name})},get_slider_step:function(ae,ac){var ad=ac-ae;return(ad<=2?0.01:1)},slide:function(ad,ae){var ac=ae.values;this.values_span.text(ac[0]+"-"+ac[1]);this.low=ac[0];this.high=ac[1];this.manager.track.request_draw(true,true)},applies_to:function(ac){if(ac.length>this.index){return true}return false},_keep_val:function(ac){return(isNaN(ac)||(ac>=this.low&&ac<=this.high))},keep:function(ad){if(!this.applies_to(ad)){return true}var af=this;var ag=ad[this.index];if(ag instanceof Array){var ae=true;for(var ac=0;ac<ag.length;ac++){if(!this._keep_val(ag[ac])){ae=false;break}}return ae}else{return this._keep_val(ad[this.index])}},update_attrs:function(af){var ac=false;if(!this.applies_to(af)){return ac}var ad=af[this.index];if(!(ad instanceof Array)){ad=[ad]}for(var ae=0;ae<ad.length;ae++){var ag=ad[ae];if(ag<this.min){this.min=Math.floor(ag);ac=true}if(ag>this.max){this.max=Math.ceil(ag);ac=true}}return ac},update_ui_elt:function(){if(this.min!==this.max){this.parent_div.show()}else{this.parent_div.hide()}var ad=this.slider.slider("option","min"),ac=this.slider.slider("option","max");if(this.min<ad||this.max>ac){this.slider.slider("option","min",this.min);this.slider.slider("option","max",this.max);this.slider.slider("option","step",this.get_slider_step(this.min,this.max));this.slider.slider("option","values",[this.min,this.max])}}});var X=function(ae,ak){this.track=ae;this.alpha_filter=null;this.height_filter=null;this.filters=[];this.parent_div=$("<div/>").addClass("filters").hide();this.parent_div.bind("drag",function(am){am.stopPropagation()}).click(function(am){am.stopPropagation()}).bind("dblclick",function(am){am.stopPropagation()}).bind("keydown",function(am){am.stopPropagation()});if(ak&&"filters" in ak){var ac=("alpha_filter" in ak?ak.alpha_filter:null),af=("height_filter" in ak?ak.height_filter:null),ah=ak.filters,ad;for(var ai=0;ai<ah.length;ai++){if(ah[ai].type==="number"){ad=new S(ah[ai]);this.add_filter(ad);if(ad.name===ac){this.alpha_filter=ad;ad.transparency_icon.addClass("active").show()}if(ad.name===af){this.height_filter=ad;ad.height_icon.addClass("active").show()}}else{console.log("ERROR: unsupported filter: ",name,type)}}if("visible" in ak&&ak.visible){this.parent_div.show()}}if(this.filters.length!==0){var al=$("<div/>").addClass("param-row").appendTo(this.parent_div);var aj=$("<input type='submit'/>").attr("value","Run on complete dataset").appendTo(al);var ag=this;aj.click(function(){ag.run_on_dataset()})}};p(X.prototype,{show:function(){this.parent_div.show()},hide:function(){this.parent_div.hide()},toggle:function(){this.parent_div.toggle()},visible:function(){return this.parent_div.is(":visible")},to_dict:function(){var af={},ae=[],ad;for(var ac=0;ac<this.filters.length;ac++){ad=this.filters[ac];ae.push(ad.to_dict())}af.filters=ae;af.alpha_filter=(this.alpha_filter?this.alpha_filter.name:null);af.height_filter=(this.height_filter?this.height_filter.name:null);af.visible=this.parent_div.is(":visible");return af},copy:function(ad){var ae=new X(ad);for(var ac=0;ac<this.filters.length;ac++){ae.add_filter(this.filters[ac].copy())}return ae},add_filter:function(ac){ac.manager=this;this.parent_div.append(ac.parent_div);this.filters.push(ac)},remove_all:function(){this.filters=[];this.parent_div.children().remove()},init_filters:function(){for(var ac=0;ac<this.filters.length;ac++){var ad=this.filters[ac];ad.update_ui_elt()}},clear_filters:function(){for(var ac=0;ac<this.filters.length;ac++){var ad=this.filters[ac];ad.slider.slider("option","values",[ad.min,ad.max])}this.alpha_filter=null;this.height_filter=null;this.parent_div.find(".icon-button").hide()},run_on_dataset:function(){var ak=function(ao,am,an){if(!(am in ao)){ao[am]=an}return ao[am]};var ae={},ac,ad,af;for(var ag=0;ag<this.filters.length;ag++){ac=this.filters[ag];if(ac.tool_id){if(ac.min!==ac.low){ad=ak(ae,ac.tool_id,[]);ad[ad.length]=ac.tool_exp_name+" >= "+ac.low}if(ac.max!==ac.high){ad=ak(ae,ac.tool_id,[]);ad[ad.length]=ac.tool_exp_name+" <= "+ac.high}}}var ai=[];for(var al in ae){ai[ai.length]=[al,ae[al]]}var aj=ai.length;(function ah(at,ap){var an=ap[0],ao=an[0],ar=an[1],aq="("+ar.join(") and (")+")",am={cond:aq,input:at,target_dataset_id:at,tool_id:ao},ap=ap.slice(1);$.getJSON(run_tool_url,am,function(au){if(au.error){show_modal("Filter Dataset","Error running tool "+ao,{Close:hide_modal})}else{if(ap.length===0){show_modal("Filtering Dataset","Filter(s) are running on the complete dataset. Outputs are in dataset's history.",{Close:hide_modal})}else{ah(au.dataset_id,ap)}}})})(this.track.dataset_id,ai)}});var z=function(ac,ad){J.Scaler.call(this,ad);this.filter=ac};z.prototype.gen_val=function(ac){if(this.filter.high===Number.MAX_VALUE||this.filter.low===-Number.MAX_VALUE||this.filter.low===this.filter.high){return this.default_val}return((parseFloat(ac[this.filter.index])-this.filter.low)/(this.filter.high-this.filter.low))};var C=function(ac){this.track=ac.track;this.params=ac.params;this.values={};this.restore_values((ac.saved_values?ac.saved_values:{}));this.onchange=ac.onchange};p(C.prototype,{restore_values:function(ac){var ad=this;$.each(this.params,function(ae,af){if(ac[af.key]!==undefined){ad.values[af.key]=ac[af.key]}else{ad.values[af.key]=af.default_value}})},build_form:function(){var af=this;var ac=$("<div />");var ae;function ad(aj,ag){for(var an=0;an<aj.length;an++){ae=aj[an];if(ae.hidden){continue}var ah="param_"+an;var ar=af.values[ae.key];var av=$("<div class='form-row' />").appendTo(ag);av.append($("<label />").attr("for",ah).text(ae.label+":"));if(ae.type==="bool"){av.append($('<input type="checkbox" />').attr("id",ah).attr("name",ah).attr("checked",ar))}else{if(ae.type==="text"){av.append($('<input type="text"/>').attr("id",ah).val(ar).click(function(){$(this).select()}))}else{if(ae.type==="select"){var ap=$("<select />").attr("id",ah);for(var al=0;al<ae.options.length;al++){$("<option/>").text(ae.options[al].label).attr("value",ae.options[al].value).appendTo(ap)}ap.val(ar);av.append(ap)}else{if(ae.type==="color"){var au=$("<div/>").appendTo(av),ao=$("<input />").attr("id",ah).attr("name",ah).val(ar).css("float","left").appendTo(au).click(function(ax){$(".tipsy").hide();var aw=$(this).siblings(".tipsy");aw.css({left:$(this).position().left+$(this).width()+5,top:$(this).position().top-($(aw).height()/2)+($(this).height()/2)}).show();aw.click(function(ay){ay.stopPropagation()});$(document).bind("click.color-picker",function(){aw.hide();$(document).unbind("click.color-picker")});ax.stopPropagation()}),am=$("<a href='javascript:void(0)'/>").addClass("icon-button arrow-circle").appendTo(au).attr("title","Set new random color").tipsy({gravity:"s"}),aq=$("<div class='tipsy tipsy-west' style='position: absolute;' />").appendTo(au).hide(),ai=$("<div style='background-color: black; padding: 10px;'></div>").appendTo(aq),at=$("<div/>").appendTo(ai),ak=$.farbtastic(at,{width:100,height:100,callback:ao,color:ar});au.append($("<div/>").css("clear","both"));(function(aw){am.click(function(){aw.setColor(get_random_color())})})(ak)}else{av.append($("<input />").attr("id",ah).attr("name",ah).val(ar))}}}}if(ae.help){av.append($("<div class='help'/>").text(ae.help))}}}ad(this.params,ac);return ac},update_from_form:function(ac){var ae=this;var ad=false;$.each(this.params,function(af,ah){if(!ah.hidden){var ai="param_"+af;var ag=ac.find("#"+ai).val();if(ah.type==="float"){ag=parseFloat(ag)}else{if(ah.type==="int"){ag=parseInt(ag)}else{if(ah.type==="bool"){ag=ac.find("#"+ai).is(":checked")}}}if(ag!==ae.values[ah.key]){ae.values[ah.key]=ag;ad=true}}});if(ad){this.onchange();this.track.changed()}}});var b=function(ac,af,ae,ad,ag){this.track=ac;this.index=af;var ah=this.track._get_tile_bounds(af,ae);this.low=ah[0];this.high=ah[1];this.resolution=ae;this.html_elt=$("<div class='track-tile'/>").append(ad);this.data=ag;this.stale=false};b.prototype.predisplay_actions=function(){};var k=function(ac,af,ae,ad,ag,ah){b.call(this,ac,af,ae,ad,ag);this.max_val=ah};p(k.prototype,b.prototype);var M=function(af,ak,ag,ae,ai,ao,aj,ap,ad,am){b.call(this,af,ak,ag,ae,ai);this.mode=aj;this.all_slotted=ad;this.feature_mapper=am;this.has_icons=false;if(ap){this.has_icons=true;var al=this;ae=this.html_elt.children()[0],message_div=$("<div/>").addClass("tile-message").css({height:A-1,width:ae.width}).prependTo(this.html_elt);var an=ai.length,ah=$("<a href='javascript:void(0);'/>").addClass("icon more-down").attr("title","For speed, only the first "+an+" features in this region were obtained from server. Click to get more data including depth").tipsy({gravity:"s"}).appendTo(message_div),ac=$("<a href='javascript:void(0);'/>").addClass("icon more-across").attr("title","For speed, only the first "+an+" features in this region were obtained from server. Click to get more data excluding depth").tipsy({gravity:"s"}).appendTo(message_div);ah.click(function(){al.stale=true;af.data_manager.get_more_data(al.low,al.high,af.mode,al.resolution,{},af.data_manager.DEEP_DATA_REQ);$(".tipsy").hide();af.request_draw()}).dblclick(function(aq){aq.stopPropagation()});ac.click(function(){al.stale=true;af.data_manager.get_more_data(al.low,al.high,af.mode,al.resolution,{},af.data_manager.BROAD_DATA_REQ);$(".tipsy").hide();af.request_draw()}).dblclick(function(aq){aq.stopPropagation()})}};p(M.prototype,b.prototype);M.prototype.predisplay_actions=function(){var ad=this,ac={};if(ad.mode!=="Pack"){return}$(this.html_elt).hover(function(){this.hovered=true;$(this).mousemove()},function(){this.hovered=false;$(this).parents(".track-content").children(".overlay").children(".feature-popup").remove()}).mousemove(function(ao){if(!this.hovered){return}var aj=$(this).offset(),an=ao.pageX-aj.left,am=ao.pageY-aj.top,at=ad.feature_mapper.get_feature_data(an,am),ak=(at?at[0]:null);$(this).parents(".track-content").children(".overlay").children(".feature-popup").each(function(){if(!ak||$(this).attr("id")!==ak.toString()){$(this).remove()}});if(at){var af=ac[ak];if(!af){var ak=at[0],ap={name:at[3],start:at[1],end:at[2],strand:at[4]},ai=ad.track.filters_manager.filters,ah;for(var al=0;al<ai.length;al++){ah=ai[al];ap[ah.name]=at[ah.index]}var af=$("<div/>").attr("id",ak).addClass("feature-popup"),au=$("<table/>"),ar,aq,av;for(ar in ap){aq=ap[ar];av=$("<tr/>").appendTo(au);$("<th/>").appendTo(av).text(ar);$("<td/>").attr("align","left").appendTo(av).text(typeof(aq)==="number"?W(aq,2):aq)}af.append($("<div class='feature-popup-inner'>").append(au));ac[ak]=af}af.appendTo($(this).parents(".track-content").children(".overlay"));var ag=an+parseInt(ad.html_elt.css("left"))-af.width()/2,ae=am+parseInt(ad.html_elt.css("top"))+7;af.css("left",ag+"px").css("top",ae+"px")}else{if(!ao.isPropagationStopped()){ao.stopPropagation();$(this).siblings().each(function(){$(this).trigger(ao)})}}}).mouseleave(function(){$(this).parents(".track-content").children(".overlay").children(".feature-popup").remove()})};var i=function(ad,ac,ae){p(ae,{drag_handle_class:"draghandle"});q.call(this,ad,ac,ae);this.data_url=("data_url" in ae?ae.data_url:default_data_url);this.data_url_extra_params={};this.data_query_wait=("data_query_wait" in ae?ae.data_query_wait:I);this.dataset_check_url=converted_datasets_state_url;this.data_manager=("data_manager" in ae?ae.data_manager:new P(F,this));this.min_height_px=16;this.max_height_px=800;this.visible_height_px=0;this.content_div=$("<div class='track-content'>").appendTo(this.container_div);if(this.container){this.container.content_div.append(this.container_div);if(!("resize" in ae)||ae.resize){this.add_resize_handle()}}};p(i.prototype,q.prototype,{action_icons_def:[{name:"mode_icon",title:"Set display mode",css_class:"chevron-expand",on_click_fn:function(){}},q.prototype.action_icons_def[0],{name:"overview_icon",title:"Set as overview",css_class:"overview-icon",on_click_fn:function(ac){ac.view.set_overview(ac)}},q.prototype.action_icons_def[1],{name:"filters_icon",title:"Filters",css_class:"filters-icon",on_click_fn:function(ac){if(ac.filters_manager.visible()){ac.filters_manager.clear_filters()}else{ac.filters_manager.init_filters()}ac.filters_manager.toggle()}},{name:"tools_icon",title:"Tool",css_class:"hammer",on_click_fn:function(ac){ac.dynamic_tool_div.toggle();if(ac.dynamic_tool_div.is(":visible")){ac.set_name(ac.name+ac.tool_region_and_parameters_str())}else{ac.revert_name()}$(".tipsy").remove()}},q.prototype.action_icons_def[2]],can_draw:function(){if(this.dataset_id&&q.prototype.can_draw.call(this)){return true}return false},build_container_div:function(){return $("<div/>").addClass("track").attr("id","track_"+this.id).css("position","relative")},build_header_div:function(){var ac=$("<div class='track-header'/>");if(this.view.editor){this.drag_div=$("<div/>").addClass(this.drag_handle_class).appendTo(ac)}this.name_div=$("<div/>").addClass("track-name").appendTo(ac).text(this.name).attr("id",this.name.replace(/\s+/g,"-").replace(/[^a-zA-Z0-9\-]/g,"").toLowerCase());return ac},on_resize:function(){},add_resize_handle:function(){var ac=this;var af=false;var ae=false;var ad=$("<div class='track-resize'>");$(ac.container_div).hover(function(){if(ac.content_visible){af=true;ad.show()}},function(){af=false;if(!ae){ad.hide()}});ad.hide().bind("dragstart",function(ag,ah){ae=true;ah.original_height=$(ac.content_div).height()}).bind("drag",function(ah,ai){var ag=Math.min(Math.max(ai.original_height+ai.deltaY,ac.min_height_px),ac.max_height_px);$(ac.tiles_div).css("height",ag);ac.visible_height_px=(ac.max_height_px===ag?0:ag);ac.on_resize()}).bind("dragend",function(ag,ah){ac.tile_cache.clear();ae=false;if(!af){ad.hide()}ac.config.values.height=ac.visible_height_px;ac.changed()}).appendTo(ac.container_div)},set_display_modes:function(af,ai){this.display_modes=af;this.mode=(ai?ai:(this.config&&this.config.values.mode?this.config.values.mode:this.display_modes[0]));this.action_icons.mode_icon.attr("title","Set display mode (now: "+this.mode+")");var ad=this,ag={};for(var ae=0,ac=ad.display_modes.length;ae<ac;ae++){var ah=ad.display_modes[ae];ag[ah]=function(aj){return function(){ad.change_mode(aj);ad.icons_div.show();ad.container_div.mouseleave(function(){ad.icons_div.hide()})}}(ah)}make_popupmenu(this.action_icons.mode_icon,ag)},build_action_icons:function(){q.prototype.build_action_icons.call(this,this.action_icons_def);if(this.display_modes!==undefined){this.set_display_modes(this.display_modes)}},hide_contents:function(){this.tiles_div.hide();this.container_div.find(".yaxislabel, .track-resize").hide()},show_contents:function(){this.tiles_div.show();this.container_div.find(".yaxislabel, .track-resize").show();this.request_draw()},get_type:function(){if(this instanceof Y){return"LabelTrack"}else{if(this instanceof y){return"ReferenceTrack"}else{if(this instanceof j){return"LineTrack"}else{if(this instanceof T){return"ReadTrack"}else{if(this instanceof Q){return"VcfTrack"}else{if(this instanceof h){return"CompositeTrack"}else{if(this instanceof d){return"FeatureTrack"}}}}}}}return""},init:function(){var ad=this;ad.enabled=false;ad.tile_cache.clear();ad.data_manager.clear();ad.content_div.css("height","auto");ad.tiles_div.children().remove();ad.container_div.removeClass("nodata error pending");if(!ad.dataset_id){return}var ac=$.Deferred();$.getJSON(this.dataset_check_url,{hda_ldda:ad.hda_ldda,dataset_id:ad.dataset_id,chrom:ad.view.chrom},function(ae){if(!ae||ae==="error"||ae.kind==="error"){ad.container_div.addClass("error");ad.tiles_div.text(o);if(ae.message){var af=$(" <a href='javascript:void(0);'></a>").text("View error").click(function(){show_modal("Trackster Error","<pre>"+ae.message+"</pre>",{Close:hide_modal})});ad.tiles_div.append(af)}}else{if(ae==="no converter"){ad.container_div.addClass("error");ad.tiles_div.text(H)}else{if(ae==="no data"||(ae.data!==undefined&&(ae.data===null||ae.data.length===0))){ad.container_div.addClass("nodata");ad.tiles_div.text(B)}else{if(ae==="pending"){ad.container_div.addClass("pending");ad.tiles_div.html(t);setTimeout(function(){ad.init()},ad.data_query_wait)}else{if(ae==="data"||ae.status==="data"){if(ae.valid_chroms){ad.valid_chroms=ae.valid_chroms;ad.update_icons()}ad.tiles_div.text(V);if(ad.view.chrom){ad.tiles_div.text("");ad.tiles_div.css("height",ad.visible_height_px+"px");ad.enabled=true;$.when(ad.predraw_init()).done(function(){ac.resolve();ad.container_div.removeClass("nodata error pending");ad.request_draw()})}else{ac.resolve()}}}}}}});this.update_icons();return ac},predraw_init:function(){}});var K=function(ae,ad,af){i.call(this,ae,ad,af);var ac=this,ae=ac.view;m(ac.container_div,ac.drag_handle_class,".group",ac);this.filters_manager=new X(this,("filters" in af?af.filters:null));this.filters_available=false;this.tool=("tool" in af&&af.tool?new r(this,af.tool,af.tool_state):null);this.tile_cache=new c(O);if(this.header_div){this.set_filters_manager(this.filters_manager);if(this.tool){this.dynamic_tool_div=this.tool.parent_div;this.header_div.after(this.dynamic_tool_div)}}this.tiles_div=$("<div/>").addClass("tiles").appendTo(this.content_div);this.overlay_div=$("<div/>").addClass("overlay").appendTo(this.content_div);if(af.mode){this.change_mode(af.mode)}};p(K.prototype,q.prototype,i.prototype,{action_icons_def:i.prototype.action_icons_def.concat([{name:"show_more_rows_icon",title:"To minimize track height, not all feature rows are displayed. Click to display more rows.",css_class:"exclamation",on_click_fn:function(ac){$(".tipsy").remove();ac.slotters[ac.view.resolution_px_b].max_rows*=2;ac.request_draw(true)},hide:true}]),copy:function(ac){var ad=this.to_dict();p(ad,{data_manager:this.data_manager});var ae=new this.constructor(this.view,ac,ad);ae.change_mode(this.mode);ae.enabled=this.enabled;return ae},set_filters_manager:function(ac){this.filters_manager=ac;this.header_div.after(this.filters_manager.parent_div)},to_dict:function(){return{track_type:this.get_type(),name:this.name,hda_ldda:this.hda_ldda,dataset_id:this.dataset_id,prefs:this.prefs,mode:this.mode,filters:this.filters_manager.to_dict(),tool_state:(this.tool?this.tool.state_dict():{})}},change_mode:function(ad){var ac=this;ac.mode=ad;ac.config.values.mode=ad;ac.tile_cache.clear();ac.request_draw();this.action_icons.mode_icon.attr("title","Set display mode (now: "+ac.mode+")");return ac},update_icons:function(){var ac=this;if(ac.filters_available){ac.action_icons.filters_icon.show()}else{ac.action_icons.filters_icon.hide()}if(ac.tool){ac.action_icons.tools_icon.show()}else{ac.action_icons.tools_icon.hide()}},_gen_tile_cache_key:function(ad,ae,ac){return ad+"_"+ae+"_"+ac},request_draw:function(ad,ac){this.view.request_redraw(false,ad,ac,this)},before_draw:function(){},_draw:function(ad,an){if(!this.can_draw()){return}var al=this.view.low,ah=this.view.high,aj=ah-al,ae=this.view.container.width(),ap=this.view.resolution_px_b,ag=this.view.resolution_b_px;if(this.is_overview){al=this.view.max_low;ah=this.view.max_high;ag=Math.pow(RESOLUTION,Math.ceil(Math.log((view.max_high-view.max_low)/R)/Math.log(RESOLUTION)));ap=ae/(view.max_high-view.max_low)}this.before_draw();this.tiles_div.children().addClass("remove");var ac=Math.floor(al/(ag*R)),ak=true,ao=[],ai=function(aq){return(aq&&"track" in aq)};while((ac*R*ag)<ah){var am=this.draw_helper(ad,ae,ac,ag,this.tiles_div,ap);if(ai(am)){ao.push(am)}else{ak=false}ac+=1}if(!an){this.tiles_div.children(".remove").remove()}var af=this;if(ak){this.tiles_div.children(".remove").remove();af.postdraw_actions(ao,ae,ap,an)}},postdraw_actions:function(af,ag,ai,ac){var ae=this;var ah=false;for(var ad=0;ad<af.length;ad++){if(af[ad].has_icons){ah=true;break}}if(ah){for(var ad=0;ad<af.length;ad++){tile=af[ad];if(!tile.has_icons){tile.html_elt.css("padding-top",A)}}}},draw_helper:function(ac,ao,au,ar,ah,ai,ap){var an=this,ax=this._gen_tile_cache_key(ao,ai,au),af=this._get_tile_bounds(au,ar),av=af[0],ad=af[1];if(!ap){ap={}}var aw=(ac?undefined:an.tile_cache.get(ax));if(aw){an.show_tile(aw,ah,ai);return aw}var al=true;var at=an.data_manager.get_data(av,ad,an.mode,ar,an.data_url_extra_params);if(is_deferred(at)){al=false}var aj;if(view.reference_track&&ai>view.canvas_manager.char_width_px){aj=view.reference_track.data_manager.get_data(av,ad,an.mode,ar,view.reference_track.data_url_extra_params);if(is_deferred(aj)){al=false}}if(al){p(at,ap.more_tile_data);var ak=an.mode;if(ak==="Auto"){ak=an.get_mode(at);an.update_auto_mode(ak)}var ae=an.view.canvas_manager.new_canvas(),af=an._get_tile_bounds(au,ar),av=af[0],ad=af[1],ao=Math.ceil((ad-av)*ai)+an.left_offset,am=an.get_canvas_height(at,ak,ai,ao);ae.width=ao;ae.height=am;var aq=ae.getContext("2d");aq.translate(this.left_offset,0);var aw=an.draw_tile(at,aq,ak,ar,au,ai,aj);if(aw!==undefined){an.tile_cache.set(ax,aw);an.show_tile(aw,ah,ai)}return aw}var ag=$.Deferred();$.when(at,aj).then(function(){view.request_redraw(false,false,false,an);ag.resolve()});return ag},get_canvas_height:function(ac,ae,af,ad){return this.visible_height_px},draw_tile:function(ac,ae,ah,ag,ad,ai,af){console.log("Warning: TiledTrack.draw_tile() not implemented.")},show_tile:function(ae,ag,ah){var ad=this,ac=ae.html_elt;ae.predisplay_actions();var af=(ae.low-(this.is_overview?this.view.max_low:this.view.low))*ah;if(this.left_offset){af-=this.left_offset}ac.css({position:"absolute",top:0,left:af,height:""});if(ac.hasClass("remove")){ac.removeClass("remove")}else{ag.append(ac)}ad.after_show_tile(ae)},after_show_tile:function(ac){},_get_tile_bounds:function(ac,ad){var af=Math.floor(ac*R*ad),ag=Math.ceil(R*ad),ae=(af+ag<=this.view.max_high?af+ag:this.view.max_high);return[af,ae]},tool_region_and_parameters_str:function(ae,ac,af){var ad=this,ag=(ae!==undefined&&ac!==undefined&&af!==undefined?ae+":"+ac+"-"+af:"all");return" - region=["+ag+"], parameters=["+ad.tool.get_param_values().join(", ")+"]"},data_and_mode_compatible:function(ac,ad){return true},can_subset:function(ac){return false},init_for_tool_data:function(){this.data_url=raw_data_url;this.data_query_wait=1000;this.dataset_check_url=dataset_state_url;this.normal_postdraw_actions=this.postdraw_actions;this.postdraw_actions=function(ae,af,ag,ac){var ad=this;ad.normal_postdraw_actions(ae,af,ag,ac);ad.dataset_state_url=converted_datasets_state_url;ad.data_query_wait=I;$.when(server_state_deferred(ad.dataset_state_url,{dataset_id:ad.dataset_id,hda_ldda:ad.hda_ldda},ad.data_query_wait,function(ah){return ah!=="pending"})).then(function(){ad.data_url=default_data_url});ad.postdraw_actions=ad.normal_postdraw_actions}}});var Y=function(ad,ac){var ae={resize:false};i.call(this,ad,ac,ae);this.container_div.addClass("label-track")};p(Y.prototype,i.prototype,{build_header_div:function(){},init:function(){this.enabled=true},_draw:function(){var ae=this.view,af=ae.high-ae.low,ai=Math.floor(Math.pow(10,Math.floor(Math.log(af)/Math.log(10)))),ac=Math.floor(ae.low/ai)*ai,ag=this.view.container.width(),ad=$("<div style='position: relative; height: 1.3em;'></div>");while(ac<ae.high){var ah=(ac-ae.low)/af*ag;ad.append($("<div class='label'>"+commatize(ac)+"</div>").css({position:"absolute",left:ah-1}));ac+=ai}this.content_div.children(":first").remove();this.content_div.append(ad)}});var h=function(ad,ac,ag){K.call(this,ad,ac,ag);this.drawables=[];this.left_offset=0;if("drawables" in ag){var af;for(var ae=0;ae<ag.drawables.length;ae++){af=ag.drawables[ae];this.drawables[ae]=object_from_template(af);if(af.left_offset>this.left_offset){this.left_offset=af.left_offset}}this.enabled=true}if(this.drawables.length!==0){this.set_display_modes(this.drawables[0].display_modes,this.drawables[0].mode)}this.update_icons();this.obj_type="CompositeTrack"};p(h.prototype,K.prototype,{action_icons_def:[{name:"composite_icon",title:"Show individual tracks",css_class:"layers-stack",on_click_fn:function(ac){$(".tipsy").remove();ac.show_group()}}].concat(K.prototype.action_icons_def),to_dict:w.prototype.to_dict,add_drawable:w.prototype.add_drawable,unpack_drawables:w.prototype.unpack_drawables,change_mode:function(ac){K.prototype.change_mode.call(this,ac);for(var ad=0;ad<this.drawables.length;ad++){this.drawables[ad].change_mode(ac)}},init:function(){var ae=[];for(var ad=0;ad<this.drawables.length;ad++){ae.push(this.drawables[ad].init())}var ac=this;$.when.apply($,ae).then(function(){ac.enabled=true;ac.request_draw()})},update_icons:function(){this.action_icons.filters_icon.hide();this.action_icons.tools_icon.hide()},can_draw:q.prototype.can_draw,draw_helper:function(ad,ar,ay,av,aj,al,at){var aq=this,aC=this._gen_tile_cache_key(ar,al,ay),ah=this._get_tile_bounds(ay,av),az=ah[0],ae=ah[1];if(!at){at={}}var aB=(ad?undefined:aq.tile_cache.get(aC));if(aB){aq.show_tile(aB,aj,al);return aB}var ak=[],aq,ao=true,aw,am;for(var ax=0;ax<this.drawables.length;ax++){aq=this.drawables[ax];aw=aq.data_manager.get_data(az,ae,aq.mode,av,aq.data_url_extra_params);if(is_deferred(aw)){ao=false}ak.push(aw);am=null;if(view.reference_track&&al>view.canvas_manager.char_width_px){am=view.reference_track.data_manager.get_data(az,ae,aq.mode,av,view.reference_track.data_url_extra_params);if(is_deferred(am)){ao=false}}ak.push(am)}if(ao){p(aw,at.more_tile_data);this.tile_predraw_init();var ag=aq.view.canvas_manager.new_canvas(),ah=aq._get_tile_bounds(ay,av),az=ah[0],ae=ah[1],aA=0,ar=Math.ceil((ae-az)*al)+this.left_offset,ap=0,af=[];var ac=0;for(var ax=0;ax<this.drawables.length;ax++,aA+=2){aq=this.drawables[ax];aw=ak[aA];var an=aq.mode;if(an==="Auto"){an=aq.get_mode(aw);aq.update_auto_mode(an)}af.push(an);ac=aq.get_canvas_height(aw,an,al,ar);if(ac>ap){ap=ac}}ag.width=ar;ag.height=(at.height?at.height:ap);aA=0;var au=ag.getContext("2d");au.translate(this.left_offset,0);au.globalAlpha=0.5;au.globalCompositeOperation="source-over";for(var ax=0;ax<this.drawables.length;ax++,aA+=2){aq=this.drawables[ax];aw=ak[aA];am=ak[aA+1];aB=aq.draw_tile(aw,au,af[ax],av,ay,al,am)}this.tile_cache.set(aC,aB);this.show_tile(aB,aj,al);return aB}var ai=$.Deferred(),aq=this;$.when.apply($,ak).then(function(){view.request_redraw(false,false,false,aq);ai.resolve()});return ai},show_group:function(){var af=new N(this.view,this.container,{name:this.name}),ac;for(var ae=0;ae<this.drawables.length;ae++){ac=this.drawables[ae];af.add_drawable(ac);ac.container=af;af.content_div.append(ac.container_div)}var ad=this.container.replace_drawable(this,af,true);af.request_draw()},tile_predraw_init:function(){var af=Number.MAX_VALUE,ac=-af,ad;for(var ae=0;ae<this.drawables.length;ae++){ad=this.drawables[ae];if(ad instanceof j){if(ad.prefs.min_value<af){af=ad.prefs.min_value}if(ad.prefs.max_value>ac){ac=ad.prefs.max_value}}}for(var ae=0;ae<this.drawables.length;ae++){ad=this.drawables[ae];ad.prefs.min_value=af;ad.prefs.max_value=ac}},postdraw_actions:function(ae,ah,aj,ad){K.prototype.postdraw_actions.call(this,ae,ah,aj,ad);var ag=-1;for(var af=0;af<ae.length;af++){var ac=ae[af].html_elt.find("canvas").height();if(ac>ag){ag=ac}}for(var af=0;af<ae.length;af++){var ai=ae[af];if(ai.html_elt.find("canvas").height()!==ag){this.draw_helper(true,ah,ai.index,ai.resolution,ai.html_elt.parent(),aj,{height:ag});ai.html_elt.remove()}}}});var y=function(ac){K.call(this,ac,{content_div:ac.top_labeltrack,resize:false},{});ac.reference_track=this;this.left_offset=200;this.visible_height_px=12;this.container_div.addClass("reference-track");this.content_div.css("background","none");this.content_div.css("min-height","0px");this.content_div.css("border","none");this.data_url=reference_url;this.data_url_extra_params={dbkey:ac.dbkey};this.data_manager=new E(F,this,false);this.hide_contents()};p(y.prototype,q.prototype,K.prototype,{build_header_div:function(){},init:function(){this.data_manager.clear();this.enabled=true},can_draw:q.prototype.can_draw,draw_tile:function(ak,al,ah,ag,ad,am){var af=this;if(am>this.view.canvas_manager.char_width_px){if(ak.data===null){this.hide_contents();return}var ae=al.canvas;al.font=al.canvas.manager.default_font;al.textAlign="center";ak=ak.data;for(var ai=0,aj=ak.length;ai<aj;ai++){var ac=Math.floor(ai*am);al.fillText(ak[ai],ac,10)}this.show_contents();return new b(af,ad,ag,ae,ak)}this.hide_contents()}});var j=function(ae,ad,af){var ac=this;this.display_modes=["Histogram","Line","Filled","Intensity"];this.mode="Histogram";K.call(this,ae,ad,af);this.hda_ldda=af.hda_ldda;this.dataset_id=af.dataset_id;this.original_dataset_id=this.dataset_id;this.left_offset=0;this.config=new C({track:this,params:[{key:"name",label:"Name",type:"text",default_value:this.name},{key:"color",label:"Color",type:"color",default_value:get_random_color()},{key:"min_value",label:"Min Value",type:"float",default_value:undefined},{key:"max_value",label:"Max Value",type:"float",default_value:undefined},{key:"mode",type:"string",default_value:this.mode,hidden:true},{key:"height",type:"int",default_value:32,hidden:true}],saved_values:af.prefs,onchange:function(){ac.set_name(ac.prefs.name);ac.vertical_range=ac.prefs.max_value-ac.prefs.min_value;ac.set_min_value(ac.prefs.min_value);ac.set_max_value(ac.prefs.max_value)}});this.prefs=this.config.values;this.visible_height_px=this.config.values.height;this.vertical_range=this.config.values.max_value-this.config.values.min_value};p(j.prototype,q.prototype,K.prototype,{on_resize:function(){this.request_draw(true)},set_min_value:function(ac){this.prefs.min_value=ac;$("#linetrack_"+this.dataset_id+"_minval").text(this.prefs.min_value);this.tile_cache.clear();this.request_draw()},set_max_value:function(ac){this.prefs.max_value=ac;$("#linetrack_"+this.dataset_id+"_maxval").text(this.prefs.max_value);this.tile_cache.clear();this.request_draw()},predraw_init:function(){var ac=this;ac.vertical_range=undefined;return $.getJSON(ac.data_url,{stats:true,chrom:ac.view.chrom,low:null,high:null,hda_ldda:ac.hda_ldda,dataset_id:ac.dataset_id},function(ad){ac.container_div.addClass("line-track");var ag=ad.data;if(isNaN(parseFloat(ac.prefs.min_value))||isNaN(parseFloat(ac.prefs.max_value))){var ae=ag.min;var ai=ag.max;ae=Math.floor(Math.min(0,Math.max(ae,ag.mean-2*ag.sd)));ai=Math.ceil(Math.max(0,Math.min(ai,ag.mean+2*ag.sd)));ac.prefs.min_value=ae;ac.prefs.max_value=ai;$("#track_"+ac.dataset_id+"_minval").val(ac.prefs.min_value);$("#track_"+ac.dataset_id+"_maxval").val(ac.prefs.max_value)}ac.vertical_range=ac.prefs.max_value-ac.prefs.min_value;ac.total_frequency=ag.total_frequency;ac.container_div.find(".yaxislabel").remove();var ah=$("<div/>").text(W(ac.prefs.min_value,3)).make_text_editable({num_cols:6,on_finish:function(aj){$(".tipsy").remove();var aj=parseFloat(aj);if(!isNaN(aj)){ac.set_min_value(aj)}},help_text:"Set min value"}).addClass("yaxislabel bottom").attr("id","linetrack_"+ac.dataset_id+"_minval").prependTo(ac.container_div),af=$("<div/>").text(W(ac.prefs.max_value,3)).make_text_editable({num_cols:6,on_finish:function(aj){$(".tipsy").remove();var aj=parseFloat(aj);if(!isNaN(aj)){ac.set_max_value(aj)}},help_text:"Set max value"}).addClass("yaxislabel top").attr("id","linetrack_"+ac.dataset_id+"_maxval").prependTo(ac.container_div)})},draw_tile:function(am,ak,ah,af,ad,al){var ae=ak.canvas,ac=this._get_tile_bounds(ad,af),ag=ac[0],aj=ac[1],ai=new J.LinePainter(am.data,ag,aj,this.prefs,ah);ai.draw(ak,ae.width,ae.height,al);return new b(this,ad,af,ae,am.data)},can_subset:function(ac){return false},});var d=function(af,ae,ah){var ad=this;this.display_modes=["Auto","Histogram","Dense","Squish","Pack"];K.call(this,af,ae,ah);var ag=get_random_color(),ac=get_random_color([ag,"#ffffff"]);this.config=new C({track:this,params:[{key:"name",label:"Name",type:"text",default_value:this.name},{key:"block_color",label:"Block color",type:"color",default_value:ag},{key:"reverse_strand_color",label:"Antisense strand color",type:"color",default_value:ac},{key:"label_color",label:"Label color",type:"color",default_value:"black"},{key:"show_counts",label:"Show summary counts",type:"bool",default_value:true,help:"Show the number of items in each bin when drawing summary histogram"},{key:"histogram_max",label:"Histogram maximum",type:"float",default_value:null,help:"clear value to set automatically"},{key:"connector_style",label:"Connector style",type:"select",default_value:"fishbones",options:[{label:"Line with arrows",value:"fishbone"},{label:"Arcs",value:"arcs"}]},{key:"mode",type:"string",default_value:this.mode,hidden:true},{key:"height",type:"int",default_value:this.visible_height_px,hidden:true}],saved_values:ah.prefs,onchange:function(){ad.set_name(ad.prefs.name);ad.tile_cache.clear();ad.set_painter_from_config();ad.request_draw()}});this.prefs=this.config.values;this.visible_height_px=this.config.values.height;this.container_div.addClass("feature-track");this.hda_ldda=ah.hda_ldda;this.dataset_id=ah.dataset_id;this.original_dataset_id=ah.dataset_id;this.show_labels_scale=0.001;this.showing_details=false;this.summary_draw_height=30;this.slotters={};this.start_end_dct={};this.left_offset=200;this.set_painter_from_config()};p(d.prototype,q.prototype,K.prototype,{set_painter_from_config:function(){if(this.config.values.connector_style==="arcs"){this.painter=J.ArcLinkedFeaturePainter}else{this.painter=J.LinkedFeaturePainter}},before_draw:function(){this.max_height_px=0},after_show_tile:function(ac){this.max_height_px=Math.max(this.max_height_px,ac.html_elt.height());ac.html_elt.parent().children().css("height",this.max_height_px+"px");var ad=this.max_height_px;if(this.visible_height_px!==0){ad=Math.min(this.max_height_px,this.visible_height_px)}this.tiles_div.css("height",ad+"px")},postdraw_actions:function(ar,am,ah,ag){K.prototype.postdraw_actions.call(this,ar,ag);var al=this;if(al.mode==="Histogram"){var ad=-1;for(var ao=0;ao<ar.length;ao++){var an=ar[ao].max_val;if(an>ad){ad=an}}for(var ao=0;ao<ar.length;ao++){var au=ar[ao];if(au.max_val!==ad){au.html_elt.remove();al.draw_helper(true,am,au.index,au.resolution,au.html_elt.parent(),ah,{more_tile_data:{max:ad}})}}}if(al.filters_manager){var ai=al.filters_manager.filters;for(var aq=0;aq<ai.length;aq++){ai[aq].update_ui_elt()}var at=false,ac,aj;for(var ao=0;ao<ar.length;ao++){if(ar[ao].data.length){ac=ar[ao].data[0];for(var aq=0;aq<ai.length;aq++){aj=ai[aq];if(aj.applies_to(ac)&&aj.min!==aj.max){at=true;break}}}}if(al.filters_available!==at){al.filters_available=at;if(!al.filters_available){al.filters_manager.hide()}al.update_icons()}}this.container_div.find(".yaxislabel").remove();var af=ar[0];if(af instanceof k){var ak=(this.prefs.histogram_max?this.prefs.histogram_max:af.max_val),ae=$("<div/>").text(ak).make_text_editable({num_cols:12,on_finish:function(av){$(".tipsy").remove();var av=parseFloat(av);al.prefs.histogram_max=(!isNaN(av)?av:null);al.tile_cache.clear();al.request_draw()},help_text:"Set max value; leave blank to use default"}).addClass("yaxislabel top").css("color",this.prefs.label_color);this.container_div.prepend(ae)}if(af instanceof M){var ap=true;for(var ao=0;ao<ar.length;ao++){if(!ar[ao].all_slotted){ap=false;break}}if(!ap){this.action_icons.show_more_rows_icon.show()}else{this.action_icons.show_more_rows_icon.hide()}}else{this.action_icons.show_more_rows_icon.hide()}},update_auto_mode:function(ac){var ac;if(this.mode==="Auto"){if(ac==="no_detail"){ac="feature spans"}else{if(ac==="summary_tree"){ac="coverage histogram"}}this.action_icons.mode_icon.attr("title","Set display mode (now: Auto/"+ac+")")}},incremental_slots:function(ag,ac,af){var ad=this.view.canvas_manager.dummy_context,ae=this.slotters[ag];if(!ae||(ae.mode!==af)){ae=new (s.FeatureSlotter)(ag,af,x,function(ah){return ad.measureText(ah)});this.slotters[ag]=ae}return ae.slot_features(ac)},get_summary_tree_data:function(ag,aj,ae,ar){if(ar>ae-aj){ar=ae-aj}var an=Math.floor((ae-aj)/ar),aq=[],af=0;var ah=0,ai=0,am,ap=0,ak=[],ao,al;var ad=function(av,au,aw,at){av[0]=au+aw*at;av[1]=au+(aw+1)*at};while(ap<ar&&ah!==ag.length){var ac=false;for(;ap<ar&&!ac;ap++){ad(ak,aj,ap,an);for(ai=ah;ai<ag.length;ai++){am=ag[ai].slice(1,3);if(is_overlap(am,ak)){ac=true;break}}if(ac){break}}data_start_index=ai;aq[aq.length]=ao=[ak[0],0];for(;ai<ag.length;ai++){am=ag[ai].slice(1,3);if(is_overlap(am,ak)){ao[1]++}else{break}}if(ao[1]>af){af=ao[1]}ap++}return{max:af,delta:an,data:aq}},get_mode:function(ac){if(ac.dataset_type==="summary_tree"){mode="summary_tree"}else{if(ac.extra_info==="no_detail"||this.is_overview){mode="no_detail"}else{if(this.view.high-this.view.low>G){mode="Squish"}else{mode="Pack"}}}return mode},get_canvas_height:function(ac,ag,ah,ad){if(ag==="summary_tree"||ag==="Histogram"){return this.summary_draw_height}else{var af=this.incremental_slots(ah,ac.data,ag);var ae=new (this.painter)(null,null,null,this.prefs,ag);return Math.max(aa,ae.get_required_height(af,ad))}},draw_tile:function(an,ar,ap,at,ax,aj,ae){var aq=this,ad=ar.canvas,ag=this._get_tile_bounds(ax,at),aA=ag[0],ac=ag[1],aF=25,af=this.left_offset;if(ap==="summary_tree"||ap==="Histogram"){if(an.dataset_type!=="summary_tree"){var ak=this.get_summary_tree_data(an.data,aA,ac,200);if(an.max){ak.max=an.max}an=ak}var aC=new J.SummaryTreePainter(an,aA,ac,this.prefs);aC.draw(ar,ad.width,ad.height,aj);return new k(aq,ax,at,ad,an.data,an.max)}var ai=[],ao=this.slotters[aj].slots;all_slotted=true;if(an.data){var al=this.filters_manager.filters;for(var au=0,aw=an.data.length;au<aw;au++){var ah=an.data[au];var av=false;var am;for(var az=0,aE=al.length;az<aE;az++){am=al[az];am.update_attrs(ah);if(!am.keep(ah)){av=true;break}}if(!av){ai.push(ah);if(!(ah[0] in ao)){all_slotted=false}}}}var aD=(this.filters_manager.alpha_filter?new z(this.filters_manager.alpha_filter):null);var aB=(this.filters_manager.height_filter?new z(this.filters_manager.height_filter):null);var aC=new (this.painter)(ai,aA,ac,this.prefs,ap,aD,aB,ae);var ay=null;ar.fillStyle=this.prefs.block_color;ar.font=ar.canvas.manager.default_font;ar.textAlign="right";if(an.data){ay=aC.draw(ar,ad.width,ad.height,aj,ao);ay.translation=-af}return new M(aq,ax,at,ad,an.data,aj,ap,an.message,all_slotted,ay)},data_and_mode_compatible:function(ac,ad){if(ad==="Auto"){return true}else{if(ac.extra_info==="no_detail"||ac.dataset_type==="summary_tree"){return false}else{return true}}},can_subset:function(ac){if(ac.dataset_type==="summary_tree"||ac.message||ac.extra_info==="no_detail"){return false}return true},});var Q=function(ad,ac,ae){d.call(this,ad,ac,ae);this.config=new C({track:this,params:[{key:"name",label:"Name",type:"text",default_value:this.name},{key:"block_color",label:"Block color",type:"color",default_value:get_random_color()},{key:"label_color",label:"Label color",type:"color",default_value:"black"},{key:"show_insertions",label:"Show insertions",type:"bool",default_value:false},{key:"show_counts",label:"Show summary counts",type:"bool",default_value:true},{key:"mode",type:"string",default_value:this.mode,hidden:true},],saved_values:ae.prefs,onchange:function(){this.track.set_name(this.track.prefs.name);this.track.tile_cache.clear();this.track.request_draw()}});this.prefs=this.config.values;this.painter=J.ReadPainter};p(Q.prototype,q.prototype,K.prototype,d.prototype);var T=function(ae,ad,ag){d.call(this,ae,ad,ag);var af=get_random_color(),ac=get_random_color([af,"#ffffff"]);this.config=new C({track:this,params:[{key:"name",label:"Name",type:"text",default_value:this.name},{key:"block_color",label:"Block and sense strand color",type:"color",default_value:af},{key:"reverse_strand_color",label:"Antisense strand color",type:"color",default_value:ac},{key:"label_color",label:"Label color",type:"color",default_value:"black"},{key:"show_insertions",label:"Show insertions",type:"bool",default_value:false},{key:"show_differences",label:"Show differences only",type:"bool",default_value:true},{key:"show_counts",label:"Show summary counts",type:"bool",default_value:true},{key:"histogram_max",label:"Histogram maximum",type:"float",default_value:null,help:"Clear value to set automatically"},{key:"mode",type:"string",default_value:this.mode,hidden:true},],saved_values:ag.prefs,onchange:function(){this.track.set_name(this.track.prefs.name);this.track.tile_cache.clear();this.track.request_draw()}});this.prefs=this.config.values;this.painter=J.ReadPainter;this.update_icons()};p(T.prototype,q.prototype,K.prototype,d.prototype);U.View=Z;U.DrawableGroup=N;U.LineTrack=j;U.FeatureTrack=d;U.ReadTrack=T;U.VcfTrack=Q;U.CompositeTrack=h};var slotting_module=function(c,b){var e=c("class").extend;var d=2,a=5;b.FeatureSlotter=function(i,h,f,g){this.slots={};this.start_end_dct={};this.w_scale=i;this.mode=h;this.include_label=(h==="Pack");this.max_rows=f;this.measureText=g};e(b.FeatureSlotter.prototype,{slot_features:function(m){var p=this.w_scale,h=this.start_end_dct,x=[],z=[],n=0,y=this.max_rows;for(var v=0,w=m.length;v<w;v++){var k=m[v],o=k[0];if(this.slots[o]!==undefined){n=Math.max(n,this.slots[o]);z.push(this.slots[o])}else{x.push(v)}}var q=function(E,F){for(var D=0;D<=y;D++){var B=false,G=h[D];if(G!==undefined){for(var A=0,C=G.length;A<C;A++){var i=G[A];if(F>i[0]&&E<i[1]){B=true;break}}}if(!B){return D}}return -1};for(var v=0,w=x.length;v<w;v++){var k=m[x[v]],o=k[0],t=k[1],f=k[2],r=k[3],g=Math.floor(t*p),l=Math.ceil(f*p),u=this.measureText(r).width,j;if(r!==undefined&&this.include_label){u+=(d+a);if(g-u>=0){g-=u;j="left"}else{l+=u;j="right"}}var s=q(g,l);if(s>=0){if(h[s]===undefined){h[s]=[]}h[s].push([g,l]);this.slots[o]=s;n=Math.max(n,s)}}return n+1}})};var painters_module=function(i,x){var u=i("class").extend;var p=function(I,A,G,z,F,D){if(D===undefined){D=4}var C=z-A;var B=F-G;var E=Math.floor(Math.sqrt(C*C+B*B)/D);var J=C/E;var H=B/E;var y;for(y=0;y<E;y++,A+=J,G+=H){if(y%2!==0){continue}I.fillRect(A,G,D,1)}};var q=function(B,A,z,E){var D=A-E/2,C=A+E/2,F=z-Math.sqrt(E*3/2);B.beginPath();B.moveTo(D,F);B.lineTo(C,F);B.lineTo(A,z);B.lineTo(D,F);B.strokeStyle=this.fillStyle;B.fill();B.stroke();B.closePath()};var d=function(y){this.default_val=(y?y:1)};d.prototype.gen_val=function(y){return this.default_val};var l=function(A,C,y,z,B){this.data=A;this.view_start=C;this.view_end=y;this.prefs=u({},this.default_prefs,z);this.mode=B};l.prototype.default_prefs={};l.prototype.draw=function(z,A,y,B){};var v=function(A,C,y,z,B){l.call(this,A,C,y,z,B)};v.prototype.default_prefs={show_counts:false};v.prototype.draw=function(L,z,K,M){var E=this.view_start,N=this.view_end-this.view_start,I=this.data.data,G=(this.prefs.histogram_max?this.prefs.histogram_max:this.data.max),B=K;delta_x_px=Math.ceil(this.data.delta*M);L.save();for(var C=0,D=I.length;C<D;C++){var H=Math.floor((I[C][0]-E)*M);var F=I[C][1];if(!F){continue}var J=F/G*K;if(F!==0&&J<1){J=1}L.fillStyle=this.prefs.block_color;L.fillRect(H,B-J,delta_x_px,J);var A=4;if(this.prefs.show_counts&&(L.measureText(F).width+A)<delta_x_px){L.fillStyle=this.prefs.label_color;L.textAlign="center";L.fillText(F,H+(delta_x_px/2),10)}}L.restore()};var b=function(y,C,E,F,A){l.call(this,y,C,E,F,A);if(this.prefs.min_value===undefined){var G=Infinity;for(var z=0,B=this.data.length;z<B;z++){G=Math.min(G,this.data[z][1])}this.prefs.min_value=G}if(this.prefs.max_value===undefined){var D=-Infinity;for(var z=0,B=this.data.length;z<B;z++){D=Math.max(D,this.data[z][1])}this.prefs.max_value=D}};b.prototype.default_prefs={min_value:undefined,max_value:undefined,mode:"Histogram",color:"#000",overflow_color:"#F66"};b.prototype.draw=function(S,Q,N,D){var I=false,K=this.prefs.min_value,F=this.prefs.max_value,M=F-K,B=N,C=this.view_start,P=this.view_end-this.view_start,L=this.mode,aa=this.data;S.save();var ac=Math.round(N+K/M*N);if(L!=="Intensity"){S.fillStyle="#aaa";S.fillRect(0,ac,Q,1)}S.beginPath();var Y,G,E;if(aa.length>1){E=Math.ceil((aa[1][0]-aa[0][0])*D)}else{E=10}var A=parseInt(this.prefs.color.slice(1),16),H=(A&16711680)>>16,R=(A&65280)>>8,V=A&255;for(var T=0,U=aa.length;T<U;T++){S.fillStyle=S.strokeStyle=this.prefs.color;Y=Math.round((aa[T][0]-C)*D);G=aa[T][1];var W=false,J=false;if(G===null){if(I&&L==="Filled"){S.lineTo(Y,B)}I=false;continue}if(G<K){J=true;G=K}else{if(G>F){W=true;G=F}}if(L==="Histogram"){G=Math.round(G/M*B);S.fillRect(Y,ac,E,-G)}else{if(L==="Intensity"){var z=(G-K)/M,O=Math.round(H+(255-H)*(1-z)),X=Math.round(R+(255-R)*(1-z)),ab=Math.round(V+(255-V)*(1-z));S.fillStyle="rgb("+O+","+X+","+ab+")";S.fillRect(Y,0,E,B)}else{G=Math.round(B-(G-K)/M*B);if(I){S.lineTo(Y,G)}else{I=true;if(L==="Filled"){S.moveTo(Y,B);S.lineTo(Y,G)}else{S.moveTo(Y,G)}}}}S.fillStyle=this.prefs.overflow_color;if(W||J){var Z;if(L==="Histogram"||L==="Intensity"){Z=E}else{Y-=2;Z=4}if(W){S.fillRect(Y,0,Z,3)}if(J){S.fillRect(Y,B-3,Z,3)}}S.fillStyle=this.prefs.color}if(L==="Filled"){if(I){S.lineTo(Y,ac);S.lineTo(0,ac)}S.fill()}else{S.stroke()}S.restore()};var m=function(y){this.feature_positions={};this.slot_height=y;this.translation=0;this.y_translation=0};m.prototype.map_feature_data=function(z,B,y,A){if(!this.feature_positions[B]){this.feature_positions[B]=[]}this.feature_positions[B].push({data:z,x_start:y,x_end:A})};m.prototype.get_feature_data=function(z,D){var C=Math.floor((D-this.y_translation)/this.slot_height),B;if(!this.feature_positions[C]){return null}z+=this.translation;for(var A=0;A<this.feature_positions[C].length;A++){B=this.feature_positions[C][A];if(z>=B.x_start&&z<=B.x_end){return B.data}}};var o=function(A,D,y,z,C,E,B){l.call(this,A,D,y,z,C);this.alpha_scaler=(E?E:new d());this.height_scaler=(B?B:new d())};o.prototype.default_prefs={block_color:"#FFF",connector_color:"#FFF"};u(o.prototype,{get_required_height:function(A,z){var y=y_scale=this.get_row_height(),B=this.mode;if(B==="no_detail"||B==="Squish"||B==="Pack"){y=A*y_scale}return y+this.get_top_padding(z)+this.get_bottom_padding(z)},get_top_padding:function(y){return 0},get_bottom_padding:function(y){return Math.max(Math.round(this.get_row_height()/2),5)},draw:function(K,I,G,E,F){var Q=this.data,D=this.view_start,M=this.view_end;K.save();K.fillStyle=this.prefs.block_color;K.textAlign="right";var H=this.view_end-this.view_start,L=this.get_row_height(),P=new m(L),B;for(var N=0,O=Q.length;N<O;N++){var A=Q[N],C=A[0],J=A[1],y=A[2],z=(F&&F[C]!==undefined?F[C]:null);if((J<M&&y>D)&&(this.mode==="Dense"||z!==null)){B=this.draw_element(K,this.mode,A,z,D,M,E,L,I);P.map_feature_data(A,z,B[0],B[1])}}K.restore();P.y_translation=this.get_top_padding(I);return P},draw_element:function(E,A,G,C,B,D,F,z,y){console.log("WARNING: Unimplemented function.");return[0,0]}});var c=10,h=3,k=5,w=10,f=1,s=9,e=3,a=9,j=2,g="#ccc";var r=function(A,D,y,z,C,E,B){o.call(this,A,D,y,z,C,E,B);this.draw_background_connector=true;this.draw_individual_connectors=false};u(r.prototype,o.prototype,{get_row_height:function(){var z=this.mode,y;if(z==="Dense"){y=c}else{if(z==="no_detail"){y=h}else{if(z==="Squish"){y=k}else{y=w}}}return y},draw_element:function(M,D,X,H,O,ai,am,ao,y){var T=X[0],ak=X[1],ad=X[2]-1,Q=X[3],K=X[4],ae=Math.floor(Math.max(0,(ak-O)*am)),N=Math.ceil(Math.min(y,Math.max(0,(ad-O)*am))),ac=ae,an=N,aa=(D==="Dense"?0:(0+H))*ao+this.get_top_padding(y),L,ag,R=null,aq=null,B=B=(!K||K==="+"?this.prefs.block_color:this.prefs.reverse_strand_color);label_color=this.prefs.label_color;M.globalAlpha=this.alpha_scaler.gen_val(X);if(D==="Dense"){H=1}if(D==="no_detail"){M.fillStyle=B;M.fillRect(ae,aa+5,N-ae,f)}else{var Z=X[5],af=X[6],C=X[7],V=true;if(Z&&af){R=Math.floor(Math.max(0,(Z-O)*am));aq=Math.ceil(Math.min(y,Math.max(0,(af-O)*am)))}var al,U;if(D==="Squish"){al=1;U=e;V=false}else{if(D==="Dense"){al=5;U=s}else{al=5;U=a}}if(!C){M.fillStyle=B;M.fillRect(ae,aa+1,N-ae,U);if(K&&V){if(K==="+"){M.fillStyle=M.canvas.manager.get_pattern("right_strand_inv")}else{if(K==="-"){M.fillStyle=M.canvas.manager.get_pattern("left_strand_inv")}}M.fillRect(ae,aa+1,N-ae,U)}}else{var J,W;if(D==="Squish"||D==="Dense"){J=aa+Math.floor(e/2)+1;W=1}else{if(K){J=aa;W=U}else{J+=(e/2)+1;W=1}}if(this.draw_background_connector){if(D==="Squish"||D==="Dense"){M.fillStyle=g}else{if(K){if(K==="+"){M.fillStyle=M.canvas.manager.get_pattern("right_strand")}else{if(K==="-"){M.fillStyle=M.canvas.manager.get_pattern("left_strand")}}}else{M.fillStyle=g}}M.fillRect(ae,J,N-ae,W)}var E;for(var aj=0,A=C.length;aj<A;aj++){var F=C[aj],z=Math.floor(Math.max(0,(F[0]-O)*am)),Y=Math.ceil(Math.min(y,Math.max((F[1]-1-O)*am))),S,ab;if(z>Y){continue}M.fillStyle=B;M.fillRect(z,aa+(U-al)/2+1,Y-z,al);if(R!==undefined&&af>Z&&!(z>aq||Y<R)){var ah=Math.max(z,R),I=Math.min(Y,aq);M.fillRect(ah,aa+1,I-ah,U);if(C.length===1&&D==="Pack"){if(K==="+"){M.fillStyle=M.canvas.manager.get_pattern("right_strand_inv")}else{if(K==="-"){M.fillStyle=M.canvas.manager.get_pattern("left_strand_inv")}}if(ah+14<I){ah+=2;I-=2}M.fillRect(ah,aa+1,I-ah,U)}}if(this.draw_individual_connectors&&S){this.draw_connector(M,S,ab,z,Y,aa)}S=z;ab=Y}if(D==="Pack"){M.globalAlpha=1;M.fillStyle="white";var G=this.height_scaler.gen_val(X),P=Math.ceil(U*G),ap=Math.round((U-P)/2);if(G!==1){M.fillRect(ae,J+1,N-ae,ap);M.fillRect(ae,J+U-ap+1,N-ae,ap)}}}M.globalAlpha=1;if(D==="Pack"&&ak>O){M.fillStyle=label_color;if(O===0&&ae-M.measureText(Q).width<0){M.textAlign="left";M.fillText(Q,N+j,aa+8);an+=M.measureText(Q).width+j}else{M.textAlign="right";M.fillText(Q,ae-j,aa+8);ac-=M.measureText(Q).width+j}}}M.globalAlpha=1;return[ac,an]}});var t=function(B,E,y,A,D,F,C,z){o.call(this,B,E,y,A,D,F,C);this.ref_seq=(z?z.data:null)};u(t.prototype,o.prototype,{get_row_height:function(){var y,z=this.mode;if(z==="Dense"){y=c}else{if(z==="Squish"){y=k}else{y=w;if(this.prefs.show_insertions){y*=2}}}return y},draw_read:function(K,A,ag,V,L,aa,ad,C,B,M){K.textAlign="center";var J=this,R=[L,aa],Z=0,W=0,D=0,F=K.canvas.manager.char_width_px,y=(B==="+"?this.prefs.block_color:this.prefs.reverse_strand_color);var O=[];if((A==="Pack"||this.mode==="Auto")&&M!==undefined&&ag>F){D=Math.round(ag/2)}if(!C){C=[[0,M.length]]}for(var G=0,I=C.length;G<I;G++){var z=C[G],E="MIDNSHP=X"[z[0]],S=z[1];if(E==="H"||E==="S"){Z-=S}var U=ad+Z,Y=Math.floor(Math.max(0,(U-L)*ag)),ab=Math.floor(Math.max(0,(U+S-L)*ag));if(Y===ab){ab+=1}switch(E){case"H":break;case"S":case"M":case"=":if(is_overlap([U,U+S],R)){var N=M.slice(W,W+S);if(D>0){K.fillStyle=y;K.fillRect(Y-D,V+1,ab-Y,9);K.fillStyle=g;for(var af=0,H=N.length;af<H;af++){if(this.prefs.show_differences){if(this.ref_seq){var P=this.ref_seq[U-L+af];if(!P||P.toLowerCase()===N[af].toLowerCase()){continue}}else{continue}}if(U+af>=L&&U+af<=aa){var X=Math.floor(Math.max(0,(U+af-L)*ag));K.fillText(N[af],X,V+9)}}}else{K.fillStyle=y;K.fillRect(Y,V+4,ab-Y,e)}}W+=S;Z+=S;break;case"N":K.fillStyle=g;K.fillRect(Y-D,V+5,ab-Y,1);Z+=S;break;case"D":K.fillStyle="red";K.fillRect(Y-D,V+4,ab-Y,3);Z+=S;break;case"P":break;case"I":var ah=Y-D;if(is_overlap([U,U+S],R)){var N=M.slice(W,W+S);if(this.prefs.show_insertions){var T=Y-(ab-Y)/2;if((A==="Pack"||this.mode==="Auto")&&M!==undefined&&ag>F){K.fillStyle="yellow";K.fillRect(T-D,V-9,ab-Y,9);O[O.length]={type:"triangle",data:[ah,V+4,5]};K.fillStyle=g;switch(compute_overlap([U,U+S],R)){case (OVERLAP_START):N=N.slice(L-U);break;case (OVERLAP_END):N=N.slice(0,U-aa);break;case (CONTAINED_BY):break;case (CONTAINS):N=N.slice(L-U,U-aa);break}for(var af=0,H=N.length;af<H;af++){var X=Math.floor(Math.max(0,(U+af-L)*ag));K.fillText(N[af],X-(ab-Y)/2,V)}}else{K.fillStyle="yellow";K.fillRect(T,V+(this.mode!=="Dense"?2:5),ab-Y,(A!=="Dense"?e:s))}}else{if((A==="Pack"||this.mode==="Auto")&&M!==undefined&&ag>F){O.push({type:"text",data:[N.length,ah,V+9]})}else{}}}W+=S;break;case"X":W+=S;break}}K.fillStyle="yellow";var Q,ai,ae;for(var ac=0;ac<O.length;ac++){Q=O[ac];ai=Q.type;ae=Q.data;if(ai==="text"){K.save();K.font="bold "+K.font;K.fillText(ae[0],ae[1],ae[2]);K.restore()}else{if(ai==="triangle"){q(K,ae[0],ae[1],ae[2])}}}},draw_element:function(R,M,E,B,U,z,I,S,P){var H=E[0],Q=E[1],A=E[2],J=E[3],D=Math.floor(Math.max(0,(Q-U)*I)),F=Math.ceil(Math.min(P,Math.max(0,(A-U)*I))),C=(M==="Dense"?0:(0+B))*S,G=this.prefs.label_color,O=0;if((M==="Pack"||this.mode==="Auto")&&I>R.canvas.manager.char_width_px){var O=Math.round(I/2)}if(E[5] instanceof Array){var N=Math.floor(Math.max(0,(E[4][0]-U)*I)),L=Math.ceil(Math.min(P,Math.max(0,(E[4][1]-U)*I))),K=Math.floor(Math.max(0,(E[5][0]-U)*I)),y=Math.ceil(Math.min(P,Math.max(0,(E[5][1]-U)*I)));if(E[4][1]>=U&&E[4][0]<=z&&E[4][2]){this.draw_read(R,M,I,C,U,z,E[4][0],E[4][2],E[4][3],E[4][4])}if(E[5][1]>=U&&E[5][0]<=z&&E[5][2]){this.draw_read(R,M,I,C,U,z,E[5][0],E[5][2],E[5][3],E[5][4])}if(K>L){R.fillStyle=g;p(R,L-O,C+5,K-O,C+5)}}else{this.draw_read(R,M,I,C,U,z,Q,E[4],E[5],E[6])}if(M==="Pack"&&Q>U&&J!=="."){R.fillStyle=this.prefs.label_color;var T=1;if(T===0&&D-R.measureText(J).width<0){R.textAlign="left";R.fillText(J,F+j-O,C+8)}else{R.textAlign="right";R.fillText(J,D-j-O,C+8)}}return[0,0]}});var n=function(A,D,y,z,C,E,B){r.call(this,A,D,y,z,C,E,B);this.longest_feature_length=this.calculate_longest_feature_length();this.draw_background_connector=false;this.draw_individual_connectors=true};u(n.prototype,o.prototype,r.prototype,{calculate_longest_feature_length:function(){var z=0;for(var C=0,y=this.data.length;C<y;C++){var B=this.data[C],A=B[1],D=B[2];z=Math.max(z,D-A)}return z},get_top_padding:function(z){var y=this.view_end-this.view_start,A=z/y;return Math.min(128,Math.ceil((this.longest_feature_length/2)*A))},draw_connector:function(G,B,F,H,E,D){var y=(F+H)/2,C=H-y;var A=Math.PI,z=0;if(C>0){G.beginPath();G.arc(y,D,H-y,Math.PI,0);G.stroke()}}});x.Scaler=d;x.SummaryTreePainter=v;x.LinePainter=b;x.LinkedFeaturePainter=r;x.ReadPainter=t;x.ArcLinkedFeaturePainter=n};(function(d){var c={};var b=function(e){return c[e]};var a=function(f,g){var e={};g(b,e);c[f]=e};a("class",class_module);a("slotting",slotting_module);a("painters",painters_module);a("trackster",trackster_module);for(key in c.trackster){d[key]=c.trackster[key]}})(window);
\ No newline at end of file
+var class_module=function(b,a){var c=function(){var f=arguments[0];for(var e=1;e<arguments.length;e++){var d=arguments[e];for(key in d){f[key]=d[key]}}return f};a.extend=c};var server_state_deferred=function(d,a,c,f){var b=$.Deferred(),e=function(){$.getJSON(d,a,function(g){if(f(g)){b.resolve(g)}else{setTimeout(e,c)}})};e();return b};var requestAnimationFrame=(function(){return window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.oRequestAnimationFrame||window.msRequestAnimationFrame||function(b,a){window.setTimeout(b,1000/60)}})();var BEFORE=1001,CONTAINS=1002,OVERLAP_START=1003,OVERLAP_END=1004,CONTAINED_BY=1005,AFTER=1006;var compute_overlap=function(e,b){var g=e[0],f=e[1],d=b[0],c=b[1],a;if(g<d){if(f<d){a=BEFORE}else{if(f<=c){a=OVERLAP_START}else{a=CONTAINS}}}else{if(g>c){a=AFTER}else{if(f<=c){a=CONTAINED_BY}else{a=OVERLAP_END}}}return a};var is_overlap=function(c,b){var a=compute_overlap(c,b);return(a!==BEFORE&&a!==AFTER)};var is_deferred=function(a){return("isResolved" in a)};var get_random_color=function(a){if(!a){a="#ffffff"}if(typeof(a)==="string"){a=[a]}for(var j=0;j<a.length;j++){a[j]=parseInt(a[j].slice(1),16)}var n=function(t,s,i){return((t*299)+(s*587)+(i*114))/1000};var e=function(v,u,w,s,i,t){return(Math.max(v,s)-Math.min(v,s))+(Math.max(u,i)-Math.min(u,i))+(Math.max(w,t)-Math.min(w,t))};var g,o,f,k,q,h,r,c,d,b,p,m=false,l=0;do{g=Math.round(Math.random()*16777215);o=(g&16711680)>>16;f=(g&65280)>>8;k=g&255;d=n(o,f,k);m=true;for(var j=0;j<a.length;j++){q=a[j];h=(q&16711680)>>16;r=(q&65280)>>8;c=q&255;b=n(h,r,c);p=e(o,f,k,h,r,c);if((Math.abs(d-b)<40)||(p<200)){m=false;break}}l++}while(!m&&l<=10);return"#"+(16777216+g).toString(16).substr(1,6)};var create_action_icon=function(c,b,a){return $("<a/>").attr("href","javascript:void(0);").attr("title",c).addClass("icon-button").addClass(b).tipsy({gravity:"s"}).click(a)};var trackster_module=function(e,U){var p=e("class").extend,s=e("slotting"),J=e("painters");var ab=function(ac,ad){this.document=ac;this.default_font=ad!==undefined?ad:"9px Monaco, Lucida Console, monospace";this.dummy_canvas=this.new_canvas();this.dummy_context=this.dummy_canvas.getContext("2d");this.dummy_context.font=this.default_font;this.char_width_px=this.dummy_context.measureText("A").width;this.patterns={};this.load_pattern("right_strand","/visualization/strand_right.png");this.load_pattern("left_strand","/visualization/strand_left.png");this.load_pattern("right_strand_inv","/visualization/strand_right_inv.png");this.load_pattern("left_strand_inv","/visualization/strand_left_inv.png")};p(ab.prototype,{load_pattern:function(ac,ag){var ad=this.patterns,ae=this.dummy_context,af=new Image();af.src=galaxy_paths.attributes.image_path+ag;af.onload=function(){ad[ac]=ae.createPattern(af,"repeat")}},get_pattern:function(ac){return this.patterns[ac]},new_canvas:function(){var ac=this.document.createElement("canvas");if(window.G_vmlCanvasManager){G_vmlCanvasManager.initElement(ac)}ac.manager=this;return ac}});var n={};var l=function(ac,ad){n[ac.attr("id")]=ad};var m=function(ac,ae,ag,af){ag=".group";var ad={};n[ac.attr("id")]=af;ac.bind("drag",{handle:"."+ae,relative:true},function(ao,ap){var an=$(this);var at=$(this).parent(),ak=at.children(),am=n[$(this).attr("id")],aj,ai,aq,ah,al;ai=$(this).parents(ag);if(ai.length!==0){aq=ai.position().top;ah=aq+ai.outerHeight();if(ap.offsetY<aq){$(this).insertBefore(ai);var ar=n[ai.attr("id")];ar.remove_drawable(am);ar.container.add_drawable_before(am,ar);return}else{if(ap.offsetY>ah){$(this).insertAfter(ai);var ar=n[ai.attr("id")];ar.remove_drawable(am);ar.container.add_drawable(am);return}}}ai=null;for(al=0;al<ak.length;al++){aj=$(ak.get(al));aq=aj.position().top;ah=aq+aj.outerHeight();if(aj.is(ag)&&this!==aj.get(0)&&ap.offsetY>=aq&&ap.offsetY<=ah){if(ap.offsetY-aq<ah-ap.offsetY){aj.find(".content-div").prepend(this)}else{aj.find(".content-div").append(this)}if(am.container){am.container.remove_drawable(am)}n[aj.attr("id")].add_drawable(am);return}}var aj;for(al=0;al<ak.length;al++){aj=$(ak.get(al));if(ap.offsetY<aj.position().top&&!(aj.hasClass("reference-track")||aj.hasClass("intro"))){break}}if(al===ak.length){if(this!==ak.get(al-1)){at.append(this);n[at.attr("id")].move_drawable(am,al)}}else{if(this!==ak.get(al)){$(this).insertBefore(ak.get(al));n[at.attr("id")].move_drawable(am,(ap.deltaY>0?al-1:al))}}}).bind("dragstart",function(){ad["border-top"]=ac.css("border-top");ad["border-bottom"]=ac.css("border-bottom");$(this).css({"border-top":"1px solid blue","border-bottom":"1px solid blue"})}).bind("dragend",function(){$(this).css(ad)})};U.moveable=m;var aa=16,D=9,A=20,x=100,G=12000,R=400,I=5000,u=100,o="There was an error in indexing this dataset. ",H="A converter for this dataset is not installed. Please check your datatypes_conf.xml file.",B="No data for this chrom/contig.",t="Preparing data. This is very fast for a small dataset but can take a long time for a large dataset. If visualization is saved and closed, preparation will continue in the background.",v="Tool cannot be rerun: ",a="Loading data...",V="Ready for display",O=10,F=20;function W(ad,ac){if(!ac){ac=0}var ae=Math.pow(10,ac);return Math.round(ad*ae)/ae}var c=function(ac){this.num_elements=ac;this.clear()};p(c.prototype,{get:function(ad){var ac=this.key_ary.indexOf(ad);if(ac!==-1){if(this.obj_cache[ad].stale){this.key_ary.splice(ac,1);delete this.obj_cache[ad]}else{this.move_key_to_end(ad,ac)}}return this.obj_cache[ad]},set:function(ad,ae){if(!this.obj_cache[ad]){if(this.key_ary.length>=this.num_elements){var ac=this.key_ary.shift();delete this.obj_cache[ac]}this.key_ary.push(ad)}this.obj_cache[ad]=ae;return ae},move_key_to_end:function(ad,ac){this.key_ary.splice(ac,1);this.key_ary.push(ad)},clear:function(){this.obj_cache={};this.key_ary=[]},size:function(){return this.key_ary.length}});var P=function(ad,ac){c.call(this,ad);this.track=ac};p(P.prototype,c.prototype,{load_data:function(al,ag,aj,ad,ai){var ak=this.track.view.chrom,af={chrom:ak,low:al,high:ag,mode:aj,resolution:ad,dataset_id:this.track.dataset_id,hda_ldda:this.track.hda_ldda};$.extend(af,ai);if(this.track.filters_manager){var am=[];var ac=this.track.filters_manager.filters;for(var ah=0;ah<ac.length;ah++){am.push(ac[ah].name)}af.filter_cols=JSON.stringify(am)}var ae=this;return $.getJSON(this.track.data_url,af,function(an){ae.set_data(al,ag,an)})},get_data:function(ak,ae,ai,ad,ah){var al=this.get(ak,ae);if(al&&(is_deferred(al)||this.track.data_and_mode_compatible(al,ai))){return al}var am,aj,ac,ag,ai,al;for(var af=0;af<this.key_ary.length;af++){am=this.key_ary[af];aj=this.split_key(am);ac=aj[0];ag=aj[1];if(ak>=ac&&ae<=ag){var al=this.obj_cache[am];if(is_deferred(al)||(this.track.data_and_mode_compatible(al,ai)&&this.track.can_subset(al))){this.move_key_to_end(am,af);return al}}}al=this.load_data(ak,ae,ai,ad,ah);this.set_data(ak,ae,al);return al},DEEP_DATA_REQ:"deep",BROAD_DATA_REQ:"breadth",get_more_data:function(ak,af,aj,ae,ai,ag){var al=this.get(ak,af);if(!(al&&this.track.data_and_mode_compatible(al,aj))){console.log("ERROR: no current data for: ",this.track,ak,af,aj,ae,ai);return}al.stale=true;var ad=ak;if(ag===this.DEEP_DATA_REQ){$.extend(ai,{start_val:al.data.length+1})}else{if(ag===this.BROAD_DATA_REQ){ad=(al.max_high?al.max_high:al.data[al.data.length-1][2])+1}}var ac=this,ah=this.load_data(ad,af,aj,ae,ai);new_data_available=$.Deferred();this.set_data(ak,af,new_data_available);$.when(ah).then(function(am){if(am.data){am.data=al.data.concat(am.data);if(am.max_low){am.max_low=al.max_low}if(am.message){am.message=am.message.replace(/[0-9]+/,am.data.length)}}ac.set_data(ak,af,am);new_data_available.resolve(am)});return new_data_available},get:function(ac,ad){return c.prototype.get.call(this,this.gen_key(ac,ad))},set_data:function(ad,ae,ac){return this.set(this.gen_key(ad,ae),ac)},gen_key:function(ac,ae){var ad=ac+"_"+ae;return ad},split_key:function(ac){return ac.split("_")}});var E=function(ad,ac,ae){P.call(this,ad,ac,ae)};p(E.prototype,P.prototype,c.prototype,{get:P.prototype.get,load_data:function(ac,af,ag,ad,ae){if(ad>1){return{data:null}}return P.prototype.load_data.call(this,ac,af,ag,ad,ae)}});var q=function(ad,ac,af){if(!q.id_counter){q.id_counter=0}this.id=q.id_counter++;this.name=af.name;this.view=ad;this.container=ac;this.config=new C({track:this,params:[{key:"name",label:"Name",type:"text",default_value:this.name}],saved_values:af.prefs,onchange:function(){this.track.set_name(this.track.config.values.name)}});this.prefs=this.config.values;this.drag_handle_class=af.drag_handle_class;this.is_overview=false;this.action_icons={};this.content_visible=true;this.container_div=this.build_container_div();this.header_div=this.build_header_div();if(this.header_div){this.container_div.append(this.header_div);this.icons_div=$("<div/>").css("float","left").hide().appendTo(this.header_div);this.build_action_icons(this.action_icons_def);this.header_div.append($("<div style='clear: both'/>"));this.header_div.dblclick(function(ag){ag.stopPropagation()});var ae=this;this.container_div.hover(function(){ae.icons_div.show()},function(){ae.icons_div.hide()});$("<div style='clear: both'/>").appendTo(this.container_div)}};q.prototype.action_icons_def=[{name:"toggle_icon",title:"Hide/show content",css_class:"toggle",on_click_fn:function(ac){if(ac.content_visible){ac.action_icons.toggle_icon.addClass("toggle-expand").removeClass("toggle");ac.hide_contents();ac.content_visible=false}else{ac.action_icons.toggle_icon.addClass("toggle").removeClass("toggle-expand");ac.content_visible=true;ac.show_contents()}}},{name:"settings_icon",title:"Edit settings",css_class:"settings-icon",on_click_fn:function(ad){var af=function(){hide_modal();$(window).unbind("keypress.check_enter_esc")},ac=function(){ad.config.update_from_form($(".dialog-box"));hide_modal();$(window).unbind("keypress.check_enter_esc")},ae=function(ag){if((ag.keyCode||ag.which)===27){af()}else{if((ag.keyCode||ag.which)===13){ac()}}};$(window).bind("keypress.check_enter_esc",ae);show_modal("Configure",ad.config.build_form(),{Cancel:af,OK:ac})}},{name:"remove_icon",title:"Remove",css_class:"remove-icon",on_click_fn:function(ac){$(".tipsy").remove();ac.remove()}}];p(q.prototype,{init:function(){},changed:function(){this.view.changed()},can_draw:function(){if(this.enabled&&this.content_visible){return true}return false},request_draw:function(){},_draw:function(){},to_dict:function(){},update_icons:function(){},set_name:function(ac){this.old_name=this.name;this.name=ac;this.name_div.text(this.name)},revert_name:function(){if(this.old_name){this.name=this.old_name;this.name_div.text(this.name)}},remove:function(){this.changed();this.container.remove_drawable(this);var ac=this.view;this.container_div.hide(0,function(){$(this).remove();ac.update_intro_div()})},build_container_div:function(){},build_header_div:function(){},add_action_icon:function(ad,ai,ah,ag,ac,af){var ae=this;this.action_icons[ad]=$("<a/>").attr("href","javascript:void(0);").attr("title",ai).addClass("icon-button").addClass(ah).tipsy({gravity:"s"}).click(function(){ag(ae)}).appendTo(this.icons_div);if(af){this.action_icons[ad].hide()}},build_action_icons:function(ac){var ae;for(var ad=0;ad<ac.length;ad++){ae=ac[ad];this.add_action_icon(ae.name,ae.title,ae.css_class,ae.on_click_fn,ae.prepend,ae.hide)}},update_icons:function(){},hide_contents:function(){},show_contents:function(){}});var w=function(ad,ac,ae){q.call(this,ad,ac,ae);this.obj_type=ae.obj_type;this.drawables=[]};p(w.prototype,q.prototype,{unpack_drawables:function(ae){this.drawables=[];var ad;for(var ac=0;ac<ae.length;ac++){ad=object_from_template(ae[ac],this);this.add_drawable(ad)}},init:function(){for(var ac=0;ac<this.drawables.length;ac++){this.drawables[ac].init()}},_draw:function(){for(var ac=0;ac<this.drawables.length;ac++){this.drawables[ac]._draw()}},to_dict:function(){var ad=[];for(var ac=0;ac<this.drawables.length;ac++){ad.push(this.drawables[ac].to_dict())}return{name:this.name,prefs:this.prefs,obj_type:this.obj_type,drawables:ad}},add_drawable:function(ac){this.drawables.push(ac);ac.container=this;this.changed()},add_drawable_before:function(ae,ac){this.changed();var ad=this.drawables.indexOf(ac);if(ad!==-1){this.drawables.splice(ad,0,ae);return true}return false},replace_drawable:function(ae,ac,ad){var af=this.drawables.indexOf(ae);if(af!==-1){this.drawables[af]=ac;if(ad){ae.container_div.replaceWith(ac.container_div)}this.changed()}return af},remove_drawable:function(ad){var ac=this.drawables.indexOf(ad);if(ac!==-1){this.drawables.splice(ac,1);ad.container=null;this.changed();return true}return false},move_drawable:function(ad,ae){var ac=this.drawables.indexOf(ad);if(ac!==-1){this.drawables.splice(ac,1);this.drawables.splice(ae,0,ad);this.changed();return true}return false}});var N=function(ad,ac,af){p(af,{obj_type:"DrawableGroup",drag_handle_class:"group-handle"});w.call(this,ad,ac,af);this.content_div=$("<div/>").addClass("content-div").attr("id","group_"+this.id+"_content_div").appendTo(this.container_div);l(this.container_div,this);l(this.content_div,this);m(this.container_div,this.drag_handle_class,".group",this);this.filters_manager=new X(this);this.header_div.after(this.filters_manager.parent_div);this.saved_filters_managers=[];if("drawables" in af){this.unpack_drawables(af.drawables)}if("filters" in af){var ae=this.filters_manager;this.filters_manager=new X(this,af.filters);ae.parent_div.replaceWith(this.filters_manager.parent_div);if(af.filters.visible){this.setup_multitrack_filtering()}}};p(N.prototype,q.prototype,w.prototype,{action_icons_def:[q.prototype.action_icons_def[0],q.prototype.action_icons_def[1],{name:"composite_icon",title:"Show composite track",css_class:"layers-stack",on_click_fn:function(ac){$(".tipsy").remove();ac.show_composite_track()}},{name:"filters_icon",title:"Filters",css_class:"filters-icon",on_click_fn:function(ac){if(ac.filters_manager.visible()){ac.filters_manager.clear_filters();ac._restore_filter_managers()}else{ac.setup_multitrack_filtering();ac.request_draw(true)}ac.filters_manager.toggle()}},q.prototype.action_icons_def[2]],build_container_div:function(){var ac=$("<div/>").addClass("group").attr("id","group_"+this.id);if(this.container){this.container.content_div.append(ac)}return ac},build_header_div:function(){var ac=$("<div/>").addClass("track-header");ac.append($("<div/>").addClass(this.drag_handle_class));this.name_div=$("<div/>").addClass("track-name").text(this.name).appendTo(ac);return ac},hide_contents:function(){this.tiles_div.hide()},show_contents:function(){this.tiles_div.show();this.request_draw()},update_icons:function(){var ae=this.drawables.length;if(ae===0){this.action_icons.composite_icon.hide();this.action_icons.filters_icon.hide()}else{if(ae===1){if(this.drawables[0] instanceof h){this.action_icons.composite_icon.show()}this.action_icons.filters_icon.hide()}else{var ai,ao=true,ag=this.drawables[0].get_type(),ac=0;for(var al=0;al<ae;al++){ai=this.drawables[al];if(ai.get_type()!==ag){can_composite=false;break}if(ai instanceof d){ac++}}if(ao||ac===1){this.action_icons.composite_icon.show()}else{this.action_icons.composite_icon.hide();$(".tipsy").remove()}if(ac>1&&ac===this.drawables.length){var ap={},ad;ai=this.drawables[0];for(var ak=0;ak<ai.filters_manager.filters.length;ak++){ad=ai.filters_manager.filters[ak];ap[ad.name]=[ad]}for(var al=1;al<this.drawables.length;al++){ai=this.drawables[al];for(var ak=0;ak<ai.filters_manager.filters.length;ak++){ad=ai.filters_manager.filters[ak];if(ad.name in ap){ap[ad.name].push(ad)}}}this.filters_manager.remove_all();var af,ah,aj,am;for(var an in ap){af=ap[an];if(af.length===ac){ah=new S({name:af[0].name,index:af[0].index});this.filters_manager.add_filter(ah)}}if(this.filters_manager.filters.length>0){this.action_icons.filters_icon.show()}else{this.action_icons.filters_icon.hide()}}else{this.action_icons.filters_icon.hide()}}}},_restore_filter_managers:function(){for(var ac=0;ac<this.drawables.length;ac++){this.drawables[ac].filters_manager=this.saved_filters_managers[ac]}this.saved_filters_managers=[]},setup_multitrack_filtering:function(){if(this.filters_manager.filters.length>0){this.saved_filters_managers=[];for(var ac=0;ac<this.drawables.length;ac++){drawable=this.drawables[ac];this.saved_filters_managers.push(drawable.filters_manager);drawable.filters_manager=this.filters_manager}}this.filters_manager.init_filters()},show_composite_track:function(){var ag=[];for(var ad=0;ad<this.drawables.length;ad++){ag.push(this.drawables[ad].name)}var ae="Composite Track of "+this.drawables.length+" tracks ("+ag.join(", ")+")";var af=new h(this.view,this.view,{name:ae,drawables:this.drawables});var ac=this.container.replace_drawable(this,af,true);af.request_draw()},add_drawable:function(ac){w.prototype.add_drawable.call(this,ac);this.update_icons()},remove_drawable:function(ac){w.prototype.remove_drawable.call(this,ac);this.update_icons()},to_dict:function(){if(this.filters_manager.visible()){this._restore_filter_managers()}var ac=p(w.prototype.to_dict.call(this),{filters:this.filters_manager.to_dict()});if(this.filters_manager.visible()){this.setup_multitrack_filtering()}return ac},request_draw:function(ac,ae){for(var ad=0;ad<this.drawables.length;ad++){this.drawables[ad].request_draw(ac,ae)}}});var Z=function(ac){p(ac,{obj_type:"View"});w.call(this,"View",ac.container,ac);this.chrom=null;this.vis_id=ac.vis_id;this.dbkey=ac.dbkey;this.label_tracks=[];this.tracks_to_be_redrawn=[];this.max_low=0;this.max_high=0;this.zoom_factor=3;this.min_separation=30;this.has_changes=false;this.load_chroms_deferred=null;this.init();this.canvas_manager=new ab(this.container.get(0).ownerDocument);this.reset()};_.extend(Z.prototype,Backbone.Events);p(Z.prototype,w.prototype,{init:function(){this.requested_redraw=false;var ae=this.container,ac=this;this.top_container=$("<div/>").addClass("top-container").appendTo(ae);this.browser_content_div=$("<div/>").addClass("content").css("position","relative").appendTo(ae);this.bottom_container=$("<div/>").addClass("bottom-container").appendTo(ae);this.top_labeltrack=$("<div/>").addClass("top-labeltrack").appendTo(this.top_container);this.viewport_container=$("<div/>").addClass("viewport-container").attr("id","viewport-container").appendTo(this.browser_content_div);this.content_div=this.viewport_container;l(this.viewport_container,ac);this.intro_div=$("<div/>").addClass("intro").appendTo(this.viewport_container).hide();var af=$("<div/>").text("Add Datasets to Visualization").addClass("action-button").appendTo(this.intro_div).click(function(){add_tracks()});this.nav_labeltrack=$("<div/>").addClass("nav-labeltrack").appendTo(this.bottom_container);this.nav_container=$("<div/>").addClass("trackster-nav-container").prependTo(this.top_container);this.nav=$("<div/>").addClass("trackster-nav").appendTo(this.nav_container);this.overview=$("<div/>").addClass("overview").appendTo(this.bottom_container);this.overview_viewport=$("<div/>").addClass("overview-viewport").appendTo(this.overview);this.overview_close=$("<a/>").attr("href","javascript:void(0);").attr("title","Close overview").addClass("icon-button overview-close tooltip").hide().appendTo(this.overview_viewport);this.overview_highlight=$("<div/>").addClass("overview-highlight").hide().appendTo(this.overview_viewport);this.overview_box_background=$("<div/>").addClass("overview-boxback").appendTo(this.overview_viewport);this.overview_box=$("<div/>").addClass("overview-box").appendTo(this.overview_viewport);this.default_overview_height=this.overview_box.height();this.nav_controls=$("<div/>").addClass("nav-controls").appendTo(this.nav);this.chrom_select=$("<select/>").attr({name:"chrom"}).css("width","15em").addClass("no-autocomplete").append("<option value=''>Loading</option>").appendTo(this.nav_controls);var ad=function(ag){if(ag.type==="focusout"||(ag.keyCode||ag.which)===13||(ag.keyCode||ag.which)===27){if((ag.keyCode||ag.which)!==27){ac.go_to($(this).val())}$(this).hide();$(this).val("");ac.location_span.show();ac.chrom_select.show()}};this.nav_input=$("<input/>").addClass("nav-input").hide().bind("keyup focusout",ad).appendTo(this.nav_controls);this.location_span=$("<span/>").addClass("location").attr("original-title","Click to change location").tipsy({gravity:"n"}).appendTo(this.nav_controls);this.location_span.click(function(){ac.location_span.hide();ac.chrom_select.hide();ac.nav_input.val(ac.chrom+":"+ac.low+"-"+ac.high);ac.nav_input.css("display","inline-block");ac.nav_input.select();ac.nav_input.focus()});if(this.vis_id!==undefined){this.hidden_input=$("<input/>").attr("type","hidden").val(this.vis_id).appendTo(this.nav_controls)}this.zo_link=$("<a/>").attr("id","zoom-out").attr("title","Zoom out").tipsy({gravity:"n"}).click(function(){ac.zoom_out();ac.request_redraw()}).appendTo(this.nav_controls);this.zi_link=$("<a/>").attr("id","zoom-in").attr("title","Zoom in").tipsy({gravity:"n"}).click(function(){ac.zoom_in();ac.request_redraw()}).appendTo(this.nav_controls);this.load_chroms_deferred=this.load_chroms({low:0});this.chrom_select.bind("change",function(){ac.change_chrom(ac.chrom_select.val())});this.browser_content_div.click(function(ag){$(this).find("input").trigger("blur")});this.browser_content_div.bind("dblclick",function(ag){ac.zoom_in(ag.pageX,this.viewport_container)});this.overview_box.bind("dragstart",function(ag,ah){this.current_x=ah.offsetX}).bind("drag",function(ag,ai){var aj=ai.offsetX-this.current_x;this.current_x=ai.offsetX;var ah=Math.round(aj/ac.viewport_container.width()*(ac.max_high-ac.max_low));ac.move_delta(-ah)});this.overview_close.click(function(){ac.reset_overview()});this.viewport_container.bind("draginit",function(ag,ah){if(ag.clientX>ac.viewport_container.width()-16){return false}}).bind("dragstart",function(ag,ah){ah.original_low=ac.low;ah.current_height=ag.clientY;ah.current_x=ah.offsetX}).bind("drag",function(ai,ak){var ag=$(this);var al=ak.offsetX-ak.current_x;var ah=ag.scrollTop()-(ai.clientY-ak.current_height);ag.scrollTop(ah);ak.current_height=ai.clientY;ak.current_x=ak.offsetX;var aj=Math.round(al/ac.viewport_container.width()*(ac.high-ac.low));ac.move_delta(aj)}).bind("mousewheel",function(ai,ak,ah,ag){if(ah){ah*=50;var aj=Math.round(-ah/ac.viewport_container.width()*(ac.high-ac.low));ac.move_delta(aj)}});this.top_labeltrack.bind("dragstart",function(ag,ah){return $("<div />").css({height:ac.browser_content_div.height()+ac.top_labeltrack.height()+ac.nav_labeltrack.height()+1,top:"0px",position:"absolute","background-color":"#ccf",opacity:0.5,"z-index":1000}).appendTo($(this))}).bind("drag",function(ak,al){$(al.proxy).css({left:Math.min(ak.pageX,al.startX)-ac.container.offset().left,width:Math.abs(ak.pageX-al.startX)});var ah=Math.min(ak.pageX,al.startX)-ac.container.offset().left,ag=Math.max(ak.pageX,al.startX)-ac.container.offset().left,aj=(ac.high-ac.low),ai=ac.viewport_container.width();ac.update_location(Math.round(ah/ai*aj)+ac.low,Math.round(ag/ai*aj)+ac.low)}).bind("dragend",function(al,am){var ah=Math.min(al.pageX,am.startX),ag=Math.max(al.pageX,am.startX),aj=(ac.high-ac.low),ai=ac.viewport_container.width(),ak=ac.low;ac.low=Math.round(ah/ai*aj)+ak;ac.high=Math.round(ag/ai*aj)+ak;$(am.proxy).remove();ac.request_redraw()});this.add_label_track(new Y(this,{content_div:this.top_labeltrack}));this.add_label_track(new Y(this,{content_div:this.nav_labeltrack}));$(window).bind("resize",function(){if(this.resize_timer){clearTimeout(this.resize_timer)}this.resize_timer=setTimeout(function(){ac.resize_window()},500)});$(document).bind("redraw",function(){ac.redraw()});this.reset();$(window).trigger("resize")},changed:function(){this.has_changes=true},update_intro_div:function(){if(this.drawables.length===0){this.intro_div.show()}else{this.intro_div.hide()}},trigger_navigate:function(ad,af,ac,ag){if(this.timer){clearTimeout(this.timer)}if(ag){var ae=this;this.timer=setTimeout(function(){ae.trigger("navigate",ad+":"+af+"-"+ac)},500)}else{view.trigger("navigate",ad+":"+af+"-"+ac)}},update_location:function(ac,ae){this.location_span.text(commatize(ac)+" - "+commatize(ae));this.nav_input.val(this.chrom+":"+commatize(ac)+"-"+commatize(ae));var ad=view.chrom_select.val();if(ad!==""){this.trigger_navigate(ad,view.low,view.high,true)}},load_chroms:function(ae){ae.num=u;ae.dbkey=this.dbkey;var ac=this,ad=$.Deferred();$.ajax({url:chrom_url,data:ae,dataType:"json",success:function(ag){if(ag.chrom_info.length===0){alert("Invalid chromosome: "+ae.chrom);return}if(ag.reference){ac.add_label_track(new y(ac))}ac.chrom_data=ag.chrom_info;var aj='<option value="">Select Chrom/Contig</option>';for(var ai=0,af=ac.chrom_data.length;ai<af;ai++){var ah=ac.chrom_data[ai].chrom;aj+='<option value="'+ah+'">'+ah+"</option>"}if(ag.prev_chroms){aj+='<option value="previous">Previous '+u+"</option>"}if(ag.next_chroms){aj+='<option value="next">Next '+u+"</option>"}ac.chrom_select.html(aj);ac.chrom_start_index=ag.start_index;ad.resolve(ag)},error:function(){alert("Could not load chroms for this dbkey:",ac.dbkey)}});return ad},change_chrom:function(ah,ad,aj){var ae=this;if(!ae.chrom_data){ae.load_chroms_deferred.then(function(){ae.change_chrom(ah,ad,aj)});return}if(!ah||ah==="None"){return}var ae=this;if(ah==="previous"){ae.load_chroms({low:this.chrom_start_index-u});return}if(ah==="next"){ae.load_chroms({low:this.chrom_start_index+u});return}var ai=$.grep(ae.chrom_data,function(ak,al){return ak.chrom===ah})[0];if(ai===undefined){ae.load_chroms({chrom:ah},function(){ae.change_chrom(ah,ad,aj)});return}else{if(ah!==ae.chrom){ae.chrom=ah;ae.chrom_select.val(ae.chrom);ae.max_high=ai.len-1;ae.reset();ae.request_redraw(true);for(var ag=0,ac=ae.drawables.length;ag<ac;ag++){var af=ae.drawables[ag];if(af.init){af.init()}}if(ae.reference_track){ae.reference_track.init()}}if(ad!==undefined&&aj!==undefined){ae.low=Math.max(ad,0);ae.high=Math.min(aj,ae.max_high)}else{ae.low=0;ae.high=ae.max_high}ae.reset_overview();ae.request_redraw()}},go_to:function(ag){ag=ag.replace(/ |,/g,"");var ak=this,ac,af,ad=ag.split(":"),ai=ad[0],aj=ad[1];if(aj!==undefined){try{var ah=aj.split("-");ac=parseInt(ah[0],10);af=parseInt(ah[1],10)}catch(ae){return false}}ak.change_chrom(ai,ac,af)},move_fraction:function(ae){var ac=this;var ad=ac.high-ac.low;this.move_delta(ae*ad)},move_delta:function(af){var ac=this;var ae=ac.high-ac.low;if(ac.low-af<ac.max_low){ac.low=ac.max_low;ac.high=ac.max_low+ae}else{if(ac.high-af>ac.max_high){ac.high=ac.max_high;ac.low=ac.max_high-ae}else{ac.high-=af;ac.low-=af}}ac.request_redraw();var ad=ac.chrom_select.val();this.trigger_navigate(ad,ac.low,ac.high,true)},add_drawable:function(ac){w.prototype.add_drawable.call(this,ac);ac.init();this.changed();this.update_intro_div()},add_label_track:function(ac){ac.view=this;ac.init();this.label_tracks.push(ac)},remove_drawable:function(ae,ad){w.prototype.remove_drawable.call(this,ae);if(ad){var ac=this;ae.container_div.hide(0,function(){$(this).remove();ac.update_intro_div()})}},reset:function(){this.low=this.max_low;this.high=this.max_high;this.viewport_container.find(".yaxislabel").remove()},request_redraw:function(ak,ac,aj,ad){var ai=this,ag=(ad?[ad]:ai.drawables),ae;var ad;for(var ah=0;ah<ag.length;ah++){ad=ag[ah];ae=-1;for(var af=0;af<ai.tracks_to_be_redrawn.length;af++){if(ai.tracks_to_be_redrawn[af][0]===ad){ae=af;break}}if(ae<0){ai.tracks_to_be_redrawn.push([ad,ac,aj])}else{ai.tracks_to_be_redrawn[ah][1]=ac;ai.tracks_to_be_redrawn[ah][2]=aj}}if(!this.requested_redraw){requestAnimationFrame(function(){ai._redraw(ak)});this.requested_redraw=true}},_redraw:function(am){this.requested_redraw=false;var aj=this.low,af=this.high;if(aj<this.max_low){aj=this.max_low}if(af>this.max_high){af=this.max_high}var al=this.high-this.low;if(this.high!==0&&al<this.min_separation){af=aj+this.min_separation}this.low=Math.floor(aj);this.high=Math.ceil(af);this.update_location(this.low,this.high);this.resolution_b_px=(this.high-this.low)/this.viewport_container.width();this.resolution_px_b=this.viewport_container.width()/(this.high-this.low);var ac=(this.low/(this.max_high-this.max_low)*this.overview_viewport.width())||0;var ai=((this.high-this.low)/(this.max_high-this.max_low)*this.overview_viewport.width())||0;var an=13;this.overview_box.css({left:ac,width:Math.max(an,ai)}).show();if(ai<an){this.overview_box.css("left",ac-(an-ai)/2)}if(this.overview_highlight){this.overview_highlight.css({left:ac,width:ai})}if(!am){var ae,ad,ak;for(var ag=0,ah=this.tracks_to_be_redrawn.length;ag<ah;ag++){ae=this.tracks_to_be_redrawn[ag][0];ad=this.tracks_to_be_redrawn[ag][1];ak=this.tracks_to_be_redrawn[ag][2];if(ae){ae._draw(ad,ak)}}this.tracks_to_be_redrawn=[];for(ag=0,ah=this.label_tracks.length;ag<ah;ag++){this.label_tracks[ag]._draw()}}},zoom_in:function(ad,ae){if(this.max_high===0||this.high-this.low<=this.min_separation){return}var af=this.high-this.low,ag=af/2+this.low,ac=(af/this.zoom_factor)/2;if(ad){ag=ad/this.viewport_container.width()*(this.high-this.low)+this.low}this.low=Math.round(ag-ac);this.high=Math.round(ag+ac);this.changed();this.request_redraw()},zoom_out:function(){if(this.max_high===0){return}var ad=this.high-this.low,ae=ad/2+this.low,ac=(ad*this.zoom_factor)/2;this.low=Math.round(ae-ac);this.high=Math.round(ae+ac);this.changed();this.request_redraw()},resize_window:function(){this.viewport_container.height(this.container.height()-this.top_container.height()-this.bottom_container.height());this.request_redraw()},set_overview:function(ae){if(this.overview_drawable){if(this.overview_drawable.dataset_id===ae.dataset_id){return}this.overview_viewport.find(".track").remove()}var ad=ae.copy({content_div:this.overview_viewport}),ac=this;ad.header_div.hide();ad.is_overview=true;ac.overview_drawable=ad;this.overview_drawable.postdraw_actions=function(){ac.overview_highlight.show().height(ac.overview_drawable.content_div.height());ac.overview_viewport.height(ac.overview_drawable.content_div.height()+ac.overview_box.outerHeight());ac.overview_close.show();ac.resize_window()};ac.overview_drawable.request_draw();this.changed()},reset_overview:function(){$(".tipsy").remove();this.overview_viewport.find(".track-tile").remove();this.overview_viewport.height(this.default_overview_height);this.overview_box.height(this.default_overview_height);this.overview_close.hide();this.overview_highlight.hide();view.resize_window();view.overview_drawable=null}});var r=function(ae,aj,af){this.track=ae;this.name=aj.name;this.params=[];var aq=aj.params;for(var ag=0;ag<aq.length;ag++){var al=aq[ag],ad=al.name,ap=al.label,ah=unescape(al.html),ar=al.value,an=al.type;if(an==="number"){this.params.push(new f(ad,ap,ah,(ad in af?af[ad]:ar),al.min,al.max))}else{if(an==="select"){this.params.push(new L(ad,ap,ah,(ad in af?af[ad]:ar)))}else{console.log("WARNING: unrecognized tool parameter type:",ad,an)}}}this.parent_div=$("<div/>").addClass("dynamic-tool").hide();this.parent_div.bind("drag",function(au){au.stopPropagation()}).click(function(au){au.stopPropagation()}).bind("dblclick",function(au){au.stopPropagation()});var ao=$("<div class='tool-name'>").appendTo(this.parent_div).text(this.name);var am=this.params;var ak=this;$.each(this.params,function(av,ay){var ax=$("<div>").addClass("param-row").appendTo(ak.parent_div);var au=$("<div>").addClass("param-label").text(ay.label).appendTo(ax);var aw=$("<div/>").addClass("param-input").html(ay.html).appendTo(ax);aw.find(":input").val(ay.value);$("<div style='clear: both;'/>").appendTo(ax)});this.parent_div.find("input").click(function(){$(this).select()});var at=$("<div>").addClass("param-row").appendTo(this.parent_div);var ai=$("<input type='submit'>").attr("value","Run on complete dataset").appendTo(at);var ac=$("<input type='submit'>").attr("value","Run on visible region").css("margin-left","3em").appendTo(at);var ak=this;ac.click(function(){ak.run_on_region()});ai.click(function(){ak.run_on_dataset()});if("visible" in af&&af.visible){this.parent_div.show()}};p(r.prototype,{update_params:function(){for(var ac=0;ac<this.params.length;ac++){this.params[ac].update_value()}},state_dict:function(){var ad={};for(var ac=0;ac<this.params.length;ac++){ad[this.params[ac].name]=this.params[ac].value}ad.visible=this.parent_div.is(":visible");return ad},get_param_values_dict:function(){var ac={};this.parent_div.find(":input").each(function(){var ad=$(this).attr("name"),ae=$(this).val();ac[ad]=JSON.stringify(ae)});return ac},get_param_values:function(){var ad=[];var ac={};this.parent_div.find(":input").each(function(){var ae=$(this).attr("name"),af=$(this).val();if(ae){ad[ad.length]=af}});return ad},run_on_dataset:function(){var ac=this;ac.run({dataset_id:this.track.original_dataset_id,tool_id:ac.name},null,function(ad){show_modal(ac.name+" is Running",ac.name+" is running on the complete dataset. Tool outputs are in dataset's history.",{Close:hide_modal})})},run_on_region:function(){var ad={dataset_id:this.track.original_dataset_id,chrom:this.track.view.chrom,low:this.track.view.low,high:this.track.view.high,tool_id:this.name},ah=this.track,ae=ad.tool_id+ah.tool_region_and_parameters_str(ad.chrom,ad.low,ad.high),ac;if(ah.container===view){var ag=new N(view,view,{name:this.name});var af=ah.container.replace_drawable(ah,ag,false);ag.container_div.insertBefore(ah.view.content_div.children()[af]);ag.add_drawable(ah);ah.container_div.appendTo(ag.content_div);ac=ag}else{ac=ah.container}var ai=new ah.constructor(view,ac,{name:ae,hda_ldda:"hda"});ai.init_for_tool_data();ai.change_mode(ah.mode);ai.set_filters_manager(ah.filters_manager.copy(ai));ai.update_icons();ac.add_drawable(ai);ai.tiles_div.text("Starting job.");this.update_params();this.run(ad,ai,function(aj){ai.dataset_id=aj.dataset_id;ai.tiles_div.text("Running job.");ai.init()})},run:function(ad,ae,af){$.extend(ad,this.get_param_values_dict());var ac=function(){$.getJSON(rerun_tool_url,ad,function(ag){if(ag==="no converter"){ae.container_div.addClass("error");ae.content_div.text(H)}else{if(ag.error){ae.container_div.addClass("error");ae.content_div.text(v+ag.message)}else{if(ag==="pending"){ae.container_div.addClass("pending");ae.content_div.text("Converting input data so that it can be used quickly with tool.");setTimeout(ac,2000)}else{af(ag)}}}})};ac()}});var L=function(ad,ac,ae,af){this.name=ad;this.label=ac;this.html=$(ae);this.value=af};p(L.prototype,{update_value:function(){this.value=$(this.html).val()}});var f=function(ae,ad,ag,ah,af,ac){L.call(this,ae,ad,ag,ah);this.min=af;this.max=ac};p(f.prototype,L.prototype,{update_value:function(){L.prototype.update_value.call(this);this.value=parseFloat(this.value)}});var g=function(ac){this.manager=null;this.name=ac.name;this.index=ac.index;this.tool_id=ac.tool_id;this.tool_exp_name=ac.tool_exp_name};p(g.prototype,{to_dict:function(){return{name:this.name,index:this.index,tool_id:this.tool_id,tool_exp_name:this.tool_exp_name}}});var S=function(al){g.call(this,al);this.low=("low" in al?al.low:-Number.MAX_VALUE);this.high=("high" in al?al.high:Number.MAX_VALUE);this.min=("min" in al?al.min:Number.MAX_VALUE);this.max=("max" in al?al.max:-Number.MAX_VALUE);this.container=null;this.slider=null;this.slider_label=null;var ah=function(am,an,ao){am.click(function(){var au=an.text(),ar=parseFloat(ao.slider("option","max")),aq=(ar<=1?4:ar<=1000000?ar.toString().length:6),at=false,ap=$(this).parents(".slider-row");ap.addClass("input");if(ao.slider("option","values")){aq=2*aq+1;at=true}an.text("");$("<input type='text'/>").attr("size",aq).attr("maxlength",aq).attr("value",au).appendTo(an).focus().select().click(function(av){av.stopPropagation()}).blur(function(){$(this).remove();an.text(au);ap.removeClass("input")}).keyup(function(az){if(az.keyCode===27){$(this).trigger("blur")}else{if(az.keyCode===13){var ax=ao.slider("option","min"),av=ao.slider("option","max"),ay=function(aA){return(isNaN(aA)||aA>av||aA<ax)},aw=$(this).val();if(!at){aw=parseFloat(aw);if(ay(aw)){alert("Parameter value must be in the range ["+ax+"-"+av+"]");return $(this)}}else{aw=aw.split("-");aw=[parseFloat(aw[0]),parseFloat(aw[1])];if(ay(aw[0])||ay(aw[1])){alert("Parameter value must be in the range ["+ax+"-"+av+"]");return $(this)}}ao.slider((at?"values":"value"),aw);ap.removeClass("input")}}})})};var ad=this;ad.parent_div=$("<div/>").addClass("filter-row slider-row");var ac=$("<div/>").addClass("elt-label").appendTo(ad.parent_div),aj=$("<span/>").addClass("slider-name").text(ad.name+" ").appendTo(ac),ae=$("<span/>").text(this.low+"-"+this.high),af=$("<span/>").addClass("slider-value").appendTo(ac).append("[").append(ae).append("]");ad.values_span=ae;var ai=$("<div/>").addClass("slider").appendTo(ad.parent_div);ad.control_element=$("<div/>").attr("id",ad.name+"-filter-control").appendTo(ai);var ag=[0,0];ad.control_element.slider({range:true,min:this.min,max:this.max,step:this.get_slider_step(this.min,this.max),values:[this.low,this.high],slide:function(am,an){ad.slide(am,an)},change:function(am,an){ad.control_element.slider("option","slide").call(ad.control_element,am,an)}});ad.slider=ad.control_element;ad.slider_label=ae;ah(af,ae,ad.control_element);var ak=$("<div/>").addClass("display-controls").appendTo(ad.parent_div);this.transparency_icon=create_action_icon("Use filter for data transparency","layer-transparent",function(){if(ad.manager.alpha_filter!==ad){ad.manager.alpha_filter=ad;ad.manager.parent_div.find(".layer-transparent").removeClass("active").hide();ad.transparency_icon.addClass("active").show()}else{ad.manager.alpha_filter=null;ad.transparency_icon.removeClass("active")}ad.manager.track.request_draw(true,true)}).appendTo(ak).hide();this.height_icon=create_action_icon("Use filter for data height","arrow-resize-090",function(){if(ad.manager.height_filter!==ad){ad.manager.height_filter=ad;ad.manager.parent_div.find(".arrow-resize-090").removeClass("active").hide();ad.height_icon.addClass("active").show()}else{ad.manager.height_filter=null;ad.height_icon.removeClass("active")}ad.manager.track.request_draw(true,true)}).appendTo(ak).hide();ad.parent_div.hover(function(){ad.transparency_icon.show();ad.height_icon.show()},function(){if(ad.manager.alpha_filter!==ad){ad.transparency_icon.hide()}if(ad.manager.height_filter!==ad){ad.height_icon.hide()}});$("<div style='clear: both;'/>").appendTo(ad.parent_div)};p(S.prototype,{to_dict:function(){var ac=g.prototype.to_dict.call(this);return p(ac,{type:"number",min:this.min,max:this.max,low:this.low,high:this.high})},copy:function(){return new S({name:this.name,index:this.index,tool_id:this.tool_id,tool_exp_name:this.tool_exp_name})},get_slider_step:function(ae,ac){var ad=ac-ae;return(ad<=2?0.01:1)},slide:function(ad,ae){var ac=ae.values;this.values_span.text(ac[0]+"-"+ac[1]);this.low=ac[0];this.high=ac[1];this.manager.track.request_draw(true,true)},applies_to:function(ac){if(ac.length>this.index){return true}return false},_keep_val:function(ac){return(isNaN(ac)||(ac>=this.low&&ac<=this.high))},keep:function(ad){if(!this.applies_to(ad)){return true}var af=this;var ag=ad[this.index];if(ag instanceof Array){var ae=true;for(var ac=0;ac<ag.length;ac++){if(!this._keep_val(ag[ac])){ae=false;break}}return ae}else{return this._keep_val(ad[this.index])}},update_attrs:function(af){var ac=false;if(!this.applies_to(af)){return ac}var ad=af[this.index];if(!(ad instanceof Array)){ad=[ad]}for(var ae=0;ae<ad.length;ae++){var ag=ad[ae];if(ag<this.min){this.min=Math.floor(ag);ac=true}if(ag>this.max){this.max=Math.ceil(ag);ac=true}}return ac},update_ui_elt:function(){if(this.min!==this.max){this.parent_div.show()}else{this.parent_div.hide()}var ad=this.slider.slider("option","min"),ac=this.slider.slider("option","max");if(this.min<ad||this.max>ac){this.slider.slider("option","min",this.min);this.slider.slider("option","max",this.max);this.slider.slider("option","step",this.get_slider_step(this.min,this.max));this.slider.slider("option","values",[this.min,this.max])}}});var X=function(ae,ak){this.track=ae;this.alpha_filter=null;this.height_filter=null;this.filters=[];this.parent_div=$("<div/>").addClass("filters").hide();this.parent_div.bind("drag",function(am){am.stopPropagation()}).click(function(am){am.stopPropagation()}).bind("dblclick",function(am){am.stopPropagation()}).bind("keydown",function(am){am.stopPropagation()});if(ak&&"filters" in ak){var ac=("alpha_filter" in ak?ak.alpha_filter:null),af=("height_filter" in ak?ak.height_filter:null),ah=ak.filters,ad;for(var ai=0;ai<ah.length;ai++){if(ah[ai].type==="number"){ad=new S(ah[ai]);this.add_filter(ad);if(ad.name===ac){this.alpha_filter=ad;ad.transparency_icon.addClass("active").show()}if(ad.name===af){this.height_filter=ad;ad.height_icon.addClass("active").show()}}else{console.log("ERROR: unsupported filter: ",name,type)}}if("visible" in ak&&ak.visible){this.parent_div.show()}}if(this.filters.length!==0){var al=$("<div/>").addClass("param-row").appendTo(this.parent_div);var aj=$("<input type='submit'/>").attr("value","Run on complete dataset").appendTo(al);var ag=this;aj.click(function(){ag.run_on_dataset()})}};p(X.prototype,{show:function(){this.parent_div.show()},hide:function(){this.parent_div.hide()},toggle:function(){this.parent_div.toggle()},visible:function(){return this.parent_div.is(":visible")},to_dict:function(){var af={},ae=[],ad;for(var ac=0;ac<this.filters.length;ac++){ad=this.filters[ac];ae.push(ad.to_dict())}af.filters=ae;af.alpha_filter=(this.alpha_filter?this.alpha_filter.name:null);af.height_filter=(this.height_filter?this.height_filter.name:null);af.visible=this.parent_div.is(":visible");return af},copy:function(ad){var ae=new X(ad);for(var ac=0;ac<this.filters.length;ac++){ae.add_filter(this.filters[ac].copy())}return ae},add_filter:function(ac){ac.manager=this;this.parent_div.append(ac.parent_div);this.filters.push(ac)},remove_all:function(){this.filters=[];this.parent_div.children().remove()},init_filters:function(){for(var ac=0;ac<this.filters.length;ac++){var ad=this.filters[ac];ad.update_ui_elt()}},clear_filters:function(){for(var ac=0;ac<this.filters.length;ac++){var ad=this.filters[ac];ad.slider.slider("option","values",[ad.min,ad.max])}this.alpha_filter=null;this.height_filter=null;this.parent_div.find(".icon-button").hide()},run_on_dataset:function(){var ak=function(ao,am,an){if(!(am in ao)){ao[am]=an}return ao[am]};var ae={},ac,ad,af;for(var ag=0;ag<this.filters.length;ag++){ac=this.filters[ag];if(ac.tool_id){if(ac.min!==ac.low){ad=ak(ae,ac.tool_id,[]);ad[ad.length]=ac.tool_exp_name+" >= "+ac.low}if(ac.max!==ac.high){ad=ak(ae,ac.tool_id,[]);ad[ad.length]=ac.tool_exp_name+" <= "+ac.high}}}var ai=[];for(var al in ae){ai[ai.length]=[al,ae[al]]}var aj=ai.length;(function ah(at,ap){var an=ap[0],ao=an[0],ar=an[1],aq="("+ar.join(") and (")+")",am={cond:aq,input:at,target_dataset_id:at,tool_id:ao},ap=ap.slice(1);$.getJSON(run_tool_url,am,function(au){if(au.error){show_modal("Filter Dataset","Error running tool "+ao,{Close:hide_modal})}else{if(ap.length===0){show_modal("Filtering Dataset","Filter(s) are running on the complete dataset. Outputs are in dataset's history.",{Close:hide_modal})}else{ah(au.dataset_id,ap)}}})})(this.track.dataset_id,ai)}});var z=function(ac,ad){J.Scaler.call(this,ad);this.filter=ac};z.prototype.gen_val=function(ac){if(this.filter.high===Number.MAX_VALUE||this.filter.low===-Number.MAX_VALUE||this.filter.low===this.filter.high){return this.default_val}return((parseFloat(ac[this.filter.index])-this.filter.low)/(this.filter.high-this.filter.low))};var C=function(ac){this.track=ac.track;this.params=ac.params;this.values={};this.restore_values((ac.saved_values?ac.saved_values:{}));this.onchange=ac.onchange};p(C.prototype,{restore_values:function(ac){var ad=this;$.each(this.params,function(ae,af){if(ac[af.key]!==undefined){ad.values[af.key]=ac[af.key]}else{ad.values[af.key]=af.default_value}})},build_form:function(){var af=this;var ac=$("<div />");var ae;function ad(aj,ag){for(var an=0;an<aj.length;an++){ae=aj[an];if(ae.hidden){continue}var ah="param_"+an;var ar=af.values[ae.key];var av=$("<div class='form-row' />").appendTo(ag);av.append($("<label />").attr("for",ah).text(ae.label+":"));if(ae.type==="bool"){av.append($('<input type="checkbox" />').attr("id",ah).attr("name",ah).attr("checked",ar))}else{if(ae.type==="text"){av.append($('<input type="text"/>').attr("id",ah).val(ar).click(function(){$(this).select()}))}else{if(ae.type==="select"){var ap=$("<select />").attr("id",ah);for(var al=0;al<ae.options.length;al++){$("<option/>").text(ae.options[al].label).attr("value",ae.options[al].value).appendTo(ap)}ap.val(ar);av.append(ap)}else{if(ae.type==="color"){var au=$("<div/>").appendTo(av),ao=$("<input />").attr("id",ah).attr("name",ah).val(ar).css("float","left").appendTo(au).click(function(ax){$(".tipsy").hide();var aw=$(this).siblings(".tipsy");aw.css({left:$(this).position().left+$(this).width()+5,top:$(this).position().top-($(aw).height()/2)+($(this).height()/2)}).show();aw.click(function(ay){ay.stopPropagation()});$(document).bind("click.color-picker",function(){aw.hide();$(document).unbind("click.color-picker")});ax.stopPropagation()}),am=$("<a href='javascript:void(0)'/>").addClass("icon-button arrow-circle").appendTo(au).attr("title","Set new random color").tipsy({gravity:"s"}),aq=$("<div class='tipsy tipsy-west' style='position: absolute;' />").appendTo(au).hide(),ai=$("<div style='background-color: black; padding: 10px;'></div>").appendTo(aq),at=$("<div/>").appendTo(ai),ak=$.farbtastic(at,{width:100,height:100,callback:ao,color:ar});au.append($("<div/>").css("clear","both"));(function(aw){am.click(function(){aw.setColor(get_random_color())})})(ak)}else{av.append($("<input />").attr("id",ah).attr("name",ah).val(ar))}}}}if(ae.help){av.append($("<div class='help'/>").text(ae.help))}}}ad(this.params,ac);return ac},update_from_form:function(ac){var ae=this;var ad=false;$.each(this.params,function(af,ah){if(!ah.hidden){var ai="param_"+af;var ag=ac.find("#"+ai).val();if(ah.type==="float"){ag=parseFloat(ag)}else{if(ah.type==="int"){ag=parseInt(ag)}else{if(ah.type==="bool"){ag=ac.find("#"+ai).is(":checked")}}}if(ag!==ae.values[ah.key]){ae.values[ah.key]=ag;ad=true}}});if(ad){this.onchange();this.track.changed()}}});var b=function(ac,af,ae,ad,ag){this.track=ac;this.index=af;var ah=this.track._get_tile_bounds(af,ae);this.low=ah[0];this.high=ah[1];this.resolution=ae;this.html_elt=$("<div class='track-tile'/>").append(ad);this.data=ag;this.stale=false};b.prototype.predisplay_actions=function(){};var k=function(ac,af,ae,ad,ag,ah){b.call(this,ac,af,ae,ad,ag);this.max_val=ah};p(k.prototype,b.prototype);var M=function(af,ak,ag,ae,ai,ao,aj,ap,ad,am){b.call(this,af,ak,ag,ae,ai);this.mode=aj;this.all_slotted=ad;this.feature_mapper=am;this.has_icons=false;if(ap){this.has_icons=true;var al=this;ae=this.html_elt.children()[0],message_div=$("<div/>").addClass("tile-message").css({height:A-1,width:ae.width}).prependTo(this.html_elt);var an=ai.length,ah=$("<a href='javascript:void(0);'/>").addClass("icon more-down").attr("title","For speed, only the first "+an+" features in this region were obtained from server. Click to get more data including depth").tipsy({gravity:"s"}).appendTo(message_div),ac=$("<a href='javascript:void(0);'/>").addClass("icon more-across").attr("title","For speed, only the first "+an+" features in this region were obtained from server. Click to get more data excluding depth").tipsy({gravity:"s"}).appendTo(message_div);ah.click(function(){al.stale=true;af.data_manager.get_more_data(al.low,al.high,af.mode,al.resolution,{},af.data_manager.DEEP_DATA_REQ);$(".tipsy").hide();af.request_draw()}).dblclick(function(aq){aq.stopPropagation()});ac.click(function(){al.stale=true;af.data_manager.get_more_data(al.low,al.high,af.mode,al.resolution,{},af.data_manager.BROAD_DATA_REQ);$(".tipsy").hide();af.request_draw()}).dblclick(function(aq){aq.stopPropagation()})}};p(M.prototype,b.prototype);M.prototype.predisplay_actions=function(){var ad=this,ac={};if(ad.mode!=="Pack"){return}$(this.html_elt).hover(function(){this.hovered=true;$(this).mousemove()},function(){this.hovered=false;$(this).parents(".track-content").children(".overlay").children(".feature-popup").remove()}).mousemove(function(ao){if(!this.hovered){return}var aj=$(this).offset(),an=ao.pageX-aj.left,am=ao.pageY-aj.top,at=ad.feature_mapper.get_feature_data(an,am),ak=(at?at[0]:null);$(this).parents(".track-content").children(".overlay").children(".feature-popup").each(function(){if(!ak||$(this).attr("id")!==ak.toString()){$(this).remove()}});if(at){var af=ac[ak];if(!af){var ak=at[0],ap={name:at[3],start:at[1],end:at[2],strand:at[4]},ai=ad.track.filters_manager.filters,ah;for(var al=0;al<ai.length;al++){ah=ai[al];ap[ah.name]=at[ah.index]}var af=$("<div/>").attr("id",ak).addClass("feature-popup"),au=$("<table/>"),ar,aq,av;for(ar in ap){aq=ap[ar];av=$("<tr/>").appendTo(au);$("<th/>").appendTo(av).text(ar);$("<td/>").attr("align","left").appendTo(av).text(typeof(aq)==="number"?W(aq,2):aq)}af.append($("<div class='feature-popup-inner'>").append(au));ac[ak]=af}af.appendTo($(this).parents(".track-content").children(".overlay"));var ag=an+parseInt(ad.html_elt.css("left"))-af.width()/2,ae=am+parseInt(ad.html_elt.css("top"))+7;af.css("left",ag+"px").css("top",ae+"px")}else{if(!ao.isPropagationStopped()){ao.stopPropagation();$(this).siblings().each(function(){$(this).trigger(ao)})}}}).mouseleave(function(){$(this).parents(".track-content").children(".overlay").children(".feature-popup").remove()})};var i=function(ad,ac,ae){p(ae,{drag_handle_class:"draghandle"});q.call(this,ad,ac,ae);this.data_url=("data_url" in ae?ae.data_url:default_data_url);this.data_url_extra_params={};this.data_query_wait=("data_query_wait" in ae?ae.data_query_wait:I);this.dataset_check_url=converted_datasets_state_url;this.data_manager=("data_manager" in ae?ae.data_manager:new P(F,this));this.min_height_px=16;this.max_height_px=800;this.visible_height_px=0;this.content_div=$("<div class='track-content'>").appendTo(this.container_div);if(this.container){this.container.content_div.append(this.container_div);if(!("resize" in ae)||ae.resize){this.add_resize_handle()}}};p(i.prototype,q.prototype,{action_icons_def:[{name:"mode_icon",title:"Set display mode",css_class:"chevron-expand",on_click_fn:function(){}},q.prototype.action_icons_def[0],{name:"overview_icon",title:"Set as overview",css_class:"overview-icon",on_click_fn:function(ac){ac.view.set_overview(ac)}},q.prototype.action_icons_def[1],{name:"filters_icon",title:"Filters",css_class:"filters-icon",on_click_fn:function(ac){if(ac.filters_manager.visible()){ac.filters_manager.clear_filters()}else{ac.filters_manager.init_filters()}ac.filters_manager.toggle()}},{name:"tools_icon",title:"Tool",css_class:"hammer",on_click_fn:function(ac){ac.dynamic_tool_div.toggle();if(ac.dynamic_tool_div.is(":visible")){ac.set_name(ac.name+ac.tool_region_and_parameters_str())}else{ac.revert_name()}$(".tipsy").remove()}},q.prototype.action_icons_def[2]],can_draw:function(){if(this.dataset_id&&q.prototype.can_draw.call(this)){return true}return false},build_container_div:function(){return $("<div/>").addClass("track").attr("id","track_"+this.id).css("position","relative")},build_header_div:function(){var ac=$("<div class='track-header'/>");if(this.view.editor){this.drag_div=$("<div/>").addClass(this.drag_handle_class).appendTo(ac)}this.name_div=$("<div/>").addClass("track-name").appendTo(ac).text(this.name).attr("id",this.name.replace(/\s+/g,"-").replace(/[^a-zA-Z0-9\-]/g,"").toLowerCase());return ac},on_resize:function(){},add_resize_handle:function(){var ac=this;var af=false;var ae=false;var ad=$("<div class='track-resize'>");$(ac.container_div).hover(function(){if(ac.content_visible){af=true;ad.show()}},function(){af=false;if(!ae){ad.hide()}});ad.hide().bind("dragstart",function(ag,ah){ae=true;ah.original_height=$(ac.content_div).height()}).bind("drag",function(ah,ai){var ag=Math.min(Math.max(ai.original_height+ai.deltaY,ac.min_height_px),ac.max_height_px);$(ac.tiles_div).css("height",ag);ac.visible_height_px=(ac.max_height_px===ag?0:ag);ac.on_resize()}).bind("dragend",function(ag,ah){ac.tile_cache.clear();ae=false;if(!af){ad.hide()}ac.config.values.height=ac.visible_height_px;ac.changed()}).appendTo(ac.container_div)},set_display_modes:function(af,ai){this.display_modes=af;this.mode=(ai?ai:(this.config&&this.config.values.mode?this.config.values.mode:this.display_modes[0]));this.action_icons.mode_icon.attr("title","Set display mode (now: "+this.mode+")");var ad=this,ag={};for(var ae=0,ac=ad.display_modes.length;ae<ac;ae++){var ah=ad.display_modes[ae];ag[ah]=function(aj){return function(){ad.change_mode(aj);ad.icons_div.show();ad.container_div.mouseleave(function(){ad.icons_div.hide()})}}(ah)}make_popupmenu(this.action_icons.mode_icon,ag)},build_action_icons:function(){q.prototype.build_action_icons.call(this,this.action_icons_def);if(this.display_modes!==undefined){this.set_display_modes(this.display_modes)}},hide_contents:function(){this.tiles_div.hide();this.container_div.find(".yaxislabel, .track-resize").hide()},show_contents:function(){this.tiles_div.show();this.container_div.find(".yaxislabel, .track-resize").show();this.request_draw()},get_type:function(){if(this instanceof Y){return"LabelTrack"}else{if(this instanceof y){return"ReferenceTrack"}else{if(this instanceof j){return"LineTrack"}else{if(this instanceof T){return"ReadTrack"}else{if(this instanceof Q){return"VcfTrack"}else{if(this instanceof h){return"CompositeTrack"}else{if(this instanceof d){return"FeatureTrack"}}}}}}}return""},init:function(){var ad=this;ad.enabled=false;ad.tile_cache.clear();ad.data_manager.clear();ad.content_div.css("height","auto");ad.tiles_div.children().remove();ad.container_div.removeClass("nodata error pending");if(!ad.dataset_id){return}var ac=$.Deferred();$.getJSON(this.dataset_check_url,{hda_ldda:ad.hda_ldda,dataset_id:ad.dataset_id,chrom:ad.view.chrom},function(ae){if(!ae||ae==="error"||ae.kind==="error"){ad.container_div.addClass("error");ad.tiles_div.text(o);if(ae.message){var af=$(" <a href='javascript:void(0);'></a>").text("View error").click(function(){show_modal("Trackster Error","<pre>"+ae.message+"</pre>",{Close:hide_modal})});ad.tiles_div.append(af)}}else{if(ae==="no converter"){ad.container_div.addClass("error");ad.tiles_div.text(H)}else{if(ae==="no data"||(ae.data!==undefined&&(ae.data===null||ae.data.length===0))){ad.container_div.addClass("nodata");ad.tiles_div.text(B)}else{if(ae==="pending"){ad.container_div.addClass("pending");ad.tiles_div.html(t);setTimeout(function(){ad.init()},ad.data_query_wait)}else{if(ae==="data"||ae.status==="data"){if(ae.valid_chroms){ad.valid_chroms=ae.valid_chroms;ad.update_icons()}ad.tiles_div.text(V);if(ad.view.chrom){ad.tiles_div.text("");ad.tiles_div.css("height",ad.visible_height_px+"px");ad.enabled=true;$.when(ad.predraw_init()).done(function(){ac.resolve();ad.container_div.removeClass("nodata error pending");ad.request_draw()})}else{ac.resolve()}}}}}}});this.update_icons();return ac},predraw_init:function(){}});var K=function(ae,ad,af){i.call(this,ae,ad,af);var ac=this,ae=ac.view;m(ac.container_div,ac.drag_handle_class,".group",ac);this.filters_manager=new X(this,("filters" in af?af.filters:null));this.filters_available=false;this.tool=("tool" in af&&af.tool?new r(this,af.tool,af.tool_state):null);this.tile_cache=new c(O);if(this.header_div){this.set_filters_manager(this.filters_manager);if(this.tool){this.dynamic_tool_div=this.tool.parent_div;this.header_div.after(this.dynamic_tool_div)}}this.tiles_div=$("<div/>").addClass("tiles").appendTo(this.content_div);this.overlay_div=$("<div/>").addClass("overlay").appendTo(this.content_div);if(af.mode){this.change_mode(af.mode)}};p(K.prototype,q.prototype,i.prototype,{action_icons_def:i.prototype.action_icons_def.concat([{name:"show_more_rows_icon",title:"To minimize track height, not all feature rows are displayed. Click to display more rows.",css_class:"exclamation",on_click_fn:function(ac){$(".tipsy").remove();ac.slotters[ac.view.resolution_px_b].max_rows*=2;ac.request_draw(true)},hide:true}]),copy:function(ac){var ad=this.to_dict();p(ad,{data_manager:this.data_manager});var ae=new this.constructor(this.view,ac,ad);ae.change_mode(this.mode);ae.enabled=this.enabled;return ae},set_filters_manager:function(ac){this.filters_manager=ac;this.header_div.after(this.filters_manager.parent_div)},to_dict:function(){return{track_type:this.get_type(),name:this.name,hda_ldda:this.hda_ldda,dataset_id:this.dataset_id,prefs:this.prefs,mode:this.mode,filters:this.filters_manager.to_dict(),tool_state:(this.tool?this.tool.state_dict():{})}},change_mode:function(ad){var ac=this;ac.mode=ad;ac.config.values.mode=ad;ac.tile_cache.clear();ac.request_draw();this.action_icons.mode_icon.attr("title","Set display mode (now: "+ac.mode+")");return ac},update_icons:function(){var ac=this;if(ac.filters_available){ac.action_icons.filters_icon.show()}else{ac.action_icons.filters_icon.hide()}if(ac.tool){ac.action_icons.tools_icon.show()}else{ac.action_icons.tools_icon.hide()}},_gen_tile_cache_key:function(ad,ae,ac){return ad+"_"+ae+"_"+ac},request_draw:function(ad,ac){this.view.request_redraw(false,ad,ac,this)},before_draw:function(){},_draw:function(ad,an){if(!this.can_draw()){return}var al=this.view.low,ah=this.view.high,aj=ah-al,ae=this.view.container.width(),ap=this.view.resolution_px_b,ag=this.view.resolution_b_px;if(this.is_overview){al=this.view.max_low;ah=this.view.max_high;ag=Math.pow(RESOLUTION,Math.ceil(Math.log((view.max_high-view.max_low)/R)/Math.log(RESOLUTION)));ap=ae/(view.max_high-view.max_low)}this.before_draw();this.tiles_div.children().addClass("remove");var ac=Math.floor(al/(ag*R)),ak=true,ao=[],ai=function(aq){return(aq&&"track" in aq)};while((ac*R*ag)<ah){var am=this.draw_helper(ad,ae,ac,ag,this.tiles_div,ap);if(ai(am)){ao.push(am)}else{ak=false}ac+=1}if(!an){this.tiles_div.children(".remove").remove()}var af=this;if(ak){this.tiles_div.children(".remove").remove();af.postdraw_actions(ao,ae,ap,an)}},postdraw_actions:function(af,ag,ai,ac){var ae=this;var ah=false;for(var ad=0;ad<af.length;ad++){if(af[ad].has_icons){ah=true;break}}if(ah){for(var ad=0;ad<af.length;ad++){tile=af[ad];if(!tile.has_icons){tile.html_elt.css("padding-top",A)}}}},draw_helper:function(ac,ao,au,ar,ah,ai,ap){var an=this,ax=this._gen_tile_cache_key(ao,ai,au),af=this._get_tile_bounds(au,ar),av=af[0],ad=af[1];if(!ap){ap={}}var aw=(ac?undefined:an.tile_cache.get(ax));if(aw){an.show_tile(aw,ah,ai);return aw}var al=true;var at=an.data_manager.get_data(av,ad,an.mode,ar,an.data_url_extra_params);if(is_deferred(at)){al=false}var aj;if(view.reference_track&&ai>view.canvas_manager.char_width_px){aj=view.reference_track.data_manager.get_data(av,ad,an.mode,ar,view.reference_track.data_url_extra_params);if(is_deferred(aj)){al=false}}if(al){p(at,ap.more_tile_data);var ak=an.mode;if(ak==="Auto"){ak=an.get_mode(at);an.update_auto_mode(ak)}var ae=an.view.canvas_manager.new_canvas(),af=an._get_tile_bounds(au,ar),av=af[0],ad=af[1],ao=Math.ceil((ad-av)*ai)+an.left_offset,am=an.get_canvas_height(at,ak,ai,ao);ae.width=ao;ae.height=am;var aq=ae.getContext("2d");aq.translate(this.left_offset,0);var aw=an.draw_tile(at,aq,ak,ar,au,ai,aj);if(aw!==undefined){an.tile_cache.set(ax,aw);an.show_tile(aw,ah,ai)}return aw}var ag=$.Deferred();$.when(at,aj).then(function(){view.request_redraw(false,false,false,an);ag.resolve()});return ag},get_canvas_height:function(ac,ae,af,ad){return this.visible_height_px},draw_tile:function(ac,ae,ah,ag,ad,ai,af){console.log("Warning: TiledTrack.draw_tile() not implemented.")},show_tile:function(ae,ag,ah){var ad=this,ac=ae.html_elt;ae.predisplay_actions();var af=(ae.low-(this.is_overview?this.view.max_low:this.view.low))*ah;if(this.left_offset){af-=this.left_offset}ac.css({position:"absolute",top:0,left:af,height:""});if(ac.hasClass("remove")){ac.removeClass("remove")}else{ag.append(ac)}ad.after_show_tile(ae)},after_show_tile:function(ac){},_get_tile_bounds:function(ac,ad){var af=Math.floor(ac*R*ad),ag=Math.ceil(R*ad),ae=(af+ag<=this.view.max_high?af+ag:this.view.max_high);return[af,ae]},tool_region_and_parameters_str:function(ae,ac,af){var ad=this,ag=(ae!==undefined&&ac!==undefined&&af!==undefined?ae+":"+ac+"-"+af:"all");return" - region=["+ag+"], parameters=["+ad.tool.get_param_values().join(", ")+"]"},data_and_mode_compatible:function(ac,ad){return true},can_subset:function(ac){return false},init_for_tool_data:function(){this.data_url=raw_data_url;this.data_query_wait=1000;this.dataset_check_url=dataset_state_url;this.normal_postdraw_actions=this.postdraw_actions;this.postdraw_actions=function(ae,af,ag,ac){var ad=this;ad.normal_postdraw_actions(ae,af,ag,ac);ad.dataset_state_url=converted_datasets_state_url;ad.data_query_wait=I;$.when(server_state_deferred(ad.dataset_state_url,{dataset_id:ad.dataset_id,hda_ldda:ad.hda_ldda},ad.data_query_wait,function(ah){return ah!=="pending"})).then(function(){ad.data_url=default_data_url});ad.postdraw_actions=ad.normal_postdraw_actions}}});var Y=function(ad,ac){var ae={resize:false};i.call(this,ad,ac,ae);this.container_div.addClass("label-track")};p(Y.prototype,i.prototype,{build_header_div:function(){},init:function(){this.enabled=true},_draw:function(){var ae=this.view,af=ae.high-ae.low,ai=Math.floor(Math.pow(10,Math.floor(Math.log(af)/Math.log(10)))),ac=Math.floor(ae.low/ai)*ai,ag=this.view.container.width(),ad=$("<div style='position: relative; height: 1.3em;'></div>");while(ac<ae.high){var ah=(ac-ae.low)/af*ag;ad.append($("<div class='label'>"+commatize(ac)+"</div>").css({position:"absolute",left:ah-1}));ac+=ai}this.content_div.children(":first").remove();this.content_div.append(ad)}});var h=function(ad,ac,ag){K.call(this,ad,ac,ag);this.drawables=[];this.left_offset=0;if("drawables" in ag){var af;for(var ae=0;ae<ag.drawables.length;ae++){af=ag.drawables[ae];this.drawables[ae]=object_from_template(af);if(af.left_offset>this.left_offset){this.left_offset=af.left_offset}}this.enabled=true}if(this.drawables.length!==0){this.set_display_modes(this.drawables[0].display_modes,this.drawables[0].mode)}this.update_icons();this.obj_type="CompositeTrack"};p(h.prototype,K.prototype,{action_icons_def:[{name:"composite_icon",title:"Show individual tracks",css_class:"layers-stack",on_click_fn:function(ac){$(".tipsy").remove();ac.show_group()}}].concat(K.prototype.action_icons_def),to_dict:w.prototype.to_dict,add_drawable:w.prototype.add_drawable,unpack_drawables:w.prototype.unpack_drawables,change_mode:function(ac){K.prototype.change_mode.call(this,ac);for(var ad=0;ad<this.drawables.length;ad++){this.drawables[ad].change_mode(ac)}},init:function(){var ae=[];for(var ad=0;ad<this.drawables.length;ad++){ae.push(this.drawables[ad].init())}var ac=this;$.when.apply($,ae).then(function(){ac.enabled=true;ac.request_draw()})},update_icons:function(){this.action_icons.filters_icon.hide();this.action_icons.tools_icon.hide()},can_draw:q.prototype.can_draw,draw_helper:function(ad,ar,ay,av,aj,al,at){var aq=this,aC=this._gen_tile_cache_key(ar,al,ay),ah=this._get_tile_bounds(ay,av),az=ah[0],ae=ah[1];if(!at){at={}}var aB=(ad?undefined:aq.tile_cache.get(aC));if(aB){aq.show_tile(aB,aj,al);return aB}var ak=[],aq,ao=true,aw,am;for(var ax=0;ax<this.drawables.length;ax++){aq=this.drawables[ax];aw=aq.data_manager.get_data(az,ae,aq.mode,av,aq.data_url_extra_params);if(is_deferred(aw)){ao=false}ak.push(aw);am=null;if(view.reference_track&&al>view.canvas_manager.char_width_px){am=view.reference_track.data_manager.get_data(az,ae,aq.mode,av,view.reference_track.data_url_extra_params);if(is_deferred(am)){ao=false}}ak.push(am)}if(ao){p(aw,at.more_tile_data);this.tile_predraw_init();var ag=aq.view.canvas_manager.new_canvas(),ah=aq._get_tile_bounds(ay,av),az=ah[0],ae=ah[1],aA=0,ar=Math.ceil((ae-az)*al)+this.left_offset,ap=0,af=[];var ac=0;for(var ax=0;ax<this.drawables.length;ax++,aA+=2){aq=this.drawables[ax];aw=ak[aA];var an=aq.mode;if(an==="Auto"){an=aq.get_mode(aw);aq.update_auto_mode(an)}af.push(an);ac=aq.get_canvas_height(aw,an,al,ar);if(ac>ap){ap=ac}}ag.width=ar;ag.height=(at.height?at.height:ap);aA=0;var au=ag.getContext("2d");au.translate(this.left_offset,0);au.globalAlpha=0.5;au.globalCompositeOperation="source-over";for(var ax=0;ax<this.drawables.length;ax++,aA+=2){aq=this.drawables[ax];aw=ak[aA];am=ak[aA+1];aB=aq.draw_tile(aw,au,af[ax],av,ay,al,am)}this.tile_cache.set(aC,aB);this.show_tile(aB,aj,al);return aB}var ai=$.Deferred(),aq=this;$.when.apply($,ak).then(function(){view.request_redraw(false,false,false,aq);ai.resolve()});return ai},show_group:function(){var af=new N(this.view,this.container,{name:this.name}),ac;for(var ae=0;ae<this.drawables.length;ae++){ac=this.drawables[ae];af.add_drawable(ac);ac.container=af;af.content_div.append(ac.container_div)}var ad=this.container.replace_drawable(this,af,true);af.request_draw()},tile_predraw_init:function(){var af=Number.MAX_VALUE,ac=-af,ad;for(var ae=0;ae<this.drawables.length;ae++){ad=this.drawables[ae];if(ad instanceof j){if(ad.prefs.min_value<af){af=ad.prefs.min_value}if(ad.prefs.max_value>ac){ac=ad.prefs.max_value}}}for(var ae=0;ae<this.drawables.length;ae++){ad=this.drawables[ae];ad.prefs.min_value=af;ad.prefs.max_value=ac}},postdraw_actions:function(ae,ah,aj,ad){K.prototype.postdraw_actions.call(this,ae,ah,aj,ad);var ag=-1;for(var af=0;af<ae.length;af++){var ac=ae[af].html_elt.find("canvas").height();if(ac>ag){ag=ac}}for(var af=0;af<ae.length;af++){var ai=ae[af];if(ai.html_elt.find("canvas").height()!==ag){this.draw_helper(true,ah,ai.index,ai.resolution,ai.html_elt.parent(),aj,{height:ag});ai.html_elt.remove()}}}});var y=function(ac){K.call(this,ac,{content_div:ac.top_labeltrack,resize:false},{});ac.reference_track=this;this.left_offset=200;this.visible_height_px=12;this.container_div.addClass("reference-track");this.content_div.css("background","none");this.content_div.css("min-height","0px");this.content_div.css("border","none");this.data_url=reference_url;this.data_url_extra_params={dbkey:ac.dbkey};this.data_manager=new E(F,this,false);this.hide_contents()};p(y.prototype,q.prototype,K.prototype,{build_header_div:function(){},init:function(){this.data_manager.clear();this.enabled=true},can_draw:q.prototype.can_draw,draw_tile:function(ak,al,ah,ag,ad,am){var af=this;if(am>this.view.canvas_manager.char_width_px){if(ak.data===null){this.hide_contents();return}var ae=al.canvas;al.font=al.canvas.manager.default_font;al.textAlign="center";ak=ak.data;for(var ai=0,aj=ak.length;ai<aj;ai++){var ac=Math.floor(ai*am);al.fillText(ak[ai],ac,10)}this.show_contents();return new b(af,ad,ag,ae,ak)}this.hide_contents()}});var j=function(ae,ad,af){var ac=this;this.display_modes=["Histogram","Line","Filled","Intensity"];this.mode="Histogram";K.call(this,ae,ad,af);this.hda_ldda=af.hda_ldda;this.dataset_id=af.dataset_id;this.original_dataset_id=this.dataset_id;this.left_offset=0;this.config=new C({track:this,params:[{key:"name",label:"Name",type:"text",default_value:this.name},{key:"color",label:"Color",type:"color",default_value:get_random_color()},{key:"min_value",label:"Min Value",type:"float",default_value:undefined},{key:"max_value",label:"Max Value",type:"float",default_value:undefined},{key:"mode",type:"string",default_value:this.mode,hidden:true},{key:"height",type:"int",default_value:32,hidden:true}],saved_values:af.prefs,onchange:function(){ac.set_name(ac.prefs.name);ac.vertical_range=ac.prefs.max_value-ac.prefs.min_value;ac.set_min_value(ac.prefs.min_value);ac.set_max_value(ac.prefs.max_value)}});this.prefs=this.config.values;this.visible_height_px=this.config.values.height;this.vertical_range=this.config.values.max_value-this.config.values.min_value};p(j.prototype,q.prototype,K.prototype,{on_resize:function(){this.request_draw(true)},set_min_value:function(ac){this.prefs.min_value=ac;$("#linetrack_"+this.dataset_id+"_minval").text(this.prefs.min_value);this.tile_cache.clear();this.request_draw()},set_max_value:function(ac){this.prefs.max_value=ac;$("#linetrack_"+this.dataset_id+"_maxval").text(this.prefs.max_value);this.tile_cache.clear();this.request_draw()},predraw_init:function(){var ac=this;ac.vertical_range=undefined;return $.getJSON(ac.data_url,{stats:true,chrom:ac.view.chrom,low:null,high:null,hda_ldda:ac.hda_ldda,dataset_id:ac.dataset_id},function(ad){ac.container_div.addClass("line-track");var ag=ad.data;if(isNaN(parseFloat(ac.prefs.min_value))||isNaN(parseFloat(ac.prefs.max_value))){var ae=ag.min;var ai=ag.max;ae=Math.floor(Math.min(0,Math.max(ae,ag.mean-2*ag.sd)));ai=Math.ceil(Math.max(0,Math.min(ai,ag.mean+2*ag.sd)));ac.prefs.min_value=ae;ac.prefs.max_value=ai;$("#track_"+ac.dataset_id+"_minval").val(ac.prefs.min_value);$("#track_"+ac.dataset_id+"_maxval").val(ac.prefs.max_value)}ac.vertical_range=ac.prefs.max_value-ac.prefs.min_value;ac.total_frequency=ag.total_frequency;ac.container_div.find(".yaxislabel").remove();var ah=$("<div/>").text(W(ac.prefs.min_value,3)).make_text_editable({num_cols:6,on_finish:function(aj){$(".tipsy").remove();var aj=parseFloat(aj);if(!isNaN(aj)){ac.set_min_value(aj)}},help_text:"Set min value"}).addClass("yaxislabel bottom").attr("id","linetrack_"+ac.dataset_id+"_minval").prependTo(ac.container_div),af=$("<div/>").text(W(ac.prefs.max_value,3)).make_text_editable({num_cols:6,on_finish:function(aj){$(".tipsy").remove();var aj=parseFloat(aj);if(!isNaN(aj)){ac.set_max_value(aj)}},help_text:"Set max value"}).addClass("yaxislabel top").attr("id","linetrack_"+ac.dataset_id+"_maxval").prependTo(ac.container_div)})},draw_tile:function(am,ak,ah,af,ad,al){var ae=ak.canvas,ac=this._get_tile_bounds(ad,af),ag=ac[0],aj=ac[1],ai=new J.LinePainter(am.data,ag,aj,this.prefs,ah);ai.draw(ak,ae.width,ae.height,al);return new b(this,ad,af,ae,am.data)},can_subset:function(ac){return false},});var d=function(af,ae,ah){var ad=this;this.display_modes=["Auto","Histogram","Dense","Squish","Pack"];K.call(this,af,ae,ah);var ag=get_random_color(),ac=get_random_color([ag,"#ffffff"]);this.config=new C({track:this,params:[{key:"name",label:"Name",type:"text",default_value:this.name},{key:"block_color",label:"Block color",type:"color",default_value:ag},{key:"reverse_strand_color",label:"Antisense strand color",type:"color",default_value:ac},{key:"label_color",label:"Label color",type:"color",default_value:"black"},{key:"show_counts",label:"Show summary counts",type:"bool",default_value:true,help:"Show the number of items in each bin when drawing summary histogram"},{key:"histogram_max",label:"Histogram maximum",type:"float",default_value:null,help:"clear value to set automatically"},{key:"connector_style",label:"Connector style",type:"select",default_value:"fishbones",options:[{label:"Line with arrows",value:"fishbone"},{label:"Arcs",value:"arcs"}]},{key:"mode",type:"string",default_value:this.mode,hidden:true},{key:"height",type:"int",default_value:this.visible_height_px,hidden:true}],saved_values:ah.prefs,onchange:function(){ad.set_name(ad.prefs.name);ad.tile_cache.clear();ad.set_painter_from_config();ad.request_draw()}});this.prefs=this.config.values;this.visible_height_px=this.config.values.height;this.container_div.addClass("feature-track");this.hda_ldda=ah.hda_ldda;this.dataset_id=ah.dataset_id;this.original_dataset_id=ah.dataset_id;this.show_labels_scale=0.001;this.showing_details=false;this.summary_draw_height=30;this.slotters={};this.start_end_dct={};this.left_offset=200;this.set_painter_from_config()};p(d.prototype,q.prototype,K.prototype,{set_painter_from_config:function(){if(this.config.values.connector_style==="arcs"){this.painter=J.ArcLinkedFeaturePainter}else{this.painter=J.LinkedFeaturePainter}},before_draw:function(){this.max_height_px=0},after_show_tile:function(ac){this.max_height_px=Math.max(this.max_height_px,ac.html_elt.height());ac.html_elt.parent().children().css("height",this.max_height_px+"px");var ad=this.max_height_px;if(this.visible_height_px!==0){ad=Math.min(this.max_height_px,this.visible_height_px)}this.tiles_div.css("height",ad+"px")},postdraw_actions:function(ar,am,ah,ag){K.prototype.postdraw_actions.call(this,ar,ag);var al=this;if(al.mode==="Histogram"){var ad=-1;for(var ao=0;ao<ar.length;ao++){var an=ar[ao].max_val;if(an>ad){ad=an}}for(var ao=0;ao<ar.length;ao++){var au=ar[ao];if(au.max_val!==ad){au.html_elt.remove();al.draw_helper(true,am,au.index,au.resolution,au.html_elt.parent(),ah,{more_tile_data:{max:ad}})}}}if(al.filters_manager){var ai=al.filters_manager.filters;for(var aq=0;aq<ai.length;aq++){ai[aq].update_ui_elt()}var at=false,ac,aj;for(var ao=0;ao<ar.length;ao++){if(ar[ao].data.length){ac=ar[ao].data[0];for(var aq=0;aq<ai.length;aq++){aj=ai[aq];if(aj.applies_to(ac)&&aj.min!==aj.max){at=true;break}}}}if(al.filters_available!==at){al.filters_available=at;if(!al.filters_available){al.filters_manager.hide()}al.update_icons()}}this.container_div.find(".yaxislabel").remove();var af=ar[0];if(af instanceof k){var ak=(this.prefs.histogram_max?this.prefs.histogram_max:af.max_val),ae=$("<div/>").text(ak).make_text_editable({num_cols:12,on_finish:function(av){$(".tipsy").remove();var av=parseFloat(av);al.prefs.histogram_max=(!isNaN(av)?av:null);al.tile_cache.clear();al.request_draw()},help_text:"Set max value; leave blank to use default"}).addClass("yaxislabel top").css("color",this.prefs.label_color);this.container_div.prepend(ae)}if(af instanceof M){var ap=true;for(var ao=0;ao<ar.length;ao++){if(!ar[ao].all_slotted){ap=false;break}}if(!ap){this.action_icons.show_more_rows_icon.show()}else{this.action_icons.show_more_rows_icon.hide()}}else{this.action_icons.show_more_rows_icon.hide()}},update_auto_mode:function(ac){var ac;if(this.mode==="Auto"){if(ac==="no_detail"){ac="feature spans"}else{if(ac==="summary_tree"){ac="coverage histogram"}}this.action_icons.mode_icon.attr("title","Set display mode (now: Auto/"+ac+")")}},incremental_slots:function(ag,ac,af){var ad=this.view.canvas_manager.dummy_context,ae=this.slotters[ag];if(!ae||(ae.mode!==af)){ae=new (s.FeatureSlotter)(ag,af,x,function(ah){return ad.measureText(ah)});this.slotters[ag]=ae}return ae.slot_features(ac)},get_summary_tree_data:function(ag,aj,ae,ar){if(ar>ae-aj){ar=ae-aj}var an=Math.floor((ae-aj)/ar),aq=[],af=0;var ah=0,ai=0,am,ap=0,ak=[],ao,al;var ad=function(av,au,aw,at){av[0]=au+aw*at;av[1]=au+(aw+1)*at};while(ap<ar&&ah!==ag.length){var ac=false;for(;ap<ar&&!ac;ap++){ad(ak,aj,ap,an);for(ai=ah;ai<ag.length;ai++){am=ag[ai].slice(1,3);if(is_overlap(am,ak)){ac=true;break}}if(ac){break}}data_start_index=ai;aq[aq.length]=ao=[ak[0],0];for(;ai<ag.length;ai++){am=ag[ai].slice(1,3);if(is_overlap(am,ak)){ao[1]++}else{break}}if(ao[1]>af){af=ao[1]}ap++}return{max:af,delta:an,data:aq}},get_mode:function(ac){if(ac.dataset_type==="summary_tree"){mode="summary_tree"}else{if(ac.extra_info==="no_detail"||this.is_overview){mode="no_detail"}else{if(this.view.high-this.view.low>G){mode="Squish"}else{mode="Pack"}}}return mode},get_canvas_height:function(ac,ag,ah,ad){if(ag==="summary_tree"||ag==="Histogram"){return this.summary_draw_height}else{var af=this.incremental_slots(ah,ac.data,ag);var ae=new (this.painter)(null,null,null,this.prefs,ag);return Math.max(aa,ae.get_required_height(af,ad))}},draw_tile:function(an,ar,ap,at,ax,aj,ae){var aq=this,ad=ar.canvas,ag=this._get_tile_bounds(ax,at),aA=ag[0],ac=ag[1],aF=25,af=this.left_offset;if(ap==="summary_tree"||ap==="Histogram"){if(an.dataset_type!=="summary_tree"){var ak=this.get_summary_tree_data(an.data,aA,ac,200);if(an.max){ak.max=an.max}an=ak}var aC=new J.SummaryTreePainter(an,aA,ac,this.prefs);aC.draw(ar,ad.width,ad.height,aj);return new k(aq,ax,at,ad,an.data,an.max)}var ai=[],ao=this.slotters[aj].slots;all_slotted=true;if(an.data){var al=this.filters_manager.filters;for(var au=0,aw=an.data.length;au<aw;au++){var ah=an.data[au];var av=false;var am;for(var az=0,aE=al.length;az<aE;az++){am=al[az];am.update_attrs(ah);if(!am.keep(ah)){av=true;break}}if(!av){ai.push(ah);if(!(ah[0] in ao)){all_slotted=false}}}}var aD=(this.filters_manager.alpha_filter?new z(this.filters_manager.alpha_filter):null);var aB=(this.filters_manager.height_filter?new z(this.filters_manager.height_filter):null);var aC=new (this.painter)(ai,aA,ac,this.prefs,ap,aD,aB,ae);var ay=null;ar.fillStyle=this.prefs.block_color;ar.font=ar.canvas.manager.default_font;ar.textAlign="right";if(an.data){ay=aC.draw(ar,ad.width,ad.height,aj,ao);ay.translation=-af}return new M(aq,ax,at,ad,an.data,aj,ap,an.message,all_slotted,ay)},data_and_mode_compatible:function(ac,ad){if(ad==="Auto"){return true}else{if(ac.extra_info==="no_detail"||ac.dataset_type==="summary_tree"){return false}else{return true}}},can_subset:function(ac){if(ac.dataset_type==="summary_tree"||ac.message||ac.extra_info==="no_detail"){return false}return true},});var Q=function(ad,ac,ae){d.call(this,ad,ac,ae);this.config=new C({track:this,params:[{key:"name",label:"Name",type:"text",default_value:this.name},{key:"block_color",label:"Block color",type:"color",default_value:get_random_color()},{key:"label_color",label:"Label color",type:"color",default_value:"black"},{key:"show_insertions",label:"Show insertions",type:"bool",default_value:false},{key:"show_counts",label:"Show summary counts",type:"bool",default_value:true},{key:"mode",type:"string",default_value:this.mode,hidden:true},],saved_values:ae.prefs,onchange:function(){this.track.set_name(this.track.prefs.name);this.track.tile_cache.clear();this.track.request_draw()}});this.prefs=this.config.values;this.painter=J.ReadPainter};p(Q.prototype,q.prototype,K.prototype,d.prototype);var T=function(ae,ad,ag){d.call(this,ae,ad,ag);var af=get_random_color(),ac=get_random_color([af,"#ffffff"]);this.config=new C({track:this,params:[{key:"name",label:"Name",type:"text",default_value:this.name},{key:"block_color",label:"Block and sense strand color",type:"color",default_value:af},{key:"reverse_strand_color",label:"Antisense strand color",type:"color",default_value:ac},{key:"label_color",label:"Label color",type:"color",default_value:"black"},{key:"show_insertions",label:"Show insertions",type:"bool",default_value:false},{key:"show_differences",label:"Show differences only",type:"bool",default_value:true},{key:"show_counts",label:"Show summary counts",type:"bool",default_value:true},{key:"histogram_max",label:"Histogram maximum",type:"float",default_value:null,help:"Clear value to set automatically"},{key:"mode",type:"string",default_value:this.mode,hidden:true},],saved_values:ag.prefs,onchange:function(){this.track.set_name(this.track.prefs.name);this.track.tile_cache.clear();this.track.request_draw()}});this.prefs=this.config.values;this.painter=J.ReadPainter;this.update_icons()};p(T.prototype,q.prototype,K.prototype,d.prototype);U.View=Z;U.DrawableGroup=N;U.LineTrack=j;U.FeatureTrack=d;U.ReadTrack=T;U.VcfTrack=Q;U.CompositeTrack=h};var slotting_module=function(c,b){var e=c("class").extend;var d=2,a=5;b.FeatureSlotter=function(i,h,f,g){this.slots={};this.start_end_dct={};this.w_scale=i;this.mode=h;this.include_label=(h==="Pack");this.max_rows=f;this.measureText=g};e(b.FeatureSlotter.prototype,{slot_features:function(m){var p=this.w_scale,h=this.start_end_dct,x=[],z=[],n=0,y=this.max_rows;for(var v=0,w=m.length;v<w;v++){var k=m[v],o=k[0];if(this.slots[o]!==undefined){n=Math.max(n,this.slots[o]);z.push(this.slots[o])}else{x.push(v)}}var q=function(E,F){for(var D=0;D<=y;D++){var B=false,G=h[D];if(G!==undefined){for(var A=0,C=G.length;A<C;A++){var i=G[A];if(F>i[0]&&E<i[1]){B=true;break}}}if(!B){return D}}return -1};for(var v=0,w=x.length;v<w;v++){var k=m[x[v]],o=k[0],t=k[1],f=k[2],r=k[3],g=Math.floor(t*p),l=Math.ceil(f*p),u=this.measureText(r).width,j;if(r!==undefined&&this.include_label){u+=(d+a);if(g-u>=0){g-=u;j="left"}else{l+=u;j="right"}}var s=q(g,l);if(s>=0){if(h[s]===undefined){h[s]=[]}h[s].push([g,l]);this.slots[o]=s;n=Math.max(n,s)}}return n+1}})};var painters_module=function(i,x){var u=i("class").extend;var p=function(I,A,G,z,F,D){if(D===undefined){D=4}var C=z-A;var B=F-G;var E=Math.floor(Math.sqrt(C*C+B*B)/D);var J=C/E;var H=B/E;var y;for(y=0;y<E;y++,A+=J,G+=H){if(y%2!==0){continue}I.fillRect(A,G,D,1)}};var q=function(B,A,z,E){var D=A-E/2,C=A+E/2,F=z-Math.sqrt(E*3/2);B.beginPath();B.moveTo(D,F);B.lineTo(C,F);B.lineTo(A,z);B.lineTo(D,F);B.strokeStyle=this.fillStyle;B.fill();B.stroke();B.closePath()};var d=function(y){this.default_val=(y?y:1)};d.prototype.gen_val=function(y){return this.default_val};var l=function(A,C,y,z,B){this.data=A;this.view_start=C;this.view_end=y;this.prefs=u({},this.default_prefs,z);this.mode=B};l.prototype.default_prefs={};l.prototype.draw=function(z,A,y,B){};var v=function(A,C,y,z,B){l.call(this,A,C,y,z,B)};v.prototype.default_prefs={show_counts:false};v.prototype.draw=function(L,z,K,M){var E=this.view_start,N=this.view_end-this.view_start,I=this.data.data,G=(this.prefs.histogram_max?this.prefs.histogram_max:this.data.max),B=K;delta_x_px=Math.ceil(this.data.delta*M);L.save();for(var C=0,D=I.length;C<D;C++){var H=Math.floor((I[C][0]-E)*M);var F=I[C][1];if(!F){continue}var J=F/G*K;if(F!==0&&J<1){J=1}L.fillStyle=this.prefs.block_color;L.fillRect(H,B-J,delta_x_px,J);var A=4;if(this.prefs.show_counts&&(L.measureText(F).width+A)<delta_x_px){L.fillStyle=this.prefs.label_color;L.textAlign="center";L.fillText(F,H+(delta_x_px/2),10)}}L.restore()};var b=function(y,C,E,F,A){l.call(this,y,C,E,F,A);if(this.prefs.min_value===undefined){var G=Infinity;for(var z=0,B=this.data.length;z<B;z++){G=Math.min(G,this.data[z][1])}this.prefs.min_value=G}if(this.prefs.max_value===undefined){var D=-Infinity;for(var z=0,B=this.data.length;z<B;z++){D=Math.max(D,this.data[z][1])}this.prefs.max_value=D}};b.prototype.default_prefs={min_value:undefined,max_value:undefined,mode:"Histogram",color:"#000",overflow_color:"#F66"};b.prototype.draw=function(S,Q,N,D){var I=false,K=this.prefs.min_value,F=this.prefs.max_value,M=F-K,B=N,C=this.view_start,P=this.view_end-this.view_start,L=this.mode,aa=this.data;S.save();var ac=Math.round(N+K/M*N);if(L!=="Intensity"){S.fillStyle="#aaa";S.fillRect(0,ac,Q,1)}S.beginPath();var Y,G,E;if(aa.length>1){E=Math.ceil((aa[1][0]-aa[0][0])*D)}else{E=10}var A=parseInt(this.prefs.color.slice(1),16),H=(A&16711680)>>16,R=(A&65280)>>8,V=A&255;for(var T=0,U=aa.length;T<U;T++){S.fillStyle=S.strokeStyle=this.prefs.color;Y=Math.round((aa[T][0]-C)*D);G=aa[T][1];var W=false,J=false;if(G===null){if(I&&L==="Filled"){S.lineTo(Y,B)}I=false;continue}if(G<K){J=true;G=K}else{if(G>F){W=true;G=F}}if(L==="Histogram"){G=Math.round(G/M*B);S.fillRect(Y,ac,E,-G)}else{if(L==="Intensity"){var z=(G-K)/M,O=Math.round(H+(255-H)*(1-z)),X=Math.round(R+(255-R)*(1-z)),ab=Math.round(V+(255-V)*(1-z));S.fillStyle="rgb("+O+","+X+","+ab+")";S.fillRect(Y,0,E,B)}else{G=Math.round(B-(G-K)/M*B);if(I){S.lineTo(Y,G)}else{I=true;if(L==="Filled"){S.moveTo(Y,B);S.lineTo(Y,G)}else{S.moveTo(Y,G)}}}}S.fillStyle=this.prefs.overflow_color;if(W||J){var Z;if(L==="Histogram"||L==="Intensity"){Z=E}else{Y-=2;Z=4}if(W){S.fillRect(Y,0,Z,3)}if(J){S.fillRect(Y,B-3,Z,3)}}S.fillStyle=this.prefs.color}if(L==="Filled"){if(I){S.lineTo(Y,ac);S.lineTo(0,ac)}S.fill()}else{S.stroke()}S.restore()};var m=function(y){this.feature_positions={};this.slot_height=y;this.translation=0;this.y_translation=0};m.prototype.map_feature_data=function(z,B,y,A){if(!this.feature_positions[B]){this.feature_positions[B]=[]}this.feature_positions[B].push({data:z,x_start:y,x_end:A})};m.prototype.get_feature_data=function(z,D){var C=Math.floor((D-this.y_translation)/this.slot_height),B;if(!this.feature_positions[C]){return null}z+=this.translation;for(var A=0;A<this.feature_positions[C].length;A++){B=this.feature_positions[C][A];if(z>=B.x_start&&z<=B.x_end){return B.data}}};var o=function(A,D,y,z,C,E,B){l.call(this,A,D,y,z,C);this.alpha_scaler=(E?E:new d());this.height_scaler=(B?B:new d())};o.prototype.default_prefs={block_color:"#FFF",connector_color:"#FFF"};u(o.prototype,{get_required_height:function(A,z){var y=y_scale=this.get_row_height(),B=this.mode;if(B==="no_detail"||B==="Squish"||B==="Pack"){y=A*y_scale}return y+this.get_top_padding(z)+this.get_bottom_padding(z)},get_top_padding:function(y){return 0},get_bottom_padding:function(y){return Math.max(Math.round(this.get_row_height()/2),5)},draw:function(K,I,G,E,F){var Q=this.data,D=this.view_start,M=this.view_end;K.save();K.fillStyle=this.prefs.block_color;K.textAlign="right";var H=this.view_end-this.view_start,L=this.get_row_height(),P=new m(L),B;for(var N=0,O=Q.length;N<O;N++){var A=Q[N],C=A[0],J=A[1],y=A[2],z=(F&&F[C]!==undefined?F[C]:null);if((J<M&&y>D)&&(this.mode==="Dense"||z!==null)){B=this.draw_element(K,this.mode,A,z,D,M,E,L,I);P.map_feature_data(A,z,B[0],B[1])}}K.restore();P.y_translation=this.get_top_padding(I);return P},draw_element:function(E,A,G,C,B,D,F,z,y){console.log("WARNING: Unimplemented function.");return[0,0]}});var c=10,h=3,k=5,w=10,f=1,s=9,e=3,a=9,j=2,g="#ccc";var r=function(A,D,y,z,C,E,B){o.call(this,A,D,y,z,C,E,B);this.draw_background_connector=true;this.draw_individual_connectors=false};u(r.prototype,o.prototype,{get_row_height:function(){var z=this.mode,y;if(z==="Dense"){y=c}else{if(z==="no_detail"){y=h}else{if(z==="Squish"){y=k}else{y=w}}}return y},draw_element:function(M,D,X,H,O,ai,am,ao,y){var T=X[0],ak=X[1],ad=X[2]-1,Q=X[3],K=X[4],ae=Math.floor(Math.max(0,(ak-O)*am)),N=Math.ceil(Math.min(y,Math.max(0,(ad-O)*am))),ac=ae,an=N,aa=(D==="Dense"?0:(0+H))*ao+this.get_top_padding(y),L,ag,R=null,aq=null,B=B=(!K||K==="+"||K==="."?this.prefs.block_color:this.prefs.reverse_strand_color);label_color=this.prefs.label_color;M.globalAlpha=this.alpha_scaler.gen_val(X);if(D==="Dense"){H=1}if(D==="no_detail"){M.fillStyle=B;M.fillRect(ae,aa+5,N-ae,f)}else{var Z=X[5],af=X[6],C=X[7],V=true;if(Z&&af){R=Math.floor(Math.max(0,(Z-O)*am));aq=Math.ceil(Math.min(y,Math.max(0,(af-O)*am)))}var al,U;if(D==="Squish"){al=1;U=e;V=false}else{if(D==="Dense"){al=5;U=s}else{al=5;U=a}}if(!C){M.fillStyle=B;M.fillRect(ae,aa+1,N-ae,U);if(K&&V){if(K==="+"){M.fillStyle=M.canvas.manager.get_pattern("right_strand_inv")}else{if(K==="-"){M.fillStyle=M.canvas.manager.get_pattern("left_strand_inv")}}M.fillRect(ae,aa+1,N-ae,U)}}else{var J,W;if(D==="Squish"||D==="Dense"){J=aa+Math.floor(e/2)+1;W=1}else{if(K){J=aa;W=U}else{J+=(e/2)+1;W=1}}if(this.draw_background_connector){if(D==="Squish"||D==="Dense"){M.fillStyle=g}else{if(K){if(K==="+"){M.fillStyle=M.canvas.manager.get_pattern("right_strand")}else{if(K==="-"){M.fillStyle=M.canvas.manager.get_pattern("left_strand")}}}else{M.fillStyle=g}}M.fillRect(ae,J,N-ae,W)}var E;for(var aj=0,A=C.length;aj<A;aj++){var F=C[aj],z=Math.floor(Math.max(0,(F[0]-O)*am)),Y=Math.ceil(Math.min(y,Math.max((F[1]-1-O)*am))),S,ab;if(z>Y){continue}M.fillStyle=B;M.fillRect(z,aa+(U-al)/2+1,Y-z,al);if(R!==undefined&&af>Z&&!(z>aq||Y<R)){var ah=Math.max(z,R),I=Math.min(Y,aq);M.fillRect(ah,aa+1,I-ah,U)}if(this.draw_individual_connectors&&S){this.draw_connector(M,S,ab,z,Y,aa)}S=z;ab=Y}if(D==="Pack"){M.globalAlpha=1;M.fillStyle="white";var G=this.height_scaler.gen_val(X),P=Math.ceil(U*G),ap=Math.round((U-P)/2);if(G!==1){M.fillRect(ae,J+1,N-ae,ap);M.fillRect(ae,J+U-ap+1,N-ae,ap)}}}M.globalAlpha=1;if(D==="Pack"&&ak>O){M.fillStyle=label_color;if(O===0&&ae-M.measureText(Q).width<0){M.textAlign="left";M.fillText(Q,N+j,aa+8);an+=M.measureText(Q).width+j}else{M.textAlign="right";M.fillText(Q,ae-j,aa+8);ac-=M.measureText(Q).width+j}}}M.globalAlpha=1;return[ac,an]}});var t=function(B,E,y,A,D,F,C,z){o.call(this,B,E,y,A,D,F,C);this.ref_seq=(z?z.data:null)};u(t.prototype,o.prototype,{get_row_height:function(){var y,z=this.mode;if(z==="Dense"){y=c}else{if(z==="Squish"){y=k}else{y=w;if(this.prefs.show_insertions){y*=2}}}return y},draw_read:function(K,A,ag,V,L,aa,ad,C,B,M){K.textAlign="center";var J=this,R=[L,aa],Z=0,W=0,D=0,F=K.canvas.manager.char_width_px,y=(B==="+"?this.prefs.block_color:this.prefs.reverse_strand_color);var O=[];if((A==="Pack"||this.mode==="Auto")&&M!==undefined&&ag>F){D=Math.round(ag/2)}if(!C){C=[[0,M.length]]}for(var G=0,I=C.length;G<I;G++){var z=C[G],E="MIDNSHP=X"[z[0]],S=z[1];if(E==="H"||E==="S"){Z-=S}var U=ad+Z,Y=Math.floor(Math.max(0,(U-L)*ag)),ab=Math.floor(Math.max(0,(U+S-L)*ag));if(Y===ab){ab+=1}switch(E){case"H":break;case"S":case"M":case"=":if(is_overlap([U,U+S],R)){var N=M.slice(W,W+S);if(D>0){K.fillStyle=y;K.fillRect(Y-D,V+1,ab-Y,9);K.fillStyle=g;for(var af=0,H=N.length;af<H;af++){if(this.prefs.show_differences){if(this.ref_seq){var P=this.ref_seq[U-L+af];if(!P||P.toLowerCase()===N[af].toLowerCase()){continue}}else{continue}}if(U+af>=L&&U+af<=aa){var X=Math.floor(Math.max(0,(U+af-L)*ag));K.fillText(N[af],X,V+9)}}}else{K.fillStyle=y;K.fillRect(Y,V+4,ab-Y,e)}}W+=S;Z+=S;break;case"N":K.fillStyle=g;K.fillRect(Y-D,V+5,ab-Y,1);Z+=S;break;case"D":K.fillStyle="red";K.fillRect(Y-D,V+4,ab-Y,3);Z+=S;break;case"P":break;case"I":var ah=Y-D;if(is_overlap([U,U+S],R)){var N=M.slice(W,W+S);if(this.prefs.show_insertions){var T=Y-(ab-Y)/2;if((A==="Pack"||this.mode==="Auto")&&M!==undefined&&ag>F){K.fillStyle="yellow";K.fillRect(T-D,V-9,ab-Y,9);O[O.length]={type:"triangle",data:[ah,V+4,5]};K.fillStyle=g;switch(compute_overlap([U,U+S],R)){case (OVERLAP_START):N=N.slice(L-U);break;case (OVERLAP_END):N=N.slice(0,U-aa);break;case (CONTAINED_BY):break;case (CONTAINS):N=N.slice(L-U,U-aa);break}for(var af=0,H=N.length;af<H;af++){var X=Math.floor(Math.max(0,(U+af-L)*ag));K.fillText(N[af],X-(ab-Y)/2,V)}}else{K.fillStyle="yellow";K.fillRect(T,V+(this.mode!=="Dense"?2:5),ab-Y,(A!=="Dense"?e:s))}}else{if((A==="Pack"||this.mode==="Auto")&&M!==undefined&&ag>F){O.push({type:"text",data:[N.length,ah,V+9]})}else{}}}W+=S;break;case"X":W+=S;break}}K.fillStyle="yellow";var Q,ai,ae;for(var ac=0;ac<O.length;ac++){Q=O[ac];ai=Q.type;ae=Q.data;if(ai==="text"){K.save();K.font="bold "+K.font;K.fillText(ae[0],ae[1],ae[2]);K.restore()}else{if(ai==="triangle"){q(K,ae[0],ae[1],ae[2])}}}},draw_element:function(R,M,E,B,U,z,I,S,P){var H=E[0],Q=E[1],A=E[2],J=E[3],D=Math.floor(Math.max(0,(Q-U)*I)),F=Math.ceil(Math.min(P,Math.max(0,(A-U)*I))),C=(M==="Dense"?0:(0+B))*S,G=this.prefs.label_color,O=0;if((M==="Pack"||this.mode==="Auto")&&I>R.canvas.manager.char_width_px){var O=Math.round(I/2)}if(E[5] instanceof Array){var N=Math.floor(Math.max(0,(E[4][0]-U)*I)),L=Math.ceil(Math.min(P,Math.max(0,(E[4][1]-U)*I))),K=Math.floor(Math.max(0,(E[5][0]-U)*I)),y=Math.ceil(Math.min(P,Math.max(0,(E[5][1]-U)*I)));if(E[4][1]>=U&&E[4][0]<=z&&E[4][2]){this.draw_read(R,M,I,C,U,z,E[4][0],E[4][2],E[4][3],E[4][4])}if(E[5][1]>=U&&E[5][0]<=z&&E[5][2]){this.draw_read(R,M,I,C,U,z,E[5][0],E[5][2],E[5][3],E[5][4])}if(K>L){R.fillStyle=g;p(R,L-O,C+5,K-O,C+5)}}else{this.draw_read(R,M,I,C,U,z,Q,E[4],E[5],E[6])}if(M==="Pack"&&Q>U&&J!=="."){R.fillStyle=this.prefs.label_color;var T=1;if(T===0&&D-R.measureText(J).width<0){R.textAlign="left";R.fillText(J,F+j-O,C+8)}else{R.textAlign="right";R.fillText(J,D-j-O,C+8)}}return[0,0]}});var n=function(A,D,y,z,C,E,B){r.call(this,A,D,y,z,C,E,B);this.longest_feature_length=this.calculate_longest_feature_length();this.draw_background_connector=false;this.draw_individual_connectors=true};u(n.prototype,o.prototype,r.prototype,{calculate_longest_feature_length:function(){var z=0;for(var C=0,y=this.data.length;C<y;C++){var B=this.data[C],A=B[1],D=B[2];z=Math.max(z,D-A)}return z},get_top_padding:function(z){var y=this.view_end-this.view_start,A=z/y;return Math.min(128,Math.ceil((this.longest_feature_length/2)*A))},draw_connector:function(G,B,F,H,E,D){var y=(F+H)/2,C=H-y;var A=Math.PI,z=0;if(C>0){G.beginPath();G.arc(y,D,H-y,Math.PI,0);G.stroke()}}});x.Scaler=d;x.SummaryTreePainter=v;x.LinePainter=b;x.LinkedFeaturePainter=r;x.ReadPainter=t;x.ArcLinkedFeaturePainter=n};(function(d){var c={};var b=function(e){return c[e]};var a=function(f,g){var e={};g(b,e);c[f]=e};a("class",class_module);a("slotting",slotting_module);a("painters",painters_module);a("trackster",trackster_module);for(key in c.trackster){d[key]=c.trackster[key]}})(window);
\ No newline at end of file
diff -r 1c196b8747e4d976cbc1d294457b64a7e27fb26c -r db93ba1751de1c39e0c1febbdb946ce326197187 static/scripts/trackster.js
--- a/static/scripts/trackster.js
+++ b/static/scripts/trackster.js
@@ -5706,7 +5706,8 @@
y_center = (mode === "Dense" ? 0 : (0 + slot)) * y_scale + this.get_top_padding(width),
thickness, y_start, thick_start = null, thick_end = null,
// TODO: is there any reason why block, label color cannot be set at the Painter level?
- block_color = block_color = (!feature_strand || feature_strand === "+" ? this.prefs.block_color : this.prefs.reverse_strand_color);
+ // For now, assume '.' === '+'
+ block_color = block_color = (!feature_strand || feature_strand === "+" || feature_strand === "." ? this.prefs.block_color : this.prefs.reverse_strand_color);
label_color = this.prefs.label_color;
// Set global alpha.
@@ -5823,17 +5824,21 @@
// Draw thin block.
ctx.fillStyle = block_color;
- ctx.fillRect(block_start, y_center + (thick_height-thin_height)/2 + 1, block_end - block_start, thin_height );
+ ctx.fillRect(block_start, y_center + (thick_height-thin_height)/2 + 1, block_end - block_start, thin_height);
// If block intersects with thick region, draw block as thick.
// - No thick is sometimes encoded as thick_start == thick_end, so don't draw in that case
if (thick_start !== undefined && feature_te > feature_ts && !(block_start > thick_end || block_end < thick_start) ) {
var block_thick_start = Math.max(block_start, thick_start),
block_thick_end = Math.min(block_end, thick_end);
- ctx.fillRect(block_thick_start, y_center + 1, block_thick_end - block_thick_start, thick_height );
+ ctx.fillRect(block_thick_start, y_center + 1, block_thick_end - block_thick_start, thick_height);
+ // FIXME: for GFF datasets, only one block of many may be fetched, so it is not possible to
+ // determine if feature has only one block. Hence, Ffr now, do not use b/c color is used to encoding
+ // strand.
+ /*
if ( feature_blocks.length === 1 && mode === "Pack") {
// Exactly one block means we have no introns, but do have a distinct "thick" region,
- // draw arrows over it if in pack mode
+ // draw arrows over it if in pack mode.
if (feature_strand === "+") {
ctx.fillStyle = ctx.canvas.manager.get_pattern( 'right_strand_inv' );
} else if (feature_strand === "-") {
@@ -5844,8 +5849,9 @@
block_thick_start += 2;
block_thick_end -= 2;
}
- ctx.fillRect(block_thick_start, y_center + 1, block_thick_end - block_thick_start, thick_height );
- }
+ ctx.fillRect(block_thick_start, y_center + 1, block_thick_end - block_thick_start, thick_height);
+ }
+ */
}
// Draw individual connectors if required
if ( this.draw_individual_connectors && last_block_start ) {
https://bitbucket.org/galaxy/galaxy-central/changeset/317e326803d4/
changeset: 317e326803d4
user: jgoecks
date: 2012-05-09 02:06:08
summary: Merge
affected #: 1 file
diff -r db93ba1751de1c39e0c1febbdb946ce326197187 -r 317e326803d42db705c93d4c59e92c1eb764fa36 lib/galaxy/webapps/community/controllers/upload.py
--- a/lib/galaxy/webapps/community/controllers/upload.py
+++ b/lib/galaxy/webapps/community/controllers/upload.py
@@ -122,6 +122,8 @@
else:
content_alert_str = ''
commands.add( repo.ui, repo, full_path )
+ # Convert from unicode to prevent "TypeError: array item must be char"
+ full_path = full_path.encode('ascii', 'replace')
try:
commands.commit( repo.ui, repo, full_path, user=trans.user.username, message=commit_message )
except Exception, e:
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: natefoo: Fix "TypeError: array item must be char" on tool shed upload.
by Bitbucket 08 May '12
by Bitbucket 08 May '12
08 May '12
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/changeset/b725cb712c8f/
changeset: b725cb712c8f
user: natefoo
date: 2012-05-08 18:32:01
summary: Fix "TypeError: array item must be char" on tool shed upload.
affected #: 1 file
diff -r 1c196b8747e4d976cbc1d294457b64a7e27fb26c -r b725cb712c8f7764120fdbdac5aa11d306d287f2 lib/galaxy/webapps/community/controllers/upload.py
--- a/lib/galaxy/webapps/community/controllers/upload.py
+++ b/lib/galaxy/webapps/community/controllers/upload.py
@@ -122,6 +122,8 @@
else:
content_alert_str = ''
commands.add( repo.ui, repo, full_path )
+ # Convert from unicode to prevent "TypeError: array item must be char"
+ full_path = full_path.encode('ascii', 'replace')
try:
commands.commit( repo.ui, repo, full_path, user=trans.user.username, message=commit_message )
except Exception, e:
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/changeset/1c196b8747e4/
changeset: 1c196b8747e4
user: dan
date: 2012-05-04 21:35:51
summary: Rewrite HbVar datasource tool.
affected #: 1 file
diff -r dd777fbcc5fa1fee5939db5d914611b8b466eed6 -r 1c196b8747e4d976cbc1d294457b64a7e27fb26c tools/data_source/hbvar.xml
--- a/tools/data_source/hbvar.xml
+++ b/tools/data_source/hbvar.xml
@@ -1,22 +1,18 @@
<?xml version="1.0"?>
-<tool name="HbVar" id="hbvar">
+<tool name="HbVar" id="hbvar" tool_type="data_source" version="2.0.0"><description>Human Hemoglobin Variants and Thalassemias</description>
- <command/>
+ <command interpreter="python">data_source.py $output $__app__.config.output_size_limit</command><inputs action="http://globin.bx.psu.edu/cgi-bin/hbvar/query_vars3" check_values="false" method="get" target="_top"><display>go to HbVar database $GALAXY_URL $tool_id</display>
- <param name="GALAXY_URL" type="baseurl" value="/tool_runner/hbvar" />
- <param name="tool_id" type="hidden" value = "hbvar"/></inputs><uihints minwidth="800"/>
- <code file="hbvar_filter.py"/>
-
<outputs>
- <data name="output" format="txt" />
+ <data name="output" format="auto" /></outputs><options sanitize="False" refresh="True"/>
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0