galaxy-commits
Threads by month
- ----- 2025 -----
- June
- May
- April
- March
- February
- January
- ----- 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
- 15302 discussions
1 new changeset in galaxy-central:
http://bitbucket.org/galaxy/galaxy-central/changeset/8b97f197b759/
changeset: 8b97f197b759
user: greg
date: 2011-07-08 22:11:28
summary: First pass implementation for tool shed repository metadata. This implementation currently provides a baseline metadata collection for tools in a tool shed repository. This change set also includes the implementation for displaying a tool UI for each valid tool config in the tool shed repository. Fixes issue # 565.
affected #: 16 files (14.8 KB)
--- a/lib/galaxy/webapps/community/app.py Fri Jul 08 09:09:02 2011 -0400
+++ b/lib/galaxy/webapps/community/app.py Fri Jul 08 16:11:28 2011 -0400
@@ -1,4 +1,6 @@
import sys, config
+import galaxy.tools.data
+import galaxy.datatypes.registry
import galaxy.webapps.community.model
from galaxy.web import security
from galaxy.tags.tag_handler import CommunityTagHandler
@@ -11,6 +13,8 @@
self.config = config.Configuration( **kwargs )
self.config.check()
config.configure_logging( self.config )
+ # Set up datatypes registry
+ self.datatypes_registry = galaxy.datatypes.registry.Registry( self.config.root, self.config.datatypes_config )
# Determine the database url
if self.config.database_connection:
db_url = self.config.database_connection
@@ -28,6 +32,8 @@
self.security = security.SecurityHelper( id_secret=self.config.id_secret )
# Tag handler
self.tag_handler = CommunityTagHandler()
+ # Tool data tables
+ self.tool_data_tables = galaxy.tools.data.ToolDataTableManager( self.config.tool_data_table_config_path )
# Load security policy
self.security_agent = self.model.security_agent
def shutdown( self ):
--- a/lib/galaxy/webapps/community/config.py Fri Jul 08 09:09:02 2011 -0400
+++ b/lib/galaxy/webapps/community/config.py Fri Jul 08 16:11:28 2011 -0400
@@ -41,6 +41,9 @@
self.cookie_path = kwargs.get( "cookie_path", "/" )
self.test_conf = resolve_path( kwargs.get( "test_conf", "" ), self.root )
self.id_secret = kwargs.get( "id_secret", "USING THE DEFAULT IS NOT SECURE!" )
+ self.tool_secret = kwargs.get( "tool_secret", "" )
+ self.tool_data_path = resolve_path( kwargs.get( "tool_data_path", "tool-data" ), os.getcwd() )
+ self.tool_data_table_config_path = resolve_path( kwargs.get( 'tool_data_table_config_path', 'tool_data_table_conf.xml' ), self.root )
self.use_remote_user = string_as_bool( kwargs.get( "use_remote_user", "False" ) )
self.remote_user_maildomain = kwargs.get( "remote_user_maildomain", None )
self.remote_user_logout_href = kwargs.get( "remote_user_logout_href", None )
@@ -56,7 +59,9 @@
self.smtp_server = kwargs.get( 'smtp_server', None )
self.smtp_username = kwargs.get( 'smtp_username', None )
self.smtp_password = kwargs.get( 'smtp_password', None )
+ self.start_job_runners = kwargs.get( 'start_job_runners', None )
self.email_alerts_from = kwargs.get( 'email_alerts_from', None )
+ self.nginx_upload_path = kwargs.get( 'nginx_upload_path', False )
self.log_actions = string_as_bool( kwargs.get( 'log_actions', 'False' ) )
self.brand = kwargs.get( 'brand', None )
self.wiki_url = kwargs.get( 'wiki_url', 'http://bitbucket.org/galaxy/galaxy-central/wiki/Home' )
@@ -65,7 +70,7 @@
self.screencasts_url = kwargs.get( 'screencasts_url', None )
self.log_events = False
self.cloud_controller_instance = False
- self.datatypes_config = kwargs.get( 'datatypes_config_file', 'community_datatypes_conf.xml' )
+ self.datatypes_config = kwargs.get( 'datatypes_config_file', 'datatypes_conf.xml' )
# Proxy features
self.apache_xsendfile = kwargs.get( 'apache_xsendfile', False )
self.nginx_x_accel_redirect_base = kwargs.get( 'nginx_x_accel_redirect_base', False )
--- a/lib/galaxy/webapps/community/controllers/common.py Fri Jul 08 09:09:02 2011 -0400
+++ b/lib/galaxy/webapps/community/controllers/common.py Fri Jul 08 16:11:28 2011 -0400
@@ -1,12 +1,13 @@
import os, string, socket, logging
from time import strftime
from datetime import *
+from galaxy.tools import *
from galaxy.util.json import from_json_string, to_json_string
from galaxy.web.base.controller import *
from galaxy.webapps.community import model
from galaxy.model.orm import *
from galaxy.model.item_attrs import UsesItemRatings
-from mercurial import hg, ui
+from mercurial import hg, ui, commands
log = logging.getLogger( __name__ )
@@ -68,14 +69,15 @@
def get_repository( trans, id ):
"""Get a repository from the database via id"""
return trans.sa_session.query( trans.model.Repository ).get( trans.security.decode_id( id ) )
+def get_repository_metadata( trans, id, changeset_revision ):
+ """Get metadata for a specified repository change set from the database"""
+ return trans.sa_session.query( trans.model.RepositoryMetadata ) \
+ .filter( and_( trans.model.RepositoryMetadata.table.c.repository_id == trans.security.decode_id( id ),
+ trans.model.RepositoryMetadata.table.c.changeset_revision == changeset_revision ) ) \
+ .first()
def get_repository_by_name( trans, name ):
"""Get a repository from the database via name"""
return trans.sa_session.query( app.model.Repository ).filter_by( name=name ).one()
-def get_repository_tip( repository ):
- # The received repository must be a mercurial repository, not a db record.
- tip_changeset = repository.changelog.tip()
- tip_ctx = repository.changectx( tip_changeset )
- return "%s:%s" % ( str( tip_ctx.rev() ), tip_ctx.parents()[0] )
def get_user( trans, id ):
"""Get a user from the database"""
return trans.sa_session.query( trans.model.User ).get( trans.security.decode_id( id ) )
@@ -121,19 +123,138 @@
def update_for_browsing( repository, current_working_dir ):
# Make a copy of a repository's files for browsing.
repo_dir = repository.repo_path
+ repo = hg.repository( ui.ui(), repo_dir )
+ # The following will delete the disk copy of only the files in the repository.
+ #os.system( 'hg update -r null > /dev/null 2>&1' )
+ repo.ui.pushbuffer()
+ commands.status( repo.ui, repo, all=True )
+ status_and_file_names = repo.ui.popbuffer().strip().split( "\n" )
+ # status_and_file_names looks something like:
+ # ['? MY_README_AGAIN', '? galaxy_tmap_tool/tmap-0.0.9.tar.gz', '? dna_filtering.py', 'C filtering.py', 'C filtering.xml']
+ # The codes used to show the status of files are:
+ # M = modified
+ # A = added
+ # R = removed
+ # C = clean
+ # ! = deleted, but still tracked
+ # ? = not tracked
+ # I = ignored
+ # We'll remove all files that are not tracked or ignored.
+ files_to_remove_from_disk = []
+ for status_and_file_name in status_and_file_names:
+ if status_and_file_name.startswith( '?' ) or status_and_file_name.startswith( 'I' ):
+ files_to_remove_from_disk.append( os.path.abspath( os.path.join( repo_dir, status_and_file_name.split()[1] ) ) )
+ for full_path in files_to_remove_from_disk:
+ if os.path.isdir( full_path ):
+ try:
+ os.rmdir( full_path )
+ except OSError, e:
+ # The directory is not empty
+ pass
+ elif os.path.isfile( full_path ):
+ os.remove( full_path )
+ dir = os.path.split( full_path )[0]
+ try:
+ os.rmdir( dir )
+ except OSError, e:
+ # The directory is not empty
+ pass
os.chdir( repo_dir )
os.system( 'hg update > /dev/null 2>&1' )
os.chdir( current_working_dir )
+def load_tool( trans, config_file ):
"""
- # TODO: the following is useful if the repository files somehow include missing or
- # untracked files. If this happens, we can enhance the following to clean things up.
- # We're not currently doing any cleanup though since so far none of the repositories
- # have problematic files for browsing.
- # Get the tip change set.
+ Load a single tool from the file named by `config_file` and return
+ an instance of `Tool`.
+ """
+ # Parse XML configuration file and get the root element
+ tree = util.parse_xml( config_file )
+ root = tree.getroot()
+ if root.tag == 'tool':
+ # Allow specifying a different tool subclass to instantiate
+ if root.find( "type" ) is not None:
+ type_elem = root.find( "type" )
+ module = type_elem.get( 'module', 'galaxy.tools' )
+ cls = type_elem.get( 'class' )
+ mod = __import__( module, globals(), locals(), [cls])
+ ToolClass = getattr( mod, cls )
+ elif root.get( 'tool_type', None ) is not None:
+ ToolClass = tool_types.get( root.get( 'tool_type' ) )
+ else:
+ ToolClass = Tool
+ return ToolClass( config_file, root, trans.app )
+ return None
+def set_repository_metadata( trans, id, ctx_str, **kwd ):
+ """Set repository metadata"""
+ message = ''
+ status = 'done'
+ repository = get_repository( trans, id )
+ repo_dir = repository.repo_path
repo = hg.repository( ui.ui(), repo_dir )
+ found = False
+ invalid_tool_configs = []
for changeset in repo.changelog:
ctx = repo.changectx( changeset )
- ctx_parent = ctx.parents()[0]
- break
- modified, added, removed, deleted, unknown, ignored, clean = repo.status( node1=ctx_parent.node(), node2=ctx.node() )
- """
+ if str( ctx ) == ctx_str:
+ found = True
+ break
+ if found:
+ for root, dirs, files in os.walk( repo_dir ):
+ if not root.find( '.hg' ) >= 0 and not root.find( 'hgrc' ) >= 0:
+ if '.hg' in dirs:
+ # Don't visit .hg directories - should be impossible since we don't
+ # allow uploaded archives that contain .hg dirs, but just in case...
+ dirs.remove( '.hg' )
+ if 'hgrc' in files:
+ # Don't include hgrc files in commit.
+ files.remove( 'hgrc' )
+ for name in files:
+ # Find all tool configs.
+ if name.endswith( '.xml' ):
+ try:
+ full_path = os.path.abspath( os.path.join( root, name ) )
+ tool = load_tool( trans, full_path )
+ if tool is not None:
+ repository_metadata = get_repository_metadata( trans, id, repository.tip )
+ # TODO: add more stuff, like requirements
+ tool_dict = dict( id = tool.id,
+ name = tool.name,
+ version = tool.version,
+ description = tool.description,
+ tool_config = full_path )
+ if repository_metadata:
+ metadata = repository_metadata.metadata
+ if metadata and 'tools' in metadata:
+ metadata_tools = metadata[ 'tools' ]
+ found = False
+ for tool_metadata_dict in metadata_tools:
+ if 'id' in tool_metadata_dict and tool_metadata_dict[ 'id' ] == tool.id and \
+ 'version' in tool_metadata_dict and tool_metadata_dict[ 'version' ] == tool.version:
+ found = True
+ tool_metadata_dict[ 'name' ] = tool.name
+ tool_metadata_dict[ 'description' ] = tool.description
+ tool_metadata_dict[ 'tool_config' ] = os.path.join( root, name )
+ # TODO: add more stuff, like tool requirements, code files, etc
+ if not found:
+ metadata_tools.append( tool_dict )
+ else:
+ if metadata is None:
+ repository_metadata.metadata = {}
+ repository_metadata.metadata[ 'tools' ] = [ tool_dict ]
+ trans.sa_session.add( repository_metadata )
+ else:
+ metadata_dict = dict( tools = [ tool_dict ] )
+ repository_metadata = trans.model.RepositoryMetadata( repository.id, repository.tip, metadata_dict )
+ trans.sa_session.add( repository_metadata )
+ trans.sa_session.flush()
+ except Exception, e:
+ invalid_tool_configs.append( ( name, str( e ) ) )
+ else:
+ message = "Repository does not include changeset revision '%s'." % str( ctx_str )
+ status = 'error'
+ if invalid_tool_configs:
+ message = "The following tool configs are invalid and were not added to the repository metadata:<br/>"
+ for itc_tup in invalid_tool_configs:
+ message += "<b>%s</b> - %s<br/>" % ( itc_tup[0], itc_tup[1] )
+ status = 'error'
+ return message, status
--- a/lib/galaxy/webapps/community/controllers/repository.py Fri Jul 08 09:09:02 2011 -0400
+++ b/lib/galaxy/webapps/community/controllers/repository.py Fri Jul 08 16:11:28 2011 -0400
@@ -76,8 +76,7 @@
return repository.name
class VersionColumn( grids.TextColumn ):
def get_value( self, trans, grid, repository ):
- repo = hg.repository( ui.ui(), repository.repo_path )
- return get_repository_tip( repo )
+ return repository.version
class DescriptionColumn( grids.TextColumn ):
def get_value( self, trans, grid, repository ):
return repository.description
@@ -124,7 +123,7 @@
key="name",
link=( lambda item: dict( operation="view_or_manage_repository", id=item.id, webapp="community" ) ),
attach_popup=False ),
- DescriptionColumn( "Description",
+ DescriptionColumn( "Synopsis",
key="description",
attach_popup=False ),
VersionColumn( "Version",
@@ -420,7 +419,7 @@
selected_files_to_delete = selected_files_to_delete.split( ',' )
current_working_dir = os.getcwd()
# Get the current repository tip.
- tip = repo[ 'tip' ]
+ tip = repository.tip
for selected_file in selected_files_to_delete:
repo_file = os.path.abspath( selected_file )
commands.remove( repo.ui, repo, repo_file )
@@ -434,10 +433,19 @@
update_for_browsing( repository, current_working_dir )
# Get the new repository tip.
repo = hg.repository( ui.ui(), repo_dir )
- if tip != repo[ 'tip' ]:
+ if tip != repository.tip:
message = "The selected files were deleted from the repository."
else:
message = 'No changes to repository.'
+ # Set metadata on the repository tip
+ error_message, status = set_repository_metadata( trans, id, repository.tip, **kwd )
+ if error_message:
+ message = '%s<br/>%s' % ( message, error_message )
+ return trans.response.send_redirect( web.url_for( controller='repository',
+ action='manage_repository',
+ id=id,
+ message=message,
+ status=status ) )
else:
message = "Select at least 1 file to delete from the repository before clicking <b>Delete selected files</b>."
status = "error"
@@ -454,7 +462,6 @@
status = params.get( 'status', 'done' )
repository = get_repository( trans, id )
repo = hg.repository( ui.ui(), repository.repo_path )
- tip = get_repository_tip( repo )
avg_rating, num_ratings = self.get_ave_item_rating_data( trans.sa_session, repository, webapp_model=trans.model )
display_reviews = util.string_as_bool( params.get( 'display_reviews', False ) )
alerts = params.get( 'alerts', '' )
@@ -481,10 +488,15 @@
trans.sa_session.flush()
checked = alerts_checked or ( user and user.email in email_alerts )
alerts_check_box = CheckboxField( 'alerts', checked=checked )
+ repository_metadata = get_repository_metadata( trans, id, repository.tip )
+ if repository_metadata:
+ metadata = repository_metadata.metadata
+ else:
+ metadata = None
return trans.fill_template( '/webapps/community/repository/view_repository.mako',
repo=repo,
repository=repository,
- tip=tip,
+ metadata=metadata,
avg_rating=avg_rating,
display_reviews=display_reviews,
num_ratings=num_ratings,
@@ -499,7 +511,6 @@
status = params.get( 'status', 'done' )
repository = get_repository( trans, id )
repo = hg.repository( ui.ui(), repository.repo_path )
- tip = get_repository_tip( repo )
repo_name = util.restore_text( params.get( 'repo_name', repository.name ) )
description = util.restore_text( params.get( 'description', repository.description ) )
long_description = util.restore_text( params.get( 'long_description', repository.long_description ) )
@@ -577,6 +588,11 @@
allow_push_select_field = self.__build_allow_push_select_field( trans, current_allow_push_list )
checked = alerts_checked or user.email in email_alerts
alerts_check_box = CheckboxField( 'alerts', checked=checked )
+ repository_metadata = get_repository_metadata( trans, id, repository.tip )
+ if repository_metadata:
+ metadata = repository_metadata.metadata
+ else:
+ metadata = None
return trans.fill_template( '/webapps/community/repository/manage_repository.mako',
repo_name=repo_name,
description=description,
@@ -585,7 +601,7 @@
allow_push_select_field=allow_push_select_field,
repo=repo,
repository=repository,
- tip=tip,
+ metadata=metadata,
avg_rating=avg_rating,
display_reviews=display_reviews,
num_ratings=num_ratings,
@@ -676,7 +692,6 @@
status='error' ) )
repository = get_repository( trans, id )
repo = hg.repository( ui.ui(), repository.repo_path )
- tip = get_repository_tip( repo )
if repository.user == trans.user:
return trans.response.send_redirect( web.url_for( controller='repository',
action='browse_repositories',
@@ -691,7 +706,6 @@
rra = self.get_user_item_rating( trans.sa_session, trans.user, repository, webapp_model=trans.model )
return trans.fill_template( '/webapps/community/repository/rate_repository.mako',
repository=repository,
- tip=tip,
avg_rating=avg_rating,
display_reviews=display_reviews,
num_ratings=num_ratings,
@@ -736,6 +750,40 @@
action='browse_repositories',
**kwd ) )
@web.expose
+ @web.require_login( "set repository metadata" )
+ def set_metadata( self, trans, id, ctx_str, **kwd ):
+ message, status = set_repository_metadata( trans, id, ctx_str, **kwd )
+ return trans.response.send_redirect( web.url_for( controller='repository',
+ action='manage_repository',
+ id=id,
+ message=message,
+ status=status ) )
+ @web.expose
+ def display_tool( self, trans, repository_id, tool_config, **kwd ):
+ params = util.Params( kwd )
+ message = util.restore_text( params.get( 'message', '' ) )
+ status = params.get( 'status', 'done' )
+ repository = get_repository( trans, repository_id )
+ tool = load_tool( trans, os.path.abspath( tool_config ) )
+ tool_state = self.__new_state( trans )
+ return trans.fill_template( "/webapps/community/repository/tool_form.mako",
+ repository=repository,
+ tool=tool,
+ tool_state=tool_state,
+ message=message,
+ status=status )
+ def __new_state( self, trans, all_pages=False ):
+ """
+ Create a new `DefaultToolState` for this tool. It will not be initialized
+ with default values for inputs.
+
+ Only inputs on the first page will be initialized unless `all_pages` is
+ True, in which case all inputs regardless of page are initialized.
+ """
+ state = DefaultToolState()
+ state.inputs = {}
+ return state
+ @web.expose
def download( self, trans, repository_id, file_type, **kwd ):
# Download an archive of the repository files compressed as zip, gz or bz2.
params = util.Params( kwd )
--- a/lib/galaxy/webapps/community/controllers/upload.py Fri Jul 08 09:09:02 2011 -0400
+++ b/lib/galaxy/webapps/community/controllers/upload.py Fri Jul 08 16:11:28 2011 -0400
@@ -33,7 +33,7 @@
uploaded_file = None
upload_point = self.__get_upload_point( repository, **kwd )
# Get the current repository tip.
- tip = repo[ 'tip' ]
+ tip = repository.tip
if params.get( 'upload_button', False ):
current_working_dir = os.getcwd()
file_data = params.get( 'file_data', '' )
@@ -89,8 +89,7 @@
# is eliminating unwanted files from the repository directory.
update_for_browsing( repository, current_working_dir )
# Get the new repository tip.
- repo = hg.repository( ui.ui(), repo_dir )
- if tip != repo[ 'tip' ]:
+ if tip != repository.tip:
if ( isgzip or isbz2 ) and uncompress_file:
uncompress_str = ' uncompressed and '
else:
@@ -102,12 +101,22 @@
else:
message += " %d files were removed from the repository root." % len( files_to_remove )
else:
- message = 'No changes to repository.'
+ message = 'No changes to repository.'
+ # Set metadata on the repository tip
+ error_message, status = set_repository_metadata( trans, repository_id, repository.tip, **kwd )
+ if error_message:
+ message = '%s<br/>%s' % ( message, error_message )
+ return trans.response.send_redirect( web.url_for( controller='repository',
+ action='manage_repository',
+ id=repository_id,
+ message=message,
+ status=status ) )
trans.response.send_redirect( web.url_for( controller='repository',
action='browse_repository',
+ id=repository_id,
commit_message='Deleted selected files',
message=message,
- id=trans.security.encode_id( repository.id ) ) )
+ status=status ) )
else:
status = 'error'
selected_categories = [ trans.security.decode_id( id ) for id in category_ids ]
--- a/lib/galaxy/webapps/community/model/__init__.py Fri Jul 08 09:09:02 2011 -0400
+++ b/lib/galaxy/webapps/community/model/__init__.py Fri Jul 08 16:11:28 2011 -0400
@@ -114,6 +114,15 @@
return config.get( "paths", option )
raise Exception( "Entry for repository %s missing in %s/hgweb.config file." % ( lhs, os.getcwd() ) )
@property
+ def version( self ):
+ repo = hg.repository( ui.ui(), self.repo_path )
+ tip_ctx = repo.changectx( repo.changelog.tip() )
+ return "%s:%s" % ( str( tip_ctx.rev() ), str( repo.changectx( repo.changelog.tip() ) ) )
+ @property
+ def tip( self ):
+ repo = hg.repository( ui.ui(), self.repo_path )
+ return str( repo.changectx( repo.changelog.tip() ) )
+ @property
def is_new( self ):
repo = hg.repository( ui.ui(), self.repo_path )
tip_ctx = repo.changectx( repo.changelog.tip() )
@@ -143,6 +152,12 @@
fp.write( line )
fp.close()
+class RepositoryMetadata( object ):
+ def __init__( self, repository_id=None, changeset_revision=None, metadata=None ):
+ self.repository_id = repository_id
+ self.changeset_revision = changeset_revision
+ self.metadata = metadata or dict()
+
class ItemRatingAssociation( object ):
def __init__( self, id=None, user=None, item=None, rating=0, comment='' ):
self.id = id
--- a/lib/galaxy/webapps/community/model/mapping.py Fri Jul 08 09:09:02 2011 -0400
+++ b/lib/galaxy/webapps/community/model/mapping.py Fri Jul 08 16:11:28 2011 -0400
@@ -111,6 +111,14 @@
Column( "email_alerts", JSONType, nullable=True ),
Column( "times_downloaded", Integer ) )
+RepositoryMetadata.table = Table( "repository_metadata", metadata,
+ Column( "id", Integer, primary_key=True ),
+ Column( "create_time", DateTime, default=now ),
+ Column( "update_time", DateTime, default=now, onupdate=now ),
+ Column( "repository_id", Integer, ForeignKey( "repository.id" ), index=True ),
+ Column( "changeset_revision", TrimmedString( 255 ), index=True ),
+ Column( "metadata", JSONType, nullable=True ) )
+
RepositoryRatingAssociation.table = Table( "repository_rating_association", metadata,
Column( "id", Integer, primary_key=True ),
Column( "create_time", DateTime, default=now ),
@@ -186,6 +194,9 @@
ratings=relation( RepositoryRatingAssociation, order_by=desc( RepositoryRatingAssociation.table.c.update_time ), backref="repositories" ),
user=relation( User.mapper ) ) )
+assign_mapper( context, RepositoryMetadata, RepositoryMetadata.table,
+ properties=dict( repository=relation( Repository ) ) )
+
assign_mapper( context, RepositoryRatingAssociation, RepositoryRatingAssociation.table,
properties=dict( repository=relation( Repository ), user=relation( User ) ) )
--- a/templates/webapps/community/repository/browse_repository.mako Fri Jul 08 09:09:02 2011 -0400
+++ b/templates/webapps/community/repository/browse_repository.mako Fri Jul 08 16:11:28 2011 -0400
@@ -5,12 +5,13 @@
<%
from galaxy.web.framework.helpers import time_ago
+ is_admin = trans.user_is_admin()
is_new = repository.is_new
can_push = trans.app.security_agent.can_push( trans.user, repository )
can_upload = can_push
can_browse_contents = not is_new
can_rate = trans.user and repository.user != trans.user
- can_manage = repository.user == trans.user
+ can_manage = is_admin or repository.user == trans.user
can_view_change_log = not is_new
%>
--- a/templates/webapps/community/repository/manage_repository.mako Fri Jul 08 09:09:02 2011 -0400
+++ b/templates/webapps/community/repository/manage_repository.mako Fri Jul 08 16:11:28 2011 -0400
@@ -121,9 +121,9 @@
<div class="form-row"><label>Version:</label>
%if can_view_change_log:
- <a href="${h.url_for( controller='repository', action='view_changelog', id=trans.app.security.encode_id( repository.id ) )}">${tip}</a>
+ <a href="${h.url_for( controller='repository', action='view_changelog', id=trans.app.security.encode_id( repository.id ) )}">${repository.version}</a>
%else:
- ${tip}
+ ${repository.version}
%endif
</div><div class="form-row">
@@ -150,6 +150,40 @@
</form></div></div>
+<p/>
+<div class="toolForm">
+ <div class="toolFormTitle">Repository metadata</div>
+ <div class="toolFormBody">
+ %if metadata:
+ %if 'tools' in metadata:
+ <div class="form-row">
+ <label>Tools:</label>
+ <% tool_dicts = metadata[ 'tools' ] %>
+ <table class="grid">
+ %for tool_dict in tool_dicts:
+ <tr>
+ <td><a href="${h.url_for( controller='repository', action='display_tool', repository_id=trans.security.encode_id( repository.id ), tool_config=tool_dict[ 'tool_config' ] )}">${tool_dict[ 'name' ]}</a></td>
+ <td>${tool_dict[ 'description' ]}</td>
+ <td>version: ${tool_dict[ 'version' ]}</td>
+ </tr>
+ %endfor
+ </table>
+ </div>
+ <div style="clear: both"></div>
+ %endif
+ %endif
+ <form name="set_metadata" action="${h.url_for( controller='repository', action='set_metadata', id=trans.security.encode_id( repository.id ), ctx_str=repository.tip )}" method="post">
+ <div class="form-row">
+ <div style="float: left; width: 250px; margin-right: 10px;">
+ <input type="submit" name="set_metadata_button" value="Reset metadata"/>
+ </div>
+ <div class="toolParamHelp" style="clear: both;">
+ Inspect the repository and reset the above attributes for the repository tip.
+ </div>
+ </div>
+ </form>
+ </div>
+</div>
%if trans.app.config.smtp_server:
<p/><div class="toolForm">
--- a/templates/webapps/community/repository/rate_repository.mako Fri Jul 08 09:09:02 2011 -0400
+++ b/templates/webapps/community/repository/rate_repository.mako Fri Jul 08 16:11:28 2011 -0400
@@ -4,12 +4,13 @@
<%
from galaxy.web.framework.helpers import time_ago
from urllib import quote_plus
+ is_admin = trans.user_is_admin()
is_new = repository.is_new
can_push = trans.app.security_agent.can_push( trans.user, repository )
can_upload = can_push
can_browse_contents = not is_new
can_rate = repository.user != trans.user
- can_manage = repository.user == trans.user
+ can_manage = is_admin or repository.user == trans.user
can_view_change_log = not is_new
if can_push:
browse_label = 'Browse or delete repository files'
@@ -103,7 +104,7 @@
</div><div class="form-row"><label>Version:</label>
- ${tip}
+ ${repository.version}
<div style="clear: both"></div></div><div class="form-row">
--- a/templates/webapps/community/repository/upload.mako Fri Jul 08 09:09:02 2011 -0400
+++ b/templates/webapps/community/repository/upload.mako Fri Jul 08 16:11:28 2011 -0400
@@ -2,11 +2,12 @@
<%namespace file="/webapps/community/repository/common.mako" import="*" /><%
+ is_admin = trans.user_is_admin()
is_new = repository.is_new
can_browse_contents = not is_new
can_browse_contents = not is_new
can_rate = repository.user != trans.user
- can_manage = repository.user == trans.user
+ can_manage = is_admin or repository.user == trans.user
can_view_change_log = not is_new
%>
--- a/templates/webapps/community/repository/view_changelog.mako Fri Jul 08 09:09:02 2011 -0400
+++ b/templates/webapps/community/repository/view_changelog.mako Fri Jul 08 16:11:28 2011 -0400
@@ -5,9 +5,10 @@
<%
from galaxy.web.framework.helpers import time_ago
+ is_admin = trans.user_is_admin()
is_new = repository.is_new
can_browse_contents = not is_new
- can_manage = trans.user == repository.user
+ can_manage = is_admin or trans.user == repository.user
can_push = trans.app.security_agent.can_push( trans.user, repository )
can_rate = trans.user and repository.user != trans.user
can_upload = can_push
--- a/templates/webapps/community/repository/view_changeset.mako Fri Jul 08 09:09:02 2011 -0400
+++ b/templates/webapps/community/repository/view_changeset.mako Fri Jul 08 16:11:28 2011 -0400
@@ -5,10 +5,11 @@
<%
from galaxy.web.framework.helpers import time_ago
+ is_admin = trans.user_is_admin()
is_new = repository.is_new
can_browse_contents = not is_new
can_rate = trans.user and repository.user != trans.user
- can_manage = trans.user == repository.user
+ can_manage = is_admin or trans.user == repository.user
can_push = trans.app.security_agent.can_push( trans.user, repository )
can_view_change_log = not is_new
can_upload = can_push
--- a/templates/webapps/community/repository/view_repository.mako Fri Jul 08 09:09:02 2011 -0400
+++ b/templates/webapps/community/repository/view_repository.mako Fri Jul 08 16:11:28 2011 -0400
@@ -120,9 +120,9 @@
<div class="form-row"><label>Version:</label>
%if can_view_change_log:
- <a href="${h.url_for( controller='repository', action='view_changelog', id=trans.app.security.encode_id( repository.id ) )}">${tip}</a>
+ <a href="${h.url_for( controller='repository', action='view_changelog', id=trans.app.security.encode_id( repository.id ) )}">${repository.version}</a>
%else:
- ${tip}
+ ${repository.version}
%endif
</div><div class="form-row">
@@ -145,6 +145,30 @@
%endif
</div></div>
+%if metadata:
+ <p/>
+ <div class="toolForm">
+ <div class="toolFormTitle">Repository metadata</div>
+ <div class="toolFormBody">
+ %if 'tools' in metadata:
+ <div class="form-row">
+ <label>Tools:</label>
+ <% tool_dicts = metadata[ 'tools' ] %>
+ <table class="grid">
+ %for tool_dict in tool_dicts:
+ <tr>
+ <td><a href="${h.url_for( controller='repository', action='display_tool', repository_id=trans.security.encode_id( repository.id ), tool_config=tool_dict[ 'tool_config' ] )}">${tool_dict[ 'name' ]}</a></td>
+ <td>${tool_dict[ 'description' ]}</td>
+ <td>version: ${tool_dict[ 'version' ]}</td>
+ </tr>
+ %endfor
+ </table>
+ </div>
+ <div style="clear: both"></div>
+ %endif
+ </div>
+ </div>
+%endif
%if trans.user and trans.app.config.smtp_server:
<p/><div class="toolForm">
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: Fix a bug when setting default history permissions in the user preferences; receiving method now gets all required params.
by Bitbucket 08 Jul '11
by Bitbucket 08 Jul '11
08 Jul '11
1 new changeset in galaxy-central:
http://bitbucket.org/galaxy/galaxy-central/changeset/a787213d08e1/
changeset: a787213d08e1
user: greg
date: 2011-07-08 15:09:02
summary: Fix a bug when setting default history permissions in the user preferences; receiving method now gets all required params.
affected #: 2 files (470 bytes)
--- a/lib/galaxy/web/controllers/user.py Thu Jul 07 12:13:49 2011 -0400
+++ b/lib/galaxy/web/controllers/user.py Fri Jul 08 09:09:02 2011 -0400
@@ -914,6 +914,9 @@
@web.expose
def set_default_permissions( self, trans, cntrller, **kwd ):
"""Sets the user's default permissions for the new histories"""
+ params = util.Params( kwd )
+ message = util.restore_text( params.get( 'message', '' ) )
+ status = params.get( 'status', 'done' )
if trans.user:
if 'update_roles_button' in kwd:
p = util.Params( kwd )
@@ -926,8 +929,11 @@
action = trans.app.security_agent.get_action( v.action ).action
permissions[ action ] = in_roles
trans.app.security_agent.user_set_default_permissions( trans.user, permissions )
- return trans.show_ok_message( 'Default new history permissions have been changed.' )
- return trans.fill_template( 'user/permissions.mako', cntrller=cntrller )
+ message = 'Default new history permissions have been changed.'
+ return trans.fill_template( 'user/permissions.mako',
+ cntrller=cntrller,
+ message=message,
+ status=status )
else:
# User not logged in, history group must be only public
return trans.show_error_message( "You must be logged in to change your default permitted actions." )
--- a/templates/user/permissions.mako Thu Jul 07 12:13:49 2011 -0400
+++ b/templates/user/permissions.mako Fri Jul 08 09:09:02 2011 -0400
@@ -1,6 +1,13 @@
<%inherit file="/base.mako"/>
+<%namespace file="/message.mako" import="render_msg" />
+<%namespace file="/dataset/security_common.mako" import="render_permission_form" />
+
<%def name="title()">Change Default Permissions on New Histories</%def>
-<%namespace file="/dataset/security_common.mako" import="render_permission_form" />
+
+%if message:
+ ${render_msg( message, status )}
+%endif
+
<br/><br/><ul class="manage-table-actions"><li>
@@ -8,5 +15,5 @@
</li></ul>
%if trans.user:
- ${render_permission_form( trans.user, trans.user.email, h.url_for(), trans.user.all_roles() )}
+ ${render_permission_form( trans.user, trans.user.email, h.url_for( controller='user', action='set_default_permissions', cntrller=cntrller ), trans.user.all_roles() )}
%endif
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: Update annotation profiler tool sample configuration file.
by Bitbucket 07 Jul '11
by Bitbucket 07 Jul '11
07 Jul '11
1 new changeset in galaxy-central:
http://bitbucket.org/galaxy/galaxy-central/changeset/4220f8a5c571/
changeset: 4220f8a5c571
user: dan
date: 2011-07-07 18:13:49
summary: Update annotation profiler tool sample configuration file.
affected #: 2 files (153 bytes)
--- a/tool-data/annotation_profiler_options.xml.sample Thu Jul 07 11:55:14 2011 -0400
+++ b/tool-data/annotation_profiler_options.xml.sample Thu Jul 07 12:13:49 2011 -0400
@@ -1,4 +1,4 @@
-<filter type="meta_key" name="dbkey" value="hg18">
+<filter type="data_meta" data_ref="input1" meta_key="dbkey" value="hg18"><options><option name="Mapping and Sequencing Tracks" value="group-map"><option name="STS Markers" value="stsMap"/>
--- a/tools/annotation_profiler/annotation_profiler_for_interval.py Thu Jul 07 11:55:14 2011 -0400
+++ b/tools/annotation_profiler/annotation_profiler_for_interval.py Thu Jul 07 12:13:49 2011 -0400
@@ -340,6 +340,8 @@
options, args = parser.parse_args()
+ assert os.path.isdir( options.path ), IOError( "Configuration error: Table directory is missing (%s)" % options.path )
+
#get profiler_info
profiler_info = parse_profiler_info( os.path.join( options.path, 'profiler_info.txt' ) )
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: Trackster: implement broad/wide incremental data fetching and add icons for data fetching.
by Bitbucket 07 Jul '11
by Bitbucket 07 Jul '11
07 Jul '11
1 new changeset in galaxy-central:
http://bitbucket.org/galaxy/galaxy-central/changeset/35c11787e690/
changeset: 35c11787e690
user: jgoecks
date: 2011-07-07 17:55:14
summary: Trackster: implement broad/wide incremental data fetching and add icons for data fetching.
affected #: 5 files (1.5 KB)
--- a/static/june_2007_style/blue/trackster.css Wed Jul 06 22:37:51 2011 -0400
+++ b/static/june_2007_style/blue/trackster.css Thu Jul 07 11:55:14 2011 -0400
@@ -51,3 +51,6 @@
.bookmark{background:white;border:solid #999 1px;border-right:none;margin:0.5em;margin-right:0;padding:0.5em;}
.bookmark .position{font-weight:bold;}
.delete-icon-container{float:right;}
+.icon{display:inline-block;width:16px;height:16px;}
+.icon.more-down{background:url('../images/fugue/arrow-transition-270-bw.png') no-repeat 0px 0px;}
+.icon.more-across{background:url('../images/fugue/arrow-transition-bw.png') no-repeat 0px 0px;}
--- a/static/june_2007_style/trackster.css.tmpl Wed Jul 06 22:37:51 2011 -0400
+++ b/static/june_2007_style/trackster.css.tmpl Thu Jul 07 11:55:14 2011 -0400
@@ -293,3 +293,16 @@
float:right;
}
+.icon {
+ display:inline-block;
+ width:16px;
+ height:16px;
+}
+.icon.more-down {
+ background:url('../images/fugue/arrow-transition-270-bw.png') no-repeat 0px 0px;
+}
+.icon.more-across{
+ background:url('../images/fugue/arrow-transition-bw.png') no-repeat 0px 0px;
+}
+
+
--- a/static/scripts/trackster.js Wed Jul 06 22:37:51 2011 -0400
+++ b/static/scripts/trackster.js Thu Jul 07 11:55:14 2011 -0400
@@ -172,7 +172,7 @@
// height of individual features within tracks. Feature height, then, should always be less
// than track height.
CHAR_HEIGHT_PX = 9, // FIXME: font size may not be static
- ERROR_PADDING = 18, // Padding at the top of tracks for error messages
+ ERROR_PADDING = 20, // Padding at the top of tracks for error messages
SUMMARY_TREE_TOP_PADDING = CHAR_HEIGHT_PX + 2,
// Maximum number of rows un a slotted track
MAX_FEATURE_DEPTH = 100,
@@ -369,13 +369,15 @@
//
// Set parameters based on request type.
//
+ var query_low = low;
if (req_type === this.DEEP_DATA_REQ) {
// Use same interval but set start_val to skip data that's already in cur_data.
$.extend(extra_params, {start_val: cur_data.data.length + 1});
}
else if (req_type === this.BROAD_DATA_REQ) {
- // Set low to be past the last feature returned.
- low = cur_data.data[cur_data.length-1][2] + 1;
+ // Set query low to be past the last feature returned so that an area of extreme feature depth
+ // is bypassed.
+ query_low = cur_data.data[cur_data.data.length - 1][2] + 1;
}
//
@@ -384,14 +386,19 @@
//
var
data_manager = this,
- new_data_request = this.load_data(low, high, resolution, extra_params)
+ new_data_request = this.load_data(query_low, high, resolution, extra_params)
new_data_available = $.Deferred();
// load_data sets cache to new_data_request, but use custom deferred object so that signal and data
// is all data, not just new data.
this.set_data(low, high, mode, new_data_available);
$.when(new_data_request).then(function(result) {
+ // Update data and message.
if (result.data) {
result.data = cur_data.data.concat(result.data);
+ if (result.message) {
+ // HACK: replace number in message with current data length. Works but is ugly.
+ result.message = result.message.replace(/[0-9]+/, result.data.length);
+ }
}
data_manager.set_data(low, high, mode, result);
new_data_available.resolve(result);
@@ -2209,18 +2216,29 @@
message_div = $("<div/>").addClass("tile-message").text(tile.message).
// -1 to account for border.
css({'height': ERROR_PADDING-1, 'width': tile.canvas.width}).appendTo(container_div),
- show_more_data_btn = $("<div/>").text("Show more").addClass("action-button").css({'padding-top': 0, 'padding-bottom':0}).appendTo(message_div);
+ more_down_icon = $("<a href='javascript:void(0);'/>").addClass("icon more-down").appendTo(message_div),
+ more_across_icon = $("<a href='javascript:void(0);'/>").addClass("icon more-across").appendTo(message_div);
container_div.append(canvas);
tile_element = container_div;
- // Set up actions for button.
- show_more_data_btn.click(function() {
+ // Set up actions for icons.
+ more_down_icon.click(function() {
// Mark tile as stale, request more data, and redraw track.
tile.stale = true;
track.data_manager.get_more_data(tile.low, tile.high, tile.resolution, {}, track.data_manager.DEEP_DATA_REQ);
track.draw();
}).dblclick(function(e) {
- // Do not propogate as this would normal zoom in.
+ // Do not propogate as this would normally zoom in.
+ e.stopPropagation();
+ });
+
+ more_across_icon.click(function() {
+ // Mark tile as stale, request more data, and redraw track.
+ tile.stale = true;
+ track.data_manager.get_more_data(tile.low, tile.high, tile.resolution, {}, track.data_manager.BROAD_DATA_REQ);
+ track.draw();
+ }).dblclick(function(e) {
+ // Do not propogate as this would normally zoom in.
e.stopPropagation();
});
}
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

06 Jul '11
1 new changeset in galaxy-central:
http://bitbucket.org/galaxy/galaxy-central/changeset/84b20f29dfdf/
changeset: 84b20f29dfdf
user: kanwei
date: 2011-07-07 04:37:51
summary: Add tool version-string support to tool wrappers. Use the <version_string> tag to denote the command to run for the tool version, such as: tophat --version (see tophat wrapper change for example)
The tool version string will currently be appended to the Info string in the history dataset and you will be able to see it in the history pane, although this might be added to the database as well in the future.
affected #: 4 files (1.1 KB)
--- a/lib/galaxy/jobs/__init__.py Thu Jul 07 10:04:20 2011 +1000
+++ b/lib/galaxy/jobs/__init__.py Wed Jul 06 22:37:51 2011 -0400
@@ -271,7 +271,7 @@
class JobWrapper( object ):
"""
- Wraps a 'model.Job' with convience methods for running processes and
+ Wraps a 'model.Job' with convenience methods for running processes and
state management.
"""
def __init__( self, job, queue ):
@@ -284,6 +284,9 @@
self.sa_session = self.app.model.context
self.extra_filenames = []
self.command_line = None
+ # Tool versioning variables
+ self.version_string_cmd = None
+ self.version_string = ""
self.galaxy_lib_dir = None
# With job outputs in the working directory, we need the working
# directory to be set before prepare is run, or else premature deletion
@@ -311,6 +314,9 @@
param_dict = self.tool.params_from_strings( param_dict, self.app )
return param_dict
+ def get_version_string_path( self ):
+ return os.path.abspath(os.path.join(self.app.config.new_file_path, "GALAXY_VERSION_STRING_%s" % self.job_id))
+
def prepare( self ):
"""
Prepare the job to run by creating the working directory and the
@@ -389,6 +395,7 @@
extra_filenames.append( param_filename )
self.param_dict = param_dict
self.extra_filenames = extra_filenames
+ self.version_string_cmd = self.tool.version_string_cmd
return extra_filenames
def fail( self, message, exception=False ):
@@ -491,6 +498,12 @@
job.state = job.states.ERROR
else:
job.state = job.states.OK
+ if self.version_string_cmd:
+ version_filename = self.get_version_string_path()
+ if os.path.exists(version_filename):
+ self.version_string = "Tool version: %s" % open(version_filename).read()
+ os.unlink(version_filename)
+
if self.app.config.outputs_to_working_directory:
for dataset_path in self.get_output_fnames():
try:
@@ -541,7 +554,7 @@
dataset.blurb = 'done'
dataset.peek = 'no peek'
- dataset.info = context['stdout'] + context['stderr']
+ dataset.info = context['stdout'] + context['stderr'] + self.version_string
dataset.set_size()
if context['stderr']:
dataset.blurb = "error"
--- a/lib/galaxy/jobs/runners/__init__.py Thu Jul 07 10:04:20 2011 +1000
+++ b/lib/galaxy/jobs/runners/__init__.py Wed Jul 06 22:37:51 2011 -0400
@@ -1,10 +1,9 @@
import os, os.path
class BaseJobRunner( object ):
-
def build_command_line( self, job_wrapper, include_metadata=False ):
"""
- Compose the sequence of commands neccesary to execute a job. This will
+ Compose the sequence of commands necessary to execute a job. This will
currently include:
- environment settings corresponding to any requirement tags
- command line taken from job wrapper
@@ -15,9 +14,13 @@
# occur
if not commands:
return None
+ # Prepend version string
+ if job_wrapper.version_string_cmd:
+ commands = "%s &> %s; " % ( job_wrapper.version_string_cmd, job_wrapper.get_version_string_path() ) + commands
# Prepend dependency injection
if job_wrapper.dependency_shell_commands:
commands = "; ".join( job_wrapper.dependency_shell_commands + [ commands ] )
+
# Append metadata setting commands, we don't want to overwrite metadata
# that was copied over in init_meta(), as per established behavior
if include_metadata and self.app.config.set_metadata_externally:
--- a/lib/galaxy/tools/__init__.py Thu Jul 07 10:04:20 2011 +1000
+++ b/lib/galaxy/tools/__init__.py Wed Jul 06 22:37:51 2011 -0400
@@ -5,7 +5,7 @@
pkg_resources.require( "simplejson" )
-import logging, os, string, sys, tempfile, glob, shutil, types, urllib
+import logging, os, string, sys, tempfile, glob, shutil, types, urllib, subprocess
import simplejson
import binascii
from UserDict import DictMixin
@@ -395,6 +395,10 @@
self.redirect_url_params = ''
# Short description of the tool
self.description = util.xml_text(root, "description")
+ # Versioning for tools
+ self.version_string_cmd = None
+ if root.find("version_string") is not None:
+ self.version_string_cmd = root.find("version_string").text
# Parallelism for tasks, read from tool config.
parallelism = root.find("parallelism")
if parallelism is not None and parallelism.get("method"):
--- a/tools/ngs_rna/tophat_wrapper.xml Thu Jul 07 10:04:20 2011 +1000
+++ b/tools/ngs_rna/tophat_wrapper.xml Wed Jul 06 22:37:51 2011 -0400
@@ -1,5 +1,6 @@
<tool id="tophat" name="Tophat for Illumina" version="1.5.0"><description>Find splice junctions using RNA-seq data</description>
+ <version_string>tophat --version</version_string><requirements><requirement type="package">tophat</requirement></requirements>
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: fubar: More comprehensive error detection for weblogo installation or execution errors
by Bitbucket 06 Jul '11
by Bitbucket 06 Jul '11
06 Jul '11
1 new changeset in galaxy-central:
http://bitbucket.org/galaxy/galaxy-central/changeset/d271dfcdf482/
changeset: d271dfcdf482
user: fubar
date: 2011-07-07 02:04:20
summary: More comprehensive error detection for weblogo installation or execution errors
affected #: 2 files (431 bytes)
--- a/tools/rgenetics/rgWebLogo3.py Wed Jul 06 10:20:57 2011 -0400
+++ b/tools/rgenetics/rgWebLogo3.py Thu Jul 07 10:04:20 2011 +1000
@@ -43,6 +43,11 @@
tlf = open(templog,'w')
process = subprocess.Popen(cl, shell=True, stderr=tlf, stdout=tlf)
rval = process.wait()
+ if rval <> 0:
+ print >> sys.stderr, '## rgWebLogo3.py error - executing %s returned error code %d' % cl
+ print >> sys.stderr, '## This may be a data problem or a tool dependency (%s) installation problem' % WEBLOGO
+ print >> sys.stderr, '## Please ensure %s is correctly installed and working on the command line -see http://code.google.com/p/weblogo' % WEBLOGO
+ sys.exit(1)
tlf.close()
tlogs = ''.join(open(templog,'r').readlines())
if len(tlogs) > 1:
--- a/tools/rgenetics/rgWebLogo3.xml Wed Jul 06 10:20:57 2011 -0400
+++ b/tools/rgenetics/rgWebLogo3.xml Thu Jul 07 10:04:20 2011 +1000
@@ -1,4 +1,4 @@
-<tool id="rgweblogo3" name="Sequence Logo" version="0.3">
+<tool id="rgweblogo3" name="Sequence Logo" version="0.4"><description>generator for fasta (eg Clustal alignments)</description><command interpreter="python">
rgWebLogo3.py -F $outformat -s $size -i $input -o $output -t "$logoname" -c "$colours" -U "$units"
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: Trackster: implement start_val parameter for data providers and use parameter to provide incremental fetching of data. Only 'deep' fetching is currently supported.
by Bitbucket 06 Jul '11
by Bitbucket 06 Jul '11
06 Jul '11
1 new changeset in galaxy-central:
http://bitbucket.org/galaxy/galaxy-central/changeset/75eceb82013e/
changeset: 75eceb82013e
user: jgoecks
date: 2011-07-06 16:20:57
summary: Trackster: implement start_val parameter for data providers and use parameter to provide incremental fetching of data. Only 'deep' fetching is currently supported.
affected #: 4 files (1.4 KB)
--- a/lib/galaxy/visualization/tracks/data_providers.py Wed Jul 06 09:52:28 2011 -0400
+++ b/lib/galaxy/visualization/tracks/data_providers.py Wed Jul 06 10:20:57 2011 -0400
@@ -72,10 +72,11 @@
# Override.
pass
- def get_data( self, chrom, start, end, max_vals=None, **kwargs ):
+ def get_data( self, chrom, start, end, start_val=0, max_vals=None, **kwargs ):
"""
- Returns data in region defined by chrom, start, and end. If max_vals
- is set, returns at most max_vals.
+ Returns data in region defined by chrom, start, and end. start_val and
+ max_vals are used to denote the data to return: start_val is the first value to
+ return and max_vals indicates the number of values to return.
"""
# Override.
pass
@@ -215,7 +216,7 @@
# Cleanup.
bamfile.close()
- def get_data( self, chrom, start, end, max_vals=sys.maxint, **kwargs ):
+ def get_data( self, chrom, start, end, start_val=0, max_vals=sys.maxint, **kwargs ):
"""
Fetch reads in the region.
@@ -253,8 +254,10 @@
# Encode reads as list of lists.
results = []
paired_pending = {}
- for read in data:
- if len(results) > max_vals:
+ for count, read in enumerate( data ):
+ if count < start_val:
+ continue
+ if count-start_val >= max_vals:
message = ERROR_MAX_VALS % ( max_vals, "reads" )
break
qname = read.qname
@@ -319,7 +322,7 @@
f.close()
return all_dat is not None
- def get_data( self, chrom, start, end, max_vals=None, **kwargs ):
+ def get_data( self, chrom, start, end, start_val=0, max_vals=None, **kwargs ):
# Bigwig has the possibility of it being a standalone bigwig file, in which case we use
# original_dataset, or coming from wig->bigwig conversion in which we use converted_dataset
f, bbi = self._get_dataset()
@@ -481,11 +484,14 @@
return tabix.fetch(reference=chrom, start=start, end=end)
- def get_data( self, chrom, start, end, max_vals=None, **kwargs ):
+ def get_data( self, chrom, start, end, start_val=0, max_vals=None, **kwargs ):
iterator = self.get_iterator( chrom, start, end )
- return self.process_data( iterator, max_vals, **kwargs )
-
+ return self.process_data( iterator, start_val, max_vals, **kwargs )
+
class IntervalIndexDataProvider( FilterableMixin, TracksDataProvider ):
+ """
+ Interval index files used only for GFF files.
+ """
col_name_data_attr_mapping = { 4 : { 'index': 4 , 'name' : 'Score' } }
def write_data_to_file( self, chrom, start, end, filename ):
@@ -501,12 +507,11 @@
out.write(interval.raw_line + '\n')
out.close()
- def get_data( self, chrom, start, end, max_vals=sys.maxint, **kwargs ):
+ def get_data( self, chrom, start, end, start_val=0, max_vals=sys.maxint, **kwargs ):
start, end = int(start), int(end)
source = open( self.original_dataset.file_name )
index = Indexes( self.converted_dataset.file_name )
results = []
- count = 0
message = None
# If chrom is not found in indexes, try removing the first three
@@ -525,14 +530,15 @@
#
filter_cols = from_json_string( kwargs.get( "filter_cols", "[]" ) )
no_detail = ( "no_detail" in kwargs )
- for start, end, offset in index.find(chrom, start, end):
- if count >= max_vals:
+ for count, val in enumerate( index.find(chrom, start, end) ):
+ start, end, offset = val[0], val[1], val[2]
+ if count < start_val:
+ continue
+ if count-start_val >= max_vals:
message = ERROR_MAX_VALS % ( max_vals, "features" )
break
- count += 1
source.seek( offset )
# TODO: can we use column metadata to fill out payload?
- # TODO: use function to set payload data
# GFF dataset.
reader = GFFReaderWrapper( source, fix_strand=True )
@@ -549,7 +555,7 @@
Payload format: [ uid (offset), start, end, name, strand, thick_start, thick_end, blocks ]
"""
- def process_data( self, iterator, max_vals=sys.maxint, **kwargs ):
+ def process_data( self, iterator, start_val=0, max_vals=sys.maxint, **kwargs ):
#
# Build data to return. Payload format is:
# [ <guid/offset>, <start>, <end>, <name>, <score>, <strand>, <thick_start>,
@@ -559,14 +565,14 @@
#
filter_cols = from_json_string( kwargs.get( "filter_cols", "[]" ) )
no_detail = ( "no_detail" in kwargs )
- count = 0
rval = []
message = None
- for line in iterator:
- if count >= max_vals:
+ for count, line in enumerate( iterator ):
+ if count < start_val:
+ continue
+ if count-start_val >= max_vals:
message = ERROR_MAX_VALS % ( max_vals, "features" )
break
- count += 1
# TODO: can we use column metadata to fill out payload?
# TODO: use function to set payload data
@@ -625,16 +631,16 @@
col_name_data_attr_mapping = { 'Qual' : { 'index': 6 , 'name' : 'Qual' } }
- def process_data( self, iterator, max_vals=sys.maxint, **kwargs ):
+ def process_data( self, iterator, start_val=0, max_vals=sys.maxint, **kwargs ):
rval = []
- count = 0
message = None
- for line in iterator:
- if count >= max_vals:
+ for count, line in enumerate( iterator ):
+ if count < start_val:
+ continue
+ if count-start_val >= max_vals:
message = ERROR_MAX_VALS % ( "max_vals", "features" )
break
- count += 1
feature = line.split()
payload = [ hash(line), int(feature[1])-1, int(feature[1]),
@@ -657,22 +663,23 @@
NOTE: this data provider does not use indices, and hence will be very slow
for large datasets.
"""
- def get_data( self, chrom, start, end, max_vals=sys.maxint, **kwargs ):
+ def get_data( self, chrom, start, end, start_val=0, max_vals=sys.maxint, **kwargs ):
start, end = int( start ), int( end )
source = open( self.original_dataset.file_name )
results = []
- count = 0
message = None
offset = 0
- for feature in GFFReaderWrapper( source, fix_strand=True ):
+ for count, feature in enumerate( GFFReaderWrapper( source, fix_strand=True ) ):
+ if count < start_val:
+ continue
+ if count-start_val >= max_vals:
+ message = ERROR_MAX_VALS % ( max_vals, "reads" )
+ break
+
feature_start, feature_end = convert_gff_coords_to_bed( [ feature.start, feature.end ] )
if feature.chrom != chrom or feature_start < start or feature_end > end:
continue
- if count >= max_vals:
- message = ERROR_MAX_VALS % ( max_vals, "features" )
- break
- count += 1
payload = package_gff_feature( feature )
payload.insert( 0, offset )
results.append( payload )
--- a/lib/galaxy/web/controllers/tracks.py Wed Jul 06 09:52:28 2011 -0400
+++ b/lib/galaxy/web/controllers/tracks.py Wed Jul 06 10:20:57 2011 -0400
@@ -469,7 +469,7 @@
return { "status": messages.DATA, "valid_chroms": valid_chroms }
@web.json
- def data( self, trans, hda_ldda, dataset_id, chrom, low, high, max_vals=5000, **kwargs ):
+ def data( self, trans, hda_ldda, dataset_id, chrom, low, high, start_val=0, max_vals=5000, **kwargs ):
"""
Provides a block of data from a dataset.
"""
@@ -526,7 +526,7 @@
data_provider = data_provider_class( converted_dataset=converted_dataset, original_dataset=dataset, dependencies=deps )
# Get and return data from data_provider.
- data = data_provider.get_data( chrom, low, high, max_vals, **kwargs )
+ data = data_provider.get_data( chrom, low, high, int(start_val), int(max_vals), **kwargs )
message = None
if isinstance(data, dict) and 'message' in data:
message = data['message']
--- a/static/scripts/packed/trackster.js Wed Jul 06 09:52:28 2011 -0400
+++ b/static/scripts/packed/trackster.js Wed Jul 06 10:20:57 2011 -0400
@@ -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 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 trackster_module=function(f,T){var n=f("class").extend,p=f("slotting"),I=f("painters");var Z=function(aa,ab){this.document=aa;this.default_font=ab!==undefined?ab:"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")};n(Z.prototype,{load_pattern:function(aa,ae){var ab=this.patterns,ac=this.dummy_context,ad=new Image();ad.src=image_path+ae;ad.onload=function(){ab[aa]=ac.createPattern(ad,"repeat")}},get_pattern:function(aa){return this.patterns[aa]},new_canvas:function(){var aa=this.document.createElement("canvas");if(window.G_vmlCanvasManager){G_vmlCanvasManager.initElement(aa)}aa.manager=this;return aa}});var C=function(aa,ab){aa.bind("drag",{handle:ab,relative:true},function(af,ag){var ae=$(this).parent();var ad=ae.children();var ac;for(ac=0;ac<ad.length;ac++){if(ag.offsetY<$(ad.get(ac)).position().top){break}}if(ac===ad.length){if(this!==ad.get(ac-1)){ae.append(this)}}else{if(this!==ad.get(ac)){$(this).insertBefore(ad.get(ac))}}}).bind("dragstart",function(){$(this).css({"border-top":"1px solid blue","border-bottom":"1px solid blue"})}).bind("dragend",function(){$(this).css("border","0px")})};T.sortable=C;var D=9,A=18,O=D+2,w=100,F=12000,M=200,z=5,s=10,H=5000,t=100,m="There was an error in indexing this dataset. ",G="A converter for this dataset is not installed. Please check your datatypes_conf.xml file.",B="No data for this chrom/contig.",q="Currently indexing... please wait",v="Tool cannot be rerun: ",a="Loading data...",U="Ready for display",d=10,r=5,y=5;function u(aa){return Math.round(aa*1000)/1000}var c=function(aa){this.num_elements=aa;this.clear()};n(c.prototype,{get:function(ab){var aa=this.key_ary.indexOf(ab);if(aa!==-1){if(this.obj_cache[ab].stale){this.key_ary.splice(aa,1);delete this.obj_cache[ab]}else{this.move_key_to_end(ab,aa)}}return this.obj_cache[ab]},set:function(ab,ac){if(!this.obj_cache[ab]){if(this.key_ary.length>=this.num_elements){var aa=this.key_ary.shift();delete this.obj_cache[aa]}this.key_ary.push(ab)}this.obj_cache[ab]=ac;return ac},move_key_to_end:function(ab,aa){this.key_ary.splice(aa,1);this.key_ary.push(ab)},clear:function(){this.obj_cache={};this.key_ary=[]},size:function(){return this.key_ary.length}});var N=function(ab,aa,ac){c.call(this,ab);this.track=aa;this.subset=(ac!==undefined?ac:true)};n(N.prototype,c.prototype,{load_data:function(ai,aj,ae,ah,ab,ag){var ad={chrom:ai,low:aj,high:ae,mode:ah,resolution:ab,dataset_id:this.track.dataset_id,hda_ldda:this.track.hda_ldda};$.extend(ad,ag);if(this.track.filters_manager){var ak=[];var aa=this.track.filters_manager.filters;for(var af=0;af<aa.length;af++){ak[ak.length]=aa[af].name}ad.filter_cols=JSON.stringify(ak)}var ac=this;return $.getJSON(this.track.data_url,ad,function(al){ac.set_data(aj,ae,ah,al)})},get_data:function(ac,aa,af,ag,ab,ae){var ad=this.get(this.gen_key(aa,af,ag));if(ad){return ad}ad=this.load_data(ac,aa,af,ag,ab,ae);this.set_data(aa,af,ag,ad);return ad},set_data:function(ab,ac,ad,aa){return this.set(this.gen_key(ab,ac,ad),aa)},gen_key:function(aa,ac,ad){var ab=aa+"_"+ac+"_"+ad;return ab},split_key:function(aa){return aa.split("_")}});var E=function(ab,aa,ac){N.call(this,ab,aa,ac)};n(E.prototype,N.prototype,c.prototype,{load_data:function(ac,aa,ae,af,ab,ad){if(ab>1){return}return N.prototype.load_data.call(this,ac,aa,ae,af,ab,ad)}});var Y=function(aa,ad,ac,ab,ae){this.container=aa;this.chrom=null;this.vis_id=ac;this.dbkey=ab;this.title=ad;this.tracks=[];this.label_tracks=[];this.max_low=0;this.max_high=0;this.num_tracks=0;this.track_id_counter=0;this.zoom_factor=3;this.min_separation=30;this.has_changes=false;this.init(ae);this.canvas_manager=new Z(aa.get(0).ownerDocument);this.reset()};n(Y.prototype,{init:function(ad){var ac=this.container,aa=this;this.top_container=$("<div/>").addClass("top-container").appendTo(ac);this.content_div=$("<div/>").addClass("content").css("position","relative").appendTo(ac);this.bottom_container=$("<div/>").addClass("bottom-container").appendTo(ac);this.top_labeltrack=$("<div/>").addClass("top-labeltrack").appendTo(this.top_container);this.viewport_container=$("<div/>").addClass("viewport-container").addClass("viewport-container").appendTo(this.content_div);this.intro_div=$("<div/>").addClass("intro").text("Select a chrom from the dropdown below").hide();this.nav_labeltrack=$("<div/>").addClass("nav-labeltrack").appendTo(this.bottom_container);this.nav_container=$("<div/>").addClass("nav-container").prependTo(this.top_container);this.nav=$("<div/>").addClass("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 href='javascript:void(0);'>Close Overview</a>").addClass("overview-close").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 ab=function(ae){if(ae.type==="focusout"||(ae.keyCode||ae.which)===13||(ae.keyCode||ae.which)===27){if((ae.keyCode||ae.which)!==27){aa.go_to($(this).val())}$(this).hide();$(this).val("");aa.location_span.show();aa.chrom_select.show()}};this.nav_input=$("<input/>").addClass("nav-input").hide().bind("keyup focusout",ab).appendTo(this.nav_controls);this.location_span=$("<span/>").addClass("location").appendTo(this.nav_controls);this.location_span.bind("click",function(){aa.location_span.hide();aa.chrom_select.hide();aa.nav_input.val(aa.chrom+":"+aa.low+"-"+aa.high);aa.nav_input.css("display","inline-block");aa.nav_input.select();aa.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 id='zoom-out' />").click(function(){aa.zoom_out();aa.redraw()}).appendTo(this.nav_controls);this.zi_link=$("<a id='zoom-in' />").click(function(){aa.zoom_in();aa.redraw()}).appendTo(this.nav_controls);this.load_chroms({low:0},ad);this.chrom_select.bind("change",function(){aa.change_chrom(aa.chrom_select.val())});this.intro_div.show();this.content_div.bind("click",function(ae){$(this).find("input").trigger("blur")});this.content_div.bind("dblclick",function(ae){aa.zoom_in(ae.pageX,this.viewport_container)});this.overview_box.bind("dragstart",function(ae,af){this.current_x=af.offsetX}).bind("drag",function(ae,ag){var ah=ag.offsetX-this.current_x;this.current_x=ag.offsetX;var af=Math.round(ah/aa.viewport_container.width()*(aa.max_high-aa.max_low));aa.move_delta(-af)});this.overview_close.bind("click",function(){for(var af=0,ae=aa.tracks.length;af<ae;af++){aa.tracks[af].is_overview=false}$(this).siblings().filter("canvas").remove();$(this).parent().css("height",aa.overview_box.height());aa.overview_highlight.hide();$(this).hide()});this.viewport_container.bind("draginit",function(ae,af){if(ae.clientX>aa.viewport_container.width()-16){return false}}).bind("dragstart",function(ae,af){af.original_low=aa.low;af.current_height=ae.clientY;af.current_x=af.offsetX}).bind("drag",function(ag,ai){var ae=$(this);var aj=ai.offsetX-ai.current_x;var af=ae.scrollTop()-(ag.clientY-ai.current_height);ae.scrollTop(af);ai.current_height=ag.clientY;ai.current_x=ai.offsetX;var ah=Math.round(aj/aa.viewport_container.width()*(aa.high-aa.low));aa.move_delta(ah)}).bind("mousewheel",function(ag,ai,af,ae){if(af){var ah=Math.round(-af/aa.viewport_container.width()*(aa.high-aa.low));aa.move_delta(ah)}});this.top_labeltrack.bind("dragstart",function(ae,af){return $("<div />").css({height:aa.content_div.height()+aa.top_labeltrack.height()+aa.nav_labeltrack.height()+1,top:"0px",position:"absolute","background-color":"#ccf",opacity:0.5,"z-index":1000}).appendTo($(this))}).bind("drag",function(ai,aj){$(aj.proxy).css({left:Math.min(ai.pageX,aj.startX),width:Math.abs(ai.pageX-aj.startX)});var af=Math.min(ai.pageX,aj.startX)-aa.container.offset().left,ae=Math.max(ai.pageX,aj.startX)-aa.container.offset().left,ah=(aa.high-aa.low),ag=aa.viewport_container.width();aa.update_location(Math.round(af/ag*ah)+aa.low,Math.round(ae/ag*ah)+aa.low)}).bind("dragend",function(aj,ak){var af=Math.min(aj.pageX,ak.startX),ae=Math.max(aj.pageX,ak.startX),ah=(aa.high-aa.low),ag=aa.viewport_container.width(),ai=aa.low;aa.low=Math.round(af/ag*ah)+ai;aa.high=Math.round(ae/ag*ah)+ai;$(ak.proxy).remove();aa.redraw()});this.add_label_track(new X(this,this.top_labeltrack));this.add_label_track(new X(this,this.nav_labeltrack));$(window).bind("resize",function(){aa.resize_window()});$(document).bind("redraw",function(){aa.redraw()});this.reset();$(window).trigger("resize")},update_location:function(aa,ab){this.location_span.text(commatize(aa)+" - "+commatize(ab));this.nav_input.val(this.chrom+":"+commatize(aa)+"-"+commatize(ab))},load_chroms:function(ab,ac){ab.num=t;$.extend(ab,(this.vis_id!==undefined?{vis_id:this.vis_id}:{dbkey:this.dbkey}));var aa=this;$.ajax({url:chrom_url,data:ab,dataType:"json",success:function(ae){if(ae.chrom_info.length===0){alert("Invalid chromosome: "+ab.chrom);return}if(ae.reference){aa.add_label_track(new x(aa))}aa.chrom_data=ae.chrom_info;var ah='<option value="">Select Chrom/Contig</option>';for(var ag=0,ad=aa.chrom_data.length;ag<ad;ag++){var af=aa.chrom_data[ag].chrom;ah+='<option value="'+af+'">'+af+"</option>"}if(ae.prev_chroms){ah+='<option value="previous">Previous '+t+"</option>"}if(ae.next_chroms){ah+='<option value="next">Next '+t+"</option>"}aa.chrom_select.html(ah);if(ac){ac()}aa.chrom_start_index=ae.start_index},error:function(){alert("Could not load chroms for this dbkey:",aa.dbkey)}})},change_chrom:function(ae,ab,ag){if(!ae||ae==="None"){return}var ad=this;if(ae==="previous"){ad.load_chroms({low:this.chrom_start_index-t});return}if(ae==="next"){ad.load_chroms({low:this.chrom_start_index+t});return}var af=$.grep(ad.chrom_data,function(ai,aj){return ai.chrom===ae})[0];if(af===undefined){ad.load_chroms({chrom:ae},function(){ad.change_chrom(ae,ab,ag)});return}else{if(ae!==ad.chrom){ad.chrom=ae;if(!ad.chrom){ad.intro_div.show()}else{ad.intro_div.hide()}ad.chrom_select.val(ad.chrom);ad.max_high=af.len-1;ad.reset();ad.redraw(true);for(var ah=0,aa=ad.tracks.length;ah<aa;ah++){var ac=ad.tracks[ah];if(ac.init){ac.init()}}}if(ab!==undefined&&ag!==undefined){ad.low=Math.max(ab,0);ad.high=Math.min(ag,ad.max_high)}ad.reset_overview();ad.redraw()}},go_to:function(ae){var ai=this,aa,ad,ab=ae.split(":"),ag=ab[0],ah=ab[1];if(ah!==undefined){try{var af=ah.split("-");aa=parseInt(af[0].replace(/,/g,""),10);ad=parseInt(af[1].replace(/,/g,""),10)}catch(ac){return false}}ai.change_chrom(ag,aa,ad)},move_fraction:function(ac){var aa=this;var ab=aa.high-aa.low;this.move_delta(ac*ab)},move_delta:function(ac){var aa=this;var ab=aa.high-aa.low;if(aa.low-ac<aa.max_low){aa.low=aa.max_low;aa.high=aa.max_low+ab}else{if(aa.high-ac>aa.max_high){aa.high=aa.max_high;aa.low=aa.max_high-ab}else{aa.high-=ac;aa.low-=ac}}aa.redraw()},add_track:function(aa){aa.view=this;aa.track_id=this.track_id_counter;this.tracks.push(aa);if(aa.init){aa.init()}aa.container_div.attr("id","track_"+aa.track_id);C(aa.container_div,".draghandle");this.track_id_counter+=1;this.num_tracks+=1},add_label_track:function(aa){aa.view=this;this.label_tracks.push(aa)},remove_track:function(aa){this.has_changes=true;aa.container_div.fadeOut("slow",function(){$(this).remove()});delete this.tracks[this.tracks.indexOf(aa)];this.num_tracks-=1},reset:function(){this.low=this.max_low;this.high=this.max_high;this.viewport_container.find(".yaxislabel").remove()},redraw:function(ah){var ag=this.high-this.low,af=this.low,ab=this.high;if(af<this.max_low){af=this.max_low}if(ab>this.max_high){ab=this.max_high}if(this.high!==0&&ag<this.min_separation){ab=af+this.min_separation}this.low=Math.floor(af);this.high=Math.ceil(ab);this.resolution=Math.pow(z,Math.ceil(Math.log((this.high-this.low)/M)/Math.log(z)));this.zoom_res=Math.pow(s,Math.max(0,Math.ceil(Math.log(this.resolution,s)/Math.log(s))));var aa=(this.low/(this.max_high-this.max_low)*this.overview_viewport.width())||0;var ae=((this.high-this.low)/(this.max_high-this.max_low)*this.overview_viewport.width())||0;var ai=13;this.overview_box.css({left:aa,width:Math.max(ai,ae)}).show();if(ae<ai){this.overview_box.css("left",aa-(ai-ae)/2)}if(this.overview_highlight){this.overview_highlight.css({left:aa,width:ae})}this.update_location(this.low,this.high);if(!ah){for(var ac=0,ad=this.tracks.length;ac<ad;ac++){if(this.tracks[ac]&&this.tracks[ac].enabled){this.tracks[ac].draw()}}for(ac=0,ad=this.label_tracks.length;ac<ad;ac++){this.label_tracks[ac].draw()}}},zoom_in:function(ab,ac){if(this.max_high===0||this.high-this.low<this.min_separation){return}var ad=this.high-this.low,ae=ad/2+this.low,aa=(ad/this.zoom_factor)/2;if(ab){ae=ab/this.viewport_container.width()*(this.high-this.low)+this.low}this.low=Math.round(ae-aa);this.high=Math.round(ae+aa);this.redraw()},zoom_out:function(){if(this.max_high===0){return}var ab=this.high-this.low,ac=ab/2+this.low,aa=(ab*this.zoom_factor)/2;this.low=Math.round(ac-aa);this.high=Math.round(ac+aa);this.redraw()},resize_window:function(){this.viewport_container.height(this.container.height()-this.top_container.height()-this.bottom_container.height());this.nav_container.width(this.container.width());this.redraw()},reset_overview:function(){this.overview_viewport.find("canvas").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()}});var o=function(ac,ag){this.track=ac;this.name=ag.name;this.params=[];var an=ag.params;for(var ad=0;ad<an.length;ad++){var ai=an[ad],ab=ai.name,am=ai.label,ae=unescape(ai.html),ao=ai.value,ak=ai.type;if(ak==="number"){this.params[this.params.length]=new g(ab,am,ae,ao,ai.min,ai.max)}else{if(ak=="select"){this.params[this.params.length]=new K(ab,am,ae,ao)}else{console.log("WARNING: unrecognized tool parameter type:",ab,ak)}}}this.parent_div=$("<div/>").addClass("dynamic-tool").hide();this.parent_div.bind("drag",function(aq){aq.stopPropagation()}).bind("click",function(aq){aq.stopPropagation()}).bind("dblclick",function(aq){aq.stopPropagation()});var al=$("<div class='tool-name'>").appendTo(this.parent_div).text(this.name);var aj=this.params;var ah=this;$.each(this.params,function(ar,av){var au=$("<div>").addClass("param-row").appendTo(ah.parent_div);var aq=$("<div>").addClass("param-label").text(av.label).appendTo(au);var at=$("<div/>").addClass("slider").html(av.html).appendTo(au);at.find(":input").val(av.value);$("<div style='clear: both;'/>").appendTo(au)});this.parent_div.find("input").click(function(){$(this).select()});var ap=$("<div>").addClass("param-row").appendTo(this.parent_div);var af=$("<input type='submit'>").attr("value","Run on complete dataset").appendTo(ap);var aa=$("<input type='submit'>").attr("value","Run on visible region").css("margin-left","3em").appendTo(ap);var ah=this;aa.click(function(){ah.run_on_region()});af.click(function(){ah.run_on_dataset()})};n(o.prototype,{get_param_values_dict:function(){var aa={};this.parent_div.find(":input").each(function(){var ab=$(this).attr("name"),ac=$(this).val();aa[ab]=JSON.stringify(ac)});return aa},get_param_values:function(){var ab=[];var aa={};this.parent_div.find(":input").each(function(){var ac=$(this).attr("name"),ad=$(this).val();if(ac){ab[ab.length]=ad}});return ab},run_on_dataset:function(){var aa=this;aa.run({dataset_id:this.track.original_dataset_id,tool_id:aa.name},function(ab){show_modal(aa.name+" is Running",aa.name+" is running on the complete dataset. Tool outputs are in dataset's history.",{Close:hide_modal})})},run_on_region:function(){var aa={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},ac=this.track,ab=aa.tool_id+ac.tool_region_and_parameters_str(aa.chrom,aa.low,aa.high),ad;if(ac instanceof e){ad=new Q(ab,view,ac.hda_ldda,undefined,{},{},ac);ad.change_mode(ac.mode)}this.track.add_track(ad);ad.content_div.text("Starting job.");this.run(aa,function(ae){ad.dataset_id=ae.dataset_id;ad.content_div.text("Running job.");ad.init()})},run:function(ab,ac){$.extend(ab,this.get_param_values_dict());var aa=function(){$.getJSON(rerun_tool_url,ab,function(ad){if(ad==="no converter"){new_track.container_div.addClass("error");new_track.content_div.text(G)}else{if(ad.error){new_track.container_div.addClass("error");new_track.content_div.text(v+ad.message)}else{if(ad==="pending"){new_track.container_div.addClass("pending");new_track.content_div.text("Converting input data so that it can be easily reused.");setTimeout(aa,2000)}else{ac(ad)}}}})};aa()}});var K=function(ab,aa,ac,ad){this.name=ab;this.label=aa;this.html=ac;this.value=ad};var g=function(ac,ab,ae,af,ad,aa){K.call(this,ac,ab,ae,af);this.min=ad;this.max=aa};var h=function(ab,aa,ac,ad){this.name=ab;this.index=aa;this.tool_id=ac;this.tool_exp_name=ad};var R=function(ab,aa,ac,ad){h.call(this,ab,aa,ac,ad);this.low=-Number.MAX_VALUE;this.high=Number.MAX_VALUE;this.min=Number.MAX_VALUE;this.max=-Number.MAX_VALUE;this.slider=null;this.slider_label=null};n(R.prototype,{applies_to:function(aa){if(aa.length>this.index){return true}return false},keep:function(aa){if(!this.applies_to(aa)){return true}var ab=parseInt(aa[this.index]);return(isNaN(ab)||(ab>=this.low&&ab<=this.high))},update_attrs:function(ab){var aa=false;if(!this.applies_to(ab)){return aa}if(ab[this.index]<this.min){this.min=Math.floor(ab[this.index]);aa=true}if(ab[this.index]>this.max){this.max=Math.ceil(ab[this.index]);aa=true}return aa},update_ui_elt:function(){var ac=function(af,ad){var ae=ad-af;return(ae<=2?0.01:1)};var ab=this.slider.slider("option","min"),aa=this.slider.slider("option","max");if(this.min<ab||this.max>aa){this.slider.slider("option","min",this.min);this.slider.slider("option","max",this.max);this.slider.slider("option","step",ac(this.min,this.max));this.slider.slider("option","values",[this.min,this.max])}}});var W=function(ac,al){this.track=ac;this.filters=[];for(var ag=0;ag<al.length;ag++){var aa=al[ag],ab=aa.name,ak=aa.type,ai=aa.index,an=aa.tool_id,ad=aa.tool_exp_name;if(ak==="int"||ak==="float"){this.filters[ag]=new R(ab,ai,an,ad)}else{console.log("ERROR: unsupported filter: ",ab,ak)}}var aj=function(ao,ap,aq){ao.click(function(){var ar=ap.text();max=parseFloat(aq.slider("option","max")),input_size=(max<=1?4:max<=1000000?max.toString().length:6),multi_value=false;if(aq.slider("option","values")){input_size=2*input_size+1;multi_value=true}ap.text("");$("<input type='text'/>").attr("size",input_size).attr("maxlength",input_size).attr("value",ar).appendTo(ap).focus().select().click(function(at){at.stopPropagation()}).blur(function(){$(this).remove();ap.text(ar)}).keyup(function(ax){if(ax.keyCode===27){$(this).trigger("blur")}else{if(ax.keyCode===13){var av=aq.slider("option","min"),at=aq.slider("option","max"),aw=function(ay){return(isNaN(ay)||ay>at||ay<av)},au=$(this).val();if(!multi_value){au=parseFloat(au);if(aw(au)){alert("Parameter value must be in the range ["+av+"-"+at+"]");return $(this)}}else{au=au.split("-");au=[parseFloat(au[0]),parseFloat(au[1])];if(aw(au[0])||aw(au[1])){alert("Parameter value must be in the range ["+av+"-"+at+"]");return $(this)}}aq.slider((multi_value?"values":"value"),au)}}})})};this.parent_div=$("<div/>").addClass("filters").hide();this.parent_div.bind("drag",function(ao){ao.stopPropagation()}).bind("click",function(ao){ao.stopPropagation()}).bind("dblclick",function(ao){ao.stopPropagation()}).bind("keydown",function(ao){ao.stopPropagation()});var ae=this;$.each(this.filters,function(av,ap){var ar=$("<div/>").addClass("slider-row").appendTo(ae.parent_div);var ao=$("<div/>").addClass("slider-label").appendTo(ar);var ax=$("<span/>").addClass("slider-name").text(ap.name+" ").appendTo(ao);var aq=$("<span/>");var at=$("<span/>").addClass("slider-value").appendTo(ao).append("[").append(aq).append("]");var aw=$("<div/>").addClass("slider").appendTo(ar);ap.control_element=$("<div/>").attr("id",ap.name+"-filter-control").appendTo(aw);var au=[0,0];ap.control_element.slider({range:true,min:Number.MAX_VALUE,max:-Number.MIN_VALUE,values:[0,0],slide:function(ay,az){au=az.values;aq.text(az.values[0]+"-"+az.values[1]);setTimeout(function(){if(az.values[0]==au[0]&&az.values[1]==au[1]){var aA=az.values;aq.text(aA[0]+"-"+aA[1]);ap.low=aA[0];ap.high=aA[1];ae.track.draw(true,true)}},50)},change:function(ay,az){ap.control_element.slider("option","slide").call(ap.control_element,ay,az)}});ap.slider=ap.control_element;ap.slider_label=aq;aj(at,aq,ap.control_element);$("<div style='clear: both;'/>").appendTo(ar)});if(this.filters.length!=0){var am=$("<div>").addClass("param-row").appendTo(this.parent_div);var ah=$("<input type='submit'>").attr("value","Run on complete dataset").appendTo(am);var af=this;ah.click(function(){af.run_on_dataset()})}};n(W.prototype,{reset_filters:function(){for(var aa=0;aa<this.filters.length;aa++){filter=this.filters[aa];filter.slider.slider("option","values",[filter.min,filter.max])}},run_on_dataset:function(){var ai=function(am,ak,al){if(!(ak in am)){am[ak]=al}return am[ak]};var ac={},aa,ab,ad;for(var ae=0;ae<this.filters.length;ae++){aa=this.filters[ae];if(aa.tool_id){if(aa.min!=aa.low){ab=ai(ac,aa.tool_id,[]);ab[ab.length]=aa.tool_exp_name+" >= "+aa.low}if(aa.max!=aa.high){ab=ai(ac,aa.tool_id,[]);ab[ab.length]=aa.tool_exp_name+" <= "+aa.high}}}var ag=[];for(var aj in ac){ag[ag.length]=[aj,ac[aj]]}var ah=ag.length;(function af(aq,an){var al=an[0],am=al[0],ap=al[1],ao="("+ap.join(") and (")+")",ak={cond:ao,input:aq,target_dataset_id:aq,tool_id:am},an=an.slice(1);$.getJSON(run_tool_url,ak,function(ar){if(ar.error){show_modal("Filter Dataset","Error running tool "+am,{Close:hide_modal})}else{if(an.length===0){show_modal("Filtering Dataset","Filter(s) are running on the complete dataset. Outputs are in dataset's history.",{Close:hide_modal})}else{af(ar.dataset_id,an)}}})})(this.track.dataset_id,ag)}});var V=function(aa){this.track=aa.track;this.params=aa.params;this.values={};if(aa.saved_values){this.restore_values(aa.saved_values)}this.onchange=aa.onchange};n(V.prototype,{restore_values:function(aa){var ab=this;$.each(this.params,function(ac,ad){if(aa[ad.key]!==undefined){ab.values[ad.key]=aa[ad.key]}else{ab.values[ad.key]=ad.default_value}})},build_form:function(){var ab=this;var aa=$("<div />");$.each(this.params,function(af,ad){if(!ad.hidden){var ac="param_"+af;var ak=$("<div class='form-row' />").appendTo(aa);ak.append($("<label />").attr("for",ac).text(ad.label+":"));if(ad.type==="bool"){ak.append($('<input type="checkbox" />').attr("id",ac).attr("name",ac).attr("checked",ab.values[ad.key]))}else{if(ad.type==="color"){var ah=ab.values[ad.key];var ag=$("<input />").attr("id",ac).attr("name",ac).val(ah);var ai=$("<div class='tipsy tipsy-north' style='position: absolute;' />").hide();var ae=$("<div style='background-color: black; padding: 10px;'></div>").appendTo(ai);var aj=$("<div/>").appendTo(ae).farbtastic({width:100,height:100,callback:ag,color:ah});$("<div />").append(ag).append(ai).appendTo(ak).bind("click",function(al){ai.css({left:$(this).position().left+($(ag).width()/2)-60,top:$(this).position().top+$(this.height)}).show();$(document).bind("click.color-picker",function(){ai.hide();$(document).unbind("click.color-picker")});al.stopPropagation()})}else{ak.append($("<input />").attr("id",ac).attr("name",ac).val(ab.values[ad.key]))}}}});return aa},update_from_form:function(aa){var ac=this;var ab=false;$.each(this.params,function(ad,af){if(!af.hidden){var ag="param_"+ad;var ae=aa.find("#"+ag).val();if(af.type==="float"){ae=parseFloat(ae)}else{if(af.type==="int"){ae=parseInt(ae)}else{if(af.type==="bool"){ae=aa.find("#"+ag).is(":checked")}}}if(ae!==ac.values[af.key]){ac.values[af.key]=ae;ab=true}}});if(ab){this.onchange()}}});var b=function(ac,ab,aa){this.index=ac;this.resolution=ab;this.canvas=$("<div class='track-tile'/>").append(aa);this.stale=false};var l=function(ac,ab,aa,ad){b.call(this,ac,ab,aa);this.max_val=ad};var L=function(ac,ab,aa,ad){b.call(this,ac,ab,aa);this.message=ad};var j=function(ab,aa,ae,ac,ad){this.name=ab;this.view=aa;this.parent_element=ae;this.data_url=(ac?ac:default_data_url);this.data_url_extra_params={};this.data_query_wait=(ad?ad:H);this.dataset_check_url=converted_datasets_state_url;this.container_div=$("<div />").addClass("track").css("position","relative");if(!this.hidden){this.header_div=$("<div class='track-header' />").appendTo(this.container_div);if(this.view.editor){this.drag_div=$("<div class='draghandle' />").appendTo(this.header_div)}this.name_div=$("<div class='menubutton popup' />").appendTo(this.header_div);this.name_div.text(this.name);this.name_div.attr("id",this.name.replace(/\s+/g,"-").replace(/[^a-zA-Z0-9\-]/g,"").toLowerCase())}this.content_div=$("<div class='track-content'>").appendTo(this.container_div);this.parent_element.append(this.container_div)};n(j.prototype,{get_type:function(){if(this instanceof X){return"LabelTrack"}else{if(this instanceof x){return"ReferenceTrack"}else{if(this instanceof k){return"LineTrack"}else{if(this instanceof S){return"ReadTrack"}else{if(this instanceof Q){return"ToolDataFeatureTrack"}else{if(this instanceof P){return"VcfTrack"}else{if(this instanceof e){return"FeatureTrack"}}}}}}}return""},init:function(){var aa=this;aa.enabled=false;aa.tile_cache.clear();aa.data_cache.clear();aa.initial_canvas=undefined;aa.content_div.css("height","auto");aa.container_div.removeClass("nodata error pending");if(!aa.dataset_id){return}$.getJSON(converted_datasets_state_url,{hda_ldda:aa.hda_ldda,dataset_id:aa.dataset_id,chrom:aa.view.chrom},function(ab){if(!ab||ab==="error"||ab.kind==="error"){aa.container_div.addClass("error");aa.content_div.text(m);if(ab.message){var ad=aa.view.tracks.indexOf(aa);var ac=$(" <a href='javascript:void(0);'></a>").text("View error").bind("click",function(){show_modal("Trackster Error","<pre>"+ab.message+"</pre>",{Close:hide_modal})});aa.content_div.append(ac)}}else{if(ab==="no converter"){aa.container_div.addClass("error");aa.content_div.text(G)}else{if(ab==="no data"||(ab.data!==undefined&&(ab.data===null||ab.data.length===0))){aa.container_div.addClass("nodata");aa.content_div.text(B)}else{if(ab==="pending"){aa.container_div.addClass("pending");aa.content_div.text(q);setTimeout(function(){aa.init()},aa.data_query_wait)}else{if(ab.status==="data"){if(ab.valid_chroms){aa.valid_chroms=ab.valid_chroms;aa.make_name_popup_menu()}aa.content_div.text(U);if(aa.view.chrom){aa.content_div.text("");aa.content_div.css("height",aa.height_px+"px");aa.enabled=true;$.when(aa.predraw_init()).done(function(){aa.container_div.removeClass("nodata error pending");aa.draw()})}}}}}}})},predraw_init:function(){},update_name:function(aa){this.old_name=this.name;this.name=aa;this.name_div.text(this.name)},revert_name:function(){this.name=this.old_name;this.name_div.text(this.name)}});var J=function(ah,af,ai){var ab=this,aj=ab.view;this.filters_manager=(ah!==undefined?new W(this,ah):undefined);this.filters_available=false;this.filters_visible=false;this.tool=(af!==undefined&&obj_length(af)>0?new o(this,af):undefined);this.parent_track=ai;this.child_tracks=[];if(ab.hidden){return}if(this.parent_track){this.header_div.find(".draghandle").removeClass("draghandle").addClass("child-track-icon").addClass("icon-button");this.parent_element.addClass("child-track");this.tool=undefined}ab.child_tracks_container=$("<div/>").addClass("child-tracks-container").hide();ab.container_div.append(ab.child_tracks_container);if(this.filters_manager){this.filters_div=this.filters_manager.parent_div;this.header_div.after(this.filters_div)}if(this.tool){this.dynamic_tool_div=this.tool.parent_div;this.header_div.after(this.dynamic_tool_div)}if(ab.display_modes!==undefined){if(ab.mode_div===undefined){ab.mode_div=$("<div class='right-float menubutton popup' />").appendTo(ab.header_div);var ac=(ab.track_config&&ab.track_config.values.mode?ab.track_config.values.mode:ab.display_modes[0]);ab.mode=ac;ab.mode_div.text(ac);var aa={};for(var ad=0,ag=ab.display_modes.length;ad<ag;ad++){var ae=ab.display_modes[ad];aa[ae]=function(ak){return function(){ab.change_mode(ak)}}(ae)}make_popupmenu(ab.mode_div,aa)}else{ab.mode_div.hide()}}this.make_name_popup_menu()};n(J.prototype,j.prototype,{change_mode:function(ab){var aa=this;aa.mode_div.text(ab);aa.mode=ab;aa.track_config.values.mode=ab;aa.tile_cache.clear();aa.draw()},make_name_popup_menu:function(){var ab=this;var aa={};aa["Edit configuration"]=function(){var ah=function(){hide_modal();$(window).unbind("keypress.check_enter_esc")},af=function(){ab.track_config.update_from_form($(".dialog-box"));hide_modal();$(window).unbind("keypress.check_enter_esc")},ag=function(ai){if((ai.keyCode||ai.which)===27){ah()}else{if((ai.keyCode||ai.which)===13){af()}}};$(window).bind("keypress.check_enter_esc",ag);show_modal("Configure Track",ab.track_config.build_form(),{Cancel:ah,OK:af})};if(ab.filters_available>0){var ae=(ab.filters_div.is(":visible")?"Hide filters":"Show filters");aa[ae]=function(){ab.filters_visible=(ab.filters_div.is(":visible"));if(ab.filters_visible){ab.filters_manager.reset_filters()}ab.filters_div.toggle();ab.make_name_popup_menu()}}if(ab.tool){var ae=(ab.dynamic_tool_div.is(":visible")?"Hide tool":"Show tool");aa[ae]=function(){if(!ab.dynamic_tool_div.is(":visible")){ab.update_name(ab.name+ab.tool_region_and_parameters_str())}else{menu_option_text="Show dynamic tool";ab.revert_name()}ab.dynamic_tool_div.toggle();ab.make_name_popup_menu()}}if(ab.valid_chroms){aa["List chrom/contigs with data"]=function(){show_modal("Chrom/contigs with data","<p>"+ab.valid_chroms.join("<br/>")+"</p>",{Close:function(){hide_modal()}})}}var ac=view;var ad=function(){$("#no-tracks").show()};if(this.parent_track){ac=this.parent_track;ad=function(){}}aa.Remove=function(){ac.remove_track(ab);if(ac.num_tracks===0){ad()}};make_popupmenu(ab.name_div,aa)},draw:function(aa,ac){if(!this.dataset_id){return}var au=this.view.low,ag=this.view.high,ai=ag-au,ak=this.view.container.width(),ae=ak/ai,al=this.view.resolution,ad=$("<div style='position: relative;'></div>"),am=function(aw,ax,av){return aw+"_"+ax+"_"+av};if(!ac){this.content_div.children().remove()}this.content_div.append(ad);this.max_height=0;var ao=Math.floor(au/al/M);var af=[];var ap=0;while((ao*M*al)<ag){var at=am(ak,ae,ao);var ah=this.tile_cache.get(at);var aq=ao*M*this.view.resolution;var ab=aq+M*this.view.resolution;if(!aa&&ah){af[af.length]=ah;this.show_tile(ah,ad,aq,ab,ae)}else{this.delayed_draw(aa,at,ao,al,ad,ae,af)}ao+=1;ap++}var aj=this;var ar=setInterval(function(){if(af.length===ap){clearInterval(ar);if(ac){var aA=aj.content_div.children();var aB=false;for(var az=aA.length-1,aF=0;az>=aF;az--){var ay=$(aA[az]);if(aB){ay.remove()}else{if(ay.children().length!==0){aB=true}}}}if(aj instanceof e&&aj.mode=="Histogram"){var aE=-1;for(var az=0;az<af.length;az++){var aH=af[az].max_val;if(aH>aE){aE=aH}}for(var az=0;az<af.length;az++){if(af[az].max_val!==aE){var aG=af[az];aG.canvas.remove();aj.delayed_draw(true,am(ak,ae,aG.index),aG.index,aG.resolution,ad,ae,[],{max:aE})}}}if(aj.filters_manager){var ax=aj.filters_manager.filters;for(var aD=0;aD<ax.length;aD++){ax[aD].update_ui_elt()}var aC=false;if(aj.example_feature){for(var aD=0;aD<ax.length;aD++){if(ax[aD].applies_to(aj.example_feature)){aC=true;break}}}if(aj.filters_available!==aC){aj.filters_available=aC;if(!aj.filters_available){aj.filters_div.hide()}aj.make_name_popup_menu()}}var av=false;for(var aw=0;aw<af.length;aw++){if(af[aw].message){av=true;break}}if(av){for(var aw=0;aw<af.length;aw++){aG=af[aw];if(!aG.message){aG.canvas.css("padding-top",A)}}}}},50);for(var an=0;an<this.child_tracks.length;an++){this.child_tracks[an].draw(aa,ac)}},delayed_draw:function(ab,ai,ac,ae,aj,am,ak,af){var ad=this,ag=ac*M*ae,al=ag+M*ae;var ah=function(av,an,ap,ao,at,au,aq){var ar=ad.draw_tile(an,ap,ao,au,aq);ad.tile_cache.set(ai,ar);if(ar===undefined){return}ad.show_tile(ar,at,ag,al,au);ak[ak.length]=ar};var aa=setTimeout(function(){if(ag<=ad.view.high&&al>=ad.view.low){var an=(ab?undefined:ad.tile_cache.get(ai));if(an){ad.show_tile(an,aj,ag,al,am);ak[ak.length]=an}else{$.when(ad.data_cache.get_data(view.chrom,ag,al,ad.mode,ae,ad.data_url_extra_params)).then(function(ao){n(ao,af);if(view.reference_track&&am>view.canvas_manager.char_width_px){$.when(view.reference_track.data_cache.get_data(view.chrom,ag,al,ad.mode,ae,view.reference_track.data_url_extra_params)).then(function(ap){ah(aa,ao,ae,ac,aj,am,ap)})}else{ah(aa,ao,ae,ac,aj,am)}})}}},50)},show_tile:function(ah,aj,ae,ak,am){var ab=this,aa=ah.canvas,af=aa;if(ah.message){var al=$("<div/>"),ai=$("<div/>").addClass("tile-message").text(ah.message).css({height:A-1,width:ah.canvas.width}).appendTo(al),ag=$("<button/>").text("Show more").css("margin-left","0.5em").appendTo(ai);al.append(aa);af=al;ag.click(function(){var an=ab.data_cache.get_data(ab.view.chrom,ae,ak,ab.mode,ah.resolution);an.stale=true;ah.stale=true;ab.data_cache.get_data(ab.view.chrom,ae,ak,ab.mode,ah.resolution,{max_vals:an.data.length*2});ab.draw()}).dblclick(function(an){an.stopPropagation()})}var ad=this.view.high-this.view.low,ac=(ae-this.view.low)*am;if(this.left_offset){ac-=this.left_offset}af.css({position:"absolute",top:0,left:ac,height:""});aj.append(af);ab.max_height=Math.max(ab.max_height,af.height());ab.content_div.css("height",ab.max_height+"px");aj.children().css("height",ab.max_height+"px")},set_overview:function(){var aa=this.view;if(this.initial_canvas&&this.is_overview){aa.overview_close.show();aa.overview_viewport.append(this.initial_canvas);aa.overview_highlight.show().height(this.initial_canvas.height());aa.overview_viewport.height(this.initial_canvas.height()+aa.overview_box.height())}$(window).trigger("resize")},tool_region_and_parameters_str:function(ac,aa,ad){var ab=this,ae=(ac!==undefined&&aa!==undefined&&ad!==undefined?ac+":"+aa+"-"+ad:"all");return" - region=["+ae+"], parameters=["+ab.tool.get_param_values().join(", ")+"]"},add_track:function(aa){aa.track_id=this.track_id+"_"+this.child_tracks.length;aa.container_div.attr("id","track_"+aa.track_id);this.child_tracks_container.append(aa.container_div);C(aa.container_div,".child-track-icon");if(!$(this.child_tracks_container).is(":visible")){this.child_tracks_container.show()}this.child_tracks.push(aa);this.view.has_changes=true},remove_track:function(aa){aa.container_div.fadeOut("slow",function(){$(this).remove()})}});var X=function(aa,ab){this.hidden=true;j.call(this,null,aa,ab);this.container_div.addClass("label-track")};n(X.prototype,j.prototype,{draw:function(){var ac=this.view,ad=ac.high-ac.low,ag=Math.floor(Math.pow(10,Math.floor(Math.log(ad)/Math.log(10)))),aa=Math.floor(ac.low/ag)*ag,ae=this.view.container.width(),ab=$("<div style='position: relative; height: 1.3em;'></div>");while(aa<ac.high){var af=(aa-ac.low)/ad*ae;ab.append($("<div class='label'>"+commatize(aa)+"</div>").css({position:"absolute",left:af-1}));aa+=ag}this.content_div.children(":first").remove();this.content_div.append(ab)}});var x=function(aa){this.hidden=true;j.call(this,null,aa,aa.top_labeltrack);J.call(this);aa.reference_track=this;this.left_offset=200;this.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:aa.dbkey};this.data_cache=new E(y,this,false);this.tile_cache=new c(r)};n(x.prototype,J.prototype,{draw_tile:function(ai,af,ab,ak){var ae=this,ac=M*af;if(ak>this.view.canvas_manager.char_width_px){if(ai===null){ae.content_div.css("height","0px");return}var ad=this.view.canvas_manager.new_canvas();var aj=ad.getContext("2d");ad.width=Math.ceil(ac*ak+ae.left_offset);ad.height=ae.height_px;aj.font=aj.canvas.manager.default_font;aj.textAlign="center";for(var ag=0,ah=ai.length;ag<ah;ag++){var aa=Math.round(ag*ak);aj.fillText(ai[ag],aa+ae.left_offset,10)}return new b(ab,af,ad)}this.content_div.css("height","0px")}});var k=function(ae,ac,af,aa,ad){var ab=this;this.display_modes=["Histogram","Line","Filled","Intensity"];this.mode="Histogram";j.call(this,ae,ac,ac.viewport_container);J.call(this);this.min_height_px=16;this.max_height_px=400;this.height_px=80;this.hda_ldda=af;this.dataset_id=aa;this.original_dataset_id=aa;this.data_cache=new N(y,this);this.tile_cache=new c(r);this.track_config=new V({track:this,params:[{key:"color",label:"Color",type:"color",default_value:"black"},{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:this.height_px,hidden:true}],saved_values:ad,onchange:function(){ab.vertical_range=ab.prefs.max_value-ab.prefs.min_value;$("#linetrack_"+ab.track_id+"_minval").text(ab.prefs.min_value);$("#linetrack_"+ab.track_id+"_maxval").text(ab.prefs.max_value);ab.tile_cache.clear();ab.draw()}});this.prefs=this.track_config.values;this.height_px=this.track_config.values.height;this.vertical_range=this.track_config.values.max_value-this.track_config.values.min_value;this.add_resize_handle()};n(k.prototype,J.prototype,{add_resize_handle:function(){var aa=this;var ad=false;var ac=false;var ab=$("<div class='track-resize'>");$(aa.container_div).hover(function(){ad=true;ab.show()},function(){ad=false;if(!ac){ab.hide()}});ab.hide().bind("dragstart",function(ae,af){ac=true;af.original_height=$(aa.content_div).height()}).bind("drag",function(af,ag){var ae=Math.min(Math.max(ag.original_height+ag.deltaY,aa.min_height_px),aa.max_height_px);$(aa.content_div).css("height",ae);aa.height_px=ae;aa.draw(true)}).bind("dragend",function(ae,af){aa.tile_cache.clear();ac=false;if(!ad){ab.hide()}aa.track_config.values.height=aa.height_px}).appendTo(aa.container_div)},predraw_init:function(){var aa=this,ab=aa.view.tracks.indexOf(aa);aa.vertical_range=undefined;return $.getJSON(aa.data_url,{stats:true,chrom:aa.view.chrom,low:null,high:null,hda_ldda:aa.hda_ldda,dataset_id:aa.dataset_id},function(ac){aa.container_div.addClass("line-track");var ae=ac.data;if(isNaN(parseFloat(aa.prefs.min_value))||isNaN(parseFloat(aa.prefs.max_value))){aa.prefs.min_value=ae.min;aa.prefs.max_value=ae.max;$("#track_"+ab+"_minval").val(aa.prefs.min_value);$("#track_"+ab+"_maxval").val(aa.prefs.max_value)}aa.vertical_range=aa.prefs.max_value-aa.prefs.min_value;aa.total_frequency=ae.total_frequency;aa.container_div.find(".yaxislabel").remove();var af=$("<div />").addClass("yaxislabel").attr("id","linetrack_"+ab+"_minval").text(u(aa.prefs.min_value));var ad=$("<div />").addClass("yaxislabel").attr("id","linetrack_"+ab+"_maxval").text(u(aa.prefs.max_value));ad.css({position:"absolute",top:"24px",left:"10px"});ad.prependTo(aa.container_div);af.css({position:"absolute",bottom:"2px",left:"10px"});af.prependTo(aa.container_div)})},draw_tile:function(ak,ae,ab,aj){if(this.vertical_range===undefined){return}var af=ab*M*ae,ad=M*ae,aa=Math.ceil(ad*aj),ah=this.height_px;var ac=this.view.canvas_manager.new_canvas();ac.width=aa,ac.height=ah;var ai=ac.getContext("2d");var ag=new I.LinePainter(ak.data,af,af+ad,this.prefs,this.mode);ag.draw(ai,aa,ah);return new b(ad,ae,ac)}});var e=function(aa,af,ae,ai,ah,ac,ad,ag){var ab=this;this.display_modes=["Auto","Histogram","Dense","Squish","Pack"];this.track_config=new V({track:this,params:[{key:"block_color",label:"Block color",type:"color",default_value:"#444"},{key:"label_color",label:"Label color",type:"color",default_value:"black"},{key:"show_counts",label:"Show summary counts",type:"bool",default_value:true},{key:"mode",type:"string",default_value:this.mode,hidden:true},],saved_values:ah,onchange:function(){ab.tile_cache.clear();ab.draw()}});this.prefs=this.track_config.values;j.call(this,aa,af,af.viewport_container);J.call(this,ac,ad,ag);this.height_px=0;this.container_div.addClass("feature-track");this.hda_ldda=ae;this.dataset_id=ai;this.original_dataset_id=ai;this.show_labels_scale=0.001;this.showing_details=false;this.summary_draw_height=30;this.inc_slots={};this.start_end_dct={};this.tile_cache=new c(d);this.data_cache=new N(20,this);this.left_offset=200;this.painter=I.LinkedFeaturePainter};n(e.prototype,J.prototype,{update_auto_mode:function(aa){if(this.mode=="Auto"){if(aa=="no_detail"){aa="feature spans"}else{if(aa=="summary_tree"){aa="coverage histogram"}}this.mode_div.text("Auto ("+aa+")")}},incremental_slots:function(ae,ab,ad){var ac=this.view.canvas_manager.dummy_context,aa=this.inc_slots[ae];if(!aa||(aa.mode!==ad)){aa=new (p.FeatureSlotter)(ae,ad==="Pack",w,function(af){return ac.measureText(af)});aa.mode=ad;this.inc_slots[ae]=aa}return aa.slot_features(ab)},get_summary_tree_data:function(ae,ah,ac,ap){if(ap>ac-ah){ap=ac-ah}var al=Math.floor((ac-ah)/ap),ao=[],ad=0;var af=0,ag=0,ak,an=0,ai=[],am,aj;var ab=function(at,ar,au,aq){at[0]=ar+au*aq;at[1]=ar+(au+1)*aq};while(an<ap&&af!==ae.length){var aa=false;for(;an<ap&&!aa;an++){ab(ai,ah,an,al);for(ag=af;ag<ae.length;ag++){ak=ae[ag].slice(1,3);if(is_overlap(ak,ai)){aa=true;break}}if(aa){break}}data_start_index=ag;ao[ao.length]=am=[ai[0],0];for(;ag<ae.length;ag++){ak=ae[ag].slice(1,3);if(is_overlap(ak,ai)){am[1]++}else{break}}if(am[1]>ad){ad=am[1]}an++}return{max:ad,delta:al,data:ao}},draw_tile:function(an,av,az,aj,ad){var ar=this,aB=az*M*av,ab=(az+1)*M*av,ap=ab-aB,at=Math.ceil(ap*aj),aq=this.mode,aF=25,ae=this.left_offset,ao,af;if(aq==="Auto"){if(an.dataset_type==="summary_tree"){aq=an.dataset_type}else{if(an.extra_info==="no_detail"){aq="no_detail"}else{var aE=an.data;if(this.view.high-this.view.low>F){aq="Squish"}else{aq="Pack"}}}this.update_auto_mode(aq)}if(aq==="summary_tree"||aq==="Histogram"){af=this.summary_draw_height;this.container_div.find(".yaxislabel").remove();var aa=$("<div />").addClass("yaxislabel");aa.text(an.max);aa.css({position:"absolute",top:"24px",left:"10px",color:this.prefs.label_color});aa.prependTo(this.container_div);var ac=this.view.canvas_manager.new_canvas();ac.width=at+ae;ac.height=af+O;if(an.dataset_type!="summary_tree"){var ak=this.get_summary_tree_data(an.data,aB,ab,200);if(an.max){ak.max=an.max}an=ak}var aC=new I.SummaryTreePainter(an,aB,ab,this.prefs);var au=ac.getContext("2d");au.translate(ae,O);aC.draw(au,at,af);return new l(az,av,ac,an.max)}var ao,ah=1;if(aq==="no_detail"||aq==="Squish"||aq==="Pack"){ah=this.incremental_slots(aj,an.data,aq);ao=this.inc_slots[aj].slots}var ai=[];if(an.data){var al=this.filters_manager.filters;for(var aw=0,ay=an.data.length;aw<ay;aw++){var ag=an.data[aw];var ax=false;var am;for(var aA=0,aD=al.length;aA<aD;aA++){am=al[aA];am.update_attrs(ag);if(!am.keep(ag)){ax=true;break}}if(!ax){ai.push(ag)}}}var aC=new (this.painter)(ai,aB,ab,this.prefs,aq,ad);var af=aC.get_required_height(ah);var ac=this.view.canvas_manager.new_canvas();ac.width=at+ae;ac.height=af;var au=ac.getContext("2d");au.fillStyle=this.prefs.block_color;au.font=au.canvas.manager.default_font;au.textAlign="right";this.container_div.find(".yaxislabel").remove();if(an.data){this.example_feature=(an.data.length?an.data[0]:undefined);au.translate(ae,0);aC.draw(au,at,af,ao)}return new L(az,av,ac,an.message)}});var P=function(ad,ab,af,aa,ac,ae){e.call(this,ad,ab,af,aa,ac,ae);this.painter=I.VariantPainter};n(P.prototype,J.prototype,e.prototype);var S=function(ad,ab,af,aa,ac,ae){e.call(this,ad,ab,af,aa,ac,ae);this.track_config=new V({track:this,params:[{key:"block_color",label:"Block color",type:"color",default_value:"#444"},{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:"mode",type:"string",default_value:this.mode,hidden:true},],saved_values:ac,onchange:function(){this.track.tile_cache.clear();this.track.draw()}});this.prefs=this.track_config.values;this.painter=I.ReadPainter;this.make_name_popup_menu()};n(S.prototype,J.prototype,e.prototype);var Q=function(ae,ac,ag,aa,ad,af,ab){e.call(this,ae,ac,ag,aa,ad,af,{},ab);this.data_url=raw_data_url;this.data_query_wait=1000;this.dataset_check_url=dataset_state_url};n(Q.prototype,J.prototype,e.prototype,{predraw_init:function(){var ab=this;var aa=function(){if(ab.data_cache.size()===0){setTimeout(aa,300)}else{ab.data_url=default_data_url;ab.data_query_wait=H;ab.dataset_state_url=converted_datasets_state_url;$.getJSON(ab.dataset_state_url,{dataset_id:ab.dataset_id,hda_ldda:ab.hda_ldda},function(ac){})}};aa()}});T.View=Y;T.LineTrack=k;T.FeatureTrack=e;T.ReadTrack=S};var slotting_module=function(c,b){var e=c("class").extend;var d=2,a=5;b.FeatureSlotter=function(j,h,f,g){this.slots={};this.start_end_dct={};this.w_scale=j;this.include_label=h;this.max_rows=f;this.measureText=g};e(b.FeatureSlotter.prototype,{slot_features:function(m){var p=this.w_scale,s=this.slots,h=this.start_end_dct,y=[],A=[],n=0,z=this.max_rows;for(var w=0,x=m.length;w<x;w++){var l=m[w],o=l[0];if(s[o]!==undefined){n=Math.max(n,s[o]);A.push(s[o])}else{y.push(w)}}var q=function(G,H){for(var F=0;F<=z;F++){var D=false,I=h[F];if(I!==undefined){for(var C=0,E=I.length;C<E;C++){var B=I[C];if(H>B[0]&&G<B[1]){D=true;break}}}if(!D){return F}}return -1};for(var w=0,x=y.length;w<x;w++){var l=m[y[w]],o=l[0],u=l[1],f=l[2],r=l[3],g=Math.floor(u*p),k=Math.ceil(f*p),v=this.measureText(r).width,j;if(r!==undefined&&this.include_label){v+=(d+a);if(g-v>=0){g-=v;j="left"}else{k+=v;j="right"}}var t=q(g,k);if(t>=0){if(h[t]===undefined){h[t]=[]}h[t].push([g,k]);s[o]=t;n=Math.max(n,t)}else{}}return n+1}})};var painters_module=function(j,w){var t=j("class").extend;var o=function(H,z,F,y,E,C){if(C===undefined){C=4}var B=y-z;var A=E-F;var D=Math.floor(Math.sqrt(B*B+A*A)/C);var I=B/D;var G=A/D;var x;for(x=0;x<D;x++,z+=I,F+=G){if(x%2!==0){continue}H.fillRect(z,F,C,1)}};var p=function(A,z,x,D){var C=z-D/2,B=z+D/2,E=x-Math.sqrt(D*3/2);A.beginPath();A.moveTo(C,E);A.lineTo(B,E);A.lineTo(z,x);A.lineTo(C,E);A.strokeStyle=this.fillStyle;A.fill();A.stroke();A.closePath()};var m=function(z,B,x,y,A){this.data=z;this.view_start=B;this.view_end=x;this.prefs=t({},this.default_prefs,y);this.mode=A};m.prototype.default_prefs={};var u=function(z,B,x,y,A){m.call(this,z,B,x,y,A)};u.prototype.default_prefs={show_counts:false};u.prototype.draw=function(M,z,L){var E=this.view_start,O=this.view_end-this.view_start,N=z/O;var J=this.data.data,I=this.data.delta,G=this.data.max,B=L;delta_x_px=Math.ceil(I*N);M.save();for(var C=0,D=J.length;C<D;C++){var H=Math.floor((J[C][0]-E)*N);var F=J[C][1];if(!F){continue}var K=F/G*L;if(F!==0&&K<1){K=1}M.fillStyle=this.prefs.block_color;M.fillRect(H,B-K,delta_x_px,K);var A=4;if(this.prefs.show_counts&&(M.measureText(F).width+A)<delta_x_px){M.fillStyle=this.prefs.label_color;M.textAlign="center";M.fillText(F,H+(delta_x_px/2),10)}}M.restore()};var c=function(x,B,D,E,z){m.call(this,x,B,D,E,z);if(this.prefs.min_value===undefined){var F=Infinity;for(var y=0,A=this.data.length;y<A;y++){F=Math.min(F,this.data[y][1])}this.prefs.min_value=F}if(this.prefs.max_value===undefined){var C=-Infinity;for(var y=0,A=this.data.length;y<A;y++){C=Math.max(C,this.data[y][1])}this.prefs.max_value=C}};c.prototype.default_prefs={min_value:undefined,max_value:undefined,mode:"Histogram",color:"#000",overflow_color:"#F66"};c.prototype.draw=function(M,L,J){var E=false,G=this.prefs.min_value,C=this.prefs.max_value,I=C-G,x=J,z=this.view_start,K=this.view_end-this.view_start,A=L/K,H=this.mode,S=this.data;M.save();var T=Math.round(J+G/I*J);if(H!=="Intensity"){M.fillStyle="#aaa";M.fillRect(0,T,L,1)}M.beginPath();var Q,D,B;if(S.length>1){B=Math.ceil((S[1][0]-S[0][0])*A)}else{B=10}for(var N=0,O=S.length;N<O;N++){M.fillStyle=this.prefs.color;Q=Math.round((S[N][0]-z)*A);D=S[N][1];var P=false,F=false;if(D===null){if(E&&H==="Filled"){M.lineTo(Q,x)}E=false;continue}if(D<G){F=true;D=G}else{if(D>C){P=true;D=C}}if(H==="Histogram"){D=Math.round(D/I*x);M.fillRect(Q,T,B,-D)}else{if(H==="Intensity"){D=255-Math.floor((D-G)/I*255);M.fillStyle="rgb("+D+","+D+","+D+")";M.fillRect(Q,0,B,x)}else{D=Math.round(x-(D-G)/I*x);if(E){M.lineTo(Q,D)}else{E=true;if(H==="Filled"){M.moveTo(Q,x);M.lineTo(Q,D)}else{M.moveTo(Q,D)}}}}M.fillStyle=this.prefs.overflow_color;if(P||F){var R;if(H==="Histogram"||H==="Intensity"){R=B}else{Q-=2;R=4}if(P){M.fillRect(Q,0,R,3)}if(F){M.fillRect(Q,x-3,R,3)}}M.fillStyle=this.prefs.color}if(H==="Filled"){if(E){M.lineTo(Q,T);M.lineTo(0,T)}M.fill()}else{M.stroke()}M.restore()};var n=function(z,B,x,y,A){m.call(this,z,B,x,y,A)};n.prototype.default_prefs={block_color:"#FFF",connector_color:"#FFF"};t(n.prototype,{get_required_height:function(y){var x=y_scale=this.get_row_height(),z=this.mode;if(z==="no_detail"||z==="Squish"||z==="Pack"){x=y*y_scale}return x+Math.max(Math.round(y_scale/2),5)},draw:function(J,A,I,F){var D=this.data,G=this.view_start,K=this.view_end;J.save();J.fillStyle=this.prefs.block_color;J.textAlign="right";var N=this.view_end-this.view_start,M=A/N,z=this.get_row_height();for(var C=0,E=D.length;C<E;C++){var L=D[C],B=L[0],x=L[1],y=L[2],H=(F&&F[B]!==undefined?F[B]:null);if((x<K&&y>G)&&(this.mode=="Dense"||H!==null)){this.draw_element(J,this.mode,L,H,G,K,M,z,A)}}J.restore()}});var d=10,h=3,l=5,v=10,f=1,r=3,e=3,a=9,k=2,g="#ccc";var q=function(z,B,x,y,A){n.call(this,z,B,x,y,A)};t(q.prototype,n.prototype,{get_row_height:function(){var y=this.mode,x;if(y==="Dense"){x=d}else{if(y==="no_detail"){x=h}else{if(y==="Squish"){x=l}else{x=v}}}return x},draw_element:function(J,C,R,E,L,ab,af,ag,x){var O=R[0],ad=R[1],V=R[2],M=R[3],W=Math.floor(Math.max(0,(ad-L)*af)),K=Math.ceil(Math.min(x,Math.max(0,(V-L)*af))),U=(C==="Dense"?0:(0+E))*ag,I,Z,N=null,ah=null,A=this.prefs.block_color,Y=this.prefs.label_color;if(C=="Dense"){E=1}if(C==="no_detail"){J.fillStyle=A;J.fillRect(W,U+5,K-W,f)}else{var H=R[4],T=R[5],X=R[6],B=R[7];if(T&&X){N=Math.floor(Math.max(0,(T-L)*af));ah=Math.ceil(Math.min(x,Math.max(0,(X-L)*af)))}var ae,P;if(C==="Squish"||C==="Dense"){ae=1;P=e}else{ae=5;P=a}if(!B){if(R.strand){if(R.strand==="+"){J.fillStyle=J.canvas.manager.get_pattern("right_strand_inv")}else{if(R.strand==="-"){J.fillStyle=J.canvas.manager.get_pattern("left_strand_inv")}}}else{J.fillStyle=A}J.fillRect(W,U,K-W,P)}else{var G,Q;if(C==="Squish"||C==="Dense"){J.fillStyle=g;G=U+Math.floor(e/2)+1;Q=1}else{if(H){var G=U;var Q=P;if(H==="+"){J.fillStyle=J.canvas.manager.get_pattern("right_strand")}else{if(H==="-"){J.fillStyle=J.canvas.manager.get_pattern("left_strand")}}}else{J.fillStyle=g;G+=(e/2)+1;Q=1}}J.fillRect(W,G,K-W,Q);for(var ac=0,z=B.length;ac<z;ac++){var D=B[ac],y=Math.floor(Math.max(0,(D[0]-L)*af)),S=Math.ceil(Math.min(x,Math.max((D[1]-L)*af)));if(y>S){continue}J.fillStyle=A;J.fillRect(y,U+(P-ae)/2+1,S-y,ae);if(N!==undefined&&X>T&&!(y>ah||S<N)){var aa=Math.max(y,N),F=Math.min(S,ah);J.fillRect(aa,U+1,F-aa,P);if(B.length==1&&C=="Pack"){if(H==="+"){J.fillStyle=J.canvas.manager.get_pattern("right_strand_inv")}else{if(H==="-"){J.fillStyle=J.canvas.manager.get_pattern("left_strand_inv")}}if(aa+14<F){aa+=2;F-=2}J.fillRect(aa,U+1,F-aa,P)}}}}if(C==="Pack"&&ad>L){J.fillStyle=Y;if(L===0&&W-J.measureText(M).width<0){J.textAlign="left";J.fillText(M,K+k,U+8)}else{J.textAlign="right";J.fillText(M,W-k,U+8)}J.fillStyle=A}}}});var b=function(z,B,x,y,A){n.call(this,z,B,x,y,A)};t(b.prototype,n.prototype,{draw_element:function(Q,L,F,B,T,z,I,R,O){var F=data[i],H=F[0],P=F[1],A=F[2],K=F[3],D=Math.floor(Math.max(0,(P-T)*I)),G=Math.ceil(Math.min(O,Math.max(0,(A-T)*I))),C=(L==="Dense"?0:(0+B))*R,x,U,y=null,J=null;if(no_label){Q.fillStyle=block_color;Q.fillRect(D+left_offset,C+5,G-D,1)}else{var S=F[4],N=F[5],E=F[6];x=9;U=1;Q.fillRect(D+left_offset,C,G-D,x);if(L!=="Dense"&&K!==undefined&&P>T){Q.fillStyle=label_color;if(T===0&&D-Q.measureText(K).width<0){Q.textAlign="left";Q.fillText(K,G+2+left_offset,C+8)}else{Q.textAlign="right";Q.fillText(K,D-2+left_offset,C+8)}Q.fillStyle=block_color}var M=S+" / "+N;if(P>T&&Q.measureText(M).width<(G-D)){Q.fillStyle="white";Q.textAlign="center";Q.fillText(M,left_offset+D+(G-D)/2,C+8);Q.fillStyle=block_color}}}});var s=function(A,C,x,z,B,y){n.call(this,A,C,x,z,B);this.ref_seq=y};s.prototype.default_prefs=t({},n.prototype.default_prefs,{show_insertions:false});t(s.prototype,n.prototype,{get_row_height:function(){var x,y=this.mode;if(y==="Dense"){x=d}else{if(y==="Squish"){x=l}else{x=v;if(this.prefs.show_insertions){x*=2}}}return x},draw_read:function(T,O,K,Y,z,S,H,E,D){T.textAlign="center";var R=this,y=[Y,z],N=0,U=0,Q=0;ref_seq=this.ref_seq,char_width_px=T.canvas.manager.char_width_px;var ad=[];if((O==="Pack"||this.mode==="Auto")&&E!==undefined&&K>char_width_px){Q=Math.round(K/2)}if(!H){H=[[0,E.length]]}for(var L=0,W=H.length;L<W;L++){var I=H[L],A="MIDNSHP=X"[I[0]],M=I[1];if(A==="H"||A==="S"){N-=M}var F=S+N,ac=Math.floor(Math.max(0,(F-Y)*K)),G=Math.floor(Math.max(0,(F+M-Y)*K));if(ac===G){G+=1}switch(A){case"H":break;case"S":case"M":case"=":if(is_overlap([F,F+M],y)){var P=E.slice(U,U+M);if(Q>0){T.fillStyle=this.prefs.block_color;T.fillRect(ac-Q,D+1,G-ac,9);T.fillStyle=g;for(var aa=0,x=P.length;aa<x;aa++){if(this.prefs.show_differences&&ref_seq){var J=ref_seq[F-Y+aa];if(!J||J.toLowerCase()===P[aa].toLowerCase()){continue}}if(F+aa>=Y&&F+aa<=z){var ab=Math.floor(Math.max(0,(F+aa-Y)*K));T.fillText(P[aa],ab,D+9)}}}else{T.fillStyle=this.prefs.block_color;T.fillRect(ac,D+4,G-ac,e)}}U+=M;N+=M;break;case"N":T.fillStyle=g;T.fillRect(ac-Q,D+5,G-ac,1);N+=M;break;case"D":T.fillStyle="red";T.fillRect(ac-Q,D+4,G-ac,3);N+=M;break;case"P":break;case"I":var X=ac-Q;if(is_overlap([F,F+M],y)){var P=E.slice(U,U+M);if(this.prefs.show_insertions){var C=ac-(G-ac)/2;if((O==="Pack"||this.mode==="Auto")&&E!==undefined&&K>char_width_px){T.fillStyle="yellow";T.fillRect(C-Q,D-9,G-ac,9);ad[ad.length]={type:"triangle",data:[X,D+4,5]};T.fillStyle=g;switch(seq_tile_overlap){case (OVERLAP_START):P=P.slice(Y-F);break;case (OVERLAP_END):P=P.slice(0,F-z);break;case (CONTAINED_BY):break;case (CONTAINS):P=P.slice(Y-F,F-z);break}for(var aa=0,x=P.length;aa<x;aa++){var ab=Math.floor(Math.max(0,(F+aa-Y)*K));T.fillText(P[aa],ab-(G-ac)/2,D)}}else{T.fillStyle="yellow";T.fillRect(C,D+(this.mode!=="Dense"?2:5),G-ac,(O!=="Dense"?e:r))}}else{if((O==="Pack"||this.mode==="Auto")&&E!==undefined&&K>char_width_px){ad[ad.length]={type:"text",data:[P.length,X,D+9]}}else{}}}U+=M;break;case"X":U+=M;break}}T.fillStyle="yellow";var Z,B,ae;for(var V=0;V<ad.length;V++){Z=ad[V];B=Z.type;ae=Z.data;if(B==="text"){T.save();T.font="bold "+T.font;T.fillText(ae[0],ae[1],ae[2]);T.restore()}else{if(B=="triangle"){p(T,ae[0],ae[1],ae[2])}}}},draw_element:function(Q,L,D,A,T,y,H,R,O){var G=D[0],P=D[1],z=D[2],I=D[3],C=Math.floor(Math.max(0,(P-T)*H)),E=Math.ceil(Math.min(O,Math.max(0,(z-T)*H))),B=(L==="Dense"?0:(0+A))*R,U=this.prefs.block_color,F=this.prefs.label_color,N=0;if((L==="Pack"||this.mode==="Auto")&&H>Q.canvas.manager.char_width_px){var N=Math.round(H/2)}Q.fillStyle=U;if(D[5] instanceof Array){var M=Math.floor(Math.max(0,(D[4][0]-T)*H)),K=Math.ceil(Math.min(O,Math.max(0,(D[4][1]-T)*H))),J=Math.floor(Math.max(0,(D[5][0]-T)*H)),x=Math.ceil(Math.min(O,Math.max(0,(D[5][1]-T)*H)));if(D[4][1]>=T&&D[4][0]<=y&&D[4][2]){this.draw_read(Q,L,H,T,y,D[4][0],D[4][2],D[4][3],B)}if(D[5][1]>=T&&D[5][0]<=y&&D[5][2]){this.draw_read(Q,L,H,T,y,D[5][0],D[5][2],D[5][3],B)}if(J>K){Q.fillStyle=g;o(Q,K-N,B+5,J-N,B+5)}}else{Q.fillStyle=U;this.draw_read(Q,L,H,T,y,P,D[4],D[5],B)}if(L==="Pack"&&P>T){Q.fillStyle=this.prefs.label_color;var S=1;if(S===0&&C-Q.measureText(I).width<0){Q.textAlign="left";Q.fillText(I,E+k-N,B+8)}else{Q.textAlign="right";Q.fillText(I,C-k-N,B+8)}Q.fillStyle=U}}});w.SummaryTreePainter=u;w.LinePainter=c;w.LinkedFeaturePainter=q;w.ReadPainter=s;w.VariantPainter=b};(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 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 trackster_module=function(f,T){var n=f("class").extend,p=f("slotting"),I=f("painters");var Z=function(aa,ab){this.document=aa;this.default_font=ab!==undefined?ab:"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")};n(Z.prototype,{load_pattern:function(aa,ae){var ab=this.patterns,ac=this.dummy_context,ad=new Image();ad.src=image_path+ae;ad.onload=function(){ab[aa]=ac.createPattern(ad,"repeat")}},get_pattern:function(aa){return this.patterns[aa]},new_canvas:function(){var aa=this.document.createElement("canvas");if(window.G_vmlCanvasManager){G_vmlCanvasManager.initElement(aa)}aa.manager=this;return aa}});var C=function(aa,ab){aa.bind("drag",{handle:ab,relative:true},function(af,ag){var ae=$(this).parent();var ad=ae.children();var ac;for(ac=0;ac<ad.length;ac++){if(ag.offsetY<$(ad.get(ac)).position().top){break}}if(ac===ad.length){if(this!==ad.get(ac-1)){ae.append(this)}}else{if(this!==ad.get(ac)){$(this).insertBefore(ad.get(ac))}}}).bind("dragstart",function(){$(this).css({"border-top":"1px solid blue","border-bottom":"1px solid blue"})}).bind("dragend",function(){$(this).css("border","0px")})};T.sortable=C;var D=9,A=18,O=D+2,w=100,F=12000,M=200,z=5,s=10,H=5000,t=100,m="There was an error in indexing this dataset. ",G="A converter for this dataset is not installed. Please check your datatypes_conf.xml file.",B="No data for this chrom/contig.",q="Currently indexing... please wait",v="Tool cannot be rerun: ",a="Loading data...",U="Ready for display",d=10,r=5,y=5;function u(aa){return Math.round(aa*1000)/1000}var c=function(aa){this.num_elements=aa;this.clear()};n(c.prototype,{get:function(ab){var aa=this.key_ary.indexOf(ab);if(aa!==-1){if(this.obj_cache[ab].stale){this.key_ary.splice(aa,1);delete this.obj_cache[ab]}else{this.move_key_to_end(ab,aa)}}return this.obj_cache[ab]},set:function(ab,ac){if(!this.obj_cache[ab]){if(this.key_ary.length>=this.num_elements){var aa=this.key_ary.shift();delete this.obj_cache[aa]}this.key_ary.push(ab)}this.obj_cache[ab]=ac;return ac},move_key_to_end:function(ab,aa){this.key_ary.splice(aa,1);this.key_ary.push(ab)},clear:function(){this.obj_cache={};this.key_ary=[]},size:function(){return this.key_ary.length}});var N=function(ab,aa,ac){c.call(this,ab);this.track=aa;this.subset=(ac!==undefined?ac:true)};n(N.prototype,c.prototype,{load_data:function(aj,ae,ab,ag){var ai=this.track.view.chrom,ah=this.track.mode,ad={chrom:ai,low:aj,high:ae,mode:ah,resolution:ab,dataset_id:this.track.dataset_id,hda_ldda:this.track.hda_ldda};$.extend(ad,ag);if(this.track.filters_manager){var ak=[];var aa=this.track.filters_manager.filters;for(var af=0;af<aa.length;af++){ak[ak.length]=aa[af].name}ad.filter_cols=JSON.stringify(ak)}var ac=this;return $.getJSON(this.track.data_url,ad,function(al){ac.set_data(aj,ae,ah,al)})},get_data:function(aa,ae,ab,ad){var af=this.track.mode,ac=this.get_data_from_cache(aa,ae,af);if(ac){return ac}ac=this.load_data(aa,ae,ab,ad);this.set_data(aa,ae,af,ac);return ac},DEEP_DATA_REQ:"deep",BROAD_DATA_REQ:"breadth",get_more_data:function(ah,ac,ab,af,ad){var ag=this.track.mode,ai=this.get_data_from_cache(ah,ac,ag);if(!ai){console.log("ERROR: no current data for: ",this.track,ah,ac,ab,af);return}ai.stale=true;if(ad===this.DEEP_DATA_REQ){$.extend(af,{start_val:ai.data.length+1})}else{if(ad===this.BROAD_DATA_REQ){ah=ai.data[ai.length-1][2]+1}}var aa=this,ae=this.load_data(ah,ac,ab,af);new_data_available=$.Deferred();this.set_data(ah,ac,ag,new_data_available);$.when(ae).then(function(aj){if(aj.data){aj.data=ai.data.concat(aj.data)}aa.set_data(ah,ac,ag,aj);new_data_available.resolve(aj)});return new_data_available},get_data_from_cache:function(aa,ab,ac){return this.get(this.gen_key(aa,ab,ac))},set_data:function(ab,ac,ad,aa){return this.set(this.gen_key(ab,ac,ad),aa)},gen_key:function(aa,ac,ad){var ab=aa+"_"+ac+"_"+ad;return ab},split_key:function(aa){return aa.split("_")}});var E=function(ab,aa,ac){N.call(this,ab,aa,ac)};n(E.prototype,N.prototype,c.prototype,{load_data:function(ac,aa,ae,af,ab,ad){if(ab>1){return}return N.prototype.load_data.call(this,ac,aa,ae,af,ab,ad)}});var Y=function(aa,ad,ac,ab,ae){this.container=aa;this.chrom=null;this.vis_id=ac;this.dbkey=ab;this.title=ad;this.tracks=[];this.label_tracks=[];this.max_low=0;this.max_high=0;this.num_tracks=0;this.track_id_counter=0;this.zoom_factor=3;this.min_separation=30;this.has_changes=false;this.init(ae);this.canvas_manager=new Z(aa.get(0).ownerDocument);this.reset()};n(Y.prototype,{init:function(ad){var ac=this.container,aa=this;this.top_container=$("<div/>").addClass("top-container").appendTo(ac);this.content_div=$("<div/>").addClass("content").css("position","relative").appendTo(ac);this.bottom_container=$("<div/>").addClass("bottom-container").appendTo(ac);this.top_labeltrack=$("<div/>").addClass("top-labeltrack").appendTo(this.top_container);this.viewport_container=$("<div/>").addClass("viewport-container").addClass("viewport-container").appendTo(this.content_div);this.intro_div=$("<div/>").addClass("intro").text("Select a chrom from the dropdown below").hide();this.nav_labeltrack=$("<div/>").addClass("nav-labeltrack").appendTo(this.bottom_container);this.nav_container=$("<div/>").addClass("nav-container").prependTo(this.top_container);this.nav=$("<div/>").addClass("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 href='javascript:void(0);'>Close Overview</a>").addClass("overview-close").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 ab=function(ae){if(ae.type==="focusout"||(ae.keyCode||ae.which)===13||(ae.keyCode||ae.which)===27){if((ae.keyCode||ae.which)!==27){aa.go_to($(this).val())}$(this).hide();$(this).val("");aa.location_span.show();aa.chrom_select.show()}};this.nav_input=$("<input/>").addClass("nav-input").hide().bind("keyup focusout",ab).appendTo(this.nav_controls);this.location_span=$("<span/>").addClass("location").appendTo(this.nav_controls);this.location_span.bind("click",function(){aa.location_span.hide();aa.chrom_select.hide();aa.nav_input.val(aa.chrom+":"+aa.low+"-"+aa.high);aa.nav_input.css("display","inline-block");aa.nav_input.select();aa.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 id='zoom-out' />").click(function(){aa.zoom_out();aa.redraw()}).appendTo(this.nav_controls);this.zi_link=$("<a id='zoom-in' />").click(function(){aa.zoom_in();aa.redraw()}).appendTo(this.nav_controls);this.load_chroms({low:0},ad);this.chrom_select.bind("change",function(){aa.change_chrom(aa.chrom_select.val())});this.intro_div.show();this.content_div.bind("click",function(ae){$(this).find("input").trigger("blur")});this.content_div.bind("dblclick",function(ae){aa.zoom_in(ae.pageX,this.viewport_container)});this.overview_box.bind("dragstart",function(ae,af){this.current_x=af.offsetX}).bind("drag",function(ae,ag){var ah=ag.offsetX-this.current_x;this.current_x=ag.offsetX;var af=Math.round(ah/aa.viewport_container.width()*(aa.max_high-aa.max_low));aa.move_delta(-af)});this.overview_close.bind("click",function(){for(var af=0,ae=aa.tracks.length;af<ae;af++){aa.tracks[af].is_overview=false}$(this).siblings().filter("canvas").remove();$(this).parent().css("height",aa.overview_box.height());aa.overview_highlight.hide();$(this).hide()});this.viewport_container.bind("draginit",function(ae,af){if(ae.clientX>aa.viewport_container.width()-16){return false}}).bind("dragstart",function(ae,af){af.original_low=aa.low;af.current_height=ae.clientY;af.current_x=af.offsetX}).bind("drag",function(ag,ai){var ae=$(this);var aj=ai.offsetX-ai.current_x;var af=ae.scrollTop()-(ag.clientY-ai.current_height);ae.scrollTop(af);ai.current_height=ag.clientY;ai.current_x=ai.offsetX;var ah=Math.round(aj/aa.viewport_container.width()*(aa.high-aa.low));aa.move_delta(ah)}).bind("mousewheel",function(ag,ai,af,ae){if(af){var ah=Math.round(-af/aa.viewport_container.width()*(aa.high-aa.low));aa.move_delta(ah)}});this.top_labeltrack.bind("dragstart",function(ae,af){return $("<div />").css({height:aa.content_div.height()+aa.top_labeltrack.height()+aa.nav_labeltrack.height()+1,top:"0px",position:"absolute","background-color":"#ccf",opacity:0.5,"z-index":1000}).appendTo($(this))}).bind("drag",function(ai,aj){$(aj.proxy).css({left:Math.min(ai.pageX,aj.startX),width:Math.abs(ai.pageX-aj.startX)});var af=Math.min(ai.pageX,aj.startX)-aa.container.offset().left,ae=Math.max(ai.pageX,aj.startX)-aa.container.offset().left,ah=(aa.high-aa.low),ag=aa.viewport_container.width();aa.update_location(Math.round(af/ag*ah)+aa.low,Math.round(ae/ag*ah)+aa.low)}).bind("dragend",function(aj,ak){var af=Math.min(aj.pageX,ak.startX),ae=Math.max(aj.pageX,ak.startX),ah=(aa.high-aa.low),ag=aa.viewport_container.width(),ai=aa.low;aa.low=Math.round(af/ag*ah)+ai;aa.high=Math.round(ae/ag*ah)+ai;$(ak.proxy).remove();aa.redraw()});this.add_label_track(new X(this,this.top_labeltrack));this.add_label_track(new X(this,this.nav_labeltrack));$(window).bind("resize",function(){aa.resize_window()});$(document).bind("redraw",function(){aa.redraw()});this.reset();$(window).trigger("resize")},update_location:function(aa,ab){this.location_span.text(commatize(aa)+" - "+commatize(ab));this.nav_input.val(this.chrom+":"+commatize(aa)+"-"+commatize(ab))},load_chroms:function(ab,ac){ab.num=t;$.extend(ab,(this.vis_id!==undefined?{vis_id:this.vis_id}:{dbkey:this.dbkey}));var aa=this;$.ajax({url:chrom_url,data:ab,dataType:"json",success:function(ae){if(ae.chrom_info.length===0){alert("Invalid chromosome: "+ab.chrom);return}if(ae.reference){aa.add_label_track(new x(aa))}aa.chrom_data=ae.chrom_info;var ah='<option value="">Select Chrom/Contig</option>';for(var ag=0,ad=aa.chrom_data.length;ag<ad;ag++){var af=aa.chrom_data[ag].chrom;ah+='<option value="'+af+'">'+af+"</option>"}if(ae.prev_chroms){ah+='<option value="previous">Previous '+t+"</option>"}if(ae.next_chroms){ah+='<option value="next">Next '+t+"</option>"}aa.chrom_select.html(ah);if(ac){ac()}aa.chrom_start_index=ae.start_index},error:function(){alert("Could not load chroms for this dbkey:",aa.dbkey)}})},change_chrom:function(ae,ab,ag){if(!ae||ae==="None"){return}var ad=this;if(ae==="previous"){ad.load_chroms({low:this.chrom_start_index-t});return}if(ae==="next"){ad.load_chroms({low:this.chrom_start_index+t});return}var af=$.grep(ad.chrom_data,function(ai,aj){return ai.chrom===ae})[0];if(af===undefined){ad.load_chroms({chrom:ae},function(){ad.change_chrom(ae,ab,ag)});return}else{if(ae!==ad.chrom){ad.chrom=ae;if(!ad.chrom){ad.intro_div.show()}else{ad.intro_div.hide()}ad.chrom_select.val(ad.chrom);ad.max_high=af.len-1;ad.reset();ad.redraw(true);for(var ah=0,aa=ad.tracks.length;ah<aa;ah++){var ac=ad.tracks[ah];if(ac.init){ac.init()}}}if(ab!==undefined&&ag!==undefined){ad.low=Math.max(ab,0);ad.high=Math.min(ag,ad.max_high)}ad.reset_overview();ad.redraw()}},go_to:function(ae){var ai=this,aa,ad,ab=ae.split(":"),ag=ab[0],ah=ab[1];if(ah!==undefined){try{var af=ah.split("-");aa=parseInt(af[0].replace(/,/g,""),10);ad=parseInt(af[1].replace(/,/g,""),10)}catch(ac){return false}}ai.change_chrom(ag,aa,ad)},move_fraction:function(ac){var aa=this;var ab=aa.high-aa.low;this.move_delta(ac*ab)},move_delta:function(ac){var aa=this;var ab=aa.high-aa.low;if(aa.low-ac<aa.max_low){aa.low=aa.max_low;aa.high=aa.max_low+ab}else{if(aa.high-ac>aa.max_high){aa.high=aa.max_high;aa.low=aa.max_high-ab}else{aa.high-=ac;aa.low-=ac}}aa.redraw()},add_track:function(aa){aa.view=this;aa.track_id=this.track_id_counter;this.tracks.push(aa);if(aa.init){aa.init()}aa.container_div.attr("id","track_"+aa.track_id);C(aa.container_div,".draghandle");this.track_id_counter+=1;this.num_tracks+=1},add_label_track:function(aa){aa.view=this;this.label_tracks.push(aa)},remove_track:function(aa){this.has_changes=true;aa.container_div.fadeOut("slow",function(){$(this).remove()});delete this.tracks[this.tracks.indexOf(aa)];this.num_tracks-=1},reset:function(){this.low=this.max_low;this.high=this.max_high;this.viewport_container.find(".yaxislabel").remove()},redraw:function(ah){var ag=this.high-this.low,af=this.low,ab=this.high;if(af<this.max_low){af=this.max_low}if(ab>this.max_high){ab=this.max_high}if(this.high!==0&&ag<this.min_separation){ab=af+this.min_separation}this.low=Math.floor(af);this.high=Math.ceil(ab);this.resolution=Math.pow(z,Math.ceil(Math.log((this.high-this.low)/M)/Math.log(z)));this.zoom_res=Math.pow(s,Math.max(0,Math.ceil(Math.log(this.resolution,s)/Math.log(s))));var aa=(this.low/(this.max_high-this.max_low)*this.overview_viewport.width())||0;var ae=((this.high-this.low)/(this.max_high-this.max_low)*this.overview_viewport.width())||0;var ai=13;this.overview_box.css({left:aa,width:Math.max(ai,ae)}).show();if(ae<ai){this.overview_box.css("left",aa-(ai-ae)/2)}if(this.overview_highlight){this.overview_highlight.css({left:aa,width:ae})}this.update_location(this.low,this.high);if(!ah){for(var ac=0,ad=this.tracks.length;ac<ad;ac++){if(this.tracks[ac]&&this.tracks[ac].enabled){this.tracks[ac].draw()}}for(ac=0,ad=this.label_tracks.length;ac<ad;ac++){this.label_tracks[ac].draw()}}},zoom_in:function(ab,ac){if(this.max_high===0||this.high-this.low<this.min_separation){return}var ad=this.high-this.low,ae=ad/2+this.low,aa=(ad/this.zoom_factor)/2;if(ab){ae=ab/this.viewport_container.width()*(this.high-this.low)+this.low}this.low=Math.round(ae-aa);this.high=Math.round(ae+aa);this.redraw()},zoom_out:function(){if(this.max_high===0){return}var ab=this.high-this.low,ac=ab/2+this.low,aa=(ab*this.zoom_factor)/2;this.low=Math.round(ac-aa);this.high=Math.round(ac+aa);this.redraw()},resize_window:function(){this.viewport_container.height(this.container.height()-this.top_container.height()-this.bottom_container.height());this.nav_container.width(this.container.width());this.redraw()},reset_overview:function(){this.overview_viewport.find("canvas").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()}});var o=function(ac,ag){this.track=ac;this.name=ag.name;this.params=[];var an=ag.params;for(var ad=0;ad<an.length;ad++){var ai=an[ad],ab=ai.name,am=ai.label,ae=unescape(ai.html),ao=ai.value,ak=ai.type;if(ak==="number"){this.params[this.params.length]=new g(ab,am,ae,ao,ai.min,ai.max)}else{if(ak=="select"){this.params[this.params.length]=new K(ab,am,ae,ao)}else{console.log("WARNING: unrecognized tool parameter type:",ab,ak)}}}this.parent_div=$("<div/>").addClass("dynamic-tool").hide();this.parent_div.bind("drag",function(aq){aq.stopPropagation()}).bind("click",function(aq){aq.stopPropagation()}).bind("dblclick",function(aq){aq.stopPropagation()});var al=$("<div class='tool-name'>").appendTo(this.parent_div).text(this.name);var aj=this.params;var ah=this;$.each(this.params,function(ar,av){var au=$("<div>").addClass("param-row").appendTo(ah.parent_div);var aq=$("<div>").addClass("param-label").text(av.label).appendTo(au);var at=$("<div/>").addClass("slider").html(av.html).appendTo(au);at.find(":input").val(av.value);$("<div style='clear: both;'/>").appendTo(au)});this.parent_div.find("input").click(function(){$(this).select()});var ap=$("<div>").addClass("param-row").appendTo(this.parent_div);var af=$("<input type='submit'>").attr("value","Run on complete dataset").appendTo(ap);var aa=$("<input type='submit'>").attr("value","Run on visible region").css("margin-left","3em").appendTo(ap);var ah=this;aa.click(function(){ah.run_on_region()});af.click(function(){ah.run_on_dataset()})};n(o.prototype,{get_param_values_dict:function(){var aa={};this.parent_div.find(":input").each(function(){var ab=$(this).attr("name"),ac=$(this).val();aa[ab]=JSON.stringify(ac)});return aa},get_param_values:function(){var ab=[];var aa={};this.parent_div.find(":input").each(function(){var ac=$(this).attr("name"),ad=$(this).val();if(ac){ab[ab.length]=ad}});return ab},run_on_dataset:function(){var aa=this;aa.run({dataset_id:this.track.original_dataset_id,tool_id:aa.name},function(ab){show_modal(aa.name+" is Running",aa.name+" is running on the complete dataset. Tool outputs are in dataset's history.",{Close:hide_modal})})},run_on_region:function(){var aa={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},ac=this.track,ab=aa.tool_id+ac.tool_region_and_parameters_str(aa.chrom,aa.low,aa.high),ad;if(ac instanceof e){ad=new Q(ab,view,ac.hda_ldda,undefined,{},{},ac);ad.change_mode(ac.mode)}this.track.add_track(ad);ad.content_div.text("Starting job.");this.run(aa,function(ae){ad.dataset_id=ae.dataset_id;ad.content_div.text("Running job.");ad.init()})},run:function(ab,ac){$.extend(ab,this.get_param_values_dict());var aa=function(){$.getJSON(rerun_tool_url,ab,function(ad){if(ad==="no converter"){new_track.container_div.addClass("error");new_track.content_div.text(G)}else{if(ad.error){new_track.container_div.addClass("error");new_track.content_div.text(v+ad.message)}else{if(ad==="pending"){new_track.container_div.addClass("pending");new_track.content_div.text("Converting input data so that it can be easily reused.");setTimeout(aa,2000)}else{ac(ad)}}}})};aa()}});var K=function(ab,aa,ac,ad){this.name=ab;this.label=aa;this.html=ac;this.value=ad};var g=function(ac,ab,ae,af,ad,aa){K.call(this,ac,ab,ae,af);this.min=ad;this.max=aa};var h=function(ab,aa,ac,ad){this.name=ab;this.index=aa;this.tool_id=ac;this.tool_exp_name=ad};var R=function(ab,aa,ac,ad){h.call(this,ab,aa,ac,ad);this.low=-Number.MAX_VALUE;this.high=Number.MAX_VALUE;this.min=Number.MAX_VALUE;this.max=-Number.MAX_VALUE;this.slider=null;this.slider_label=null};n(R.prototype,{applies_to:function(aa){if(aa.length>this.index){return true}return false},keep:function(aa){if(!this.applies_to(aa)){return true}var ab=parseInt(aa[this.index]);return(isNaN(ab)||(ab>=this.low&&ab<=this.high))},update_attrs:function(ab){var aa=false;if(!this.applies_to(ab)){return aa}if(ab[this.index]<this.min){this.min=Math.floor(ab[this.index]);aa=true}if(ab[this.index]>this.max){this.max=Math.ceil(ab[this.index]);aa=true}return aa},update_ui_elt:function(){var ac=function(af,ad){var ae=ad-af;return(ae<=2?0.01:1)};var ab=this.slider.slider("option","min"),aa=this.slider.slider("option","max");if(this.min<ab||this.max>aa){this.slider.slider("option","min",this.min);this.slider.slider("option","max",this.max);this.slider.slider("option","step",ac(this.min,this.max));this.slider.slider("option","values",[this.min,this.max])}}});var W=function(ac,al){this.track=ac;this.filters=[];for(var ag=0;ag<al.length;ag++){var aa=al[ag],ab=aa.name,ak=aa.type,ai=aa.index,an=aa.tool_id,ad=aa.tool_exp_name;if(ak==="int"||ak==="float"){this.filters[ag]=new R(ab,ai,an,ad)}else{console.log("ERROR: unsupported filter: ",ab,ak)}}var aj=function(ao,ap,aq){ao.click(function(){var ar=ap.text();max=parseFloat(aq.slider("option","max")),input_size=(max<=1?4:max<=1000000?max.toString().length:6),multi_value=false;if(aq.slider("option","values")){input_size=2*input_size+1;multi_value=true}ap.text("");$("<input type='text'/>").attr("size",input_size).attr("maxlength",input_size).attr("value",ar).appendTo(ap).focus().select().click(function(at){at.stopPropagation()}).blur(function(){$(this).remove();ap.text(ar)}).keyup(function(ax){if(ax.keyCode===27){$(this).trigger("blur")}else{if(ax.keyCode===13){var av=aq.slider("option","min"),at=aq.slider("option","max"),aw=function(ay){return(isNaN(ay)||ay>at||ay<av)},au=$(this).val();if(!multi_value){au=parseFloat(au);if(aw(au)){alert("Parameter value must be in the range ["+av+"-"+at+"]");return $(this)}}else{au=au.split("-");au=[parseFloat(au[0]),parseFloat(au[1])];if(aw(au[0])||aw(au[1])){alert("Parameter value must be in the range ["+av+"-"+at+"]");return $(this)}}aq.slider((multi_value?"values":"value"),au)}}})})};this.parent_div=$("<div/>").addClass("filters").hide();this.parent_div.bind("drag",function(ao){ao.stopPropagation()}).bind("click",function(ao){ao.stopPropagation()}).bind("dblclick",function(ao){ao.stopPropagation()}).bind("keydown",function(ao){ao.stopPropagation()});var ae=this;$.each(this.filters,function(av,ap){var ar=$("<div/>").addClass("slider-row").appendTo(ae.parent_div);var ao=$("<div/>").addClass("slider-label").appendTo(ar);var ax=$("<span/>").addClass("slider-name").text(ap.name+" ").appendTo(ao);var aq=$("<span/>");var at=$("<span/>").addClass("slider-value").appendTo(ao).append("[").append(aq).append("]");var aw=$("<div/>").addClass("slider").appendTo(ar);ap.control_element=$("<div/>").attr("id",ap.name+"-filter-control").appendTo(aw);var au=[0,0];ap.control_element.slider({range:true,min:Number.MAX_VALUE,max:-Number.MIN_VALUE,values:[0,0],slide:function(ay,az){au=az.values;aq.text(az.values[0]+"-"+az.values[1]);setTimeout(function(){if(az.values[0]==au[0]&&az.values[1]==au[1]){var aA=az.values;aq.text(aA[0]+"-"+aA[1]);ap.low=aA[0];ap.high=aA[1];ae.track.draw(true,true)}},50)},change:function(ay,az){ap.control_element.slider("option","slide").call(ap.control_element,ay,az)}});ap.slider=ap.control_element;ap.slider_label=aq;aj(at,aq,ap.control_element);$("<div style='clear: both;'/>").appendTo(ar)});if(this.filters.length!=0){var am=$("<div>").addClass("param-row").appendTo(this.parent_div);var ah=$("<input type='submit'>").attr("value","Run on complete dataset").appendTo(am);var af=this;ah.click(function(){af.run_on_dataset()})}};n(W.prototype,{reset_filters:function(){for(var aa=0;aa<this.filters.length;aa++){filter=this.filters[aa];filter.slider.slider("option","values",[filter.min,filter.max])}},run_on_dataset:function(){var ai=function(am,ak,al){if(!(ak in am)){am[ak]=al}return am[ak]};var ac={},aa,ab,ad;for(var ae=0;ae<this.filters.length;ae++){aa=this.filters[ae];if(aa.tool_id){if(aa.min!=aa.low){ab=ai(ac,aa.tool_id,[]);ab[ab.length]=aa.tool_exp_name+" >= "+aa.low}if(aa.max!=aa.high){ab=ai(ac,aa.tool_id,[]);ab[ab.length]=aa.tool_exp_name+" <= "+aa.high}}}var ag=[];for(var aj in ac){ag[ag.length]=[aj,ac[aj]]}var ah=ag.length;(function af(aq,an){var al=an[0],am=al[0],ap=al[1],ao="("+ap.join(") and (")+")",ak={cond:ao,input:aq,target_dataset_id:aq,tool_id:am},an=an.slice(1);$.getJSON(run_tool_url,ak,function(ar){if(ar.error){show_modal("Filter Dataset","Error running tool "+am,{Close:hide_modal})}else{if(an.length===0){show_modal("Filtering Dataset","Filter(s) are running on the complete dataset. Outputs are in dataset's history.",{Close:hide_modal})}else{af(ar.dataset_id,an)}}})})(this.track.dataset_id,ag)}});var V=function(aa){this.track=aa.track;this.params=aa.params;this.values={};if(aa.saved_values){this.restore_values(aa.saved_values)}this.onchange=aa.onchange};n(V.prototype,{restore_values:function(aa){var ab=this;$.each(this.params,function(ac,ad){if(aa[ad.key]!==undefined){ab.values[ad.key]=aa[ad.key]}else{ab.values[ad.key]=ad.default_value}})},build_form:function(){var ab=this;var aa=$("<div />");$.each(this.params,function(af,ad){if(!ad.hidden){var ac="param_"+af;var ak=$("<div class='form-row' />").appendTo(aa);ak.append($("<label />").attr("for",ac).text(ad.label+":"));if(ad.type==="bool"){ak.append($('<input type="checkbox" />').attr("id",ac).attr("name",ac).attr("checked",ab.values[ad.key]))}else{if(ad.type==="color"){var ah=ab.values[ad.key];var ag=$("<input />").attr("id",ac).attr("name",ac).val(ah);var ai=$("<div class='tipsy tipsy-north' style='position: absolute;' />").hide();var ae=$("<div style='background-color: black; padding: 10px;'></div>").appendTo(ai);var aj=$("<div/>").appendTo(ae).farbtastic({width:100,height:100,callback:ag,color:ah});$("<div />").append(ag).append(ai).appendTo(ak).bind("click",function(al){ai.css({left:$(this).position().left+($(ag).width()/2)-60,top:$(this).position().top+$(this.height)}).show();$(document).bind("click.color-picker",function(){ai.hide();$(document).unbind("click.color-picker")});al.stopPropagation()})}else{ak.append($("<input />").attr("id",ac).attr("name",ac).val(ab.values[ad.key]))}}}});return aa},update_from_form:function(aa){var ac=this;var ab=false;$.each(this.params,function(ad,af){if(!af.hidden){var ag="param_"+ad;var ae=aa.find("#"+ag).val();if(af.type==="float"){ae=parseFloat(ae)}else{if(af.type==="int"){ae=parseInt(ae)}else{if(af.type==="bool"){ae=aa.find("#"+ag).is(":checked")}}}if(ae!==ac.values[af.key]){ac.values[af.key]=ae;ab=true}}});if(ab){this.onchange()}}});var b=function(ac,ab,aa){this.index=ac;this.low=ac*M*ab;this.high=(ac+1)*M*ab;this.resolution=ab;this.canvas=$("<div class='track-tile'/>").append(aa);this.stale=false};var l=function(ac,ab,aa,ad){b.call(this,ac,ab,aa);this.max_val=ad};var L=function(ac,ab,aa,ad){b.call(this,ac,ab,aa);this.message=ad};var j=function(ab,aa,ae,ac,ad){this.name=ab;this.view=aa;this.parent_element=ae;this.data_url=(ac?ac:default_data_url);this.data_url_extra_params={};this.data_query_wait=(ad?ad:H);this.dataset_check_url=converted_datasets_state_url;this.container_div=$("<div />").addClass("track").css("position","relative");if(!this.hidden){this.header_div=$("<div class='track-header' />").appendTo(this.container_div);if(this.view.editor){this.drag_div=$("<div class='draghandle' />").appendTo(this.header_div)}this.name_div=$("<div class='menubutton popup' />").appendTo(this.header_div);this.name_div.text(this.name);this.name_div.attr("id",this.name.replace(/\s+/g,"-").replace(/[^a-zA-Z0-9\-]/g,"").toLowerCase())}this.content_div=$("<div class='track-content'>").appendTo(this.container_div);this.parent_element.append(this.container_div)};n(j.prototype,{get_type:function(){if(this instanceof X){return"LabelTrack"}else{if(this instanceof x){return"ReferenceTrack"}else{if(this instanceof k){return"LineTrack"}else{if(this instanceof S){return"ReadTrack"}else{if(this instanceof Q){return"ToolDataFeatureTrack"}else{if(this instanceof P){return"VcfTrack"}else{if(this instanceof e){return"FeatureTrack"}}}}}}}return""},init:function(){var aa=this;aa.enabled=false;aa.tile_cache.clear();aa.data_manager.clear();aa.initial_canvas=undefined;aa.content_div.css("height","auto");aa.container_div.removeClass("nodata error pending");if(!aa.dataset_id){return}$.getJSON(converted_datasets_state_url,{hda_ldda:aa.hda_ldda,dataset_id:aa.dataset_id,chrom:aa.view.chrom},function(ab){if(!ab||ab==="error"||ab.kind==="error"){aa.container_div.addClass("error");aa.content_div.text(m);if(ab.message){var ad=aa.view.tracks.indexOf(aa);var ac=$(" <a href='javascript:void(0);'></a>").text("View error").bind("click",function(){show_modal("Trackster Error","<pre>"+ab.message+"</pre>",{Close:hide_modal})});aa.content_div.append(ac)}}else{if(ab==="no converter"){aa.container_div.addClass("error");aa.content_div.text(G)}else{if(ab==="no data"||(ab.data!==undefined&&(ab.data===null||ab.data.length===0))){aa.container_div.addClass("nodata");aa.content_div.text(B)}else{if(ab==="pending"){aa.container_div.addClass("pending");aa.content_div.text(q);setTimeout(function(){aa.init()},aa.data_query_wait)}else{if(ab.status==="data"){if(ab.valid_chroms){aa.valid_chroms=ab.valid_chroms;aa.make_name_popup_menu()}aa.content_div.text(U);if(aa.view.chrom){aa.content_div.text("");aa.content_div.css("height",aa.height_px+"px");aa.enabled=true;$.when(aa.predraw_init()).done(function(){aa.container_div.removeClass("nodata error pending");aa.draw()})}}}}}}})},predraw_init:function(){},update_name:function(aa){this.old_name=this.name;this.name=aa;this.name_div.text(this.name)},revert_name:function(){this.name=this.old_name;this.name_div.text(this.name)}});var J=function(ah,af,ai){var ab=this,aj=ab.view;this.filters_manager=(ah!==undefined?new W(this,ah):undefined);this.filters_available=false;this.filters_visible=false;this.tool=(af!==undefined&&obj_length(af)>0?new o(this,af):undefined);this.parent_track=ai;this.child_tracks=[];if(ab.hidden){return}if(this.parent_track){this.header_div.find(".draghandle").removeClass("draghandle").addClass("child-track-icon").addClass("icon-button");this.parent_element.addClass("child-track");this.tool=undefined}ab.child_tracks_container=$("<div/>").addClass("child-tracks-container").hide();ab.container_div.append(ab.child_tracks_container);if(this.filters_manager){this.filters_div=this.filters_manager.parent_div;this.header_div.after(this.filters_div)}if(this.tool){this.dynamic_tool_div=this.tool.parent_div;this.header_div.after(this.dynamic_tool_div)}if(ab.display_modes!==undefined){if(ab.mode_div===undefined){ab.mode_div=$("<div class='right-float menubutton popup' />").appendTo(ab.header_div);var ac=(ab.track_config&&ab.track_config.values.mode?ab.track_config.values.mode:ab.display_modes[0]);ab.mode=ac;ab.mode_div.text(ac);var aa={};for(var ad=0,ag=ab.display_modes.length;ad<ag;ad++){var ae=ab.display_modes[ad];aa[ae]=function(ak){return function(){ab.change_mode(ak)}}(ae)}make_popupmenu(ab.mode_div,aa)}else{ab.mode_div.hide()}}this.make_name_popup_menu()};n(J.prototype,j.prototype,{change_mode:function(ab){var aa=this;aa.mode_div.text(ab);aa.mode=ab;aa.track_config.values.mode=ab;aa.tile_cache.clear();aa.draw()},make_name_popup_menu:function(){var ab=this;var aa={};aa["Edit configuration"]=function(){var ah=function(){hide_modal();$(window).unbind("keypress.check_enter_esc")},af=function(){ab.track_config.update_from_form($(".dialog-box"));hide_modal();$(window).unbind("keypress.check_enter_esc")},ag=function(ai){if((ai.keyCode||ai.which)===27){ah()}else{if((ai.keyCode||ai.which)===13){af()}}};$(window).bind("keypress.check_enter_esc",ag);show_modal("Configure Track",ab.track_config.build_form(),{Cancel:ah,OK:af})};if(ab.filters_available>0){var ae=(ab.filters_div.is(":visible")?"Hide filters":"Show filters");aa[ae]=function(){ab.filters_visible=(ab.filters_div.is(":visible"));if(ab.filters_visible){ab.filters_manager.reset_filters()}ab.filters_div.toggle();ab.make_name_popup_menu()}}if(ab.tool){var ae=(ab.dynamic_tool_div.is(":visible")?"Hide tool":"Show tool");aa[ae]=function(){if(!ab.dynamic_tool_div.is(":visible")){ab.update_name(ab.name+ab.tool_region_and_parameters_str())}else{menu_option_text="Show dynamic tool";ab.revert_name()}ab.dynamic_tool_div.toggle();ab.make_name_popup_menu()}}if(ab.valid_chroms){aa["List chrom/contigs with data"]=function(){show_modal("Chrom/contigs with data","<p>"+ab.valid_chroms.join("<br/>")+"</p>",{Close:function(){hide_modal()}})}}var ac=view;var ad=function(){$("#no-tracks").show()};if(this.parent_track){ac=this.parent_track;ad=function(){}}aa.Remove=function(){ac.remove_track(ab);if(ac.num_tracks===0){ad()}};make_popupmenu(ab.name_div,aa)},draw:function(aa,ac){if(!this.dataset_id){return}var au=this.view.low,ag=this.view.high,ai=ag-au,ak=this.view.container.width(),ae=ak/ai,al=this.view.resolution,ad=$("<div style='position: relative;'></div>"),am=function(aw,ax,av){return aw+"_"+ax+"_"+av};if(!ac){this.content_div.children().remove()}this.content_div.append(ad);this.max_height=0;var ao=Math.floor(au/al/M);var af=[];var ap=0;while((ao*M*al)<ag){var at=am(ak,ae,ao);var ah=this.tile_cache.get(at);var aq=ao*M*this.view.resolution;var ab=aq+M*this.view.resolution;if(!aa&&ah){af[af.length]=ah;this.show_tile(ah,ad,ae)}else{this.delayed_draw(aa,at,ao,al,ad,ae,af)}ao+=1;ap++}var aj=this;var ar=setInterval(function(){if(af.length===ap){clearInterval(ar);if(ac){var aA=aj.content_div.children();var aB=false;for(var az=aA.length-1,aF=0;az>=aF;az--){var ay=$(aA[az]);if(aB){ay.remove()}else{if(ay.children().length!==0){aB=true}}}}if(aj instanceof e&&aj.mode=="Histogram"){var aE=-1;for(var az=0;az<af.length;az++){var aH=af[az].max_val;if(aH>aE){aE=aH}}for(var az=0;az<af.length;az++){if(af[az].max_val!==aE){var aG=af[az];aG.canvas.remove();aj.delayed_draw(true,am(ak,ae,aG.index),aG.index,aG.resolution,ad,ae,[],{max:aE})}}}if(aj.filters_manager){var ax=aj.filters_manager.filters;for(var aD=0;aD<ax.length;aD++){ax[aD].update_ui_elt()}var aC=false;if(aj.example_feature){for(var aD=0;aD<ax.length;aD++){if(ax[aD].applies_to(aj.example_feature)){aC=true;break}}}if(aj.filters_available!==aC){aj.filters_available=aC;if(!aj.filters_available){aj.filters_div.hide()}aj.make_name_popup_menu()}}var av=false;for(var aw=0;aw<af.length;aw++){if(af[aw].message){av=true;break}}if(av){for(var aw=0;aw<af.length;aw++){aG=af[aw];if(!aG.message){aG.canvas.css("padding-top",A)}}}}},50);for(var an=0;an<this.child_tracks.length;an++){this.child_tracks[an].draw(aa,ac)}},delayed_draw:function(ab,ai,ac,ae,aj,am,ak,af){var ad=this,ag=ac*M*ae,al=ag+M*ae;var ah=function(av,an,ap,ao,at,au,aq){var ar=ad.draw_tile(an,ap,ao,au,aq);ad.tile_cache.set(ai,ar);if(ar===undefined){return}ad.show_tile(ar,at,au);ak[ak.length]=ar};var aa=setTimeout(function(){if(ag<=ad.view.high&&al>=ad.view.low){var an=(ab?undefined:ad.tile_cache.get(ai));if(an){ad.show_tile(an,aj,am);ak[ak.length]=an}else{$.when(ad.data_manager.get_data(ag,al,ae,ad.data_url_extra_params)).then(function(ao){n(ao,af);if(view.reference_track&&am>view.canvas_manager.char_width_px){$.when(view.reference_track.data_manager.get_data(ag,al,ae,view.reference_track.data_url_extra_params)).then(function(ap){ah(aa,ao,ae,ac,aj,am,ap)})}else{ah(aa,ao,ae,ac,aj,am)}})}}},50)},show_tile:function(ag,ai,aj){var ab=this,aa=ag.canvas,ae=aa;if(ag.message){var ak=$("<div/>"),ah=$("<div/>").addClass("tile-message").text(ag.message).css({height:A-1,width:ag.canvas.width}).appendTo(ak),af=$("<div/>").text("Show more").addClass("action-button").css({"padding-top":0,"padding-bottom":0}).appendTo(ah);ak.append(aa);ae=ak;af.click(function(){ag.stale=true;ab.data_manager.get_more_data(ag.low,ag.high,ag.resolution,{},ab.data_manager.DEEP_DATA_REQ);ab.draw()}).dblclick(function(al){al.stopPropagation()})}var ad=this.view.high-this.view.low,ac=(ag.low-this.view.low)*aj;if(this.left_offset){ac-=this.left_offset}ae.css({position:"absolute",top:0,left:ac,height:""});ai.append(ae);ab.max_height=Math.max(ab.max_height,ae.height());ab.content_div.css("height",ab.max_height+"px");ai.children().css("height",ab.max_height+"px")},set_overview:function(){var aa=this.view;if(this.initial_canvas&&this.is_overview){aa.overview_close.show();aa.overview_viewport.append(this.initial_canvas);aa.overview_highlight.show().height(this.initial_canvas.height());aa.overview_viewport.height(this.initial_canvas.height()+aa.overview_box.height())}$(window).trigger("resize")},tool_region_and_parameters_str:function(ac,aa,ad){var ab=this,ae=(ac!==undefined&&aa!==undefined&&ad!==undefined?ac+":"+aa+"-"+ad:"all");return" - region=["+ae+"], parameters=["+ab.tool.get_param_values().join(", ")+"]"},add_track:function(aa){aa.track_id=this.track_id+"_"+this.child_tracks.length;aa.container_div.attr("id","track_"+aa.track_id);this.child_tracks_container.append(aa.container_div);C(aa.container_div,".child-track-icon");if(!$(this.child_tracks_container).is(":visible")){this.child_tracks_container.show()}this.child_tracks.push(aa);this.view.has_changes=true},remove_track:function(aa){aa.container_div.fadeOut("slow",function(){$(this).remove()})}});var X=function(aa,ab){this.hidden=true;j.call(this,null,aa,ab);this.container_div.addClass("label-track")};n(X.prototype,j.prototype,{draw:function(){var ac=this.view,ad=ac.high-ac.low,ag=Math.floor(Math.pow(10,Math.floor(Math.log(ad)/Math.log(10)))),aa=Math.floor(ac.low/ag)*ag,ae=this.view.container.width(),ab=$("<div style='position: relative; height: 1.3em;'></div>");while(aa<ac.high){var af=(aa-ac.low)/ad*ae;ab.append($("<div class='label'>"+commatize(aa)+"</div>").css({position:"absolute",left:af-1}));aa+=ag}this.content_div.children(":first").remove();this.content_div.append(ab)}});var x=function(aa){this.hidden=true;j.call(this,null,aa,aa.top_labeltrack);J.call(this);aa.reference_track=this;this.left_offset=200;this.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:aa.dbkey};this.data_manager=new E(y,this,false);this.tile_cache=new c(r)};n(x.prototype,J.prototype,{draw_tile:function(ai,af,ab,ak){var ae=this,ac=M*af;if(ak>this.view.canvas_manager.char_width_px){if(ai===null){ae.content_div.css("height","0px");return}var ad=this.view.canvas_manager.new_canvas();var aj=ad.getContext("2d");ad.width=Math.ceil(ac*ak+ae.left_offset);ad.height=ae.height_px;aj.font=aj.canvas.manager.default_font;aj.textAlign="center";for(var ag=0,ah=ai.length;ag<ah;ag++){var aa=Math.round(ag*ak);aj.fillText(ai[ag],aa+ae.left_offset,10)}return new b(ab,af,ad)}this.content_div.css("height","0px")}});var k=function(ae,ac,af,aa,ad){var ab=this;this.display_modes=["Histogram","Line","Filled","Intensity"];this.mode="Histogram";j.call(this,ae,ac,ac.viewport_container);J.call(this);this.min_height_px=16;this.max_height_px=400;this.height_px=80;this.hda_ldda=af;this.dataset_id=aa;this.original_dataset_id=aa;this.data_manager=new N(y,this);this.tile_cache=new c(r);this.track_config=new V({track:this,params:[{key:"color",label:"Color",type:"color",default_value:"black"},{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:this.height_px,hidden:true}],saved_values:ad,onchange:function(){ab.vertical_range=ab.prefs.max_value-ab.prefs.min_value;$("#linetrack_"+ab.track_id+"_minval").text(ab.prefs.min_value);$("#linetrack_"+ab.track_id+"_maxval").text(ab.prefs.max_value);ab.tile_cache.clear();ab.draw()}});this.prefs=this.track_config.values;this.height_px=this.track_config.values.height;this.vertical_range=this.track_config.values.max_value-this.track_config.values.min_value;this.add_resize_handle()};n(k.prototype,J.prototype,{add_resize_handle:function(){var aa=this;var ad=false;var ac=false;var ab=$("<div class='track-resize'>");$(aa.container_div).hover(function(){ad=true;ab.show()},function(){ad=false;if(!ac){ab.hide()}});ab.hide().bind("dragstart",function(ae,af){ac=true;af.original_height=$(aa.content_div).height()}).bind("drag",function(af,ag){var ae=Math.min(Math.max(ag.original_height+ag.deltaY,aa.min_height_px),aa.max_height_px);$(aa.content_div).css("height",ae);aa.height_px=ae;aa.draw(true)}).bind("dragend",function(ae,af){aa.tile_cache.clear();ac=false;if(!ad){ab.hide()}aa.track_config.values.height=aa.height_px}).appendTo(aa.container_div)},predraw_init:function(){var aa=this,ab=aa.view.tracks.indexOf(aa);aa.vertical_range=undefined;return $.getJSON(aa.data_url,{stats:true,chrom:aa.view.chrom,low:null,high:null,hda_ldda:aa.hda_ldda,dataset_id:aa.dataset_id},function(ac){aa.container_div.addClass("line-track");var ae=ac.data;if(isNaN(parseFloat(aa.prefs.min_value))||isNaN(parseFloat(aa.prefs.max_value))){aa.prefs.min_value=ae.min;aa.prefs.max_value=ae.max;$("#track_"+ab+"_minval").val(aa.prefs.min_value);$("#track_"+ab+"_maxval").val(aa.prefs.max_value)}aa.vertical_range=aa.prefs.max_value-aa.prefs.min_value;aa.total_frequency=ae.total_frequency;aa.container_div.find(".yaxislabel").remove();var af=$("<div />").addClass("yaxislabel").attr("id","linetrack_"+ab+"_minval").text(u(aa.prefs.min_value));var ad=$("<div />").addClass("yaxislabel").attr("id","linetrack_"+ab+"_maxval").text(u(aa.prefs.max_value));ad.css({position:"absolute",top:"24px",left:"10px"});ad.prependTo(aa.container_div);af.css({position:"absolute",bottom:"2px",left:"10px"});af.prependTo(aa.container_div)})},draw_tile:function(ak,ae,ab,aj){if(this.vertical_range===undefined){return}var af=ab*M*ae,ad=M*ae,aa=Math.ceil(ad*aj),ah=this.height_px;var ac=this.view.canvas_manager.new_canvas();ac.width=aa,ac.height=ah;var ai=ac.getContext("2d");var ag=new I.LinePainter(ak.data,af,af+ad,this.prefs,this.mode);ag.draw(ai,aa,ah);return new b(ab,ae,ac)}});var e=function(aa,af,ae,ai,ah,ac,ad,ag){var ab=this;this.display_modes=["Auto","Histogram","Dense","Squish","Pack"];this.track_config=new V({track:this,params:[{key:"block_color",label:"Block color",type:"color",default_value:"#444"},{key:"label_color",label:"Label color",type:"color",default_value:"black"},{key:"show_counts",label:"Show summary counts",type:"bool",default_value:true},{key:"mode",type:"string",default_value:this.mode,hidden:true},],saved_values:ah,onchange:function(){ab.tile_cache.clear();ab.draw()}});this.prefs=this.track_config.values;j.call(this,aa,af,af.viewport_container);J.call(this,ac,ad,ag);this.height_px=0;this.container_div.addClass("feature-track");this.hda_ldda=ae;this.dataset_id=ai;this.original_dataset_id=ai;this.show_labels_scale=0.001;this.showing_details=false;this.summary_draw_height=30;this.inc_slots={};this.start_end_dct={};this.tile_cache=new c(d);this.data_manager=new N(20,this);this.left_offset=200;this.painter=I.LinkedFeaturePainter};n(e.prototype,J.prototype,{update_auto_mode:function(aa){if(this.mode=="Auto"){if(aa=="no_detail"){aa="feature spans"}else{if(aa=="summary_tree"){aa="coverage histogram"}}this.mode_div.text("Auto ("+aa+")")}},incremental_slots:function(ae,ab,ad){var ac=this.view.canvas_manager.dummy_context,aa=this.inc_slots[ae];if(!aa||(aa.mode!==ad)){aa=new (p.FeatureSlotter)(ae,ad==="Pack",w,function(af){return ac.measureText(af)});aa.mode=ad;this.inc_slots[ae]=aa}return aa.slot_features(ab)},get_summary_tree_data:function(ae,ah,ac,ap){if(ap>ac-ah){ap=ac-ah}var al=Math.floor((ac-ah)/ap),ao=[],ad=0;var af=0,ag=0,ak,an=0,ai=[],am,aj;var ab=function(at,ar,au,aq){at[0]=ar+au*aq;at[1]=ar+(au+1)*aq};while(an<ap&&af!==ae.length){var aa=false;for(;an<ap&&!aa;an++){ab(ai,ah,an,al);for(ag=af;ag<ae.length;ag++){ak=ae[ag].slice(1,3);if(is_overlap(ak,ai)){aa=true;break}}if(aa){break}}data_start_index=ag;ao[ao.length]=am=[ai[0],0];for(;ag<ae.length;ag++){ak=ae[ag].slice(1,3);if(is_overlap(ak,ai)){am[1]++}else{break}}if(am[1]>ad){ad=am[1]}an++}return{max:ad,delta:al,data:ao}},draw_tile:function(an,av,az,aj,ad){var ar=this,aB=az*M*av,ab=(az+1)*M*av,ap=ab-aB,at=Math.ceil(ap*aj),aq=this.mode,aF=25,ae=this.left_offset,ao,af;if(aq==="Auto"){if(an.dataset_type==="summary_tree"){aq=an.dataset_type}else{if(an.extra_info==="no_detail"){aq="no_detail"}else{var aE=an.data;if(this.view.high-this.view.low>F){aq="Squish"}else{aq="Pack"}}}this.update_auto_mode(aq)}if(aq==="summary_tree"||aq==="Histogram"){af=this.summary_draw_height;this.container_div.find(".yaxislabel").remove();var aa=$("<div />").addClass("yaxislabel");aa.text(an.max);aa.css({position:"absolute",top:"24px",left:"10px",color:this.prefs.label_color});aa.prependTo(this.container_div);var ac=this.view.canvas_manager.new_canvas();ac.width=at+ae;ac.height=af+O;if(an.dataset_type!="summary_tree"){var ak=this.get_summary_tree_data(an.data,aB,ab,200);if(an.max){ak.max=an.max}an=ak}var aC=new I.SummaryTreePainter(an,aB,ab,this.prefs);var au=ac.getContext("2d");au.translate(ae,O);aC.draw(au,at,af);return new l(az,av,ac,an.max)}var ao,ah=1;if(aq==="no_detail"||aq==="Squish"||aq==="Pack"){ah=this.incremental_slots(aj,an.data,aq);ao=this.inc_slots[aj].slots}var ai=[];if(an.data){var al=this.filters_manager.filters;for(var aw=0,ay=an.data.length;aw<ay;aw++){var ag=an.data[aw];var ax=false;var am;for(var aA=0,aD=al.length;aA<aD;aA++){am=al[aA];am.update_attrs(ag);if(!am.keep(ag)){ax=true;break}}if(!ax){ai.push(ag)}}}var aC=new (this.painter)(ai,aB,ab,this.prefs,aq,ad);var af=aC.get_required_height(ah);var ac=this.view.canvas_manager.new_canvas();ac.width=at+ae;ac.height=af;var au=ac.getContext("2d");au.fillStyle=this.prefs.block_color;au.font=au.canvas.manager.default_font;au.textAlign="right";this.container_div.find(".yaxislabel").remove();if(an.data){this.example_feature=(an.data.length?an.data[0]:undefined);au.translate(ae,0);aC.draw(au,at,af,ao)}return new L(az,av,ac,an.message)}});var P=function(ad,ab,af,aa,ac,ae){e.call(this,ad,ab,af,aa,ac,ae);this.painter=I.VariantPainter};n(P.prototype,J.prototype,e.prototype);var S=function(ad,ab,af,aa,ac,ae){e.call(this,ad,ab,af,aa,ac,ae);this.track_config=new V({track:this,params:[{key:"block_color",label:"Block color",type:"color",default_value:"#444"},{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:"mode",type:"string",default_value:this.mode,hidden:true},],saved_values:ac,onchange:function(){this.track.tile_cache.clear();this.track.draw()}});this.prefs=this.track_config.values;this.painter=I.ReadPainter;this.make_name_popup_menu()};n(S.prototype,J.prototype,e.prototype);var Q=function(ae,ac,ag,aa,ad,af,ab){e.call(this,ae,ac,ag,aa,ad,af,{},ab);this.data_url=raw_data_url;this.data_query_wait=1000;this.dataset_check_url=dataset_state_url};n(Q.prototype,J.prototype,e.prototype,{predraw_init:function(){var ab=this;var aa=function(){if(ab.data_manager.size()===0){setTimeout(aa,300)}else{ab.data_url=default_data_url;ab.data_query_wait=H;ab.dataset_state_url=converted_datasets_state_url;$.getJSON(ab.dataset_state_url,{dataset_id:ab.dataset_id,hda_ldda:ab.hda_ldda},function(ac){})}};aa()}});T.View=Y;T.LineTrack=k;T.FeatureTrack=e;T.ReadTrack=S};var slotting_module=function(c,b){var e=c("class").extend;var d=2,a=5;b.FeatureSlotter=function(j,h,f,g){this.slots={};this.start_end_dct={};this.w_scale=j;this.include_label=h;this.max_rows=f;this.measureText=g};e(b.FeatureSlotter.prototype,{slot_features:function(m){var p=this.w_scale,s=this.slots,h=this.start_end_dct,y=[],A=[],n=0,z=this.max_rows;for(var w=0,x=m.length;w<x;w++){var l=m[w],o=l[0];if(s[o]!==undefined){n=Math.max(n,s[o]);A.push(s[o])}else{y.push(w)}}var q=function(G,H){for(var F=0;F<=z;F++){var D=false,I=h[F];if(I!==undefined){for(var C=0,E=I.length;C<E;C++){var B=I[C];if(H>B[0]&&G<B[1]){D=true;break}}}if(!D){return F}}return -1};for(var w=0,x=y.length;w<x;w++){var l=m[y[w]],o=l[0],u=l[1],f=l[2],r=l[3],g=Math.floor(u*p),k=Math.ceil(f*p),v=this.measureText(r).width,j;if(r!==undefined&&this.include_label){v+=(d+a);if(g-v>=0){g-=v;j="left"}else{k+=v;j="right"}}var t=q(g,k);if(t>=0){if(h[t]===undefined){h[t]=[]}h[t].push([g,k]);s[o]=t;n=Math.max(n,t)}else{}}return n+1}})};var painters_module=function(j,w){var t=j("class").extend;var o=function(H,z,F,y,E,C){if(C===undefined){C=4}var B=y-z;var A=E-F;var D=Math.floor(Math.sqrt(B*B+A*A)/C);var I=B/D;var G=A/D;var x;for(x=0;x<D;x++,z+=I,F+=G){if(x%2!==0){continue}H.fillRect(z,F,C,1)}};var p=function(A,z,x,D){var C=z-D/2,B=z+D/2,E=x-Math.sqrt(D*3/2);A.beginPath();A.moveTo(C,E);A.lineTo(B,E);A.lineTo(z,x);A.lineTo(C,E);A.strokeStyle=this.fillStyle;A.fill();A.stroke();A.closePath()};var m=function(z,B,x,y,A){this.data=z;this.view_start=B;this.view_end=x;this.prefs=t({},this.default_prefs,y);this.mode=A};m.prototype.default_prefs={};var u=function(z,B,x,y,A){m.call(this,z,B,x,y,A)};u.prototype.default_prefs={show_counts:false};u.prototype.draw=function(M,z,L){var E=this.view_start,O=this.view_end-this.view_start,N=z/O;var J=this.data.data,I=this.data.delta,G=this.data.max,B=L;delta_x_px=Math.ceil(I*N);M.save();for(var C=0,D=J.length;C<D;C++){var H=Math.floor((J[C][0]-E)*N);var F=J[C][1];if(!F){continue}var K=F/G*L;if(F!==0&&K<1){K=1}M.fillStyle=this.prefs.block_color;M.fillRect(H,B-K,delta_x_px,K);var A=4;if(this.prefs.show_counts&&(M.measureText(F).width+A)<delta_x_px){M.fillStyle=this.prefs.label_color;M.textAlign="center";M.fillText(F,H+(delta_x_px/2),10)}}M.restore()};var c=function(x,B,D,E,z){m.call(this,x,B,D,E,z);if(this.prefs.min_value===undefined){var F=Infinity;for(var y=0,A=this.data.length;y<A;y++){F=Math.min(F,this.data[y][1])}this.prefs.min_value=F}if(this.prefs.max_value===undefined){var C=-Infinity;for(var y=0,A=this.data.length;y<A;y++){C=Math.max(C,this.data[y][1])}this.prefs.max_value=C}};c.prototype.default_prefs={min_value:undefined,max_value:undefined,mode:"Histogram",color:"#000",overflow_color:"#F66"};c.prototype.draw=function(M,L,J){var E=false,G=this.prefs.min_value,C=this.prefs.max_value,I=C-G,x=J,z=this.view_start,K=this.view_end-this.view_start,A=L/K,H=this.mode,S=this.data;M.save();var T=Math.round(J+G/I*J);if(H!=="Intensity"){M.fillStyle="#aaa";M.fillRect(0,T,L,1)}M.beginPath();var Q,D,B;if(S.length>1){B=Math.ceil((S[1][0]-S[0][0])*A)}else{B=10}for(var N=0,O=S.length;N<O;N++){M.fillStyle=this.prefs.color;Q=Math.round((S[N][0]-z)*A);D=S[N][1];var P=false,F=false;if(D===null){if(E&&H==="Filled"){M.lineTo(Q,x)}E=false;continue}if(D<G){F=true;D=G}else{if(D>C){P=true;D=C}}if(H==="Histogram"){D=Math.round(D/I*x);M.fillRect(Q,T,B,-D)}else{if(H==="Intensity"){D=255-Math.floor((D-G)/I*255);M.fillStyle="rgb("+D+","+D+","+D+")";M.fillRect(Q,0,B,x)}else{D=Math.round(x-(D-G)/I*x);if(E){M.lineTo(Q,D)}else{E=true;if(H==="Filled"){M.moveTo(Q,x);M.lineTo(Q,D)}else{M.moveTo(Q,D)}}}}M.fillStyle=this.prefs.overflow_color;if(P||F){var R;if(H==="Histogram"||H==="Intensity"){R=B}else{Q-=2;R=4}if(P){M.fillRect(Q,0,R,3)}if(F){M.fillRect(Q,x-3,R,3)}}M.fillStyle=this.prefs.color}if(H==="Filled"){if(E){M.lineTo(Q,T);M.lineTo(0,T)}M.fill()}else{M.stroke()}M.restore()};var n=function(z,B,x,y,A){m.call(this,z,B,x,y,A)};n.prototype.default_prefs={block_color:"#FFF",connector_color:"#FFF"};t(n.prototype,{get_required_height:function(y){var x=y_scale=this.get_row_height(),z=this.mode;if(z==="no_detail"||z==="Squish"||z==="Pack"){x=y*y_scale}return x+Math.max(Math.round(y_scale/2),5)},draw:function(J,A,I,F){var D=this.data,G=this.view_start,K=this.view_end;J.save();J.fillStyle=this.prefs.block_color;J.textAlign="right";var N=this.view_end-this.view_start,M=A/N,z=this.get_row_height();for(var C=0,E=D.length;C<E;C++){var L=D[C],B=L[0],x=L[1],y=L[2],H=(F&&F[B]!==undefined?F[B]:null);if((x<K&&y>G)&&(this.mode=="Dense"||H!==null)){this.draw_element(J,this.mode,L,H,G,K,M,z,A)}}J.restore()}});var d=10,h=3,l=5,v=10,f=1,r=3,e=3,a=9,k=2,g="#ccc";var q=function(z,B,x,y,A){n.call(this,z,B,x,y,A)};t(q.prototype,n.prototype,{get_row_height:function(){var y=this.mode,x;if(y==="Dense"){x=d}else{if(y==="no_detail"){x=h}else{if(y==="Squish"){x=l}else{x=v}}}return x},draw_element:function(J,C,R,E,L,ab,af,ag,x){var O=R[0],ad=R[1],V=R[2],M=R[3],W=Math.floor(Math.max(0,(ad-L)*af)),K=Math.ceil(Math.min(x,Math.max(0,(V-L)*af))),U=(C==="Dense"?0:(0+E))*ag,I,Z,N=null,ah=null,A=this.prefs.block_color,Y=this.prefs.label_color;if(C=="Dense"){E=1}if(C==="no_detail"){J.fillStyle=A;J.fillRect(W,U+5,K-W,f)}else{var H=R[4],T=R[5],X=R[6],B=R[7];if(T&&X){N=Math.floor(Math.max(0,(T-L)*af));ah=Math.ceil(Math.min(x,Math.max(0,(X-L)*af)))}var ae,P;if(C==="Squish"||C==="Dense"){ae=1;P=e}else{ae=5;P=a}if(!B){if(R.strand){if(R.strand==="+"){J.fillStyle=J.canvas.manager.get_pattern("right_strand_inv")}else{if(R.strand==="-"){J.fillStyle=J.canvas.manager.get_pattern("left_strand_inv")}}}else{J.fillStyle=A}J.fillRect(W,U,K-W,P)}else{var G,Q;if(C==="Squish"||C==="Dense"){J.fillStyle=g;G=U+Math.floor(e/2)+1;Q=1}else{if(H){var G=U;var Q=P;if(H==="+"){J.fillStyle=J.canvas.manager.get_pattern("right_strand")}else{if(H==="-"){J.fillStyle=J.canvas.manager.get_pattern("left_strand")}}}else{J.fillStyle=g;G+=(e/2)+1;Q=1}}J.fillRect(W,G,K-W,Q);for(var ac=0,z=B.length;ac<z;ac++){var D=B[ac],y=Math.floor(Math.max(0,(D[0]-L)*af)),S=Math.ceil(Math.min(x,Math.max((D[1]-L)*af)));if(y>S){continue}J.fillStyle=A;J.fillRect(y,U+(P-ae)/2+1,S-y,ae);if(N!==undefined&&X>T&&!(y>ah||S<N)){var aa=Math.max(y,N),F=Math.min(S,ah);J.fillRect(aa,U+1,F-aa,P);if(B.length==1&&C=="Pack"){if(H==="+"){J.fillStyle=J.canvas.manager.get_pattern("right_strand_inv")}else{if(H==="-"){J.fillStyle=J.canvas.manager.get_pattern("left_strand_inv")}}if(aa+14<F){aa+=2;F-=2}J.fillRect(aa,U+1,F-aa,P)}}}}if(C==="Pack"&&ad>L){J.fillStyle=Y;if(L===0&&W-J.measureText(M).width<0){J.textAlign="left";J.fillText(M,K+k,U+8)}else{J.textAlign="right";J.fillText(M,W-k,U+8)}J.fillStyle=A}}}});var b=function(z,B,x,y,A){n.call(this,z,B,x,y,A)};t(b.prototype,n.prototype,{draw_element:function(Q,L,F,B,T,z,I,R,O){var F=data[i],H=F[0],P=F[1],A=F[2],K=F[3],D=Math.floor(Math.max(0,(P-T)*I)),G=Math.ceil(Math.min(O,Math.max(0,(A-T)*I))),C=(L==="Dense"?0:(0+B))*R,x,U,y=null,J=null;if(no_label){Q.fillStyle=block_color;Q.fillRect(D+left_offset,C+5,G-D,1)}else{var S=F[4],N=F[5],E=F[6];x=9;U=1;Q.fillRect(D+left_offset,C,G-D,x);if(L!=="Dense"&&K!==undefined&&P>T){Q.fillStyle=label_color;if(T===0&&D-Q.measureText(K).width<0){Q.textAlign="left";Q.fillText(K,G+2+left_offset,C+8)}else{Q.textAlign="right";Q.fillText(K,D-2+left_offset,C+8)}Q.fillStyle=block_color}var M=S+" / "+N;if(P>T&&Q.measureText(M).width<(G-D)){Q.fillStyle="white";Q.textAlign="center";Q.fillText(M,left_offset+D+(G-D)/2,C+8);Q.fillStyle=block_color}}}});var s=function(A,C,x,z,B,y){n.call(this,A,C,x,z,B);this.ref_seq=y};s.prototype.default_prefs=t({},n.prototype.default_prefs,{show_insertions:false});t(s.prototype,n.prototype,{get_row_height:function(){var x,y=this.mode;if(y==="Dense"){x=d}else{if(y==="Squish"){x=l}else{x=v;if(this.prefs.show_insertions){x*=2}}}return x},draw_read:function(T,O,K,Y,z,S,H,E,D){T.textAlign="center";var R=this,y=[Y,z],N=0,U=0,Q=0;ref_seq=this.ref_seq,char_width_px=T.canvas.manager.char_width_px;var ad=[];if((O==="Pack"||this.mode==="Auto")&&E!==undefined&&K>char_width_px){Q=Math.round(K/2)}if(!H){H=[[0,E.length]]}for(var L=0,W=H.length;L<W;L++){var I=H[L],A="MIDNSHP=X"[I[0]],M=I[1];if(A==="H"||A==="S"){N-=M}var F=S+N,ac=Math.floor(Math.max(0,(F-Y)*K)),G=Math.floor(Math.max(0,(F+M-Y)*K));if(ac===G){G+=1}switch(A){case"H":break;case"S":case"M":case"=":if(is_overlap([F,F+M],y)){var P=E.slice(U,U+M);if(Q>0){T.fillStyle=this.prefs.block_color;T.fillRect(ac-Q,D+1,G-ac,9);T.fillStyle=g;for(var aa=0,x=P.length;aa<x;aa++){if(this.prefs.show_differences&&ref_seq){var J=ref_seq[F-Y+aa];if(!J||J.toLowerCase()===P[aa].toLowerCase()){continue}}if(F+aa>=Y&&F+aa<=z){var ab=Math.floor(Math.max(0,(F+aa-Y)*K));T.fillText(P[aa],ab,D+9)}}}else{T.fillStyle=this.prefs.block_color;T.fillRect(ac,D+4,G-ac,e)}}U+=M;N+=M;break;case"N":T.fillStyle=g;T.fillRect(ac-Q,D+5,G-ac,1);N+=M;break;case"D":T.fillStyle="red";T.fillRect(ac-Q,D+4,G-ac,3);N+=M;break;case"P":break;case"I":var X=ac-Q;if(is_overlap([F,F+M],y)){var P=E.slice(U,U+M);if(this.prefs.show_insertions){var C=ac-(G-ac)/2;if((O==="Pack"||this.mode==="Auto")&&E!==undefined&&K>char_width_px){T.fillStyle="yellow";T.fillRect(C-Q,D-9,G-ac,9);ad[ad.length]={type:"triangle",data:[X,D+4,5]};T.fillStyle=g;switch(seq_tile_overlap){case (OVERLAP_START):P=P.slice(Y-F);break;case (OVERLAP_END):P=P.slice(0,F-z);break;case (CONTAINED_BY):break;case (CONTAINS):P=P.slice(Y-F,F-z);break}for(var aa=0,x=P.length;aa<x;aa++){var ab=Math.floor(Math.max(0,(F+aa-Y)*K));T.fillText(P[aa],ab-(G-ac)/2,D)}}else{T.fillStyle="yellow";T.fillRect(C,D+(this.mode!=="Dense"?2:5),G-ac,(O!=="Dense"?e:r))}}else{if((O==="Pack"||this.mode==="Auto")&&E!==undefined&&K>char_width_px){ad[ad.length]={type:"text",data:[P.length,X,D+9]}}else{}}}U+=M;break;case"X":U+=M;break}}T.fillStyle="yellow";var Z,B,ae;for(var V=0;V<ad.length;V++){Z=ad[V];B=Z.type;ae=Z.data;if(B==="text"){T.save();T.font="bold "+T.font;T.fillText(ae[0],ae[1],ae[2]);T.restore()}else{if(B=="triangle"){p(T,ae[0],ae[1],ae[2])}}}},draw_element:function(Q,L,D,A,T,y,H,R,O){var G=D[0],P=D[1],z=D[2],I=D[3],C=Math.floor(Math.max(0,(P-T)*H)),E=Math.ceil(Math.min(O,Math.max(0,(z-T)*H))),B=(L==="Dense"?0:(0+A))*R,U=this.prefs.block_color,F=this.prefs.label_color,N=0;if((L==="Pack"||this.mode==="Auto")&&H>Q.canvas.manager.char_width_px){var N=Math.round(H/2)}Q.fillStyle=U;if(D[5] instanceof Array){var M=Math.floor(Math.max(0,(D[4][0]-T)*H)),K=Math.ceil(Math.min(O,Math.max(0,(D[4][1]-T)*H))),J=Math.floor(Math.max(0,(D[5][0]-T)*H)),x=Math.ceil(Math.min(O,Math.max(0,(D[5][1]-T)*H)));if(D[4][1]>=T&&D[4][0]<=y&&D[4][2]){this.draw_read(Q,L,H,T,y,D[4][0],D[4][2],D[4][3],B)}if(D[5][1]>=T&&D[5][0]<=y&&D[5][2]){this.draw_read(Q,L,H,T,y,D[5][0],D[5][2],D[5][3],B)}if(J>K){Q.fillStyle=g;o(Q,K-N,B+5,J-N,B+5)}}else{Q.fillStyle=U;this.draw_read(Q,L,H,T,y,P,D[4],D[5],B)}if(L==="Pack"&&P>T){Q.fillStyle=this.prefs.label_color;var S=1;if(S===0&&C-Q.measureText(I).width<0){Q.textAlign="left";Q.fillText(I,E+k-N,B+8)}else{Q.textAlign="right";Q.fillText(I,C-k-N,B+8)}Q.fillStyle=U}}});w.SummaryTreePainter=u;w.LinePainter=c;w.LinkedFeaturePainter=q;w.ReadPainter=s;w.VariantPainter=b};(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
--- a/static/scripts/trackster.js Wed Jul 06 09:52:28 2011 -0400
+++ b/static/scripts/trackster.js Wed Jul 06 10:20:57 2011 -0400
@@ -370,10 +370,8 @@
// Set parameters based on request type.
//
if (req_type === this.DEEP_DATA_REQ) {
- // HACK: for now, just up the max vals and request all data; in the future,
- // need server to recognize min_vals and max_vals to specify range of data to
- // return.
- $.extend(extra_params, {max_vals: cur_data.data.length * 2});
+ // Use same interval but set start_val to skip data that's already in cur_data.
+ $.extend(extra_params, {start_val: cur_data.data.length + 1});
}
else if (req_type === this.BROAD_DATA_REQ) {
// Set low to be past the last feature returned.
@@ -393,7 +391,7 @@
this.set_data(low, high, mode, new_data_available);
$.when(new_data_request).then(function(result) {
if (result.data) {
- //result.data.append(cur_data.data);
+ result.data = cur_data.data.concat(result.data);
}
data_manager.set_data(low, high, mode, result);
new_data_available.resolve(result);
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: Add patch from Assaf Gordon to fix the cleanup_dataset.py script, correcting the behavior of setting the info_only flag to True when running delete_datasets.sh and purge_datasets.sh.
by Bitbucket 06 Jul '11
by Bitbucket 06 Jul '11
06 Jul '11
1 new changeset in galaxy-central:
http://bitbucket.org/galaxy/galaxy-central/changeset/a5e0a5d3c0a1/
changeset: a5e0a5d3c0a1
user: greg
date: 2011-07-06 15:52:28
summary: Add patch from Assaf Gordon to fix the cleanup_dataset.py script, correcting the behavior of setting the info_only flag to True when running delete_datasets.sh and purge_datasets.sh.
affected #: 1 file (265 bytes)
--- a/scripts/cleanup_datasets/cleanup_datasets.py Wed Jul 06 09:45:41 2011 +1000
+++ b/scripts/cleanup_datasets/cleanup_datasets.py Wed Jul 06 09:52:28 2011 -0400
@@ -411,10 +411,13 @@
app.sa_session.add( metadata_file )
app.sa_session.flush()
print "%s" % metadata_file.file_name
- print "Deleting dataset id", dataset.id
- dataset.deleted = True
- app.sa_session.add( dataset )
- app.sa_session.flush()
+ if not info_only:
+ print "Deleting dataset id", dataset.id
+ dataset.deleted = True
+ app.sa_session.add( dataset )
+ app.sa_session.flush()
+ else:
+ print "Dataset %i will be deleted (without 'info_only' mode)" % ( dataset.id )
def _purge_dataset( app, dataset, remove_from_disk, info_only = False ):
if dataset.deleted:
@@ -433,6 +436,8 @@
dataset.purged = True
app.sa_session.add( dataset )
app.sa_session.flush()
+ else:
+ print "Dataset %i will be purged (without 'info_only' mode)" % (dataset.id)
else:
print "This dataset (%i) is not purgable, the file (%s) will not be removed.\n" % ( dataset.id, dataset.file_name )
except OSError, exc:
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 changesets in galaxy-central:
http://bitbucket.org/galaxy/galaxy-central/changeset/94e63070cbb1/
changeset: 94e63070cbb1
user: fubar
date: 2011-07-06 01:44:56
summary: Backed out changeset 48bbe32beefe which introduced a whole bunch of unintended reversions from a broken hg repository
This is a backout of commit 5765
affected #: 250 files (5.2 KB)
--- a/lib/galaxy/security/__init__.py Tue Jul 05 12:40:43 2011 +1000
+++ b/lib/galaxy/security/__init__.py Wed Jul 06 09:44:56 2011 +1000
@@ -1005,8 +1005,7 @@
ucsc_main = ( 'hgw1.cse.ucsc.edu', 'hgw2.cse.ucsc.edu', 'hgw3.cse.ucsc.edu', 'hgw4.cse.ucsc.edu',
'hgw5.cse.ucsc.edu', 'hgw6.cse.ucsc.edu', 'hgw7.cse.ucsc.edu', 'hgw8.cse.ucsc.edu' ),
ucsc_test = ( 'hgwdev.cse.ucsc.edu', ),
- ucsc_archaea = ( 'lowepub.cse.ucsc.edu', ),
- ucsc_bhri = ('ucsc.omics.bhri.internal','galaxy.omics.bhri.internal'),
+ ucsc_archaea = ( 'lowepub.cse.ucsc.edu', )
)
def __init__( self, model, permitted_actions=None ):
self.model = model
@@ -1037,7 +1036,7 @@
# We're going to search in order, but if the remote site is load
# balancing their connections (as UCSC does), this is okay.
try:
- if socket.gethostbyname( server ) == addr or server == '127.0.0.1' or server == '172.16.0.38':
+ if socket.gethostbyname( server ) == addr:
break # remote host is in the server list
except ( socket.error, socket.gaierror ):
pass # can't resolve, try next
--- a/lib/galaxy/tools/__init__.py Tue Jul 05 12:40:43 2011 +1000
+++ b/lib/galaxy/tools/__init__.py Wed Jul 06 09:44:56 2011 +1000
@@ -922,8 +922,6 @@
if not self.check_values:
return
for input in self.inputs.itervalues():
- if input.name not in value:
- value[input.name] = input.get_initial_value( None, value )
if isinstance( input, ToolParameter ):
callback( "", input, value[input.name] )
else:
--- a/lib/galaxy/tools/parameters/basic.py Tue Jul 05 12:40:43 2011 +1000
+++ b/lib/galaxy/tools/parameters/basic.py Wed Jul 06 09:44:56 2011 +1000
@@ -748,6 +748,9 @@
# Dependency on a value that does not yet exist
if isinstance( dep_value, RuntimeValue ):
return True
+ #dataset not ready yet
+ if hasattr( self, 'ref_input' ) and isinstance( dep_value, self.tool.app.model.HistoryDatasetAssociation ) and ( dep_value.is_pending or not isinstance( dep_value.datatype, self.ref_input.formats ) ):
+ return True
# Dynamic, but all dependenceis are known and have values
return False
def get_initial_value( self, trans, context ):
@@ -878,6 +881,7 @@
self.force_select = string_as_bool( elem.get( "force_select", True ))
self.accept_default = string_as_bool( elem.get( "accept_default", False ))
self.data_ref = elem.get( "data_ref", None )
+ self.ref_input = None
self.default_value = elem.get( "default_value", None )
self.is_dynamic = True
def from_html( self, value, trans=None, context={} ):
@@ -973,7 +977,7 @@
if not dataset.metadata.columns:
# Only allow late validation if the dataset is not yet ready
# (since we have reason to expect the metadata to be ready eventually)
- if dataset.is_pending:
+ if dataset.is_pending or not isinstance( dataset.datatype, self.ref_input.formats ):
return True
# No late validation
return False
@@ -1353,7 +1357,7 @@
selected = ( value and ( hda in value ) )
field.add_option( "%s: %s" % ( hid, hda_name ), hda.id, selected )
else:
- target_ext, converted_dataset = hda.find_conversion_destination( self.formats, converter_safe = self.converter_safe( other_values, trans ) )
+ target_ext, converted_dataset = hda.find_conversion_destination( self.formats )
if target_ext:
if converted_dataset:
hda = converted_dataset
@@ -1402,13 +1406,22 @@
pass #no valid options
def dataset_collector( datasets ):
def is_convertable( dataset ):
- target_ext, converted_dataset = dataset.find_conversion_destination( self.formats, converter_safe = self.converter_safe( context, trans ) )
+ target_ext, converted_dataset = dataset.find_conversion_destination( self.formats )
if target_ext is not None:
return True
return False
for i, data in enumerate( datasets ):
- if data.visible and not data.deleted and data.state not in [data.states.ERROR, data.states.DISCARDED] and ( isinstance( data.datatype, self.formats) or is_convertable( data ) ):
- if self.options and self._options_filter_attribute( data ) != filter_value:
+ if data.visible and not data.deleted and data.state not in [data.states.ERROR, data.states.DISCARDED]:
+ is_valid = False
+ if isinstance( data.datatype, self.formats ):
+ is_valid = True
+ else:
+ target_ext, converted_dataset = data.find_conversion_destination( self.formats )
+ if target_ext:
+ is_valid = True
+ if converted_dataset:
+ data = converted_dataset
+ if not is_valid or ( self.options and self._options_filter_attribute( data ) != filter_value ):
continue
most_recent_dataset[0] = data
# Also collect children via association object
--- a/lib/galaxy/web/framework/middleware/remoteuser.py Tue Jul 05 12:40:43 2011 +1000
+++ b/lib/galaxy/web/framework/middleware/remoteuser.py Wed Jul 06 09:44:56 2011 +1000
@@ -36,7 +36,6 @@
"""
UCSC_MAIN_SERVERS = (
- 'omics.bhri.internal',
'hgw1.cse.ucsc.edu',
'hgw2.cse.ucsc.edu',
'hgw3.cse.ucsc.edu',
@@ -50,7 +49,6 @@
'lowepub.cse.ucsc.edu',
)
-
class RemoteUser( object ):
def __init__( self, app, maildomain=None, ucsc_display_sites=[], admin_users=[] ):
self.app = app
@@ -58,7 +56,7 @@
self.allow_ucsc_main = False
self.allow_ucsc_archaea = False
self.admin_users = admin_users
- if 'main' in ucsc_display_sites or 'test' in ucsc_display_sites or 'bhri' in ucsc_display_sites:
+ if 'main' in ucsc_display_sites or 'test' in ucsc_display_sites:
self.allow_ucsc_main = True
if 'archaea' in ucsc_display_sites:
self.allow_ucsc_archaea = True
--- a/scripts/cleanup_datasets/purge_libraries.sh Tue Jul 05 12:40:43 2011 +1000
+++ b/scripts/cleanup_datasets/purge_libraries.sh Wed Jul 06 09:44:56 2011 +1000
@@ -1,5 +1,4 @@
#!/bin/sh
cd `dirname $0`/../..
-#python ./scripts/cleanup_datasets/cleanup_datasets.py ./universe_wsgi.ini -d 10 -4 -r $@ >> ./scripts/cleanup_datasets/purge_libraries.log
-python ./scripts/cleanup_datasets/cleanup_datasets.py ./universe_wsgi.ini -d 2 -4 -r $@ >> ./scripts/cleanup_datasets/purge_libraries.log
+python ./scripts/cleanup_datasets/cleanup_datasets.py ./universe_wsgi.ini -d 10 -4 -r $@ >> ./scripts/cleanup_datasets/purge_libraries.log
--- a/tool-data/shared/ucsc/ucsc_build_sites.txt Tue Jul 05 12:40:43 2011 +1000
+++ b/tool-data/shared/ucsc/ucsc_build_sites.txt Wed Jul 06 09:44:56 2011 +1000
@@ -1,6 +1,5 @@
#Harvested from http://genome.ucsc.edu/cgi-bin/das/dsn
main http://genome.ucsc.edu/cgi-bin/hgTracks? priPac1,danRer4,mm9,mm8,droAna1,mm5,caeRem2,mm7,mm6,panTro1,dm3,panTro2,anoCar1,ce4,galGal3,galGal2,ce1,rn3,rn2,droMoj1,droMoj2,rn4,droYak1,droYak2,dp3,dp2,dm1,canFam1,danRer5,canFam2,danRer3,danRer2,ornAna1,ci2,ci1,tetNig1,bosTau1,bosTau3,bosTau2,equCab1,oryLat1,droAna2,droEre1,ponAbe2,rheMac2,sacCer1,droPer1,droSim1,monDom1,cb1,dm2,droSec1,strPur1,droVir2,droVir1,strPur2,sc1,xenTro1,droGri1,xenTro2,cb3,gasAcu1,caePb1,anoGam1,fr2,fr1,hg15,hg16,hg17,hg18,felCat3,apiMel2,monDom4,apiMel1,ce2
-bhri http://ucsc.omics.bhri.internal/cgi-bin/hgTracks? hg18,hg19,mm8,mm9,rn4
#Harvested from http://archaea.ucsc.edu/cgi-bin/das/dsn
archaea http://archaea.ucsc.edu/cgi-bin/hgTracks? alkaEhrl_MLHE_1,shewW318,idioLoih_L2TR,sulSol1,erwiCaro_ATROSEPTICA,symbTher_IAM14863,moorTher_ATCC39073,therFusc_YX,methHung1,bradJapo,therElon,shewPutrCN32,pediPent_ATCC25745,mariMari_MCS10,nanEqu1,baciSubt,chlaTrac,magnMagn_AMB_1,chroViol,ralsSola,acidCryp_JF_5,erytLito_HTCC2594,desuVulg_HILDENBOROUG,pyrAer1,sulfToko1,shewANA3,paraSp_UWE25,geobKaus_HTA426,rhizEtli_CFN_42,uncuMeth_RCI,candBloc_FLORIDANUS,deinRadi,yersPest_CO92,saccEryt_NRRL_2338,rhodRHA1,candCars_RUDDII,burkMall_ATCC23344,eschColi_O157H7,burk383,psycIngr_37,rhodSpha_2_4_1,wolbEndo_OF_DROSOPHIL,burkViet_G4,propAcne_KPA171202,enteFaec_V583,campJeju_81_176,acidJS42,heliPylo_26695,pseuHalo_TAC125,chroSale_DSM3043,methVann1,archFulg1,neisMeni_Z2491_1,fusoNucl,vermEise_EF01_2,anabVari_ATCC29413,tropWhip_TW08_27,heliHepa,acinSp_ADP1,anapMarg_ST_MARIES,natrPhar1,haheChej_KCTC_2396,therPetr_RKU_1,neisGono_FA1090_1,colwPsyc_34H,desuPsyc_LSV54,hyphNept_ATCC15444,vibrChol1,deinGeot_DSM11300,strePyog_M1_GAS,franCcI3,salmTyph,metaSedu,lactSali_UCC118,trepPall,neisMeni_MC58_1,syntWolf_GOETTINGEN,flavJohn_UW101,methBoon1,haemSomn_129PT,shewLoihPV4,igniHosp1,haemInfl_KW20,haloHalo_SL1,ferrAcid1,sphiAlas_RB2256,candPela_UBIQUE_HTCC1,caldSacc_DSM8903,aerPer1,lactPlan,carbHydr_Z_2901,therTher_HB8,vibrVuln_YJ016_1,rhodPalu_CGA009,acidCell_11B,siliPome_DSS_3,therVolc1,haloWals1,rubrXyla_DSM9941,shewAmaz,nocaJS61,vibrVuln_CMCP6_1,sinoMeli,ureaUrea,baciHalo,bartHens_HOUSTON_1,nitrWino_NB_255,hypeButy1,methBurt2,polaJS66,mesoLoti,methMari_C7,caulCres,neisMeni_FAM18_1,acidBact_ELLIN345,caldMaqu1,salmEnte_PARATYPI_ATC,glucOxyd_621H,cytoHutc_ATCC33406,nitrEuro,therMari,coxiBurn,woliSucc,heliPylo_HPAG1,mesoFlor_L1,pyrHor1,methAeol1,procMari_CCMP1375,pyroArse1,oenoOeni_PSU_1,alcaBork_SK2,wiggBrev,actiPleu_L20,lactLact,methJann1,paraDeni_PD1222,borrBurg,pyroIsla1,orieTsut_BORYONG,shewMR4,methKand1,methCaps_BATH,onioYell_PHYTOPLASMA,bordBron,cenaSymb1,burkCeno_HI2424,franTula_TULARENSIS,pyrFur2,mariAqua_VT8,heliPylo_J99,psycArct_273_4,vibrChol_MO10_1,vibrPara1,rickBell_RML369_C,metAce1,buchSp,ehrlRumi_WELGEVONDEN,methLabrZ_1,chlaPneu_CWL029,thioCrun_XCL_2,pyroCali1,chloTepi_TLS,stapAure_MU50,novoArom_DSM12444,magnMC1,zymoMobi_ZM4,salmTyph_TY2,chloChlo_CAD3,azoaSp_EBN1,therTher_HB27,bifiLong,picrTorr1,listInno,bdelBact,gramFors_KT0803,sulfAcid1,geobTher_NG80_2,peloCarb,ralsEutr_JMP134,mannSucc_MBEL55E,syneSp_WH8102,methTherPT1,clavMich_NCPPB_382,therAcid1,syntAcid_SB,porpGing_W83,therNeut0,leifXyli_XYLI_CTCB0,shewFrig,photProf_SS9,thioDeni_ATCC25259,methMaze1,desuRedu_MI_1,burkThai_E264,campFetu_82_40,blocFlor,jannCCS1,nitrMult_ATCC25196,streCoel,soliUsit_ELLIN6076,pastMult,saliRube_DSM13855,methTher1,nostSp,shigFlex_2A,saccDegr_2_40,oceaIhey,dehaEthe_195,rhodRubr_ATCC11170,arthFB24,shewMR7,pireSp,anaeDeha_2CP_C,haloVolc1,dichNodo_VCS1703A,tricEryt_IMS101,mycoGeni,thioDeni_ATCC33889,methSmit1,geobUran_RF4,shewDeni,halMar1,desuHafn_Y51,methStad1,granBeth_CGDNIH1,therPend1,legiPneu_PHILADELPHIA,vibrChol_O395_1,nitrOcea_ATCC19707,campJeju_RM1221,methPetr_PM1,heliAcin_SHEEBA,eschColi_APEC_O1,peloTher_SI,haloHalo1,syntFuma_MPOB,xyleFast,gloeViol,leucMese_ATCC8293,bactThet_VPI_5482,xantCamp,sodaGlos_MORSITANS,geobSulf,roseDeni_OCH_114,coryEffi_YS_314,brucMeli,mycoTube_H37RV,vibrFisc_ES114_1,pyrAby1,burkXeno_LB400,polyQLWP,stapMari1,peloLute_DSM273,burkCeno_AU_1054,shewBalt,nocaFarc_IFM10152,ente638,mculMari1,saliTrop_CNB_440,neorSenn_MIYAYAMA,aquiAeol,dechArom_RCB,myxoXant_DK_1622,burkPseu_1106A,burkCepa_AMMD,methMari_C5_1,azorCaul2,methFlag_KT,leptInte,eschColi_K12,synePCC6,baumCica_HOMALODISCA,methBark1,pseuAeru,geobMeta_GS15,eschColi_CFT073,photLumi,metMar1,hermArse,campJeju,therKoda1,aeroHydr_ATCC7966,baciAnth_AMES,shewOnei,therTeng,lawsIntr_PHE_MN1_00
#Harvested from http://genome-test.cse.ucsc.edu/cgi-bin/das/dsn
--- a/tool_conf.xml.sample Tue Jul 05 12:40:43 2011 +1000
+++ b/tool_conf.xml.sample Wed Jul 06 09:44:56 2011 +1000
@@ -368,7 +368,6 @@
</section><section name="NGS: Simulation" id="ngs-simulation"><tool file="ngs_simulation/ngs_simulation.xml" />
- <tool file="rgenetics/EpiD.xml" /></section><section name="SNP/WGA: Data; Filters" id="rgdat"><label text="Data: Import and upload" id="rgimport" />
--- a/tools/data_source/ucsc_tablebrowser.xml Tue Jul 05 12:40:43 2011 +1000
+++ b/tools/data_source/ucsc_tablebrowser.xml Wed Jul 06 09:44:56 2011 +1000
@@ -5,27 +5,27 @@
initial response ( in addition to 'URL' ) will be encoded and appended to URL and a post will be performed.
--><tool name="UCSC Main" id="ucsc_table_direct1" tool_type="data_source">
- <description>table browser</description>
- <command interpreter="python">data_source.py $output $__app__.config.output_size_limit</command>
- <inputs action="http://ucsc.omics.bhri.internal/cgi-bin/hgTables" check_values="false" method="get">
- <display>go to UCSC Table Browser $GALAXY_URL</display>
- <param name="GALAXY_URL" type="baseurl" value="/tool_runner" />
- <param name="tool_id" type="hidden" value="ucsc_table_direct1" />
- <param name="sendToGalaxy" type="hidden" value="1" />
- <param name="hgta_compressType" type="hidden" value="none" />
- <param name="hgta_outputType" type="hidden" value="bed" />
- </inputs>
- <request_param_translation>
+ <description>table browser</description>
+ <command interpreter="python">data_source.py $output $__app__.config.output_size_limit</command>
+ <inputs action="http://genome.ucsc.edu/cgi-bin/hgTables" check_values="false" method="get">
+ <display>go to UCSC Table Browser $GALAXY_URL</display>
+ <param name="GALAXY_URL" type="baseurl" value="/tool_runner" />
+ <param name="tool_id" type="hidden" value="ucsc_table_direct1" />
+ <param name="sendToGalaxy" type="hidden" value="1" />
+ <param name="hgta_compressType" type="hidden" value="none" />
+ <param name="hgta_outputType" type="hidden" value="bed" />
+ </inputs>
+ <request_param_translation><request_param galaxy_name="URL_method" remote_name="URL_method" missing="post" /><request_param galaxy_name="URL" remote_name="URL" missing="" /><request_param galaxy_name="dbkey" remote_name="db" missing="?" /><request_param galaxy_name="organism" remote_name="org" missing="unknown species" />
- <request_param galaxy_name="table" remote_name="hgta_table" missing="unknown table" />
- <request_param galaxy_name="description" remote_name="hgta_regionType" missing="no description" />
- <request_param galaxy_name="data_type" remote_name="hgta_outputType" missing="tabular" >
+ <request_param galaxy_name="table" remote_name="hgta_table" missing="unknown table" />
+ <request_param galaxy_name="description" remote_name="hgta_regionType" missing="no description" />
+ <request_param galaxy_name="data_type" remote_name="hgta_outputType" missing="auto" ><value_translation>
- <value galaxy_value="tabular" remote_value="primaryTable" />
- <value galaxy_value="tabular" remote_value="selectedFields" />
+ <value galaxy_value="auto" remote_value="primaryTable" />
+ <value galaxy_value="auto" remote_value="selectedFields" /><value galaxy_value="wig" remote_value="wigData" /><value galaxy_value="interval" remote_value="tab" /><value galaxy_value="html" remote_value="hyperlinks" />
@@ -33,10 +33,10 @@
<value galaxy_value="gtf" remote_value="gff" /></value_translation></request_param>
- </request_param_translation>
- <uihints minwidth="800"/>
- <outputs>
- <data name="output" format="tabular" />
- </outputs>
- <options sanitize="False" refresh="True"/>
+ </request_param_translation>
+ <uihints minwidth="800"/>
+ <outputs>
+ <data name="output" format="tabular" label="${tool.name} on ${organism}: ${table} (#if $description == 'range' then $getVar( 'position', 'unknown position' ) else $description#)"/>
+ </outputs>
+ <options sanitize="False" refresh="True"/></tool>
--- a/tools/meme/meme.xml Tue Jul 05 12:40:43 2011 +1000
+++ b/tools/meme/meme.xml Wed Jul 06 09:44:56 2011 +1000
@@ -304,7 +304,7 @@
</when></conditional>
- <param name="non_commercial_use" label="I certify that I am not using this tool for commercial purposes." type="boolean" truevalue="NON_COMMERCIAL_USE" falsevalue="COMMERCIAL_USE" checked="True">
+ <param name="non_commercial_use" label="I certify that I am not using this tool for commercial purposes." type="boolean" truevalue="NON_COMMERCIAL_USE" falsevalue="COMMERCIAL_USE" checked="False"><validator type="expression" message="This tool is only available for non-commercial use.">value == True</validator></param>
--- a/tools/peak_calling/macs_wrapper.py Tue Jul 05 12:40:43 2011 +1000
+++ b/tools/peak_calling/macs_wrapper.py Wed Jul 06 09:44:56 2011 +1000
@@ -51,8 +51,7 @@
cmdline = "macs -t %s" % ",".join( options['input_chipseq'] )
if options['input_control']:
cmdline = "%s -c %s" % ( cmdline, ",".join( options['input_control'] ) )
- cmdline = "%s --format='%s' --name='%s' --gsize='%s' --tsize='%s' --bw='%s' --pvalue='%s' --mfold='%s' %s %s" %\
- ( cmdline, options['format'], experiment_name, options['gsize'], options['tsize'], options['bw'], options['pvalue'], options['mfold'], options['nolambda'], options['futurefdr'] )
+ cmdline = "%s --format='%s' --name='%s' --gsize='%s' --tsize='%s' --bw='%s' --pvalue='%s' --mfold='%s' %s --lambdaset='%s' %s" % ( cmdline, options['format'], experiment_name, options['gsize'], options['tsize'], options['bw'], options['pvalue'], options['mfold'], options['nolambda'], options['lambdaset'], options['futurefdr'] )
if 'wig' in options:
wigextend = int( options['wig']['wigextend'] )
if wigextend >= 0:
--- a/tools/peak_calling/macs_wrapper.xml Tue Jul 05 12:40:43 2011 +1000
+++ b/tools/peak_calling/macs_wrapper.xml Wed Jul 06 09:44:56 2011 +1000
@@ -28,8 +28,7 @@
<param name="tsize" type="integer" label="Tag size" value="25"/><param name="bw" type="integer" label="Band width" value="300"/><param name="pvalue" type="float" label="Pvalue cutoff for peak detection" value="1e-5" help="default: 1e-5"/>
- <param name="mfold" type="text" label="Select the regions with MFOLD high-confidence enrichment ratio against background to build model" value="10,30"
- help="Range for high-confidence enrichment ratio against background for model are within this range. DEFAULT:10,30" />
+ <param name="mfold" type="integer" label="Select the regions with MFOLD high-confidence enrichment ratio against background to build model" value="32"/><param name="xls_to_interval" label="Parse xls files into into distinct interval files" type="boolean" truevalue="create" falsevalue="do_not_create" checked="False"/><conditional name="wig_type"><param name="wig_type_selector" type="select" label="Save shifted raw tag count at every bp into a wiggle file">
@@ -45,6 +44,7 @@
</when></conditional><param name="nolambda" label="Use fixed background lambda as local lambda for every peak region" type="boolean" truevalue="--nolambda" falsevalue="" checked="False" help="up to 9X more time consuming"/>
+ <param name="lambdaset" type="text" label="3 levels of regions around the peak region to calculate the maximum lambda as local lambda" value="1000,5000,10000" size="50"/><conditional name="nomodel_type"><param name="nomodel_type_selector" type="select" label="Build Model"><option value="nomodel">Do not build the shifting model</option>
@@ -95,7 +95,7 @@
<configfile name="options_file"><%
import simplejson
%>
-#set $__options = { 'experiment_name':str( $experiment_name ), 'gsize':int( float( str( $gsize ) ) ), 'tsize':str( $tsize ), 'bw':str( $bw ), 'pvalue':str( $pvalue ), 'mfold':str( $mfold ), 'nolambda':str( $nolambda ), 'futurefdr':str( $futurefdr ) }
+#set $__options = { 'experiment_name':str( $experiment_name ), 'gsize':int( float( str( $gsize ) ) ), 'tsize':str( $tsize ), 'bw':str( $bw ), 'pvalue':str( $pvalue ), 'mfold':str( $mfold ), 'nolambda':str( $nolambda ), 'lambdaset': str( $lambdaset ), 'futurefdr':str( $futurefdr ) }
#if str( $xls_to_interval ) == 'create':
#set $__options['xls_to_interval'] = { 'peaks_file': str( $output_xls_to_interval_peaks_file ), 'negative_peaks_file': str( $output_xls_to_interval_negative_peaks_file ) }
#else:
@@ -145,13 +145,14 @@
<param name="input_control_file1" value="chipseq_input.bed.gz" ftype="bed" /><param name="experiment_name" value="Galaxy Test Run" /><param name="tsize" value="36" />
- <param name="mfold" value="10,30" />
+ <param name="mfold" value="13" /><param name="gsize" value="2.7e+9" /><param name="bw" value="300" /><param name="pvalue" value="1e-5" /><param name="xls_to_interval" /><param name="wig_type_selector" value="no_wig" /><param name="nolambda"/>
+ <param name="lambdaset" value="1000,5000,10000"/><param name="nomodel_type_selector" value="create_model" /><param name="diag_type_selector" value="no_diag" /><param name="futurefdr"/>
@@ -170,13 +171,14 @@
<param name="input_control_file1" value="chipseq_input.bed.gz" ftype="bed" /><param name="experiment_name" value="Galaxy Test Run" /><param name="tsize" value="36" />
- <param name="mfold" value="10,30" />
+ <param name="mfold" value="13" /><param name="gsize" value="2.7e+9" /><param name="bw" value="300" /><param name="pvalue" value="1e-5" /><param name="xls_to_interval" value="true" /><param name="wig_type_selector" value="no_wig" /><param name="nolambda"/>
+ <param name="lambdaset" value="1000,5000,10000"/><param name="nomodel_type_selector" value="create_model" /><param name="diag_type_selector" value="no_diag" /><param name="futurefdr"/>
@@ -193,7 +195,7 @@
<param name="input_control_file1" value="chipseq_input.bed.gz" ftype="bed" /><param name="experiment_name" value="Galaxy Test Run" /><param name="tsize" value="36" />
- <param name="mfold" value="10,30" />
+ <param name="mfold" value="13" /><param name="gsize" value="2.7e+9" /><param name="bw" value="300" /><param name="pvalue" value="1e-5" />
@@ -202,6 +204,7 @@
<param name="wigextend" value="-1" /><param name="space" value="10" /><param name="nolambda"/>
+ <param name="lambdaset" value="1000,5000,10000"/><param name="nomodel_type_selector" value="create_model" /><param name="diag_type_selector" value="no_diag" /><param name="futurefdr"/>
--- a/tools/plotting/histogram.py Tue Jul 05 12:40:43 2011 +1000
+++ b/tools/plotting/histogram.py Wed Jul 06 09:44:56 2011 +1000
@@ -73,8 +73,7 @@
if skipped_lines < i:
try:
- #a = array( matrix )
- a=matrix
+ a = r.array( matrix )
r.pdf( out_fname, 8, 8 )
histogram = r.hist( a, probability=not frequency, main=title, xlab=xlab, breaks=breaks )
if density:
--- a/tools/plotting/scatterplot.py Tue Jul 05 12:40:43 2011 +1000
+++ b/tools/plotting/scatterplot.py Wed Jul 06 09:44:56 2011 +1000
@@ -19,14 +19,8 @@
title = sys.argv[5]
xlab = sys.argv[6]
ylab = sys.argv[7]
- out_type = sys.argv[8]
- out_width = int(sys.argv[9])
- out_height = int(sys.argv[10])
- point_size = float(sys.argv[11])
-
- xvec=[]
- yvec=[]
+ matrix = []
skipped_lines = 0
first_invalid_line = 0
invalid_value = ''
@@ -34,19 +28,17 @@
i = 0
for i, line in enumerate( file( in_fname ) ):
valid = True
- vals = []
line = line.rstrip( '\r\n' )
if line and not line.startswith( '#' ):
row = []
fields = line.split( "\t" )
- for c,column in enumerate(columns):
+ for column in columns:
try:
val = fields[column]
if val.lower() == "na":
- v = float( "nan" )
+ row.append( float( "nan" ) )
else:
- v = float( fields[column] )
- vals.append(val)
+ row.append( float( fields[column] ) )
except:
valid = False
skipped_lines += 1
@@ -65,19 +57,12 @@
first_invalid_line = i+1
if valid:
- xvec.append(vals[0])
- yvec.append(vals[1])
+ matrix.append( row )
+
if skipped_lines < i:
try:
- if out_type == "jpg":
- r.jpeg(out_fname,width=out_width,height=out_height)
- elif out_type == "png":
- # type="cairo" needed to be set for headless servers
- r.png(out_fname,type="cairo",width=out_width,height=out_height)
- else:
- r.pdf(out_fname, out_width, out_height)
-
- r.plot(xvec,yvec, type="p", main=title, xlab=xlab, ylab=ylab, col="blue", pch=19,cex=point_size )
+ r.pdf( out_fname, 8, 8 )
+ r.plot( array( matrix ), type="p", main=title, xlab=xlab, ylab=ylab, col="blue", pch=19 )
r.dev_off()
except Exception, exc:
stop_err( "%s" %str( exc ) )
--- a/tools/plotting/scatterplot.xml Tue Jul 05 12:40:43 2011 +1000
+++ b/tools/plotting/scatterplot.xml Wed Jul 06 09:44:56 2011 +1000
@@ -1,6 +1,6 @@
<tool id="scatterplot_rpy" name="Scatterplot"><description>of two numeric columns</description>
- <command interpreter="python">scatterplot.py $input $out_file1 $col1 $col2 "$title" "$xlab" "$ylab" $output_format $out_width $out_height $point_size</command>
+ <command interpreter="python">scatterplot.py $input $out_file1 $col1 $col2 "$title" "$xlab" "$ylab"</command><inputs><param name="input" type="data" format="tabular" label="Dataset" help="Dataset missing? See TIP below"/><param name="col1" type="data_column" data_ref="input" numerical="True" label="Numerical column for x axis" />
@@ -8,26 +8,15 @@
<param name="title" size="30" type="text" value="Scatterplot" label="Plot title"/><param name="xlab" size="30" type="text" value="V1" label="Label for x axis"/><param name="ylab" size="30" type="text" value="V2" label="Label for y axis"/>
- <param name="output_format" type="select" label="Output format">
- <option value="pdf">pdf</option>
- <option value="png">png</option>
- <option value="jpg">jpg</option>
- </param>
- <param name="out_width" size="4" type="integer" value="8" label="Width (pdf=inches, image=pixels)"/>
- <param name="out_height" size="4" type="integer" value="8" label="Height (pdf=inches, image=pixels)"/>
- <param name="point_size" size="4" type="float" value="0.2" label="Point Size"/></inputs><outputs>
- <data format="pdf" name="out_file1">
- <change_format>
- <when input="output_format" value="png" format="png" />
- <when input="output_format" value="jpg" format="jpg" />
- </change_format>
- </data>
+ <data format="pdf" name="out_file1" /></outputs><requirements><requirement type="python-module">rpy</requirement></requirements>
+ <!-- TODO: uncomment the following test when we have tools.update_state() working for
+ multiple dependents with the same dependency.
<tests><test><param name="input" value="scatterplot_in1.tabular" ftype="tabular"/>
@@ -36,38 +25,8 @@
<param name="title" value="Scatterplot"/><param name="xlab" value="V1"/><param name="ylab" value="V2"/>
- <param name="out_width" value="8"/>
- <param name="out_height" value="8"/>
- <param name="point_size" value="0.5"/>
- <param name="output_format" value="pdf" /><output name="out_file1" file="scatterplot_out1.pdf" /></test>
- <test>
- <param name="input" value="scatterplot_in1.tabular" ftype="tabular"/>
- <param name="col1" value="2"/>
- <param name="col2" value="3"/>
- <param name="title" value="Scatterplot"/>
- <param name="xlab" value="V1"/>
- <param name="ylab" value="V2"/>
- <param name="out_width" value="800"/>
- <param name="out_height" value="600"/>
- <param name="point_size" value="0.5"/>
- <param name="output_format" value="png" />
- <output name="out_file1" file="scatterplot_out1.png" />
- </test>
- <test>
- <param name="input" value="scatterplot_in1.tabular" ftype="tabular"/>
- <param name="col1" value="2"/>
- <param name="col2" value="3"/>
- <param name="title" value="Scatterplot"/>
- <param name="xlab" value="V1"/>
- <param name="ylab" value="V2"/>
- <param name="out_width" value="800"/>
- <param name="out_height" value="600"/>
- <param name="point_size" value="0.5"/>
- <param name="output_format" value="jpg" />
- <output name="out_file1" file="scatterplot_out1.jpg" />
- </test></tests>
--><help>
--- a/tools/samtools/bam_to_sam.py Tue Jul 05 12:40:43 2011 +1000
+++ b/tools/samtools/bam_to_sam.py Wed Jul 06 09:44:56 2011 +1000
@@ -21,6 +21,7 @@
parser = optparse.OptionParser()
parser.add_option( '', '--input1', dest='input1', help='The input SAM dataset' )
parser.add_option( '', '--output1', dest='output1', help='The output BAM dataset' )
+ parser.add_option( '', '--header', dest='header', action='store_true', default=False, help='Write SAM Header' )
( options, args ) = parser.parse_args()
# output version # of tool
@@ -87,7 +88,11 @@
try:
# Extract all alignments from the input BAM file to SAM format ( since no region is specified, all the alignments will be extracted ).
- command = 'samtools view -o -h %s %s' % ( options.output1, tmp_sorted_aligns_file_name )
+ if options.header:
+ view_options = "-h"
+ else:
+ view_options = ""
+ command = 'samtools view %s -o %s %s' % ( view_options, options.output1, tmp_sorted_aligns_file_name )
tmp = tempfile.NamedTemporaryFile( dir=tmp_dir ).name
tmp_stderr = open( tmp, 'wb' )
proc = subprocess.Popen( args=command, shell=True, cwd=tmp_dir, stderr=tmp_stderr.fileno() )
--- a/tools/samtools/sam_bitwise_flag_filter.py Tue Jul 05 12:40:43 2011 +1000
+++ b/tools/samtools/sam_bitwise_flag_filter.py Wed Jul 06 09:44:56 2011 +1000
@@ -1,6 +1,6 @@
#!/usr/bin/env python
# Refactored on 11/13/2010 by Kanwei Li
-# Added drop_header option - default is now keep headers for downstream sanity by ross lazarus
+
import sys
import optparse
@@ -14,11 +14,7 @@
options (listed below) default to 'None' if omitted
"""
parser = optparse.OptionParser(usage=usage)
- parser.add_option('--drop_header',
- action = 'store_true',
- dest='drop_header',
- help="Remove sam header - you probably NEVER want this for fussy downstream tools")
-
+
parser.add_option(
'--0x0001','--is_paired',
choices = ( '0','1' ),
@@ -133,24 +129,21 @@
opt_map = { '0': False, '1': True }
used_indices = [(index, opt_map[opt]) for index, opt in enumerate(opt_ary) if opt is not None]
flag_col = int( options.flag_col ) - 1
+
for line in infile:
line = line.rstrip( '\r\n' )
- if line:
- if line.startswith('@'):
- if not options.drop_header:
- print line # usually want these so add -h if you don't want headers
- elif not line.startswith( '#' ) :
- fields = line.split( '\t' )
- flags = int( fields[flag_col] )
+ if line and not line.startswith( '#' ) and not line.startswith( '@' ) :
+ fields = line.split( '\t' )
+ flags = int( fields[flag_col] )
- valid_line = True
- for index, opt_bool in used_indices:
- if bool(flags & 0x0001 << index) != opt_bool:
- valid_line = False
- break
+ valid_line = True
+ for index, opt_bool in used_indices:
+ if bool(flags & 0x0001 << index) != opt_bool:
+ valid_line = False
+ break
- if valid_line:
- print line
+ if valid_line:
+ print line
if __name__ == "__main__": main()
--- a/tools/samtools/sam_bitwise_flag_filter.xml Tue Jul 05 12:40:43 2011 +1000
+++ b/tools/samtools/sam_bitwise_flag_filter.xml Wed Jul 06 09:44:56 2011 +1000
@@ -1,11 +1,8 @@
-<tool id="sam_bw_filter" name="Filter SAM" version="1.0.1">
+<tool id="sam_bw_filter" name="Filter SAM" version="1.0.0"><description>on bitwise flag values</description><parallelism method="basic"></parallelism><command interpreter="python">
sam_bitwise_flag_filter.py
- #if $drop_header == "1":
- --drop_header
- #end if
--input_sam_file=$input1
--flag_column=2
#for $bit in $bits
@@ -15,11 +12,6 @@
</command><inputs><param format="sam" name="input1" type="data" label="Select dataset to filter"/>
- <param name="drop_header" type="select" display="radio" label="DROP sam headers"
- help="Set this if you REALLY want to throw away existing sam header metadata - downstream (eg Picard) tools often demand it" >
- <option value="0" selected="true">Keep headers (default)</option>
- <option value="1">Drop headers</option>
- </param><repeat name="bits" title="Flag"><param name="flags" type="select" label="Type"><option value="--0x0001">Read is paired</option>
--- a/tools/samtools/sam_to_bam.py Tue Jul 05 12:40:43 2011 +1000
+++ b/tools/samtools/sam_to_bam.py Wed Jul 06 09:44:56 2011 +1000
@@ -68,7 +68,7 @@
# and the equCab2.fa file will contain fasta sequences.
seq_path = check_seq_file( options.dbkey, cached_seqs_pointer_file )
tmp_dir = tempfile.mkdtemp()
- if options.ref_file == 'None':
+ if not options.ref_file or options.ref_file == 'None':
# We're using locally cached reference sequences( e.g., /galaxy/data/equCab2/sam_index/equCab2.fa ).
# The indexes for /galaxy/data/equCab2/sam_index/equCab2.fa will be contained in
# a file named /galaxy/data/equCab2/sam_index/equCab2.fa.fai
@@ -125,9 +125,7 @@
tmp_aligns_file = tempfile.NamedTemporaryFile( dir=tmp_dir )
tmp_aligns_file_name = tmp_aligns_file.name
tmp_aligns_file.close()
- # IMPORTANT NOTE: for some reason the samtools view command gzips the resulting bam file without warning,
- # and the docs do not currently state that this occurs ( very bad ).
- command = 'samtools view -h -bt %s -o %s %s' % ( fai_index_file_path, tmp_aligns_file_name, options.input1 )
+ command = 'samtools view -bt %s -o %s %s' % ( fai_index_file_path, tmp_aligns_file_name, options.input1 )
tmp = tempfile.NamedTemporaryFile( dir=tmp_dir ).name
tmp_stderr = open( tmp, 'wb' )
proc = subprocess.Popen( args=command, shell=True, cwd=tmp_dir, stderr=tmp_stderr.fileno() )
@@ -147,8 +145,6 @@
tmp_stderr.close()
if returncode != 0:
raise Exception, stderr
- if len( open( tmp_aligns_file_name ).read() ) == 0:
- raise Exception, 'Initial BAM file empty'
except Exception, e:
#clean up temp files
if os.path.exists( tmp_dir ):
@@ -188,11 +184,6 @@
stop_err( 'Error sorting alignments from (%s), %s' % ( tmp_aligns_file_name, str( e ) ) )
# Move tmp_aligns_file_name to our output dataset location
sorted_bam_file = '%s.bam' % tmp_sorted_aligns_file_name
- if os.path.getsize( sorted_bam_file ) == 0:
- #clean up temp files
- if os.path.exists( tmp_dir ):
- shutil.rmtree( tmp_dir )
- stop_err( 'Error creating sorted version of BAM file' )
shutil.move( sorted_bam_file, options.output1 )
#clean up temp files
if os.path.exists( tmp_dir ):
@@ -201,6 +192,6 @@
if os.path.getsize( options.output1 ) > 0:
sys.stdout.write( 'SAM file converted to BAM' )
else:
- stop_err( 'The output file is empty, there may be an error with your input file or settings.' )
+ stop_err( 'Error creating sorted version of BAM file.' )
if __name__=="__main__": __main__()
http://bitbucket.org/galaxy/galaxy-central/changeset/f37951db86e6/
changeset: f37951db86e6
user: fubar
date: 2011-07-06 01:45:41
summary: committing backout from 5765 which included reversions from a broken galaxy-central repository
affected #: 251 files (5.7 KB)
--- a/lib/galaxy/security/__init__.py Tue Jul 05 11:42:56 2011 -0400
+++ b/lib/galaxy/security/__init__.py Wed Jul 06 09:45:41 2011 +1000
@@ -1005,8 +1005,7 @@
ucsc_main = ( 'hgw1.cse.ucsc.edu', 'hgw2.cse.ucsc.edu', 'hgw3.cse.ucsc.edu', 'hgw4.cse.ucsc.edu',
'hgw5.cse.ucsc.edu', 'hgw6.cse.ucsc.edu', 'hgw7.cse.ucsc.edu', 'hgw8.cse.ucsc.edu' ),
ucsc_test = ( 'hgwdev.cse.ucsc.edu', ),
- ucsc_archaea = ( 'lowepub.cse.ucsc.edu', ),
- ucsc_bhri = ('ucsc.omics.bhri.internal','galaxy.omics.bhri.internal'),
+ ucsc_archaea = ( 'lowepub.cse.ucsc.edu', )
)
def __init__( self, model, permitted_actions=None ):
self.model = model
@@ -1037,7 +1036,7 @@
# We're going to search in order, but if the remote site is load
# balancing their connections (as UCSC does), this is okay.
try:
- if socket.gethostbyname( server ) == addr or server == '127.0.0.1' or server == '172.16.0.38':
+ if socket.gethostbyname( server ) == addr:
break # remote host is in the server list
except ( socket.error, socket.gaierror ):
pass # can't resolve, try next
--- a/lib/galaxy/tools/__init__.py Tue Jul 05 11:42:56 2011 -0400
+++ b/lib/galaxy/tools/__init__.py Wed Jul 06 09:45:41 2011 +1000
@@ -922,8 +922,6 @@
if not self.check_values:
return
for input in self.inputs.itervalues():
- if input.name not in value:
- value[input.name] = input.get_initial_value( None, value )
if isinstance( input, ToolParameter ):
callback( "", input, value[input.name] )
else:
--- a/lib/galaxy/tools/parameters/basic.py Tue Jul 05 11:42:56 2011 -0400
+++ b/lib/galaxy/tools/parameters/basic.py Wed Jul 06 09:45:41 2011 +1000
@@ -748,6 +748,9 @@
# Dependency on a value that does not yet exist
if isinstance( dep_value, RuntimeValue ):
return True
+ #dataset not ready yet
+ if hasattr( self, 'ref_input' ) and isinstance( dep_value, self.tool.app.model.HistoryDatasetAssociation ) and ( dep_value.is_pending or not isinstance( dep_value.datatype, self.ref_input.formats ) ):
+ return True
# Dynamic, but all dependenceis are known and have values
return False
def get_initial_value( self, trans, context ):
@@ -878,6 +881,7 @@
self.force_select = string_as_bool( elem.get( "force_select", True ))
self.accept_default = string_as_bool( elem.get( "accept_default", False ))
self.data_ref = elem.get( "data_ref", None )
+ self.ref_input = None
self.default_value = elem.get( "default_value", None )
self.is_dynamic = True
def from_html( self, value, trans=None, context={} ):
@@ -973,7 +977,7 @@
if not dataset.metadata.columns:
# Only allow late validation if the dataset is not yet ready
# (since we have reason to expect the metadata to be ready eventually)
- if dataset.is_pending:
+ if dataset.is_pending or not isinstance( dataset.datatype, self.ref_input.formats ):
return True
# No late validation
return False
@@ -1353,7 +1357,7 @@
selected = ( value and ( hda in value ) )
field.add_option( "%s: %s" % ( hid, hda_name ), hda.id, selected )
else:
- target_ext, converted_dataset = hda.find_conversion_destination( self.formats, converter_safe = self.converter_safe( other_values, trans ) )
+ target_ext, converted_dataset = hda.find_conversion_destination( self.formats )
if target_ext:
if converted_dataset:
hda = converted_dataset
@@ -1402,13 +1406,22 @@
pass #no valid options
def dataset_collector( datasets ):
def is_convertable( dataset ):
- target_ext, converted_dataset = dataset.find_conversion_destination( self.formats, converter_safe = self.converter_safe( context, trans ) )
+ target_ext, converted_dataset = dataset.find_conversion_destination( self.formats )
if target_ext is not None:
return True
return False
for i, data in enumerate( datasets ):
- if data.visible and not data.deleted and data.state not in [data.states.ERROR, data.states.DISCARDED] and ( isinstance( data.datatype, self.formats) or is_convertable( data ) ):
- if self.options and self._options_filter_attribute( data ) != filter_value:
+ if data.visible and not data.deleted and data.state not in [data.states.ERROR, data.states.DISCARDED]:
+ is_valid = False
+ if isinstance( data.datatype, self.formats ):
+ is_valid = True
+ else:
+ target_ext, converted_dataset = data.find_conversion_destination( self.formats )
+ if target_ext:
+ is_valid = True
+ if converted_dataset:
+ data = converted_dataset
+ if not is_valid or ( self.options and self._options_filter_attribute( data ) != filter_value ):
continue
most_recent_dataset[0] = data
# Also collect children via association object
--- a/lib/galaxy/web/framework/middleware/remoteuser.py Tue Jul 05 11:42:56 2011 -0400
+++ b/lib/galaxy/web/framework/middleware/remoteuser.py Wed Jul 06 09:45:41 2011 +1000
@@ -36,7 +36,6 @@
"""
UCSC_MAIN_SERVERS = (
- 'omics.bhri.internal',
'hgw1.cse.ucsc.edu',
'hgw2.cse.ucsc.edu',
'hgw3.cse.ucsc.edu',
@@ -50,7 +49,6 @@
'lowepub.cse.ucsc.edu',
)
-
class RemoteUser( object ):
def __init__( self, app, maildomain=None, ucsc_display_sites=[], admin_users=[] ):
self.app = app
@@ -58,7 +56,7 @@
self.allow_ucsc_main = False
self.allow_ucsc_archaea = False
self.admin_users = admin_users
- if 'main' in ucsc_display_sites or 'test' in ucsc_display_sites or 'bhri' in ucsc_display_sites:
+ if 'main' in ucsc_display_sites or 'test' in ucsc_display_sites:
self.allow_ucsc_main = True
if 'archaea' in ucsc_display_sites:
self.allow_ucsc_archaea = True
--- a/scripts/cleanup_datasets/purge_libraries.sh Tue Jul 05 11:42:56 2011 -0400
+++ b/scripts/cleanup_datasets/purge_libraries.sh Wed Jul 06 09:45:41 2011 +1000
@@ -1,5 +1,4 @@
#!/bin/sh
cd `dirname $0`/../..
-#python ./scripts/cleanup_datasets/cleanup_datasets.py ./universe_wsgi.ini -d 10 -4 -r $@ >> ./scripts/cleanup_datasets/purge_libraries.log
-python ./scripts/cleanup_datasets/cleanup_datasets.py ./universe_wsgi.ini -d 2 -4 -r $@ >> ./scripts/cleanup_datasets/purge_libraries.log
+python ./scripts/cleanup_datasets/cleanup_datasets.py ./universe_wsgi.ini -d 10 -4 -r $@ >> ./scripts/cleanup_datasets/purge_libraries.log
--- a/tool-data/shared/ucsc/ucsc_build_sites.txt Tue Jul 05 11:42:56 2011 -0400
+++ b/tool-data/shared/ucsc/ucsc_build_sites.txt Wed Jul 06 09:45:41 2011 +1000
@@ -1,6 +1,5 @@
#Harvested from http://genome.ucsc.edu/cgi-bin/das/dsn
main http://genome.ucsc.edu/cgi-bin/hgTracks? priPac1,danRer4,mm9,mm8,droAna1,mm5,caeRem2,mm7,mm6,panTro1,dm3,panTro2,anoCar1,ce4,galGal3,galGal2,ce1,rn3,rn2,droMoj1,droMoj2,rn4,droYak1,droYak2,dp3,dp2,dm1,canFam1,danRer5,canFam2,danRer3,danRer2,ornAna1,ci2,ci1,tetNig1,bosTau1,bosTau3,bosTau2,equCab1,oryLat1,droAna2,droEre1,ponAbe2,rheMac2,sacCer1,droPer1,droSim1,monDom1,cb1,dm2,droSec1,strPur1,droVir2,droVir1,strPur2,sc1,xenTro1,droGri1,xenTro2,cb3,gasAcu1,caePb1,anoGam1,fr2,fr1,hg15,hg16,hg17,hg18,felCat3,apiMel2,monDom4,apiMel1,ce2
-bhri http://ucsc.omics.bhri.internal/cgi-bin/hgTracks? hg18,hg19,mm8,mm9,rn4
#Harvested from http://archaea.ucsc.edu/cgi-bin/das/dsn
archaea http://archaea.ucsc.edu/cgi-bin/hgTracks? alkaEhrl_MLHE_1,shewW318,idioLoih_L2TR,sulSol1,erwiCaro_ATROSEPTICA,symbTher_IAM14863,moorTher_ATCC39073,therFusc_YX,methHung1,bradJapo,therElon,shewPutrCN32,pediPent_ATCC25745,mariMari_MCS10,nanEqu1,baciSubt,chlaTrac,magnMagn_AMB_1,chroViol,ralsSola,acidCryp_JF_5,erytLito_HTCC2594,desuVulg_HILDENBOROUG,pyrAer1,sulfToko1,shewANA3,paraSp_UWE25,geobKaus_HTA426,rhizEtli_CFN_42,uncuMeth_RCI,candBloc_FLORIDANUS,deinRadi,yersPest_CO92,saccEryt_NRRL_2338,rhodRHA1,candCars_RUDDII,burkMall_ATCC23344,eschColi_O157H7,burk383,psycIngr_37,rhodSpha_2_4_1,wolbEndo_OF_DROSOPHIL,burkViet_G4,propAcne_KPA171202,enteFaec_V583,campJeju_81_176,acidJS42,heliPylo_26695,pseuHalo_TAC125,chroSale_DSM3043,methVann1,archFulg1,neisMeni_Z2491_1,fusoNucl,vermEise_EF01_2,anabVari_ATCC29413,tropWhip_TW08_27,heliHepa,acinSp_ADP1,anapMarg_ST_MARIES,natrPhar1,haheChej_KCTC_2396,therPetr_RKU_1,neisGono_FA1090_1,colwPsyc_34H,desuPsyc_LSV54,hyphNept_ATCC15444,vibrChol1,deinGeot_DSM11300,strePyog_M1_GAS,franCcI3,salmTyph,metaSedu,lactSali_UCC118,trepPall,neisMeni_MC58_1,syntWolf_GOETTINGEN,flavJohn_UW101,methBoon1,haemSomn_129PT,shewLoihPV4,igniHosp1,haemInfl_KW20,haloHalo_SL1,ferrAcid1,sphiAlas_RB2256,candPela_UBIQUE_HTCC1,caldSacc_DSM8903,aerPer1,lactPlan,carbHydr_Z_2901,therTher_HB8,vibrVuln_YJ016_1,rhodPalu_CGA009,acidCell_11B,siliPome_DSS_3,therVolc1,haloWals1,rubrXyla_DSM9941,shewAmaz,nocaJS61,vibrVuln_CMCP6_1,sinoMeli,ureaUrea,baciHalo,bartHens_HOUSTON_1,nitrWino_NB_255,hypeButy1,methBurt2,polaJS66,mesoLoti,methMari_C7,caulCres,neisMeni_FAM18_1,acidBact_ELLIN345,caldMaqu1,salmEnte_PARATYPI_ATC,glucOxyd_621H,cytoHutc_ATCC33406,nitrEuro,therMari,coxiBurn,woliSucc,heliPylo_HPAG1,mesoFlor_L1,pyrHor1,methAeol1,procMari_CCMP1375,pyroArse1,oenoOeni_PSU_1,alcaBork_SK2,wiggBrev,actiPleu_L20,lactLact,methJann1,paraDeni_PD1222,borrBurg,pyroIsla1,orieTsut_BORYONG,shewMR4,methKand1,methCaps_BATH,onioYell_PHYTOPLASMA,bordBron,cenaSymb1,burkCeno_HI2424,franTula_TULARENSIS,pyrFur2,mariAqua_VT8,heliPylo_J99,psycArct_273_4,vibrChol_MO10_1,vibrPara1,rickBell_RML369_C,metAce1,buchSp,ehrlRumi_WELGEVONDEN,methLabrZ_1,chlaPneu_CWL029,thioCrun_XCL_2,pyroCali1,chloTepi_TLS,stapAure_MU50,novoArom_DSM12444,magnMC1,zymoMobi_ZM4,salmTyph_TY2,chloChlo_CAD3,azoaSp_EBN1,therTher_HB27,bifiLong,picrTorr1,listInno,bdelBact,gramFors_KT0803,sulfAcid1,geobTher_NG80_2,peloCarb,ralsEutr_JMP134,mannSucc_MBEL55E,syneSp_WH8102,methTherPT1,clavMich_NCPPB_382,therAcid1,syntAcid_SB,porpGing_W83,therNeut0,leifXyli_XYLI_CTCB0,shewFrig,photProf_SS9,thioDeni_ATCC25259,methMaze1,desuRedu_MI_1,burkThai_E264,campFetu_82_40,blocFlor,jannCCS1,nitrMult_ATCC25196,streCoel,soliUsit_ELLIN6076,pastMult,saliRube_DSM13855,methTher1,nostSp,shigFlex_2A,saccDegr_2_40,oceaIhey,dehaEthe_195,rhodRubr_ATCC11170,arthFB24,shewMR7,pireSp,anaeDeha_2CP_C,haloVolc1,dichNodo_VCS1703A,tricEryt_IMS101,mycoGeni,thioDeni_ATCC33889,methSmit1,geobUran_RF4,shewDeni,halMar1,desuHafn_Y51,methStad1,granBeth_CGDNIH1,therPend1,legiPneu_PHILADELPHIA,vibrChol_O395_1,nitrOcea_ATCC19707,campJeju_RM1221,methPetr_PM1,heliAcin_SHEEBA,eschColi_APEC_O1,peloTher_SI,haloHalo1,syntFuma_MPOB,xyleFast,gloeViol,leucMese_ATCC8293,bactThet_VPI_5482,xantCamp,sodaGlos_MORSITANS,geobSulf,roseDeni_OCH_114,coryEffi_YS_314,brucMeli,mycoTube_H37RV,vibrFisc_ES114_1,pyrAby1,burkXeno_LB400,polyQLWP,stapMari1,peloLute_DSM273,burkCeno_AU_1054,shewBalt,nocaFarc_IFM10152,ente638,mculMari1,saliTrop_CNB_440,neorSenn_MIYAYAMA,aquiAeol,dechArom_RCB,myxoXant_DK_1622,burkPseu_1106A,burkCepa_AMMD,methMari_C5_1,azorCaul2,methFlag_KT,leptInte,eschColi_K12,synePCC6,baumCica_HOMALODISCA,methBark1,pseuAeru,geobMeta_GS15,eschColi_CFT073,photLumi,metMar1,hermArse,campJeju,therKoda1,aeroHydr_ATCC7966,baciAnth_AMES,shewOnei,therTeng,lawsIntr_PHE_MN1_00
#Harvested from http://genome-test.cse.ucsc.edu/cgi-bin/das/dsn
--- a/tool_conf.xml.sample Tue Jul 05 11:42:56 2011 -0400
+++ b/tool_conf.xml.sample Wed Jul 06 09:45:41 2011 +1000
@@ -368,7 +368,6 @@
</section><section name="NGS: Simulation" id="ngs-simulation"><tool file="ngs_simulation/ngs_simulation.xml" />
- <tool file="rgenetics/EpiD.xml" /></section><section name="SNP/WGA: Data; Filters" id="rgdat"><label text="Data: Import and upload" id="rgimport" />
--- a/tools/data_source/ucsc_tablebrowser.xml Tue Jul 05 11:42:56 2011 -0400
+++ b/tools/data_source/ucsc_tablebrowser.xml Wed Jul 06 09:45:41 2011 +1000
@@ -5,27 +5,27 @@
initial response ( in addition to 'URL' ) will be encoded and appended to URL and a post will be performed.
--><tool name="UCSC Main" id="ucsc_table_direct1" tool_type="data_source">
- <description>table browser</description>
- <command interpreter="python">data_source.py $output $__app__.config.output_size_limit</command>
- <inputs action="http://ucsc.omics.bhri.internal/cgi-bin/hgTables" check_values="false" method="get">
- <display>go to UCSC Table Browser $GALAXY_URL</display>
- <param name="GALAXY_URL" type="baseurl" value="/tool_runner" />
- <param name="tool_id" type="hidden" value="ucsc_table_direct1" />
- <param name="sendToGalaxy" type="hidden" value="1" />
- <param name="hgta_compressType" type="hidden" value="none" />
- <param name="hgta_outputType" type="hidden" value="bed" />
- </inputs>
- <request_param_translation>
+ <description>table browser</description>
+ <command interpreter="python">data_source.py $output $__app__.config.output_size_limit</command>
+ <inputs action="http://genome.ucsc.edu/cgi-bin/hgTables" check_values="false" method="get">
+ <display>go to UCSC Table Browser $GALAXY_URL</display>
+ <param name="GALAXY_URL" type="baseurl" value="/tool_runner" />
+ <param name="tool_id" type="hidden" value="ucsc_table_direct1" />
+ <param name="sendToGalaxy" type="hidden" value="1" />
+ <param name="hgta_compressType" type="hidden" value="none" />
+ <param name="hgta_outputType" type="hidden" value="bed" />
+ </inputs>
+ <request_param_translation><request_param galaxy_name="URL_method" remote_name="URL_method" missing="post" /><request_param galaxy_name="URL" remote_name="URL" missing="" /><request_param galaxy_name="dbkey" remote_name="db" missing="?" /><request_param galaxy_name="organism" remote_name="org" missing="unknown species" />
- <request_param galaxy_name="table" remote_name="hgta_table" missing="unknown table" />
- <request_param galaxy_name="description" remote_name="hgta_regionType" missing="no description" />
- <request_param galaxy_name="data_type" remote_name="hgta_outputType" missing="tabular" >
+ <request_param galaxy_name="table" remote_name="hgta_table" missing="unknown table" />
+ <request_param galaxy_name="description" remote_name="hgta_regionType" missing="no description" />
+ <request_param galaxy_name="data_type" remote_name="hgta_outputType" missing="auto" ><value_translation>
- <value galaxy_value="tabular" remote_value="primaryTable" />
- <value galaxy_value="tabular" remote_value="selectedFields" />
+ <value galaxy_value="auto" remote_value="primaryTable" />
+ <value galaxy_value="auto" remote_value="selectedFields" /><value galaxy_value="wig" remote_value="wigData" /><value galaxy_value="interval" remote_value="tab" /><value galaxy_value="html" remote_value="hyperlinks" />
@@ -33,10 +33,10 @@
<value galaxy_value="gtf" remote_value="gff" /></value_translation></request_param>
- </request_param_translation>
- <uihints minwidth="800"/>
- <outputs>
- <data name="output" format="tabular" />
- </outputs>
- <options sanitize="False" refresh="True"/>
+ </request_param_translation>
+ <uihints minwidth="800"/>
+ <outputs>
+ <data name="output" format="tabular" label="${tool.name} on ${organism}: ${table} (#if $description == 'range' then $getVar( 'position', 'unknown position' ) else $description#)"/>
+ </outputs>
+ <options sanitize="False" refresh="True"/></tool>
--- a/tools/meme/meme.xml Tue Jul 05 11:42:56 2011 -0400
+++ b/tools/meme/meme.xml Wed Jul 06 09:45:41 2011 +1000
@@ -304,7 +304,7 @@
</when></conditional>
- <param name="non_commercial_use" label="I certify that I am not using this tool for commercial purposes." type="boolean" truevalue="NON_COMMERCIAL_USE" falsevalue="COMMERCIAL_USE" checked="True">
+ <param name="non_commercial_use" label="I certify that I am not using this tool for commercial purposes." type="boolean" truevalue="NON_COMMERCIAL_USE" falsevalue="COMMERCIAL_USE" checked="False"><validator type="expression" message="This tool is only available for non-commercial use.">value == True</validator></param>
--- a/tools/peak_calling/macs_wrapper.py Tue Jul 05 11:42:56 2011 -0400
+++ b/tools/peak_calling/macs_wrapper.py Wed Jul 06 09:45:41 2011 +1000
@@ -51,8 +51,7 @@
cmdline = "macs -t %s" % ",".join( options['input_chipseq'] )
if options['input_control']:
cmdline = "%s -c %s" % ( cmdline, ",".join( options['input_control'] ) )
- cmdline = "%s --format='%s' --name='%s' --gsize='%s' --tsize='%s' --bw='%s' --pvalue='%s' --mfold='%s' %s %s" %\
- ( cmdline, options['format'], experiment_name, options['gsize'], options['tsize'], options['bw'], options['pvalue'], options['mfold'], options['nolambda'], options['futurefdr'] )
+ cmdline = "%s --format='%s' --name='%s' --gsize='%s' --tsize='%s' --bw='%s' --pvalue='%s' --mfold='%s' %s --lambdaset='%s' %s" % ( cmdline, options['format'], experiment_name, options['gsize'], options['tsize'], options['bw'], options['pvalue'], options['mfold'], options['nolambda'], options['lambdaset'], options['futurefdr'] )
if 'wig' in options:
wigextend = int( options['wig']['wigextend'] )
if wigextend >= 0:
--- a/tools/peak_calling/macs_wrapper.xml Tue Jul 05 11:42:56 2011 -0400
+++ b/tools/peak_calling/macs_wrapper.xml Wed Jul 06 09:45:41 2011 +1000
@@ -28,8 +28,7 @@
<param name="tsize" type="integer" label="Tag size" value="25"/><param name="bw" type="integer" label="Band width" value="300"/><param name="pvalue" type="float" label="Pvalue cutoff for peak detection" value="1e-5" help="default: 1e-5"/>
- <param name="mfold" type="text" label="Select the regions with MFOLD high-confidence enrichment ratio against background to build model" value="10,30"
- help="Range for high-confidence enrichment ratio against background for model are within this range. DEFAULT:10,30" />
+ <param name="mfold" type="integer" label="Select the regions with MFOLD high-confidence enrichment ratio against background to build model" value="32"/><param name="xls_to_interval" label="Parse xls files into into distinct interval files" type="boolean" truevalue="create" falsevalue="do_not_create" checked="False"/><conditional name="wig_type"><param name="wig_type_selector" type="select" label="Save shifted raw tag count at every bp into a wiggle file">
@@ -45,6 +44,7 @@
</when></conditional><param name="nolambda" label="Use fixed background lambda as local lambda for every peak region" type="boolean" truevalue="--nolambda" falsevalue="" checked="False" help="up to 9X more time consuming"/>
+ <param name="lambdaset" type="text" label="3 levels of regions around the peak region to calculate the maximum lambda as local lambda" value="1000,5000,10000" size="50"/><conditional name="nomodel_type"><param name="nomodel_type_selector" type="select" label="Build Model"><option value="nomodel">Do not build the shifting model</option>
@@ -95,7 +95,7 @@
<configfile name="options_file"><%
import simplejson
%>
-#set $__options = { 'experiment_name':str( $experiment_name ), 'gsize':int( float( str( $gsize ) ) ), 'tsize':str( $tsize ), 'bw':str( $bw ), 'pvalue':str( $pvalue ), 'mfold':str( $mfold ), 'nolambda':str( $nolambda ), 'futurefdr':str( $futurefdr ) }
+#set $__options = { 'experiment_name':str( $experiment_name ), 'gsize':int( float( str( $gsize ) ) ), 'tsize':str( $tsize ), 'bw':str( $bw ), 'pvalue':str( $pvalue ), 'mfold':str( $mfold ), 'nolambda':str( $nolambda ), 'lambdaset': str( $lambdaset ), 'futurefdr':str( $futurefdr ) }
#if str( $xls_to_interval ) == 'create':
#set $__options['xls_to_interval'] = { 'peaks_file': str( $output_xls_to_interval_peaks_file ), 'negative_peaks_file': str( $output_xls_to_interval_negative_peaks_file ) }
#else:
@@ -145,13 +145,14 @@
<param name="input_control_file1" value="chipseq_input.bed.gz" ftype="bed" /><param name="experiment_name" value="Galaxy Test Run" /><param name="tsize" value="36" />
- <param name="mfold" value="10,30" />
+ <param name="mfold" value="13" /><param name="gsize" value="2.7e+9" /><param name="bw" value="300" /><param name="pvalue" value="1e-5" /><param name="xls_to_interval" /><param name="wig_type_selector" value="no_wig" /><param name="nolambda"/>
+ <param name="lambdaset" value="1000,5000,10000"/><param name="nomodel_type_selector" value="create_model" /><param name="diag_type_selector" value="no_diag" /><param name="futurefdr"/>
@@ -170,13 +171,14 @@
<param name="input_control_file1" value="chipseq_input.bed.gz" ftype="bed" /><param name="experiment_name" value="Galaxy Test Run" /><param name="tsize" value="36" />
- <param name="mfold" value="10,30" />
+ <param name="mfold" value="13" /><param name="gsize" value="2.7e+9" /><param name="bw" value="300" /><param name="pvalue" value="1e-5" /><param name="xls_to_interval" value="true" /><param name="wig_type_selector" value="no_wig" /><param name="nolambda"/>
+ <param name="lambdaset" value="1000,5000,10000"/><param name="nomodel_type_selector" value="create_model" /><param name="diag_type_selector" value="no_diag" /><param name="futurefdr"/>
@@ -193,7 +195,7 @@
<param name="input_control_file1" value="chipseq_input.bed.gz" ftype="bed" /><param name="experiment_name" value="Galaxy Test Run" /><param name="tsize" value="36" />
- <param name="mfold" value="10,30" />
+ <param name="mfold" value="13" /><param name="gsize" value="2.7e+9" /><param name="bw" value="300" /><param name="pvalue" value="1e-5" />
@@ -202,6 +204,7 @@
<param name="wigextend" value="-1" /><param name="space" value="10" /><param name="nolambda"/>
+ <param name="lambdaset" value="1000,5000,10000"/><param name="nomodel_type_selector" value="create_model" /><param name="diag_type_selector" value="no_diag" /><param name="futurefdr"/>
--- a/tools/plotting/histogram.py Tue Jul 05 11:42:56 2011 -0400
+++ b/tools/plotting/histogram.py Wed Jul 06 09:45:41 2011 +1000
@@ -73,8 +73,7 @@
if skipped_lines < i:
try:
- #a = array( matrix )
- a=matrix
+ a = r.array( matrix )
r.pdf( out_fname, 8, 8 )
histogram = r.hist( a, probability=not frequency, main=title, xlab=xlab, breaks=breaks )
if density:
--- a/tools/plotting/scatterplot.py Tue Jul 05 11:42:56 2011 -0400
+++ b/tools/plotting/scatterplot.py Wed Jul 06 09:45:41 2011 +1000
@@ -19,14 +19,8 @@
title = sys.argv[5]
xlab = sys.argv[6]
ylab = sys.argv[7]
- out_type = sys.argv[8]
- out_width = int(sys.argv[9])
- out_height = int(sys.argv[10])
- point_size = float(sys.argv[11])
-
- xvec=[]
- yvec=[]
+ matrix = []
skipped_lines = 0
first_invalid_line = 0
invalid_value = ''
@@ -34,19 +28,17 @@
i = 0
for i, line in enumerate( file( in_fname ) ):
valid = True
- vals = []
line = line.rstrip( '\r\n' )
if line and not line.startswith( '#' ):
row = []
fields = line.split( "\t" )
- for c,column in enumerate(columns):
+ for column in columns:
try:
val = fields[column]
if val.lower() == "na":
- v = float( "nan" )
+ row.append( float( "nan" ) )
else:
- v = float( fields[column] )
- vals.append(val)
+ row.append( float( fields[column] ) )
except:
valid = False
skipped_lines += 1
@@ -65,19 +57,12 @@
first_invalid_line = i+1
if valid:
- xvec.append(vals[0])
- yvec.append(vals[1])
+ matrix.append( row )
+
if skipped_lines < i:
try:
- if out_type == "jpg":
- r.jpeg(out_fname,width=out_width,height=out_height)
- elif out_type == "png":
- # type="cairo" needed to be set for headless servers
- r.png(out_fname,type="cairo",width=out_width,height=out_height)
- else:
- r.pdf(out_fname, out_width, out_height)
-
- r.plot(xvec,yvec, type="p", main=title, xlab=xlab, ylab=ylab, col="blue", pch=19,cex=point_size )
+ r.pdf( out_fname, 8, 8 )
+ r.plot( array( matrix ), type="p", main=title, xlab=xlab, ylab=ylab, col="blue", pch=19 )
r.dev_off()
except Exception, exc:
stop_err( "%s" %str( exc ) )
--- a/tools/plotting/scatterplot.xml Tue Jul 05 11:42:56 2011 -0400
+++ b/tools/plotting/scatterplot.xml Wed Jul 06 09:45:41 2011 +1000
@@ -1,6 +1,6 @@
<tool id="scatterplot_rpy" name="Scatterplot"><description>of two numeric columns</description>
- <command interpreter="python">scatterplot.py $input $out_file1 $col1 $col2 "$title" "$xlab" "$ylab" $output_format $out_width $out_height $point_size</command>
+ <command interpreter="python">scatterplot.py $input $out_file1 $col1 $col2 "$title" "$xlab" "$ylab"</command><inputs><param name="input" type="data" format="tabular" label="Dataset" help="Dataset missing? See TIP below"/><param name="col1" type="data_column" data_ref="input" numerical="True" label="Numerical column for x axis" />
@@ -8,26 +8,15 @@
<param name="title" size="30" type="text" value="Scatterplot" label="Plot title"/><param name="xlab" size="30" type="text" value="V1" label="Label for x axis"/><param name="ylab" size="30" type="text" value="V2" label="Label for y axis"/>
- <param name="output_format" type="select" label="Output format">
- <option value="pdf">pdf</option>
- <option value="png">png</option>
- <option value="jpg">jpg</option>
- </param>
- <param name="out_width" size="4" type="integer" value="8" label="Width (pdf=inches, image=pixels)"/>
- <param name="out_height" size="4" type="integer" value="8" label="Height (pdf=inches, image=pixels)"/>
- <param name="point_size" size="4" type="float" value="0.2" label="Point Size"/></inputs><outputs>
- <data format="pdf" name="out_file1">
- <change_format>
- <when input="output_format" value="png" format="png" />
- <when input="output_format" value="jpg" format="jpg" />
- </change_format>
- </data>
+ <data format="pdf" name="out_file1" /></outputs><requirements><requirement type="python-module">rpy</requirement></requirements>
+ <!-- TODO: uncomment the following test when we have tools.update_state() working for
+ multiple dependents with the same dependency.
<tests><test><param name="input" value="scatterplot_in1.tabular" ftype="tabular"/>
@@ -36,38 +25,8 @@
<param name="title" value="Scatterplot"/><param name="xlab" value="V1"/><param name="ylab" value="V2"/>
- <param name="out_width" value="8"/>
- <param name="out_height" value="8"/>
- <param name="point_size" value="0.5"/>
- <param name="output_format" value="pdf" /><output name="out_file1" file="scatterplot_out1.pdf" /></test>
- <test>
- <param name="input" value="scatterplot_in1.tabular" ftype="tabular"/>
- <param name="col1" value="2"/>
- <param name="col2" value="3"/>
- <param name="title" value="Scatterplot"/>
- <param name="xlab" value="V1"/>
- <param name="ylab" value="V2"/>
- <param name="out_width" value="800"/>
- <param name="out_height" value="600"/>
- <param name="point_size" value="0.5"/>
- <param name="output_format" value="png" />
- <output name="out_file1" file="scatterplot_out1.png" />
- </test>
- <test>
- <param name="input" value="scatterplot_in1.tabular" ftype="tabular"/>
- <param name="col1" value="2"/>
- <param name="col2" value="3"/>
- <param name="title" value="Scatterplot"/>
- <param name="xlab" value="V1"/>
- <param name="ylab" value="V2"/>
- <param name="out_width" value="800"/>
- <param name="out_height" value="600"/>
- <param name="point_size" value="0.5"/>
- <param name="output_format" value="jpg" />
- <output name="out_file1" file="scatterplot_out1.jpg" />
- </test></tests>
--><help>
--- a/tools/samtools/bam_to_sam.py Tue Jul 05 11:42:56 2011 -0400
+++ b/tools/samtools/bam_to_sam.py Wed Jul 06 09:45:41 2011 +1000
@@ -21,6 +21,7 @@
parser = optparse.OptionParser()
parser.add_option( '', '--input1', dest='input1', help='The input SAM dataset' )
parser.add_option( '', '--output1', dest='output1', help='The output BAM dataset' )
+ parser.add_option( '', '--header', dest='header', action='store_true', default=False, help='Write SAM Header' )
( options, args ) = parser.parse_args()
# output version # of tool
@@ -87,7 +88,11 @@
try:
# Extract all alignments from the input BAM file to SAM format ( since no region is specified, all the alignments will be extracted ).
- command = 'samtools view -o -h %s %s' % ( options.output1, tmp_sorted_aligns_file_name )
+ if options.header:
+ view_options = "-h"
+ else:
+ view_options = ""
+ command = 'samtools view %s -o %s %s' % ( view_options, options.output1, tmp_sorted_aligns_file_name )
tmp = tempfile.NamedTemporaryFile( dir=tmp_dir ).name
tmp_stderr = open( tmp, 'wb' )
proc = subprocess.Popen( args=command, shell=True, cwd=tmp_dir, stderr=tmp_stderr.fileno() )
--- a/tools/samtools/sam_bitwise_flag_filter.py Tue Jul 05 11:42:56 2011 -0400
+++ b/tools/samtools/sam_bitwise_flag_filter.py Wed Jul 06 09:45:41 2011 +1000
@@ -1,6 +1,6 @@
#!/usr/bin/env python
# Refactored on 11/13/2010 by Kanwei Li
-# Added drop_header option - default is now keep headers for downstream sanity by ross lazarus
+
import sys
import optparse
@@ -14,11 +14,7 @@
options (listed below) default to 'None' if omitted
"""
parser = optparse.OptionParser(usage=usage)
- parser.add_option('--drop_header',
- action = 'store_true',
- dest='drop_header',
- help="Remove sam header - you probably NEVER want this for fussy downstream tools")
-
+
parser.add_option(
'--0x0001','--is_paired',
choices = ( '0','1' ),
@@ -133,24 +129,21 @@
opt_map = { '0': False, '1': True }
used_indices = [(index, opt_map[opt]) for index, opt in enumerate(opt_ary) if opt is not None]
flag_col = int( options.flag_col ) - 1
+
for line in infile:
line = line.rstrip( '\r\n' )
- if line:
- if line.startswith('@'):
- if not options.drop_header:
- print line # usually want these so add -h if you don't want headers
- elif not line.startswith( '#' ) :
- fields = line.split( '\t' )
- flags = int( fields[flag_col] )
+ if line and not line.startswith( '#' ) and not line.startswith( '@' ) :
+ fields = line.split( '\t' )
+ flags = int( fields[flag_col] )
- valid_line = True
- for index, opt_bool in used_indices:
- if bool(flags & 0x0001 << index) != opt_bool:
- valid_line = False
- break
+ valid_line = True
+ for index, opt_bool in used_indices:
+ if bool(flags & 0x0001 << index) != opt_bool:
+ valid_line = False
+ break
- if valid_line:
- print line
+ if valid_line:
+ print line
if __name__ == "__main__": main()
--- a/tools/samtools/sam_bitwise_flag_filter.xml Tue Jul 05 11:42:56 2011 -0400
+++ b/tools/samtools/sam_bitwise_flag_filter.xml Wed Jul 06 09:45:41 2011 +1000
@@ -1,11 +1,8 @@
-<tool id="sam_bw_filter" name="Filter SAM" version="1.0.1">
+<tool id="sam_bw_filter" name="Filter SAM" version="1.0.0"><description>on bitwise flag values</description><parallelism method="basic"></parallelism><command interpreter="python">
sam_bitwise_flag_filter.py
- #if $drop_header == "1":
- --drop_header
- #end if
--input_sam_file=$input1
--flag_column=2
#for $bit in $bits
@@ -15,11 +12,6 @@
</command><inputs><param format="sam" name="input1" type="data" label="Select dataset to filter"/>
- <param name="drop_header" type="select" display="radio" label="DROP sam headers"
- help="Set this if you REALLY want to throw away existing sam header metadata - downstream (eg Picard) tools often demand it" >
- <option value="0" selected="true">Keep headers (default)</option>
- <option value="1">Drop headers</option>
- </param><repeat name="bits" title="Flag"><param name="flags" type="select" label="Type"><option value="--0x0001">Read is paired</option>
--- a/tools/samtools/sam_to_bam.py Tue Jul 05 11:42:56 2011 -0400
+++ b/tools/samtools/sam_to_bam.py Wed Jul 06 09:45:41 2011 +1000
@@ -68,7 +68,7 @@
# and the equCab2.fa file will contain fasta sequences.
seq_path = check_seq_file( options.dbkey, cached_seqs_pointer_file )
tmp_dir = tempfile.mkdtemp()
- if options.ref_file == 'None':
+ if not options.ref_file or options.ref_file == 'None':
# We're using locally cached reference sequences( e.g., /galaxy/data/equCab2/sam_index/equCab2.fa ).
# The indexes for /galaxy/data/equCab2/sam_index/equCab2.fa will be contained in
# a file named /galaxy/data/equCab2/sam_index/equCab2.fa.fai
@@ -125,9 +125,7 @@
tmp_aligns_file = tempfile.NamedTemporaryFile( dir=tmp_dir )
tmp_aligns_file_name = tmp_aligns_file.name
tmp_aligns_file.close()
- # IMPORTANT NOTE: for some reason the samtools view command gzips the resulting bam file without warning,
- # and the docs do not currently state that this occurs ( very bad ).
- command = 'samtools view -h -bt %s -o %s %s' % ( fai_index_file_path, tmp_aligns_file_name, options.input1 )
+ command = 'samtools view -bt %s -o %s %s' % ( fai_index_file_path, tmp_aligns_file_name, options.input1 )
tmp = tempfile.NamedTemporaryFile( dir=tmp_dir ).name
tmp_stderr = open( tmp, 'wb' )
proc = subprocess.Popen( args=command, shell=True, cwd=tmp_dir, stderr=tmp_stderr.fileno() )
@@ -147,8 +145,6 @@
tmp_stderr.close()
if returncode != 0:
raise Exception, stderr
- if len( open( tmp_aligns_file_name ).read() ) == 0:
- raise Exception, 'Initial BAM file empty'
except Exception, e:
#clean up temp files
if os.path.exists( tmp_dir ):
@@ -188,11 +184,6 @@
stop_err( 'Error sorting alignments from (%s), %s' % ( tmp_aligns_file_name, str( e ) ) )
# Move tmp_aligns_file_name to our output dataset location
sorted_bam_file = '%s.bam' % tmp_sorted_aligns_file_name
- if os.path.getsize( sorted_bam_file ) == 0:
- #clean up temp files
- if os.path.exists( tmp_dir ):
- shutil.rmtree( tmp_dir )
- stop_err( 'Error creating sorted version of BAM file' )
shutil.move( sorted_bam_file, options.output1 )
#clean up temp files
if os.path.exists( tmp_dir ):
@@ -201,6 +192,6 @@
if os.path.getsize( options.output1 ) > 0:
sys.stdout.write( 'SAM file converted to BAM' )
else:
- stop_err( 'The output file is empty, there may be an error with your input file or settings.' )
+ stop_err( 'Error creating sorted version of BAM file.' )
if __name__=="__main__": __main__()
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: Trackster: add infrastructure for getting data iteratively but, for now, still fetch all data when getting more data. Use Galaxy button styles as well.
by Bitbucket 05 Jul '11
by Bitbucket 05 Jul '11
05 Jul '11
1 new changeset in galaxy-central:
http://bitbucket.org/galaxy/galaxy-central/changeset/9a5c403bb2e5/
changeset: 9a5c403bb2e5
user: jgoecks
date: 2011-07-05 17:42:56
summary: Trackster: add infrastructure for getting data iteratively but, for now, still fetch all data when getting more data. Use Galaxy button styles as well.
affected #: 1 file (2.2 KB)
--- a/static/scripts/trackster.js Tue Jul 05 16:46:21 2011 +1000
+++ b/static/scripts/trackster.js Tue Jul 05 11:42:56 2011 -0400
@@ -305,10 +305,8 @@
// Look for entry and return if found.
var
mode = this.track.mode,
- entry = this.get(this.gen_key(low, high, mode));
- if (entry) {
- return entry;
- }
+ entry = this.get_data_from_cache(low, high, mode);
+ if (entry) { return entry; }
//
// If data supports subsetting:
@@ -348,6 +346,69 @@
this.set_data(low, high, mode, entry);
return entry
},
+ /** "Deep" data request; used as a parameter for DataManager.get_more_data() */
+ DEEP_DATA_REQ: "deep",
+ /** "Broad" data request; used as a parameter for DataManager.get_more_data() */
+ BROAD_DATA_REQ: "breadth",
+ /**
+ * Gets more data for a region using either a depth-first or a breadth-first approach.
+ */
+ get_more_data: function(low, high, resolution, extra_params, req_type) {
+ //
+ // Get current data from cache and mark as stale.
+ //
+ var
+ mode = this.track.mode,
+ cur_data = this.get_data_from_cache(low, high, mode);
+ if (!cur_data) {
+ console.log("ERROR: no current data for: ", this.track, low, high, resolution, extra_params);
+ return;
+ }
+ cur_data.stale = true;
+
+ //
+ // Set parameters based on request type.
+ //
+ if (req_type === this.DEEP_DATA_REQ) {
+ // HACK: for now, just up the max vals and request all data; in the future,
+ // need server to recognize min_vals and max_vals to specify range of data to
+ // return.
+ $.extend(extra_params, {max_vals: cur_data.data.length * 2});
+ }
+ else if (req_type === this.BROAD_DATA_REQ) {
+ // Set low to be past the last feature returned.
+ low = cur_data.data[cur_data.length-1][2] + 1;
+ }
+
+ //
+ // Get additional data, append to current data, and set new data. Use a custom deferred object
+ // to signal when new data is available.
+ //
+ var
+ data_manager = this,
+ new_data_request = this.load_data(low, high, resolution, extra_params)
+ new_data_available = $.Deferred();
+ // load_data sets cache to new_data_request, but use custom deferred object so that signal and data
+ // is all data, not just new data.
+ this.set_data(low, high, mode, new_data_available);
+ $.when(new_data_request).then(function(result) {
+ if (result.data) {
+ //result.data.append(cur_data.data);
+ }
+ data_manager.set_data(low, high, mode, result);
+ new_data_available.resolve(result);
+ });
+ return new_data_available;
+ },
+ /**
+ * Gets data from the cache.
+ */
+ get_data_from_cache: function(low, high, mode) {
+ return this.get(this.gen_key(low, high, mode));
+ },
+ /**
+ * Sets data in the cache.
+ */
set_data: function(low, high, mode, result) {
//console.log("set_data", low, high, mode, result);
return this.set(this.gen_key(low, high, mode), result);
@@ -2150,18 +2211,15 @@
message_div = $("<div/>").addClass("tile-message").text(tile.message).
// -1 to account for border.
css({'height': ERROR_PADDING-1, 'width': tile.canvas.width}).appendTo(container_div),
- show_more_data_btn = $("<button/>").text("Show more").css("margin-left", "0.5em").appendTo(message_div);
+ show_more_data_btn = $("<div/>").text("Show more").addClass("action-button").css({'padding-top': 0, 'padding-bottom':0}).appendTo(message_div);
container_div.append(canvas);
tile_element = container_div;
// Set up actions for button.
show_more_data_btn.click(function() {
- // Mark data, tile as stale, request more data, and redraw track.
- // HACK: get_data used will return object that can be marked as stale, but a better way to this is needed.
- var cur_data = track.data_manager.get_data(tile.low, tile.high, tile.resolution);
- cur_data.stale = true;
+ // Mark tile as stale, request more data, and redraw track.
tile.stale = true;
- track.data_manager.get_data(tile.low, tile.high, tile.resolution, {max_vals: cur_data.data.length * 2});
+ track.data_manager.get_more_data(tile.low, tile.high, tile.resolution, {}, track.data_manager.DEEP_DATA_REQ);
track.draw();
}).dblclick(function(e) {
// Do not propogate as this would normal zoom in.
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 changesets in galaxy-central:
http://bitbucket.org/galaxy/galaxy-central/changeset/48bbe32beefe/
changeset: 48bbe32beefe
user: galaxy galaxy
date: 2011-07-05 04:40:43
summary: branch merge
affected #: 250 files (5.2 KB)
--- a/lib/galaxy/security/__init__.py Mon Jul 04 11:06:04 2011 -0400
+++ b/lib/galaxy/security/__init__.py Tue Jul 05 12:40:43 2011 +1000
@@ -1005,7 +1005,8 @@
ucsc_main = ( 'hgw1.cse.ucsc.edu', 'hgw2.cse.ucsc.edu', 'hgw3.cse.ucsc.edu', 'hgw4.cse.ucsc.edu',
'hgw5.cse.ucsc.edu', 'hgw6.cse.ucsc.edu', 'hgw7.cse.ucsc.edu', 'hgw8.cse.ucsc.edu' ),
ucsc_test = ( 'hgwdev.cse.ucsc.edu', ),
- ucsc_archaea = ( 'lowepub.cse.ucsc.edu', )
+ ucsc_archaea = ( 'lowepub.cse.ucsc.edu', ),
+ ucsc_bhri = ('ucsc.omics.bhri.internal','galaxy.omics.bhri.internal'),
)
def __init__( self, model, permitted_actions=None ):
self.model = model
@@ -1036,7 +1037,7 @@
# We're going to search in order, but if the remote site is load
# balancing their connections (as UCSC does), this is okay.
try:
- if socket.gethostbyname( server ) == addr:
+ if socket.gethostbyname( server ) == addr or server == '127.0.0.1' or server == '172.16.0.38':
break # remote host is in the server list
except ( socket.error, socket.gaierror ):
pass # can't resolve, try next
--- a/lib/galaxy/tools/__init__.py Mon Jul 04 11:06:04 2011 -0400
+++ b/lib/galaxy/tools/__init__.py Tue Jul 05 12:40:43 2011 +1000
@@ -922,6 +922,8 @@
if not self.check_values:
return
for input in self.inputs.itervalues():
+ if input.name not in value:
+ value[input.name] = input.get_initial_value( None, value )
if isinstance( input, ToolParameter ):
callback( "", input, value[input.name] )
else:
--- a/lib/galaxy/tools/parameters/basic.py Mon Jul 04 11:06:04 2011 -0400
+++ b/lib/galaxy/tools/parameters/basic.py Tue Jul 05 12:40:43 2011 +1000
@@ -748,9 +748,6 @@
# Dependency on a value that does not yet exist
if isinstance( dep_value, RuntimeValue ):
return True
- #dataset not ready yet
- if hasattr( self, 'ref_input' ) and isinstance( dep_value, self.tool.app.model.HistoryDatasetAssociation ) and ( dep_value.is_pending or not isinstance( dep_value.datatype, self.ref_input.formats ) ):
- return True
# Dynamic, but all dependenceis are known and have values
return False
def get_initial_value( self, trans, context ):
@@ -881,7 +878,6 @@
self.force_select = string_as_bool( elem.get( "force_select", True ))
self.accept_default = string_as_bool( elem.get( "accept_default", False ))
self.data_ref = elem.get( "data_ref", None )
- self.ref_input = None
self.default_value = elem.get( "default_value", None )
self.is_dynamic = True
def from_html( self, value, trans=None, context={} ):
@@ -977,7 +973,7 @@
if not dataset.metadata.columns:
# Only allow late validation if the dataset is not yet ready
# (since we have reason to expect the metadata to be ready eventually)
- if dataset.is_pending or not isinstance( dataset.datatype, self.ref_input.formats ):
+ if dataset.is_pending:
return True
# No late validation
return False
@@ -1357,7 +1353,7 @@
selected = ( value and ( hda in value ) )
field.add_option( "%s: %s" % ( hid, hda_name ), hda.id, selected )
else:
- target_ext, converted_dataset = hda.find_conversion_destination( self.formats )
+ target_ext, converted_dataset = hda.find_conversion_destination( self.formats, converter_safe = self.converter_safe( other_values, trans ) )
if target_ext:
if converted_dataset:
hda = converted_dataset
@@ -1406,22 +1402,13 @@
pass #no valid options
def dataset_collector( datasets ):
def is_convertable( dataset ):
- target_ext, converted_dataset = dataset.find_conversion_destination( self.formats )
+ target_ext, converted_dataset = dataset.find_conversion_destination( self.formats, converter_safe = self.converter_safe( context, trans ) )
if target_ext is not None:
return True
return False
for i, data in enumerate( datasets ):
- if data.visible and not data.deleted and data.state not in [data.states.ERROR, data.states.DISCARDED]:
- is_valid = False
- if isinstance( data.datatype, self.formats ):
- is_valid = True
- else:
- target_ext, converted_dataset = data.find_conversion_destination( self.formats )
- if target_ext:
- is_valid = True
- if converted_dataset:
- data = converted_dataset
- if not is_valid or ( self.options and self._options_filter_attribute( data ) != filter_value ):
+ if data.visible and not data.deleted and data.state not in [data.states.ERROR, data.states.DISCARDED] and ( isinstance( data.datatype, self.formats) or is_convertable( data ) ):
+ if self.options and self._options_filter_attribute( data ) != filter_value:
continue
most_recent_dataset[0] = data
# Also collect children via association object
--- a/lib/galaxy/web/framework/middleware/remoteuser.py Mon Jul 04 11:06:04 2011 -0400
+++ b/lib/galaxy/web/framework/middleware/remoteuser.py Tue Jul 05 12:40:43 2011 +1000
@@ -36,6 +36,7 @@
"""
UCSC_MAIN_SERVERS = (
+ 'omics.bhri.internal',
'hgw1.cse.ucsc.edu',
'hgw2.cse.ucsc.edu',
'hgw3.cse.ucsc.edu',
@@ -49,6 +50,7 @@
'lowepub.cse.ucsc.edu',
)
+
class RemoteUser( object ):
def __init__( self, app, maildomain=None, ucsc_display_sites=[], admin_users=[] ):
self.app = app
@@ -56,7 +58,7 @@
self.allow_ucsc_main = False
self.allow_ucsc_archaea = False
self.admin_users = admin_users
- if 'main' in ucsc_display_sites or 'test' in ucsc_display_sites:
+ if 'main' in ucsc_display_sites or 'test' in ucsc_display_sites or 'bhri' in ucsc_display_sites:
self.allow_ucsc_main = True
if 'archaea' in ucsc_display_sites:
self.allow_ucsc_archaea = True
--- a/scripts/cleanup_datasets/purge_libraries.sh Mon Jul 04 11:06:04 2011 -0400
+++ b/scripts/cleanup_datasets/purge_libraries.sh Tue Jul 05 12:40:43 2011 +1000
@@ -1,4 +1,5 @@
#!/bin/sh
cd `dirname $0`/../..
-python ./scripts/cleanup_datasets/cleanup_datasets.py ./universe_wsgi.ini -d 10 -4 -r $@ >> ./scripts/cleanup_datasets/purge_libraries.log
+#python ./scripts/cleanup_datasets/cleanup_datasets.py ./universe_wsgi.ini -d 10 -4 -r $@ >> ./scripts/cleanup_datasets/purge_libraries.log
+python ./scripts/cleanup_datasets/cleanup_datasets.py ./universe_wsgi.ini -d 2 -4 -r $@ >> ./scripts/cleanup_datasets/purge_libraries.log
--- a/tool-data/shared/ucsc/ucsc_build_sites.txt Mon Jul 04 11:06:04 2011 -0400
+++ b/tool-data/shared/ucsc/ucsc_build_sites.txt Tue Jul 05 12:40:43 2011 +1000
@@ -1,5 +1,6 @@
#Harvested from http://genome.ucsc.edu/cgi-bin/das/dsn
main http://genome.ucsc.edu/cgi-bin/hgTracks? priPac1,danRer4,mm9,mm8,droAna1,mm5,caeRem2,mm7,mm6,panTro1,dm3,panTro2,anoCar1,ce4,galGal3,galGal2,ce1,rn3,rn2,droMoj1,droMoj2,rn4,droYak1,droYak2,dp3,dp2,dm1,canFam1,danRer5,canFam2,danRer3,danRer2,ornAna1,ci2,ci1,tetNig1,bosTau1,bosTau3,bosTau2,equCab1,oryLat1,droAna2,droEre1,ponAbe2,rheMac2,sacCer1,droPer1,droSim1,monDom1,cb1,dm2,droSec1,strPur1,droVir2,droVir1,strPur2,sc1,xenTro1,droGri1,xenTro2,cb3,gasAcu1,caePb1,anoGam1,fr2,fr1,hg15,hg16,hg17,hg18,felCat3,apiMel2,monDom4,apiMel1,ce2
+bhri http://ucsc.omics.bhri.internal/cgi-bin/hgTracks? hg18,hg19,mm8,mm9,rn4
#Harvested from http://archaea.ucsc.edu/cgi-bin/das/dsn
archaea http://archaea.ucsc.edu/cgi-bin/hgTracks? alkaEhrl_MLHE_1,shewW318,idioLoih_L2TR,sulSol1,erwiCaro_ATROSEPTICA,symbTher_IAM14863,moorTher_ATCC39073,therFusc_YX,methHung1,bradJapo,therElon,shewPutrCN32,pediPent_ATCC25745,mariMari_MCS10,nanEqu1,baciSubt,chlaTrac,magnMagn_AMB_1,chroViol,ralsSola,acidCryp_JF_5,erytLito_HTCC2594,desuVulg_HILDENBOROUG,pyrAer1,sulfToko1,shewANA3,paraSp_UWE25,geobKaus_HTA426,rhizEtli_CFN_42,uncuMeth_RCI,candBloc_FLORIDANUS,deinRadi,yersPest_CO92,saccEryt_NRRL_2338,rhodRHA1,candCars_RUDDII,burkMall_ATCC23344,eschColi_O157H7,burk383,psycIngr_37,rhodSpha_2_4_1,wolbEndo_OF_DROSOPHIL,burkViet_G4,propAcne_KPA171202,enteFaec_V583,campJeju_81_176,acidJS42,heliPylo_26695,pseuHalo_TAC125,chroSale_DSM3043,methVann1,archFulg1,neisMeni_Z2491_1,fusoNucl,vermEise_EF01_2,anabVari_ATCC29413,tropWhip_TW08_27,heliHepa,acinSp_ADP1,anapMarg_ST_MARIES,natrPhar1,haheChej_KCTC_2396,therPetr_RKU_1,neisGono_FA1090_1,colwPsyc_34H,desuPsyc_LSV54,hyphNept_ATCC15444,vibrChol1,deinGeot_DSM11300,strePyog_M1_GAS,franCcI3,salmTyph,metaSedu,lactSali_UCC118,trepPall,neisMeni_MC58_1,syntWolf_GOETTINGEN,flavJohn_UW101,methBoon1,haemSomn_129PT,shewLoihPV4,igniHosp1,haemInfl_KW20,haloHalo_SL1,ferrAcid1,sphiAlas_RB2256,candPela_UBIQUE_HTCC1,caldSacc_DSM8903,aerPer1,lactPlan,carbHydr_Z_2901,therTher_HB8,vibrVuln_YJ016_1,rhodPalu_CGA009,acidCell_11B,siliPome_DSS_3,therVolc1,haloWals1,rubrXyla_DSM9941,shewAmaz,nocaJS61,vibrVuln_CMCP6_1,sinoMeli,ureaUrea,baciHalo,bartHens_HOUSTON_1,nitrWino_NB_255,hypeButy1,methBurt2,polaJS66,mesoLoti,methMari_C7,caulCres,neisMeni_FAM18_1,acidBact_ELLIN345,caldMaqu1,salmEnte_PARATYPI_ATC,glucOxyd_621H,cytoHutc_ATCC33406,nitrEuro,therMari,coxiBurn,woliSucc,heliPylo_HPAG1,mesoFlor_L1,pyrHor1,methAeol1,procMari_CCMP1375,pyroArse1,oenoOeni_PSU_1,alcaBork_SK2,wiggBrev,actiPleu_L20,lactLact,methJann1,paraDeni_PD1222,borrBurg,pyroIsla1,orieTsut_BORYONG,shewMR4,methKand1,methCaps_BATH,onioYell_PHYTOPLASMA,bordBron,cenaSymb1,burkCeno_HI2424,franTula_TULARENSIS,pyrFur2,mariAqua_VT8,heliPylo_J99,psycArct_273_4,vibrChol_MO10_1,vibrPara1,rickBell_RML369_C,metAce1,buchSp,ehrlRumi_WELGEVONDEN,methLabrZ_1,chlaPneu_CWL029,thioCrun_XCL_2,pyroCali1,chloTepi_TLS,stapAure_MU50,novoArom_DSM12444,magnMC1,zymoMobi_ZM4,salmTyph_TY2,chloChlo_CAD3,azoaSp_EBN1,therTher_HB27,bifiLong,picrTorr1,listInno,bdelBact,gramFors_KT0803,sulfAcid1,geobTher_NG80_2,peloCarb,ralsEutr_JMP134,mannSucc_MBEL55E,syneSp_WH8102,methTherPT1,clavMich_NCPPB_382,therAcid1,syntAcid_SB,porpGing_W83,therNeut0,leifXyli_XYLI_CTCB0,shewFrig,photProf_SS9,thioDeni_ATCC25259,methMaze1,desuRedu_MI_1,burkThai_E264,campFetu_82_40,blocFlor,jannCCS1,nitrMult_ATCC25196,streCoel,soliUsit_ELLIN6076,pastMult,saliRube_DSM13855,methTher1,nostSp,shigFlex_2A,saccDegr_2_40,oceaIhey,dehaEthe_195,rhodRubr_ATCC11170,arthFB24,shewMR7,pireSp,anaeDeha_2CP_C,haloVolc1,dichNodo_VCS1703A,tricEryt_IMS101,mycoGeni,thioDeni_ATCC33889,methSmit1,geobUran_RF4,shewDeni,halMar1,desuHafn_Y51,methStad1,granBeth_CGDNIH1,therPend1,legiPneu_PHILADELPHIA,vibrChol_O395_1,nitrOcea_ATCC19707,campJeju_RM1221,methPetr_PM1,heliAcin_SHEEBA,eschColi_APEC_O1,peloTher_SI,haloHalo1,syntFuma_MPOB,xyleFast,gloeViol,leucMese_ATCC8293,bactThet_VPI_5482,xantCamp,sodaGlos_MORSITANS,geobSulf,roseDeni_OCH_114,coryEffi_YS_314,brucMeli,mycoTube_H37RV,vibrFisc_ES114_1,pyrAby1,burkXeno_LB400,polyQLWP,stapMari1,peloLute_DSM273,burkCeno_AU_1054,shewBalt,nocaFarc_IFM10152,ente638,mculMari1,saliTrop_CNB_440,neorSenn_MIYAYAMA,aquiAeol,dechArom_RCB,myxoXant_DK_1622,burkPseu_1106A,burkCepa_AMMD,methMari_C5_1,azorCaul2,methFlag_KT,leptInte,eschColi_K12,synePCC6,baumCica_HOMALODISCA,methBark1,pseuAeru,geobMeta_GS15,eschColi_CFT073,photLumi,metMar1,hermArse,campJeju,therKoda1,aeroHydr_ATCC7966,baciAnth_AMES,shewOnei,therTeng,lawsIntr_PHE_MN1_00
#Harvested from http://genome-test.cse.ucsc.edu/cgi-bin/das/dsn
--- a/tool_conf.xml.sample Mon Jul 04 11:06:04 2011 -0400
+++ b/tool_conf.xml.sample Tue Jul 05 12:40:43 2011 +1000
@@ -368,6 +368,7 @@
</section><section name="NGS: Simulation" id="ngs-simulation"><tool file="ngs_simulation/ngs_simulation.xml" />
+ <tool file="rgenetics/EpiD.xml" /></section><section name="SNP/WGA: Data; Filters" id="rgdat"><label text="Data: Import and upload" id="rgimport" />
--- a/tools/data_source/ucsc_tablebrowser.xml Mon Jul 04 11:06:04 2011 -0400
+++ b/tools/data_source/ucsc_tablebrowser.xml Tue Jul 05 12:40:43 2011 +1000
@@ -5,27 +5,27 @@
initial response ( in addition to 'URL' ) will be encoded and appended to URL and a post will be performed.
--><tool name="UCSC Main" id="ucsc_table_direct1" tool_type="data_source">
- <description>table browser</description>
- <command interpreter="python">data_source.py $output $__app__.config.output_size_limit</command>
- <inputs action="http://genome.ucsc.edu/cgi-bin/hgTables" check_values="false" method="get">
- <display>go to UCSC Table Browser $GALAXY_URL</display>
- <param name="GALAXY_URL" type="baseurl" value="/tool_runner" />
- <param name="tool_id" type="hidden" value="ucsc_table_direct1" />
- <param name="sendToGalaxy" type="hidden" value="1" />
- <param name="hgta_compressType" type="hidden" value="none" />
- <param name="hgta_outputType" type="hidden" value="bed" />
- </inputs>
- <request_param_translation>
+ <description>table browser</description>
+ <command interpreter="python">data_source.py $output $__app__.config.output_size_limit</command>
+ <inputs action="http://ucsc.omics.bhri.internal/cgi-bin/hgTables" check_values="false" method="get">
+ <display>go to UCSC Table Browser $GALAXY_URL</display>
+ <param name="GALAXY_URL" type="baseurl" value="/tool_runner" />
+ <param name="tool_id" type="hidden" value="ucsc_table_direct1" />
+ <param name="sendToGalaxy" type="hidden" value="1" />
+ <param name="hgta_compressType" type="hidden" value="none" />
+ <param name="hgta_outputType" type="hidden" value="bed" />
+ </inputs>
+ <request_param_translation><request_param galaxy_name="URL_method" remote_name="URL_method" missing="post" /><request_param galaxy_name="URL" remote_name="URL" missing="" /><request_param galaxy_name="dbkey" remote_name="db" missing="?" /><request_param galaxy_name="organism" remote_name="org" missing="unknown species" />
- <request_param galaxy_name="table" remote_name="hgta_table" missing="unknown table" />
- <request_param galaxy_name="description" remote_name="hgta_regionType" missing="no description" />
- <request_param galaxy_name="data_type" remote_name="hgta_outputType" missing="auto" >
+ <request_param galaxy_name="table" remote_name="hgta_table" missing="unknown table" />
+ <request_param galaxy_name="description" remote_name="hgta_regionType" missing="no description" />
+ <request_param galaxy_name="data_type" remote_name="hgta_outputType" missing="tabular" ><value_translation>
- <value galaxy_value="auto" remote_value="primaryTable" />
- <value galaxy_value="auto" remote_value="selectedFields" />
+ <value galaxy_value="tabular" remote_value="primaryTable" />
+ <value galaxy_value="tabular" remote_value="selectedFields" /><value galaxy_value="wig" remote_value="wigData" /><value galaxy_value="interval" remote_value="tab" /><value galaxy_value="html" remote_value="hyperlinks" />
@@ -33,10 +33,10 @@
<value galaxy_value="gtf" remote_value="gff" /></value_translation></request_param>
- </request_param_translation>
- <uihints minwidth="800"/>
- <outputs>
- <data name="output" format="tabular" label="${tool.name} on ${organism}: ${table} (#if $description == 'range' then $getVar( 'position', 'unknown position' ) else $description#)"/>
- </outputs>
- <options sanitize="False" refresh="True"/>
+ </request_param_translation>
+ <uihints minwidth="800"/>
+ <outputs>
+ <data name="output" format="tabular" />
+ </outputs>
+ <options sanitize="False" refresh="True"/></tool>
--- a/tools/meme/meme.xml Mon Jul 04 11:06:04 2011 -0400
+++ b/tools/meme/meme.xml Tue Jul 05 12:40:43 2011 +1000
@@ -304,7 +304,7 @@
</when></conditional>
- <param name="non_commercial_use" label="I certify that I am not using this tool for commercial purposes." type="boolean" truevalue="NON_COMMERCIAL_USE" falsevalue="COMMERCIAL_USE" checked="False">
+ <param name="non_commercial_use" label="I certify that I am not using this tool for commercial purposes." type="boolean" truevalue="NON_COMMERCIAL_USE" falsevalue="COMMERCIAL_USE" checked="True"><validator type="expression" message="This tool is only available for non-commercial use.">value == True</validator></param>
--- a/tools/peak_calling/macs_wrapper.py Mon Jul 04 11:06:04 2011 -0400
+++ b/tools/peak_calling/macs_wrapper.py Tue Jul 05 12:40:43 2011 +1000
@@ -51,7 +51,8 @@
cmdline = "macs -t %s" % ",".join( options['input_chipseq'] )
if options['input_control']:
cmdline = "%s -c %s" % ( cmdline, ",".join( options['input_control'] ) )
- cmdline = "%s --format='%s' --name='%s' --gsize='%s' --tsize='%s' --bw='%s' --pvalue='%s' --mfold='%s' %s --lambdaset='%s' %s" % ( cmdline, options['format'], experiment_name, options['gsize'], options['tsize'], options['bw'], options['pvalue'], options['mfold'], options['nolambda'], options['lambdaset'], options['futurefdr'] )
+ cmdline = "%s --format='%s' --name='%s' --gsize='%s' --tsize='%s' --bw='%s' --pvalue='%s' --mfold='%s' %s %s" %\
+ ( cmdline, options['format'], experiment_name, options['gsize'], options['tsize'], options['bw'], options['pvalue'], options['mfold'], options['nolambda'], options['futurefdr'] )
if 'wig' in options:
wigextend = int( options['wig']['wigextend'] )
if wigextend >= 0:
--- a/tools/peak_calling/macs_wrapper.xml Mon Jul 04 11:06:04 2011 -0400
+++ b/tools/peak_calling/macs_wrapper.xml Tue Jul 05 12:40:43 2011 +1000
@@ -28,7 +28,8 @@
<param name="tsize" type="integer" label="Tag size" value="25"/><param name="bw" type="integer" label="Band width" value="300"/><param name="pvalue" type="float" label="Pvalue cutoff for peak detection" value="1e-5" help="default: 1e-5"/>
- <param name="mfold" type="integer" label="Select the regions with MFOLD high-confidence enrichment ratio against background to build model" value="32"/>
+ <param name="mfold" type="text" label="Select the regions with MFOLD high-confidence enrichment ratio against background to build model" value="10,30"
+ help="Range for high-confidence enrichment ratio against background for model are within this range. DEFAULT:10,30" /><param name="xls_to_interval" label="Parse xls files into into distinct interval files" type="boolean" truevalue="create" falsevalue="do_not_create" checked="False"/><conditional name="wig_type"><param name="wig_type_selector" type="select" label="Save shifted raw tag count at every bp into a wiggle file">
@@ -44,7 +45,6 @@
</when></conditional><param name="nolambda" label="Use fixed background lambda as local lambda for every peak region" type="boolean" truevalue="--nolambda" falsevalue="" checked="False" help="up to 9X more time consuming"/>
- <param name="lambdaset" type="text" label="3 levels of regions around the peak region to calculate the maximum lambda as local lambda" value="1000,5000,10000" size="50"/><conditional name="nomodel_type"><param name="nomodel_type_selector" type="select" label="Build Model"><option value="nomodel">Do not build the shifting model</option>
@@ -95,7 +95,7 @@
<configfile name="options_file"><%
import simplejson
%>
-#set $__options = { 'experiment_name':str( $experiment_name ), 'gsize':int( float( str( $gsize ) ) ), 'tsize':str( $tsize ), 'bw':str( $bw ), 'pvalue':str( $pvalue ), 'mfold':str( $mfold ), 'nolambda':str( $nolambda ), 'lambdaset': str( $lambdaset ), 'futurefdr':str( $futurefdr ) }
+#set $__options = { 'experiment_name':str( $experiment_name ), 'gsize':int( float( str( $gsize ) ) ), 'tsize':str( $tsize ), 'bw':str( $bw ), 'pvalue':str( $pvalue ), 'mfold':str( $mfold ), 'nolambda':str( $nolambda ), 'futurefdr':str( $futurefdr ) }
#if str( $xls_to_interval ) == 'create':
#set $__options['xls_to_interval'] = { 'peaks_file': str( $output_xls_to_interval_peaks_file ), 'negative_peaks_file': str( $output_xls_to_interval_negative_peaks_file ) }
#else:
@@ -145,14 +145,13 @@
<param name="input_control_file1" value="chipseq_input.bed.gz" ftype="bed" /><param name="experiment_name" value="Galaxy Test Run" /><param name="tsize" value="36" />
- <param name="mfold" value="13" />
+ <param name="mfold" value="10,30" /><param name="gsize" value="2.7e+9" /><param name="bw" value="300" /><param name="pvalue" value="1e-5" /><param name="xls_to_interval" /><param name="wig_type_selector" value="no_wig" /><param name="nolambda"/>
- <param name="lambdaset" value="1000,5000,10000"/><param name="nomodel_type_selector" value="create_model" /><param name="diag_type_selector" value="no_diag" /><param name="futurefdr"/>
@@ -171,14 +170,13 @@
<param name="input_control_file1" value="chipseq_input.bed.gz" ftype="bed" /><param name="experiment_name" value="Galaxy Test Run" /><param name="tsize" value="36" />
- <param name="mfold" value="13" />
+ <param name="mfold" value="10,30" /><param name="gsize" value="2.7e+9" /><param name="bw" value="300" /><param name="pvalue" value="1e-5" /><param name="xls_to_interval" value="true" /><param name="wig_type_selector" value="no_wig" /><param name="nolambda"/>
- <param name="lambdaset" value="1000,5000,10000"/><param name="nomodel_type_selector" value="create_model" /><param name="diag_type_selector" value="no_diag" /><param name="futurefdr"/>
@@ -195,7 +193,7 @@
<param name="input_control_file1" value="chipseq_input.bed.gz" ftype="bed" /><param name="experiment_name" value="Galaxy Test Run" /><param name="tsize" value="36" />
- <param name="mfold" value="13" />
+ <param name="mfold" value="10,30" /><param name="gsize" value="2.7e+9" /><param name="bw" value="300" /><param name="pvalue" value="1e-5" />
@@ -204,7 +202,6 @@
<param name="wigextend" value="-1" /><param name="space" value="10" /><param name="nolambda"/>
- <param name="lambdaset" value="1000,5000,10000"/><param name="nomodel_type_selector" value="create_model" /><param name="diag_type_selector" value="no_diag" /><param name="futurefdr"/>
--- a/tools/plotting/histogram.py Mon Jul 04 11:06:04 2011 -0400
+++ b/tools/plotting/histogram.py Tue Jul 05 12:40:43 2011 +1000
@@ -73,7 +73,8 @@
if skipped_lines < i:
try:
- a = r.array( matrix )
+ #a = array( matrix )
+ a=matrix
r.pdf( out_fname, 8, 8 )
histogram = r.hist( a, probability=not frequency, main=title, xlab=xlab, breaks=breaks )
if density:
--- a/tools/plotting/scatterplot.py Mon Jul 04 11:06:04 2011 -0400
+++ b/tools/plotting/scatterplot.py Tue Jul 05 12:40:43 2011 +1000
@@ -19,8 +19,14 @@
title = sys.argv[5]
xlab = sys.argv[6]
ylab = sys.argv[7]
+ out_type = sys.argv[8]
+ out_width = int(sys.argv[9])
+ out_height = int(sys.argv[10])
+ point_size = float(sys.argv[11])
- matrix = []
+
+ xvec=[]
+ yvec=[]
skipped_lines = 0
first_invalid_line = 0
invalid_value = ''
@@ -28,17 +34,19 @@
i = 0
for i, line in enumerate( file( in_fname ) ):
valid = True
+ vals = []
line = line.rstrip( '\r\n' )
if line and not line.startswith( '#' ):
row = []
fields = line.split( "\t" )
- for column in columns:
+ for c,column in enumerate(columns):
try:
val = fields[column]
if val.lower() == "na":
- row.append( float( "nan" ) )
+ v = float( "nan" )
else:
- row.append( float( fields[column] ) )
+ v = float( fields[column] )
+ vals.append(val)
except:
valid = False
skipped_lines += 1
@@ -57,12 +65,19 @@
first_invalid_line = i+1
if valid:
- matrix.append( row )
-
+ xvec.append(vals[0])
+ yvec.append(vals[1])
if skipped_lines < i:
try:
- r.pdf( out_fname, 8, 8 )
- r.plot( array( matrix ), type="p", main=title, xlab=xlab, ylab=ylab, col="blue", pch=19 )
+ if out_type == "jpg":
+ r.jpeg(out_fname,width=out_width,height=out_height)
+ elif out_type == "png":
+ # type="cairo" needed to be set for headless servers
+ r.png(out_fname,type="cairo",width=out_width,height=out_height)
+ else:
+ r.pdf(out_fname, out_width, out_height)
+
+ r.plot(xvec,yvec, type="p", main=title, xlab=xlab, ylab=ylab, col="blue", pch=19,cex=point_size )
r.dev_off()
except Exception, exc:
stop_err( "%s" %str( exc ) )
--- a/tools/plotting/scatterplot.xml Mon Jul 04 11:06:04 2011 -0400
+++ b/tools/plotting/scatterplot.xml Tue Jul 05 12:40:43 2011 +1000
@@ -1,6 +1,6 @@
<tool id="scatterplot_rpy" name="Scatterplot"><description>of two numeric columns</description>
- <command interpreter="python">scatterplot.py $input $out_file1 $col1 $col2 "$title" "$xlab" "$ylab"</command>
+ <command interpreter="python">scatterplot.py $input $out_file1 $col1 $col2 "$title" "$xlab" "$ylab" $output_format $out_width $out_height $point_size</command><inputs><param name="input" type="data" format="tabular" label="Dataset" help="Dataset missing? See TIP below"/><param name="col1" type="data_column" data_ref="input" numerical="True" label="Numerical column for x axis" />
@@ -8,15 +8,26 @@
<param name="title" size="30" type="text" value="Scatterplot" label="Plot title"/><param name="xlab" size="30" type="text" value="V1" label="Label for x axis"/><param name="ylab" size="30" type="text" value="V2" label="Label for y axis"/>
+ <param name="output_format" type="select" label="Output format">
+ <option value="pdf">pdf</option>
+ <option value="png">png</option>
+ <option value="jpg">jpg</option>
+ </param>
+ <param name="out_width" size="4" type="integer" value="8" label="Width (pdf=inches, image=pixels)"/>
+ <param name="out_height" size="4" type="integer" value="8" label="Height (pdf=inches, image=pixels)"/>
+ <param name="point_size" size="4" type="float" value="0.2" label="Point Size"/></inputs><outputs>
- <data format="pdf" name="out_file1" />
+ <data format="pdf" name="out_file1">
+ <change_format>
+ <when input="output_format" value="png" format="png" />
+ <when input="output_format" value="jpg" format="jpg" />
+ </change_format>
+ </data></outputs><requirements><requirement type="python-module">rpy</requirement></requirements>
- <!-- TODO: uncomment the following test when we have tools.update_state() working for
- multiple dependents with the same dependency.
<tests><test><param name="input" value="scatterplot_in1.tabular" ftype="tabular"/>
@@ -25,8 +36,38 @@
<param name="title" value="Scatterplot"/><param name="xlab" value="V1"/><param name="ylab" value="V2"/>
+ <param name="out_width" value="8"/>
+ <param name="out_height" value="8"/>
+ <param name="point_size" value="0.5"/>
+ <param name="output_format" value="pdf" /><output name="out_file1" file="scatterplot_out1.pdf" /></test>
+ <test>
+ <param name="input" value="scatterplot_in1.tabular" ftype="tabular"/>
+ <param name="col1" value="2"/>
+ <param name="col2" value="3"/>
+ <param name="title" value="Scatterplot"/>
+ <param name="xlab" value="V1"/>
+ <param name="ylab" value="V2"/>
+ <param name="out_width" value="800"/>
+ <param name="out_height" value="600"/>
+ <param name="point_size" value="0.5"/>
+ <param name="output_format" value="png" />
+ <output name="out_file1" file="scatterplot_out1.png" />
+ </test>
+ <test>
+ <param name="input" value="scatterplot_in1.tabular" ftype="tabular"/>
+ <param name="col1" value="2"/>
+ <param name="col2" value="3"/>
+ <param name="title" value="Scatterplot"/>
+ <param name="xlab" value="V1"/>
+ <param name="ylab" value="V2"/>
+ <param name="out_width" value="800"/>
+ <param name="out_height" value="600"/>
+ <param name="point_size" value="0.5"/>
+ <param name="output_format" value="jpg" />
+ <output name="out_file1" file="scatterplot_out1.jpg" />
+ </test></tests>
--><help>
--- a/tools/samtools/bam_to_sam.py Mon Jul 04 11:06:04 2011 -0400
+++ b/tools/samtools/bam_to_sam.py Tue Jul 05 12:40:43 2011 +1000
@@ -21,7 +21,6 @@
parser = optparse.OptionParser()
parser.add_option( '', '--input1', dest='input1', help='The input SAM dataset' )
parser.add_option( '', '--output1', dest='output1', help='The output BAM dataset' )
- parser.add_option( '', '--header', dest='header', action='store_true', default=False, help='Write SAM Header' )
( options, args ) = parser.parse_args()
# output version # of tool
@@ -88,11 +87,7 @@
try:
# Extract all alignments from the input BAM file to SAM format ( since no region is specified, all the alignments will be extracted ).
- if options.header:
- view_options = "-h"
- else:
- view_options = ""
- command = 'samtools view %s -o %s %s' % ( view_options, options.output1, tmp_sorted_aligns_file_name )
+ command = 'samtools view -o -h %s %s' % ( options.output1, tmp_sorted_aligns_file_name )
tmp = tempfile.NamedTemporaryFile( dir=tmp_dir ).name
tmp_stderr = open( tmp, 'wb' )
proc = subprocess.Popen( args=command, shell=True, cwd=tmp_dir, stderr=tmp_stderr.fileno() )
--- a/tools/samtools/sam_bitwise_flag_filter.py Mon Jul 04 11:06:04 2011 -0400
+++ b/tools/samtools/sam_bitwise_flag_filter.py Tue Jul 05 12:40:43 2011 +1000
@@ -1,6 +1,6 @@
#!/usr/bin/env python
# Refactored on 11/13/2010 by Kanwei Li
-
+# Added drop_header option - default is now keep headers for downstream sanity by ross lazarus
import sys
import optparse
@@ -14,7 +14,11 @@
options (listed below) default to 'None' if omitted
"""
parser = optparse.OptionParser(usage=usage)
-
+ parser.add_option('--drop_header',
+ action = 'store_true',
+ dest='drop_header',
+ help="Remove sam header - you probably NEVER want this for fussy downstream tools")
+
parser.add_option(
'--0x0001','--is_paired',
choices = ( '0','1' ),
@@ -129,21 +133,24 @@
opt_map = { '0': False, '1': True }
used_indices = [(index, opt_map[opt]) for index, opt in enumerate(opt_ary) if opt is not None]
flag_col = int( options.flag_col ) - 1
-
for line in infile:
line = line.rstrip( '\r\n' )
- if line and not line.startswith( '#' ) and not line.startswith( '@' ) :
- fields = line.split( '\t' )
- flags = int( fields[flag_col] )
+ if line:
+ if line.startswith('@'):
+ if not options.drop_header:
+ print line # usually want these so add -h if you don't want headers
+ elif not line.startswith( '#' ) :
+ fields = line.split( '\t' )
+ flags = int( fields[flag_col] )
- valid_line = True
- for index, opt_bool in used_indices:
- if bool(flags & 0x0001 << index) != opt_bool:
- valid_line = False
- break
+ valid_line = True
+ for index, opt_bool in used_indices:
+ if bool(flags & 0x0001 << index) != opt_bool:
+ valid_line = False
+ break
- if valid_line:
- print line
+ if valid_line:
+ print line
if __name__ == "__main__": main()
--- a/tools/samtools/sam_bitwise_flag_filter.xml Mon Jul 04 11:06:04 2011 -0400
+++ b/tools/samtools/sam_bitwise_flag_filter.xml Tue Jul 05 12:40:43 2011 +1000
@@ -1,8 +1,11 @@
-<tool id="sam_bw_filter" name="Filter SAM" version="1.0.0">
+<tool id="sam_bw_filter" name="Filter SAM" version="1.0.1"><description>on bitwise flag values</description><parallelism method="basic"></parallelism><command interpreter="python">
sam_bitwise_flag_filter.py
+ #if $drop_header == "1":
+ --drop_header
+ #end if
--input_sam_file=$input1
--flag_column=2
#for $bit in $bits
@@ -12,6 +15,11 @@
</command><inputs><param format="sam" name="input1" type="data" label="Select dataset to filter"/>
+ <param name="drop_header" type="select" display="radio" label="DROP sam headers"
+ help="Set this if you REALLY want to throw away existing sam header metadata - downstream (eg Picard) tools often demand it" >
+ <option value="0" selected="true">Keep headers (default)</option>
+ <option value="1">Drop headers</option>
+ </param><repeat name="bits" title="Flag"><param name="flags" type="select" label="Type"><option value="--0x0001">Read is paired</option>
--- a/tools/samtools/sam_to_bam.py Mon Jul 04 11:06:04 2011 -0400
+++ b/tools/samtools/sam_to_bam.py Tue Jul 05 12:40:43 2011 +1000
@@ -68,7 +68,7 @@
# and the equCab2.fa file will contain fasta sequences.
seq_path = check_seq_file( options.dbkey, cached_seqs_pointer_file )
tmp_dir = tempfile.mkdtemp()
- if not options.ref_file or options.ref_file == 'None':
+ if options.ref_file == 'None':
# We're using locally cached reference sequences( e.g., /galaxy/data/equCab2/sam_index/equCab2.fa ).
# The indexes for /galaxy/data/equCab2/sam_index/equCab2.fa will be contained in
# a file named /galaxy/data/equCab2/sam_index/equCab2.fa.fai
@@ -125,7 +125,9 @@
tmp_aligns_file = tempfile.NamedTemporaryFile( dir=tmp_dir )
tmp_aligns_file_name = tmp_aligns_file.name
tmp_aligns_file.close()
- command = 'samtools view -bt %s -o %s %s' % ( fai_index_file_path, tmp_aligns_file_name, options.input1 )
+ # IMPORTANT NOTE: for some reason the samtools view command gzips the resulting bam file without warning,
+ # and the docs do not currently state that this occurs ( very bad ).
+ command = 'samtools view -h -bt %s -o %s %s' % ( fai_index_file_path, tmp_aligns_file_name, options.input1 )
tmp = tempfile.NamedTemporaryFile( dir=tmp_dir ).name
tmp_stderr = open( tmp, 'wb' )
proc = subprocess.Popen( args=command, shell=True, cwd=tmp_dir, stderr=tmp_stderr.fileno() )
@@ -145,6 +147,8 @@
tmp_stderr.close()
if returncode != 0:
raise Exception, stderr
+ if len( open( tmp_aligns_file_name ).read() ) == 0:
+ raise Exception, 'Initial BAM file empty'
except Exception, e:
#clean up temp files
if os.path.exists( tmp_dir ):
@@ -184,6 +188,11 @@
stop_err( 'Error sorting alignments from (%s), %s' % ( tmp_aligns_file_name, str( e ) ) )
# Move tmp_aligns_file_name to our output dataset location
sorted_bam_file = '%s.bam' % tmp_sorted_aligns_file_name
+ if os.path.getsize( sorted_bam_file ) == 0:
+ #clean up temp files
+ if os.path.exists( tmp_dir ):
+ shutil.rmtree( tmp_dir )
+ stop_err( 'Error creating sorted version of BAM file' )
shutil.move( sorted_bam_file, options.output1 )
#clean up temp files
if os.path.exists( tmp_dir ):
@@ -192,6 +201,6 @@
if os.path.getsize( options.output1 ) > 0:
sys.stdout.write( 'SAM file converted to BAM' )
else:
- stop_err( 'Error creating sorted version of BAM file.' )
+ stop_err( 'The output file is empty, there may be an error with your input file or settings.' )
if __name__=="__main__": __main__()
http://bitbucket.org/galaxy/galaxy-central/changeset/100080d818fa/
changeset: 100080d818fa
user: galaxy galaxy
date: 2011-07-05 08:46:21
summary: Added new test and optional x axis unit alternatives (bits/probability/kcal etc) to weblogo as suggested by Assaf Gordon
affected #: 3 files (28.9 KB)
Binary file test-data/rgWebLogo3_test2.png has changed
--- a/tools/rgenetics/rgWebLogo3.py Tue Jul 05 12:40:43 2011 +1000
+++ b/tools/rgenetics/rgWebLogo3.py Tue Jul 05 16:46:21 2011 +1000
@@ -1,10 +1,13 @@
"""
+# modified june 2 ross lazarus to add units option at Assaf Gordon's suggestion
# rgWebLogo3.py
# wrapper to check that all fasta files are same length
"""
import optparse, os, sys, subprocess, tempfile
+WEBLOGO = 'weblogo' # executable name for weblogo3 - confusing isn't it?
+
class WL3:
"""
simple wrapper class to check fasta sequence lengths are all identical
@@ -18,10 +21,21 @@
self.fastaf = file(self.opts.input,'r')
self.clparams = {}
+ def whereis(self,program):
+ for path in os.environ.get('PATH', '').split(':'):
+ if os.path.exists(os.path.join(path, program)) and not os.path.isdir(os.path.join(path, program)):
+ return os.path.join(path, program)
+ return None
+
def runCL(self):
""" construct and run a command line
"""
- cll = ['weblogo',]
+ wl = self.whereis(WEBLOGO)
+ if not wl:
+ print >> sys.stderr, '## rgWebLogo3.py error - cannot locate the weblogo binary %s on the current path' % WEBLOGO
+ print >> sys.stderr, '## Please ensure it is installed and working from http://code.google.com/p/weblogo'
+ sys.exit(1)
+ cll = [WEBLOGO,]
cll += [' '.join(it) for it in list(self.clparams.items())]
cl = ' '.join(cll)
assert cl > '', 'runCL needs a command line as clparms'
@@ -59,8 +73,13 @@
sys.exit(1)
else:
seqname = row[1:].strip()
- else:
- aseq.append(row.strip())
+ else: # sequence row
+ if seqname == None:
+ print >> sys.stderr,'Invalid fasta file %s - does not start with %s - please read the tool documentation carefully' % (self.opts.input,self.FASTASTARTSYM)
+ sys.exit(1)
+ else:
+ aseq.append(row.strip())
+
if seqname <> None: # last one
l = len(''.join(aseq))
yield (seqname,l)
@@ -74,7 +93,7 @@
lasti = None
f = self.iter_fasta()
for i,(seqname,seqlen) in enumerate(f):
- lasti = i
+ lasti = i
if i == 0:
flen = seqlen
else:
@@ -98,6 +117,8 @@
self.clparams['-u'] = self.opts.upper
if self.opts.colours <> None:
self.clparams['-c'] = self.opts.colours
+ if self.opts.units <> None:
+ self.clparams['-U'] = self.opts.units
s = self.runCL()
return check,s
@@ -122,6 +143,7 @@
op.add_option('-c', '--colours', default=None)
op.add_option('-l', '--lower', default=None)
op.add_option('-u', '--upper', default=None)
+ op.add_option('-U', '--units', default=None)
opts, args = op.parse_args()
assert opts.input <> None,'weblogo3 needs a -i parameter with a fasta input file - cannot open'
assert os.path.isfile(opts.input),'weblogo3 needs a valid fasta input file - cannot open %s' % opts.input
--- a/tools/rgenetics/rgWebLogo3.xml Tue Jul 05 12:40:43 2011 +1000
+++ b/tools/rgenetics/rgWebLogo3.xml Tue Jul 05 16:46:21 2011 +1000
@@ -1,7 +1,7 @@
-<tool id="rgweblogo3" name="Sequence Logo" version="0.2">
+<tool id="rgweblogo3" name="Sequence Logo" version="0.3"><description>generator for fasta (eg Clustal alignments)</description><command interpreter="python">
- rgWebLogo3.py -F $outformat -s $size -i $input -o $output -t "$logoname" -c "$colours"
+ rgWebLogo3.py -F $outformat -s $size -i $input -o $output -t "$logoname" -c "$colours" -U "$units"
#if $range.mode == 'part'
-l "$range.seqstart" -u "$range.seqend"
#end if
@@ -18,6 +18,15 @@
<option value="eps">EPS</option><option value="txt">Text (shows the detailed calculations for each position - no image)</option></param>
+ <param name="units" type="select" label="Display Units"
+ help="What the height of each logo element depicts - eg bits of entropy (default)">
+ <option value="bits" selected="True">Entropy (bits)</option>
+ <option value="probability">Probability</option>
+ <option value="nats">Nats</option>
+ <option value="kT">kT</option>
+ <option value="kJ/mol">kJ/mol</option>
+ <option value="kcal/mol">kcal/mol</option>
+ </param><param name="colours" type="select" label="Colour scheme for output Sequence Logo"
help="Note that some of these only make sense for protein sequences!"><option value="auto" selected="True">Default automatic colour selection</option>
@@ -28,6 +37,7 @@
<option value="hydrophobicity">Hydrophobicity</option><option value="monochrome">monochrome</option></param>
+
<conditional name="range"><param name="mode" type="select" label="Include entire sequence (default) or specify a subsequence range to use">
@@ -63,17 +73,26 @@
</data></outputs><tests>
- <test>
-
+ <test><param name="input" value="rgClustal_testout.fasta" /><param name = "logoname" value="Galaxy/Rgenetics weblogo" /><param name = "outformat" value="jpeg" /><param name = "mode" value="complete" /><param name = "size" value="medium" /><param name = "colours" value="auto" />
+ <param name = "units" value="bits" /><output name="output" file="rgWebLogo3_test.jpg" ftype="jpg" compare="sim_size" delta="10000" /></test>
-
+ <test>
+ <param name="input" value="rgClustal_testout.fasta" />
+ <param name = "logoname" value="Galaxy/Rgenetics weblogo" />
+ <param name = "outformat" value="png" />
+ <param name = "mode" value="complete" />
+ <param name = "size" value="medium" />
+ <param name = "colours" value="auto" />
+ <param name = "units" value="probability" />
+ <output name="output" file="rgWebLogo3_test2.png" ftype="png" compare="sim_size" delta="10000" />
+ </test></tests><help>
@@ -92,7 +111,8 @@
**Warning about input Fasta format files**
-The Weblogo3 program used by this tool will fail if your fasta sequences are not all EXACTLY the same length.
+The Weblogo3 program used by this tool will fail if your fasta sequences are not all EXACTLY the same length. The tool will provide a warning
+and refuse to call the weblogo3 executable if irregular length sequences are detected.
Fasta alignments from the companion ClustalW Galaxy tool will work but many other fasta files may cause this tool to fail - please do not file
a Galaxy bug report - this is a feature of the tool and a problem with your source data - not a tool error - please make certain all your fasta
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

04 Jul '11
1 new changeset in galaxy-central:
http://bitbucket.org/galaxy/galaxy-central/changeset/ffa23ea969e6/
changeset: ffa23ea969e6
user: jgoecks
date: 2011-07-04 17:06:04
summary: Trackster refactoring: (a) change data_cache attributes to data_manager to reflect attribute type; (b) automatically use track mode and track view's chrom when getting data from the manager; and (c) calculate and store low, high for Tiles to facilitate reuse.
affected #: 1 file (64 bytes)
--- a/static/scripts/trackster.js Sun Jul 03 15:05:25 2011 -0400
+++ b/static/scripts/trackster.js Mon Jul 04 11:06:04 2011 -0400
@@ -263,9 +263,12 @@
/**
* Load data from server; returns AJAX object so that use of Deferred is possible.
*/
- load_data: function(chrom, low, high, mode, resolution, extra_params) {
+ load_data: function(low, high, resolution, extra_params) {
// Setup data request params.
- var params = {"chrom": chrom, "low": low, "high": high, "mode": mode,
+ var
+ chrom = this.track.view.chrom,
+ mode = this.track.mode,
+ params = {"chrom": chrom, "low": low, "high": high, "mode": mode,
"resolution": resolution, "dataset_id" : this.track.dataset_id,
"hda_ldda": this.track.hda_ldda};
$.extend(params, extra_params);
@@ -289,7 +292,7 @@
/**
* Get track data.
*/
- get_data: function(chrom, low, high, mode, resolution, extra_params) {
+ get_data: function(low, high, resolution, extra_params) {
// Debugging:
//console.log("get_data", low, high, mode);
/*
@@ -300,7 +303,9 @@
*/
// Look for entry and return if found.
- var entry = this.get(this.gen_key(low, high, mode));
+ var
+ mode = this.track.mode,
+ entry = this.get(this.gen_key(low, high, mode));
if (entry) {
return entry;
}
@@ -315,6 +320,7 @@
//
/* Disabling for now, more detailed data is never loaded for line tracks
+ TODO: can using resolution in the key solve this problem?
if (this.subset) {
var key, split_key, entry_low, entry_high, mode, entry;
for (var i = 0; i < this.key_ary.length; i++) {
@@ -338,7 +344,7 @@
// Load data from server. The deferred is immediately saved until the
// data is ready, it then replaces itself with the actual data
- entry = this.load_data(chrom, low, high, mode, resolution, extra_params);
+ entry = this.load_data(low, high, resolution, extra_params);
this.set_data(low, high, mode, entry);
return entry
},
@@ -349,6 +355,8 @@
/**
* Generate key for cache.
*/
+ // TODO: use chrom in key so that (a) data is not thrown away when changing chroms and (b)
+ // manager does not need to be cleared when changing chroms.
gen_key: function(low, high, mode) {
var key = low + "_" + high + "_" + mode;
return key;
@@ -1504,6 +1512,8 @@
*/
var Tile = function(index, resolution, canvas) {
this.index = index;
+ this.low = index * DENSITY * resolution;
+ this.high = (index + 1) * DENSITY * resolution;
this.resolution = resolution;
// Wrap element in div for background.
this.canvas = $("<div class='track-tile'/>").append(canvas);
@@ -1598,7 +1608,7 @@
var track = this;
track.enabled = false;
track.tile_cache.clear();
- track.data_cache.clear();
+ track.data_manager.clear();
track.initial_canvas = undefined;
track.content_div.css("height", "auto");
/*
@@ -1935,7 +1945,7 @@
var tile_high = tile_low + DENSITY * this.view.resolution;
if (!force && cached) {
drawn_tiles[drawn_tiles.length] = cached;
- this.show_tile(cached, parent_element, tile_low, tile_high, w_scale);
+ this.show_tile(cached, parent_element, w_scale);
} else {
this.delayed_draw(force, key, tile_index, resolution, parent_element, w_scale, drawn_tiles);
}
@@ -2087,7 +2097,7 @@
if (tile === undefined) {
return;
}
- track.show_tile(tile, parent_element, tile_low, tile_high, w_scale);
+ track.show_tile(tile, parent_element, w_scale);
drawn_tiles[drawn_tiles.length] = tile;
};
// Put a 50ms delay on drawing so that if the user scrolls fast, we don't load extra data
@@ -2096,21 +2106,19 @@
// Show/draw tile: check cache for tile; if tile not in cache, draw it.
var tile = (force ? undefined : track.tile_cache.get(key));
if (tile) {
- track.show_tile(tile, parent_element, tile_low, tile_high, w_scale);
+ track.show_tile(tile, parent_element, w_scale);
drawn_tiles[drawn_tiles.length] = tile;
}
else {
//
// Really draw tile: get data, seq data if available, and draw tile.
//
- $.when(track.data_cache.get_data(view.chrom, tile_low, tile_high, track.mode,
- resolution, track.data_url_extra_params)).then(function(tile_data) {
+ $.when(track.data_manager.get_data(tile_low, tile_high, resolution, track.data_url_extra_params)).then(function(tile_data) {
extend(tile_data, more_tile_data);
// If sequence data needed, get that and draw. Otherwise draw.
if (view.reference_track && w_scale > view.canvas_manager.char_width_px) {
- $.when(view.reference_track.data_cache.get_data(view.chrom, tile_low, tile_high,
- track.mode, resolution,
- view.reference_track.data_url_extra_params)).then(function(seq_data) {
+ $.when(view.reference_track.data_manager.get_data(tile_low, tile_high, resolution,
+ view.reference_track.data_url_extra_params)).then(function(seq_data) {
draw_and_show_tile(id, tile_data, resolution, tile_index, parent_element, w_scale, seq_data);
});
}
@@ -2125,7 +2133,7 @@
/**
* Show track tile and perform associated actions.
*/
- show_tile: function(tile, parent_element, tile_low, tile_high, w_scale) {
+ show_tile: function(tile, parent_element, w_scale) {
// Readability.
var
track = this,
@@ -2150,10 +2158,10 @@
show_more_data_btn.click(function() {
// Mark data, tile as stale, request more data, and redraw track.
// HACK: get_data used will return object that can be marked as stale, but a better way to this is needed.
- var cur_data = track.data_cache.get_data(track.view.chrom, tile_low, tile_high, track.mode, tile.resolution);
+ var cur_data = track.data_manager.get_data(tile.low, tile.high, tile.resolution);
cur_data.stale = true;
tile.stale = true;
- track.data_cache.get_data(track.view.chrom, tile_low, tile_high, track.mode, tile.resolution, {max_vals: cur_data.data.length * 2});
+ track.data_manager.get_data(tile.low, tile.high, tile.resolution, {max_vals: cur_data.data.length * 2});
track.draw();
}).dblclick(function(e) {
// Do not propogate as this would normal zoom in.
@@ -2167,7 +2175,7 @@
// Position tile element, recalculate left position at display time
var range = this.view.high - this.view.low,
- left = (tile_low - this.view.low) * w_scale;
+ left = (tile.low - this.view.low) * w_scale;
if (this.left_offset) {
left -= this.left_offset;
}
@@ -2259,13 +2267,13 @@
view.reference_track = this;
this.left_offset = 200;
this.height_px = 12;
- this.container_div.addClass( "reference-track" );
+ 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: view.dbkey};
- this.data_cache = new ReferenceTrackDataManager(CACHED_DATA, this, false);
+ this.data_manager = new ReferenceTrackDataManager(CACHED_DATA, this, false);
this.tile_cache = new Cache(CACHED_TILES_LINE);
};
extend(ReferenceTrack.prototype, TiledTrack.prototype, {
@@ -2283,7 +2291,7 @@
}
var canvas = this.view.canvas_manager.new_canvas();
var ctx = canvas.getContext("2d");
- canvas.width = Math.ceil( tile_length * w_scale + track.left_offset);
+ canvas.width = Math.ceil(tile_length * w_scale + track.left_offset);
canvas.height = track.height_px;
ctx.font = ctx.canvas.manager.default_font;
ctx.textAlign = "center";
@@ -2310,7 +2318,7 @@
this.hda_ldda = hda_ldda;
this.dataset_id = dataset_id;
this.original_dataset_id = dataset_id;
- this.data_cache = new DataManager(CACHED_DATA, this);
+ this.data_manager = new DataManager(CACHED_DATA, this);
this.tile_cache = new Cache(CACHED_TILES_LINE);
// Define track configuration
@@ -2426,11 +2434,10 @@
// Paint line onto full canvas
var ctx = canvas.getContext("2d");
- var painter = new painters.LinePainter( result.data, tile_low, tile_low + tile_length,
- this.prefs, this.mode );
+ var painter = new painters.LinePainter(result.data, tile_low, tile_low + tile_length, this.prefs, this.mode);
painter.draw(ctx, width, height);
- return new Tile(tile_length, resolution, canvas);
+ return new Tile(tile_index, resolution, canvas);
}
});
@@ -2475,7 +2482,7 @@
this.inc_slots = {};
this.start_end_dct = {};
this.tile_cache = new Cache(CACHED_TILES_FEATURE);
- this.data_cache = new DataManager(20, this);
+ this.data_manager = new DataManager(20, this);
this.left_offset = 200;
this.painter = painters.LinkedFeaturePainter;
@@ -2600,9 +2607,9 @@
draw_tile: function(result, resolution, tile_index, w_scale, ref_seq) {
var track = this,
tile_low = tile_index * DENSITY * resolution,
- tile_high = ( tile_index + 1 ) * DENSITY * resolution,
+ tile_high = (tile_index + 1) * DENSITY * resolution,
tile_span = tile_high - tile_low,
- width = Math.ceil( tile_span * w_scale ),
+ width = Math.ceil(tile_span * w_scale),
mode = this.mode,
min_height = 25,
left_offset = this.left_offset,
@@ -2703,7 +2710,7 @@
// Create painter, and canvas of sufficient size to contain all features
// HACK: ref_seq will only be defined for ReadTracks, and only the ReadPainter accepts that argument
- var painter = new (this.painter)( filtered, tile_low, tile_high, this.prefs, mode, ref_seq );
+ var painter = new (this.painter)(filtered, tile_low, tile_high, this.prefs, mode, ref_seq);
var required_height = painter.get_required_height(slots_required);
var canvas = this.view.canvas_manager.new_canvas();
@@ -2786,7 +2793,7 @@
// Postdraw init: once data has been fetched, reset data url, wait time and start indexing.
var track = this;
var post_init = function() {
- if (track.data_cache.size() === 0) {
+ if (track.data_manager.size() === 0) {
// Track still drawing initial data, so do nothing.
setTimeout(post_init, 300);
}
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 changeset in galaxy-central:
http://bitbucket.org/galaxy/galaxy-central/changeset/ee846dba409f/
changeset: ee846dba409f
user: jgoecks
date: 2011-07-03 21:05:25
summary: Trackster: provide option to fetch additional data when not all data initially fetched for a tile. For now, all data is refetched rather than iterative fetching. As part of this functionality: (a) enable data providers to accept a max_vals parameter that is used to fetch a particular number of values; and (b) Trackster caches now ignore items with stale=true.
affected #: 4 files (2.3 KB)
--- a/lib/galaxy/visualization/tracks/data_providers.py Thu Jun 30 16:13:52 2011 -0400
+++ b/lib/galaxy/visualization/tracks/data_providers.py Sun Jul 03 15:05:25 2011 -0400
@@ -24,8 +24,7 @@
from pysam import csamtools, ctabix
-MAX_VALS = 5000 # only display first MAX_VALS features
-ERROR_MAX_VALS = "Only the first " + str(MAX_VALS) + " %s in the region denoted by the red line are displayed."
+ERROR_MAX_VALS = "Only the first %i %s in this region are displayed."
# Return None instead of NaN to pass jQuery 1.4's strict JSON
def float_nan(n):
@@ -73,8 +72,11 @@
# Override.
pass
- def get_data( self, chrom, start, end, **kwargs ):
- """ Returns data in region defined by chrom, start, and end. """
+ def get_data( self, chrom, start, end, max_vals=None, **kwargs ):
+ """
+ Returns data in region defined by chrom, start, and end. If max_vals
+ is set, returns at most max_vals.
+ """
# Override.
pass
@@ -213,14 +215,26 @@
# Cleanup.
bamfile.close()
- def get_data( self, chrom, start, end, **kwargs ):
+ def get_data( self, chrom, start, end, max_vals=sys.maxint, **kwargs ):
"""
- Fetch intervals in the region
+ Fetch reads in the region.
+
+ Each read is a list with the format
+ [<guid>, <start>, <end>, <name>, <read_1>, <read_2>]
+ where <read_1> has the format
+ [<start>, <end>, <cigar>, ?<read_seq>?]
+ and <read_2> has the format
+ [<start>, <end>, <cigar>, ?<read_seq>?]
+ For single-end reads, read has format:
+ [<guid>, <start>, <end>, <name>, cigar, seq]
+ NOTE: read end and sequence data are not valid for reads outside of
+ requested region and should not be used.
"""
start, end = int(start), int(end)
orig_data_filename = self.original_dataset.file_name
index_filename = self.converted_dataset.file_name
no_detail = "no_detail" in kwargs
+
# Attempt to open the BAM file with index
bamfile = csamtools.Samfile( filename=orig_data_filename, mode='rb', index_filename=index_filename )
message = None
@@ -235,21 +249,13 @@
return None
else:
return None
- # Encode reads as list of lists; each read is a list with the format
- # [<guid>, <start>, <end>, <name>, <read_1>, <read_2>]
- # where <read_1> has the format
- # [<start>, <end>, <cigar>, ?<read_seq>?]
- # and <read_2> has the format
- # [<start>, <end>, <cigar>, ?<read_seq>?]
- # For single-end reads, read has format:
- # [<guid>, <start>, <end>, <name>, cigar, seq]
- # NOTE: read end and sequence data are not valid for reads outside of
- # requested region and should not be used.
+
+ # Encode reads as list of lists.
results = []
paired_pending = {}
for read in data:
- if len(results) > MAX_VALS:
- message = ERROR_MAX_VALS % "reads"
+ if len(results) > max_vals:
+ message = ERROR_MAX_VALS % ( max_vals, "reads" )
break
qname = read.qname
seq = read.seq
@@ -273,7 +279,9 @@
paired_pending[qname] = { 'start': read.pos, 'end': read.pos + read_len, 'seq': seq, 'mate_start': read.mpos, 'rlen': read_len, 'cigar': read.cigar }
else:
results.append( [ "%i_%s" % ( read.pos, qname ), read.pos, read.pos + read_len, qname, read.cigar, read.seq] )
+
# Take care of reads whose mates are out of range.
+ # TODO: count paired reads when adhering to max_vals?
for qname, read in paired_pending.iteritems():
if read['mate_start'] < read['start']:
# Mate is before read.
@@ -311,7 +319,7 @@
f.close()
return all_dat is not None
- def get_data( self, chrom, start, end, **kwargs ):
+ def get_data( self, chrom, start, end, max_vals=None, **kwargs ):
# Bigwig has the possibility of it being a standalone bigwig file, in which case we use
# original_dataset, or coming from wig->bigwig conversion in which we use converted_dataset
f, bbi = self._get_dataset()
@@ -473,9 +481,9 @@
return tabix.fetch(reference=chrom, start=start, end=end)
- def get_data( self, chrom, start, end, **kwargs ):
+ def get_data( self, chrom, start, end, max_vals=None, **kwargs ):
iterator = self.get_iterator( chrom, start, end )
- return self.process_data(iterator, **kwargs)
+ return self.process_data( iterator, max_vals, **kwargs )
class IntervalIndexDataProvider( FilterableMixin, TracksDataProvider ):
col_name_data_attr_mapping = { 4 : { 'index': 4 , 'name' : 'Score' } }
@@ -493,7 +501,7 @@
out.write(interval.raw_line + '\n')
out.close()
- def get_data( self, chrom, start, end, **kwargs ):
+ def get_data( self, chrom, start, end, max_vals=sys.maxint, **kwargs ):
start, end = int(start), int(end)
source = open( self.original_dataset.file_name )
index = Indexes( self.converted_dataset.file_name )
@@ -518,8 +526,8 @@
filter_cols = from_json_string( kwargs.get( "filter_cols", "[]" ) )
no_detail = ( "no_detail" in kwargs )
for start, end, offset in index.find(chrom, start, end):
- if count >= MAX_VALS:
- message = ERROR_MAX_VALS % "features"
+ if count >= max_vals:
+ message = ERROR_MAX_VALS % ( max_vals, "features" )
break
count += 1
source.seek( offset )
@@ -541,7 +549,7 @@
Payload format: [ uid (offset), start, end, name, strand, thick_start, thick_end, blocks ]
"""
- def process_data( self, iterator, **kwargs ):
+ def process_data( self, iterator, max_vals=sys.maxint, **kwargs ):
#
# Build data to return. Payload format is:
# [ <guid/offset>, <start>, <end>, <name>, <score>, <strand>, <thick_start>,
@@ -555,8 +563,8 @@
rval = []
message = None
for line in iterator:
- if count >= MAX_VALS:
- message = ERROR_MAX_VALS % "features"
+ if count >= max_vals:
+ message = ERROR_MAX_VALS % ( max_vals, "features" )
break
count += 1
# TODO: can we use column metadata to fill out payload?
@@ -617,14 +625,14 @@
col_name_data_attr_mapping = { 'Qual' : { 'index': 6 , 'name' : 'Qual' } }
- def process_data( self, iterator, **kwargs ):
+ def process_data( self, iterator, max_vals=sys.maxint, **kwargs ):
rval = []
count = 0
message = None
for line in iterator:
- if count >= MAX_VALS:
- message = ERROR_MAX_VALS % "features"
+ if count >= max_vals:
+ message = ERROR_MAX_VALS % ( "max_vals", "features" )
break
count += 1
@@ -649,7 +657,7 @@
NOTE: this data provider does not use indices, and hence will be very slow
for large datasets.
"""
- def get_data( self, chrom, start, end, **kwargs ):
+ def get_data( self, chrom, start, end, max_vals=sys.maxint, **kwargs ):
start, end = int( start ), int( end )
source = open( self.original_dataset.file_name )
results = []
@@ -661,8 +669,8 @@
feature_start, feature_end = convert_gff_coords_to_bed( [ feature.start, feature.end ] )
if feature.chrom != chrom or feature_start < start or feature_end > end:
continue
- if count >= MAX_VALS:
- message = ERROR_MAX_VALS % "features"
+ if count >= max_vals:
+ message = ERROR_MAX_VALS % ( max_vals, "features" )
break
count += 1
payload = package_gff_feature( feature )
--- a/lib/galaxy/web/controllers/tracks.py Thu Jun 30 16:13:52 2011 -0400
+++ b/lib/galaxy/web/controllers/tracks.py Sun Jul 03 15:05:25 2011 -0400
@@ -168,13 +168,7 @@
histories_grid = HistorySelectionGrid()
history_datasets_grid = HistoryDatasetsSelectionGrid()
tracks_grid = TracksterSelectionGrid()
-
- #
- # TODO: need to encode dataset id and use
- # UsesHistoryDatasetAssociation.get_dataset
- # for better dataset security.
- #
-
+
available_tracks = None
available_genomes = None
@@ -475,9 +469,9 @@
return { "status": messages.DATA, "valid_chroms": valid_chroms }
@web.json
- def data( self, trans, hda_ldda, dataset_id, chrom, low, high, **kwargs ):
+ def data( self, trans, hda_ldda, dataset_id, chrom, low, high, max_vals=5000, **kwargs ):
"""
- Called by the browser to request a block of data
+ Provides a block of data from a dataset.
"""
# Parameter check.
@@ -532,7 +526,7 @@
data_provider = data_provider_class( converted_dataset=converted_dataset, original_dataset=dataset, dependencies=deps )
# Get and return data from data_provider.
- data = data_provider.get_data( chrom, low, high, **kwargs )
+ data = data_provider.get_data( chrom, low, high, max_vals, **kwargs )
message = None
if isinstance(data, dict) and 'message' in data:
message = data['message']
--- a/static/scripts/packed/trackster.js Thu Jun 30 16:13:52 2011 -0400
+++ b/static/scripts/packed/trackster.js Sun Jul 03 15:05:25 2011 -0400
@@ -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 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 trackster_module=function(f,T){var n=f("class").extend,p=f("slotting"),I=f("painters");var Z=function(aa,ab){this.document=aa;this.default_font=ab!==undefined?ab:"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")};n(Z.prototype,{load_pattern:function(aa,ae){var ab=this.patterns,ac=this.dummy_context,ad=new Image();ad.src=image_path+ae;ad.onload=function(){ab[aa]=ac.createPattern(ad,"repeat")}},get_pattern:function(aa){return this.patterns[aa]},new_canvas:function(){var aa=this.document.createElement("canvas");if(window.G_vmlCanvasManager){G_vmlCanvasManager.initElement(aa)}aa.manager=this;return aa}});var C=function(aa,ab){aa.bind("drag",{handle:ab,relative:true},function(af,ag){var ae=$(this).parent();var ad=ae.children();var ac;for(ac=0;ac<ad.length;ac++){if(ag.offsetY<$(ad.get(ac)).position().top){break}}if(ac===ad.length){if(this!==ad.get(ac-1)){ae.append(this)}}else{if(this!==ad.get(ac)){$(this).insertBefore(ad.get(ac))}}}).bind("dragstart",function(){$(this).css({"border-top":"1px solid blue","border-bottom":"1px solid blue"})}).bind("dragend",function(){$(this).css("border","0px")})};T.sortable=C;var D=9,A=15,O=D+2,w=100,F=12000,M=200,z=5,s=10,H=5000,t=100,m="There was an error in indexing this dataset. ",G="A converter for this dataset is not installed. Please check your datatypes_conf.xml file.",B="No data for this chrom/contig.",q="Currently indexing... please wait",v="Tool cannot be rerun: ",a="Loading data...",U="Ready for display",d=10,r=5,y=5;function u(aa){return Math.round(aa*1000)/1000}var c=function(aa){this.num_elements=aa;this.clear()};n(c.prototype,{get:function(ab){var aa=this.key_ary.indexOf(ab);if(aa!==-1){this.move_key_to_end(ab,aa)}return this.obj_cache[ab]},set:function(ab,ac){if(!this.obj_cache[ab]){if(this.key_ary.length>=this.num_elements){var aa=this.key_ary.shift();delete this.obj_cache[aa]}this.key_ary.push(ab)}this.obj_cache[ab]=ac;return ac},move_key_to_end:function(ab,aa){this.key_ary.splice(aa,1);this.key_ary.push(ab)},clear:function(){this.obj_cache={};this.key_ary=[]},size:function(){return this.key_ary.length}});var N=function(ab,aa,ac){c.call(this,ab);this.track=aa;this.subset=(ac!==undefined?ac:true)};n(N.prototype,c.prototype,{load_data:function(ai,aj,ae,ah,ab,ag){var ad={chrom:ai,low:aj,high:ae,mode:ah,resolution:ab,dataset_id:this.track.dataset_id,hda_ldda:this.track.hda_ldda};$.extend(ad,ag);if(this.track.filters_manager){var ak=[];var aa=this.track.filters_manager.filters;for(var af=0;af<aa.length;af++){ak[ak.length]=aa[af].name}ad.filter_cols=JSON.stringify(ak)}var ac=this;return $.getJSON(this.track.data_url,ad,function(al){ac.set_data(aj,ae,ah,al)})},get_data:function(ac,aa,af,ag,ab,ae){var ad=this.get(this.gen_key(aa,af,ag));if(ad){return ad}ad=this.load_data(ac,aa,af,ag,ab,ae);this.set_data(aa,af,ag,ad);return ad},set_data:function(ab,ac,ad,aa){return this.set(this.gen_key(ab,ac,ad),aa)},gen_key:function(aa,ac,ad){var ab=aa+"_"+ac+"_"+ad;return ab},split_key:function(aa){return aa.split("_")}});var E=function(ab,aa,ac){N.call(this,ab,aa,ac)};n(E.prototype,N.prototype,c.prototype,{load_data:function(ac,aa,ae,af,ab,ad){if(ab>1){return}return N.prototype.load_data.call(this,ac,aa,ae,af,ab,ad)}});var Y=function(aa,ad,ac,ab,ae){this.container=aa;this.chrom=null;this.vis_id=ac;this.dbkey=ab;this.title=ad;this.tracks=[];this.label_tracks=[];this.max_low=0;this.max_high=0;this.num_tracks=0;this.track_id_counter=0;this.zoom_factor=3;this.min_separation=30;this.has_changes=false;this.init(ae);this.canvas_manager=new Z(aa.get(0).ownerDocument);this.reset()};n(Y.prototype,{init:function(ad){var ac=this.container,aa=this;this.top_container=$("<div/>").addClass("top-container").appendTo(ac);this.content_div=$("<div/>").addClass("content").css("position","relative").appendTo(ac);this.bottom_container=$("<div/>").addClass("bottom-container").appendTo(ac);this.top_labeltrack=$("<div/>").addClass("top-labeltrack").appendTo(this.top_container);this.viewport_container=$("<div/>").addClass("viewport-container").addClass("viewport-container").appendTo(this.content_div);this.intro_div=$("<div/>").addClass("intro").text("Select a chrom from the dropdown below").hide();this.nav_labeltrack=$("<div/>").addClass("nav-labeltrack").appendTo(this.bottom_container);this.nav_container=$("<div/>").addClass("nav-container").prependTo(this.top_container);this.nav=$("<div/>").addClass("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 href='javascript:void(0);'>Close Overview</a>").addClass("overview-close").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 ab=function(ae){if(ae.type==="focusout"||(ae.keyCode||ae.which)===13||(ae.keyCode||ae.which)===27){if((ae.keyCode||ae.which)!==27){aa.go_to($(this).val())}$(this).hide();$(this).val("");aa.location_span.show();aa.chrom_select.show()}};this.nav_input=$("<input/>").addClass("nav-input").hide().bind("keyup focusout",ab).appendTo(this.nav_controls);this.location_span=$("<span/>").addClass("location").appendTo(this.nav_controls);this.location_span.bind("click",function(){aa.location_span.hide();aa.chrom_select.hide();aa.nav_input.val(aa.chrom+":"+aa.low+"-"+aa.high);aa.nav_input.css("display","inline-block");aa.nav_input.select();aa.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 id='zoom-out' />").click(function(){aa.zoom_out();aa.redraw()}).appendTo(this.nav_controls);this.zi_link=$("<a id='zoom-in' />").click(function(){aa.zoom_in();aa.redraw()}).appendTo(this.nav_controls);this.load_chroms({low:0},ad);this.chrom_select.bind("change",function(){aa.change_chrom(aa.chrom_select.val())});this.intro_div.show();this.content_div.bind("click",function(ae){$(this).find("input").trigger("blur")});this.content_div.bind("dblclick",function(ae){aa.zoom_in(ae.pageX,this.viewport_container)});this.overview_box.bind("dragstart",function(ae,af){this.current_x=af.offsetX}).bind("drag",function(ae,ag){var ah=ag.offsetX-this.current_x;this.current_x=ag.offsetX;var af=Math.round(ah/aa.viewport_container.width()*(aa.max_high-aa.max_low));aa.move_delta(-af)});this.overview_close.bind("click",function(){for(var af=0,ae=aa.tracks.length;af<ae;af++){aa.tracks[af].is_overview=false}$(this).siblings().filter("canvas").remove();$(this).parent().css("height",aa.overview_box.height());aa.overview_highlight.hide();$(this).hide()});this.viewport_container.bind("draginit",function(ae,af){if(ae.clientX>aa.viewport_container.width()-16){return false}}).bind("dragstart",function(ae,af){af.original_low=aa.low;af.current_height=ae.clientY;af.current_x=af.offsetX}).bind("drag",function(ag,ai){var ae=$(this);var aj=ai.offsetX-ai.current_x;var af=ae.scrollTop()-(ag.clientY-ai.current_height);ae.scrollTop(af);ai.current_height=ag.clientY;ai.current_x=ai.offsetX;var ah=Math.round(aj/aa.viewport_container.width()*(aa.high-aa.low));aa.move_delta(ah)}).bind("mousewheel",function(ag,ai,af,ae){if(af){var ah=Math.round(-af/aa.viewport_container.width()*(aa.high-aa.low));aa.move_delta(ah)}});this.top_labeltrack.bind("dragstart",function(ae,af){return $("<div />").css({height:aa.content_div.height()+aa.top_labeltrack.height()+aa.nav_labeltrack.height()+1,top:"0px",position:"absolute","background-color":"#ccf",opacity:0.5,"z-index":1000}).appendTo($(this))}).bind("drag",function(ai,aj){$(aj.proxy).css({left:Math.min(ai.pageX,aj.startX),width:Math.abs(ai.pageX-aj.startX)});var af=Math.min(ai.pageX,aj.startX)-aa.container.offset().left,ae=Math.max(ai.pageX,aj.startX)-aa.container.offset().left,ah=(aa.high-aa.low),ag=aa.viewport_container.width();aa.update_location(Math.round(af/ag*ah)+aa.low,Math.round(ae/ag*ah)+aa.low)}).bind("dragend",function(aj,ak){var af=Math.min(aj.pageX,ak.startX),ae=Math.max(aj.pageX,ak.startX),ah=(aa.high-aa.low),ag=aa.viewport_container.width(),ai=aa.low;aa.low=Math.round(af/ag*ah)+ai;aa.high=Math.round(ae/ag*ah)+ai;$(ak.proxy).remove();aa.redraw()});this.add_label_track(new X(this,this.top_labeltrack));this.add_label_track(new X(this,this.nav_labeltrack));$(window).bind("resize",function(){aa.resize_window()});$(document).bind("redraw",function(){aa.redraw()});this.reset();$(window).trigger("resize")},update_location:function(aa,ab){this.location_span.text(commatize(aa)+" - "+commatize(ab));this.nav_input.val(this.chrom+":"+commatize(aa)+"-"+commatize(ab))},load_chroms:function(ab,ac){ab.num=t;$.extend(ab,(this.vis_id!==undefined?{vis_id:this.vis_id}:{dbkey:this.dbkey}));var aa=this;$.ajax({url:chrom_url,data:ab,dataType:"json",success:function(ae){if(ae.chrom_info.length===0){alert("Invalid chromosome: "+ab.chrom);return}if(ae.reference){aa.add_label_track(new x(aa))}aa.chrom_data=ae.chrom_info;var ah='<option value="">Select Chrom/Contig</option>';for(var ag=0,ad=aa.chrom_data.length;ag<ad;ag++){var af=aa.chrom_data[ag].chrom;ah+='<option value="'+af+'">'+af+"</option>"}if(ae.prev_chroms){ah+='<option value="previous">Previous '+t+"</option>"}if(ae.next_chroms){ah+='<option value="next">Next '+t+"</option>"}aa.chrom_select.html(ah);if(ac){ac()}aa.chrom_start_index=ae.start_index},error:function(){alert("Could not load chroms for this dbkey:",aa.dbkey)}})},change_chrom:function(ae,ab,ag){if(!ae||ae==="None"){return}var ad=this;if(ae==="previous"){ad.load_chroms({low:this.chrom_start_index-t});return}if(ae==="next"){ad.load_chroms({low:this.chrom_start_index+t});return}var af=$.grep(ad.chrom_data,function(ai,aj){return ai.chrom===ae})[0];if(af===undefined){ad.load_chroms({chrom:ae},function(){ad.change_chrom(ae,ab,ag)});return}else{if(ae!==ad.chrom){ad.chrom=ae;if(!ad.chrom){ad.intro_div.show()}else{ad.intro_div.hide()}ad.chrom_select.val(ad.chrom);ad.max_high=af.len-1;ad.reset();ad.redraw(true);for(var ah=0,aa=ad.tracks.length;ah<aa;ah++){var ac=ad.tracks[ah];if(ac.init){ac.init()}}}if(ab!==undefined&&ag!==undefined){ad.low=Math.max(ab,0);ad.high=Math.min(ag,ad.max_high)}ad.reset_overview();ad.redraw()}},go_to:function(ae){var ai=this,aa,ad,ab=ae.split(":"),ag=ab[0],ah=ab[1];if(ah!==undefined){try{var af=ah.split("-");aa=parseInt(af[0].replace(/,/g,""),10);ad=parseInt(af[1].replace(/,/g,""),10)}catch(ac){return false}}ai.change_chrom(ag,aa,ad)},move_fraction:function(ac){var aa=this;var ab=aa.high-aa.low;this.move_delta(ac*ab)},move_delta:function(ac){var aa=this;var ab=aa.high-aa.low;if(aa.low-ac<aa.max_low){aa.low=aa.max_low;aa.high=aa.max_low+ab}else{if(aa.high-ac>aa.max_high){aa.high=aa.max_high;aa.low=aa.max_high-ab}else{aa.high-=ac;aa.low-=ac}}aa.redraw()},add_track:function(aa){aa.view=this;aa.track_id=this.track_id_counter;this.tracks.push(aa);if(aa.init){aa.init()}aa.container_div.attr("id","track_"+aa.track_id);C(aa.container_div,".draghandle");this.track_id_counter+=1;this.num_tracks+=1},add_label_track:function(aa){aa.view=this;this.label_tracks.push(aa)},remove_track:function(aa){this.has_changes=true;aa.container_div.fadeOut("slow",function(){$(this).remove()});delete this.tracks[this.tracks.indexOf(aa)];this.num_tracks-=1},reset:function(){this.low=this.max_low;this.high=this.max_high;this.viewport_container.find(".yaxislabel").remove()},redraw:function(ah){var ag=this.high-this.low,af=this.low,ab=this.high;if(af<this.max_low){af=this.max_low}if(ab>this.max_high){ab=this.max_high}if(this.high!==0&&ag<this.min_separation){ab=af+this.min_separation}this.low=Math.floor(af);this.high=Math.ceil(ab);this.resolution=Math.pow(z,Math.ceil(Math.log((this.high-this.low)/M)/Math.log(z)));this.zoom_res=Math.pow(s,Math.max(0,Math.ceil(Math.log(this.resolution,s)/Math.log(s))));var aa=(this.low/(this.max_high-this.max_low)*this.overview_viewport.width())||0;var ae=((this.high-this.low)/(this.max_high-this.max_low)*this.overview_viewport.width())||0;var ai=13;this.overview_box.css({left:aa,width:Math.max(ai,ae)}).show();if(ae<ai){this.overview_box.css("left",aa-(ai-ae)/2)}if(this.overview_highlight){this.overview_highlight.css({left:aa,width:ae})}this.update_location(this.low,this.high);if(!ah){for(var ac=0,ad=this.tracks.length;ac<ad;ac++){if(this.tracks[ac]&&this.tracks[ac].enabled){this.tracks[ac].draw()}}for(ac=0,ad=this.label_tracks.length;ac<ad;ac++){this.label_tracks[ac].draw()}}},zoom_in:function(ab,ac){if(this.max_high===0||this.high-this.low<this.min_separation){return}var ad=this.high-this.low,ae=ad/2+this.low,aa=(ad/this.zoom_factor)/2;if(ab){ae=ab/this.viewport_container.width()*(this.high-this.low)+this.low}this.low=Math.round(ae-aa);this.high=Math.round(ae+aa);this.redraw()},zoom_out:function(){if(this.max_high===0){return}var ab=this.high-this.low,ac=ab/2+this.low,aa=(ab*this.zoom_factor)/2;this.low=Math.round(ac-aa);this.high=Math.round(ac+aa);this.redraw()},resize_window:function(){this.viewport_container.height(this.container.height()-this.top_container.height()-this.bottom_container.height());this.nav_container.width(this.container.width());this.redraw()},reset_overview:function(){this.overview_viewport.find("canvas").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()}});var o=function(ac,ag){this.track=ac;this.name=ag.name;this.params=[];var an=ag.params;for(var ad=0;ad<an.length;ad++){var ai=an[ad],ab=ai.name,am=ai.label,ae=unescape(ai.html),ao=ai.value,ak=ai.type;if(ak==="number"){this.params[this.params.length]=new g(ab,am,ae,ao,ai.min,ai.max)}else{if(ak=="select"){this.params[this.params.length]=new K(ab,am,ae,ao)}else{console.log("WARNING: unrecognized tool parameter type:",ab,ak)}}}this.parent_div=$("<div/>").addClass("dynamic-tool").hide();this.parent_div.bind("drag",function(aq){aq.stopPropagation()}).bind("click",function(aq){aq.stopPropagation()}).bind("dblclick",function(aq){aq.stopPropagation()});var al=$("<div class='tool-name'>").appendTo(this.parent_div).text(this.name);var aj=this.params;var ah=this;$.each(this.params,function(ar,av){var au=$("<div>").addClass("param-row").appendTo(ah.parent_div);var aq=$("<div>").addClass("param-label").text(av.label).appendTo(au);var at=$("<div/>").addClass("slider").html(av.html).appendTo(au);at.find(":input").val(av.value);$("<div style='clear: both;'/>").appendTo(au)});this.parent_div.find("input").click(function(){$(this).select()});var ap=$("<div>").addClass("param-row").appendTo(this.parent_div);var af=$("<input type='submit'>").attr("value","Run on complete dataset").appendTo(ap);var aa=$("<input type='submit'>").attr("value","Run on visible region").css("margin-left","3em").appendTo(ap);var ah=this;aa.click(function(){ah.run_on_region()});af.click(function(){ah.run_on_dataset()})};n(o.prototype,{get_param_values_dict:function(){var aa={};this.parent_div.find(":input").each(function(){var ab=$(this).attr("name"),ac=$(this).val();aa[ab]=JSON.stringify(ac)});return aa},get_param_values:function(){var ab=[];var aa={};this.parent_div.find(":input").each(function(){var ac=$(this).attr("name"),ad=$(this).val();if(ac){ab[ab.length]=ad}});return ab},run_on_dataset:function(){var aa=this;aa.run({dataset_id:this.track.original_dataset_id,tool_id:aa.name},function(ab){show_modal(aa.name+" is Running",aa.name+" is running on the complete dataset. Tool outputs are in dataset's history.",{Close:hide_modal})})},run_on_region:function(){var aa={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},ac=this.track,ab=aa.tool_id+ac.tool_region_and_parameters_str(aa.chrom,aa.low,aa.high),ad;if(ac instanceof e){ad=new Q(ab,view,ac.hda_ldda,undefined,{},{},ac);ad.change_mode(ac.mode)}this.track.add_track(ad);ad.content_div.text("Starting job.");this.run(aa,function(ae){ad.dataset_id=ae.dataset_id;ad.content_div.text("Running job.");ad.init()})},run:function(ab,ac){$.extend(ab,this.get_param_values_dict());var aa=function(){$.getJSON(rerun_tool_url,ab,function(ad){if(ad==="no converter"){new_track.container_div.addClass("error");new_track.content_div.text(G)}else{if(ad.error){new_track.container_div.addClass("error");new_track.content_div.text(v+ad.message)}else{if(ad==="pending"){new_track.container_div.addClass("pending");new_track.content_div.text("Converting input data so that it can be easily reused.");setTimeout(aa,2000)}else{ac(ad)}}}})};aa()}});var K=function(ab,aa,ac,ad){this.name=ab;this.label=aa;this.html=ac;this.value=ad};var g=function(ac,ab,ae,af,ad,aa){K.call(this,ac,ab,ae,af);this.min=ad;this.max=aa};var h=function(ab,aa,ac,ad){this.name=ab;this.index=aa;this.tool_id=ac;this.tool_exp_name=ad};var R=function(ab,aa,ac,ad){h.call(this,ab,aa,ac,ad);this.low=-Number.MAX_VALUE;this.high=Number.MAX_VALUE;this.min=Number.MAX_VALUE;this.max=-Number.MAX_VALUE;this.slider=null;this.slider_label=null};n(R.prototype,{applies_to:function(aa){if(aa.length>this.index){return true}return false},keep:function(aa){if(!this.applies_to(aa)){return true}var ab=parseInt(aa[this.index]);return(isNaN(ab)||(ab>=this.low&&ab<=this.high))},update_attrs:function(ab){var aa=false;if(!this.applies_to(ab)){return aa}if(ab[this.index]<this.min){this.min=Math.floor(ab[this.index]);aa=true}if(ab[this.index]>this.max){this.max=Math.ceil(ab[this.index]);aa=true}return aa},update_ui_elt:function(){var ac=function(af,ad){var ae=ad-af;return(ae<=2?0.01:1)};var ab=this.slider.slider("option","min"),aa=this.slider.slider("option","max");if(this.min<ab||this.max>aa){this.slider.slider("option","min",this.min);this.slider.slider("option","max",this.max);this.slider.slider("option","step",ac(this.min,this.max));this.slider.slider("option","values",[this.min,this.max])}}});var W=function(ac,al){this.track=ac;this.filters=[];for(var ag=0;ag<al.length;ag++){var aa=al[ag],ab=aa.name,ak=aa.type,ai=aa.index,an=aa.tool_id,ad=aa.tool_exp_name;if(ak==="int"||ak==="float"){this.filters[ag]=new R(ab,ai,an,ad)}else{console.log("ERROR: unsupported filter: ",ab,ak)}}var aj=function(ao,ap,aq){ao.click(function(){var ar=ap.text();max=parseFloat(aq.slider("option","max")),input_size=(max<=1?4:max<=1000000?max.toString().length:6),multi_value=false;if(aq.slider("option","values")){input_size=2*input_size+1;multi_value=true}ap.text("");$("<input type='text'/>").attr("size",input_size).attr("maxlength",input_size).attr("value",ar).appendTo(ap).focus().select().click(function(at){at.stopPropagation()}).blur(function(){$(this).remove();ap.text(ar)}).keyup(function(ax){if(ax.keyCode===27){$(this).trigger("blur")}else{if(ax.keyCode===13){var av=aq.slider("option","min"),at=aq.slider("option","max"),aw=function(ay){return(isNaN(ay)||ay>at||ay<av)},au=$(this).val();if(!multi_value){au=parseFloat(au);if(aw(au)){alert("Parameter value must be in the range ["+av+"-"+at+"]");return $(this)}}else{au=au.split("-");au=[parseFloat(au[0]),parseFloat(au[1])];if(aw(au[0])||aw(au[1])){alert("Parameter value must be in the range ["+av+"-"+at+"]");return $(this)}}aq.slider((multi_value?"values":"value"),au)}}})})};this.parent_div=$("<div/>").addClass("filters").hide();this.parent_div.bind("drag",function(ao){ao.stopPropagation()}).bind("click",function(ao){ao.stopPropagation()}).bind("dblclick",function(ao){ao.stopPropagation()}).bind("keydown",function(ao){ao.stopPropagation()});var ae=this;$.each(this.filters,function(av,ap){var ar=$("<div/>").addClass("slider-row").appendTo(ae.parent_div);var ao=$("<div/>").addClass("slider-label").appendTo(ar);var ax=$("<span/>").addClass("slider-name").text(ap.name+" ").appendTo(ao);var aq=$("<span/>");var at=$("<span/>").addClass("slider-value").appendTo(ao).append("[").append(aq).append("]");var aw=$("<div/>").addClass("slider").appendTo(ar);ap.control_element=$("<div/>").attr("id",ap.name+"-filter-control").appendTo(aw);var au=[0,0];ap.control_element.slider({range:true,min:Number.MAX_VALUE,max:-Number.MIN_VALUE,values:[0,0],slide:function(ay,az){au=az.values;aq.text(az.values[0]+"-"+az.values[1]);setTimeout(function(){if(az.values[0]==au[0]&&az.values[1]==au[1]){var aA=az.values;aq.text(aA[0]+"-"+aA[1]);ap.low=aA[0];ap.high=aA[1];ae.track.draw(true,true)}},50)},change:function(ay,az){ap.control_element.slider("option","slide").call(ap.control_element,ay,az)}});ap.slider=ap.control_element;ap.slider_label=aq;aj(at,aq,ap.control_element);$("<div style='clear: both;'/>").appendTo(ar)});if(this.filters.length!=0){var am=$("<div>").addClass("param-row").appendTo(this.parent_div);var ah=$("<input type='submit'>").attr("value","Run on complete dataset").appendTo(am);var af=this;ah.click(function(){af.run_on_dataset()})}};n(W.prototype,{reset_filters:function(){for(var aa=0;aa<this.filters.length;aa++){filter=this.filters[aa];filter.slider.slider("option","values",[filter.min,filter.max])}},run_on_dataset:function(){var ai=function(am,ak,al){if(!(ak in am)){am[ak]=al}return am[ak]};var ac={},aa,ab,ad;for(var ae=0;ae<this.filters.length;ae++){aa=this.filters[ae];if(aa.tool_id){if(aa.min!=aa.low){ab=ai(ac,aa.tool_id,[]);ab[ab.length]=aa.tool_exp_name+" >= "+aa.low}if(aa.max!=aa.high){ab=ai(ac,aa.tool_id,[]);ab[ab.length]=aa.tool_exp_name+" <= "+aa.high}}}var ag=[];for(var aj in ac){ag[ag.length]=[aj,ac[aj]]}var ah=ag.length;(function af(aq,an){var al=an[0],am=al[0],ap=al[1],ao="("+ap.join(") and (")+")",ak={cond:ao,input:aq,target_dataset_id:aq,tool_id:am},an=an.slice(1);$.getJSON(run_tool_url,ak,function(ar){if(ar.error){show_modal("Filter Dataset","Error running tool "+am,{Close:hide_modal})}else{if(an.length===0){show_modal("Filtering Dataset","Filter(s) are running on the complete dataset. Outputs are in dataset's history.",{Close:hide_modal})}else{af(ar.dataset_id,an)}}})})(this.track.dataset_id,ag)}});var V=function(aa){this.track=aa.track;this.params=aa.params;this.values={};if(aa.saved_values){this.restore_values(aa.saved_values)}this.onchange=aa.onchange};n(V.prototype,{restore_values:function(aa){var ab=this;$.each(this.params,function(ac,ad){if(aa[ad.key]!==undefined){ab.values[ad.key]=aa[ad.key]}else{ab.values[ad.key]=ad.default_value}})},build_form:function(){var ab=this;var aa=$("<div />");$.each(this.params,function(af,ad){if(!ad.hidden){var ac="param_"+af;var ak=$("<div class='form-row' />").appendTo(aa);ak.append($("<label />").attr("for",ac).text(ad.label+":"));if(ad.type==="bool"){ak.append($('<input type="checkbox" />').attr("id",ac).attr("name",ac).attr("checked",ab.values[ad.key]))}else{if(ad.type==="color"){var ah=ab.values[ad.key];var ag=$("<input />").attr("id",ac).attr("name",ac).val(ah);var ai=$("<div class='tipsy tipsy-north' style='position: absolute;' />").hide();var ae=$("<div style='background-color: black; padding: 10px;'></div>").appendTo(ai);var aj=$("<div/>").appendTo(ae).farbtastic({width:100,height:100,callback:ag,color:ah});$("<div />").append(ag).append(ai).appendTo(ak).bind("click",function(al){ai.css({left:$(this).position().left+($(ag).width()/2)-60,top:$(this).position().top+$(this.height)}).show();$(document).bind("click.color-picker",function(){ai.hide();$(document).unbind("click.color-picker")});al.stopPropagation()})}else{ak.append($("<input />").attr("id",ac).attr("name",ac).val(ab.values[ad.key]))}}}});return aa},update_from_form:function(aa){var ac=this;var ab=false;$.each(this.params,function(ad,af){if(!af.hidden){var ag="param_"+ad;var ae=aa.find("#"+ag).val();if(af.type==="float"){ae=parseFloat(ae)}else{if(af.type==="int"){ae=parseInt(ae)}else{if(af.type==="bool"){ae=aa.find("#"+ag).is(":checked")}}}if(ae!==ac.values[af.key]){ac.values[af.key]=ae;ab=true}}});if(ab){this.onchange()}}});var b=function(ac,ab,aa){this.index=ac;this.resolution=ab;this.canvas=$("<div class='track-tile'/>").append(aa)};var l=function(ac,ab,aa,ad){b.call(this,ac,ab,aa);this.max_val=ad};var L=function(ac,ab,aa,ad){b.call(this,ac,ab,aa);this.message=ad};var j=function(ab,aa,ae,ac,ad){this.name=ab;this.view=aa;this.parent_element=ae;this.data_url=(ac?ac:default_data_url);this.data_url_extra_params={};this.data_query_wait=(ad?ad:H);this.dataset_check_url=converted_datasets_state_url;this.container_div=$("<div />").addClass("track").css("position","relative");if(!this.hidden){this.header_div=$("<div class='track-header' />").appendTo(this.container_div);if(this.view.editor){this.drag_div=$("<div class='draghandle' />").appendTo(this.header_div)}this.name_div=$("<div class='menubutton popup' />").appendTo(this.header_div);this.name_div.text(this.name);this.name_div.attr("id",this.name.replace(/\s+/g,"-").replace(/[^a-zA-Z0-9\-]/g,"").toLowerCase())}this.content_div=$("<div class='track-content'>").appendTo(this.container_div);this.parent_element.append(this.container_div)};n(j.prototype,{get_type:function(){if(this instanceof X){return"LabelTrack"}else{if(this instanceof x){return"ReferenceTrack"}else{if(this instanceof k){return"LineTrack"}else{if(this instanceof S){return"ReadTrack"}else{if(this instanceof Q){return"ToolDataFeatureTrack"}else{if(this instanceof P){return"VcfTrack"}else{if(this instanceof e){return"FeatureTrack"}}}}}}}return""},init:function(){var aa=this;aa.enabled=false;aa.tile_cache.clear();aa.data_cache.clear();aa.initial_canvas=undefined;aa.content_div.css("height","auto");aa.container_div.removeClass("nodata error pending");if(!aa.dataset_id){return}$.getJSON(converted_datasets_state_url,{hda_ldda:aa.hda_ldda,dataset_id:aa.dataset_id,chrom:aa.view.chrom},function(ab){if(!ab||ab==="error"||ab.kind==="error"){aa.container_div.addClass("error");aa.content_div.text(m);if(ab.message){var ad=aa.view.tracks.indexOf(aa);var ac=$(" <a href='javascript:void(0);'></a>").text("View error").bind("click",function(){show_modal("Trackster Error","<pre>"+ab.message+"</pre>",{Close:hide_modal})});aa.content_div.append(ac)}}else{if(ab==="no converter"){aa.container_div.addClass("error");aa.content_div.text(G)}else{if(ab==="no data"||(ab.data!==undefined&&(ab.data===null||ab.data.length===0))){aa.container_div.addClass("nodata");aa.content_div.text(B)}else{if(ab==="pending"){aa.container_div.addClass("pending");aa.content_div.text(q);setTimeout(function(){aa.init()},aa.data_query_wait)}else{if(ab.status==="data"){if(ab.valid_chroms){aa.valid_chroms=ab.valid_chroms;aa.make_name_popup_menu()}aa.content_div.text(U);if(aa.view.chrom){aa.content_div.text("");aa.content_div.css("height",aa.height_px+"px");aa.enabled=true;$.when(aa.predraw_init()).done(function(){aa.container_div.removeClass("nodata error pending");aa.draw()})}}}}}}})},predraw_init:function(){},update_name:function(aa){this.old_name=this.name;this.name=aa;this.name_div.text(this.name)},revert_name:function(){this.name=this.old_name;this.name_div.text(this.name)}});var J=function(ah,af,ai){var ab=this,aj=ab.view;this.filters_manager=(ah!==undefined?new W(this,ah):undefined);this.filters_available=false;this.filters_visible=false;this.tool=(af!==undefined&&obj_length(af)>0?new o(this,af):undefined);this.parent_track=ai;this.child_tracks=[];if(ab.hidden){return}if(this.parent_track){this.header_div.find(".draghandle").removeClass("draghandle").addClass("child-track-icon").addClass("icon-button");this.parent_element.addClass("child-track");this.tool=undefined}ab.child_tracks_container=$("<div/>").addClass("child-tracks-container").hide();ab.container_div.append(ab.child_tracks_container);if(this.filters_manager){this.filters_div=this.filters_manager.parent_div;this.header_div.after(this.filters_div)}if(this.tool){this.dynamic_tool_div=this.tool.parent_div;this.header_div.after(this.dynamic_tool_div)}if(ab.display_modes!==undefined){if(ab.mode_div===undefined){ab.mode_div=$("<div class='right-float menubutton popup' />").appendTo(ab.header_div);var ac=(ab.track_config&&ab.track_config.values.mode?ab.track_config.values.mode:ab.display_modes[0]);ab.mode=ac;ab.mode_div.text(ac);var aa={};for(var ad=0,ag=ab.display_modes.length;ad<ag;ad++){var ae=ab.display_modes[ad];aa[ae]=function(ak){return function(){ab.change_mode(ak)}}(ae)}make_popupmenu(ab.mode_div,aa)}else{ab.mode_div.hide()}}this.make_name_popup_menu()};n(J.prototype,j.prototype,{change_mode:function(ab){var aa=this;aa.mode_div.text(ab);aa.mode=ab;aa.track_config.values.mode=ab;aa.tile_cache.clear();aa.draw()},make_name_popup_menu:function(){var ab=this;var aa={};aa["Edit configuration"]=function(){var ah=function(){hide_modal();$(window).unbind("keypress.check_enter_esc")},af=function(){ab.track_config.update_from_form($(".dialog-box"));hide_modal();$(window).unbind("keypress.check_enter_esc")},ag=function(ai){if((ai.keyCode||ai.which)===27){ah()}else{if((ai.keyCode||ai.which)===13){af()}}};$(window).bind("keypress.check_enter_esc",ag);show_modal("Configure Track",ab.track_config.build_form(),{Cancel:ah,OK:af})};if(ab.filters_available>0){var ae=(ab.filters_div.is(":visible")?"Hide filters":"Show filters");aa[ae]=function(){ab.filters_visible=(ab.filters_div.is(":visible"));if(ab.filters_visible){ab.filters_manager.reset_filters()}ab.filters_div.toggle();ab.make_name_popup_menu()}}if(ab.tool){var ae=(ab.dynamic_tool_div.is(":visible")?"Hide tool":"Show tool");aa[ae]=function(){if(!ab.dynamic_tool_div.is(":visible")){ab.update_name(ab.name+ab.tool_region_and_parameters_str())}else{menu_option_text="Show dynamic tool";ab.revert_name()}ab.dynamic_tool_div.toggle();ab.make_name_popup_menu()}}if(ab.valid_chroms){aa["List chrom/contigs with data"]=function(){show_modal("Chrom/contigs with data","<p>"+ab.valid_chroms.join("<br/>")+"</p>",{Close:function(){hide_modal()}})}}var ac=view;var ad=function(){$("#no-tracks").show()};if(this.parent_track){ac=this.parent_track;ad=function(){}}aa.Remove=function(){ac.remove_track(ab);if(ac.num_tracks===0){ad()}};make_popupmenu(ab.name_div,aa)},draw:function(aa,ac){if(!this.dataset_id){return}var au=this.view.low,ag=this.view.high,ai=ag-au,ak=this.view.container.width(),ae=ak/ai,al=this.view.resolution,ad=$("<div style='position: relative;'></div>"),am=function(aw,ax,av){return aw+"_"+ax+"_"+av};if(!ac){this.content_div.children().remove()}this.content_div.append(ad);this.max_height=0;var ao=Math.floor(au/al/M);var af=[];var ap=0;while((ao*M*al)<ag){var at=am(ak,ae,ao);var ah=this.tile_cache.get(at);var aq=ao*M*this.view.resolution;var ab=aq+M*this.view.resolution;if(!aa&&ah){af[af.length]=ah;this.show_tile(ah,ad,aq,ae)}else{this.delayed_draw(aa,at,ao,al,ad,ae,af)}ao+=1;ap++}var aj=this;var ar=setInterval(function(){if(af.length===ap){clearInterval(ar);if(ac){var aA=aj.content_div.children();var aB=false;for(var az=aA.length-1,aF=0;az>=aF;az--){var ay=$(aA[az]);if(aB){ay.remove()}else{if(ay.children().length!==0){aB=true}}}}if(aj instanceof e&&aj.mode=="Histogram"){var aE=-1;for(var az=0;az<af.length;az++){var aH=af[az].max_val;if(aH>aE){aE=aH}}for(var az=0;az<af.length;az++){if(af[az].max_val!==aE){var aG=af[az];aG.canvas.remove();aj.delayed_draw(true,am(ak,ae,aG.index),aG.index,aG.resolution,ad,ae,[],{max:aE})}}}if(aj.filters_manager){var ax=aj.filters_manager.filters;for(var aD=0;aD<ax.length;aD++){ax[aD].update_ui_elt()}var aC=false;if(aj.example_feature){for(var aD=0;aD<ax.length;aD++){if(ax[aD].applies_to(aj.example_feature)){aC=true;break}}}if(aj.filters_available!==aC){aj.filters_available=aC;if(!aj.filters_available){aj.filters_div.hide()}aj.make_name_popup_menu()}}var av=false;for(var aw=0;aw<af.length;aw++){if(af[aw].message){av=true;break}}if(av){for(var aw=0;aw<af.length;aw++){aG=af[aw];if(!aG.message){aG.canvas.css("padding-top",A)}}}}},50);for(var an=0;an<this.child_tracks.length;an++){this.child_tracks[an].draw(aa,ac)}},delayed_draw:function(ab,ai,ac,ae,aj,am,ak,af){var ad=this,ag=ac*M*ae,al=ag+M*ae;var ah=function(av,an,ap,ao,at,au,aq){var ar=ad.draw_tile(an,ap,ao,au,aq);ad.tile_cache.set(ai,ar);if(ar===undefined){return}ad.show_tile(ar,at,ag,au);ak[ak.length]=ar};var aa=setTimeout(function(){if(ag<=ad.view.high&&al>=ad.view.low){var an=(ab?undefined:ad.tile_cache.get(ai));if(an){ad.show_tile(an,aj,ag,am);ak[ak.length]=an}else{$.when(ad.data_cache.get_data(view.chrom,ag,al,ad.mode,ae,ad.data_url_extra_params)).then(function(ao){n(ao,af);if(view.reference_track&&am>view.canvas_manager.char_width_px){$.when(view.reference_track.data_cache.get_data(view.chrom,ag,al,ad.mode,ae,view.reference_track.data_url_extra_params)).then(function(ap){ah(aa,ao,ae,ac,aj,am,ap)})}else{ah(aa,ao,ae,ac,aj,am)}})}}},50)},show_tile:function(ad,ag,ae,ah){var ab=this;var ac=this.view.high-this.view.low,af=(ae-this.view.low)*ah;if(this.left_offset){af-=this.left_offset}var aa=ad.canvas;aa.css({position:"absolute",top:0,left:af,height:""});ag.append(aa);ab.max_height=Math.max(ab.max_height,aa.height());ab.content_div.css("height",ab.max_height+"px");ag.children().css("height",ab.max_height+"px")},set_overview:function(){var aa=this.view;if(this.initial_canvas&&this.is_overview){aa.overview_close.show();aa.overview_viewport.append(this.initial_canvas);aa.overview_highlight.show().height(this.initial_canvas.height());aa.overview_viewport.height(this.initial_canvas.height()+aa.overview_box.height())}$(window).trigger("resize")},tool_region_and_parameters_str:function(ac,aa,ad){var ab=this,ae=(ac!==undefined&&aa!==undefined&&ad!==undefined?ac+":"+aa+"-"+ad:"all");return" - region=["+ae+"], parameters=["+ab.tool.get_param_values().join(", ")+"]"},add_track:function(aa){aa.track_id=this.track_id+"_"+this.child_tracks.length;aa.container_div.attr("id","track_"+aa.track_id);this.child_tracks_container.append(aa.container_div);C(aa.container_div,".child-track-icon");if(!$(this.child_tracks_container).is(":visible")){this.child_tracks_container.show()}this.child_tracks.push(aa);this.view.has_changes=true},remove_track:function(aa){aa.container_div.fadeOut("slow",function(){$(this).remove()})}});var X=function(aa,ab){this.hidden=true;j.call(this,null,aa,ab);this.container_div.addClass("label-track")};n(X.prototype,j.prototype,{draw:function(){var ac=this.view,ad=ac.high-ac.low,ag=Math.floor(Math.pow(10,Math.floor(Math.log(ad)/Math.log(10)))),aa=Math.floor(ac.low/ag)*ag,ae=this.view.container.width(),ab=$("<div style='position: relative; height: 1.3em;'></div>");while(aa<ac.high){var af=(aa-ac.low)/ad*ae;ab.append($("<div class='label'>"+commatize(aa)+"</div>").css({position:"absolute",left:af-1}));aa+=ag}this.content_div.children(":first").remove();this.content_div.append(ab)}});var x=function(aa){this.hidden=true;j.call(this,null,aa,aa.top_labeltrack);J.call(this);aa.reference_track=this;this.left_offset=200;this.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:aa.dbkey};this.data_cache=new E(y,this,false);this.tile_cache=new c(r)};n(x.prototype,J.prototype,{draw_tile:function(ai,af,ab,ak){var ae=this,ac=M*af;if(ak>this.view.canvas_manager.char_width_px){if(ai===null){ae.content_div.css("height","0px");return}var ad=this.view.canvas_manager.new_canvas();var aj=ad.getContext("2d");ad.width=Math.ceil(ac*ak+ae.left_offset);ad.height=ae.height_px;aj.font=aj.canvas.manager.default_font;aj.textAlign="center";for(var ag=0,ah=ai.length;ag<ah;ag++){var aa=Math.round(ag*ak);aj.fillText(ai[ag],aa+ae.left_offset,10)}return new b(ab,af,ad)}this.content_div.css("height","0px")}});var k=function(ae,ac,af,aa,ad){var ab=this;this.display_modes=["Histogram","Line","Filled","Intensity"];this.mode="Histogram";j.call(this,ae,ac,ac.viewport_container);J.call(this);this.min_height_px=16;this.max_height_px=400;this.height_px=80;this.hda_ldda=af;this.dataset_id=aa;this.original_dataset_id=aa;this.data_cache=new N(y,this);this.tile_cache=new c(r);this.track_config=new V({track:this,params:[{key:"color",label:"Color",type:"color",default_value:"black"},{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:this.height_px,hidden:true}],saved_values:ad,onchange:function(){ab.vertical_range=ab.prefs.max_value-ab.prefs.min_value;$("#linetrack_"+ab.track_id+"_minval").text(ab.prefs.min_value);$("#linetrack_"+ab.track_id+"_maxval").text(ab.prefs.max_value);ab.tile_cache.clear();ab.draw()}});this.prefs=this.track_config.values;this.height_px=this.track_config.values.height;this.vertical_range=this.track_config.values.max_value-this.track_config.values.min_value;this.add_resize_handle()};n(k.prototype,J.prototype,{add_resize_handle:function(){var aa=this;var ad=false;var ac=false;var ab=$("<div class='track-resize'>");$(aa.container_div).hover(function(){ad=true;ab.show()},function(){ad=false;if(!ac){ab.hide()}});ab.hide().bind("dragstart",function(ae,af){ac=true;af.original_height=$(aa.content_div).height()}).bind("drag",function(af,ag){var ae=Math.min(Math.max(ag.original_height+ag.deltaY,aa.min_height_px),aa.max_height_px);$(aa.content_div).css("height",ae);aa.height_px=ae;aa.draw(true)}).bind("dragend",function(ae,af){aa.tile_cache.clear();ac=false;if(!ad){ab.hide()}aa.track_config.values.height=aa.height_px}).appendTo(aa.container_div)},predraw_init:function(){var aa=this,ab=aa.view.tracks.indexOf(aa);aa.vertical_range=undefined;return $.getJSON(aa.data_url,{stats:true,chrom:aa.view.chrom,low:null,high:null,hda_ldda:aa.hda_ldda,dataset_id:aa.dataset_id},function(ac){aa.container_div.addClass("line-track");var ae=ac.data;if(isNaN(parseFloat(aa.prefs.min_value))||isNaN(parseFloat(aa.prefs.max_value))){aa.prefs.min_value=ae.min;aa.prefs.max_value=ae.max;$("#track_"+ab+"_minval").val(aa.prefs.min_value);$("#track_"+ab+"_maxval").val(aa.prefs.max_value)}aa.vertical_range=aa.prefs.max_value-aa.prefs.min_value;aa.total_frequency=ae.total_frequency;aa.container_div.find(".yaxislabel").remove();var af=$("<div />").addClass("yaxislabel").attr("id","linetrack_"+ab+"_minval").text(u(aa.prefs.min_value));var ad=$("<div />").addClass("yaxislabel").attr("id","linetrack_"+ab+"_maxval").text(u(aa.prefs.max_value));ad.css({position:"absolute",top:"24px",left:"10px"});ad.prependTo(aa.container_div);af.css({position:"absolute",bottom:"2px",left:"10px"});af.prependTo(aa.container_div)})},draw_tile:function(ak,ae,ab,aj){if(this.vertical_range===undefined){return}var af=ab*M*ae,ad=M*ae,aa=Math.ceil(ad*aj),ah=this.height_px;var ac=this.view.canvas_manager.new_canvas();ac.width=aa,ac.height=ah;var ai=ac.getContext("2d");var ag=new I.LinePainter(ak.data,af,af+ad,this.prefs,this.mode);ag.draw(ai,aa,ah);return new b(ad,ae,ac)}});var e=function(aa,af,ae,ai,ah,ac,ad,ag){var ab=this;this.display_modes=["Auto","Histogram","Dense","Squish","Pack"];this.track_config=new V({track:this,params:[{key:"block_color",label:"Block color",type:"color",default_value:"#444"},{key:"label_color",label:"Label color",type:"color",default_value:"black"},{key:"show_counts",label:"Show summary counts",type:"bool",default_value:true},{key:"mode",type:"string",default_value:this.mode,hidden:true},],saved_values:ah,onchange:function(){ab.tile_cache.clear();ab.draw()}});this.prefs=this.track_config.values;j.call(this,aa,af,af.viewport_container);J.call(this,ac,ad,ag);this.height_px=0;this.container_div.addClass("feature-track");this.hda_ldda=ae;this.dataset_id=ai;this.original_dataset_id=ai;this.show_labels_scale=0.001;this.showing_details=false;this.summary_draw_height=30;this.inc_slots={};this.start_end_dct={};this.tile_cache=new c(d);this.data_cache=new N(20,this);this.left_offset=200;this.painter=I.LinkedFeaturePainter};n(e.prototype,J.prototype,{update_auto_mode:function(aa){if(this.mode=="Auto"){if(aa=="no_detail"){aa="feature spans"}else{if(aa=="summary_tree"){aa="coverage histogram"}}this.mode_div.text("Auto ("+aa+")")}},incremental_slots:function(ae,ab,ad){var ac=this.view.canvas_manager.dummy_context,aa=this.inc_slots[ae];if(!aa||(aa.mode!==ad)){aa=new (p.FeatureSlotter)(ae,ad==="Pack",w,function(af){return ac.measureText(af)});aa.mode=ad;this.inc_slots[ae]=aa}return aa.slot_features(ab)},get_summary_tree_data:function(ae,ah,ac,ap){if(ap>ac-ah){ap=ac-ah}var al=Math.floor((ac-ah)/ap),ao=[],ad=0;var af=0,ag=0,ak,an=0,ai=[],am,aj;var ab=function(at,ar,au,aq){at[0]=ar+au*aq;at[1]=ar+(au+1)*aq};while(an<ap&&af!==ae.length){var aa=false;for(;an<ap&&!aa;an++){ab(ai,ah,an,al);for(ag=af;ag<ae.length;ag++){ak=ae[ag].slice(1,3);if(is_overlap(ak,ai)){aa=true;break}}if(aa){break}}data_start_index=ag;ao[ao.length]=am=[ai[0],0];for(;ag<ae.length;ag++){ak=ae[ag].slice(1,3);if(is_overlap(ak,ai)){am[1]++}else{break}}if(am[1]>ad){ad=am[1]}an++}return{max:ad,delta:al,data:ao}},draw_tile:function(an,aw,aA,aj,ad){var at=this,aC=aA*M*aw,ab=(aA+1)*M*aw,ap=ab-aC,au=Math.ceil(ap*aj),aq=this.mode,aH=25,ae=this.left_offset,ao,af;if(aq==="Auto"){if(an.dataset_type==="summary_tree"){aq=an.dataset_type}else{if(an.extra_info==="no_detail"){aq="no_detail"}else{var aG=an.data;if(this.view.high-this.view.low>F){aq="Squish"}else{aq="Pack"}}}this.update_auto_mode(aq)}if(aq==="summary_tree"||aq==="Histogram"){af=this.summary_draw_height;this.container_div.find(".yaxislabel").remove();var aa=$("<div />").addClass("yaxislabel");aa.text(an.max);aa.css({position:"absolute",top:"24px",left:"10px",color:this.prefs.label_color});aa.prependTo(this.container_div);var ac=this.view.canvas_manager.new_canvas();ac.width=au+ae;ac.height=af+O;if(an.dataset_type!="summary_tree"){var ak=this.get_summary_tree_data(an.data,aC,ab,200);if(an.max){ak.max=an.max}an=ak}var aE=new I.SummaryTreePainter(an,aC,ab,this.prefs);var av=ac.getContext("2d");av.translate(ae,O);aE.draw(av,au,af);return new l(aA,aw,ac,an.max)}var ao,ah=1;if(aq==="no_detail"||aq==="Squish"||aq==="Pack"){ah=this.incremental_slots(aj,an.data,aq);ao=this.inc_slots[aj].slots}var ai=[];if(an.data){var al=this.filters_manager.filters;for(var ax=0,az=an.data.length;ax<az;ax++){var ag=an.data[ax];var ay=false;var am;for(var aB=0,aF=al.length;aB<aF;aB++){am=al[aB];am.update_attrs(ag);if(!am.keep(ag)){ay=true;break}}if(!ay){ai.push(ag)}}}var aE=new (this.painter)(ai,aC,ab,this.prefs,aq,ad);var af=aE.get_required_height(ah);var ac=this.view.canvas_manager.new_canvas();ac.width=au+ae;ac.height=af;var av=ac.getContext("2d");av.fillStyle=this.prefs.block_color;av.font=av.canvas.manager.default_font;av.textAlign="right";this.container_div.find(".yaxislabel").remove();if(an.data){this.example_feature=(an.data.length?an.data[0]:undefined);av.translate(ae,0);aE.draw(av,au,af,ao)}if(an.message){var ar=$("<div/>");var aD=$("<div/>").addClass("tile-message").text(an.message).css("width",ac.width);aD.css({position:"absolute",top:0});$(ac).css("top",15);ar.append(aD);ar.append(ac);ac=ar}return new L(aA,aw,ac,an.message)}});var P=function(ad,ab,af,aa,ac,ae){e.call(this,ad,ab,af,aa,ac,ae);this.painter=I.VariantPainter};n(P.prototype,J.prototype,e.prototype);var S=function(ad,ab,af,aa,ac,ae){e.call(this,ad,ab,af,aa,ac,ae);this.track_config=new V({track:this,params:[{key:"block_color",label:"Block color",type:"color",default_value:"#444"},{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:"mode",type:"string",default_value:this.mode,hidden:true},],saved_values:ac,onchange:function(){this.track.tile_cache.clear();this.track.draw()}});this.prefs=this.track_config.values;this.painter=I.ReadPainter;this.make_name_popup_menu()};n(S.prototype,J.prototype,e.prototype);var Q=function(ae,ac,ag,aa,ad,af,ab){e.call(this,ae,ac,ag,aa,ad,af,{},ab);this.data_url=raw_data_url;this.data_query_wait=1000;this.dataset_check_url=dataset_state_url};n(Q.prototype,J.prototype,e.prototype,{predraw_init:function(){var ab=this;var aa=function(){if(ab.data_cache.size()===0){setTimeout(aa,300)}else{ab.data_url=default_data_url;ab.data_query_wait=H;ab.dataset_state_url=converted_datasets_state_url;$.getJSON(ab.dataset_state_url,{dataset_id:ab.dataset_id,hda_ldda:ab.hda_ldda},function(ac){})}};aa()}});T.View=Y;T.LineTrack=k;T.FeatureTrack=e;T.ReadTrack=S};var slotting_module=function(c,b){var e=c("class").extend;var d=2,a=5;b.FeatureSlotter=function(j,h,f,g){this.slots={};this.start_end_dct={};this.w_scale=j;this.include_label=h;this.max_rows=f;this.measureText=g};e(b.FeatureSlotter.prototype,{slot_features:function(m){var p=this.w_scale,s=this.slots,h=this.start_end_dct,y=[],A=[],n=0,z=this.max_rows;for(var w=0,x=m.length;w<x;w++){var l=m[w],o=l[0];if(s[o]!==undefined){n=Math.max(n,s[o]);A.push(s[o])}else{y.push(w)}}var q=function(G,H){for(var F=0;F<=z;F++){var D=false,I=h[F];if(I!==undefined){for(var C=0,E=I.length;C<E;C++){var B=I[C];if(H>B[0]&&G<B[1]){D=true;break}}}if(!D){return F}}return -1};for(var w=0,x=y.length;w<x;w++){var l=m[y[w]],o=l[0],u=l[1],f=l[2],r=l[3],g=Math.floor(u*p),k=Math.ceil(f*p),v=this.measureText(r).width,j;if(r!==undefined&&this.include_label){v+=(d+a);if(g-v>=0){g-=v;j="left"}else{k+=v;j="right"}}var t=q(g,k);if(t>=0){if(h[t]===undefined){h[t]=[]}h[t].push([g,k]);s[o]=t;n=Math.max(n,t)}else{}}return n+1}})};var painters_module=function(j,w){var t=j("class").extend;var o=function(H,z,F,y,E,C){if(C===undefined){C=4}var B=y-z;var A=E-F;var D=Math.floor(Math.sqrt(B*B+A*A)/C);var I=B/D;var G=A/D;var x;for(x=0;x<D;x++,z+=I,F+=G){if(x%2!==0){continue}H.fillRect(z,F,C,1)}};var p=function(A,z,x,D){var C=z-D/2,B=z+D/2,E=x-Math.sqrt(D*3/2);A.beginPath();A.moveTo(C,E);A.lineTo(B,E);A.lineTo(z,x);A.lineTo(C,E);A.strokeStyle=this.fillStyle;A.fill();A.stroke();A.closePath()};var m=function(z,B,x,y,A){this.data=z;this.view_start=B;this.view_end=x;this.prefs=t({},this.default_prefs,y);this.mode=A};m.prototype.default_prefs={};var u=function(z,B,x,y,A){m.call(this,z,B,x,y,A)};u.prototype.default_prefs={show_counts:false};u.prototype.draw=function(M,z,L){var E=this.view_start,O=this.view_end-this.view_start,N=z/O;var J=this.data.data,I=this.data.delta,G=this.data.max,B=L;delta_x_px=Math.ceil(I*N);M.save();for(var C=0,D=J.length;C<D;C++){var H=Math.floor((J[C][0]-E)*N);var F=J[C][1];if(!F){continue}var K=F/G*L;if(F!==0&&K<1){K=1}M.fillStyle=this.prefs.block_color;M.fillRect(H,B-K,delta_x_px,K);var A=4;if(this.prefs.show_counts&&(M.measureText(F).width+A)<delta_x_px){M.fillStyle=this.prefs.label_color;M.textAlign="center";M.fillText(F,H+(delta_x_px/2),10)}}M.restore()};var c=function(x,B,D,E,z){m.call(this,x,B,D,E,z);if(this.prefs.min_value===undefined){var F=Infinity;for(var y=0,A=this.data.length;y<A;y++){F=Math.min(F,this.data[y][1])}this.prefs.min_value=F}if(this.prefs.max_value===undefined){var C=-Infinity;for(var y=0,A=this.data.length;y<A;y++){C=Math.max(C,this.data[y][1])}this.prefs.max_value=C}};c.prototype.default_prefs={min_value:undefined,max_value:undefined,mode:"Histogram",color:"#000",overflow_color:"#F66"};c.prototype.draw=function(M,L,J){var E=false,G=this.prefs.min_value,C=this.prefs.max_value,I=C-G,x=J,z=this.view_start,K=this.view_end-this.view_start,A=L/K,H=this.mode,S=this.data;M.save();var T=Math.round(J+G/I*J);if(H!=="Intensity"){M.fillStyle="#aaa";M.fillRect(0,T,L,1)}M.beginPath();var Q,D,B;if(S.length>1){B=Math.ceil((S[1][0]-S[0][0])*A)}else{B=10}for(var N=0,O=S.length;N<O;N++){M.fillStyle=this.prefs.color;Q=Math.round((S[N][0]-z)*A);D=S[N][1];var P=false,F=false;if(D===null){if(E&&H==="Filled"){M.lineTo(Q,x)}E=false;continue}if(D<G){F=true;D=G}else{if(D>C){P=true;D=C}}if(H==="Histogram"){D=Math.round(D/I*x);M.fillRect(Q,T,B,-D)}else{if(H==="Intensity"){D=255-Math.floor((D-G)/I*255);M.fillStyle="rgb("+D+","+D+","+D+")";M.fillRect(Q,0,B,x)}else{D=Math.round(x-(D-G)/I*x);if(E){M.lineTo(Q,D)}else{E=true;if(H==="Filled"){M.moveTo(Q,x);M.lineTo(Q,D)}else{M.moveTo(Q,D)}}}}M.fillStyle=this.prefs.overflow_color;if(P||F){var R;if(H==="Histogram"||H==="Intensity"){R=B}else{Q-=2;R=4}if(P){M.fillRect(Q,0,R,3)}if(F){M.fillRect(Q,x-3,R,3)}}M.fillStyle=this.prefs.color}if(H==="Filled"){if(E){M.lineTo(Q,T);M.lineTo(0,T)}M.fill()}else{M.stroke()}M.restore()};var n=function(z,B,x,y,A){m.call(this,z,B,x,y,A)};n.prototype.default_prefs={block_color:"#FFF",connector_color:"#FFF"};t(n.prototype,{get_required_height:function(y){var x=y_scale=this.get_row_height(),z=this.mode;if(z==="no_detail"||z==="Squish"||z==="Pack"){x=y*y_scale}return x+Math.max(Math.round(y_scale/2),5)},draw:function(J,A,I,F){var D=this.data,G=this.view_start,K=this.view_end;J.save();J.fillStyle=this.prefs.block_color;J.textAlign="right";var N=this.view_end-this.view_start,M=A/N,z=this.get_row_height();for(var C=0,E=D.length;C<E;C++){var L=D[C],B=L[0],x=L[1],y=L[2],H=(F&&F[B]!==undefined?F[B]:null);if((x<K&&y>G)&&(this.mode=="Dense"||H!==null)){this.draw_element(J,this.mode,L,H,G,K,M,z,A)}}J.restore()}});var d=10,h=3,l=5,v=10,f=1,r=3,e=3,a=9,k=2,g="#ccc";var q=function(z,B,x,y,A){n.call(this,z,B,x,y,A)};t(q.prototype,n.prototype,{get_row_height:function(){var y=this.mode,x;if(y==="Dense"){x=d}else{if(y==="no_detail"){x=h}else{if(y==="Squish"){x=l}else{x=v}}}return x},draw_element:function(J,C,R,E,L,ab,af,ag,x){var O=R[0],ad=R[1],V=R[2],M=R[3],W=Math.floor(Math.max(0,(ad-L)*af)),K=Math.ceil(Math.min(x,Math.max(0,(V-L)*af))),U=(C==="Dense"?0:(0+E))*ag,I,Z,N=null,ah=null,A=this.prefs.block_color,Y=this.prefs.label_color;if(C=="Dense"){E=1}if(C==="no_detail"){J.fillStyle=A;J.fillRect(W,U+5,K-W,f)}else{var H=R[4],T=R[5],X=R[6],B=R[7];if(T&&X){N=Math.floor(Math.max(0,(T-L)*af));ah=Math.ceil(Math.min(x,Math.max(0,(X-L)*af)))}var ae,P;if(C==="Squish"||C==="Dense"){ae=1;P=e}else{ae=5;P=a}if(!B){if(R.strand){if(R.strand==="+"){J.fillStyle=J.canvas.manager.get_pattern("right_strand_inv")}else{if(R.strand==="-"){J.fillStyle=J.canvas.manager.get_pattern("left_strand_inv")}}}else{J.fillStyle=A}J.fillRect(W,U,K-W,P)}else{var G,Q;if(C==="Squish"||C==="Dense"){J.fillStyle=g;G=U+Math.floor(e/2)+1;Q=1}else{if(H){var G=U;var Q=P;if(H==="+"){J.fillStyle=J.canvas.manager.get_pattern("right_strand")}else{if(H==="-"){J.fillStyle=J.canvas.manager.get_pattern("left_strand")}}}else{J.fillStyle=g;G+=(e/2)+1;Q=1}}J.fillRect(W,G,K-W,Q);for(var ac=0,z=B.length;ac<z;ac++){var D=B[ac],y=Math.floor(Math.max(0,(D[0]-L)*af)),S=Math.ceil(Math.min(x,Math.max((D[1]-L)*af)));if(y>S){continue}J.fillStyle=A;J.fillRect(y,U+(P-ae)/2+1,S-y,ae);if(N!==undefined&&X>T&&!(y>ah||S<N)){var aa=Math.max(y,N),F=Math.min(S,ah);J.fillRect(aa,U+1,F-aa,P);if(B.length==1&&C=="Pack"){if(H==="+"){J.fillStyle=J.canvas.manager.get_pattern("right_strand_inv")}else{if(H==="-"){J.fillStyle=J.canvas.manager.get_pattern("left_strand_inv")}}if(aa+14<F){aa+=2;F-=2}J.fillRect(aa,U+1,F-aa,P)}}}}if(C==="Pack"&&ad>L){J.fillStyle=Y;if(L===0&&W-J.measureText(M).width<0){J.textAlign="left";J.fillText(M,K+k,U+8)}else{J.textAlign="right";J.fillText(M,W-k,U+8)}J.fillStyle=A}}}});var b=function(z,B,x,y,A){n.call(this,z,B,x,y,A)};t(b.prototype,n.prototype,{draw_element:function(Q,L,F,B,T,z,I,R,O){var F=data[i],H=F[0],P=F[1],A=F[2],K=F[3],D=Math.floor(Math.max(0,(P-T)*I)),G=Math.ceil(Math.min(O,Math.max(0,(A-T)*I))),C=(L==="Dense"?0:(0+B))*R,x,U,y=null,J=null;if(no_label){Q.fillStyle=block_color;Q.fillRect(D+left_offset,C+5,G-D,1)}else{var S=F[4],N=F[5],E=F[6];x=9;U=1;Q.fillRect(D+left_offset,C,G-D,x);if(L!=="Dense"&&K!==undefined&&P>T){Q.fillStyle=label_color;if(T===0&&D-Q.measureText(K).width<0){Q.textAlign="left";Q.fillText(K,G+2+left_offset,C+8)}else{Q.textAlign="right";Q.fillText(K,D-2+left_offset,C+8)}Q.fillStyle=block_color}var M=S+" / "+N;if(P>T&&Q.measureText(M).width<(G-D)){Q.fillStyle="white";Q.textAlign="center";Q.fillText(M,left_offset+D+(G-D)/2,C+8);Q.fillStyle=block_color}}}});var s=function(A,C,x,z,B,y){n.call(this,A,C,x,z,B);this.ref_seq=y};s.prototype.default_prefs=t({},n.prototype.default_prefs,{show_insertions:false});t(s.prototype,n.prototype,{get_row_height:function(){var x,y=this.mode;if(y==="Dense"){x=d}else{if(y==="Squish"){x=l}else{x=v;if(this.prefs.show_insertions){x*=2}}}return x},draw_read:function(T,O,K,Y,z,S,H,E,D){T.textAlign="center";var R=this,y=[Y,z],N=0,U=0,Q=0;ref_seq=this.ref_seq,char_width_px=T.canvas.manager.char_width_px;var ad=[];if((O==="Pack"||this.mode==="Auto")&&E!==undefined&&K>char_width_px){Q=Math.round(K/2)}if(!H){H=[[0,E.length]]}for(var L=0,W=H.length;L<W;L++){var I=H[L],A="MIDNSHP=X"[I[0]],M=I[1];if(A==="H"||A==="S"){N-=M}var F=S+N,ac=Math.floor(Math.max(0,(F-Y)*K)),G=Math.floor(Math.max(0,(F+M-Y)*K));if(ac===G){G+=1}switch(A){case"H":break;case"S":case"M":case"=":if(is_overlap([F,F+M],y)){var P=E.slice(U,U+M);if(Q>0){T.fillStyle=this.prefs.block_color;T.fillRect(ac-Q,D+1,G-ac,9);T.fillStyle=g;for(var aa=0,x=P.length;aa<x;aa++){if(this.prefs.show_differences&&ref_seq){var J=ref_seq[F-Y+aa];if(!J||J.toLowerCase()===P[aa].toLowerCase()){continue}}if(F+aa>=Y&&F+aa<=z){var ab=Math.floor(Math.max(0,(F+aa-Y)*K));T.fillText(P[aa],ab,D+9)}}}else{T.fillStyle=this.prefs.block_color;T.fillRect(ac,D+4,G-ac,e)}}U+=M;N+=M;break;case"N":T.fillStyle=g;T.fillRect(ac-Q,D+5,G-ac,1);N+=M;break;case"D":T.fillStyle="red";T.fillRect(ac-Q,D+4,G-ac,3);N+=M;break;case"P":break;case"I":var X=ac-Q;if(is_overlap([F,F+M],y)){var P=E.slice(U,U+M);if(this.prefs.show_insertions){var C=ac-(G-ac)/2;if((O==="Pack"||this.mode==="Auto")&&E!==undefined&&K>char_width_px){T.fillStyle="yellow";T.fillRect(C-Q,D-9,G-ac,9);ad[ad.length]={type:"triangle",data:[X,D+4,5]};T.fillStyle=g;switch(seq_tile_overlap){case (OVERLAP_START):P=P.slice(Y-F);break;case (OVERLAP_END):P=P.slice(0,F-z);break;case (CONTAINED_BY):break;case (CONTAINS):P=P.slice(Y-F,F-z);break}for(var aa=0,x=P.length;aa<x;aa++){var ab=Math.floor(Math.max(0,(F+aa-Y)*K));T.fillText(P[aa],ab-(G-ac)/2,D)}}else{T.fillStyle="yellow";T.fillRect(C,D+(this.mode!=="Dense"?2:5),G-ac,(O!=="Dense"?e:r))}}else{if((O==="Pack"||this.mode==="Auto")&&E!==undefined&&K>char_width_px){ad[ad.length]={type:"text",data:[P.length,X,D+9]}}else{}}}U+=M;break;case"X":U+=M;break}}T.fillStyle="yellow";var Z,B,ae;for(var V=0;V<ad.length;V++){Z=ad[V];B=Z.type;ae=Z.data;if(B==="text"){T.save();T.font="bold "+T.font;T.fillText(ae[0],ae[1],ae[2]);T.restore()}else{if(B=="triangle"){p(T,ae[0],ae[1],ae[2])}}}},draw_element:function(Q,L,D,A,T,y,H,R,O){var G=D[0],P=D[1],z=D[2],I=D[3],C=Math.floor(Math.max(0,(P-T)*H)),E=Math.ceil(Math.min(O,Math.max(0,(z-T)*H))),B=(L==="Dense"?0:(0+A))*R,U=this.prefs.block_color,F=this.prefs.label_color,N=0;if((L==="Pack"||this.mode==="Auto")&&H>Q.canvas.manager.char_width_px){var N=Math.round(H/2)}Q.fillStyle=U;if(D[5] instanceof Array){var M=Math.floor(Math.max(0,(D[4][0]-T)*H)),K=Math.ceil(Math.min(O,Math.max(0,(D[4][1]-T)*H))),J=Math.floor(Math.max(0,(D[5][0]-T)*H)),x=Math.ceil(Math.min(O,Math.max(0,(D[5][1]-T)*H)));if(D[4][1]>=T&&D[4][0]<=y&&D[4][2]){this.draw_read(Q,L,H,T,y,D[4][0],D[4][2],D[4][3],B)}if(D[5][1]>=T&&D[5][0]<=y&&D[5][2]){this.draw_read(Q,L,H,T,y,D[5][0],D[5][2],D[5][3],B)}if(J>K){Q.fillStyle=g;o(Q,K-N,B+5,J-N,B+5)}}else{Q.fillStyle=U;this.draw_read(Q,L,H,T,y,P,D[4],D[5],B)}if(L==="Pack"&&P>T){Q.fillStyle=this.prefs.label_color;var S=1;if(S===0&&C-Q.measureText(I).width<0){Q.textAlign="left";Q.fillText(I,E+k-N,B+8)}else{Q.textAlign="right";Q.fillText(I,C-k-N,B+8)}Q.fillStyle=U}}});w.SummaryTreePainter=u;w.LinePainter=c;w.LinkedFeaturePainter=q;w.ReadPainter=s;w.VariantPainter=b};(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 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 trackster_module=function(f,T){var n=f("class").extend,p=f("slotting"),I=f("painters");var Z=function(aa,ab){this.document=aa;this.default_font=ab!==undefined?ab:"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")};n(Z.prototype,{load_pattern:function(aa,ae){var ab=this.patterns,ac=this.dummy_context,ad=new Image();ad.src=image_path+ae;ad.onload=function(){ab[aa]=ac.createPattern(ad,"repeat")}},get_pattern:function(aa){return this.patterns[aa]},new_canvas:function(){var aa=this.document.createElement("canvas");if(window.G_vmlCanvasManager){G_vmlCanvasManager.initElement(aa)}aa.manager=this;return aa}});var C=function(aa,ab){aa.bind("drag",{handle:ab,relative:true},function(af,ag){var ae=$(this).parent();var ad=ae.children();var ac;for(ac=0;ac<ad.length;ac++){if(ag.offsetY<$(ad.get(ac)).position().top){break}}if(ac===ad.length){if(this!==ad.get(ac-1)){ae.append(this)}}else{if(this!==ad.get(ac)){$(this).insertBefore(ad.get(ac))}}}).bind("dragstart",function(){$(this).css({"border-top":"1px solid blue","border-bottom":"1px solid blue"})}).bind("dragend",function(){$(this).css("border","0px")})};T.sortable=C;var D=9,A=18,O=D+2,w=100,F=12000,M=200,z=5,s=10,H=5000,t=100,m="There was an error in indexing this dataset. ",G="A converter for this dataset is not installed. Please check your datatypes_conf.xml file.",B="No data for this chrom/contig.",q="Currently indexing... please wait",v="Tool cannot be rerun: ",a="Loading data...",U="Ready for display",d=10,r=5,y=5;function u(aa){return Math.round(aa*1000)/1000}var c=function(aa){this.num_elements=aa;this.clear()};n(c.prototype,{get:function(ab){var aa=this.key_ary.indexOf(ab);if(aa!==-1){if(this.obj_cache[ab].stale){this.key_ary.splice(aa,1);delete this.obj_cache[ab]}else{this.move_key_to_end(ab,aa)}}return this.obj_cache[ab]},set:function(ab,ac){if(!this.obj_cache[ab]){if(this.key_ary.length>=this.num_elements){var aa=this.key_ary.shift();delete this.obj_cache[aa]}this.key_ary.push(ab)}this.obj_cache[ab]=ac;return ac},move_key_to_end:function(ab,aa){this.key_ary.splice(aa,1);this.key_ary.push(ab)},clear:function(){this.obj_cache={};this.key_ary=[]},size:function(){return this.key_ary.length}});var N=function(ab,aa,ac){c.call(this,ab);this.track=aa;this.subset=(ac!==undefined?ac:true)};n(N.prototype,c.prototype,{load_data:function(ai,aj,ae,ah,ab,ag){var ad={chrom:ai,low:aj,high:ae,mode:ah,resolution:ab,dataset_id:this.track.dataset_id,hda_ldda:this.track.hda_ldda};$.extend(ad,ag);if(this.track.filters_manager){var ak=[];var aa=this.track.filters_manager.filters;for(var af=0;af<aa.length;af++){ak[ak.length]=aa[af].name}ad.filter_cols=JSON.stringify(ak)}var ac=this;return $.getJSON(this.track.data_url,ad,function(al){ac.set_data(aj,ae,ah,al)})},get_data:function(ac,aa,af,ag,ab,ae){var ad=this.get(this.gen_key(aa,af,ag));if(ad){return ad}ad=this.load_data(ac,aa,af,ag,ab,ae);this.set_data(aa,af,ag,ad);return ad},set_data:function(ab,ac,ad,aa){return this.set(this.gen_key(ab,ac,ad),aa)},gen_key:function(aa,ac,ad){var ab=aa+"_"+ac+"_"+ad;return ab},split_key:function(aa){return aa.split("_")}});var E=function(ab,aa,ac){N.call(this,ab,aa,ac)};n(E.prototype,N.prototype,c.prototype,{load_data:function(ac,aa,ae,af,ab,ad){if(ab>1){return}return N.prototype.load_data.call(this,ac,aa,ae,af,ab,ad)}});var Y=function(aa,ad,ac,ab,ae){this.container=aa;this.chrom=null;this.vis_id=ac;this.dbkey=ab;this.title=ad;this.tracks=[];this.label_tracks=[];this.max_low=0;this.max_high=0;this.num_tracks=0;this.track_id_counter=0;this.zoom_factor=3;this.min_separation=30;this.has_changes=false;this.init(ae);this.canvas_manager=new Z(aa.get(0).ownerDocument);this.reset()};n(Y.prototype,{init:function(ad){var ac=this.container,aa=this;this.top_container=$("<div/>").addClass("top-container").appendTo(ac);this.content_div=$("<div/>").addClass("content").css("position","relative").appendTo(ac);this.bottom_container=$("<div/>").addClass("bottom-container").appendTo(ac);this.top_labeltrack=$("<div/>").addClass("top-labeltrack").appendTo(this.top_container);this.viewport_container=$("<div/>").addClass("viewport-container").addClass("viewport-container").appendTo(this.content_div);this.intro_div=$("<div/>").addClass("intro").text("Select a chrom from the dropdown below").hide();this.nav_labeltrack=$("<div/>").addClass("nav-labeltrack").appendTo(this.bottom_container);this.nav_container=$("<div/>").addClass("nav-container").prependTo(this.top_container);this.nav=$("<div/>").addClass("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 href='javascript:void(0);'>Close Overview</a>").addClass("overview-close").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 ab=function(ae){if(ae.type==="focusout"||(ae.keyCode||ae.which)===13||(ae.keyCode||ae.which)===27){if((ae.keyCode||ae.which)!==27){aa.go_to($(this).val())}$(this).hide();$(this).val("");aa.location_span.show();aa.chrom_select.show()}};this.nav_input=$("<input/>").addClass("nav-input").hide().bind("keyup focusout",ab).appendTo(this.nav_controls);this.location_span=$("<span/>").addClass("location").appendTo(this.nav_controls);this.location_span.bind("click",function(){aa.location_span.hide();aa.chrom_select.hide();aa.nav_input.val(aa.chrom+":"+aa.low+"-"+aa.high);aa.nav_input.css("display","inline-block");aa.nav_input.select();aa.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 id='zoom-out' />").click(function(){aa.zoom_out();aa.redraw()}).appendTo(this.nav_controls);this.zi_link=$("<a id='zoom-in' />").click(function(){aa.zoom_in();aa.redraw()}).appendTo(this.nav_controls);this.load_chroms({low:0},ad);this.chrom_select.bind("change",function(){aa.change_chrom(aa.chrom_select.val())});this.intro_div.show();this.content_div.bind("click",function(ae){$(this).find("input").trigger("blur")});this.content_div.bind("dblclick",function(ae){aa.zoom_in(ae.pageX,this.viewport_container)});this.overview_box.bind("dragstart",function(ae,af){this.current_x=af.offsetX}).bind("drag",function(ae,ag){var ah=ag.offsetX-this.current_x;this.current_x=ag.offsetX;var af=Math.round(ah/aa.viewport_container.width()*(aa.max_high-aa.max_low));aa.move_delta(-af)});this.overview_close.bind("click",function(){for(var af=0,ae=aa.tracks.length;af<ae;af++){aa.tracks[af].is_overview=false}$(this).siblings().filter("canvas").remove();$(this).parent().css("height",aa.overview_box.height());aa.overview_highlight.hide();$(this).hide()});this.viewport_container.bind("draginit",function(ae,af){if(ae.clientX>aa.viewport_container.width()-16){return false}}).bind("dragstart",function(ae,af){af.original_low=aa.low;af.current_height=ae.clientY;af.current_x=af.offsetX}).bind("drag",function(ag,ai){var ae=$(this);var aj=ai.offsetX-ai.current_x;var af=ae.scrollTop()-(ag.clientY-ai.current_height);ae.scrollTop(af);ai.current_height=ag.clientY;ai.current_x=ai.offsetX;var ah=Math.round(aj/aa.viewport_container.width()*(aa.high-aa.low));aa.move_delta(ah)}).bind("mousewheel",function(ag,ai,af,ae){if(af){var ah=Math.round(-af/aa.viewport_container.width()*(aa.high-aa.low));aa.move_delta(ah)}});this.top_labeltrack.bind("dragstart",function(ae,af){return $("<div />").css({height:aa.content_div.height()+aa.top_labeltrack.height()+aa.nav_labeltrack.height()+1,top:"0px",position:"absolute","background-color":"#ccf",opacity:0.5,"z-index":1000}).appendTo($(this))}).bind("drag",function(ai,aj){$(aj.proxy).css({left:Math.min(ai.pageX,aj.startX),width:Math.abs(ai.pageX-aj.startX)});var af=Math.min(ai.pageX,aj.startX)-aa.container.offset().left,ae=Math.max(ai.pageX,aj.startX)-aa.container.offset().left,ah=(aa.high-aa.low),ag=aa.viewport_container.width();aa.update_location(Math.round(af/ag*ah)+aa.low,Math.round(ae/ag*ah)+aa.low)}).bind("dragend",function(aj,ak){var af=Math.min(aj.pageX,ak.startX),ae=Math.max(aj.pageX,ak.startX),ah=(aa.high-aa.low),ag=aa.viewport_container.width(),ai=aa.low;aa.low=Math.round(af/ag*ah)+ai;aa.high=Math.round(ae/ag*ah)+ai;$(ak.proxy).remove();aa.redraw()});this.add_label_track(new X(this,this.top_labeltrack));this.add_label_track(new X(this,this.nav_labeltrack));$(window).bind("resize",function(){aa.resize_window()});$(document).bind("redraw",function(){aa.redraw()});this.reset();$(window).trigger("resize")},update_location:function(aa,ab){this.location_span.text(commatize(aa)+" - "+commatize(ab));this.nav_input.val(this.chrom+":"+commatize(aa)+"-"+commatize(ab))},load_chroms:function(ab,ac){ab.num=t;$.extend(ab,(this.vis_id!==undefined?{vis_id:this.vis_id}:{dbkey:this.dbkey}));var aa=this;$.ajax({url:chrom_url,data:ab,dataType:"json",success:function(ae){if(ae.chrom_info.length===0){alert("Invalid chromosome: "+ab.chrom);return}if(ae.reference){aa.add_label_track(new x(aa))}aa.chrom_data=ae.chrom_info;var ah='<option value="">Select Chrom/Contig</option>';for(var ag=0,ad=aa.chrom_data.length;ag<ad;ag++){var af=aa.chrom_data[ag].chrom;ah+='<option value="'+af+'">'+af+"</option>"}if(ae.prev_chroms){ah+='<option value="previous">Previous '+t+"</option>"}if(ae.next_chroms){ah+='<option value="next">Next '+t+"</option>"}aa.chrom_select.html(ah);if(ac){ac()}aa.chrom_start_index=ae.start_index},error:function(){alert("Could not load chroms for this dbkey:",aa.dbkey)}})},change_chrom:function(ae,ab,ag){if(!ae||ae==="None"){return}var ad=this;if(ae==="previous"){ad.load_chroms({low:this.chrom_start_index-t});return}if(ae==="next"){ad.load_chroms({low:this.chrom_start_index+t});return}var af=$.grep(ad.chrom_data,function(ai,aj){return ai.chrom===ae})[0];if(af===undefined){ad.load_chroms({chrom:ae},function(){ad.change_chrom(ae,ab,ag)});return}else{if(ae!==ad.chrom){ad.chrom=ae;if(!ad.chrom){ad.intro_div.show()}else{ad.intro_div.hide()}ad.chrom_select.val(ad.chrom);ad.max_high=af.len-1;ad.reset();ad.redraw(true);for(var ah=0,aa=ad.tracks.length;ah<aa;ah++){var ac=ad.tracks[ah];if(ac.init){ac.init()}}}if(ab!==undefined&&ag!==undefined){ad.low=Math.max(ab,0);ad.high=Math.min(ag,ad.max_high)}ad.reset_overview();ad.redraw()}},go_to:function(ae){var ai=this,aa,ad,ab=ae.split(":"),ag=ab[0],ah=ab[1];if(ah!==undefined){try{var af=ah.split("-");aa=parseInt(af[0].replace(/,/g,""),10);ad=parseInt(af[1].replace(/,/g,""),10)}catch(ac){return false}}ai.change_chrom(ag,aa,ad)},move_fraction:function(ac){var aa=this;var ab=aa.high-aa.low;this.move_delta(ac*ab)},move_delta:function(ac){var aa=this;var ab=aa.high-aa.low;if(aa.low-ac<aa.max_low){aa.low=aa.max_low;aa.high=aa.max_low+ab}else{if(aa.high-ac>aa.max_high){aa.high=aa.max_high;aa.low=aa.max_high-ab}else{aa.high-=ac;aa.low-=ac}}aa.redraw()},add_track:function(aa){aa.view=this;aa.track_id=this.track_id_counter;this.tracks.push(aa);if(aa.init){aa.init()}aa.container_div.attr("id","track_"+aa.track_id);C(aa.container_div,".draghandle");this.track_id_counter+=1;this.num_tracks+=1},add_label_track:function(aa){aa.view=this;this.label_tracks.push(aa)},remove_track:function(aa){this.has_changes=true;aa.container_div.fadeOut("slow",function(){$(this).remove()});delete this.tracks[this.tracks.indexOf(aa)];this.num_tracks-=1},reset:function(){this.low=this.max_low;this.high=this.max_high;this.viewport_container.find(".yaxislabel").remove()},redraw:function(ah){var ag=this.high-this.low,af=this.low,ab=this.high;if(af<this.max_low){af=this.max_low}if(ab>this.max_high){ab=this.max_high}if(this.high!==0&&ag<this.min_separation){ab=af+this.min_separation}this.low=Math.floor(af);this.high=Math.ceil(ab);this.resolution=Math.pow(z,Math.ceil(Math.log((this.high-this.low)/M)/Math.log(z)));this.zoom_res=Math.pow(s,Math.max(0,Math.ceil(Math.log(this.resolution,s)/Math.log(s))));var aa=(this.low/(this.max_high-this.max_low)*this.overview_viewport.width())||0;var ae=((this.high-this.low)/(this.max_high-this.max_low)*this.overview_viewport.width())||0;var ai=13;this.overview_box.css({left:aa,width:Math.max(ai,ae)}).show();if(ae<ai){this.overview_box.css("left",aa-(ai-ae)/2)}if(this.overview_highlight){this.overview_highlight.css({left:aa,width:ae})}this.update_location(this.low,this.high);if(!ah){for(var ac=0,ad=this.tracks.length;ac<ad;ac++){if(this.tracks[ac]&&this.tracks[ac].enabled){this.tracks[ac].draw()}}for(ac=0,ad=this.label_tracks.length;ac<ad;ac++){this.label_tracks[ac].draw()}}},zoom_in:function(ab,ac){if(this.max_high===0||this.high-this.low<this.min_separation){return}var ad=this.high-this.low,ae=ad/2+this.low,aa=(ad/this.zoom_factor)/2;if(ab){ae=ab/this.viewport_container.width()*(this.high-this.low)+this.low}this.low=Math.round(ae-aa);this.high=Math.round(ae+aa);this.redraw()},zoom_out:function(){if(this.max_high===0){return}var ab=this.high-this.low,ac=ab/2+this.low,aa=(ab*this.zoom_factor)/2;this.low=Math.round(ac-aa);this.high=Math.round(ac+aa);this.redraw()},resize_window:function(){this.viewport_container.height(this.container.height()-this.top_container.height()-this.bottom_container.height());this.nav_container.width(this.container.width());this.redraw()},reset_overview:function(){this.overview_viewport.find("canvas").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()}});var o=function(ac,ag){this.track=ac;this.name=ag.name;this.params=[];var an=ag.params;for(var ad=0;ad<an.length;ad++){var ai=an[ad],ab=ai.name,am=ai.label,ae=unescape(ai.html),ao=ai.value,ak=ai.type;if(ak==="number"){this.params[this.params.length]=new g(ab,am,ae,ao,ai.min,ai.max)}else{if(ak=="select"){this.params[this.params.length]=new K(ab,am,ae,ao)}else{console.log("WARNING: unrecognized tool parameter type:",ab,ak)}}}this.parent_div=$("<div/>").addClass("dynamic-tool").hide();this.parent_div.bind("drag",function(aq){aq.stopPropagation()}).bind("click",function(aq){aq.stopPropagation()}).bind("dblclick",function(aq){aq.stopPropagation()});var al=$("<div class='tool-name'>").appendTo(this.parent_div).text(this.name);var aj=this.params;var ah=this;$.each(this.params,function(ar,av){var au=$("<div>").addClass("param-row").appendTo(ah.parent_div);var aq=$("<div>").addClass("param-label").text(av.label).appendTo(au);var at=$("<div/>").addClass("slider").html(av.html).appendTo(au);at.find(":input").val(av.value);$("<div style='clear: both;'/>").appendTo(au)});this.parent_div.find("input").click(function(){$(this).select()});var ap=$("<div>").addClass("param-row").appendTo(this.parent_div);var af=$("<input type='submit'>").attr("value","Run on complete dataset").appendTo(ap);var aa=$("<input type='submit'>").attr("value","Run on visible region").css("margin-left","3em").appendTo(ap);var ah=this;aa.click(function(){ah.run_on_region()});af.click(function(){ah.run_on_dataset()})};n(o.prototype,{get_param_values_dict:function(){var aa={};this.parent_div.find(":input").each(function(){var ab=$(this).attr("name"),ac=$(this).val();aa[ab]=JSON.stringify(ac)});return aa},get_param_values:function(){var ab=[];var aa={};this.parent_div.find(":input").each(function(){var ac=$(this).attr("name"),ad=$(this).val();if(ac){ab[ab.length]=ad}});return ab},run_on_dataset:function(){var aa=this;aa.run({dataset_id:this.track.original_dataset_id,tool_id:aa.name},function(ab){show_modal(aa.name+" is Running",aa.name+" is running on the complete dataset. Tool outputs are in dataset's history.",{Close:hide_modal})})},run_on_region:function(){var aa={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},ac=this.track,ab=aa.tool_id+ac.tool_region_and_parameters_str(aa.chrom,aa.low,aa.high),ad;if(ac instanceof e){ad=new Q(ab,view,ac.hda_ldda,undefined,{},{},ac);ad.change_mode(ac.mode)}this.track.add_track(ad);ad.content_div.text("Starting job.");this.run(aa,function(ae){ad.dataset_id=ae.dataset_id;ad.content_div.text("Running job.");ad.init()})},run:function(ab,ac){$.extend(ab,this.get_param_values_dict());var aa=function(){$.getJSON(rerun_tool_url,ab,function(ad){if(ad==="no converter"){new_track.container_div.addClass("error");new_track.content_div.text(G)}else{if(ad.error){new_track.container_div.addClass("error");new_track.content_div.text(v+ad.message)}else{if(ad==="pending"){new_track.container_div.addClass("pending");new_track.content_div.text("Converting input data so that it can be easily reused.");setTimeout(aa,2000)}else{ac(ad)}}}})};aa()}});var K=function(ab,aa,ac,ad){this.name=ab;this.label=aa;this.html=ac;this.value=ad};var g=function(ac,ab,ae,af,ad,aa){K.call(this,ac,ab,ae,af);this.min=ad;this.max=aa};var h=function(ab,aa,ac,ad){this.name=ab;this.index=aa;this.tool_id=ac;this.tool_exp_name=ad};var R=function(ab,aa,ac,ad){h.call(this,ab,aa,ac,ad);this.low=-Number.MAX_VALUE;this.high=Number.MAX_VALUE;this.min=Number.MAX_VALUE;this.max=-Number.MAX_VALUE;this.slider=null;this.slider_label=null};n(R.prototype,{applies_to:function(aa){if(aa.length>this.index){return true}return false},keep:function(aa){if(!this.applies_to(aa)){return true}var ab=parseInt(aa[this.index]);return(isNaN(ab)||(ab>=this.low&&ab<=this.high))},update_attrs:function(ab){var aa=false;if(!this.applies_to(ab)){return aa}if(ab[this.index]<this.min){this.min=Math.floor(ab[this.index]);aa=true}if(ab[this.index]>this.max){this.max=Math.ceil(ab[this.index]);aa=true}return aa},update_ui_elt:function(){var ac=function(af,ad){var ae=ad-af;return(ae<=2?0.01:1)};var ab=this.slider.slider("option","min"),aa=this.slider.slider("option","max");if(this.min<ab||this.max>aa){this.slider.slider("option","min",this.min);this.slider.slider("option","max",this.max);this.slider.slider("option","step",ac(this.min,this.max));this.slider.slider("option","values",[this.min,this.max])}}});var W=function(ac,al){this.track=ac;this.filters=[];for(var ag=0;ag<al.length;ag++){var aa=al[ag],ab=aa.name,ak=aa.type,ai=aa.index,an=aa.tool_id,ad=aa.tool_exp_name;if(ak==="int"||ak==="float"){this.filters[ag]=new R(ab,ai,an,ad)}else{console.log("ERROR: unsupported filter: ",ab,ak)}}var aj=function(ao,ap,aq){ao.click(function(){var ar=ap.text();max=parseFloat(aq.slider("option","max")),input_size=(max<=1?4:max<=1000000?max.toString().length:6),multi_value=false;if(aq.slider("option","values")){input_size=2*input_size+1;multi_value=true}ap.text("");$("<input type='text'/>").attr("size",input_size).attr("maxlength",input_size).attr("value",ar).appendTo(ap).focus().select().click(function(at){at.stopPropagation()}).blur(function(){$(this).remove();ap.text(ar)}).keyup(function(ax){if(ax.keyCode===27){$(this).trigger("blur")}else{if(ax.keyCode===13){var av=aq.slider("option","min"),at=aq.slider("option","max"),aw=function(ay){return(isNaN(ay)||ay>at||ay<av)},au=$(this).val();if(!multi_value){au=parseFloat(au);if(aw(au)){alert("Parameter value must be in the range ["+av+"-"+at+"]");return $(this)}}else{au=au.split("-");au=[parseFloat(au[0]),parseFloat(au[1])];if(aw(au[0])||aw(au[1])){alert("Parameter value must be in the range ["+av+"-"+at+"]");return $(this)}}aq.slider((multi_value?"values":"value"),au)}}})})};this.parent_div=$("<div/>").addClass("filters").hide();this.parent_div.bind("drag",function(ao){ao.stopPropagation()}).bind("click",function(ao){ao.stopPropagation()}).bind("dblclick",function(ao){ao.stopPropagation()}).bind("keydown",function(ao){ao.stopPropagation()});var ae=this;$.each(this.filters,function(av,ap){var ar=$("<div/>").addClass("slider-row").appendTo(ae.parent_div);var ao=$("<div/>").addClass("slider-label").appendTo(ar);var ax=$("<span/>").addClass("slider-name").text(ap.name+" ").appendTo(ao);var aq=$("<span/>");var at=$("<span/>").addClass("slider-value").appendTo(ao).append("[").append(aq).append("]");var aw=$("<div/>").addClass("slider").appendTo(ar);ap.control_element=$("<div/>").attr("id",ap.name+"-filter-control").appendTo(aw);var au=[0,0];ap.control_element.slider({range:true,min:Number.MAX_VALUE,max:-Number.MIN_VALUE,values:[0,0],slide:function(ay,az){au=az.values;aq.text(az.values[0]+"-"+az.values[1]);setTimeout(function(){if(az.values[0]==au[0]&&az.values[1]==au[1]){var aA=az.values;aq.text(aA[0]+"-"+aA[1]);ap.low=aA[0];ap.high=aA[1];ae.track.draw(true,true)}},50)},change:function(ay,az){ap.control_element.slider("option","slide").call(ap.control_element,ay,az)}});ap.slider=ap.control_element;ap.slider_label=aq;aj(at,aq,ap.control_element);$("<div style='clear: both;'/>").appendTo(ar)});if(this.filters.length!=0){var am=$("<div>").addClass("param-row").appendTo(this.parent_div);var ah=$("<input type='submit'>").attr("value","Run on complete dataset").appendTo(am);var af=this;ah.click(function(){af.run_on_dataset()})}};n(W.prototype,{reset_filters:function(){for(var aa=0;aa<this.filters.length;aa++){filter=this.filters[aa];filter.slider.slider("option","values",[filter.min,filter.max])}},run_on_dataset:function(){var ai=function(am,ak,al){if(!(ak in am)){am[ak]=al}return am[ak]};var ac={},aa,ab,ad;for(var ae=0;ae<this.filters.length;ae++){aa=this.filters[ae];if(aa.tool_id){if(aa.min!=aa.low){ab=ai(ac,aa.tool_id,[]);ab[ab.length]=aa.tool_exp_name+" >= "+aa.low}if(aa.max!=aa.high){ab=ai(ac,aa.tool_id,[]);ab[ab.length]=aa.tool_exp_name+" <= "+aa.high}}}var ag=[];for(var aj in ac){ag[ag.length]=[aj,ac[aj]]}var ah=ag.length;(function af(aq,an){var al=an[0],am=al[0],ap=al[1],ao="("+ap.join(") and (")+")",ak={cond:ao,input:aq,target_dataset_id:aq,tool_id:am},an=an.slice(1);$.getJSON(run_tool_url,ak,function(ar){if(ar.error){show_modal("Filter Dataset","Error running tool "+am,{Close:hide_modal})}else{if(an.length===0){show_modal("Filtering Dataset","Filter(s) are running on the complete dataset. Outputs are in dataset's history.",{Close:hide_modal})}else{af(ar.dataset_id,an)}}})})(this.track.dataset_id,ag)}});var V=function(aa){this.track=aa.track;this.params=aa.params;this.values={};if(aa.saved_values){this.restore_values(aa.saved_values)}this.onchange=aa.onchange};n(V.prototype,{restore_values:function(aa){var ab=this;$.each(this.params,function(ac,ad){if(aa[ad.key]!==undefined){ab.values[ad.key]=aa[ad.key]}else{ab.values[ad.key]=ad.default_value}})},build_form:function(){var ab=this;var aa=$("<div />");$.each(this.params,function(af,ad){if(!ad.hidden){var ac="param_"+af;var ak=$("<div class='form-row' />").appendTo(aa);ak.append($("<label />").attr("for",ac).text(ad.label+":"));if(ad.type==="bool"){ak.append($('<input type="checkbox" />').attr("id",ac).attr("name",ac).attr("checked",ab.values[ad.key]))}else{if(ad.type==="color"){var ah=ab.values[ad.key];var ag=$("<input />").attr("id",ac).attr("name",ac).val(ah);var ai=$("<div class='tipsy tipsy-north' style='position: absolute;' />").hide();var ae=$("<div style='background-color: black; padding: 10px;'></div>").appendTo(ai);var aj=$("<div/>").appendTo(ae).farbtastic({width:100,height:100,callback:ag,color:ah});$("<div />").append(ag).append(ai).appendTo(ak).bind("click",function(al){ai.css({left:$(this).position().left+($(ag).width()/2)-60,top:$(this).position().top+$(this.height)}).show();$(document).bind("click.color-picker",function(){ai.hide();$(document).unbind("click.color-picker")});al.stopPropagation()})}else{ak.append($("<input />").attr("id",ac).attr("name",ac).val(ab.values[ad.key]))}}}});return aa},update_from_form:function(aa){var ac=this;var ab=false;$.each(this.params,function(ad,af){if(!af.hidden){var ag="param_"+ad;var ae=aa.find("#"+ag).val();if(af.type==="float"){ae=parseFloat(ae)}else{if(af.type==="int"){ae=parseInt(ae)}else{if(af.type==="bool"){ae=aa.find("#"+ag).is(":checked")}}}if(ae!==ac.values[af.key]){ac.values[af.key]=ae;ab=true}}});if(ab){this.onchange()}}});var b=function(ac,ab,aa){this.index=ac;this.resolution=ab;this.canvas=$("<div class='track-tile'/>").append(aa);this.stale=false};var l=function(ac,ab,aa,ad){b.call(this,ac,ab,aa);this.max_val=ad};var L=function(ac,ab,aa,ad){b.call(this,ac,ab,aa);this.message=ad};var j=function(ab,aa,ae,ac,ad){this.name=ab;this.view=aa;this.parent_element=ae;this.data_url=(ac?ac:default_data_url);this.data_url_extra_params={};this.data_query_wait=(ad?ad:H);this.dataset_check_url=converted_datasets_state_url;this.container_div=$("<div />").addClass("track").css("position","relative");if(!this.hidden){this.header_div=$("<div class='track-header' />").appendTo(this.container_div);if(this.view.editor){this.drag_div=$("<div class='draghandle' />").appendTo(this.header_div)}this.name_div=$("<div class='menubutton popup' />").appendTo(this.header_div);this.name_div.text(this.name);this.name_div.attr("id",this.name.replace(/\s+/g,"-").replace(/[^a-zA-Z0-9\-]/g,"").toLowerCase())}this.content_div=$("<div class='track-content'>").appendTo(this.container_div);this.parent_element.append(this.container_div)};n(j.prototype,{get_type:function(){if(this instanceof X){return"LabelTrack"}else{if(this instanceof x){return"ReferenceTrack"}else{if(this instanceof k){return"LineTrack"}else{if(this instanceof S){return"ReadTrack"}else{if(this instanceof Q){return"ToolDataFeatureTrack"}else{if(this instanceof P){return"VcfTrack"}else{if(this instanceof e){return"FeatureTrack"}}}}}}}return""},init:function(){var aa=this;aa.enabled=false;aa.tile_cache.clear();aa.data_cache.clear();aa.initial_canvas=undefined;aa.content_div.css("height","auto");aa.container_div.removeClass("nodata error pending");if(!aa.dataset_id){return}$.getJSON(converted_datasets_state_url,{hda_ldda:aa.hda_ldda,dataset_id:aa.dataset_id,chrom:aa.view.chrom},function(ab){if(!ab||ab==="error"||ab.kind==="error"){aa.container_div.addClass("error");aa.content_div.text(m);if(ab.message){var ad=aa.view.tracks.indexOf(aa);var ac=$(" <a href='javascript:void(0);'></a>").text("View error").bind("click",function(){show_modal("Trackster Error","<pre>"+ab.message+"</pre>",{Close:hide_modal})});aa.content_div.append(ac)}}else{if(ab==="no converter"){aa.container_div.addClass("error");aa.content_div.text(G)}else{if(ab==="no data"||(ab.data!==undefined&&(ab.data===null||ab.data.length===0))){aa.container_div.addClass("nodata");aa.content_div.text(B)}else{if(ab==="pending"){aa.container_div.addClass("pending");aa.content_div.text(q);setTimeout(function(){aa.init()},aa.data_query_wait)}else{if(ab.status==="data"){if(ab.valid_chroms){aa.valid_chroms=ab.valid_chroms;aa.make_name_popup_menu()}aa.content_div.text(U);if(aa.view.chrom){aa.content_div.text("");aa.content_div.css("height",aa.height_px+"px");aa.enabled=true;$.when(aa.predraw_init()).done(function(){aa.container_div.removeClass("nodata error pending");aa.draw()})}}}}}}})},predraw_init:function(){},update_name:function(aa){this.old_name=this.name;this.name=aa;this.name_div.text(this.name)},revert_name:function(){this.name=this.old_name;this.name_div.text(this.name)}});var J=function(ah,af,ai){var ab=this,aj=ab.view;this.filters_manager=(ah!==undefined?new W(this,ah):undefined);this.filters_available=false;this.filters_visible=false;this.tool=(af!==undefined&&obj_length(af)>0?new o(this,af):undefined);this.parent_track=ai;this.child_tracks=[];if(ab.hidden){return}if(this.parent_track){this.header_div.find(".draghandle").removeClass("draghandle").addClass("child-track-icon").addClass("icon-button");this.parent_element.addClass("child-track");this.tool=undefined}ab.child_tracks_container=$("<div/>").addClass("child-tracks-container").hide();ab.container_div.append(ab.child_tracks_container);if(this.filters_manager){this.filters_div=this.filters_manager.parent_div;this.header_div.after(this.filters_div)}if(this.tool){this.dynamic_tool_div=this.tool.parent_div;this.header_div.after(this.dynamic_tool_div)}if(ab.display_modes!==undefined){if(ab.mode_div===undefined){ab.mode_div=$("<div class='right-float menubutton popup' />").appendTo(ab.header_div);var ac=(ab.track_config&&ab.track_config.values.mode?ab.track_config.values.mode:ab.display_modes[0]);ab.mode=ac;ab.mode_div.text(ac);var aa={};for(var ad=0,ag=ab.display_modes.length;ad<ag;ad++){var ae=ab.display_modes[ad];aa[ae]=function(ak){return function(){ab.change_mode(ak)}}(ae)}make_popupmenu(ab.mode_div,aa)}else{ab.mode_div.hide()}}this.make_name_popup_menu()};n(J.prototype,j.prototype,{change_mode:function(ab){var aa=this;aa.mode_div.text(ab);aa.mode=ab;aa.track_config.values.mode=ab;aa.tile_cache.clear();aa.draw()},make_name_popup_menu:function(){var ab=this;var aa={};aa["Edit configuration"]=function(){var ah=function(){hide_modal();$(window).unbind("keypress.check_enter_esc")},af=function(){ab.track_config.update_from_form($(".dialog-box"));hide_modal();$(window).unbind("keypress.check_enter_esc")},ag=function(ai){if((ai.keyCode||ai.which)===27){ah()}else{if((ai.keyCode||ai.which)===13){af()}}};$(window).bind("keypress.check_enter_esc",ag);show_modal("Configure Track",ab.track_config.build_form(),{Cancel:ah,OK:af})};if(ab.filters_available>0){var ae=(ab.filters_div.is(":visible")?"Hide filters":"Show filters");aa[ae]=function(){ab.filters_visible=(ab.filters_div.is(":visible"));if(ab.filters_visible){ab.filters_manager.reset_filters()}ab.filters_div.toggle();ab.make_name_popup_menu()}}if(ab.tool){var ae=(ab.dynamic_tool_div.is(":visible")?"Hide tool":"Show tool");aa[ae]=function(){if(!ab.dynamic_tool_div.is(":visible")){ab.update_name(ab.name+ab.tool_region_and_parameters_str())}else{menu_option_text="Show dynamic tool";ab.revert_name()}ab.dynamic_tool_div.toggle();ab.make_name_popup_menu()}}if(ab.valid_chroms){aa["List chrom/contigs with data"]=function(){show_modal("Chrom/contigs with data","<p>"+ab.valid_chroms.join("<br/>")+"</p>",{Close:function(){hide_modal()}})}}var ac=view;var ad=function(){$("#no-tracks").show()};if(this.parent_track){ac=this.parent_track;ad=function(){}}aa.Remove=function(){ac.remove_track(ab);if(ac.num_tracks===0){ad()}};make_popupmenu(ab.name_div,aa)},draw:function(aa,ac){if(!this.dataset_id){return}var au=this.view.low,ag=this.view.high,ai=ag-au,ak=this.view.container.width(),ae=ak/ai,al=this.view.resolution,ad=$("<div style='position: relative;'></div>"),am=function(aw,ax,av){return aw+"_"+ax+"_"+av};if(!ac){this.content_div.children().remove()}this.content_div.append(ad);this.max_height=0;var ao=Math.floor(au/al/M);var af=[];var ap=0;while((ao*M*al)<ag){var at=am(ak,ae,ao);var ah=this.tile_cache.get(at);var aq=ao*M*this.view.resolution;var ab=aq+M*this.view.resolution;if(!aa&&ah){af[af.length]=ah;this.show_tile(ah,ad,aq,ab,ae)}else{this.delayed_draw(aa,at,ao,al,ad,ae,af)}ao+=1;ap++}var aj=this;var ar=setInterval(function(){if(af.length===ap){clearInterval(ar);if(ac){var aA=aj.content_div.children();var aB=false;for(var az=aA.length-1,aF=0;az>=aF;az--){var ay=$(aA[az]);if(aB){ay.remove()}else{if(ay.children().length!==0){aB=true}}}}if(aj instanceof e&&aj.mode=="Histogram"){var aE=-1;for(var az=0;az<af.length;az++){var aH=af[az].max_val;if(aH>aE){aE=aH}}for(var az=0;az<af.length;az++){if(af[az].max_val!==aE){var aG=af[az];aG.canvas.remove();aj.delayed_draw(true,am(ak,ae,aG.index),aG.index,aG.resolution,ad,ae,[],{max:aE})}}}if(aj.filters_manager){var ax=aj.filters_manager.filters;for(var aD=0;aD<ax.length;aD++){ax[aD].update_ui_elt()}var aC=false;if(aj.example_feature){for(var aD=0;aD<ax.length;aD++){if(ax[aD].applies_to(aj.example_feature)){aC=true;break}}}if(aj.filters_available!==aC){aj.filters_available=aC;if(!aj.filters_available){aj.filters_div.hide()}aj.make_name_popup_menu()}}var av=false;for(var aw=0;aw<af.length;aw++){if(af[aw].message){av=true;break}}if(av){for(var aw=0;aw<af.length;aw++){aG=af[aw];if(!aG.message){aG.canvas.css("padding-top",A)}}}}},50);for(var an=0;an<this.child_tracks.length;an++){this.child_tracks[an].draw(aa,ac)}},delayed_draw:function(ab,ai,ac,ae,aj,am,ak,af){var ad=this,ag=ac*M*ae,al=ag+M*ae;var ah=function(av,an,ap,ao,at,au,aq){var ar=ad.draw_tile(an,ap,ao,au,aq);ad.tile_cache.set(ai,ar);if(ar===undefined){return}ad.show_tile(ar,at,ag,al,au);ak[ak.length]=ar};var aa=setTimeout(function(){if(ag<=ad.view.high&&al>=ad.view.low){var an=(ab?undefined:ad.tile_cache.get(ai));if(an){ad.show_tile(an,aj,ag,al,am);ak[ak.length]=an}else{$.when(ad.data_cache.get_data(view.chrom,ag,al,ad.mode,ae,ad.data_url_extra_params)).then(function(ao){n(ao,af);if(view.reference_track&&am>view.canvas_manager.char_width_px){$.when(view.reference_track.data_cache.get_data(view.chrom,ag,al,ad.mode,ae,view.reference_track.data_url_extra_params)).then(function(ap){ah(aa,ao,ae,ac,aj,am,ap)})}else{ah(aa,ao,ae,ac,aj,am)}})}}},50)},show_tile:function(ah,aj,ae,ak,am){var ab=this,aa=ah.canvas,af=aa;if(ah.message){var al=$("<div/>"),ai=$("<div/>").addClass("tile-message").text(ah.message).css({height:A-1,width:ah.canvas.width}).appendTo(al),ag=$("<button/>").text("Show more").css("margin-left","0.5em").appendTo(ai);al.append(aa);af=al;ag.click(function(){var an=ab.data_cache.get_data(ab.view.chrom,ae,ak,ab.mode,ah.resolution);an.stale=true;ah.stale=true;ab.data_cache.get_data(ab.view.chrom,ae,ak,ab.mode,ah.resolution,{max_vals:an.data.length*2});ab.draw()}).dblclick(function(an){an.stopPropagation()})}var ad=this.view.high-this.view.low,ac=(ae-this.view.low)*am;if(this.left_offset){ac-=this.left_offset}af.css({position:"absolute",top:0,left:ac,height:""});aj.append(af);ab.max_height=Math.max(ab.max_height,af.height());ab.content_div.css("height",ab.max_height+"px");aj.children().css("height",ab.max_height+"px")},set_overview:function(){var aa=this.view;if(this.initial_canvas&&this.is_overview){aa.overview_close.show();aa.overview_viewport.append(this.initial_canvas);aa.overview_highlight.show().height(this.initial_canvas.height());aa.overview_viewport.height(this.initial_canvas.height()+aa.overview_box.height())}$(window).trigger("resize")},tool_region_and_parameters_str:function(ac,aa,ad){var ab=this,ae=(ac!==undefined&&aa!==undefined&&ad!==undefined?ac+":"+aa+"-"+ad:"all");return" - region=["+ae+"], parameters=["+ab.tool.get_param_values().join(", ")+"]"},add_track:function(aa){aa.track_id=this.track_id+"_"+this.child_tracks.length;aa.container_div.attr("id","track_"+aa.track_id);this.child_tracks_container.append(aa.container_div);C(aa.container_div,".child-track-icon");if(!$(this.child_tracks_container).is(":visible")){this.child_tracks_container.show()}this.child_tracks.push(aa);this.view.has_changes=true},remove_track:function(aa){aa.container_div.fadeOut("slow",function(){$(this).remove()})}});var X=function(aa,ab){this.hidden=true;j.call(this,null,aa,ab);this.container_div.addClass("label-track")};n(X.prototype,j.prototype,{draw:function(){var ac=this.view,ad=ac.high-ac.low,ag=Math.floor(Math.pow(10,Math.floor(Math.log(ad)/Math.log(10)))),aa=Math.floor(ac.low/ag)*ag,ae=this.view.container.width(),ab=$("<div style='position: relative; height: 1.3em;'></div>");while(aa<ac.high){var af=(aa-ac.low)/ad*ae;ab.append($("<div class='label'>"+commatize(aa)+"</div>").css({position:"absolute",left:af-1}));aa+=ag}this.content_div.children(":first").remove();this.content_div.append(ab)}});var x=function(aa){this.hidden=true;j.call(this,null,aa,aa.top_labeltrack);J.call(this);aa.reference_track=this;this.left_offset=200;this.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:aa.dbkey};this.data_cache=new E(y,this,false);this.tile_cache=new c(r)};n(x.prototype,J.prototype,{draw_tile:function(ai,af,ab,ak){var ae=this,ac=M*af;if(ak>this.view.canvas_manager.char_width_px){if(ai===null){ae.content_div.css("height","0px");return}var ad=this.view.canvas_manager.new_canvas();var aj=ad.getContext("2d");ad.width=Math.ceil(ac*ak+ae.left_offset);ad.height=ae.height_px;aj.font=aj.canvas.manager.default_font;aj.textAlign="center";for(var ag=0,ah=ai.length;ag<ah;ag++){var aa=Math.round(ag*ak);aj.fillText(ai[ag],aa+ae.left_offset,10)}return new b(ab,af,ad)}this.content_div.css("height","0px")}});var k=function(ae,ac,af,aa,ad){var ab=this;this.display_modes=["Histogram","Line","Filled","Intensity"];this.mode="Histogram";j.call(this,ae,ac,ac.viewport_container);J.call(this);this.min_height_px=16;this.max_height_px=400;this.height_px=80;this.hda_ldda=af;this.dataset_id=aa;this.original_dataset_id=aa;this.data_cache=new N(y,this);this.tile_cache=new c(r);this.track_config=new V({track:this,params:[{key:"color",label:"Color",type:"color",default_value:"black"},{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:this.height_px,hidden:true}],saved_values:ad,onchange:function(){ab.vertical_range=ab.prefs.max_value-ab.prefs.min_value;$("#linetrack_"+ab.track_id+"_minval").text(ab.prefs.min_value);$("#linetrack_"+ab.track_id+"_maxval").text(ab.prefs.max_value);ab.tile_cache.clear();ab.draw()}});this.prefs=this.track_config.values;this.height_px=this.track_config.values.height;this.vertical_range=this.track_config.values.max_value-this.track_config.values.min_value;this.add_resize_handle()};n(k.prototype,J.prototype,{add_resize_handle:function(){var aa=this;var ad=false;var ac=false;var ab=$("<div class='track-resize'>");$(aa.container_div).hover(function(){ad=true;ab.show()},function(){ad=false;if(!ac){ab.hide()}});ab.hide().bind("dragstart",function(ae,af){ac=true;af.original_height=$(aa.content_div).height()}).bind("drag",function(af,ag){var ae=Math.min(Math.max(ag.original_height+ag.deltaY,aa.min_height_px),aa.max_height_px);$(aa.content_div).css("height",ae);aa.height_px=ae;aa.draw(true)}).bind("dragend",function(ae,af){aa.tile_cache.clear();ac=false;if(!ad){ab.hide()}aa.track_config.values.height=aa.height_px}).appendTo(aa.container_div)},predraw_init:function(){var aa=this,ab=aa.view.tracks.indexOf(aa);aa.vertical_range=undefined;return $.getJSON(aa.data_url,{stats:true,chrom:aa.view.chrom,low:null,high:null,hda_ldda:aa.hda_ldda,dataset_id:aa.dataset_id},function(ac){aa.container_div.addClass("line-track");var ae=ac.data;if(isNaN(parseFloat(aa.prefs.min_value))||isNaN(parseFloat(aa.prefs.max_value))){aa.prefs.min_value=ae.min;aa.prefs.max_value=ae.max;$("#track_"+ab+"_minval").val(aa.prefs.min_value);$("#track_"+ab+"_maxval").val(aa.prefs.max_value)}aa.vertical_range=aa.prefs.max_value-aa.prefs.min_value;aa.total_frequency=ae.total_frequency;aa.container_div.find(".yaxislabel").remove();var af=$("<div />").addClass("yaxislabel").attr("id","linetrack_"+ab+"_minval").text(u(aa.prefs.min_value));var ad=$("<div />").addClass("yaxislabel").attr("id","linetrack_"+ab+"_maxval").text(u(aa.prefs.max_value));ad.css({position:"absolute",top:"24px",left:"10px"});ad.prependTo(aa.container_div);af.css({position:"absolute",bottom:"2px",left:"10px"});af.prependTo(aa.container_div)})},draw_tile:function(ak,ae,ab,aj){if(this.vertical_range===undefined){return}var af=ab*M*ae,ad=M*ae,aa=Math.ceil(ad*aj),ah=this.height_px;var ac=this.view.canvas_manager.new_canvas();ac.width=aa,ac.height=ah;var ai=ac.getContext("2d");var ag=new I.LinePainter(ak.data,af,af+ad,this.prefs,this.mode);ag.draw(ai,aa,ah);return new b(ad,ae,ac)}});var e=function(aa,af,ae,ai,ah,ac,ad,ag){var ab=this;this.display_modes=["Auto","Histogram","Dense","Squish","Pack"];this.track_config=new V({track:this,params:[{key:"block_color",label:"Block color",type:"color",default_value:"#444"},{key:"label_color",label:"Label color",type:"color",default_value:"black"},{key:"show_counts",label:"Show summary counts",type:"bool",default_value:true},{key:"mode",type:"string",default_value:this.mode,hidden:true},],saved_values:ah,onchange:function(){ab.tile_cache.clear();ab.draw()}});this.prefs=this.track_config.values;j.call(this,aa,af,af.viewport_container);J.call(this,ac,ad,ag);this.height_px=0;this.container_div.addClass("feature-track");this.hda_ldda=ae;this.dataset_id=ai;this.original_dataset_id=ai;this.show_labels_scale=0.001;this.showing_details=false;this.summary_draw_height=30;this.inc_slots={};this.start_end_dct={};this.tile_cache=new c(d);this.data_cache=new N(20,this);this.left_offset=200;this.painter=I.LinkedFeaturePainter};n(e.prototype,J.prototype,{update_auto_mode:function(aa){if(this.mode=="Auto"){if(aa=="no_detail"){aa="feature spans"}else{if(aa=="summary_tree"){aa="coverage histogram"}}this.mode_div.text("Auto ("+aa+")")}},incremental_slots:function(ae,ab,ad){var ac=this.view.canvas_manager.dummy_context,aa=this.inc_slots[ae];if(!aa||(aa.mode!==ad)){aa=new (p.FeatureSlotter)(ae,ad==="Pack",w,function(af){return ac.measureText(af)});aa.mode=ad;this.inc_slots[ae]=aa}return aa.slot_features(ab)},get_summary_tree_data:function(ae,ah,ac,ap){if(ap>ac-ah){ap=ac-ah}var al=Math.floor((ac-ah)/ap),ao=[],ad=0;var af=0,ag=0,ak,an=0,ai=[],am,aj;var ab=function(at,ar,au,aq){at[0]=ar+au*aq;at[1]=ar+(au+1)*aq};while(an<ap&&af!==ae.length){var aa=false;for(;an<ap&&!aa;an++){ab(ai,ah,an,al);for(ag=af;ag<ae.length;ag++){ak=ae[ag].slice(1,3);if(is_overlap(ak,ai)){aa=true;break}}if(aa){break}}data_start_index=ag;ao[ao.length]=am=[ai[0],0];for(;ag<ae.length;ag++){ak=ae[ag].slice(1,3);if(is_overlap(ak,ai)){am[1]++}else{break}}if(am[1]>ad){ad=am[1]}an++}return{max:ad,delta:al,data:ao}},draw_tile:function(an,av,az,aj,ad){var ar=this,aB=az*M*av,ab=(az+1)*M*av,ap=ab-aB,at=Math.ceil(ap*aj),aq=this.mode,aF=25,ae=this.left_offset,ao,af;if(aq==="Auto"){if(an.dataset_type==="summary_tree"){aq=an.dataset_type}else{if(an.extra_info==="no_detail"){aq="no_detail"}else{var aE=an.data;if(this.view.high-this.view.low>F){aq="Squish"}else{aq="Pack"}}}this.update_auto_mode(aq)}if(aq==="summary_tree"||aq==="Histogram"){af=this.summary_draw_height;this.container_div.find(".yaxislabel").remove();var aa=$("<div />").addClass("yaxislabel");aa.text(an.max);aa.css({position:"absolute",top:"24px",left:"10px",color:this.prefs.label_color});aa.prependTo(this.container_div);var ac=this.view.canvas_manager.new_canvas();ac.width=at+ae;ac.height=af+O;if(an.dataset_type!="summary_tree"){var ak=this.get_summary_tree_data(an.data,aB,ab,200);if(an.max){ak.max=an.max}an=ak}var aC=new I.SummaryTreePainter(an,aB,ab,this.prefs);var au=ac.getContext("2d");au.translate(ae,O);aC.draw(au,at,af);return new l(az,av,ac,an.max)}var ao,ah=1;if(aq==="no_detail"||aq==="Squish"||aq==="Pack"){ah=this.incremental_slots(aj,an.data,aq);ao=this.inc_slots[aj].slots}var ai=[];if(an.data){var al=this.filters_manager.filters;for(var aw=0,ay=an.data.length;aw<ay;aw++){var ag=an.data[aw];var ax=false;var am;for(var aA=0,aD=al.length;aA<aD;aA++){am=al[aA];am.update_attrs(ag);if(!am.keep(ag)){ax=true;break}}if(!ax){ai.push(ag)}}}var aC=new (this.painter)(ai,aB,ab,this.prefs,aq,ad);var af=aC.get_required_height(ah);var ac=this.view.canvas_manager.new_canvas();ac.width=at+ae;ac.height=af;var au=ac.getContext("2d");au.fillStyle=this.prefs.block_color;au.font=au.canvas.manager.default_font;au.textAlign="right";this.container_div.find(".yaxislabel").remove();if(an.data){this.example_feature=(an.data.length?an.data[0]:undefined);au.translate(ae,0);aC.draw(au,at,af,ao)}return new L(az,av,ac,an.message)}});var P=function(ad,ab,af,aa,ac,ae){e.call(this,ad,ab,af,aa,ac,ae);this.painter=I.VariantPainter};n(P.prototype,J.prototype,e.prototype);var S=function(ad,ab,af,aa,ac,ae){e.call(this,ad,ab,af,aa,ac,ae);this.track_config=new V({track:this,params:[{key:"block_color",label:"Block color",type:"color",default_value:"#444"},{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:"mode",type:"string",default_value:this.mode,hidden:true},],saved_values:ac,onchange:function(){this.track.tile_cache.clear();this.track.draw()}});this.prefs=this.track_config.values;this.painter=I.ReadPainter;this.make_name_popup_menu()};n(S.prototype,J.prototype,e.prototype);var Q=function(ae,ac,ag,aa,ad,af,ab){e.call(this,ae,ac,ag,aa,ad,af,{},ab);this.data_url=raw_data_url;this.data_query_wait=1000;this.dataset_check_url=dataset_state_url};n(Q.prototype,J.prototype,e.prototype,{predraw_init:function(){var ab=this;var aa=function(){if(ab.data_cache.size()===0){setTimeout(aa,300)}else{ab.data_url=default_data_url;ab.data_query_wait=H;ab.dataset_state_url=converted_datasets_state_url;$.getJSON(ab.dataset_state_url,{dataset_id:ab.dataset_id,hda_ldda:ab.hda_ldda},function(ac){})}};aa()}});T.View=Y;T.LineTrack=k;T.FeatureTrack=e;T.ReadTrack=S};var slotting_module=function(c,b){var e=c("class").extend;var d=2,a=5;b.FeatureSlotter=function(j,h,f,g){this.slots={};this.start_end_dct={};this.w_scale=j;this.include_label=h;this.max_rows=f;this.measureText=g};e(b.FeatureSlotter.prototype,{slot_features:function(m){var p=this.w_scale,s=this.slots,h=this.start_end_dct,y=[],A=[],n=0,z=this.max_rows;for(var w=0,x=m.length;w<x;w++){var l=m[w],o=l[0];if(s[o]!==undefined){n=Math.max(n,s[o]);A.push(s[o])}else{y.push(w)}}var q=function(G,H){for(var F=0;F<=z;F++){var D=false,I=h[F];if(I!==undefined){for(var C=0,E=I.length;C<E;C++){var B=I[C];if(H>B[0]&&G<B[1]){D=true;break}}}if(!D){return F}}return -1};for(var w=0,x=y.length;w<x;w++){var l=m[y[w]],o=l[0],u=l[1],f=l[2],r=l[3],g=Math.floor(u*p),k=Math.ceil(f*p),v=this.measureText(r).width,j;if(r!==undefined&&this.include_label){v+=(d+a);if(g-v>=0){g-=v;j="left"}else{k+=v;j="right"}}var t=q(g,k);if(t>=0){if(h[t]===undefined){h[t]=[]}h[t].push([g,k]);s[o]=t;n=Math.max(n,t)}else{}}return n+1}})};var painters_module=function(j,w){var t=j("class").extend;var o=function(H,z,F,y,E,C){if(C===undefined){C=4}var B=y-z;var A=E-F;var D=Math.floor(Math.sqrt(B*B+A*A)/C);var I=B/D;var G=A/D;var x;for(x=0;x<D;x++,z+=I,F+=G){if(x%2!==0){continue}H.fillRect(z,F,C,1)}};var p=function(A,z,x,D){var C=z-D/2,B=z+D/2,E=x-Math.sqrt(D*3/2);A.beginPath();A.moveTo(C,E);A.lineTo(B,E);A.lineTo(z,x);A.lineTo(C,E);A.strokeStyle=this.fillStyle;A.fill();A.stroke();A.closePath()};var m=function(z,B,x,y,A){this.data=z;this.view_start=B;this.view_end=x;this.prefs=t({},this.default_prefs,y);this.mode=A};m.prototype.default_prefs={};var u=function(z,B,x,y,A){m.call(this,z,B,x,y,A)};u.prototype.default_prefs={show_counts:false};u.prototype.draw=function(M,z,L){var E=this.view_start,O=this.view_end-this.view_start,N=z/O;var J=this.data.data,I=this.data.delta,G=this.data.max,B=L;delta_x_px=Math.ceil(I*N);M.save();for(var C=0,D=J.length;C<D;C++){var H=Math.floor((J[C][0]-E)*N);var F=J[C][1];if(!F){continue}var K=F/G*L;if(F!==0&&K<1){K=1}M.fillStyle=this.prefs.block_color;M.fillRect(H,B-K,delta_x_px,K);var A=4;if(this.prefs.show_counts&&(M.measureText(F).width+A)<delta_x_px){M.fillStyle=this.prefs.label_color;M.textAlign="center";M.fillText(F,H+(delta_x_px/2),10)}}M.restore()};var c=function(x,B,D,E,z){m.call(this,x,B,D,E,z);if(this.prefs.min_value===undefined){var F=Infinity;for(var y=0,A=this.data.length;y<A;y++){F=Math.min(F,this.data[y][1])}this.prefs.min_value=F}if(this.prefs.max_value===undefined){var C=-Infinity;for(var y=0,A=this.data.length;y<A;y++){C=Math.max(C,this.data[y][1])}this.prefs.max_value=C}};c.prototype.default_prefs={min_value:undefined,max_value:undefined,mode:"Histogram",color:"#000",overflow_color:"#F66"};c.prototype.draw=function(M,L,J){var E=false,G=this.prefs.min_value,C=this.prefs.max_value,I=C-G,x=J,z=this.view_start,K=this.view_end-this.view_start,A=L/K,H=this.mode,S=this.data;M.save();var T=Math.round(J+G/I*J);if(H!=="Intensity"){M.fillStyle="#aaa";M.fillRect(0,T,L,1)}M.beginPath();var Q,D,B;if(S.length>1){B=Math.ceil((S[1][0]-S[0][0])*A)}else{B=10}for(var N=0,O=S.length;N<O;N++){M.fillStyle=this.prefs.color;Q=Math.round((S[N][0]-z)*A);D=S[N][1];var P=false,F=false;if(D===null){if(E&&H==="Filled"){M.lineTo(Q,x)}E=false;continue}if(D<G){F=true;D=G}else{if(D>C){P=true;D=C}}if(H==="Histogram"){D=Math.round(D/I*x);M.fillRect(Q,T,B,-D)}else{if(H==="Intensity"){D=255-Math.floor((D-G)/I*255);M.fillStyle="rgb("+D+","+D+","+D+")";M.fillRect(Q,0,B,x)}else{D=Math.round(x-(D-G)/I*x);if(E){M.lineTo(Q,D)}else{E=true;if(H==="Filled"){M.moveTo(Q,x);M.lineTo(Q,D)}else{M.moveTo(Q,D)}}}}M.fillStyle=this.prefs.overflow_color;if(P||F){var R;if(H==="Histogram"||H==="Intensity"){R=B}else{Q-=2;R=4}if(P){M.fillRect(Q,0,R,3)}if(F){M.fillRect(Q,x-3,R,3)}}M.fillStyle=this.prefs.color}if(H==="Filled"){if(E){M.lineTo(Q,T);M.lineTo(0,T)}M.fill()}else{M.stroke()}M.restore()};var n=function(z,B,x,y,A){m.call(this,z,B,x,y,A)};n.prototype.default_prefs={block_color:"#FFF",connector_color:"#FFF"};t(n.prototype,{get_required_height:function(y){var x=y_scale=this.get_row_height(),z=this.mode;if(z==="no_detail"||z==="Squish"||z==="Pack"){x=y*y_scale}return x+Math.max(Math.round(y_scale/2),5)},draw:function(J,A,I,F){var D=this.data,G=this.view_start,K=this.view_end;J.save();J.fillStyle=this.prefs.block_color;J.textAlign="right";var N=this.view_end-this.view_start,M=A/N,z=this.get_row_height();for(var C=0,E=D.length;C<E;C++){var L=D[C],B=L[0],x=L[1],y=L[2],H=(F&&F[B]!==undefined?F[B]:null);if((x<K&&y>G)&&(this.mode=="Dense"||H!==null)){this.draw_element(J,this.mode,L,H,G,K,M,z,A)}}J.restore()}});var d=10,h=3,l=5,v=10,f=1,r=3,e=3,a=9,k=2,g="#ccc";var q=function(z,B,x,y,A){n.call(this,z,B,x,y,A)};t(q.prototype,n.prototype,{get_row_height:function(){var y=this.mode,x;if(y==="Dense"){x=d}else{if(y==="no_detail"){x=h}else{if(y==="Squish"){x=l}else{x=v}}}return x},draw_element:function(J,C,R,E,L,ab,af,ag,x){var O=R[0],ad=R[1],V=R[2],M=R[3],W=Math.floor(Math.max(0,(ad-L)*af)),K=Math.ceil(Math.min(x,Math.max(0,(V-L)*af))),U=(C==="Dense"?0:(0+E))*ag,I,Z,N=null,ah=null,A=this.prefs.block_color,Y=this.prefs.label_color;if(C=="Dense"){E=1}if(C==="no_detail"){J.fillStyle=A;J.fillRect(W,U+5,K-W,f)}else{var H=R[4],T=R[5],X=R[6],B=R[7];if(T&&X){N=Math.floor(Math.max(0,(T-L)*af));ah=Math.ceil(Math.min(x,Math.max(0,(X-L)*af)))}var ae,P;if(C==="Squish"||C==="Dense"){ae=1;P=e}else{ae=5;P=a}if(!B){if(R.strand){if(R.strand==="+"){J.fillStyle=J.canvas.manager.get_pattern("right_strand_inv")}else{if(R.strand==="-"){J.fillStyle=J.canvas.manager.get_pattern("left_strand_inv")}}}else{J.fillStyle=A}J.fillRect(W,U,K-W,P)}else{var G,Q;if(C==="Squish"||C==="Dense"){J.fillStyle=g;G=U+Math.floor(e/2)+1;Q=1}else{if(H){var G=U;var Q=P;if(H==="+"){J.fillStyle=J.canvas.manager.get_pattern("right_strand")}else{if(H==="-"){J.fillStyle=J.canvas.manager.get_pattern("left_strand")}}}else{J.fillStyle=g;G+=(e/2)+1;Q=1}}J.fillRect(W,G,K-W,Q);for(var ac=0,z=B.length;ac<z;ac++){var D=B[ac],y=Math.floor(Math.max(0,(D[0]-L)*af)),S=Math.ceil(Math.min(x,Math.max((D[1]-L)*af)));if(y>S){continue}J.fillStyle=A;J.fillRect(y,U+(P-ae)/2+1,S-y,ae);if(N!==undefined&&X>T&&!(y>ah||S<N)){var aa=Math.max(y,N),F=Math.min(S,ah);J.fillRect(aa,U+1,F-aa,P);if(B.length==1&&C=="Pack"){if(H==="+"){J.fillStyle=J.canvas.manager.get_pattern("right_strand_inv")}else{if(H==="-"){J.fillStyle=J.canvas.manager.get_pattern("left_strand_inv")}}if(aa+14<F){aa+=2;F-=2}J.fillRect(aa,U+1,F-aa,P)}}}}if(C==="Pack"&&ad>L){J.fillStyle=Y;if(L===0&&W-J.measureText(M).width<0){J.textAlign="left";J.fillText(M,K+k,U+8)}else{J.textAlign="right";J.fillText(M,W-k,U+8)}J.fillStyle=A}}}});var b=function(z,B,x,y,A){n.call(this,z,B,x,y,A)};t(b.prototype,n.prototype,{draw_element:function(Q,L,F,B,T,z,I,R,O){var F=data[i],H=F[0],P=F[1],A=F[2],K=F[3],D=Math.floor(Math.max(0,(P-T)*I)),G=Math.ceil(Math.min(O,Math.max(0,(A-T)*I))),C=(L==="Dense"?0:(0+B))*R,x,U,y=null,J=null;if(no_label){Q.fillStyle=block_color;Q.fillRect(D+left_offset,C+5,G-D,1)}else{var S=F[4],N=F[5],E=F[6];x=9;U=1;Q.fillRect(D+left_offset,C,G-D,x);if(L!=="Dense"&&K!==undefined&&P>T){Q.fillStyle=label_color;if(T===0&&D-Q.measureText(K).width<0){Q.textAlign="left";Q.fillText(K,G+2+left_offset,C+8)}else{Q.textAlign="right";Q.fillText(K,D-2+left_offset,C+8)}Q.fillStyle=block_color}var M=S+" / "+N;if(P>T&&Q.measureText(M).width<(G-D)){Q.fillStyle="white";Q.textAlign="center";Q.fillText(M,left_offset+D+(G-D)/2,C+8);Q.fillStyle=block_color}}}});var s=function(A,C,x,z,B,y){n.call(this,A,C,x,z,B);this.ref_seq=y};s.prototype.default_prefs=t({},n.prototype.default_prefs,{show_insertions:false});t(s.prototype,n.prototype,{get_row_height:function(){var x,y=this.mode;if(y==="Dense"){x=d}else{if(y==="Squish"){x=l}else{x=v;if(this.prefs.show_insertions){x*=2}}}return x},draw_read:function(T,O,K,Y,z,S,H,E,D){T.textAlign="center";var R=this,y=[Y,z],N=0,U=0,Q=0;ref_seq=this.ref_seq,char_width_px=T.canvas.manager.char_width_px;var ad=[];if((O==="Pack"||this.mode==="Auto")&&E!==undefined&&K>char_width_px){Q=Math.round(K/2)}if(!H){H=[[0,E.length]]}for(var L=0,W=H.length;L<W;L++){var I=H[L],A="MIDNSHP=X"[I[0]],M=I[1];if(A==="H"||A==="S"){N-=M}var F=S+N,ac=Math.floor(Math.max(0,(F-Y)*K)),G=Math.floor(Math.max(0,(F+M-Y)*K));if(ac===G){G+=1}switch(A){case"H":break;case"S":case"M":case"=":if(is_overlap([F,F+M],y)){var P=E.slice(U,U+M);if(Q>0){T.fillStyle=this.prefs.block_color;T.fillRect(ac-Q,D+1,G-ac,9);T.fillStyle=g;for(var aa=0,x=P.length;aa<x;aa++){if(this.prefs.show_differences&&ref_seq){var J=ref_seq[F-Y+aa];if(!J||J.toLowerCase()===P[aa].toLowerCase()){continue}}if(F+aa>=Y&&F+aa<=z){var ab=Math.floor(Math.max(0,(F+aa-Y)*K));T.fillText(P[aa],ab,D+9)}}}else{T.fillStyle=this.prefs.block_color;T.fillRect(ac,D+4,G-ac,e)}}U+=M;N+=M;break;case"N":T.fillStyle=g;T.fillRect(ac-Q,D+5,G-ac,1);N+=M;break;case"D":T.fillStyle="red";T.fillRect(ac-Q,D+4,G-ac,3);N+=M;break;case"P":break;case"I":var X=ac-Q;if(is_overlap([F,F+M],y)){var P=E.slice(U,U+M);if(this.prefs.show_insertions){var C=ac-(G-ac)/2;if((O==="Pack"||this.mode==="Auto")&&E!==undefined&&K>char_width_px){T.fillStyle="yellow";T.fillRect(C-Q,D-9,G-ac,9);ad[ad.length]={type:"triangle",data:[X,D+4,5]};T.fillStyle=g;switch(seq_tile_overlap){case (OVERLAP_START):P=P.slice(Y-F);break;case (OVERLAP_END):P=P.slice(0,F-z);break;case (CONTAINED_BY):break;case (CONTAINS):P=P.slice(Y-F,F-z);break}for(var aa=0,x=P.length;aa<x;aa++){var ab=Math.floor(Math.max(0,(F+aa-Y)*K));T.fillText(P[aa],ab-(G-ac)/2,D)}}else{T.fillStyle="yellow";T.fillRect(C,D+(this.mode!=="Dense"?2:5),G-ac,(O!=="Dense"?e:r))}}else{if((O==="Pack"||this.mode==="Auto")&&E!==undefined&&K>char_width_px){ad[ad.length]={type:"text",data:[P.length,X,D+9]}}else{}}}U+=M;break;case"X":U+=M;break}}T.fillStyle="yellow";var Z,B,ae;for(var V=0;V<ad.length;V++){Z=ad[V];B=Z.type;ae=Z.data;if(B==="text"){T.save();T.font="bold "+T.font;T.fillText(ae[0],ae[1],ae[2]);T.restore()}else{if(B=="triangle"){p(T,ae[0],ae[1],ae[2])}}}},draw_element:function(Q,L,D,A,T,y,H,R,O){var G=D[0],P=D[1],z=D[2],I=D[3],C=Math.floor(Math.max(0,(P-T)*H)),E=Math.ceil(Math.min(O,Math.max(0,(z-T)*H))),B=(L==="Dense"?0:(0+A))*R,U=this.prefs.block_color,F=this.prefs.label_color,N=0;if((L==="Pack"||this.mode==="Auto")&&H>Q.canvas.manager.char_width_px){var N=Math.round(H/2)}Q.fillStyle=U;if(D[5] instanceof Array){var M=Math.floor(Math.max(0,(D[4][0]-T)*H)),K=Math.ceil(Math.min(O,Math.max(0,(D[4][1]-T)*H))),J=Math.floor(Math.max(0,(D[5][0]-T)*H)),x=Math.ceil(Math.min(O,Math.max(0,(D[5][1]-T)*H)));if(D[4][1]>=T&&D[4][0]<=y&&D[4][2]){this.draw_read(Q,L,H,T,y,D[4][0],D[4][2],D[4][3],B)}if(D[5][1]>=T&&D[5][0]<=y&&D[5][2]){this.draw_read(Q,L,H,T,y,D[5][0],D[5][2],D[5][3],B)}if(J>K){Q.fillStyle=g;o(Q,K-N,B+5,J-N,B+5)}}else{Q.fillStyle=U;this.draw_read(Q,L,H,T,y,P,D[4],D[5],B)}if(L==="Pack"&&P>T){Q.fillStyle=this.prefs.label_color;var S=1;if(S===0&&C-Q.measureText(I).width<0){Q.textAlign="left";Q.fillText(I,E+k-N,B+8)}else{Q.textAlign="right";Q.fillText(I,C-k-N,B+8)}Q.fillStyle=U}}});w.SummaryTreePainter=u;w.LinePainter=c;w.LinkedFeaturePainter=q;w.ReadPainter=s;w.VariantPainter=b};(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
--- a/static/scripts/trackster.js Thu Jun 30 16:13:52 2011 -0400
+++ b/static/scripts/trackster.js Sun Jul 03 15:05:25 2011 -0400
@@ -172,7 +172,7 @@
// height of individual features within tracks. Feature height, then, should always be less
// than track height.
CHAR_HEIGHT_PX = 9, // FIXME: font size may not be static
- ERROR_PADDING = 15, // Padding at the top of tracks for error messages
+ ERROR_PADDING = 18, // Padding at the top of tracks for error messages
SUMMARY_TREE_TOP_PADDING = CHAR_HEIGHT_PX + 2,
// Maximum number of rows un a slotted track
MAX_FEATURE_DEPTH = 100,
@@ -212,7 +212,14 @@
get: function(key) {
var index = this.key_ary.indexOf(key);
if (index !== -1) {
- this.move_key_to_end(key, index);
+ if (this.obj_cache[key].stale) {
+ // Object is stale, so remove key and object.
+ this.key_ary.splice(index, 1);
+ delete this.obj_cache[key];
+ }
+ else {
+ this.move_key_to_end(key, index);
+ }
}
return this.obj_cache[key];
},
@@ -280,7 +287,7 @@
});
},
/**
- * Get data and do callback.
+ * Get track data.
*/
get_data: function(chrom, low, high, mode, resolution, extra_params) {
// Debugging:
@@ -332,7 +339,7 @@
// Load data from server. The deferred is immediately saved until the
// data is ready, it then replaces itself with the actual data
entry = this.load_data(chrom, low, high, mode, resolution, extra_params);
- this.set_data( low, high, mode, entry );
+ this.set_data(low, high, mode, entry);
return entry
},
set_data: function(low, high, mode, result) {
@@ -1500,6 +1507,7 @@
this.resolution = resolution;
// Wrap element in div for background.
this.canvas = $("<div class='track-tile'/>").append(canvas);
+ this.stale = false;
};
var SummaryTreeTile = function(index, resolution, canvas, max_val) {
@@ -1925,9 +1933,9 @@
var cached = this.tile_cache.get(key);
var tile_low = tile_index * DENSITY * this.view.resolution;
var tile_high = tile_low + DENSITY * this.view.resolution;
- if ( !force && cached ) {
+ if (!force && cached) {
drawn_tiles[drawn_tiles.length] = cached;
- this.show_tile(cached, parent_element, tile_low, w_scale);
+ this.show_tile(cached, parent_element, tile_low, tile_high, w_scale);
} else {
this.delayed_draw(force, key, tile_index, resolution, parent_element, w_scale, drawn_tiles);
}
@@ -2079,7 +2087,7 @@
if (tile === undefined) {
return;
}
- track.show_tile(tile, parent_element, tile_low, w_scale);
+ track.show_tile(tile, parent_element, tile_low, tile_high, w_scale);
drawn_tiles[drawn_tiles.length] = tile;
};
// Put a 50ms delay on drawing so that if the user scrolls fast, we don't load extra data
@@ -2088,7 +2096,7 @@
// Show/draw tile: check cache for tile; if tile not in cache, draw it.
var tile = (force ? undefined : track.tile_cache.get(key));
if (tile) {
- track.show_tile(tile, parent_element, tile_low, w_scale);
+ track.show_tile(tile, parent_element, tile_low, tile_high, w_scale);
drawn_tiles[drawn_tiles.length] = tile;
}
else {
@@ -2117,9 +2125,41 @@
/**
* Show track tile and perform associated actions.
*/
- show_tile: function(tile, parent_element, tile_low, w_scale) {
+ show_tile: function(tile, parent_element, tile_low, tile_high, w_scale) {
// Readability.
- var track = this;
+ var
+ track = this,
+ canvas = tile.canvas,
+ tile_element = canvas;
+
+ //
+ // If tile has message, display message and button to show more data.
+ // TODO: need to handle other messages, not assume message === show more data.
+ //
+ if (tile.message) {
+ var
+ container_div = $("<div/>"),
+ message_div = $("<div/>").addClass("tile-message").text(tile.message).
+ // -1 to account for border.
+ css({'height': ERROR_PADDING-1, 'width': tile.canvas.width}).appendTo(container_div),
+ show_more_data_btn = $("<button/>").text("Show more").css("margin-left", "0.5em").appendTo(message_div);
+ container_div.append(canvas);
+ tile_element = container_div;
+
+ // Set up actions for button.
+ show_more_data_btn.click(function() {
+ // Mark data, tile as stale, request more data, and redraw track.
+ // HACK: get_data used will return object that can be marked as stale, but a better way to this is needed.
+ var cur_data = track.data_cache.get_data(track.view.chrom, tile_low, tile_high, track.mode, tile.resolution);
+ cur_data.stale = true;
+ tile.stale = true;
+ track.data_cache.get_data(track.view.chrom, tile_low, tile_high, track.mode, tile.resolution, {max_vals: cur_data.data.length * 2});
+ track.draw();
+ }).dblclick(function(e) {
+ // Do not propogate as this would normal zoom in.
+ e.stopPropagation();
+ });
+ }
//
// Show tile element.
@@ -2131,7 +2171,6 @@
if (this.left_offset) {
left -= this.left_offset;
}
- var tile_element = tile.canvas;
tile_element.css({ position: 'absolute', top: 0, left: left, height: '' });
parent_element.append(tile_element);
@@ -2389,7 +2428,7 @@
var ctx = canvas.getContext("2d");
var painter = new painters.LinePainter( result.data, tile_low, tile_low + tile_length,
this.prefs, this.mode );
- painter.draw( ctx, width, height );
+ painter.draw(ctx, width, height);
return new Tile(tile_length, resolution, canvas);
}
@@ -2680,6 +2719,7 @@
if (result.data) {
// Set example feature. This is needed so that track can update its UI based on feature attributes.
+ // TODO: use tile data rather than example feature?
this.example_feature = (result.data.length ? result.data[0] : undefined);
// Draw features.
@@ -2687,17 +2727,6 @@
painter.draw(ctx, width, required_height, slots);
}
- // If tile has a message, create container div with both a message div and the canvas.
- if (result.message) {
- var container_div = $("<div/>");
- var message_div = $("<div/>").addClass("tile-message").text(result.message).css('width', canvas.width);
- message_div.css({position: 'absolute', top: 0});
- $(canvas).css("top", 15);
- container_div.append(message_div);
- container_div.append(canvas);
- canvas = container_div;
- }
-
return new FeatureTrackTile(tile_index, resolution, canvas, result.message);
}
});
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: Fix FeatureTracks display bug introduced in 5640:b7c4c1bcf03d.
by Bitbucket 30 Jun '11
by Bitbucket 30 Jun '11
30 Jun '11
1 new changeset in galaxy-central:
http://bitbucket.org/galaxy/galaxy-central/changeset/1cda4c563a94/
changeset: 1cda4c563a94
user: jgoecks
date: 2011-06-30 22:13:52
summary: Fix FeatureTracks display bug introduced in 5640:b7c4c1bcf03d.
affected #: 2 files (427 bytes)
--- a/static/scripts/packed/trackster.js Thu Jun 30 15:09:08 2011 -0400
+++ b/static/scripts/packed/trackster.js Thu Jun 30 16:13:52 2011 -0400
@@ -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 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 trackster_module=function(f,T){var n=f("class").extend,p=f("slotting"),I=f("painters");var Z=function(aa,ab){this.document=aa;this.default_font=ab!==undefined?ab:"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")};n(Z.prototype,{load_pattern:function(aa,ae){var ab=this.patterns,ac=this.dummy_context,ad=new Image();ad.src=image_path+ae;ad.onload=function(){ab[aa]=ac.createPattern(ad,"repeat")}},get_pattern:function(aa){return this.patterns[aa]},new_canvas:function(){var aa=this.document.createElement("canvas");if(window.G_vmlCanvasManager){G_vmlCanvasManager.initElement(aa)}aa.manager=this;return aa}});var C=function(aa,ab){aa.bind("drag",{handle:ab,relative:true},function(af,ag){var ae=$(this).parent();var ad=ae.children();var ac;for(ac=0;ac<ad.length;ac++){if(ag.offsetY<$(ad.get(ac)).position().top){break}}if(ac===ad.length){if(this!==ad.get(ac-1)){ae.append(this)}}else{if(this!==ad.get(ac)){$(this).insertBefore(ad.get(ac))}}}).bind("dragstart",function(){$(this).css({"border-top":"1px solid blue","border-bottom":"1px solid blue"})}).bind("dragend",function(){$(this).css("border","0px")})};T.sortable=C;var D=9,A=15,O=D+2,w=100,F=12000,M=200,z=5,s=10,H=5000,t=100,m="There was an error in indexing this dataset. ",G="A converter for this dataset is not installed. Please check your datatypes_conf.xml file.",B="No data for this chrom/contig.",q="Currently indexing... please wait",v="Tool cannot be rerun: ",a="Loading data...",U="Ready for display",d=10,r=5,y=5;function u(aa){return Math.round(aa*1000)/1000}var c=function(aa){this.num_elements=aa;this.clear()};n(c.prototype,{get:function(ab){var aa=this.key_ary.indexOf(ab);if(aa!==-1){this.move_key_to_end(ab,aa)}return this.obj_cache[ab]},set:function(ab,ac){if(!this.obj_cache[ab]){if(this.key_ary.length>=this.num_elements){var aa=this.key_ary.shift();delete this.obj_cache[aa]}this.key_ary.push(ab)}this.obj_cache[ab]=ac;return ac},move_key_to_end:function(ab,aa){this.key_ary.splice(aa,1);this.key_ary.push(ab)},clear:function(){this.obj_cache={};this.key_ary=[]},size:function(){return this.key_ary.length}});var N=function(ab,aa,ac){c.call(this,ab);this.track=aa;this.subset=(ac!==undefined?ac:true)};n(N.prototype,c.prototype,{load_data:function(ai,aj,ae,ah,ab,ag){var ad={chrom:ai,low:aj,high:ae,mode:ah,resolution:ab,dataset_id:this.track.dataset_id,hda_ldda:this.track.hda_ldda};$.extend(ad,ag);if(this.track.filters_manager){var ak=[];var aa=this.track.filters_manager.filters;for(var af=0;af<aa.length;af++){ak[ak.length]=aa[af].name}ad.filter_cols=JSON.stringify(ak)}var ac=this;return $.getJSON(this.track.data_url,ad,function(al){ac.set_data(aj,ae,ah,al)})},get_data:function(ac,aa,af,ag,ab,ae){var ad=this.get(this.gen_key(aa,af,ag));if(ad){return ad}ad=this.load_data(ac,aa,af,ag,ab,ae);this.set_data(aa,af,ag,ad);return ad},set_data:function(ab,ac,ad,aa){return this.set(this.gen_key(ab,ac,ad),aa)},gen_key:function(aa,ac,ad){var ab=aa+"_"+ac+"_"+ad;return ab},split_key:function(aa){return aa.split("_")}});var E=function(ab,aa,ac){N.call(this,ab,aa,ac)};n(E.prototype,N.prototype,c.prototype,{load_data:function(ac,aa,ae,af,ab,ad){if(ab>1){return}return N.prototype.load_data.call(this,ac,aa,ae,af,ab,ad)}});var Y=function(aa,ad,ac,ab,ae){this.container=aa;this.chrom=null;this.vis_id=ac;this.dbkey=ab;this.title=ad;this.tracks=[];this.label_tracks=[];this.max_low=0;this.max_high=0;this.num_tracks=0;this.track_id_counter=0;this.zoom_factor=3;this.min_separation=30;this.has_changes=false;this.init(ae);this.canvas_manager=new Z(aa.get(0).ownerDocument);this.reset()};n(Y.prototype,{init:function(ad){var ac=this.container,aa=this;this.top_container=$("<div/>").addClass("top-container").appendTo(ac);this.content_div=$("<div/>").addClass("content").css("position","relative").appendTo(ac);this.bottom_container=$("<div/>").addClass("bottom-container").appendTo(ac);this.top_labeltrack=$("<div/>").addClass("top-labeltrack").appendTo(this.top_container);this.viewport_container=$("<div/>").addClass("viewport-container").addClass("viewport-container").appendTo(this.content_div);this.intro_div=$("<div/>").addClass("intro").text("Select a chrom from the dropdown below").hide();this.nav_labeltrack=$("<div/>").addClass("nav-labeltrack").appendTo(this.bottom_container);this.nav_container=$("<div/>").addClass("nav-container").prependTo(this.top_container);this.nav=$("<div/>").addClass("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 href='javascript:void(0);'>Close Overview</a>").addClass("overview-close").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 ab=function(ae){if(ae.type==="focusout"||(ae.keyCode||ae.which)===13||(ae.keyCode||ae.which)===27){if((ae.keyCode||ae.which)!==27){aa.go_to($(this).val())}$(this).hide();$(this).val("");aa.location_span.show();aa.chrom_select.show()}};this.nav_input=$("<input/>").addClass("nav-input").hide().bind("keyup focusout",ab).appendTo(this.nav_controls);this.location_span=$("<span/>").addClass("location").appendTo(this.nav_controls);this.location_span.bind("click",function(){aa.location_span.hide();aa.chrom_select.hide();aa.nav_input.val(aa.chrom+":"+aa.low+"-"+aa.high);aa.nav_input.css("display","inline-block");aa.nav_input.select();aa.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 id='zoom-out' />").click(function(){aa.zoom_out();aa.redraw()}).appendTo(this.nav_controls);this.zi_link=$("<a id='zoom-in' />").click(function(){aa.zoom_in();aa.redraw()}).appendTo(this.nav_controls);this.load_chroms({low:0},ad);this.chrom_select.bind("change",function(){aa.change_chrom(aa.chrom_select.val())});this.intro_div.show();this.content_div.bind("click",function(ae){$(this).find("input").trigger("blur")});this.content_div.bind("dblclick",function(ae){aa.zoom_in(ae.pageX,this.viewport_container)});this.overview_box.bind("dragstart",function(ae,af){this.current_x=af.offsetX}).bind("drag",function(ae,ag){var ah=ag.offsetX-this.current_x;this.current_x=ag.offsetX;var af=Math.round(ah/aa.viewport_container.width()*(aa.max_high-aa.max_low));aa.move_delta(-af)});this.overview_close.bind("click",function(){for(var af=0,ae=aa.tracks.length;af<ae;af++){aa.tracks[af].is_overview=false}$(this).siblings().filter("canvas").remove();$(this).parent().css("height",aa.overview_box.height());aa.overview_highlight.hide();$(this).hide()});this.viewport_container.bind("draginit",function(ae,af){if(ae.clientX>aa.viewport_container.width()-16){return false}}).bind("dragstart",function(ae,af){af.original_low=aa.low;af.current_height=ae.clientY;af.current_x=af.offsetX}).bind("drag",function(ag,ai){var ae=$(this);var aj=ai.offsetX-ai.current_x;var af=ae.scrollTop()-(ag.clientY-ai.current_height);ae.scrollTop(af);ai.current_height=ag.clientY;ai.current_x=ai.offsetX;var ah=Math.round(aj/aa.viewport_container.width()*(aa.high-aa.low));aa.move_delta(ah)}).bind("mousewheel",function(ag,ai,af,ae){if(af){var ah=Math.round(-af/aa.viewport_container.width()*(aa.high-aa.low));aa.move_delta(ah)}});this.top_labeltrack.bind("dragstart",function(ae,af){return $("<div />").css({height:aa.content_div.height()+aa.top_labeltrack.height()+aa.nav_labeltrack.height()+1,top:"0px",position:"absolute","background-color":"#ccf",opacity:0.5,"z-index":1000}).appendTo($(this))}).bind("drag",function(ai,aj){$(aj.proxy).css({left:Math.min(ai.pageX,aj.startX),width:Math.abs(ai.pageX-aj.startX)});var af=Math.min(ai.pageX,aj.startX)-aa.container.offset().left,ae=Math.max(ai.pageX,aj.startX)-aa.container.offset().left,ah=(aa.high-aa.low),ag=aa.viewport_container.width();aa.update_location(Math.round(af/ag*ah)+aa.low,Math.round(ae/ag*ah)+aa.low)}).bind("dragend",function(aj,ak){var af=Math.min(aj.pageX,ak.startX),ae=Math.max(aj.pageX,ak.startX),ah=(aa.high-aa.low),ag=aa.viewport_container.width(),ai=aa.low;aa.low=Math.round(af/ag*ah)+ai;aa.high=Math.round(ae/ag*ah)+ai;$(ak.proxy).remove();aa.redraw()});this.add_label_track(new X(this,this.top_labeltrack));this.add_label_track(new X(this,this.nav_labeltrack));$(window).bind("resize",function(){aa.resize_window()});$(document).bind("redraw",function(){aa.redraw()});this.reset();$(window).trigger("resize")},update_location:function(aa,ab){this.location_span.text(commatize(aa)+" - "+commatize(ab));this.nav_input.val(this.chrom+":"+commatize(aa)+"-"+commatize(ab))},load_chroms:function(ab,ac){ab.num=t;$.extend(ab,(this.vis_id!==undefined?{vis_id:this.vis_id}:{dbkey:this.dbkey}));var aa=this;$.ajax({url:chrom_url,data:ab,dataType:"json",success:function(ae){if(ae.chrom_info.length===0){alert("Invalid chromosome: "+ab.chrom);return}if(ae.reference){aa.add_label_track(new x(aa))}aa.chrom_data=ae.chrom_info;var ah='<option value="">Select Chrom/Contig</option>';for(var ag=0,ad=aa.chrom_data.length;ag<ad;ag++){var af=aa.chrom_data[ag].chrom;ah+='<option value="'+af+'">'+af+"</option>"}if(ae.prev_chroms){ah+='<option value="previous">Previous '+t+"</option>"}if(ae.next_chroms){ah+='<option value="next">Next '+t+"</option>"}aa.chrom_select.html(ah);if(ac){ac()}aa.chrom_start_index=ae.start_index},error:function(){alert("Could not load chroms for this dbkey:",aa.dbkey)}})},change_chrom:function(ae,ab,ag){if(!ae||ae==="None"){return}var ad=this;if(ae==="previous"){ad.load_chroms({low:this.chrom_start_index-t});return}if(ae==="next"){ad.load_chroms({low:this.chrom_start_index+t});return}var af=$.grep(ad.chrom_data,function(ai,aj){return ai.chrom===ae})[0];if(af===undefined){ad.load_chroms({chrom:ae},function(){ad.change_chrom(ae,ab,ag)});return}else{if(ae!==ad.chrom){ad.chrom=ae;if(!ad.chrom){ad.intro_div.show()}else{ad.intro_div.hide()}ad.chrom_select.val(ad.chrom);ad.max_high=af.len-1;ad.reset();ad.redraw(true);for(var ah=0,aa=ad.tracks.length;ah<aa;ah++){var ac=ad.tracks[ah];if(ac.init){ac.init()}}}if(ab!==undefined&&ag!==undefined){ad.low=Math.max(ab,0);ad.high=Math.min(ag,ad.max_high)}ad.reset_overview();ad.redraw()}},go_to:function(ae){var ai=this,aa,ad,ab=ae.split(":"),ag=ab[0],ah=ab[1];if(ah!==undefined){try{var af=ah.split("-");aa=parseInt(af[0].replace(/,/g,""),10);ad=parseInt(af[1].replace(/,/g,""),10)}catch(ac){return false}}ai.change_chrom(ag,aa,ad)},move_fraction:function(ac){var aa=this;var ab=aa.high-aa.low;this.move_delta(ac*ab)},move_delta:function(ac){var aa=this;var ab=aa.high-aa.low;if(aa.low-ac<aa.max_low){aa.low=aa.max_low;aa.high=aa.max_low+ab}else{if(aa.high-ac>aa.max_high){aa.high=aa.max_high;aa.low=aa.max_high-ab}else{aa.high-=ac;aa.low-=ac}}aa.redraw()},add_track:function(aa){aa.view=this;aa.track_id=this.track_id_counter;this.tracks.push(aa);if(aa.init){aa.init()}aa.container_div.attr("id","track_"+aa.track_id);C(aa.container_div,".draghandle");this.track_id_counter+=1;this.num_tracks+=1},add_label_track:function(aa){aa.view=this;this.label_tracks.push(aa)},remove_track:function(aa){this.has_changes=true;aa.container_div.fadeOut("slow",function(){$(this).remove()});delete this.tracks[this.tracks.indexOf(aa)];this.num_tracks-=1},reset:function(){this.low=this.max_low;this.high=this.max_high;this.viewport_container.find(".yaxislabel").remove()},redraw:function(ah){var ag=this.high-this.low,af=this.low,ab=this.high;if(af<this.max_low){af=this.max_low}if(ab>this.max_high){ab=this.max_high}if(this.high!==0&&ag<this.min_separation){ab=af+this.min_separation}this.low=Math.floor(af);this.high=Math.ceil(ab);this.resolution=Math.pow(z,Math.ceil(Math.log((this.high-this.low)/M)/Math.log(z)));this.zoom_res=Math.pow(s,Math.max(0,Math.ceil(Math.log(this.resolution,s)/Math.log(s))));var aa=(this.low/(this.max_high-this.max_low)*this.overview_viewport.width())||0;var ae=((this.high-this.low)/(this.max_high-this.max_low)*this.overview_viewport.width())||0;var ai=13;this.overview_box.css({left:aa,width:Math.max(ai,ae)}).show();if(ae<ai){this.overview_box.css("left",aa-(ai-ae)/2)}if(this.overview_highlight){this.overview_highlight.css({left:aa,width:ae})}this.update_location(this.low,this.high);if(!ah){for(var ac=0,ad=this.tracks.length;ac<ad;ac++){if(this.tracks[ac]&&this.tracks[ac].enabled){this.tracks[ac].draw()}}for(ac=0,ad=this.label_tracks.length;ac<ad;ac++){this.label_tracks[ac].draw()}}},zoom_in:function(ab,ac){if(this.max_high===0||this.high-this.low<this.min_separation){return}var ad=this.high-this.low,ae=ad/2+this.low,aa=(ad/this.zoom_factor)/2;if(ab){ae=ab/this.viewport_container.width()*(this.high-this.low)+this.low}this.low=Math.round(ae-aa);this.high=Math.round(ae+aa);this.redraw()},zoom_out:function(){if(this.max_high===0){return}var ab=this.high-this.low,ac=ab/2+this.low,aa=(ab*this.zoom_factor)/2;this.low=Math.round(ac-aa);this.high=Math.round(ac+aa);this.redraw()},resize_window:function(){this.viewport_container.height(this.container.height()-this.top_container.height()-this.bottom_container.height());this.nav_container.width(this.container.width());this.redraw()},reset_overview:function(){this.overview_viewport.find("canvas").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()}});var o=function(ac,ag){this.track=ac;this.name=ag.name;this.params=[];var an=ag.params;for(var ad=0;ad<an.length;ad++){var ai=an[ad],ab=ai.name,am=ai.label,ae=unescape(ai.html),ao=ai.value,ak=ai.type;if(ak==="number"){this.params[this.params.length]=new g(ab,am,ae,ao,ai.min,ai.max)}else{if(ak=="select"){this.params[this.params.length]=new K(ab,am,ae,ao)}else{console.log("WARNING: unrecognized tool parameter type:",ab,ak)}}}this.parent_div=$("<div/>").addClass("dynamic-tool").hide();this.parent_div.bind("drag",function(aq){aq.stopPropagation()}).bind("click",function(aq){aq.stopPropagation()}).bind("dblclick",function(aq){aq.stopPropagation()});var al=$("<div class='tool-name'>").appendTo(this.parent_div).text(this.name);var aj=this.params;var ah=this;$.each(this.params,function(ar,av){var au=$("<div>").addClass("param-row").appendTo(ah.parent_div);var aq=$("<div>").addClass("param-label").text(av.label).appendTo(au);var at=$("<div/>").addClass("slider").html(av.html).appendTo(au);at.find(":input").val(av.value);$("<div style='clear: both;'/>").appendTo(au)});this.parent_div.find("input").click(function(){$(this).select()});var ap=$("<div>").addClass("param-row").appendTo(this.parent_div);var af=$("<input type='submit'>").attr("value","Run on complete dataset").appendTo(ap);var aa=$("<input type='submit'>").attr("value","Run on visible region").css("margin-left","3em").appendTo(ap);var ah=this;aa.click(function(){ah.run_on_region()});af.click(function(){ah.run_on_dataset()})};n(o.prototype,{get_param_values_dict:function(){var aa={};this.parent_div.find(":input").each(function(){var ab=$(this).attr("name"),ac=$(this).val();aa[ab]=JSON.stringify(ac)});return aa},get_param_values:function(){var ab=[];var aa={};this.parent_div.find(":input").each(function(){var ac=$(this).attr("name"),ad=$(this).val();if(ac){ab[ab.length]=ad}});return ab},run_on_dataset:function(){var aa=this;aa.run({dataset_id:this.track.original_dataset_id,tool_id:aa.name},function(ab){show_modal(aa.name+" is Running",aa.name+" is running on the complete dataset. Tool outputs are in dataset's history.",{Close:hide_modal})})},run_on_region:function(){var aa={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},ac=this.track,ab=aa.tool_id+ac.tool_region_and_parameters_str(aa.chrom,aa.low,aa.high),ad;if(ac instanceof e){ad=new Q(ab,view,ac.hda_ldda,undefined,{},{},ac);ad.change_mode(ac.mode)}this.track.add_track(ad);ad.content_div.text("Starting job.");this.run(aa,function(ae){ad.dataset_id=ae.dataset_id;ad.content_div.text("Running job.");ad.init()})},run:function(ab,ac){$.extend(ab,this.get_param_values_dict());var aa=function(){$.getJSON(rerun_tool_url,ab,function(ad){if(ad==="no converter"){new_track.container_div.addClass("error");new_track.content_div.text(G)}else{if(ad.error){new_track.container_div.addClass("error");new_track.content_div.text(v+ad.message)}else{if(ad==="pending"){new_track.container_div.addClass("pending");new_track.content_div.text("Converting input data so that it can be easily reused.");setTimeout(aa,2000)}else{ac(ad)}}}})};aa()}});var K=function(ab,aa,ac,ad){this.name=ab;this.label=aa;this.html=ac;this.value=ad};var g=function(ac,ab,ae,af,ad,aa){K.call(this,ac,ab,ae,af);this.min=ad;this.max=aa};var h=function(ab,aa,ac,ad){this.name=ab;this.index=aa;this.tool_id=ac;this.tool_exp_name=ad};var R=function(ab,aa,ac,ad){h.call(this,ab,aa,ac,ad);this.low=-Number.MAX_VALUE;this.high=Number.MAX_VALUE;this.min=Number.MAX_VALUE;this.max=-Number.MAX_VALUE;this.slider=null;this.slider_label=null};n(R.prototype,{applies_to:function(aa){if(aa.length>this.index){return true}return false},keep:function(aa){if(!this.applies_to(aa)){return true}var ab=parseInt(aa[this.index]);return(isNaN(ab)||(ab>=this.low&&ab<=this.high))},update_attrs:function(ab){var aa=false;if(!this.applies_to(ab)){return aa}if(ab[this.index]<this.min){this.min=Math.floor(ab[this.index]);aa=true}if(ab[this.index]>this.max){this.max=Math.ceil(ab[this.index]);aa=true}return aa},update_ui_elt:function(){var ac=function(af,ad){var ae=ad-af;return(ae<=2?0.01:1)};var ab=this.slider.slider("option","min"),aa=this.slider.slider("option","max");if(this.min<ab||this.max>aa){this.slider.slider("option","min",this.min);this.slider.slider("option","max",this.max);this.slider.slider("option","step",ac(this.min,this.max));this.slider.slider("option","values",[this.min,this.max])}}});var W=function(ac,al){this.track=ac;this.filters=[];for(var ag=0;ag<al.length;ag++){var aa=al[ag],ab=aa.name,ak=aa.type,ai=aa.index,an=aa.tool_id,ad=aa.tool_exp_name;if(ak==="int"||ak==="float"){this.filters[ag]=new R(ab,ai,an,ad)}else{console.log("ERROR: unsupported filter: ",ab,ak)}}var aj=function(ao,ap,aq){ao.click(function(){var ar=ap.text();max=parseFloat(aq.slider("option","max")),input_size=(max<=1?4:max<=1000000?max.toString().length:6),multi_value=false;if(aq.slider("option","values")){input_size=2*input_size+1;multi_value=true}ap.text("");$("<input type='text'/>").attr("size",input_size).attr("maxlength",input_size).attr("value",ar).appendTo(ap).focus().select().click(function(at){at.stopPropagation()}).blur(function(){$(this).remove();ap.text(ar)}).keyup(function(ax){if(ax.keyCode===27){$(this).trigger("blur")}else{if(ax.keyCode===13){var av=aq.slider("option","min"),at=aq.slider("option","max"),aw=function(ay){return(isNaN(ay)||ay>at||ay<av)},au=$(this).val();if(!multi_value){au=parseFloat(au);if(aw(au)){alert("Parameter value must be in the range ["+av+"-"+at+"]");return $(this)}}else{au=au.split("-");au=[parseFloat(au[0]),parseFloat(au[1])];if(aw(au[0])||aw(au[1])){alert("Parameter value must be in the range ["+av+"-"+at+"]");return $(this)}}aq.slider((multi_value?"values":"value"),au)}}})})};this.parent_div=$("<div/>").addClass("filters").hide();this.parent_div.bind("drag",function(ao){ao.stopPropagation()}).bind("click",function(ao){ao.stopPropagation()}).bind("dblclick",function(ao){ao.stopPropagation()}).bind("keydown",function(ao){ao.stopPropagation()});var ae=this;$.each(this.filters,function(av,ap){var ar=$("<div/>").addClass("slider-row").appendTo(ae.parent_div);var ao=$("<div/>").addClass("slider-label").appendTo(ar);var ax=$("<span/>").addClass("slider-name").text(ap.name+" ").appendTo(ao);var aq=$("<span/>");var at=$("<span/>").addClass("slider-value").appendTo(ao).append("[").append(aq).append("]");var aw=$("<div/>").addClass("slider").appendTo(ar);ap.control_element=$("<div/>").attr("id",ap.name+"-filter-control").appendTo(aw);var au=[0,0];ap.control_element.slider({range:true,min:Number.MAX_VALUE,max:-Number.MIN_VALUE,values:[0,0],slide:function(ay,az){au=az.values;aq.text(az.values[0]+"-"+az.values[1]);setTimeout(function(){if(az.values[0]==au[0]&&az.values[1]==au[1]){var aA=az.values;aq.text(aA[0]+"-"+aA[1]);ap.low=aA[0];ap.high=aA[1];ae.track.draw(true,true)}},50)},change:function(ay,az){ap.control_element.slider("option","slide").call(ap.control_element,ay,az)}});ap.slider=ap.control_element;ap.slider_label=aq;aj(at,aq,ap.control_element);$("<div style='clear: both;'/>").appendTo(ar)});if(this.filters.length!=0){var am=$("<div>").addClass("param-row").appendTo(this.parent_div);var ah=$("<input type='submit'>").attr("value","Run on complete dataset").appendTo(am);var af=this;ah.click(function(){af.run_on_dataset()})}};n(W.prototype,{reset_filters:function(){for(var aa=0;aa<this.filters.length;aa++){filter=this.filters[aa];filter.slider.slider("option","values",[filter.min,filter.max])}},run_on_dataset:function(){var ai=function(am,ak,al){if(!(ak in am)){am[ak]=al}return am[ak]};var ac={},aa,ab,ad;for(var ae=0;ae<this.filters.length;ae++){aa=this.filters[ae];if(aa.tool_id){if(aa.min!=aa.low){ab=ai(ac,aa.tool_id,[]);ab[ab.length]=aa.tool_exp_name+" >= "+aa.low}if(aa.max!=aa.high){ab=ai(ac,aa.tool_id,[]);ab[ab.length]=aa.tool_exp_name+" <= "+aa.high}}}var ag=[];for(var aj in ac){ag[ag.length]=[aj,ac[aj]]}var ah=ag.length;(function af(aq,an){var al=an[0],am=al[0],ap=al[1],ao="("+ap.join(") and (")+")",ak={cond:ao,input:aq,target_dataset_id:aq,tool_id:am},an=an.slice(1);$.getJSON(run_tool_url,ak,function(ar){if(ar.error){show_modal("Filter Dataset","Error running tool "+am,{Close:hide_modal})}else{if(an.length===0){show_modal("Filtering Dataset","Filter(s) are running on the complete dataset. Outputs are in dataset's history.",{Close:hide_modal})}else{af(ar.dataset_id,an)}}})})(this.track.dataset_id,ag)}});var V=function(aa){this.track=aa.track;this.params=aa.params;this.values={};if(aa.saved_values){this.restore_values(aa.saved_values)}this.onchange=aa.onchange};n(V.prototype,{restore_values:function(aa){var ab=this;$.each(this.params,function(ac,ad){if(aa[ad.key]!==undefined){ab.values[ad.key]=aa[ad.key]}else{ab.values[ad.key]=ad.default_value}})},build_form:function(){var ab=this;var aa=$("<div />");$.each(this.params,function(af,ad){if(!ad.hidden){var ac="param_"+af;var ak=$("<div class='form-row' />").appendTo(aa);ak.append($("<label />").attr("for",ac).text(ad.label+":"));if(ad.type==="bool"){ak.append($('<input type="checkbox" />').attr("id",ac).attr("name",ac).attr("checked",ab.values[ad.key]))}else{if(ad.type==="color"){var ah=ab.values[ad.key];var ag=$("<input />").attr("id",ac).attr("name",ac).val(ah);var ai=$("<div class='tipsy tipsy-north' style='position: absolute;' />").hide();var ae=$("<div style='background-color: black; padding: 10px;'></div>").appendTo(ai);var aj=$("<div/>").appendTo(ae).farbtastic({width:100,height:100,callback:ag,color:ah});$("<div />").append(ag).append(ai).appendTo(ak).bind("click",function(al){ai.css({left:$(this).position().left+($(ag).width()/2)-60,top:$(this).position().top+$(this.height)}).show();$(document).bind("click.color-picker",function(){ai.hide();$(document).unbind("click.color-picker")});al.stopPropagation()})}else{ak.append($("<input />").attr("id",ac).attr("name",ac).val(ab.values[ad.key]))}}}});return aa},update_from_form:function(aa){var ac=this;var ab=false;$.each(this.params,function(ad,af){if(!af.hidden){var ag="param_"+ad;var ae=aa.find("#"+ag).val();if(af.type==="float"){ae=parseFloat(ae)}else{if(af.type==="int"){ae=parseInt(ae)}else{if(af.type==="bool"){ae=aa.find("#"+ag).is(":checked")}}}if(ae!==ac.values[af.key]){ac.values[af.key]=ae;ab=true}}});if(ab){this.onchange()}}});var b=function(ac,ab,aa){this.index=ac;this.resolution=ab;this.canvas=$("<div class='track-tile'/>").append(aa)};var l=function(ac,ab,aa,ad){b.call(this,ac,ab,aa);this.max_val=ad};var L=function(ac,ab,aa,ad){b.call(this,ac,ab,aa);this.message=ad};var j=function(ab,aa,ae,ac,ad){this.name=ab;this.view=aa;this.parent_element=ae;this.data_url=(ac?ac:default_data_url);this.data_url_extra_params={};this.data_query_wait=(ad?ad:H);this.dataset_check_url=converted_datasets_state_url;this.container_div=$("<div />").addClass("track").css("position","relative");if(!this.hidden){this.header_div=$("<div class='track-header' />").appendTo(this.container_div);if(this.view.editor){this.drag_div=$("<div class='draghandle' />").appendTo(this.header_div)}this.name_div=$("<div class='menubutton popup' />").appendTo(this.header_div);this.name_div.text(this.name);this.name_div.attr("id",this.name.replace(/\s+/g,"-").replace(/[^a-zA-Z0-9\-]/g,"").toLowerCase())}this.content_div=$("<div class='track-content'>").appendTo(this.container_div);this.parent_element.append(this.container_div)};n(j.prototype,{init:function(){var aa=this;aa.enabled=false;aa.tile_cache.clear();aa.data_cache.clear();aa.initial_canvas=undefined;aa.content_div.css("height","auto");aa.container_div.removeClass("nodata error pending");if(!aa.dataset_id){return}$.getJSON(converted_datasets_state_url,{hda_ldda:aa.hda_ldda,dataset_id:aa.dataset_id,chrom:aa.view.chrom},function(ab){if(!ab||ab==="error"||ab.kind==="error"){aa.container_div.addClass("error");aa.content_div.text(m);if(ab.message){var ad=aa.view.tracks.indexOf(aa);var ac=$(" <a href='javascript:void(0);'></a>").text("View error").bind("click",function(){show_modal("Trackster Error","<pre>"+ab.message+"</pre>",{Close:hide_modal})});aa.content_div.append(ac)}}else{if(ab==="no converter"){aa.container_div.addClass("error");aa.content_div.text(G)}else{if(ab==="no data"||(ab.data!==undefined&&(ab.data===null||ab.data.length===0))){aa.container_div.addClass("nodata");aa.content_div.text(B)}else{if(ab==="pending"){aa.container_div.addClass("pending");aa.content_div.text(q);setTimeout(function(){aa.init()},aa.data_query_wait)}else{if(ab.status==="data"){if(ab.valid_chroms){aa.valid_chroms=ab.valid_chroms;aa.make_name_popup_menu()}aa.content_div.text(U);if(aa.view.chrom){aa.content_div.text("");aa.content_div.css("height",aa.height_px+"px");aa.enabled=true;$.when(aa.predraw_init()).done(function(){aa.container_div.removeClass("nodata error pending");aa.draw()})}}}}}}})},predraw_init:function(){},update_name:function(aa){this.old_name=this.name;this.name=aa;this.name_div.text(this.name)},revert_name:function(){this.name=this.old_name;this.name_div.text(this.name)}});var J=function(ah,af,ai){var ab=this,aj=ab.view;this.filters_manager=(ah!==undefined?new W(this,ah):undefined);this.filters_available=false;this.filters_visible=false;this.tool=(af!==undefined&&obj_length(af)>0?new o(this,af):undefined);this.parent_track=ai;this.child_tracks=[];if(ab.hidden){return}if(this.parent_track){this.header_div.find(".draghandle").removeClass("draghandle").addClass("child-track-icon").addClass("icon-button");this.parent_element.addClass("child-track");this.tool=undefined}ab.child_tracks_container=$("<div/>").addClass("child-tracks-container").hide();ab.container_div.append(ab.child_tracks_container);if(this.filters_manager){this.filters_div=this.filters_manager.parent_div;this.header_div.after(this.filters_div)}if(this.tool){this.dynamic_tool_div=this.tool.parent_div;this.header_div.after(this.dynamic_tool_div)}if(ab.display_modes!==undefined){if(ab.mode_div===undefined){ab.mode_div=$("<div class='right-float menubutton popup' />").appendTo(ab.header_div);var ac=(ab.track_config&&ab.track_config.values.mode?ab.track_config.values.mode:ab.display_modes[0]);ab.mode=ac;ab.mode_div.text(ac);var aa={};for(var ad=0,ag=ab.display_modes.length;ad<ag;ad++){var ae=ab.display_modes[ad];aa[ae]=function(ak){return function(){ab.change_mode(ak)}}(ae)}make_popupmenu(ab.mode_div,aa)}else{ab.mode_div.hide()}}this.make_name_popup_menu()};n(J.prototype,j.prototype,{change_mode:function(ab){var aa=this;aa.mode_div.text(ab);aa.mode=ab;aa.track_config.values.mode=ab;aa.tile_cache.clear();aa.draw()},make_name_popup_menu:function(){var ab=this;var aa={};aa["Edit configuration"]=function(){var ah=function(){hide_modal();$(window).unbind("keypress.check_enter_esc")},af=function(){ab.track_config.update_from_form($(".dialog-box"));hide_modal();$(window).unbind("keypress.check_enter_esc")},ag=function(ai){if((ai.keyCode||ai.which)===27){ah()}else{if((ai.keyCode||ai.which)===13){af()}}};$(window).bind("keypress.check_enter_esc",ag);show_modal("Configure Track",ab.track_config.build_form(),{Cancel:ah,OK:af})};if(ab.filters_available>0){var ae=(ab.filters_div.is(":visible")?"Hide filters":"Show filters");aa[ae]=function(){ab.filters_visible=(ab.filters_div.is(":visible"));if(ab.filters_visible){ab.filters_manager.reset_filters()}ab.filters_div.toggle();ab.make_name_popup_menu()}}if(ab.tool){var ae=(ab.dynamic_tool_div.is(":visible")?"Hide tool":"Show tool");aa[ae]=function(){if(!ab.dynamic_tool_div.is(":visible")){ab.update_name(ab.name+ab.tool_region_and_parameters_str())}else{menu_option_text="Show dynamic tool";ab.revert_name()}ab.dynamic_tool_div.toggle();ab.make_name_popup_menu()}}if(ab.valid_chroms){aa["List chrom/contigs with data"]=function(){show_modal("Chrom/contigs with data","<p>"+ab.valid_chroms.join("<br/>")+"</p>",{Close:function(){hide_modal()}})}}var ac=view;var ad=function(){$("#no-tracks").show()};if(this.parent_track){ac=this.parent_track;ad=function(){}}aa.Remove=function(){ac.remove_track(ab);if(ac.num_tracks===0){ad()}};make_popupmenu(ab.name_div,aa)},draw:function(aa,ac){if(!this.dataset_id){return}var au=this.view.low,ag=this.view.high,ai=ag-au,ak=this.view.container.width(),ae=ak/ai,al=this.view.resolution,ad=$("<div style='position: relative;'></div>"),am=function(aw,ax,av){return aw+"_"+ax+"_"+av};if(!ac){this.content_div.children().remove()}this.content_div.append(ad);this.max_height=0;var ao=Math.floor(au/al/M);var af=[];var ap=0;while((ao*M*al)<ag){var at=am(ak,ae,ao);var ah=this.tile_cache.get(at);var aq=ao*M*this.view.resolution;var ab=aq+M*this.view.resolution;if(!aa&&ah){af[af.length]=ah;this.show_tile(ah,ad,aq,ae)}else{this.delayed_draw(aa,at,ao,al,ad,ae,af)}ao+=1;ap++}var aj=this;var ar=setInterval(function(){if(af.length===ap){clearInterval(ar);if(ac){var aA=aj.content_div.children();var aB=false;for(var az=aA.length-1,aF=0;az>=aF;az--){var ay=$(aA[az]);if(aB){ay.remove()}else{if(ay.children().length!==0){aB=true}}}}if(aj instanceof e&&aj.mode=="Histogram"){var aE=-1;for(var az=0;az<af.length;az++){var aH=af[az].max_val;if(aH>aE){aE=aH}}for(var az=0;az<af.length;az++){if(af[az].max_val!==aE){var aG=af[az];aG.canvas.remove();aj.delayed_draw(true,am(ak,ae,aG.index),aG.index,aG.resolution,ad,ae,[],{max:aE})}}}if(aj.filters_manager){var ax=aj.filters_manager.filters;for(var aD=0;aD<ax.length;aD++){ax[aD].update_ui_elt()}var aC=false;if(aj.example_feature){for(var aD=0;aD<ax.length;aD++){if(ax[aD].applies_to(aj.example_feature)){aC=true;break}}}if(aj.filters_available!==aC){aj.filters_available=aC;if(!aj.filters_available){aj.filters_div.hide()}aj.make_name_popup_menu()}}var av=false;for(var aw=0;aw<af.length;aw++){if(af[aw].message){av=true;break}}if(av){for(var aw=0;aw<af.length;aw++){aG=af[aw];if(!aG.message){aG.canvas.css("padding-top",A)}}}}},50);for(var an=0;an<this.child_tracks.length;an++){this.child_tracks[an].draw(aa,ac)}},delayed_draw:function(ab,ai,ac,ae,aj,am,ak,af){var ad=this,ag=ac*M*ae,al=ag+M*ae;var ah=function(av,an,ap,ao,at,au,aq){var ar=ad.draw_tile(an,ap,ao,au,aq);ad.tile_cache.set(ai,ar);if(ar===undefined){return}ad.show_tile(ar,at,ag,au);ak[ak.length]=ar};var aa=setTimeout(function(){if(ag<=ad.view.high&&al>=ad.view.low){var an=(ab?undefined:ad.tile_cache.get(ai));if(an){ad.show_tile(an,aj,ag,am);ak[ak.length]=an}else{$.when(ad.data_cache.get_data(view.chrom,ag,al,ad.mode,ae,ad.data_url_extra_params)).then(function(ao){n(ao,af);if(view.reference_track&&am>view.canvas_manager.char_width_px){$.when(view.reference_track.data_cache.get_data(view.chrom,ag,al,ad.mode,ae,view.reference_track.data_url_extra_params)).then(function(ap){ah(aa,ao,ae,ac,aj,am,ap)})}else{ah(aa,ao,ae,ac,aj,am)}})}}},50)},show_tile:function(ad,ag,ae,ah){var ab=this;var ac=this.view.high-this.view.low,af=(ae-this.view.low)*ah;if(this.left_offset){af-=this.left_offset}var aa=ad.canvas;aa.css({position:"absolute",top:0,left:af,height:""});ag.append(aa);ab.max_height=Math.max(ab.max_height,aa.height());ab.content_div.css("height",ab.max_height+"px");ag.children().css("height",ab.max_height+"px")},set_overview:function(){var aa=this.view;if(this.initial_canvas&&this.is_overview){aa.overview_close.show();aa.overview_viewport.append(this.initial_canvas);aa.overview_highlight.show().height(this.initial_canvas.height());aa.overview_viewport.height(this.initial_canvas.height()+aa.overview_box.height())}$(window).trigger("resize")},tool_region_and_parameters_str:function(ac,aa,ad){var ab=this,ae=(ac!==undefined&&aa!==undefined&&ad!==undefined?ac+":"+aa+"-"+ad:"all");return" - region=["+ae+"], parameters=["+ab.tool.get_param_values().join(", ")+"]"},add_track:function(aa){aa.track_id=this.track_id+"_"+this.child_tracks.length;aa.container_div.attr("id","track_"+aa.track_id);this.child_tracks_container.append(aa.container_div);C(aa.container_div,".child-track-icon");if(!$(this.child_tracks_container).is(":visible")){this.child_tracks_container.show()}this.child_tracks.push(aa);this.view.has_changes=true},remove_track:function(aa){aa.container_div.fadeOut("slow",function(){$(this).remove()})}});var X=function(aa,ab){this.hidden=true;j.call(this,null,aa,ab);this.container_div.addClass("label-track")};n(X.prototype,j.prototype,{draw:function(){var ac=this.view,ad=ac.high-ac.low,ag=Math.floor(Math.pow(10,Math.floor(Math.log(ad)/Math.log(10)))),aa=Math.floor(ac.low/ag)*ag,ae=this.view.container.width(),ab=$("<div style='position: relative; height: 1.3em;'></div>");while(aa<ac.high){var af=(aa-ac.low)/ad*ae;ab.append($("<div class='label'>"+commatize(aa)+"</div>").css({position:"absolute",left:af-1}));aa+=ag}this.content_div.children(":first").remove();this.content_div.append(ab)}});var x=function(aa){this.hidden=true;j.call(this,null,aa,aa.top_labeltrack);J.call(this);aa.reference_track=this;this.left_offset=200;this.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:aa.dbkey};this.data_cache=new E(y,this,false);this.tile_cache=new c(r)};n(x.prototype,J.prototype,{draw_tile:function(ai,af,ab,ak){var ae=this,ac=M*af;if(ak>this.view.canvas_manager.char_width_px){if(ai===null){ae.content_div.css("height","0px");return}var ad=this.view.canvas_manager.new_canvas();var aj=ad.getContext("2d");ad.width=Math.ceil(ac*ak+ae.left_offset);ad.height=ae.height_px;aj.font=aj.canvas.manager.default_font;aj.textAlign="center";for(var ag=0,ah=ai.length;ag<ah;ag++){var aa=Math.round(ag*ak);aj.fillText(ai[ag],aa+ae.left_offset,10)}return new b(ab,af,ad)}this.content_div.css("height","0px")}});var k=function(ae,ac,af,aa,ad){var ab=this;this.display_modes=["Histogram","Line","Filled","Intensity"];this.mode="Histogram";j.call(this,ae,ac,ac.viewport_container);J.call(this);this.min_height_px=16;this.max_height_px=400;this.height_px=80;this.hda_ldda=af;this.dataset_id=aa;this.original_dataset_id=aa;this.data_cache=new N(y,this);this.tile_cache=new c(r);this.track_config=new V({track:this,params:[{key:"color",label:"Color",type:"color",default_value:"black"},{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:this.height_px,hidden:true}],saved_values:ad,onchange:function(){ab.vertical_range=ab.prefs.max_value-ab.prefs.min_value;$("#linetrack_"+ab.track_id+"_minval").text(ab.prefs.min_value);$("#linetrack_"+ab.track_id+"_maxval").text(ab.prefs.max_value);ab.tile_cache.clear();ab.draw()}});this.prefs=this.track_config.values;this.height_px=this.track_config.values.height;this.vertical_range=this.track_config.values.max_value-this.track_config.values.min_value;this.add_resize_handle()};n(k.prototype,J.prototype,{add_resize_handle:function(){var aa=this;var ad=false;var ac=false;var ab=$("<div class='track-resize'>");$(aa.container_div).hover(function(){ad=true;ab.show()},function(){ad=false;if(!ac){ab.hide()}});ab.hide().bind("dragstart",function(ae,af){ac=true;af.original_height=$(aa.content_div).height()}).bind("drag",function(af,ag){var ae=Math.min(Math.max(ag.original_height+ag.deltaY,aa.min_height_px),aa.max_height_px);$(aa.content_div).css("height",ae);aa.height_px=ae;aa.draw(true)}).bind("dragend",function(ae,af){aa.tile_cache.clear();ac=false;if(!ad){ab.hide()}aa.track_config.values.height=aa.height_px}).appendTo(aa.container_div)},predraw_init:function(){var aa=this,ab=aa.view.tracks.indexOf(aa);aa.vertical_range=undefined;return $.getJSON(aa.data_url,{stats:true,chrom:aa.view.chrom,low:null,high:null,hda_ldda:aa.hda_ldda,dataset_id:aa.dataset_id},function(ac){aa.container_div.addClass("line-track");var ae=ac.data;if(isNaN(parseFloat(aa.prefs.min_value))||isNaN(parseFloat(aa.prefs.max_value))){aa.prefs.min_value=ae.min;aa.prefs.max_value=ae.max;$("#track_"+ab+"_minval").val(aa.prefs.min_value);$("#track_"+ab+"_maxval").val(aa.prefs.max_value)}aa.vertical_range=aa.prefs.max_value-aa.prefs.min_value;aa.total_frequency=ae.total_frequency;aa.container_div.find(".yaxislabel").remove();var af=$("<div />").addClass("yaxislabel").attr("id","linetrack_"+ab+"_minval").text(u(aa.prefs.min_value));var ad=$("<div />").addClass("yaxislabel").attr("id","linetrack_"+ab+"_maxval").text(u(aa.prefs.max_value));ad.css({position:"absolute",top:"24px",left:"10px"});ad.prependTo(aa.container_div);af.css({position:"absolute",bottom:"2px",left:"10px"});af.prependTo(aa.container_div)})},draw_tile:function(ak,ae,ab,aj){if(this.vertical_range===undefined){return}var af=ab*M*ae,ad=M*ae,aa=Math.ceil(ad*aj),ah=this.height_px;var ac=this.view.canvas_manager.new_canvas();ac.width=aa,ac.height=ah;var ai=ac.getContext("2d");var ag=new I.LinePainter(ak.data,af,af+ad,this.prefs,this.mode);ag.draw(ai,aa,ah);return new b(ad,ae,ac)}});var e=function(aa,af,ae,ai,ah,ac,ad,ag){var ab=this;this.display_modes=["Auto","Histogram","Dense","Squish","Pack"];this.track_config=new V({track:this,params:[{key:"block_color",label:"Block color",type:"color",default_value:"#444"},{key:"label_color",label:"Label color",type:"color",default_value:"black"},{key:"show_counts",label:"Show summary counts",type:"bool",default_value:true},{key:"mode",type:"string",default_value:this.mode,hidden:true},],saved_values:ah,onchange:function(){ab.tile_cache.clear();ab.draw()}});this.prefs=this.track_config.values;j.call(this,aa,af,af.viewport_container);J.call(this,ac,ad,ag);this.height_px=0;this.container_div.addClass("feature-track");this.hda_ldda=ae;this.dataset_id=ai;this.original_dataset_id=ai;this.show_labels_scale=0.001;this.showing_details=false;this.summary_draw_height=30;this.inc_slots={};this.start_end_dct={};this.tile_cache=new c(d);this.data_cache=new N(20,this);this.left_offset=200;this.painter=I.LinkedFeaturePainter};n(e.prototype,J.prototype,{update_auto_mode:function(aa){if(this.mode=="Auto"){if(aa=="no_detail"){aa="feature spans"}else{if(aa=="summary_tree"){aa="coverage histogram"}}this.mode_div.text("Auto ("+aa+")")}},incremental_slots:function(ae,ab,ad){var ac=this.view.canvas_manager.dummy_context,aa=this.inc_slots[ae];if(!aa||(aa.mode!==ad)){aa=new (p.FeatureSlotter)(ae,ad==="Pack",w,function(af){return ac.measureText(af)});aa.mode=ad;this.inc_slots[ae]=aa}return aa.slot_features(ab)},get_summary_tree_data:function(ae,ah,ac,ap){if(ap>ac-ah){ap=ac-ah}var al=Math.floor((ac-ah)/ap),ao=[],ad=0;var af=0,ag=0,ak,an=0,ai=[],am,aj;var ab=function(at,ar,au,aq){at[0]=ar+au*aq;at[1]=ar+(au+1)*aq};while(an<ap&&af!==ae.length){var aa=false;for(;an<ap&&!aa;an++){ab(ai,ah,an,al);for(ag=af;ag<ae.length;ag++){ak=ae[ag].slice(1,3);if(is_overlap(ak,ai)){aa=true;break}}if(aa){break}}data_start_index=ag;ao[ao.length]=am=[ai[0],0];for(;ag<ae.length;ag++){ak=ae[ag].slice(1,3);if(is_overlap(ak,ai)){am[1]++}else{break}}if(am[1]>ad){ad=am[1]}an++}return{max:ad,delta:al,data:ao}},draw_tile:function(an,aw,aA,aj,ad){var at=this,aC=aA*M*aw,ab=(aA+1)*M*aw,ap=ab-aC,au=Math.ceil(ap*aj),aq=this.mode,aH=25,ae=this.left_offset,ao,af;if(aq==="Auto"){if(an.dataset_type==="summary_tree"){aq=an.dataset_type}else{if(an.extra_info==="no_detail"){aq="no_detail"}else{var aG=an.data;if(this.view.high-this.view.low>F){aq="Squish"}else{aq="Pack"}}}this.update_auto_mode(aq)}if(aq==="summary_tree"||aq==="Histogram"){af=this.summary_draw_height;this.container_div.find(".yaxislabel").remove();var aa=$("<div />").addClass("yaxislabel");aa.text(an.max);aa.css({position:"absolute",top:"24px",left:"10px",color:this.prefs.label_color});aa.prependTo(this.container_div);var ac=this.view.canvas_manager.new_canvas();ac.width=au+ae;ac.height=af+O;if(an.dataset_type!="summary_tree"){var ak=this.get_summary_tree_data(an.data,aC,ab,200);if(an.max){ak.max=an.max}an=ak}var aE=new I.SummaryTreePainter(an,aC,ab,this.prefs);var av=ac.getContext("2d");av.translate(ae,O);aE.draw(av,au,af);return new l(aA,aw,ac,an.max)}var ao,ah=1;if(aq==="no_detail"||aq==="Squish"||aq==="Pack"){ah=this.incremental_slots(aj,an.data,aq);ao=this.inc_slots[aj].slots}var ai=[];if(an.data){var al=this.filters_manager.filters;for(var ax=0,az=an.data.length;ax<az;ax++){var ag=an.data[ax];var ay=false;var am;for(var aB=0,aF=al.length;aB<aF;aB++){am=al[aB];am.update_attrs(ag);if(!am.keep(ag)){ay=true;break}}if(!ay){ai.push(ag)}}}var aE=new (this.painter)(ai,aC,ab,this.prefs,aq,ad);var af=aE.get_required_height(ah);var ac=this.view.canvas_manager.new_canvas();ac.width=au+ae;ac.height=af;var av=ac.getContext("2d");av.fillStyle=this.prefs.block_color;av.font=av.canvas.manager.default_font;av.textAlign="right";this.container_div.find(".yaxislabel").remove();if(an.data){this.example_feature=(an.data.length?an.data[0]:undefined);aE.draw(av,au,af,ao)}if(an.message){var ar=$("<div/>");var aD=$("<div/>").addClass("tile-message").text(an.message).css("width",ac.width);aD.css({position:"absolute",top:0});$(ac).css("top",15);ar.append(aD);ar.append(ac);ac=ar}return new L(aA,aw,ac,an.message)}});var P=function(ad,ab,af,aa,ac,ae){e.call(this,ad,ab,af,aa,ac,ae);this.painter=I.VariantPainter};n(P.prototype,J.prototype,e.prototype);var S=function(ad,ab,af,aa,ac,ae){e.call(this,ad,ab,af,aa,ac,ae);this.track_config=new V({track:this,params:[{key:"block_color",label:"Block color",type:"color",default_value:"#444"},{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:"mode",type:"string",default_value:this.mode,hidden:true},],saved_values:ac,onchange:function(){this.track.tile_cache.clear();this.track.draw()}});this.prefs=this.track_config.values;this.painter=I.ReadPainter;this.make_name_popup_menu()};n(S.prototype,J.prototype,e.prototype);var Q=function(ae,ac,ag,aa,ad,af,ab){e.call(this,ae,ac,ag,aa,ad,af,{},ab);this.data_url=raw_data_url;this.data_query_wait=1000;this.dataset_check_url=dataset_state_url};n(Q.prototype,J.prototype,e.prototype,{predraw_init:function(){var ab=this;var aa=function(){if(ab.data_cache.size()===0){setTimeout(aa,300)}else{ab.data_url=default_data_url;ab.data_query_wait=H;ab.dataset_state_url=converted_datasets_state_url;$.getJSON(ab.dataset_state_url,{dataset_id:ab.dataset_id,hda_ldda:ab.hda_ldda},function(ac){})}};aa()}});T.View=Y;T.LineTrack=k;T.FeatureTrack=e;T.ReadTrack=S};var slotting_module=function(c,b){var e=c("class").extend;var d=2,a=5;b.FeatureSlotter=function(j,h,f,g){this.slots={};this.start_end_dct={};this.w_scale=j;this.include_label=h;this.max_rows=f;this.measureText=g};e(b.FeatureSlotter.prototype,{slot_features:function(m){var p=this.w_scale,s=this.slots,h=this.start_end_dct,y=[],A=[],n=0,z=this.max_rows;for(var w=0,x=m.length;w<x;w++){var l=m[w],o=l[0];if(s[o]!==undefined){n=Math.max(n,s[o]);A.push(s[o])}else{y.push(w)}}var q=function(G,H){for(var F=0;F<=z;F++){var D=false,I=h[F];if(I!==undefined){for(var C=0,E=I.length;C<E;C++){var B=I[C];if(H>B[0]&&G<B[1]){D=true;break}}}if(!D){return F}}return -1};for(var w=0,x=y.length;w<x;w++){var l=m[y[w]],o=l[0],u=l[1],f=l[2],r=l[3],g=Math.floor(u*p),k=Math.ceil(f*p),v=this.measureText(r).width,j;if(r!==undefined&&this.include_label){v+=(d+a);if(g-v>=0){g-=v;j="left"}else{k+=v;j="right"}}var t=q(g,k);if(t>=0){if(h[t]===undefined){h[t]=[]}h[t].push([g,k]);s[o]=t;n=Math.max(n,t)}else{}}return n+1}})};var painters_module=function(j,w){var t=j("class").extend;var o=function(H,z,F,y,E,C){if(C===undefined){C=4}var B=y-z;var A=E-F;var D=Math.floor(Math.sqrt(B*B+A*A)/C);var I=B/D;var G=A/D;var x;for(x=0;x<D;x++,z+=I,F+=G){if(x%2!==0){continue}H.fillRect(z,F,C,1)}};var p=function(A,z,x,D){var C=z-D/2,B=z+D/2,E=x-Math.sqrt(D*3/2);A.beginPath();A.moveTo(C,E);A.lineTo(B,E);A.lineTo(z,x);A.lineTo(C,E);A.strokeStyle=this.fillStyle;A.fill();A.stroke();A.closePath()};var m=function(z,B,x,y,A){this.data=z;this.view_start=B;this.view_end=x;this.prefs=t({},this.default_prefs,y);this.mode=A};m.prototype.default_prefs={};var u=function(z,B,x,y,A){m.call(this,z,B,x,y,A)};u.prototype.default_prefs={show_counts:false};u.prototype.draw=function(M,z,L){var E=this.view_start,O=this.view_end-this.view_start,N=z/O;var J=this.data.data,I=this.data.delta,G=this.data.max,B=L;delta_x_px=Math.ceil(I*N);M.save();for(var C=0,D=J.length;C<D;C++){var H=Math.floor((J[C][0]-E)*N);var F=J[C][1];if(!F){continue}var K=F/G*L;if(F!==0&&K<1){K=1}M.fillStyle=this.prefs.block_color;M.fillRect(H,B-K,delta_x_px,K);var A=4;if(this.prefs.show_counts&&(M.measureText(F).width+A)<delta_x_px){M.fillStyle=this.prefs.label_color;M.textAlign="center";M.fillText(F,H+(delta_x_px/2),10)}}M.restore()};var c=function(x,B,D,E,z){m.call(this,x,B,D,E,z);if(this.prefs.min_value===undefined){var F=Infinity;for(var y=0,A=this.data.length;y<A;y++){F=Math.min(F,this.data[y][1])}this.prefs.min_value=F}if(this.prefs.max_value===undefined){var C=-Infinity;for(var y=0,A=this.data.length;y<A;y++){C=Math.max(C,this.data[y][1])}this.prefs.max_value=C}};c.prototype.default_prefs={min_value:undefined,max_value:undefined,mode:"Histogram",color:"#000",overflow_color:"#F66"};c.prototype.draw=function(M,L,J){var E=false,G=this.prefs.min_value,C=this.prefs.max_value,I=C-G,x=J,z=this.view_start,K=this.view_end-this.view_start,A=L/K,H=this.mode,S=this.data;M.save();var T=Math.round(J+G/I*J);if(H!=="Intensity"){M.fillStyle="#aaa";M.fillRect(0,T,L,1)}M.beginPath();var Q,D,B;if(S.length>1){B=Math.ceil((S[1][0]-S[0][0])*A)}else{B=10}for(var N=0,O=S.length;N<O;N++){M.fillStyle=this.prefs.color;Q=Math.round((S[N][0]-z)*A);D=S[N][1];var P=false,F=false;if(D===null){if(E&&H==="Filled"){M.lineTo(Q,x)}E=false;continue}if(D<G){F=true;D=G}else{if(D>C){P=true;D=C}}if(H==="Histogram"){D=Math.round(D/I*x);M.fillRect(Q,T,B,-D)}else{if(H==="Intensity"){D=255-Math.floor((D-G)/I*255);M.fillStyle="rgb("+D+","+D+","+D+")";M.fillRect(Q,0,B,x)}else{D=Math.round(x-(D-G)/I*x);if(E){M.lineTo(Q,D)}else{E=true;if(H==="Filled"){M.moveTo(Q,x);M.lineTo(Q,D)}else{M.moveTo(Q,D)}}}}M.fillStyle=this.prefs.overflow_color;if(P||F){var R;if(H==="Histogram"||H==="Intensity"){R=B}else{Q-=2;R=4}if(P){M.fillRect(Q,0,R,3)}if(F){M.fillRect(Q,x-3,R,3)}}M.fillStyle=this.prefs.color}if(H==="Filled"){if(E){M.lineTo(Q,T);M.lineTo(0,T)}M.fill()}else{M.stroke()}M.restore()};var n=function(z,B,x,y,A){m.call(this,z,B,x,y,A)};n.prototype.default_prefs={block_color:"#FFF",connector_color:"#FFF"};t(n.prototype,{get_required_height:function(y){var x=y_scale=this.get_row_height(),z=this.mode;if(z==="no_detail"||z==="Squish"||z==="Pack"){x=y*y_scale}return x+Math.max(Math.round(y_scale/2),5)},draw:function(J,A,I,F){var D=this.data,G=this.view_start,K=this.view_end;J.save();J.fillStyle=this.prefs.block_color;J.textAlign="right";var N=this.view_end-this.view_start,M=A/N,z=this.get_row_height();for(var C=0,E=D.length;C<E;C++){var L=D[C],B=L[0],x=L[1],y=L[2],H=(F&&F[B]!==undefined?F[B]:null);if((x<K&&y>G)&&(this.mode=="Dense"||H!==null)){this.draw_element(J,this.mode,L,H,G,K,M,z,A)}}J.restore()}});var d=10,h=3,l=5,v=10,f=1,r=3,e=3,a=9,k=2,g="#ccc";var q=function(z,B,x,y,A){n.call(this,z,B,x,y,A)};t(q.prototype,n.prototype,{get_row_height:function(){var y=this.mode,x;if(y==="Dense"){x=d}else{if(y==="no_detail"){x=h}else{if(y==="Squish"){x=l}else{x=v}}}return x},draw_element:function(J,C,R,E,L,ab,af,ag,x){var O=R[0],ad=R[1],V=R[2],M=R[3],W=Math.floor(Math.max(0,(ad-L)*af)),K=Math.ceil(Math.min(x,Math.max(0,(V-L)*af))),U=(C==="Dense"?0:(0+E))*ag,I,Z,N=null,ah=null,A=this.prefs.block_color,Y=this.prefs.label_color;if(C=="Dense"){E=1}if(C==="no_detail"){J.fillStyle=A;J.fillRect(W,U+5,K-W,f)}else{var H=R[4],T=R[5],X=R[6],B=R[7];if(T&&X){N=Math.floor(Math.max(0,(T-L)*af));ah=Math.ceil(Math.min(x,Math.max(0,(X-L)*af)))}var ae,P;if(C==="Squish"||C==="Dense"){ae=1;P=e}else{ae=5;P=a}if(!B){if(R.strand){if(R.strand==="+"){J.fillStyle=J.canvas.manager.get_pattern("right_strand_inv")}else{if(R.strand==="-"){J.fillStyle=J.canvas.manager.get_pattern("left_strand_inv")}}}else{J.fillStyle=A}J.fillRect(W,U,K-W,P)}else{var G,Q;if(C==="Squish"||C==="Dense"){J.fillStyle=g;G=U+Math.floor(e/2)+1;Q=1}else{if(H){var G=U;var Q=P;if(H==="+"){J.fillStyle=J.canvas.manager.get_pattern("right_strand")}else{if(H==="-"){J.fillStyle=J.canvas.manager.get_pattern("left_strand")}}}else{J.fillStyle=g;G+=(e/2)+1;Q=1}}J.fillRect(W,G,K-W,Q);for(var ac=0,z=B.length;ac<z;ac++){var D=B[ac],y=Math.floor(Math.max(0,(D[0]-L)*af)),S=Math.ceil(Math.min(x,Math.max((D[1]-L)*af)));if(y>S){continue}J.fillStyle=A;J.fillRect(y,U+(P-ae)/2+1,S-y,ae);if(N!==undefined&&X>T&&!(y>ah||S<N)){var aa=Math.max(y,N),F=Math.min(S,ah);J.fillRect(aa,U+1,F-aa,P);if(B.length==1&&C=="Pack"){if(H==="+"){J.fillStyle=J.canvas.manager.get_pattern("right_strand_inv")}else{if(H==="-"){J.fillStyle=J.canvas.manager.get_pattern("left_strand_inv")}}if(aa+14<F){aa+=2;F-=2}J.fillRect(aa,U+1,F-aa,P)}}}}if(C==="Pack"&&ad>L){J.fillStyle=Y;if(L===0&&W-J.measureText(M).width<0){J.textAlign="left";J.fillText(M,K+k,U+8)}else{J.textAlign="right";J.fillText(M,W-k,U+8)}J.fillStyle=A}}}});var b=function(z,B,x,y,A){n.call(this,z,B,x,y,A)};t(b.prototype,n.prototype,{draw_element:function(Q,L,F,B,T,z,I,R,O){var F=data[i],H=F[0],P=F[1],A=F[2],K=F[3],D=Math.floor(Math.max(0,(P-T)*I)),G=Math.ceil(Math.min(O,Math.max(0,(A-T)*I))),C=(L==="Dense"?0:(0+B))*R,x,U,y=null,J=null;if(no_label){Q.fillStyle=block_color;Q.fillRect(D+left_offset,C+5,G-D,1)}else{var S=F[4],N=F[5],E=F[6];x=9;U=1;Q.fillRect(D+left_offset,C,G-D,x);if(L!=="Dense"&&K!==undefined&&P>T){Q.fillStyle=label_color;if(T===0&&D-Q.measureText(K).width<0){Q.textAlign="left";Q.fillText(K,G+2+left_offset,C+8)}else{Q.textAlign="right";Q.fillText(K,D-2+left_offset,C+8)}Q.fillStyle=block_color}var M=S+" / "+N;if(P>T&&Q.measureText(M).width<(G-D)){Q.fillStyle="white";Q.textAlign="center";Q.fillText(M,left_offset+D+(G-D)/2,C+8);Q.fillStyle=block_color}}}});var s=function(A,C,x,z,B,y){n.call(this,A,C,x,z,B);this.ref_seq=y};s.prototype.default_prefs=t({},n.prototype.default_prefs,{show_insertions:false});t(s.prototype,n.prototype,{get_row_height:function(){var x,y=this.mode;if(y==="Dense"){x=d}else{if(y==="Squish"){x=l}else{x=v;if(this.prefs.show_insertions){x*=2}}}return x},draw_read:function(T,O,K,Y,z,S,H,E,D){T.textAlign="center";var R=this,y=[Y,z],N=0,U=0,Q=0;ref_seq=this.ref_seq,char_width_px=T.canvas.manager.char_width_px;var ad=[];if((O==="Pack"||this.mode==="Auto")&&E!==undefined&&K>char_width_px){Q=Math.round(K/2)}if(!H){H=[[0,E.length]]}for(var L=0,W=H.length;L<W;L++){var I=H[L],A="MIDNSHP=X"[I[0]],M=I[1];if(A==="H"||A==="S"){N-=M}var F=S+N,ac=Math.floor(Math.max(0,(F-Y)*K)),G=Math.floor(Math.max(0,(F+M-Y)*K));if(ac===G){G+=1}switch(A){case"H":break;case"S":case"M":case"=":if(is_overlap([F,F+M],y)){var P=E.slice(U,U+M);if(Q>0){T.fillStyle=this.prefs.block_color;T.fillRect(ac-Q,D+1,G-ac,9);T.fillStyle=g;for(var aa=0,x=P.length;aa<x;aa++){if(this.prefs.show_differences&&ref_seq){var J=ref_seq[F-Y+aa];if(!J||J.toLowerCase()===P[aa].toLowerCase()){continue}}if(F+aa>=Y&&F+aa<=z){var ab=Math.floor(Math.max(0,(F+aa-Y)*K));T.fillText(P[aa],ab,D+9)}}}else{T.fillStyle=this.prefs.block_color;T.fillRect(ac,D+4,G-ac,e)}}U+=M;N+=M;break;case"N":T.fillStyle=g;T.fillRect(ac-Q,D+5,G-ac,1);N+=M;break;case"D":T.fillStyle="red";T.fillRect(ac-Q,D+4,G-ac,3);N+=M;break;case"P":break;case"I":var X=ac-Q;if(is_overlap([F,F+M],y)){var P=E.slice(U,U+M);if(this.prefs.show_insertions){var C=ac-(G-ac)/2;if((O==="Pack"||this.mode==="Auto")&&E!==undefined&&K>char_width_px){T.fillStyle="yellow";T.fillRect(C-Q,D-9,G-ac,9);ad[ad.length]={type:"triangle",data:[X,D+4,5]};T.fillStyle=g;switch(seq_tile_overlap){case (OVERLAP_START):P=P.slice(Y-F);break;case (OVERLAP_END):P=P.slice(0,F-z);break;case (CONTAINED_BY):break;case (CONTAINS):P=P.slice(Y-F,F-z);break}for(var aa=0,x=P.length;aa<x;aa++){var ab=Math.floor(Math.max(0,(F+aa-Y)*K));T.fillText(P[aa],ab-(G-ac)/2,D)}}else{T.fillStyle="yellow";T.fillRect(C,D+(this.mode!=="Dense"?2:5),G-ac,(O!=="Dense"?e:r))}}else{if((O==="Pack"||this.mode==="Auto")&&E!==undefined&&K>char_width_px){ad[ad.length]={type:"text",data:[P.length,X,D+9]}}else{}}}U+=M;break;case"X":U+=M;break}}T.fillStyle="yellow";var Z,B,ae;for(var V=0;V<ad.length;V++){Z=ad[V];B=Z.type;ae=Z.data;if(B==="text"){T.save();T.font="bold "+T.font;T.fillText(ae[0],ae[1],ae[2]);T.restore()}else{if(B=="triangle"){p(T,ae[0],ae[1],ae[2])}}}},draw_element:function(Q,L,D,A,T,y,H,R,O){var G=D[0],P=D[1],z=D[2],I=D[3],C=Math.floor(Math.max(0,(P-T)*H)),E=Math.ceil(Math.min(O,Math.max(0,(z-T)*H))),B=(L==="Dense"?0:(0+A))*R,U=this.prefs.block_color,F=this.prefs.label_color,N=0;if((L==="Pack"||this.mode==="Auto")&&H>Q.canvas.manager.char_width_px){var N=Math.round(H/2)}Q.fillStyle=U;if(D[5] instanceof Array){var M=Math.floor(Math.max(0,(D[4][0]-T)*H)),K=Math.ceil(Math.min(O,Math.max(0,(D[4][1]-T)*H))),J=Math.floor(Math.max(0,(D[5][0]-T)*H)),x=Math.ceil(Math.min(O,Math.max(0,(D[5][1]-T)*H)));if(D[4][1]>=T&&D[4][0]<=y&&D[4][2]){this.draw_read(Q,L,H,T,y,D[4][0],D[4][2],D[4][3],B)}if(D[5][1]>=T&&D[5][0]<=y&&D[5][2]){this.draw_read(Q,L,H,T,y,D[5][0],D[5][2],D[5][3],B)}if(J>K){Q.fillStyle=g;o(Q,K-N,B+5,J-N,B+5)}}else{Q.fillStyle=U;this.draw_read(Q,L,H,T,y,P,D[4],D[5],B)}if(L==="Pack"&&P>T){Q.fillStyle=this.prefs.label_color;var S=1;if(S===0&&C-Q.measureText(I).width<0){Q.textAlign="left";Q.fillText(I,E+k-N,B+8)}else{Q.textAlign="right";Q.fillText(I,C-k-N,B+8)}Q.fillStyle=U}}});w.SummaryTreePainter=u;w.LinePainter=c;w.LinkedFeaturePainter=q;w.ReadPainter=s;w.VariantPainter=b};(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 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 trackster_module=function(f,T){var n=f("class").extend,p=f("slotting"),I=f("painters");var Z=function(aa,ab){this.document=aa;this.default_font=ab!==undefined?ab:"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")};n(Z.prototype,{load_pattern:function(aa,ae){var ab=this.patterns,ac=this.dummy_context,ad=new Image();ad.src=image_path+ae;ad.onload=function(){ab[aa]=ac.createPattern(ad,"repeat")}},get_pattern:function(aa){return this.patterns[aa]},new_canvas:function(){var aa=this.document.createElement("canvas");if(window.G_vmlCanvasManager){G_vmlCanvasManager.initElement(aa)}aa.manager=this;return aa}});var C=function(aa,ab){aa.bind("drag",{handle:ab,relative:true},function(af,ag){var ae=$(this).parent();var ad=ae.children();var ac;for(ac=0;ac<ad.length;ac++){if(ag.offsetY<$(ad.get(ac)).position().top){break}}if(ac===ad.length){if(this!==ad.get(ac-1)){ae.append(this)}}else{if(this!==ad.get(ac)){$(this).insertBefore(ad.get(ac))}}}).bind("dragstart",function(){$(this).css({"border-top":"1px solid blue","border-bottom":"1px solid blue"})}).bind("dragend",function(){$(this).css("border","0px")})};T.sortable=C;var D=9,A=15,O=D+2,w=100,F=12000,M=200,z=5,s=10,H=5000,t=100,m="There was an error in indexing this dataset. ",G="A converter for this dataset is not installed. Please check your datatypes_conf.xml file.",B="No data for this chrom/contig.",q="Currently indexing... please wait",v="Tool cannot be rerun: ",a="Loading data...",U="Ready for display",d=10,r=5,y=5;function u(aa){return Math.round(aa*1000)/1000}var c=function(aa){this.num_elements=aa;this.clear()};n(c.prototype,{get:function(ab){var aa=this.key_ary.indexOf(ab);if(aa!==-1){this.move_key_to_end(ab,aa)}return this.obj_cache[ab]},set:function(ab,ac){if(!this.obj_cache[ab]){if(this.key_ary.length>=this.num_elements){var aa=this.key_ary.shift();delete this.obj_cache[aa]}this.key_ary.push(ab)}this.obj_cache[ab]=ac;return ac},move_key_to_end:function(ab,aa){this.key_ary.splice(aa,1);this.key_ary.push(ab)},clear:function(){this.obj_cache={};this.key_ary=[]},size:function(){return this.key_ary.length}});var N=function(ab,aa,ac){c.call(this,ab);this.track=aa;this.subset=(ac!==undefined?ac:true)};n(N.prototype,c.prototype,{load_data:function(ai,aj,ae,ah,ab,ag){var ad={chrom:ai,low:aj,high:ae,mode:ah,resolution:ab,dataset_id:this.track.dataset_id,hda_ldda:this.track.hda_ldda};$.extend(ad,ag);if(this.track.filters_manager){var ak=[];var aa=this.track.filters_manager.filters;for(var af=0;af<aa.length;af++){ak[ak.length]=aa[af].name}ad.filter_cols=JSON.stringify(ak)}var ac=this;return $.getJSON(this.track.data_url,ad,function(al){ac.set_data(aj,ae,ah,al)})},get_data:function(ac,aa,af,ag,ab,ae){var ad=this.get(this.gen_key(aa,af,ag));if(ad){return ad}ad=this.load_data(ac,aa,af,ag,ab,ae);this.set_data(aa,af,ag,ad);return ad},set_data:function(ab,ac,ad,aa){return this.set(this.gen_key(ab,ac,ad),aa)},gen_key:function(aa,ac,ad){var ab=aa+"_"+ac+"_"+ad;return ab},split_key:function(aa){return aa.split("_")}});var E=function(ab,aa,ac){N.call(this,ab,aa,ac)};n(E.prototype,N.prototype,c.prototype,{load_data:function(ac,aa,ae,af,ab,ad){if(ab>1){return}return N.prototype.load_data.call(this,ac,aa,ae,af,ab,ad)}});var Y=function(aa,ad,ac,ab,ae){this.container=aa;this.chrom=null;this.vis_id=ac;this.dbkey=ab;this.title=ad;this.tracks=[];this.label_tracks=[];this.max_low=0;this.max_high=0;this.num_tracks=0;this.track_id_counter=0;this.zoom_factor=3;this.min_separation=30;this.has_changes=false;this.init(ae);this.canvas_manager=new Z(aa.get(0).ownerDocument);this.reset()};n(Y.prototype,{init:function(ad){var ac=this.container,aa=this;this.top_container=$("<div/>").addClass("top-container").appendTo(ac);this.content_div=$("<div/>").addClass("content").css("position","relative").appendTo(ac);this.bottom_container=$("<div/>").addClass("bottom-container").appendTo(ac);this.top_labeltrack=$("<div/>").addClass("top-labeltrack").appendTo(this.top_container);this.viewport_container=$("<div/>").addClass("viewport-container").addClass("viewport-container").appendTo(this.content_div);this.intro_div=$("<div/>").addClass("intro").text("Select a chrom from the dropdown below").hide();this.nav_labeltrack=$("<div/>").addClass("nav-labeltrack").appendTo(this.bottom_container);this.nav_container=$("<div/>").addClass("nav-container").prependTo(this.top_container);this.nav=$("<div/>").addClass("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 href='javascript:void(0);'>Close Overview</a>").addClass("overview-close").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 ab=function(ae){if(ae.type==="focusout"||(ae.keyCode||ae.which)===13||(ae.keyCode||ae.which)===27){if((ae.keyCode||ae.which)!==27){aa.go_to($(this).val())}$(this).hide();$(this).val("");aa.location_span.show();aa.chrom_select.show()}};this.nav_input=$("<input/>").addClass("nav-input").hide().bind("keyup focusout",ab).appendTo(this.nav_controls);this.location_span=$("<span/>").addClass("location").appendTo(this.nav_controls);this.location_span.bind("click",function(){aa.location_span.hide();aa.chrom_select.hide();aa.nav_input.val(aa.chrom+":"+aa.low+"-"+aa.high);aa.nav_input.css("display","inline-block");aa.nav_input.select();aa.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 id='zoom-out' />").click(function(){aa.zoom_out();aa.redraw()}).appendTo(this.nav_controls);this.zi_link=$("<a id='zoom-in' />").click(function(){aa.zoom_in();aa.redraw()}).appendTo(this.nav_controls);this.load_chroms({low:0},ad);this.chrom_select.bind("change",function(){aa.change_chrom(aa.chrom_select.val())});this.intro_div.show();this.content_div.bind("click",function(ae){$(this).find("input").trigger("blur")});this.content_div.bind("dblclick",function(ae){aa.zoom_in(ae.pageX,this.viewport_container)});this.overview_box.bind("dragstart",function(ae,af){this.current_x=af.offsetX}).bind("drag",function(ae,ag){var ah=ag.offsetX-this.current_x;this.current_x=ag.offsetX;var af=Math.round(ah/aa.viewport_container.width()*(aa.max_high-aa.max_low));aa.move_delta(-af)});this.overview_close.bind("click",function(){for(var af=0,ae=aa.tracks.length;af<ae;af++){aa.tracks[af].is_overview=false}$(this).siblings().filter("canvas").remove();$(this).parent().css("height",aa.overview_box.height());aa.overview_highlight.hide();$(this).hide()});this.viewport_container.bind("draginit",function(ae,af){if(ae.clientX>aa.viewport_container.width()-16){return false}}).bind("dragstart",function(ae,af){af.original_low=aa.low;af.current_height=ae.clientY;af.current_x=af.offsetX}).bind("drag",function(ag,ai){var ae=$(this);var aj=ai.offsetX-ai.current_x;var af=ae.scrollTop()-(ag.clientY-ai.current_height);ae.scrollTop(af);ai.current_height=ag.clientY;ai.current_x=ai.offsetX;var ah=Math.round(aj/aa.viewport_container.width()*(aa.high-aa.low));aa.move_delta(ah)}).bind("mousewheel",function(ag,ai,af,ae){if(af){var ah=Math.round(-af/aa.viewport_container.width()*(aa.high-aa.low));aa.move_delta(ah)}});this.top_labeltrack.bind("dragstart",function(ae,af){return $("<div />").css({height:aa.content_div.height()+aa.top_labeltrack.height()+aa.nav_labeltrack.height()+1,top:"0px",position:"absolute","background-color":"#ccf",opacity:0.5,"z-index":1000}).appendTo($(this))}).bind("drag",function(ai,aj){$(aj.proxy).css({left:Math.min(ai.pageX,aj.startX),width:Math.abs(ai.pageX-aj.startX)});var af=Math.min(ai.pageX,aj.startX)-aa.container.offset().left,ae=Math.max(ai.pageX,aj.startX)-aa.container.offset().left,ah=(aa.high-aa.low),ag=aa.viewport_container.width();aa.update_location(Math.round(af/ag*ah)+aa.low,Math.round(ae/ag*ah)+aa.low)}).bind("dragend",function(aj,ak){var af=Math.min(aj.pageX,ak.startX),ae=Math.max(aj.pageX,ak.startX),ah=(aa.high-aa.low),ag=aa.viewport_container.width(),ai=aa.low;aa.low=Math.round(af/ag*ah)+ai;aa.high=Math.round(ae/ag*ah)+ai;$(ak.proxy).remove();aa.redraw()});this.add_label_track(new X(this,this.top_labeltrack));this.add_label_track(new X(this,this.nav_labeltrack));$(window).bind("resize",function(){aa.resize_window()});$(document).bind("redraw",function(){aa.redraw()});this.reset();$(window).trigger("resize")},update_location:function(aa,ab){this.location_span.text(commatize(aa)+" - "+commatize(ab));this.nav_input.val(this.chrom+":"+commatize(aa)+"-"+commatize(ab))},load_chroms:function(ab,ac){ab.num=t;$.extend(ab,(this.vis_id!==undefined?{vis_id:this.vis_id}:{dbkey:this.dbkey}));var aa=this;$.ajax({url:chrom_url,data:ab,dataType:"json",success:function(ae){if(ae.chrom_info.length===0){alert("Invalid chromosome: "+ab.chrom);return}if(ae.reference){aa.add_label_track(new x(aa))}aa.chrom_data=ae.chrom_info;var ah='<option value="">Select Chrom/Contig</option>';for(var ag=0,ad=aa.chrom_data.length;ag<ad;ag++){var af=aa.chrom_data[ag].chrom;ah+='<option value="'+af+'">'+af+"</option>"}if(ae.prev_chroms){ah+='<option value="previous">Previous '+t+"</option>"}if(ae.next_chroms){ah+='<option value="next">Next '+t+"</option>"}aa.chrom_select.html(ah);if(ac){ac()}aa.chrom_start_index=ae.start_index},error:function(){alert("Could not load chroms for this dbkey:",aa.dbkey)}})},change_chrom:function(ae,ab,ag){if(!ae||ae==="None"){return}var ad=this;if(ae==="previous"){ad.load_chroms({low:this.chrom_start_index-t});return}if(ae==="next"){ad.load_chroms({low:this.chrom_start_index+t});return}var af=$.grep(ad.chrom_data,function(ai,aj){return ai.chrom===ae})[0];if(af===undefined){ad.load_chroms({chrom:ae},function(){ad.change_chrom(ae,ab,ag)});return}else{if(ae!==ad.chrom){ad.chrom=ae;if(!ad.chrom){ad.intro_div.show()}else{ad.intro_div.hide()}ad.chrom_select.val(ad.chrom);ad.max_high=af.len-1;ad.reset();ad.redraw(true);for(var ah=0,aa=ad.tracks.length;ah<aa;ah++){var ac=ad.tracks[ah];if(ac.init){ac.init()}}}if(ab!==undefined&&ag!==undefined){ad.low=Math.max(ab,0);ad.high=Math.min(ag,ad.max_high)}ad.reset_overview();ad.redraw()}},go_to:function(ae){var ai=this,aa,ad,ab=ae.split(":"),ag=ab[0],ah=ab[1];if(ah!==undefined){try{var af=ah.split("-");aa=parseInt(af[0].replace(/,/g,""),10);ad=parseInt(af[1].replace(/,/g,""),10)}catch(ac){return false}}ai.change_chrom(ag,aa,ad)},move_fraction:function(ac){var aa=this;var ab=aa.high-aa.low;this.move_delta(ac*ab)},move_delta:function(ac){var aa=this;var ab=aa.high-aa.low;if(aa.low-ac<aa.max_low){aa.low=aa.max_low;aa.high=aa.max_low+ab}else{if(aa.high-ac>aa.max_high){aa.high=aa.max_high;aa.low=aa.max_high-ab}else{aa.high-=ac;aa.low-=ac}}aa.redraw()},add_track:function(aa){aa.view=this;aa.track_id=this.track_id_counter;this.tracks.push(aa);if(aa.init){aa.init()}aa.container_div.attr("id","track_"+aa.track_id);C(aa.container_div,".draghandle");this.track_id_counter+=1;this.num_tracks+=1},add_label_track:function(aa){aa.view=this;this.label_tracks.push(aa)},remove_track:function(aa){this.has_changes=true;aa.container_div.fadeOut("slow",function(){$(this).remove()});delete this.tracks[this.tracks.indexOf(aa)];this.num_tracks-=1},reset:function(){this.low=this.max_low;this.high=this.max_high;this.viewport_container.find(".yaxislabel").remove()},redraw:function(ah){var ag=this.high-this.low,af=this.low,ab=this.high;if(af<this.max_low){af=this.max_low}if(ab>this.max_high){ab=this.max_high}if(this.high!==0&&ag<this.min_separation){ab=af+this.min_separation}this.low=Math.floor(af);this.high=Math.ceil(ab);this.resolution=Math.pow(z,Math.ceil(Math.log((this.high-this.low)/M)/Math.log(z)));this.zoom_res=Math.pow(s,Math.max(0,Math.ceil(Math.log(this.resolution,s)/Math.log(s))));var aa=(this.low/(this.max_high-this.max_low)*this.overview_viewport.width())||0;var ae=((this.high-this.low)/(this.max_high-this.max_low)*this.overview_viewport.width())||0;var ai=13;this.overview_box.css({left:aa,width:Math.max(ai,ae)}).show();if(ae<ai){this.overview_box.css("left",aa-(ai-ae)/2)}if(this.overview_highlight){this.overview_highlight.css({left:aa,width:ae})}this.update_location(this.low,this.high);if(!ah){for(var ac=0,ad=this.tracks.length;ac<ad;ac++){if(this.tracks[ac]&&this.tracks[ac].enabled){this.tracks[ac].draw()}}for(ac=0,ad=this.label_tracks.length;ac<ad;ac++){this.label_tracks[ac].draw()}}},zoom_in:function(ab,ac){if(this.max_high===0||this.high-this.low<this.min_separation){return}var ad=this.high-this.low,ae=ad/2+this.low,aa=(ad/this.zoom_factor)/2;if(ab){ae=ab/this.viewport_container.width()*(this.high-this.low)+this.low}this.low=Math.round(ae-aa);this.high=Math.round(ae+aa);this.redraw()},zoom_out:function(){if(this.max_high===0){return}var ab=this.high-this.low,ac=ab/2+this.low,aa=(ab*this.zoom_factor)/2;this.low=Math.round(ac-aa);this.high=Math.round(ac+aa);this.redraw()},resize_window:function(){this.viewport_container.height(this.container.height()-this.top_container.height()-this.bottom_container.height());this.nav_container.width(this.container.width());this.redraw()},reset_overview:function(){this.overview_viewport.find("canvas").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()}});var o=function(ac,ag){this.track=ac;this.name=ag.name;this.params=[];var an=ag.params;for(var ad=0;ad<an.length;ad++){var ai=an[ad],ab=ai.name,am=ai.label,ae=unescape(ai.html),ao=ai.value,ak=ai.type;if(ak==="number"){this.params[this.params.length]=new g(ab,am,ae,ao,ai.min,ai.max)}else{if(ak=="select"){this.params[this.params.length]=new K(ab,am,ae,ao)}else{console.log("WARNING: unrecognized tool parameter type:",ab,ak)}}}this.parent_div=$("<div/>").addClass("dynamic-tool").hide();this.parent_div.bind("drag",function(aq){aq.stopPropagation()}).bind("click",function(aq){aq.stopPropagation()}).bind("dblclick",function(aq){aq.stopPropagation()});var al=$("<div class='tool-name'>").appendTo(this.parent_div).text(this.name);var aj=this.params;var ah=this;$.each(this.params,function(ar,av){var au=$("<div>").addClass("param-row").appendTo(ah.parent_div);var aq=$("<div>").addClass("param-label").text(av.label).appendTo(au);var at=$("<div/>").addClass("slider").html(av.html).appendTo(au);at.find(":input").val(av.value);$("<div style='clear: both;'/>").appendTo(au)});this.parent_div.find("input").click(function(){$(this).select()});var ap=$("<div>").addClass("param-row").appendTo(this.parent_div);var af=$("<input type='submit'>").attr("value","Run on complete dataset").appendTo(ap);var aa=$("<input type='submit'>").attr("value","Run on visible region").css("margin-left","3em").appendTo(ap);var ah=this;aa.click(function(){ah.run_on_region()});af.click(function(){ah.run_on_dataset()})};n(o.prototype,{get_param_values_dict:function(){var aa={};this.parent_div.find(":input").each(function(){var ab=$(this).attr("name"),ac=$(this).val();aa[ab]=JSON.stringify(ac)});return aa},get_param_values:function(){var ab=[];var aa={};this.parent_div.find(":input").each(function(){var ac=$(this).attr("name"),ad=$(this).val();if(ac){ab[ab.length]=ad}});return ab},run_on_dataset:function(){var aa=this;aa.run({dataset_id:this.track.original_dataset_id,tool_id:aa.name},function(ab){show_modal(aa.name+" is Running",aa.name+" is running on the complete dataset. Tool outputs are in dataset's history.",{Close:hide_modal})})},run_on_region:function(){var aa={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},ac=this.track,ab=aa.tool_id+ac.tool_region_and_parameters_str(aa.chrom,aa.low,aa.high),ad;if(ac instanceof e){ad=new Q(ab,view,ac.hda_ldda,undefined,{},{},ac);ad.change_mode(ac.mode)}this.track.add_track(ad);ad.content_div.text("Starting job.");this.run(aa,function(ae){ad.dataset_id=ae.dataset_id;ad.content_div.text("Running job.");ad.init()})},run:function(ab,ac){$.extend(ab,this.get_param_values_dict());var aa=function(){$.getJSON(rerun_tool_url,ab,function(ad){if(ad==="no converter"){new_track.container_div.addClass("error");new_track.content_div.text(G)}else{if(ad.error){new_track.container_div.addClass("error");new_track.content_div.text(v+ad.message)}else{if(ad==="pending"){new_track.container_div.addClass("pending");new_track.content_div.text("Converting input data so that it can be easily reused.");setTimeout(aa,2000)}else{ac(ad)}}}})};aa()}});var K=function(ab,aa,ac,ad){this.name=ab;this.label=aa;this.html=ac;this.value=ad};var g=function(ac,ab,ae,af,ad,aa){K.call(this,ac,ab,ae,af);this.min=ad;this.max=aa};var h=function(ab,aa,ac,ad){this.name=ab;this.index=aa;this.tool_id=ac;this.tool_exp_name=ad};var R=function(ab,aa,ac,ad){h.call(this,ab,aa,ac,ad);this.low=-Number.MAX_VALUE;this.high=Number.MAX_VALUE;this.min=Number.MAX_VALUE;this.max=-Number.MAX_VALUE;this.slider=null;this.slider_label=null};n(R.prototype,{applies_to:function(aa){if(aa.length>this.index){return true}return false},keep:function(aa){if(!this.applies_to(aa)){return true}var ab=parseInt(aa[this.index]);return(isNaN(ab)||(ab>=this.low&&ab<=this.high))},update_attrs:function(ab){var aa=false;if(!this.applies_to(ab)){return aa}if(ab[this.index]<this.min){this.min=Math.floor(ab[this.index]);aa=true}if(ab[this.index]>this.max){this.max=Math.ceil(ab[this.index]);aa=true}return aa},update_ui_elt:function(){var ac=function(af,ad){var ae=ad-af;return(ae<=2?0.01:1)};var ab=this.slider.slider("option","min"),aa=this.slider.slider("option","max");if(this.min<ab||this.max>aa){this.slider.slider("option","min",this.min);this.slider.slider("option","max",this.max);this.slider.slider("option","step",ac(this.min,this.max));this.slider.slider("option","values",[this.min,this.max])}}});var W=function(ac,al){this.track=ac;this.filters=[];for(var ag=0;ag<al.length;ag++){var aa=al[ag],ab=aa.name,ak=aa.type,ai=aa.index,an=aa.tool_id,ad=aa.tool_exp_name;if(ak==="int"||ak==="float"){this.filters[ag]=new R(ab,ai,an,ad)}else{console.log("ERROR: unsupported filter: ",ab,ak)}}var aj=function(ao,ap,aq){ao.click(function(){var ar=ap.text();max=parseFloat(aq.slider("option","max")),input_size=(max<=1?4:max<=1000000?max.toString().length:6),multi_value=false;if(aq.slider("option","values")){input_size=2*input_size+1;multi_value=true}ap.text("");$("<input type='text'/>").attr("size",input_size).attr("maxlength",input_size).attr("value",ar).appendTo(ap).focus().select().click(function(at){at.stopPropagation()}).blur(function(){$(this).remove();ap.text(ar)}).keyup(function(ax){if(ax.keyCode===27){$(this).trigger("blur")}else{if(ax.keyCode===13){var av=aq.slider("option","min"),at=aq.slider("option","max"),aw=function(ay){return(isNaN(ay)||ay>at||ay<av)},au=$(this).val();if(!multi_value){au=parseFloat(au);if(aw(au)){alert("Parameter value must be in the range ["+av+"-"+at+"]");return $(this)}}else{au=au.split("-");au=[parseFloat(au[0]),parseFloat(au[1])];if(aw(au[0])||aw(au[1])){alert("Parameter value must be in the range ["+av+"-"+at+"]");return $(this)}}aq.slider((multi_value?"values":"value"),au)}}})})};this.parent_div=$("<div/>").addClass("filters").hide();this.parent_div.bind("drag",function(ao){ao.stopPropagation()}).bind("click",function(ao){ao.stopPropagation()}).bind("dblclick",function(ao){ao.stopPropagation()}).bind("keydown",function(ao){ao.stopPropagation()});var ae=this;$.each(this.filters,function(av,ap){var ar=$("<div/>").addClass("slider-row").appendTo(ae.parent_div);var ao=$("<div/>").addClass("slider-label").appendTo(ar);var ax=$("<span/>").addClass("slider-name").text(ap.name+" ").appendTo(ao);var aq=$("<span/>");var at=$("<span/>").addClass("slider-value").appendTo(ao).append("[").append(aq).append("]");var aw=$("<div/>").addClass("slider").appendTo(ar);ap.control_element=$("<div/>").attr("id",ap.name+"-filter-control").appendTo(aw);var au=[0,0];ap.control_element.slider({range:true,min:Number.MAX_VALUE,max:-Number.MIN_VALUE,values:[0,0],slide:function(ay,az){au=az.values;aq.text(az.values[0]+"-"+az.values[1]);setTimeout(function(){if(az.values[0]==au[0]&&az.values[1]==au[1]){var aA=az.values;aq.text(aA[0]+"-"+aA[1]);ap.low=aA[0];ap.high=aA[1];ae.track.draw(true,true)}},50)},change:function(ay,az){ap.control_element.slider("option","slide").call(ap.control_element,ay,az)}});ap.slider=ap.control_element;ap.slider_label=aq;aj(at,aq,ap.control_element);$("<div style='clear: both;'/>").appendTo(ar)});if(this.filters.length!=0){var am=$("<div>").addClass("param-row").appendTo(this.parent_div);var ah=$("<input type='submit'>").attr("value","Run on complete dataset").appendTo(am);var af=this;ah.click(function(){af.run_on_dataset()})}};n(W.prototype,{reset_filters:function(){for(var aa=0;aa<this.filters.length;aa++){filter=this.filters[aa];filter.slider.slider("option","values",[filter.min,filter.max])}},run_on_dataset:function(){var ai=function(am,ak,al){if(!(ak in am)){am[ak]=al}return am[ak]};var ac={},aa,ab,ad;for(var ae=0;ae<this.filters.length;ae++){aa=this.filters[ae];if(aa.tool_id){if(aa.min!=aa.low){ab=ai(ac,aa.tool_id,[]);ab[ab.length]=aa.tool_exp_name+" >= "+aa.low}if(aa.max!=aa.high){ab=ai(ac,aa.tool_id,[]);ab[ab.length]=aa.tool_exp_name+" <= "+aa.high}}}var ag=[];for(var aj in ac){ag[ag.length]=[aj,ac[aj]]}var ah=ag.length;(function af(aq,an){var al=an[0],am=al[0],ap=al[1],ao="("+ap.join(") and (")+")",ak={cond:ao,input:aq,target_dataset_id:aq,tool_id:am},an=an.slice(1);$.getJSON(run_tool_url,ak,function(ar){if(ar.error){show_modal("Filter Dataset","Error running tool "+am,{Close:hide_modal})}else{if(an.length===0){show_modal("Filtering Dataset","Filter(s) are running on the complete dataset. Outputs are in dataset's history.",{Close:hide_modal})}else{af(ar.dataset_id,an)}}})})(this.track.dataset_id,ag)}});var V=function(aa){this.track=aa.track;this.params=aa.params;this.values={};if(aa.saved_values){this.restore_values(aa.saved_values)}this.onchange=aa.onchange};n(V.prototype,{restore_values:function(aa){var ab=this;$.each(this.params,function(ac,ad){if(aa[ad.key]!==undefined){ab.values[ad.key]=aa[ad.key]}else{ab.values[ad.key]=ad.default_value}})},build_form:function(){var ab=this;var aa=$("<div />");$.each(this.params,function(af,ad){if(!ad.hidden){var ac="param_"+af;var ak=$("<div class='form-row' />").appendTo(aa);ak.append($("<label />").attr("for",ac).text(ad.label+":"));if(ad.type==="bool"){ak.append($('<input type="checkbox" />').attr("id",ac).attr("name",ac).attr("checked",ab.values[ad.key]))}else{if(ad.type==="color"){var ah=ab.values[ad.key];var ag=$("<input />").attr("id",ac).attr("name",ac).val(ah);var ai=$("<div class='tipsy tipsy-north' style='position: absolute;' />").hide();var ae=$("<div style='background-color: black; padding: 10px;'></div>").appendTo(ai);var aj=$("<div/>").appendTo(ae).farbtastic({width:100,height:100,callback:ag,color:ah});$("<div />").append(ag).append(ai).appendTo(ak).bind("click",function(al){ai.css({left:$(this).position().left+($(ag).width()/2)-60,top:$(this).position().top+$(this.height)}).show();$(document).bind("click.color-picker",function(){ai.hide();$(document).unbind("click.color-picker")});al.stopPropagation()})}else{ak.append($("<input />").attr("id",ac).attr("name",ac).val(ab.values[ad.key]))}}}});return aa},update_from_form:function(aa){var ac=this;var ab=false;$.each(this.params,function(ad,af){if(!af.hidden){var ag="param_"+ad;var ae=aa.find("#"+ag).val();if(af.type==="float"){ae=parseFloat(ae)}else{if(af.type==="int"){ae=parseInt(ae)}else{if(af.type==="bool"){ae=aa.find("#"+ag).is(":checked")}}}if(ae!==ac.values[af.key]){ac.values[af.key]=ae;ab=true}}});if(ab){this.onchange()}}});var b=function(ac,ab,aa){this.index=ac;this.resolution=ab;this.canvas=$("<div class='track-tile'/>").append(aa)};var l=function(ac,ab,aa,ad){b.call(this,ac,ab,aa);this.max_val=ad};var L=function(ac,ab,aa,ad){b.call(this,ac,ab,aa);this.message=ad};var j=function(ab,aa,ae,ac,ad){this.name=ab;this.view=aa;this.parent_element=ae;this.data_url=(ac?ac:default_data_url);this.data_url_extra_params={};this.data_query_wait=(ad?ad:H);this.dataset_check_url=converted_datasets_state_url;this.container_div=$("<div />").addClass("track").css("position","relative");if(!this.hidden){this.header_div=$("<div class='track-header' />").appendTo(this.container_div);if(this.view.editor){this.drag_div=$("<div class='draghandle' />").appendTo(this.header_div)}this.name_div=$("<div class='menubutton popup' />").appendTo(this.header_div);this.name_div.text(this.name);this.name_div.attr("id",this.name.replace(/\s+/g,"-").replace(/[^a-zA-Z0-9\-]/g,"").toLowerCase())}this.content_div=$("<div class='track-content'>").appendTo(this.container_div);this.parent_element.append(this.container_div)};n(j.prototype,{get_type:function(){if(this instanceof X){return"LabelTrack"}else{if(this instanceof x){return"ReferenceTrack"}else{if(this instanceof k){return"LineTrack"}else{if(this instanceof S){return"ReadTrack"}else{if(this instanceof Q){return"ToolDataFeatureTrack"}else{if(this instanceof P){return"VcfTrack"}else{if(this instanceof e){return"FeatureTrack"}}}}}}}return""},init:function(){var aa=this;aa.enabled=false;aa.tile_cache.clear();aa.data_cache.clear();aa.initial_canvas=undefined;aa.content_div.css("height","auto");aa.container_div.removeClass("nodata error pending");if(!aa.dataset_id){return}$.getJSON(converted_datasets_state_url,{hda_ldda:aa.hda_ldda,dataset_id:aa.dataset_id,chrom:aa.view.chrom},function(ab){if(!ab||ab==="error"||ab.kind==="error"){aa.container_div.addClass("error");aa.content_div.text(m);if(ab.message){var ad=aa.view.tracks.indexOf(aa);var ac=$(" <a href='javascript:void(0);'></a>").text("View error").bind("click",function(){show_modal("Trackster Error","<pre>"+ab.message+"</pre>",{Close:hide_modal})});aa.content_div.append(ac)}}else{if(ab==="no converter"){aa.container_div.addClass("error");aa.content_div.text(G)}else{if(ab==="no data"||(ab.data!==undefined&&(ab.data===null||ab.data.length===0))){aa.container_div.addClass("nodata");aa.content_div.text(B)}else{if(ab==="pending"){aa.container_div.addClass("pending");aa.content_div.text(q);setTimeout(function(){aa.init()},aa.data_query_wait)}else{if(ab.status==="data"){if(ab.valid_chroms){aa.valid_chroms=ab.valid_chroms;aa.make_name_popup_menu()}aa.content_div.text(U);if(aa.view.chrom){aa.content_div.text("");aa.content_div.css("height",aa.height_px+"px");aa.enabled=true;$.when(aa.predraw_init()).done(function(){aa.container_div.removeClass("nodata error pending");aa.draw()})}}}}}}})},predraw_init:function(){},update_name:function(aa){this.old_name=this.name;this.name=aa;this.name_div.text(this.name)},revert_name:function(){this.name=this.old_name;this.name_div.text(this.name)}});var J=function(ah,af,ai){var ab=this,aj=ab.view;this.filters_manager=(ah!==undefined?new W(this,ah):undefined);this.filters_available=false;this.filters_visible=false;this.tool=(af!==undefined&&obj_length(af)>0?new o(this,af):undefined);this.parent_track=ai;this.child_tracks=[];if(ab.hidden){return}if(this.parent_track){this.header_div.find(".draghandle").removeClass("draghandle").addClass("child-track-icon").addClass("icon-button");this.parent_element.addClass("child-track");this.tool=undefined}ab.child_tracks_container=$("<div/>").addClass("child-tracks-container").hide();ab.container_div.append(ab.child_tracks_container);if(this.filters_manager){this.filters_div=this.filters_manager.parent_div;this.header_div.after(this.filters_div)}if(this.tool){this.dynamic_tool_div=this.tool.parent_div;this.header_div.after(this.dynamic_tool_div)}if(ab.display_modes!==undefined){if(ab.mode_div===undefined){ab.mode_div=$("<div class='right-float menubutton popup' />").appendTo(ab.header_div);var ac=(ab.track_config&&ab.track_config.values.mode?ab.track_config.values.mode:ab.display_modes[0]);ab.mode=ac;ab.mode_div.text(ac);var aa={};for(var ad=0,ag=ab.display_modes.length;ad<ag;ad++){var ae=ab.display_modes[ad];aa[ae]=function(ak){return function(){ab.change_mode(ak)}}(ae)}make_popupmenu(ab.mode_div,aa)}else{ab.mode_div.hide()}}this.make_name_popup_menu()};n(J.prototype,j.prototype,{change_mode:function(ab){var aa=this;aa.mode_div.text(ab);aa.mode=ab;aa.track_config.values.mode=ab;aa.tile_cache.clear();aa.draw()},make_name_popup_menu:function(){var ab=this;var aa={};aa["Edit configuration"]=function(){var ah=function(){hide_modal();$(window).unbind("keypress.check_enter_esc")},af=function(){ab.track_config.update_from_form($(".dialog-box"));hide_modal();$(window).unbind("keypress.check_enter_esc")},ag=function(ai){if((ai.keyCode||ai.which)===27){ah()}else{if((ai.keyCode||ai.which)===13){af()}}};$(window).bind("keypress.check_enter_esc",ag);show_modal("Configure Track",ab.track_config.build_form(),{Cancel:ah,OK:af})};if(ab.filters_available>0){var ae=(ab.filters_div.is(":visible")?"Hide filters":"Show filters");aa[ae]=function(){ab.filters_visible=(ab.filters_div.is(":visible"));if(ab.filters_visible){ab.filters_manager.reset_filters()}ab.filters_div.toggle();ab.make_name_popup_menu()}}if(ab.tool){var ae=(ab.dynamic_tool_div.is(":visible")?"Hide tool":"Show tool");aa[ae]=function(){if(!ab.dynamic_tool_div.is(":visible")){ab.update_name(ab.name+ab.tool_region_and_parameters_str())}else{menu_option_text="Show dynamic tool";ab.revert_name()}ab.dynamic_tool_div.toggle();ab.make_name_popup_menu()}}if(ab.valid_chroms){aa["List chrom/contigs with data"]=function(){show_modal("Chrom/contigs with data","<p>"+ab.valid_chroms.join("<br/>")+"</p>",{Close:function(){hide_modal()}})}}var ac=view;var ad=function(){$("#no-tracks").show()};if(this.parent_track){ac=this.parent_track;ad=function(){}}aa.Remove=function(){ac.remove_track(ab);if(ac.num_tracks===0){ad()}};make_popupmenu(ab.name_div,aa)},draw:function(aa,ac){if(!this.dataset_id){return}var au=this.view.low,ag=this.view.high,ai=ag-au,ak=this.view.container.width(),ae=ak/ai,al=this.view.resolution,ad=$("<div style='position: relative;'></div>"),am=function(aw,ax,av){return aw+"_"+ax+"_"+av};if(!ac){this.content_div.children().remove()}this.content_div.append(ad);this.max_height=0;var ao=Math.floor(au/al/M);var af=[];var ap=0;while((ao*M*al)<ag){var at=am(ak,ae,ao);var ah=this.tile_cache.get(at);var aq=ao*M*this.view.resolution;var ab=aq+M*this.view.resolution;if(!aa&&ah){af[af.length]=ah;this.show_tile(ah,ad,aq,ae)}else{this.delayed_draw(aa,at,ao,al,ad,ae,af)}ao+=1;ap++}var aj=this;var ar=setInterval(function(){if(af.length===ap){clearInterval(ar);if(ac){var aA=aj.content_div.children();var aB=false;for(var az=aA.length-1,aF=0;az>=aF;az--){var ay=$(aA[az]);if(aB){ay.remove()}else{if(ay.children().length!==0){aB=true}}}}if(aj instanceof e&&aj.mode=="Histogram"){var aE=-1;for(var az=0;az<af.length;az++){var aH=af[az].max_val;if(aH>aE){aE=aH}}for(var az=0;az<af.length;az++){if(af[az].max_val!==aE){var aG=af[az];aG.canvas.remove();aj.delayed_draw(true,am(ak,ae,aG.index),aG.index,aG.resolution,ad,ae,[],{max:aE})}}}if(aj.filters_manager){var ax=aj.filters_manager.filters;for(var aD=0;aD<ax.length;aD++){ax[aD].update_ui_elt()}var aC=false;if(aj.example_feature){for(var aD=0;aD<ax.length;aD++){if(ax[aD].applies_to(aj.example_feature)){aC=true;break}}}if(aj.filters_available!==aC){aj.filters_available=aC;if(!aj.filters_available){aj.filters_div.hide()}aj.make_name_popup_menu()}}var av=false;for(var aw=0;aw<af.length;aw++){if(af[aw].message){av=true;break}}if(av){for(var aw=0;aw<af.length;aw++){aG=af[aw];if(!aG.message){aG.canvas.css("padding-top",A)}}}}},50);for(var an=0;an<this.child_tracks.length;an++){this.child_tracks[an].draw(aa,ac)}},delayed_draw:function(ab,ai,ac,ae,aj,am,ak,af){var ad=this,ag=ac*M*ae,al=ag+M*ae;var ah=function(av,an,ap,ao,at,au,aq){var ar=ad.draw_tile(an,ap,ao,au,aq);ad.tile_cache.set(ai,ar);if(ar===undefined){return}ad.show_tile(ar,at,ag,au);ak[ak.length]=ar};var aa=setTimeout(function(){if(ag<=ad.view.high&&al>=ad.view.low){var an=(ab?undefined:ad.tile_cache.get(ai));if(an){ad.show_tile(an,aj,ag,am);ak[ak.length]=an}else{$.when(ad.data_cache.get_data(view.chrom,ag,al,ad.mode,ae,ad.data_url_extra_params)).then(function(ao){n(ao,af);if(view.reference_track&&am>view.canvas_manager.char_width_px){$.when(view.reference_track.data_cache.get_data(view.chrom,ag,al,ad.mode,ae,view.reference_track.data_url_extra_params)).then(function(ap){ah(aa,ao,ae,ac,aj,am,ap)})}else{ah(aa,ao,ae,ac,aj,am)}})}}},50)},show_tile:function(ad,ag,ae,ah){var ab=this;var ac=this.view.high-this.view.low,af=(ae-this.view.low)*ah;if(this.left_offset){af-=this.left_offset}var aa=ad.canvas;aa.css({position:"absolute",top:0,left:af,height:""});ag.append(aa);ab.max_height=Math.max(ab.max_height,aa.height());ab.content_div.css("height",ab.max_height+"px");ag.children().css("height",ab.max_height+"px")},set_overview:function(){var aa=this.view;if(this.initial_canvas&&this.is_overview){aa.overview_close.show();aa.overview_viewport.append(this.initial_canvas);aa.overview_highlight.show().height(this.initial_canvas.height());aa.overview_viewport.height(this.initial_canvas.height()+aa.overview_box.height())}$(window).trigger("resize")},tool_region_and_parameters_str:function(ac,aa,ad){var ab=this,ae=(ac!==undefined&&aa!==undefined&&ad!==undefined?ac+":"+aa+"-"+ad:"all");return" - region=["+ae+"], parameters=["+ab.tool.get_param_values().join(", ")+"]"},add_track:function(aa){aa.track_id=this.track_id+"_"+this.child_tracks.length;aa.container_div.attr("id","track_"+aa.track_id);this.child_tracks_container.append(aa.container_div);C(aa.container_div,".child-track-icon");if(!$(this.child_tracks_container).is(":visible")){this.child_tracks_container.show()}this.child_tracks.push(aa);this.view.has_changes=true},remove_track:function(aa){aa.container_div.fadeOut("slow",function(){$(this).remove()})}});var X=function(aa,ab){this.hidden=true;j.call(this,null,aa,ab);this.container_div.addClass("label-track")};n(X.prototype,j.prototype,{draw:function(){var ac=this.view,ad=ac.high-ac.low,ag=Math.floor(Math.pow(10,Math.floor(Math.log(ad)/Math.log(10)))),aa=Math.floor(ac.low/ag)*ag,ae=this.view.container.width(),ab=$("<div style='position: relative; height: 1.3em;'></div>");while(aa<ac.high){var af=(aa-ac.low)/ad*ae;ab.append($("<div class='label'>"+commatize(aa)+"</div>").css({position:"absolute",left:af-1}));aa+=ag}this.content_div.children(":first").remove();this.content_div.append(ab)}});var x=function(aa){this.hidden=true;j.call(this,null,aa,aa.top_labeltrack);J.call(this);aa.reference_track=this;this.left_offset=200;this.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:aa.dbkey};this.data_cache=new E(y,this,false);this.tile_cache=new c(r)};n(x.prototype,J.prototype,{draw_tile:function(ai,af,ab,ak){var ae=this,ac=M*af;if(ak>this.view.canvas_manager.char_width_px){if(ai===null){ae.content_div.css("height","0px");return}var ad=this.view.canvas_manager.new_canvas();var aj=ad.getContext("2d");ad.width=Math.ceil(ac*ak+ae.left_offset);ad.height=ae.height_px;aj.font=aj.canvas.manager.default_font;aj.textAlign="center";for(var ag=0,ah=ai.length;ag<ah;ag++){var aa=Math.round(ag*ak);aj.fillText(ai[ag],aa+ae.left_offset,10)}return new b(ab,af,ad)}this.content_div.css("height","0px")}});var k=function(ae,ac,af,aa,ad){var ab=this;this.display_modes=["Histogram","Line","Filled","Intensity"];this.mode="Histogram";j.call(this,ae,ac,ac.viewport_container);J.call(this);this.min_height_px=16;this.max_height_px=400;this.height_px=80;this.hda_ldda=af;this.dataset_id=aa;this.original_dataset_id=aa;this.data_cache=new N(y,this);this.tile_cache=new c(r);this.track_config=new V({track:this,params:[{key:"color",label:"Color",type:"color",default_value:"black"},{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:this.height_px,hidden:true}],saved_values:ad,onchange:function(){ab.vertical_range=ab.prefs.max_value-ab.prefs.min_value;$("#linetrack_"+ab.track_id+"_minval").text(ab.prefs.min_value);$("#linetrack_"+ab.track_id+"_maxval").text(ab.prefs.max_value);ab.tile_cache.clear();ab.draw()}});this.prefs=this.track_config.values;this.height_px=this.track_config.values.height;this.vertical_range=this.track_config.values.max_value-this.track_config.values.min_value;this.add_resize_handle()};n(k.prototype,J.prototype,{add_resize_handle:function(){var aa=this;var ad=false;var ac=false;var ab=$("<div class='track-resize'>");$(aa.container_div).hover(function(){ad=true;ab.show()},function(){ad=false;if(!ac){ab.hide()}});ab.hide().bind("dragstart",function(ae,af){ac=true;af.original_height=$(aa.content_div).height()}).bind("drag",function(af,ag){var ae=Math.min(Math.max(ag.original_height+ag.deltaY,aa.min_height_px),aa.max_height_px);$(aa.content_div).css("height",ae);aa.height_px=ae;aa.draw(true)}).bind("dragend",function(ae,af){aa.tile_cache.clear();ac=false;if(!ad){ab.hide()}aa.track_config.values.height=aa.height_px}).appendTo(aa.container_div)},predraw_init:function(){var aa=this,ab=aa.view.tracks.indexOf(aa);aa.vertical_range=undefined;return $.getJSON(aa.data_url,{stats:true,chrom:aa.view.chrom,low:null,high:null,hda_ldda:aa.hda_ldda,dataset_id:aa.dataset_id},function(ac){aa.container_div.addClass("line-track");var ae=ac.data;if(isNaN(parseFloat(aa.prefs.min_value))||isNaN(parseFloat(aa.prefs.max_value))){aa.prefs.min_value=ae.min;aa.prefs.max_value=ae.max;$("#track_"+ab+"_minval").val(aa.prefs.min_value);$("#track_"+ab+"_maxval").val(aa.prefs.max_value)}aa.vertical_range=aa.prefs.max_value-aa.prefs.min_value;aa.total_frequency=ae.total_frequency;aa.container_div.find(".yaxislabel").remove();var af=$("<div />").addClass("yaxislabel").attr("id","linetrack_"+ab+"_minval").text(u(aa.prefs.min_value));var ad=$("<div />").addClass("yaxislabel").attr("id","linetrack_"+ab+"_maxval").text(u(aa.prefs.max_value));ad.css({position:"absolute",top:"24px",left:"10px"});ad.prependTo(aa.container_div);af.css({position:"absolute",bottom:"2px",left:"10px"});af.prependTo(aa.container_div)})},draw_tile:function(ak,ae,ab,aj){if(this.vertical_range===undefined){return}var af=ab*M*ae,ad=M*ae,aa=Math.ceil(ad*aj),ah=this.height_px;var ac=this.view.canvas_manager.new_canvas();ac.width=aa,ac.height=ah;var ai=ac.getContext("2d");var ag=new I.LinePainter(ak.data,af,af+ad,this.prefs,this.mode);ag.draw(ai,aa,ah);return new b(ad,ae,ac)}});var e=function(aa,af,ae,ai,ah,ac,ad,ag){var ab=this;this.display_modes=["Auto","Histogram","Dense","Squish","Pack"];this.track_config=new V({track:this,params:[{key:"block_color",label:"Block color",type:"color",default_value:"#444"},{key:"label_color",label:"Label color",type:"color",default_value:"black"},{key:"show_counts",label:"Show summary counts",type:"bool",default_value:true},{key:"mode",type:"string",default_value:this.mode,hidden:true},],saved_values:ah,onchange:function(){ab.tile_cache.clear();ab.draw()}});this.prefs=this.track_config.values;j.call(this,aa,af,af.viewport_container);J.call(this,ac,ad,ag);this.height_px=0;this.container_div.addClass("feature-track");this.hda_ldda=ae;this.dataset_id=ai;this.original_dataset_id=ai;this.show_labels_scale=0.001;this.showing_details=false;this.summary_draw_height=30;this.inc_slots={};this.start_end_dct={};this.tile_cache=new c(d);this.data_cache=new N(20,this);this.left_offset=200;this.painter=I.LinkedFeaturePainter};n(e.prototype,J.prototype,{update_auto_mode:function(aa){if(this.mode=="Auto"){if(aa=="no_detail"){aa="feature spans"}else{if(aa=="summary_tree"){aa="coverage histogram"}}this.mode_div.text("Auto ("+aa+")")}},incremental_slots:function(ae,ab,ad){var ac=this.view.canvas_manager.dummy_context,aa=this.inc_slots[ae];if(!aa||(aa.mode!==ad)){aa=new (p.FeatureSlotter)(ae,ad==="Pack",w,function(af){return ac.measureText(af)});aa.mode=ad;this.inc_slots[ae]=aa}return aa.slot_features(ab)},get_summary_tree_data:function(ae,ah,ac,ap){if(ap>ac-ah){ap=ac-ah}var al=Math.floor((ac-ah)/ap),ao=[],ad=0;var af=0,ag=0,ak,an=0,ai=[],am,aj;var ab=function(at,ar,au,aq){at[0]=ar+au*aq;at[1]=ar+(au+1)*aq};while(an<ap&&af!==ae.length){var aa=false;for(;an<ap&&!aa;an++){ab(ai,ah,an,al);for(ag=af;ag<ae.length;ag++){ak=ae[ag].slice(1,3);if(is_overlap(ak,ai)){aa=true;break}}if(aa){break}}data_start_index=ag;ao[ao.length]=am=[ai[0],0];for(;ag<ae.length;ag++){ak=ae[ag].slice(1,3);if(is_overlap(ak,ai)){am[1]++}else{break}}if(am[1]>ad){ad=am[1]}an++}return{max:ad,delta:al,data:ao}},draw_tile:function(an,aw,aA,aj,ad){var at=this,aC=aA*M*aw,ab=(aA+1)*M*aw,ap=ab-aC,au=Math.ceil(ap*aj),aq=this.mode,aH=25,ae=this.left_offset,ao,af;if(aq==="Auto"){if(an.dataset_type==="summary_tree"){aq=an.dataset_type}else{if(an.extra_info==="no_detail"){aq="no_detail"}else{var aG=an.data;if(this.view.high-this.view.low>F){aq="Squish"}else{aq="Pack"}}}this.update_auto_mode(aq)}if(aq==="summary_tree"||aq==="Histogram"){af=this.summary_draw_height;this.container_div.find(".yaxislabel").remove();var aa=$("<div />").addClass("yaxislabel");aa.text(an.max);aa.css({position:"absolute",top:"24px",left:"10px",color:this.prefs.label_color});aa.prependTo(this.container_div);var ac=this.view.canvas_manager.new_canvas();ac.width=au+ae;ac.height=af+O;if(an.dataset_type!="summary_tree"){var ak=this.get_summary_tree_data(an.data,aC,ab,200);if(an.max){ak.max=an.max}an=ak}var aE=new I.SummaryTreePainter(an,aC,ab,this.prefs);var av=ac.getContext("2d");av.translate(ae,O);aE.draw(av,au,af);return new l(aA,aw,ac,an.max)}var ao,ah=1;if(aq==="no_detail"||aq==="Squish"||aq==="Pack"){ah=this.incremental_slots(aj,an.data,aq);ao=this.inc_slots[aj].slots}var ai=[];if(an.data){var al=this.filters_manager.filters;for(var ax=0,az=an.data.length;ax<az;ax++){var ag=an.data[ax];var ay=false;var am;for(var aB=0,aF=al.length;aB<aF;aB++){am=al[aB];am.update_attrs(ag);if(!am.keep(ag)){ay=true;break}}if(!ay){ai.push(ag)}}}var aE=new (this.painter)(ai,aC,ab,this.prefs,aq,ad);var af=aE.get_required_height(ah);var ac=this.view.canvas_manager.new_canvas();ac.width=au+ae;ac.height=af;var av=ac.getContext("2d");av.fillStyle=this.prefs.block_color;av.font=av.canvas.manager.default_font;av.textAlign="right";this.container_div.find(".yaxislabel").remove();if(an.data){this.example_feature=(an.data.length?an.data[0]:undefined);av.translate(ae,0);aE.draw(av,au,af,ao)}if(an.message){var ar=$("<div/>");var aD=$("<div/>").addClass("tile-message").text(an.message).css("width",ac.width);aD.css({position:"absolute",top:0});$(ac).css("top",15);ar.append(aD);ar.append(ac);ac=ar}return new L(aA,aw,ac,an.message)}});var P=function(ad,ab,af,aa,ac,ae){e.call(this,ad,ab,af,aa,ac,ae);this.painter=I.VariantPainter};n(P.prototype,J.prototype,e.prototype);var S=function(ad,ab,af,aa,ac,ae){e.call(this,ad,ab,af,aa,ac,ae);this.track_config=new V({track:this,params:[{key:"block_color",label:"Block color",type:"color",default_value:"#444"},{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:"mode",type:"string",default_value:this.mode,hidden:true},],saved_values:ac,onchange:function(){this.track.tile_cache.clear();this.track.draw()}});this.prefs=this.track_config.values;this.painter=I.ReadPainter;this.make_name_popup_menu()};n(S.prototype,J.prototype,e.prototype);var Q=function(ae,ac,ag,aa,ad,af,ab){e.call(this,ae,ac,ag,aa,ad,af,{},ab);this.data_url=raw_data_url;this.data_query_wait=1000;this.dataset_check_url=dataset_state_url};n(Q.prototype,J.prototype,e.prototype,{predraw_init:function(){var ab=this;var aa=function(){if(ab.data_cache.size()===0){setTimeout(aa,300)}else{ab.data_url=default_data_url;ab.data_query_wait=H;ab.dataset_state_url=converted_datasets_state_url;$.getJSON(ab.dataset_state_url,{dataset_id:ab.dataset_id,hda_ldda:ab.hda_ldda},function(ac){})}};aa()}});T.View=Y;T.LineTrack=k;T.FeatureTrack=e;T.ReadTrack=S};var slotting_module=function(c,b){var e=c("class").extend;var d=2,a=5;b.FeatureSlotter=function(j,h,f,g){this.slots={};this.start_end_dct={};this.w_scale=j;this.include_label=h;this.max_rows=f;this.measureText=g};e(b.FeatureSlotter.prototype,{slot_features:function(m){var p=this.w_scale,s=this.slots,h=this.start_end_dct,y=[],A=[],n=0,z=this.max_rows;for(var w=0,x=m.length;w<x;w++){var l=m[w],o=l[0];if(s[o]!==undefined){n=Math.max(n,s[o]);A.push(s[o])}else{y.push(w)}}var q=function(G,H){for(var F=0;F<=z;F++){var D=false,I=h[F];if(I!==undefined){for(var C=0,E=I.length;C<E;C++){var B=I[C];if(H>B[0]&&G<B[1]){D=true;break}}}if(!D){return F}}return -1};for(var w=0,x=y.length;w<x;w++){var l=m[y[w]],o=l[0],u=l[1],f=l[2],r=l[3],g=Math.floor(u*p),k=Math.ceil(f*p),v=this.measureText(r).width,j;if(r!==undefined&&this.include_label){v+=(d+a);if(g-v>=0){g-=v;j="left"}else{k+=v;j="right"}}var t=q(g,k);if(t>=0){if(h[t]===undefined){h[t]=[]}h[t].push([g,k]);s[o]=t;n=Math.max(n,t)}else{}}return n+1}})};var painters_module=function(j,w){var t=j("class").extend;var o=function(H,z,F,y,E,C){if(C===undefined){C=4}var B=y-z;var A=E-F;var D=Math.floor(Math.sqrt(B*B+A*A)/C);var I=B/D;var G=A/D;var x;for(x=0;x<D;x++,z+=I,F+=G){if(x%2!==0){continue}H.fillRect(z,F,C,1)}};var p=function(A,z,x,D){var C=z-D/2,B=z+D/2,E=x-Math.sqrt(D*3/2);A.beginPath();A.moveTo(C,E);A.lineTo(B,E);A.lineTo(z,x);A.lineTo(C,E);A.strokeStyle=this.fillStyle;A.fill();A.stroke();A.closePath()};var m=function(z,B,x,y,A){this.data=z;this.view_start=B;this.view_end=x;this.prefs=t({},this.default_prefs,y);this.mode=A};m.prototype.default_prefs={};var u=function(z,B,x,y,A){m.call(this,z,B,x,y,A)};u.prototype.default_prefs={show_counts:false};u.prototype.draw=function(M,z,L){var E=this.view_start,O=this.view_end-this.view_start,N=z/O;var J=this.data.data,I=this.data.delta,G=this.data.max,B=L;delta_x_px=Math.ceil(I*N);M.save();for(var C=0,D=J.length;C<D;C++){var H=Math.floor((J[C][0]-E)*N);var F=J[C][1];if(!F){continue}var K=F/G*L;if(F!==0&&K<1){K=1}M.fillStyle=this.prefs.block_color;M.fillRect(H,B-K,delta_x_px,K);var A=4;if(this.prefs.show_counts&&(M.measureText(F).width+A)<delta_x_px){M.fillStyle=this.prefs.label_color;M.textAlign="center";M.fillText(F,H+(delta_x_px/2),10)}}M.restore()};var c=function(x,B,D,E,z){m.call(this,x,B,D,E,z);if(this.prefs.min_value===undefined){var F=Infinity;for(var y=0,A=this.data.length;y<A;y++){F=Math.min(F,this.data[y][1])}this.prefs.min_value=F}if(this.prefs.max_value===undefined){var C=-Infinity;for(var y=0,A=this.data.length;y<A;y++){C=Math.max(C,this.data[y][1])}this.prefs.max_value=C}};c.prototype.default_prefs={min_value:undefined,max_value:undefined,mode:"Histogram",color:"#000",overflow_color:"#F66"};c.prototype.draw=function(M,L,J){var E=false,G=this.prefs.min_value,C=this.prefs.max_value,I=C-G,x=J,z=this.view_start,K=this.view_end-this.view_start,A=L/K,H=this.mode,S=this.data;M.save();var T=Math.round(J+G/I*J);if(H!=="Intensity"){M.fillStyle="#aaa";M.fillRect(0,T,L,1)}M.beginPath();var Q,D,B;if(S.length>1){B=Math.ceil((S[1][0]-S[0][0])*A)}else{B=10}for(var N=0,O=S.length;N<O;N++){M.fillStyle=this.prefs.color;Q=Math.round((S[N][0]-z)*A);D=S[N][1];var P=false,F=false;if(D===null){if(E&&H==="Filled"){M.lineTo(Q,x)}E=false;continue}if(D<G){F=true;D=G}else{if(D>C){P=true;D=C}}if(H==="Histogram"){D=Math.round(D/I*x);M.fillRect(Q,T,B,-D)}else{if(H==="Intensity"){D=255-Math.floor((D-G)/I*255);M.fillStyle="rgb("+D+","+D+","+D+")";M.fillRect(Q,0,B,x)}else{D=Math.round(x-(D-G)/I*x);if(E){M.lineTo(Q,D)}else{E=true;if(H==="Filled"){M.moveTo(Q,x);M.lineTo(Q,D)}else{M.moveTo(Q,D)}}}}M.fillStyle=this.prefs.overflow_color;if(P||F){var R;if(H==="Histogram"||H==="Intensity"){R=B}else{Q-=2;R=4}if(P){M.fillRect(Q,0,R,3)}if(F){M.fillRect(Q,x-3,R,3)}}M.fillStyle=this.prefs.color}if(H==="Filled"){if(E){M.lineTo(Q,T);M.lineTo(0,T)}M.fill()}else{M.stroke()}M.restore()};var n=function(z,B,x,y,A){m.call(this,z,B,x,y,A)};n.prototype.default_prefs={block_color:"#FFF",connector_color:"#FFF"};t(n.prototype,{get_required_height:function(y){var x=y_scale=this.get_row_height(),z=this.mode;if(z==="no_detail"||z==="Squish"||z==="Pack"){x=y*y_scale}return x+Math.max(Math.round(y_scale/2),5)},draw:function(J,A,I,F){var D=this.data,G=this.view_start,K=this.view_end;J.save();J.fillStyle=this.prefs.block_color;J.textAlign="right";var N=this.view_end-this.view_start,M=A/N,z=this.get_row_height();for(var C=0,E=D.length;C<E;C++){var L=D[C],B=L[0],x=L[1],y=L[2],H=(F&&F[B]!==undefined?F[B]:null);if((x<K&&y>G)&&(this.mode=="Dense"||H!==null)){this.draw_element(J,this.mode,L,H,G,K,M,z,A)}}J.restore()}});var d=10,h=3,l=5,v=10,f=1,r=3,e=3,a=9,k=2,g="#ccc";var q=function(z,B,x,y,A){n.call(this,z,B,x,y,A)};t(q.prototype,n.prototype,{get_row_height:function(){var y=this.mode,x;if(y==="Dense"){x=d}else{if(y==="no_detail"){x=h}else{if(y==="Squish"){x=l}else{x=v}}}return x},draw_element:function(J,C,R,E,L,ab,af,ag,x){var O=R[0],ad=R[1],V=R[2],M=R[3],W=Math.floor(Math.max(0,(ad-L)*af)),K=Math.ceil(Math.min(x,Math.max(0,(V-L)*af))),U=(C==="Dense"?0:(0+E))*ag,I,Z,N=null,ah=null,A=this.prefs.block_color,Y=this.prefs.label_color;if(C=="Dense"){E=1}if(C==="no_detail"){J.fillStyle=A;J.fillRect(W,U+5,K-W,f)}else{var H=R[4],T=R[5],X=R[6],B=R[7];if(T&&X){N=Math.floor(Math.max(0,(T-L)*af));ah=Math.ceil(Math.min(x,Math.max(0,(X-L)*af)))}var ae,P;if(C==="Squish"||C==="Dense"){ae=1;P=e}else{ae=5;P=a}if(!B){if(R.strand){if(R.strand==="+"){J.fillStyle=J.canvas.manager.get_pattern("right_strand_inv")}else{if(R.strand==="-"){J.fillStyle=J.canvas.manager.get_pattern("left_strand_inv")}}}else{J.fillStyle=A}J.fillRect(W,U,K-W,P)}else{var G,Q;if(C==="Squish"||C==="Dense"){J.fillStyle=g;G=U+Math.floor(e/2)+1;Q=1}else{if(H){var G=U;var Q=P;if(H==="+"){J.fillStyle=J.canvas.manager.get_pattern("right_strand")}else{if(H==="-"){J.fillStyle=J.canvas.manager.get_pattern("left_strand")}}}else{J.fillStyle=g;G+=(e/2)+1;Q=1}}J.fillRect(W,G,K-W,Q);for(var ac=0,z=B.length;ac<z;ac++){var D=B[ac],y=Math.floor(Math.max(0,(D[0]-L)*af)),S=Math.ceil(Math.min(x,Math.max((D[1]-L)*af)));if(y>S){continue}J.fillStyle=A;J.fillRect(y,U+(P-ae)/2+1,S-y,ae);if(N!==undefined&&X>T&&!(y>ah||S<N)){var aa=Math.max(y,N),F=Math.min(S,ah);J.fillRect(aa,U+1,F-aa,P);if(B.length==1&&C=="Pack"){if(H==="+"){J.fillStyle=J.canvas.manager.get_pattern("right_strand_inv")}else{if(H==="-"){J.fillStyle=J.canvas.manager.get_pattern("left_strand_inv")}}if(aa+14<F){aa+=2;F-=2}J.fillRect(aa,U+1,F-aa,P)}}}}if(C==="Pack"&&ad>L){J.fillStyle=Y;if(L===0&&W-J.measureText(M).width<0){J.textAlign="left";J.fillText(M,K+k,U+8)}else{J.textAlign="right";J.fillText(M,W-k,U+8)}J.fillStyle=A}}}});var b=function(z,B,x,y,A){n.call(this,z,B,x,y,A)};t(b.prototype,n.prototype,{draw_element:function(Q,L,F,B,T,z,I,R,O){var F=data[i],H=F[0],P=F[1],A=F[2],K=F[3],D=Math.floor(Math.max(0,(P-T)*I)),G=Math.ceil(Math.min(O,Math.max(0,(A-T)*I))),C=(L==="Dense"?0:(0+B))*R,x,U,y=null,J=null;if(no_label){Q.fillStyle=block_color;Q.fillRect(D+left_offset,C+5,G-D,1)}else{var S=F[4],N=F[5],E=F[6];x=9;U=1;Q.fillRect(D+left_offset,C,G-D,x);if(L!=="Dense"&&K!==undefined&&P>T){Q.fillStyle=label_color;if(T===0&&D-Q.measureText(K).width<0){Q.textAlign="left";Q.fillText(K,G+2+left_offset,C+8)}else{Q.textAlign="right";Q.fillText(K,D-2+left_offset,C+8)}Q.fillStyle=block_color}var M=S+" / "+N;if(P>T&&Q.measureText(M).width<(G-D)){Q.fillStyle="white";Q.textAlign="center";Q.fillText(M,left_offset+D+(G-D)/2,C+8);Q.fillStyle=block_color}}}});var s=function(A,C,x,z,B,y){n.call(this,A,C,x,z,B);this.ref_seq=y};s.prototype.default_prefs=t({},n.prototype.default_prefs,{show_insertions:false});t(s.prototype,n.prototype,{get_row_height:function(){var x,y=this.mode;if(y==="Dense"){x=d}else{if(y==="Squish"){x=l}else{x=v;if(this.prefs.show_insertions){x*=2}}}return x},draw_read:function(T,O,K,Y,z,S,H,E,D){T.textAlign="center";var R=this,y=[Y,z],N=0,U=0,Q=0;ref_seq=this.ref_seq,char_width_px=T.canvas.manager.char_width_px;var ad=[];if((O==="Pack"||this.mode==="Auto")&&E!==undefined&&K>char_width_px){Q=Math.round(K/2)}if(!H){H=[[0,E.length]]}for(var L=0,W=H.length;L<W;L++){var I=H[L],A="MIDNSHP=X"[I[0]],M=I[1];if(A==="H"||A==="S"){N-=M}var F=S+N,ac=Math.floor(Math.max(0,(F-Y)*K)),G=Math.floor(Math.max(0,(F+M-Y)*K));if(ac===G){G+=1}switch(A){case"H":break;case"S":case"M":case"=":if(is_overlap([F,F+M],y)){var P=E.slice(U,U+M);if(Q>0){T.fillStyle=this.prefs.block_color;T.fillRect(ac-Q,D+1,G-ac,9);T.fillStyle=g;for(var aa=0,x=P.length;aa<x;aa++){if(this.prefs.show_differences&&ref_seq){var J=ref_seq[F-Y+aa];if(!J||J.toLowerCase()===P[aa].toLowerCase()){continue}}if(F+aa>=Y&&F+aa<=z){var ab=Math.floor(Math.max(0,(F+aa-Y)*K));T.fillText(P[aa],ab,D+9)}}}else{T.fillStyle=this.prefs.block_color;T.fillRect(ac,D+4,G-ac,e)}}U+=M;N+=M;break;case"N":T.fillStyle=g;T.fillRect(ac-Q,D+5,G-ac,1);N+=M;break;case"D":T.fillStyle="red";T.fillRect(ac-Q,D+4,G-ac,3);N+=M;break;case"P":break;case"I":var X=ac-Q;if(is_overlap([F,F+M],y)){var P=E.slice(U,U+M);if(this.prefs.show_insertions){var C=ac-(G-ac)/2;if((O==="Pack"||this.mode==="Auto")&&E!==undefined&&K>char_width_px){T.fillStyle="yellow";T.fillRect(C-Q,D-9,G-ac,9);ad[ad.length]={type:"triangle",data:[X,D+4,5]};T.fillStyle=g;switch(seq_tile_overlap){case (OVERLAP_START):P=P.slice(Y-F);break;case (OVERLAP_END):P=P.slice(0,F-z);break;case (CONTAINED_BY):break;case (CONTAINS):P=P.slice(Y-F,F-z);break}for(var aa=0,x=P.length;aa<x;aa++){var ab=Math.floor(Math.max(0,(F+aa-Y)*K));T.fillText(P[aa],ab-(G-ac)/2,D)}}else{T.fillStyle="yellow";T.fillRect(C,D+(this.mode!=="Dense"?2:5),G-ac,(O!=="Dense"?e:r))}}else{if((O==="Pack"||this.mode==="Auto")&&E!==undefined&&K>char_width_px){ad[ad.length]={type:"text",data:[P.length,X,D+9]}}else{}}}U+=M;break;case"X":U+=M;break}}T.fillStyle="yellow";var Z,B,ae;for(var V=0;V<ad.length;V++){Z=ad[V];B=Z.type;ae=Z.data;if(B==="text"){T.save();T.font="bold "+T.font;T.fillText(ae[0],ae[1],ae[2]);T.restore()}else{if(B=="triangle"){p(T,ae[0],ae[1],ae[2])}}}},draw_element:function(Q,L,D,A,T,y,H,R,O){var G=D[0],P=D[1],z=D[2],I=D[3],C=Math.floor(Math.max(0,(P-T)*H)),E=Math.ceil(Math.min(O,Math.max(0,(z-T)*H))),B=(L==="Dense"?0:(0+A))*R,U=this.prefs.block_color,F=this.prefs.label_color,N=0;if((L==="Pack"||this.mode==="Auto")&&H>Q.canvas.manager.char_width_px){var N=Math.round(H/2)}Q.fillStyle=U;if(D[5] instanceof Array){var M=Math.floor(Math.max(0,(D[4][0]-T)*H)),K=Math.ceil(Math.min(O,Math.max(0,(D[4][1]-T)*H))),J=Math.floor(Math.max(0,(D[5][0]-T)*H)),x=Math.ceil(Math.min(O,Math.max(0,(D[5][1]-T)*H)));if(D[4][1]>=T&&D[4][0]<=y&&D[4][2]){this.draw_read(Q,L,H,T,y,D[4][0],D[4][2],D[4][3],B)}if(D[5][1]>=T&&D[5][0]<=y&&D[5][2]){this.draw_read(Q,L,H,T,y,D[5][0],D[5][2],D[5][3],B)}if(J>K){Q.fillStyle=g;o(Q,K-N,B+5,J-N,B+5)}}else{Q.fillStyle=U;this.draw_read(Q,L,H,T,y,P,D[4],D[5],B)}if(L==="Pack"&&P>T){Q.fillStyle=this.prefs.label_color;var S=1;if(S===0&&C-Q.measureText(I).width<0){Q.textAlign="left";Q.fillText(I,E+k-N,B+8)}else{Q.textAlign="right";Q.fillText(I,C-k-N,B+8)}Q.fillStyle=U}}});w.SummaryTreePainter=u;w.LinePainter=c;w.LinkedFeaturePainter=q;w.ReadPainter=s;w.VariantPainter=b};(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
--- a/static/scripts/trackster.js Thu Jun 30 15:09:08 2011 -0400
+++ b/static/scripts/trackster.js Thu Jun 30 16:13:52 2011 -0400
@@ -2683,6 +2683,7 @@
this.example_feature = (result.data.length ? result.data[0] : undefined);
// Draw features.
+ ctx.translate(left_offset, 0);
painter.draw(ctx, width, required_height, slots);
}
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: Increment the repository.times_downloaded column in the Galaxy tool shed database when the repository is cloned from the command line.
by Bitbucket 30 Jun '11
by Bitbucket 30 Jun '11
30 Jun '11
1 new changeset in galaxy-central:
http://bitbucket.org/galaxy/galaxy-central/changeset/cb18eb985ab3/
changeset: cb18eb985ab3
user: greg
date: 2011-06-30 21:09:08
summary: Increment the repository.times_downloaded column in the Galaxy tool shed database when the repository is cloned from the command line.
affected #: 1 file (1.6 KB)
--- a/lib/galaxy/webapps/community/framework/middleware/hg.py Thu Jun 30 14:07:55 2011 -0400
+++ b/lib/galaxy/webapps/community/framework/middleware/hg.py Thu Jun 30 15:09:08 2011 -0400
@@ -23,14 +23,41 @@
self.username = None
self.action = None
def __call__( self, environ, start_response ):
- # Handle authentication for hg push commands
cmd = self.__get_hg_command( **environ )
+ if cmd == 'changegroup':
+ # This is an hg clone from the command line. When doing this, the following 5 commands, in order,
+ # will be retrieved from environ:
+ # between -> heads -> changegroup -> capabilities -> listkeys
+ #
+ # Increment the value of the times_downloaded column in the repository table for the cloned repository.
+ if 'PATH_INFO' in environ:
+ path_info = environ[ 'PATH_INFO' ].lstrip( '/' )
+ # An example of path_info is: '/repos/test/column1'
+ path_info_components = path_info.split( '/' )
+ username = path_info_components[1]
+ name = path_info_components[2]
+ # Instantiate a database connection
+ db_url = self.config[ 'database_connection' ]
+ engine = create_engine( db_url )
+ connection = engine.connect()
+ result_set = connection.execute( "select id from galaxy_user where username = '%s'" % username.lower() )
+ for row in result_set:
+ # Should only be 1 row...
+ user_id = row[ 'id' ]
+ result_set = connection.execute( "select times_downloaded from repository where user_id = %d and name = '%s'" % ( user_id, name.lower() ) )
+ for row in result_set:
+ # Should only be 1 row...
+ times_downloaded = row[ 'times_downloaded' ]
+ times_downloaded += 1
+ connection.execute( "update repository set times_downloaded = %d where user_id = %d and name = '%s'" % ( times_downloaded, user_id, name.lower() ) )
+ connection.close()
if cmd == 'unbundle':
+ # This is an hg push from the command line. When doing this, the following 7 commands, in order,
+ # will be retrieved from environ:
+ # between -> capabilities -> heads -> branchmap -> unbundle -> unbundle -> listkeys
+ #
# The mercurial API unbundle() ( i.e., hg push ) method ultimately requires authorization.
- # We'll force password entry every time a change set is pushed. The user that pushes the changes
- # sets may not be the same user that committed the change sets. In other words, the user that is
- # pushing is the one being authenticated, but the owner of a specific change set in the change log
- # may be different.
+ # We'll force password entry every time a change set is pushed.
#
# When a user executes hg commit, it is not guaranteed to succeed. Mercurial records your name
# and address with each change that you commit, so that you and others will later be able to
@@ -40,7 +67,7 @@
# 1) If you specify a -u option to the hg commit command on the command line, followed by a username,
# this is always given the highest precedence.
# 2) If you have set the HGUSER environment variable, this is checked next.
- # 3) If you create a file in your home directory called .hgrc (~/.hgrc), with a username entry, that
+ # 3) If you create a file in your home directory called .hgrc with a username entry, that
# will be used next.
# 4) If you have set the EMAIL environment variable, this will be used next.
# 5) Mercurial will query your system to find out your local user name and host name, and construct
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: Fix a bug in the Galaxy tool shed I just introduced in my last commit.
by Bitbucket 30 Jun '11
by Bitbucket 30 Jun '11
30 Jun '11
1 new changeset in galaxy-central:
http://bitbucket.org/galaxy/galaxy-central/changeset/2eb45c152c10/
changeset: 2eb45c152c10
user: greg
date: 2011-06-30 20:07:55
summary: Fix a bug in the Galaxy tool shed I just introduced in my last commit.
affected #: 1 file (5 bytes)
--- a/lib/galaxy/webapps/community/controllers/repository.py Thu Jun 30 12:13:20 2011 -0400
+++ b/lib/galaxy/webapps/community/controllers/repository.py Thu Jun 30 14:07:55 2011 -0400
@@ -143,7 +143,7 @@
# Columns that are valid for filtering but are not visible.
EmailColumn( "Email",
model_class=model.User,
- key="User.email",
+ key="email",
visible=False ),
RepositoryCategoryColumn( "Category",
model_class=model.Category,
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 changeset in galaxy-central:
http://bitbucket.org/galaxy/galaxy-central/changeset/c2d266a4a8f8/
changeset: c2d266a4a8f8
user: greg
date: 2011-06-30 18:13:20
summary: Add the ability for a tool shed admin to delete / undelete repositories. Fix the display for TextArea fields in the tool shed. Fix a bug in the Advanced search gid feature - the Advanced search box will now correctly close even if the grid's default_filter dictionary is not empty. Add the ability to not render the Advanced search box on a grid by passing a flag value to the render method.
affected #: 10 files (2.9 KB)
--- a/lib/galaxy/web/framework/helpers/grids.py Thu Jun 30 11:45:24 2011 -0400
+++ b/lib/galaxy/web/framework/helpers/grids.py Thu Jun 30 12:13:20 2011 -0400
@@ -626,6 +626,13 @@
args = { self.key: val }
accepted_filters.append( GridColumnFilter( label, args) )
return accepted_filters
+ def filter( self, trans, user, query, column_filter ):
+ """Modify query to filter self.model_class by state."""
+ if column_filter == "All":
+ pass
+ elif column_filter in [ "True", "False" ]:
+ query = query.filter( self.model_class.deleted == column_filter )
+ return query
class StateColumn( GridColumn ):
"""
--- a/lib/galaxy/webapps/community/controllers/admin.py Thu Jun 30 11:45:24 2011 -0400
+++ b/lib/galaxy/webapps/community/controllers/admin.py Thu Jun 30 12:13:20 2011 -0400
@@ -2,6 +2,7 @@
from galaxy.webapps.community import model
from galaxy.model.orm import *
from galaxy.web.framework.helpers import time_ago, iff, grids
+from galaxy.util import inflector
from common import get_category, get_repository
from repository import RepositoryListGrid, CategoryListGrid
import logging
@@ -282,39 +283,30 @@
preserve_state = False
use_paging = True
-class AdminCategoryListGrid( CategoryListGrid ):
- # Override standard filters
- standard_filters = [
- grids.GridColumnFilter( "Active", args=dict( deleted=False ) ),
- grids.GridColumnFilter( "Deleted", args=dict( deleted=True ) ),
- grids.GridColumnFilter( "All", args=dict( deleted='All' ) )
- ]
-
class ManageCategoryListGrid( CategoryListGrid ):
columns = [ col for col in CategoryListGrid.columns ]
# Override the NameColumn to include an Edit link
columns[ 0 ] = CategoryListGrid.NameColumn( "Name",
- key="name",
+ key="Category.name",
link=( lambda item: dict( operation="Edit", id=item.id, webapp="community" ) ),
model_class=model.Category,
- attach_popup=False,
- filterable="advanced" )
+ attach_popup=False )
global_actions = [
grids.GridAction( "Add new category",
dict( controller='admin', action='manage_categories', operation='create', webapp="community" ) )
]
- operations = [ grids.GridOperation( "Delete",
- condition=( lambda item: not item.deleted ),
- allow_multiple=True,
- url_args=dict( webapp="community", action="mark_category_deleted" ) ),
- grids.GridOperation( "Undelete",
- condition=( lambda item: item.deleted ),
- allow_multiple=True,
- url_args=dict( webapp="community", action="undelete_category" ) ),
- grids.GridOperation( "Purge",
- condition=( lambda item: item.deleted ),
- allow_multiple=True,
- url_args=dict( webapp="community", action="purge_category" ) ) ]
+
+class AdminRepositoryListGrid( RepositoryListGrid ):
+ operations = [ operation for operation in RepositoryListGrid.operations ]
+ operations.append( grids.GridOperation( "Delete",
+ allow_multiple=True,
+ condition=( lambda item: not item.deleted ),
+ async_compatible=False ) )
+ operations.append( grids.GridOperation( "Undelete",
+ allow_multiple=True,
+ condition=( lambda item: item.deleted ),
+ async_compatible=False ) )
+ standard_filters = []
class AdminController( BaseController, Admin ):
@@ -322,7 +314,7 @@
role_list_grid = RoleListGrid()
group_list_grid = GroupListGrid()
manage_category_list_grid = ManageCategoryListGrid()
- repository_list_grid = RepositoryListGrid()
+ repository_list_grid = AdminRepositoryListGrid()
@web.expose
@web.require_admin
@@ -363,10 +355,81 @@
category_id = kwd.get( 'id', None )
category = get_category( trans, category_id )
kwd[ 'f-Category.name' ] = category.name
+ elif operation == "receive email alerts":
+ if kwd[ 'id' ]:
+ return trans.response.send_redirect( web.url_for( controller='repository',
+ action='set_email_alerts',
+ **kwd ) )
+ else:
+ del kwd[ 'operation' ]
+ elif operation == 'delete':
+ return self.mark_repository_deleted( trans, **kwd )
+ elif operation == "undelete":
+ return self.undelete_repository( trans, **kwd )
# Render the list view
return self.repository_list_grid( trans, **kwd )
@web.expose
@web.require_admin
+ def mark_repository_deleted( self, trans, **kwd ):
+ params = util.Params( kwd )
+ message = util.restore_text( params.get( 'message', '' ) )
+ status = params.get( 'status', 'done' )
+ id = kwd.get( 'id', None )
+ if id:
+ ids = util.listify( id )
+ count = 0
+ deleted_repositories = ""
+ for repository_id in ids:
+ repository = get_repository( trans, repository_id )
+ if not repository.deleted:
+ repository.deleted = True
+ trans.sa_session.add( repository )
+ trans.sa_session.flush()
+ count += 1
+ deleted_repositories += " %s " % repository.name
+ if count:
+ message = "Deleted %d %s: %s" % ( count, inflector.cond_plural( len( ids ), "repository" ), deleted_repositories )
+ else:
+ message = "All selected repositories were already marked deleted."
+ else:
+ message = "No repository ids received for deleting."
+ status = 'error'
+ trans.response.send_redirect( web.url_for( controller='admin',
+ action='browse_repositories',
+ message=util.sanitize_text( message ),
+ status=status ) )
+ @web.expose
+ @web.require_admin
+ def undelete_repository( self, trans, **kwd ):
+ params = util.Params( kwd )
+ message = util.restore_text( params.get( 'message', '' ) )
+ status = params.get( 'status', 'done' )
+ id = kwd.get( 'id', None )
+ if id:
+ ids = util.listify( id )
+ count = 0
+ undeleted_repositories = ""
+ for repository_id in ids:
+ repository = get_repository( trans, repository_id )
+ if repository.deleted:
+ repository.deleted = False
+ trans.sa_session.add( repository )
+ trans.sa_session.flush()
+ count += 1
+ undeleted_repositories += " %s" % repository.name
+ if count:
+ message = "Undeleted %d %s: %s" % ( count, inflector.cond_plural( count, "repository" ), undeleted_repositories )
+ else:
+ message = "No selected repositories were marked deleted, so they could not be undeleted."
+ else:
+ message = "No repository ids received for undeleting."
+ status = 'error'
+ trans.response.send_redirect( web.url_for( controller='admin',
+ action='browse_repositories',
+ message=util.sanitize_text( message ),
+ status='done' ) )
+ @web.expose
+ @web.require_admin
def manage_categories( self, trans, **kwd ):
if 'f-free-text-search' in kwd:
# Trick to enable searching repository name, description from the CategoryListGrid.
@@ -476,22 +539,25 @@
@web.expose
@web.require_admin
def mark_category_deleted( self, trans, **kwd ):
+ # TODO: We should probably eliminate the Category.deleted column since it really makes no
+ # sense to mark a category as deleted (category names and descriptions can be changed instead).
+ # If we do this, and the following 2 methods can be eliminated.
params = util.Params( kwd )
+ message = util.restore_text( params.get( 'message', '' ) )
+ status = params.get( 'status', 'done' )
id = kwd.get( 'id', None )
- if not id:
- message = "No category ids received for deleting"
- trans.response.send_redirect( web.url_for( controller='admin',
- action='manage_categories',
- message=message,
- status='error' ) )
- ids = util.listify( id )
- message = "Deleted %d categories: " % len( ids )
- for category_id in ids:
- category = get_category( trans, category_id )
- category.deleted = True
- trans.sa_session.add( category )
- trans.sa_session.flush()
- message += " %s " % category.name
+ if id:
+ ids = util.listify( id )
+ message = "Deleted %d categories: " % len( ids )
+ for category_id in ids:
+ category = get_category( trans, category_id )
+ category.deleted = True
+ trans.sa_session.add( category )
+ trans.sa_session.flush()
+ message += " %s " % category.name
+ else:
+ message = "No category ids received for deleting."
+ status = 'error'
trans.response.send_redirect( web.url_for( controller='admin',
action='manage_categories',
message=util.sanitize_text( message ),
@@ -500,30 +566,25 @@
@web.require_admin
def undelete_category( self, trans, **kwd ):
params = util.Params( kwd )
+ message = util.restore_text( params.get( 'message', '' ) )
+ status = params.get( 'status', 'done' )
id = kwd.get( 'id', None )
- if not id:
- message = "No category ids received for undeleting"
- trans.response.send_redirect( web.url_for( controller='admin',
- action='manage_categories',
- message=message,
- status='error' ) )
- ids = util.listify( id )
- count = 0
- undeleted_categories = ""
- for category_id in ids:
- category = get_category( trans, category_id )
- if not category.deleted:
- message = "Category '%s' has not been deleted, so it cannot be undeleted." % category.name
- trans.response.send_redirect( web.url_for( controller='admin',
- action='manage_categories',
- message=util.sanitize_text( message ),
- status='error' ) )
- category.deleted = False
- trans.sa_session.add( category )
- trans.sa_session.flush()
- count += 1
- undeleted_categories += " %s" % category.name
- message = "Undeleted %d categories: %s" % ( count, undeleted_categories )
+ if id:
+ ids = util.listify( id )
+ count = 0
+ undeleted_categories = ""
+ for category_id in ids:
+ category = get_category( trans, category_id )
+ if category.deleted:
+ category.deleted = False
+ trans.sa_session.add( category )
+ trans.sa_session.flush()
+ count += 1
+ undeleted_categories += " %s" % category.name
+ message = "Undeleted %d categories: %s" % ( count, undeleted_categories )
+ else:
+ message = "No category ids received for undeleting."
+ status = 'error'
trans.response.send_redirect( web.url_for( controller='admin',
action='manage_categories',
message=util.sanitize_text( message ),
@@ -535,28 +596,26 @@
# Purging a deleted Category deletes all of the following from the database:
# - RepoitoryCategoryAssociations where category_id == Category.id
params = util.Params( kwd )
+ message = util.restore_text( params.get( 'message', '' ) )
+ status = params.get( 'status', 'done' )
id = kwd.get( 'id', None )
- if not id:
- message = "No category ids received for purging"
- trans.response.send_redirect( web.url_for( controller='admin',
- action='manage_categories',
- message=util.sanitize_text( message ),
- status='error' ) )
- ids = util.listify( id )
- message = "Purged %d categories: " % len( ids )
- for category_id in ids:
- category = get_category( trans, category_id )
- if not category.deleted:
- message = "Category '%s' has not been deleted, so it cannot be purged." % category.name
- trans.response.send_redirect( web.url_for( controller='admin',
- action='manage_categories',
- message=util.sanitize_text( message ),
- status='error' ) )
- # Delete RepositoryCategoryAssociations
- for rca in category.repositories:
- trans.sa_session.delete( rca )
- trans.sa_session.flush()
- message += " %s " % category.name
+ if id:
+ ids = util.listify( id )
+ count = 0
+ purged_categories = ""
+ message = "Purged %d categories: " % len( ids )
+ for category_id in ids:
+ category = get_category( trans, category_id )
+ if category.deleted:
+ # Delete RepositoryCategoryAssociations
+ for rca in category.repositories:
+ trans.sa_session.delete( rca )
+ trans.sa_session.flush()
+ purged_categories += " %s " % category.name
+ message = "Purged %d categories: %s" % ( count, purged_categories )
+ else:
+ message = "No category ids received for purging."
+ status = 'error'
trans.response.send_redirect( web.url_for( controller='admin',
action='manage_categories',
message=util.sanitize_text( message ),
--- a/lib/galaxy/webapps/community/controllers/repository.py Thu Jun 30 11:45:24 2011 -0400
+++ b/lib/galaxy/webapps/community/controllers/repository.py Thu Jun 30 12:13:20 2011 -0400
@@ -50,25 +50,19 @@
default_sort_key = "name"
columns = [
NameColumn( "Name",
- key="name",
+ key="Category.name",
link=( lambda item: dict( operation="repositories_by_category", id=item.id, webapp="community" ) ),
- attach_popup=False,
- filterable="advanced" ),
+ attach_popup=False ),
DescriptionColumn( "Description",
- key="description",
- attach_popup=False,
- filterable="advanced" ),
+ key="Category.description",
+ attach_popup=False ),
# Columns that are valid for filtering but are not visible.
- grids.DeletedColumn( "Deleted",
- key="deleted",
- visible=False,
- filterable="advanced" ),
RepositoriesColumn( "Repositories",
model_class=model.Repository,
attach_popup=False )
]
-
# Override these
+ default_filter = {}
global_actions = []
operations = []
standard_filters = []
@@ -102,7 +96,7 @@
def filter( self, trans, user, query, column_filter ):
"""Modify query to filter by category."""
if column_filter == "All":
- pass
+ return query
return query.filter( model.Category.name == column_filter )
class UserColumn( grids.TextColumn ):
def get_value( self, trans, grid, repository ):
@@ -127,7 +121,7 @@
default_sort_key = "name"
columns = [
NameColumn( "Name",
- key="Repository.name",
+ key="name",
link=( lambda item: dict( operation="view_or_manage_repository", id=item.id, webapp="community" ) ),
attach_popup=False ),
DescriptionColumn( "Description",
@@ -143,20 +137,22 @@
model_class=model.User,
link=( lambda item: dict( operation="repositories_by_user", id=item.id, webapp="community" ) ),
attach_popup=False,
- key="username" ),
- grids.CommunityRatingColumn( "Average Rating",
- key="rating" ),
- EmailAlertsColumn( "Alert",
- attach_popup=False ),
+ key="User.username" ),
+ grids.CommunityRatingColumn( "Average Rating", key="rating" ),
+ EmailAlertsColumn( "Alert", attach_popup=False ),
# Columns that are valid for filtering but are not visible.
EmailColumn( "Email",
model_class=model.User,
- key="email",
+ key="User.email",
visible=False ),
RepositoryCategoryColumn( "Category",
model_class=model.Category,
key="Category.name",
- visible=False )
+ visible=False ),
+ grids.DeletedColumn( "Deleted",
+ key="deleted",
+ visible=False,
+ filterable="advanced" )
]
columns.append( grids.MulticolFilterColumn( "Search repository name, description",
cols_to_filter=[ columns[0], columns[1] ],
@@ -168,7 +164,7 @@
condition=( lambda item: not item.deleted ),
async_compatible=False ) ]
standard_filters = []
- default_filter = {}
+ default_filter = dict( deleted="False" )
num_rows_per_page = 50
preserve_state = False
use_paging = True
--- a/templates/grid_common.mako Thu Jun 30 11:45:24 2011 -0400
+++ b/templates/grid_common.mako Thu Jun 30 12:13:20 2011 -0400
@@ -102,7 +102,7 @@
</%def>
## Print grid search/filtering UI.
-<%def name="render_grid_filters( grid )">
+<%def name="render_grid_filters( grid, render_advanced_search=True )">
## Standard search.
<div id="standard-search"><table>
@@ -124,11 +124,12 @@
## Only show advanced search if there are filterable columns.
<%
show_advanced_search_link = False
- for column in grid.columns:
- if column.filterable == "advanced":
- show_advanced_search_link = True
- break
- endif
+ if render_advanced_search:
+ for column in grid.columns:
+ if column.filterable == "advanced":
+ show_advanced_search_link = True
+ break
+ endif
%>
%if show_advanced_search_link:
<% args = { "advanced-search" : True } %>
@@ -170,7 +171,7 @@
%if column.key in cur_filter_dict and column.key in default_filter_dict and \
cur_filter_dict[column.key] != default_filter_dict[column.key]:
<script type="text/javascript">
- $('#advanced-search').css("display", "block");
+ $('#advanced-search').css("display", "none");
</script>
%endif
--- a/templates/webapps/community/category/grid.mako Thu Jun 30 11:45:24 2011 -0400
+++ b/templates/webapps/community/category/grid.mako Thu Jun 30 12:13:20 2011 -0400
@@ -25,7 +25,7 @@
%endif
</ul>
%endif
- ${render_grid_filters( repo_grid )}
+ ${render_grid_filters( repo_grid, render_advanced_search=False )}
</div></%def>
--- a/templates/webapps/community/repository/create_repository.mako Thu Jun 30 11:45:24 2011 -0400
+++ b/templates/webapps/community/repository/create_repository.mako Thu Jun 30 12:13:20 2011 -0400
@@ -31,7 +31,7 @@
<div class="form-row"><label>Detailed description:</label>
%if long_description:
- <textarea name="long_description" rows="3" cols="80">${long_description}</textarea>
+ <pre><textarea name="long_description" rows="3" cols="80">${long_description}</textarea></pre>
%else:
<textarea name="long_description" rows="3" cols="80"></textarea>
%endif
--- a/templates/webapps/community/repository/manage_repository.mako Thu Jun 30 11:45:24 2011 -0400
+++ b/templates/webapps/community/repository/manage_repository.mako Thu Jun 30 12:13:20 2011 -0400
@@ -112,7 +112,7 @@
<div class="form-row"><label>Detailed description:</label>
%if long_description:
- <textarea name="long_description" rows="3" cols="80">${long_description}</textarea>
+ <pre><textarea name="long_description" rows="3" cols="80">${long_description}</textarea></pre>
%else:
<textarea name="long_description" rows="3" cols="80"></textarea>
%endif
@@ -247,7 +247,7 @@
%><tr><td>${render_star_rating( name, review.rating, disabled=True )}</td>
- <td>${review.comment}</td>
+ <td><pre>${review.comment}</pre></td><td>${time_ago( review.update_time )}</td><td>${review.user.username}</td></tr>
--- a/templates/webapps/community/repository/rate_repository.mako Thu Jun 30 11:45:24 2011 -0400
+++ b/templates/webapps/community/repository/rate_repository.mako Thu Jun 30 12:13:20 2011 -0400
@@ -142,9 +142,13 @@
<div class="form-row"><label>Review:</label>
%if rra and rra.comment:
- <div class="form-row-input"><textarea name="comment" rows="5" cols="35">${rra.comment}</textarea></div>
+ <div class="form-row-input">
+ <pre><textarea name="comment" rows="5" cols="80">${rra.comment}</textarea></pre>
+ </div>
%else:
- <div class="form-row-input"><textarea name="comment" rows="5" cols="35"></textarea></div>
+ <div class="form-row-input">
+ <textarea name="comment" rows="5" cols="80"></textarea>
+ </div>
%endif
<div style="clear: both"></div></div>
@@ -179,7 +183,7 @@
%><tr><td>${render_star_rating( name, review.rating, disabled=True )}</td>
- <td>${review.comment}</td>
+ <td><pre>${review.comment}</pre></td><td>${time_ago( review.update_time )}</td><td>${review.user.username}</td></tr>
--- a/templates/webapps/community/repository/upload.mako Thu Jun 30 11:45:24 2011 -0400
+++ b/templates/webapps/community/repository/upload.mako Thu Jun 30 12:13:20 2011 -0400
@@ -125,7 +125,7 @@
<label>Change set commit message:</label><div class="form-row-input">
%if commit_message:
- <textarea name="commit_message" rows="3" cols="35">${commit_message}</textarea>
+ <pre><textarea name="commit_message" rows="3" cols="35">${commit_message}</textarea></pre>
%else:
<textarea name="commit_message" rows="3" cols="35"></textarea>
%endif
--- a/templates/webapps/community/repository/view_repository.mako Thu Jun 30 11:45:24 2011 -0400
+++ b/templates/webapps/community/repository/view_repository.mako Thu Jun 30 12:13:20 2011 -0400
@@ -113,7 +113,7 @@
%if repository.long_description:
<div class="form-row"><label>Detailed description:</label>
- ${repository.long_description}
+ <pre>${repository.long_description}</pre><div style="clear: both"></div></div>
%endif
@@ -206,7 +206,7 @@
%><tr><td>${render_star_rating( name, review.rating, disabled=True )}</td>
- <td>${review.comment}</td>
+ <td><pre>${review.comment}</pre></td><td>${time_ago( review.update_time )}</td><td>${review.user.username}</td></tr>
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: Another fix for migration script 65 - the previous fix for MySQL broke PostgreSQL.
by Bitbucket 30 Jun '11
by Bitbucket 30 Jun '11
30 Jun '11
1 new changeset in galaxy-central:
http://bitbucket.org/galaxy/galaxy-central/changeset/d713ce5d01d0/
changeset: d713ce5d01d0
user: natefoo
date: 2011-06-30 17:45:24
summary: Another fix for migration script 65 - the previous fix for MySQL broke PostgreSQL.
affected #: 1 file (433 bytes)
--- a/lib/galaxy/model/migrate/versions/0065_add_name_to_form_fields_and_values.py Wed Jun 29 13:27:01 2011 -0400
+++ b/lib/galaxy/model/migrate/versions/0065_add_name_to_form_fields_and_values.py Thu Jun 30 11:45:24 2011 -0400
@@ -10,6 +10,7 @@
from migrate.changeset import *
from sqlalchemy.exc import *
from galaxy.util.json import from_json_string, to_json_string
+from galaxy.model.custom_types import _sniffnfix_pg9_hex
import datetime
now = datetime.datetime.utcnow
@@ -52,14 +53,17 @@
fields = str( row[1] )
if not fields.strip():
continue
- fields_list = from_json_string( fields )
+ fields_list = from_json_string( _sniffnfix_pg9_hex( fields ) )
if len( fields_list ):
for index, field in enumerate( fields_list ):
field[ 'name' ] = 'field_%i' % index
field[ 'helptext' ] = field[ 'helptext' ].replace("'", "''").replace('"', "")
field[ 'label' ] = field[ 'label' ].replace("'", "''")
fields_json = to_json_string( fields_list )
- cmd = "UPDATE form_definition AS f SET f.fields='%s' WHERE f.id=%i" %( fields_json, form_definition_id )
+ if migrate_engine.name == 'mysql':
+ cmd = "UPDATE form_definition AS f SET f.fields='%s' WHERE f.id=%i" %( fields_json, form_definition_id )
+ else:
+ cmd = "UPDATE form_definition SET fields='%s' WHERE id=%i" %( fields_json, form_definition_id )
db_session.execute( cmd )
# replace the values list in the content field of the form_values table with a name:value dict
cmd = "SELECT form_values.id, form_values.content, form_definition.fields" \
@@ -121,15 +125,17 @@
cmd = "SELECT f.id, f.fields FROM form_definition AS f"
result = db_session.execute( cmd )
for row in result:
- og.debug("Line 124 ROW: %s" % str( row ))
form_definition_id = row[0]
fields = str( row[1] )
if not fields.strip():
continue
- fields_list = from_json_string( fields )
+ fields_list = from_json_string( _sniffnfix_pg9_hex( fields ) )
if len( fields_list ):
for index, field in enumerate( fields_list ):
if field.has_key( 'name' ):
del field[ 'name' ]
- cmd = "UPDATE form_definition AS f SET f.fields='%s' WHERE id=%i" %( to_json_string( fields_list ), form_definition_id )
+ if migrate_engine.name == 'mysql':
+ cmd = "UPDATE form_definition AS f SET f.fields='%s' WHERE f.id=%i" %( to_json_string( fields_list ), form_definition_id )
+ else:
+ cmd = "UPDATE form_definition SET fields='%s' WHERE id=%i" %( to_json_string( fields_list ), form_definition_id )
db_session.execute( cmd )
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: Fix bugs and enable workflows to be uploaded to myExperiment (www.myexperiment.org).
by Bitbucket 29 Jun '11
by Bitbucket 29 Jun '11
29 Jun '11
1 new changeset in galaxy-central:
http://bitbucket.org/galaxy/galaxy-central/changeset/963e73d40e24/
changeset: 963e73d40e24
user: jgoecks
date: 2011-06-29 19:27:01
summary: Fix bugs and enable workflows to be uploaded to myExperiment (www.myexperiment.org)
affected #: 2 files (115 bytes)
--- a/lib/galaxy/web/controllers/workflow.py Wed Jun 29 11:07:37 2011 -0400
+++ b/lib/galaxy/web/controllers/workflow.py Wed Jun 29 13:27:01 2011 -0400
@@ -107,7 +107,7 @@
stored_list_grid = StoredWorkflowListGrid()
published_list_grid = StoredWorkflowAllPublishedGrid()
- __myexp_url = "sandbox.myexperiment.org:80"
+ __myexp_url = "www.myexperiment.org:80"
@web.expose
def index( self, trans ):
@@ -972,7 +972,7 @@
# NOTE: blocks web thread.
headers = {}
if myexp_username and myexp_password:
- auth_header = base64.b64encode( '%s:%s' % ( myexp_username, myexp_password ))[:-1]
+ auth_header = base64.b64encode( '%s:%s' % ( myexp_username, myexp_password ))
headers = { "Authorization" : "Basic %s" % auth_header }
conn.request( "GET", "/workflow.xml?id=%s&elements=content" % myexp_id, headers=headers )
response = conn.getresponse()
@@ -1037,8 +1037,8 @@
request = unicode( request_raw.strip(), 'utf-8' )
# Do request and get result.
- auth_header = base64.b64encode( '%s:%s' % ( myexp_username, myexp_password ))[:-1]
- headers = { "Content-type": "text/xml", "Accept": "text/plain", "Authorization" : "Basic %s" % auth_header }
+ 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 )
# NOTE: blocks web thread.
conn.request("POST", "/workflow.xml", request, headers)
--- a/templates/workflow/export.mako Wed Jun 29 11:07:37 2011 -0400
+++ b/templates/workflow/export.mako Wed Jun 29 13:27:01 2011 -0400
@@ -22,9 +22,8 @@
##
## Renders form for exporting workflow to myExperiment.
##
- <h3>Export to myExperiment <em>sandbox</em></h3>
+ <h3>Export to myExperiment</h3>
- ##def export_to_myexp( self, trans, id, myexp_username, myexp_password ):
<div class="toolForm"><div class="toolFormTitle">Export</div><form action="${h.url_for( action='export_to_myexp', id=trans.security.encode_id( item.id ) )}"
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: Allow viewing deleted datasets from /history/view.
by Bitbucket 29 Jun '11
by Bitbucket 29 Jun '11
29 Jun '11
1 new changeset in galaxy-central:
http://bitbucket.org/galaxy/galaxy-central/changeset/ddd51b0d4556/
changeset: ddd51b0d4556
user: natefoo
date: 2011-06-29 17:07:37
summary: Allow viewing deleted datasets from /history/view.
affected #: 3 files (453 bytes)
--- a/lib/galaxy/web/controllers/history.py Tue Jun 28 16:19:30 2011 -0400
+++ b/lib/galaxy/web/controllers/history.py Wed Jun 29 11:07:37 2011 -0400
@@ -738,7 +738,7 @@
""" % ( web.url_for( id=id, confirm=True, referer=trans.request.referer ), referer_message ), use_panels=True )
@web.expose
- def view( self, trans, id=None ):
+ def view( self, trans, id=None, show_deleted=False ):
"""View a history. If a history is importable, then it is viewable by any user."""
# Get history to view.
if not id:
@@ -751,11 +751,12 @@
if not trans.user_is_admin() and not history_to_view.importable:
error( "Either you are not allowed to view this history or the owner of this history has not made it accessible." )
# View history.
- datasets = self.get_history_datasets( trans, history_to_view )
+ show_deleted = util.string_as_bool( show_deleted )
+ datasets = self.get_history_datasets( trans, history_to_view, show_deleted=show_deleted )
return trans.stream_template_mako( "history/view.mako",
history = history_to_view,
datasets = datasets,
- show_deleted = False )
+ show_deleted = show_deleted )
@web.expose
def display_by_username_and_slug( self, trans, username, slug ):
--- a/templates/history/view.mako Tue Jun 28 16:19:30 2011 -0400
+++ b/templates/history/view.mako Wed Jun 29 11:07:37 2011 -0400
@@ -84,7 +84,9 @@
<a href="${h.url_for( action='imp', id=trans.security.encode_id(history.id) )}">import and start using history</a> |
<a href="${get_history_link( history )}">${_('refresh')}</a>
%if show_deleted:
- | <a href="${h.url_for('history', show_deleted=False)}">${_('hide deleted')}</a>
+ | <a href="${h.url_for( id=trans.security.encode_id(history.id), show_deleted=False )}">${_('hide deleted')}</a>
+ %else:
+ | <a href="${h.url_for( id=trans.security.encode_id(history.id), show_deleted=True )}">${_('show deleted')}</a>
%endif
| <a href="#" class="toggle">collapse all</a></div>
--- a/templates/root/history_common.mako Tue Jun 28 16:19:30 2011 -0400
+++ b/templates/root/history_common.mako Wed Jun 29 11:07:37 2011 -0400
@@ -49,11 +49,14 @@
%if data.dataset.purged or data.purged:
This dataset has been deleted and removed from disk.
%else:
- This dataset has been deleted. Click <a href="${h.url_for( controller='dataset', action='undelete', id=data.id )}" class="historyItemUndelete" id="historyItemUndeleter-${data.id}" target="galaxy_history">here</a> to undelete
- %if trans.app.config.allow_user_dataset_purge:
- or <a href="${h.url_for( controller='dataset', action='purge', id=data.id )}" class="historyItemPurge" id="historyItemPurger-${data.id}" target="galaxy_history">here</a> to immediately remove it from disk.
- %else:
- it.
+ This dataset has been deleted.
+ %if for_editing:
+ Click <a href="${h.url_for( controller='dataset', action='undelete', id=data.id )}" class="historyItemUndelete" id="historyItemUndeleter-${data.id}" target="galaxy_history">here</a> to undelete
+ %if trans.app.config.allow_user_dataset_purge:
+ or <a href="${h.url_for( controller='dataset', action='purge', id=data.id )}" class="historyItemPurge" id="historyItemPurger-${data.id}" target="galaxy_history">here</a> to immediately remove it from disk.
+ %else:
+ it.
+ %endif
%endif
%endif
</strong></div>
@@ -151,7 +154,9 @@
An error occurred running this job: <i>${data.display_info().strip()}</i></div><div>
- <a href="${h.url_for( controller='dataset', action='errors', id=data.id )}" target="galaxy_main" title="View or report this error" class="icon-button bug tooltip"></a>
+ %if for_editing:
+ <a href="${h.url_for( controller='dataset', action='errors', id=data.id )}" target="galaxy_main" title="View or report this error" class="icon-button bug tooltip"></a>
+ %endif
%if data.has_data():
${render_download_links( data, dataset_id )}
%endif
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: 2 minor bug fixes in the tool shed, and remove unwanted debug statements in an old db migration script.
by Bitbucket 28 Jun '11
by Bitbucket 28 Jun '11
28 Jun '11
1 new changeset in galaxy-central:
http://bitbucket.org/galaxy/galaxy-central/changeset/6da32e46756b/
changeset: 6da32e46756b
user: greg
date: 2011-06-28 22:19:30
summary: 2 minor bug fixes in the tool shed, and remove unwanted debug statements in an old db migration script.
affected #: 2 files (441 bytes)
--- a/lib/galaxy/model/migrate/versions/0065_add_name_to_form_fields_and_values.py Tue Jun 28 15:45:56 2011 -0400
+++ b/lib/galaxy/model/migrate/versions/0065_add_name_to_form_fields_and_values.py Tue Jun 28 16:19:30 2011 -0400
@@ -48,24 +48,18 @@
cmd = "SELECT f.id, f.fields FROM form_definition AS f"
result = db_session.execute( cmd )
for row in result:
- log.debug("Line 51 ROW: %s" % str( row ))
form_definition_id = row[0]
- log.debug("form_definition_id: %s" % str( form_definition_id ))
fields = str( row[1] )
- log.debug("fields: %s" % str( fields ))
if not fields.strip():
continue
fields_list = from_json_string( fields )
- log.debug("fields_list: %s" % str( fields_list ))
if len( fields_list ):
for index, field in enumerate( fields_list ):
field[ 'name' ] = 'field_%i' % index
field[ 'helptext' ] = field[ 'helptext' ].replace("'", "''").replace('"', "")
field[ 'label' ] = field[ 'label' ].replace("'", "''")
fields_json = to_json_string( fields_list )
- log.debug("fields_json: %s" % str( fields_json ))
cmd = "UPDATE form_definition AS f SET f.fields='%s' WHERE f.id=%i" %( fields_json, form_definition_id )
- log.debug("cmd: %s" % str( cmd ))
db_session.execute( cmd )
# replace the values list in the content field of the form_values table with a name:value dict
cmd = "SELECT form_values.id, form_values.content, form_definition.fields" \
--- a/lib/galaxy/webapps/community/controllers/repository.py Tue Jun 28 15:45:56 2011 -0400
+++ b/lib/galaxy/webapps/community/controllers/repository.py Tue Jun 28 16:19:30 2011 -0400
@@ -261,9 +261,12 @@
category = get_category( trans, category_id )
kwd[ 'f-Category.name' ] = category.name
elif operation == "receive email alerts":
- return trans.response.send_redirect( web.url_for( controller='repository',
- action='set_email_alerts',
- **kwd ) )
+ if kwd[ 'id' ]:
+ return trans.response.send_redirect( web.url_for( controller='repository',
+ action='set_email_alerts',
+ **kwd ) )
+ else:
+ del kwd[ 'operation' ]
# Render the list view
return self.repository_list_grid( trans, **kwd )
@web.expose
@@ -708,8 +711,8 @@
repository_ids = util.listify( kwd.get( 'id', '' ) )
total_alerts_added = 0
total_alerts_removed = 0
+ flush_needed = False
for repository_id in repository_ids:
- flush_needed = False
repository = get_repository( trans, repository_id )
if repository.email_alerts:
email_alerts = from_json_string( repository.email_alerts )
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: Add new long description and number of times downloaded features for tool shed repositories. Fix a bug when rating a repository. Fix a bug when calls to email_alerts are made.
by Bitbucket 28 Jun '11
by Bitbucket 28 Jun '11
28 Jun '11
1 new changeset in galaxy-central:
http://bitbucket.org/galaxy/galaxy-central/changeset/372577e7bc6a/
changeset: 372577e7bc6a
user: greg
date: 2011-06-28 21:45:56
summary: Add new long description and number of times downloaded features for tool shed repositories. Fix a bug when rating a repository. Fix a bug when calls to email_alerts are made.
affected #: 11 files (3.4 KB)
--- a/lib/galaxy/model/migrate/versions/0065_add_name_to_form_fields_and_values.py Tue Jun 28 11:03:55 2011 -0400
+++ b/lib/galaxy/model/migrate/versions/0065_add_name_to_form_fields_and_values.py Tue Jun 28 15:45:56 2011 -0400
@@ -14,8 +14,14 @@
import datetime
now = datetime.datetime.utcnow
-import logging
+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 )
db_session = scoped_session( sessionmaker( bind=migrate_engine, autoflush=False, autocommit=True ) )
@@ -42,18 +48,24 @@
cmd = "SELECT f.id, f.fields FROM form_definition AS f"
result = db_session.execute( cmd )
for row in result:
+ log.debug("Line 51 ROW: %s" % str( row ))
form_definition_id = row[0]
+ log.debug("form_definition_id: %s" % str( form_definition_id ))
fields = str( row[1] )
+ log.debug("fields: %s" % str( fields ))
if not fields.strip():
continue
fields_list = from_json_string( fields )
+ log.debug("fields_list: %s" % str( fields_list ))
if len( fields_list ):
for index, field in enumerate( fields_list ):
field[ 'name' ] = 'field_%i' % index
field[ 'helptext' ] = field[ 'helptext' ].replace("'", "''").replace('"', "")
field[ 'label' ] = field[ 'label' ].replace("'", "''")
fields_json = to_json_string( fields_list )
+ log.debug("fields_json: %s" % str( fields_json ))
cmd = "UPDATE form_definition AS f SET f.fields='%s' WHERE f.id=%i" %( fields_json, form_definition_id )
+ log.debug("cmd: %s" % str( cmd ))
db_session.execute( cmd )
# replace the values list in the content field of the form_values table with a name:value dict
cmd = "SELECT form_values.id, form_values.content, form_definition.fields" \
@@ -115,6 +127,7 @@
cmd = "SELECT f.id, f.fields FROM form_definition AS f"
result = db_session.execute( cmd )
for row in result:
+ og.debug("Line 124 ROW: %s" % str( row ))
form_definition_id = row[0]
fields = str( row[1] )
if not fields.strip():
--- a/lib/galaxy/webapps/community/controllers/repository.py Tue Jun 28 11:03:55 2011 -0400
+++ b/lib/galaxy/webapps/community/controllers/repository.py Tue Jun 28 15:45:56 2011 -0400
@@ -282,6 +282,7 @@
status=status ) )
name = util.restore_text( params.get( 'name', '' ) )
description = util.restore_text( params.get( 'description', '' ) )
+ long_description = util.restore_text( params.get( 'long_description', '' ) )
category_ids = util.listify( params.get( 'category_id', '' ) )
selected_categories = [ trans.security.decode_id( id ) for id in category_ids ]
if params.get( 'create_repository_button', False ):
@@ -294,7 +295,10 @@
error = True
if not error:
# Add the repository record to the db
- repository = trans.app.model.Repository( name=name, description=description, user_id=trans.user.id )
+ repository = trans.app.model.Repository( name=name,
+ description=description,
+ long_description=long_description,
+ user_id=trans.user.id )
# Flush to get the id
trans.sa_session.add( repository )
trans.sa_session.flush()
@@ -333,6 +337,7 @@
return trans.fill_template( '/webapps/community/repository/create_repository.mako',
name=name,
description=description,
+ long_description=long_description,
selected_categories=selected_categories,
categories=categories,
message=message,
@@ -498,6 +503,7 @@
tip = get_repository_tip( repo )
repo_name = util.restore_text( params.get( 'repo_name', repository.name ) )
description = util.restore_text( params.get( 'description', repository.description ) )
+ long_description = util.restore_text( params.get( 'long_description', repository.long_description ) )
avg_rating, num_ratings = self.get_ave_item_rating_data( trans.sa_session, repository, webapp_model=trans.model )
display_reviews = util.string_as_bool( params.get( 'display_reviews', False ) )
alerts = params.get( 'alerts', '' )
@@ -529,6 +535,9 @@
if description != repository.description:
repository.description = description
flush_needed = True
+ if long_description != repository.long_description:
+ repository.long_description = long_description
+ flush_needed = True
if flush_needed:
trans.sa_session.add( repository )
trans.sa_session.flush()
@@ -572,6 +581,7 @@
return trans.fill_template( '/webapps/community/repository/manage_repository.mako',
repo_name=repo_name,
description=description,
+ long_description=long_description,
current_allow_push_list=current_allow_push_list,
allow_push_select_field=allow_push_select_field,
repo=repo,
@@ -666,6 +676,8 @@
message='Select a repository to rate',
status='error' ) )
repository = get_repository( trans, id )
+ repo = hg.repository( ui.ui(), repository.repo_path )
+ tip = get_repository_tip( repo )
if repository.user == trans.user:
return trans.response.send_redirect( web.url_for( controller='repository',
action='browse_repositories',
@@ -680,6 +692,7 @@
rra = self.get_user_item_rating( trans.sa_session, trans.user, repository, webapp_model=trans.model )
return trans.fill_template( '/webapps/community/repository/rate_repository.mako',
repository=repository,
+ tip=tip,
avg_rating=avg_rating,
display_reviews=display_reviews,
num_ratings=num_ratings,
@@ -691,34 +704,35 @@
# Set email alerts for selected repositories
params = util.Params( kwd )
user = trans.user
- repository_ids = util.listify( kwd.get( 'id', '' ) )
- total_alerts_added = 0
- total_alerts_removed = 0
- for repository_id in repository_ids:
- flush_needed = False
- repository = get_repository( trans, repository_id )
- if repository.email_alerts:
- email_alerts = from_json_string( repository.email_alerts )
- else:
- email_alerts = []
- if user.email in email_alerts:
- email_alerts.remove( user.email )
- repository.email_alerts = to_json_string( email_alerts )
- trans.sa_session.add( repository )
- flush_needed = True
- total_alerts_removed += 1
- else:
- email_alerts.append( user.email )
- repository.email_alerts = to_json_string( email_alerts )
- trans.sa_session.add( repository )
- flush_needed = True
- total_alerts_added += 1
- if flush_needed:
- trans.sa_session.flush()
- message = 'Total alerts added: %d, total alerts removed: %d' % ( total_alerts_added, total_alerts_removed )
- kwd[ 'message' ] = message
- kwd[ 'status' ] = 'done'
- del( kwd[ 'operation' ] )
+ if user:
+ repository_ids = util.listify( kwd.get( 'id', '' ) )
+ total_alerts_added = 0
+ total_alerts_removed = 0
+ for repository_id in repository_ids:
+ flush_needed = False
+ repository = get_repository( trans, repository_id )
+ if repository.email_alerts:
+ email_alerts = from_json_string( repository.email_alerts )
+ else:
+ email_alerts = []
+ if user.email in email_alerts:
+ email_alerts.remove( user.email )
+ repository.email_alerts = to_json_string( email_alerts )
+ trans.sa_session.add( repository )
+ flush_needed = True
+ total_alerts_removed += 1
+ else:
+ email_alerts.append( user.email )
+ repository.email_alerts = to_json_string( email_alerts )
+ trans.sa_session.add( repository )
+ flush_needed = True
+ total_alerts_added += 1
+ if flush_needed:
+ trans.sa_session.flush()
+ message = 'Total alerts added: %d, total alerts removed: %d' % ( total_alerts_added, total_alerts_removed )
+ kwd[ 'message' ] = message
+ kwd[ 'status' ] = 'done'
+ del kwd[ 'operation' ]
return trans.response.send_redirect( web.url_for( controller='repository',
action='browse_repositories',
**kwd ) )
@@ -737,6 +751,9 @@
file_type_str = 'tip.tar.bz2'
elif file_type == 'gz':
file_type_str = 'tip.tar.gz'
+ repository.times_downloaded += 1
+ trans.sa_session.add( repository )
+ trans.sa_session.flush()
download_url = '/repos/%s/%s/archive/%s' % ( repository.user.username, repository.name, file_type_str )
return trans.response.send_redirect( download_url )
@web.json
--- a/lib/galaxy/webapps/community/model/__init__.py Tue Jun 28 11:03:55 2011 -0400
+++ b/lib/galaxy/webapps/community/model/__init__.py Tue Jun 28 15:45:56 2011 -0400
@@ -89,12 +89,14 @@
MARKED_FOR_REMOVAL = 'r',
MARKED_FOR_ADDITION = 'a',
NOT_TRACKED = '?' )
- def __init__( self, name=None, description=None, user_id=None, private=False, email_alerts=None ):
+ def __init__( self, name=None, description=None, long_description=None, user_id=None, private=False, email_alerts=None, times_downloaded=0 ):
self.name = name or "Unnamed repository"
self.description = description
+ self.long_description = long_description
self.user_id = user_id
self.private = private
self.email_alerts = email_alerts
+ self.times_downloaded = times_downloaded
@property
def repo_path( self ):
# Repository locations on disk are defined in the hgweb.config file
--- a/lib/galaxy/webapps/community/model/mapping.py Tue Jun 28 11:03:55 2011 -0400
+++ b/lib/galaxy/webapps/community/model/mapping.py Tue Jun 28 15:45:56 2011 -0400
@@ -104,10 +104,12 @@
Column( "update_time", DateTime, default=now, onupdate=now ),
Column( "name", TrimmedString( 255 ), index=True ),
Column( "description" , TEXT ),
+ Column( "long_description" , TEXT ),
Column( "user_id", Integer, ForeignKey( "galaxy_user.id" ), index=True ),
Column( "private", Boolean, default=False ),
Column( "deleted", Boolean, index=True, default=False ),
- Column( "email_alerts", JSONType, nullable=True ) )
+ Column( "email_alerts", JSONType, nullable=True ),
+ Column( "times_downloaded", Integer ) )
RepositoryRatingAssociation.table = Table( "repository_rating_association", metadata,
Column( "id", Integer, primary_key=True ),
--- a/lib/galaxy/webapps/community/model/migrate/versions/0004_repository_tables.py Tue Jun 28 11:03:55 2011 -0400
+++ b/lib/galaxy/webapps/community/model/migrate/versions/0004_repository_tables.py Tue Jun 28 15:45:56 2011 -0400
@@ -30,7 +30,7 @@
Column( "create_time", DateTime, default=now ),
Column( "update_time", DateTime, default=now, onupdate=now ),
Column( "name", TrimmedString( 255 ), index=True ),
- Column( "description" , TEXT ),
+ Column( "description", TEXT ),
Column( "user_id", Integer, ForeignKey( "galaxy_user.id" ), index=True ),
Column( "private", Boolean, default=False ),
Column( "deleted", Boolean, index=True, default=False ) )
--- a/templates/webapps/community/repository/create_repository.mako Tue Jun 28 11:03:55 2011 -0400
+++ b/templates/webapps/community/repository/create_repository.mako Tue Jun 28 15:45:56 2011 -0400
@@ -24,11 +24,20 @@
<div style="clear: both"></div></div><div class="form-row">
- <label>Description:</label>
+ <label>Synopsis:</label><input name="description" type="textfield" value="${description}" size=80"/><div style="clear: both"></div></div><div class="form-row">
+ <label>Detailed description:</label>
+ %if long_description:
+ <textarea name="long_description" rows="3" cols="80">${long_description}</textarea>
+ %else:
+ <textarea name="long_description" rows="3" cols="80"></textarea>
+ %endif
+ <div style="clear: both"></div>
+ </div>
+ <div class="form-row"><label>Category</label><div class="form-row"><select name="category_id" multiple>
--- a/templates/webapps/community/repository/manage_repository.mako Tue Jun 28 11:03:55 2011 -0400
+++ b/templates/webapps/community/repository/manage_repository.mako Tue Jun 28 15:45:56 2011 -0400
@@ -101,37 +101,50 @@
</div><div class="form-row"><label>Name:</label>
- <input name="repo_name" type="textfield" value="${repo_name}" size=40"/>
+ <input name="repo_name" type="textfield" value="${repo_name}" size="40"/><div style="clear: both"></div></div><div class="form-row">
- <label>Description:</label>
- <input name="description" type="textfield" value="${description}" size=80"/>
+ <label>Synopsis:</label>
+ <input name="description" type="textfield" value="${description}" size="80"/>
+ <div style="clear: both"></div>
+ </div>
+ <div class="form-row">
+ <label>Detailed description:</label>
+ %if long_description:
+ <textarea name="long_description" rows="3" cols="80">${long_description}</textarea>
+ %else:
+ <textarea name="long_description" rows="3" cols="80"></textarea>
+ %endif
<div style="clear: both"></div></div><div class="form-row"><label>Version:</label>
- %if can_view_change_log:
- <a href="${h.url_for( controller='repository', action='view_changelog', id=trans.app.security.encode_id( repository.id ) )}">${tip}</a>
- %else:
- ${tip}
- %endif
+ %if can_view_change_log:
+ <a href="${h.url_for( controller='repository', action='view_changelog', id=trans.app.security.encode_id( repository.id ) )}">${tip}</a>
+ %else:
+ ${tip}
+ %endif
</div><div class="form-row"><label>Owner:</label>
${repository.user.username}
</div>
+ <div class="form-row">
+ <label>Times downloaded:</label>
+ ${repository.times_downloaded}
+ </div>
%if trans.user_is_admin():
<div class="form-row"><label>Location:</label>
${repository.repo_path}
</div>
+ <div class="form-row">
+ <label>Deleted:</label>
+ ${repository.deleted}
+ </div>
%endif
<div class="form-row">
- <label>Deleted:</label>
- ${repository.deleted}
- </div>
- <div class="form-row"><input type="submit" name="edit_repository_button" value="Save"/></div></form>
--- a/templates/webapps/community/repository/rate_repository.mako Tue Jun 28 11:03:55 2011 -0400
+++ b/templates/webapps/community/repository/rate_repository.mako Tue Jun 28 15:45:56 2011 -0400
@@ -103,7 +103,7 @@
</div><div class="form-row"><label>Version:</label>
- ${repository.version}
+ ${tip}
<div style="clear: both"></div></div><div class="form-row">
--- a/templates/webapps/community/repository/upload.mako Tue Jun 28 11:03:55 2011 -0400
+++ b/templates/webapps/community/repository/upload.mako Tue Jun 28 15:45:56 2011 -0400
@@ -96,29 +96,31 @@
some_file.tar contains some_contained_file.gz, the contained file will not be uncompressed.
</div></div>
- <div class="form-row">
- <%
- if remove_repo_files_not_in_tar:
- yes_selected = 'selected'
- no_selected = ''
- else:
- yes_selected = ''
- no_selected = 'selected'
- %>
- <label>Remove files in the repository (relative to the root or selected upload point) that are not in the uploaded archive?</label>
- <div class="form-row-input">
- <select name="remove_repo_files_not_in_tar">
- <option value="true" ${yes_selected}>Yes
- <option value="false" ${no_selected}>No
- </select>
+ %if not is_new:
+ <div class="form-row">
+ <%
+ if remove_repo_files_not_in_tar:
+ yes_selected = 'selected'
+ no_selected = ''
+ else:
+ yes_selected = ''
+ no_selected = 'selected'
+ %>
+ <label>Remove files in the repository (relative to the root or selected upload point) that are not in the uploaded archive?</label>
+ <div class="form-row-input">
+ <select name="remove_repo_files_not_in_tar">
+ <option value="true" ${yes_selected}>Yes
+ <option value="false" ${no_selected}>No
+ </select>
+ </div>
+ <div class="toolParamHelp" style="clear: both;">
+ This selection pertains only to uploaded tar archives, not to single file uploads. If <b>Yes</b> is selected, files
+ that exist in the repository (relative to the root or selected upload point) but that are not in the uploaded archive
+ will be removed from the repository. Otherwise, all existing repository files will remain and the uploaded archive
+ files will be added to the repository.
+ </div></div>
- <div class="toolParamHelp" style="clear: both;">
- This selection pertains only to uploaded tar archives, not to single file uploads. If <b>Yes</b> is selected, files
- that exist in the repository (relative to the root or selected upload point) but that are not in the uploaded archive
- will be removed from the repository. Otherwise, all existing repository files will remain and the uploaded archive
- files will be added to the repository.
- </div>
- </div>
+ %endif
<div class="form-row"><label>Change set commit message:</label><div class="form-row-input">
--- a/templates/webapps/community/repository/view_repository.mako Tue Jun 28 11:03:55 2011 -0400
+++ b/templates/webapps/community/repository/view_repository.mako Tue Jun 28 15:45:56 2011 -0400
@@ -107,9 +107,16 @@
%endif
</div><div class="form-row">
- <label>Description:</label>
+ <label>Synopsis:</label>
${repository.description}
</div>
+ %if repository.long_description:
+ <div class="form-row">
+ <label>Detailed description:</label>
+ ${repository.long_description}
+ <div style="clear: both"></div>
+ </div>
+ %endif
<div class="form-row"><label>Version:</label>
%if can_view_change_log:
@@ -122,16 +129,20 @@
<label>Owner:</label>
${repository.user.username}
</div>
+ <div class="form-row">
+ <label>Times downloaded:</label>
+ ${repository.times_downloaded}
+ </div>
%if trans.user_is_admin():
<div class="form-row"><label>Location:</label>
${repository.repo_path}
</div>
+ <div class="form-row">
+ <label>Deleted:</label>
+ ${repository.deleted}
+ </div>
%endif
- <div class="form-row">
- <label>Deleted:</label>
- ${repository.deleted}
- </div></div></div>
%if trans.user and trans.app.config.smtp_server:
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: Make sure the current authenticated user is the one that is associated with new committed change sets in the tool shed repositories.
by Bitbucket 28 Jun '11
by Bitbucket 28 Jun '11
28 Jun '11
1 new changeset in galaxy-central:
http://bitbucket.org/galaxy/galaxy-central/changeset/6f7bcfffe6ff/
changeset: 6f7bcfffe6ff
user: greg
date: 2011-06-28 17:03:55
summary: Make sure the current authenticated user is the one that is associated with new committed change sets in the tool shed repositories.
affected #: 2 files (78 bytes)
--- a/lib/galaxy/webapps/community/controllers/repository.py Tue Jun 28 10:24:49 2011 -0400
+++ b/lib/galaxy/webapps/community/controllers/repository.py Tue Jun 28 11:03:55 2011 -0400
@@ -424,7 +424,7 @@
if not commit_message:
commit_message = 'Deleted selected files'
# Commit the changes.
- commands.commit( repo.ui, repo, repo_dir, message=commit_message )
+ commands.commit( repo.ui, repo, repo_dir, user=trans.user.username, message=commit_message )
handle_email_alerts( trans, repository )
# Update the repository files for browsing.
update_for_browsing( repository, current_working_dir )
--- a/lib/galaxy/webapps/community/controllers/upload.py Tue Jun 28 10:24:49 2011 -0400
+++ b/lib/galaxy/webapps/community/controllers/upload.py Tue Jun 28 11:03:55 2011 -0400
@@ -82,7 +82,7 @@
# Move the uploaded file to the load_point within the repository hierarchy.
shutil.move( uploaded_file_name, full_path )
commands.add( repo.ui, repo, full_path )
- commands.commit( repo.ui, repo, full_path, message=commit_message )
+ commands.commit( repo.ui, repo, full_path, user=trans.user.username, message=commit_message )
handle_email_alerts( trans, repository )
if ok:
# Update the repository files for browsing, a by-product of doing this
@@ -162,7 +162,7 @@
for filename_in_archive in filenames_in_archive:
commands.add( repo.ui, repo, filename_in_archive )
# Commit the changes.
- commands.commit( repo.ui, repo, full_path, message=commit_message )
+ commands.commit( repo.ui, repo, full_path, user=trans.user.username, message=commit_message )
handle_email_alerts( trans, repository )
return True, '', files_to_remove
def uncompress( self, repository, uploaded_file_name, uploaded_file_filename, isgzip, isbz2 ):
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: Change many tool shed methods to use the mercurial api. Fix 2 bugs introduced when email alerts were added - unauthenticated users can once again browse categories / repositories.
by Bitbucket 28 Jun '11
by Bitbucket 28 Jun '11
28 Jun '11
1 new changeset in galaxy-central:
http://bitbucket.org/galaxy/galaxy-central/changeset/dca79f6fb1ec/
changeset: dca79f6fb1ec
user: greg
date: 2011-06-28 16:24:49
summary: Change many tool shed methods to use the mercurial api. Fix 2 bugs introduced when email alerts were added - unauthenticated users can once again browse categories / repositories.
affected #: 11 files (14.7 KB)
--- a/.hgignore Mon Jun 27 17:25:32 2011 -0400
+++ b/.hgignore Tue Jun 28 10:24:49 2011 -0400
@@ -13,6 +13,7 @@
# Database stuff
database/beaker_sessions
+database/community_files
database/compiled_templates
database/files
database/pbs
--- a/lib/galaxy/webapps/community/controllers/common.py Mon Jun 27 17:25:32 2011 -0400
+++ b/lib/galaxy/webapps/community/controllers/common.py Tue Jun 28 10:24:49 2011 -0400
@@ -1,15 +1,13 @@
-import os, tarfile, tempfile, shutil, string, socket
+import os, string, socket, logging
from time import strftime
from datetime import *
from galaxy.util.json import from_json_string, to_json_string
from galaxy.web.base.controller import *
from galaxy.webapps.community import model
from galaxy.model.orm import *
-from galaxy.web.framework.helpers import time_ago, iff, grids
-from galaxy.web.form_builder import SelectField
from galaxy.model.item_attrs import UsesItemRatings
from mercurial import hg, ui
-import logging
+
log = logging.getLogger( __name__ )
email_alert_template = """
@@ -81,42 +79,9 @@
def get_user( trans, id ):
"""Get a user from the database"""
return trans.sa_session.query( trans.model.User ).get( trans.security.decode_id( id ) )
-def hg_add( trans, current_working_dir, cloned_repo_dir ):
- # Add files to a cloned repository. If they're already tracked, this should do nothing.
- os.chdir( cloned_repo_dir )
- os.system( 'hg add > /dev/null 2>&1' )
- os.chdir( current_working_dir )
-def hg_clone( trans, repository, current_working_dir ):
- # Make a clone of a repository in a temporary location.
- repo_dir = repository.repo_path
- tmp_dir = tempfile.mkdtemp()
- tmp_archive_dir = os.path.join( tmp_dir, 'tmp_archive_dir' )
- if not os.path.exists( tmp_archive_dir ):
- os.makedirs( tmp_archive_dir )
- cmd = "hg clone %s > /dev/null 2>&1" % os.path.abspath( repo_dir )
- os.chdir( tmp_archive_dir )
- os.system( cmd )
- os.chdir( current_working_dir )
- cloned_repo_dir = os.path.join( tmp_archive_dir, 'repo_%d' % repository.id )
- return tmp_dir, cloned_repo_dir
-def hg_commit( commit_message, current_working_dir, cloned_repo_dir ):
- # Commit a change set to a cloned repository.
- if not commit_message:
- commit_message = "No commit message"
- os.chdir( cloned_repo_dir )
- os.system( "hg commit -m '%s' > /dev/null 2>&1" % commit_message )
- os.chdir( current_working_dir )
-def hg_push( trans, repository, current_working_dir, cloned_repo_dir ):
- # Push a change set from a cloned repository to a master repository.
+def handle_email_alerts( trans, repository ):
repo_dir = repository.repo_path
repo = hg.repository( ui.ui(), repo_dir )
- # We want these change sets to be associated with the owner of the repository, so we'll
- # set the HGUSER environment variable accordingly.
- os.environ[ 'HGUSER' ] = trans.user.username
- cmd = "hg push %s > /dev/null 2>&1" % os.path.abspath( repo_dir )
- os.chdir( cloned_repo_dir )
- os.system( cmd )
- os.chdir( current_working_dir )
smtp_server = trans.app.config.smtp_server
if smtp_server and repository.email_alerts:
# Send email alert to users that want them.
@@ -152,20 +117,23 @@
try:
util.send_mail( frm, to, subject, body, trans.app.config )
except Exception, e:
- log.exception( "An error occurred sending a tool shed repository update alert by email." )
-def hg_remove( file_path, current_working_dir, cloned_repo_dir ):
- # Remove a file path from a cloned repository. Since mercurial doesn't track
- # directories (only files), directories are automatically removed when they
- # become empty.
- abs_file_path = os.path.join( cloned_repo_dir, file_path )
- if os.path.exists( abs_file_path ):
- cmd = 'hg remove %s > /dev/null 2>&1' % file_path
- os.chdir( cloned_repo_dir )
- os.system( cmd )
- os.chdir( current_working_dir )
+ log.exception( "An error occurred sending a tool shed repository update alert by email." )
def update_for_browsing( repository, current_working_dir ):
# Make a copy of a repository's files for browsing.
repo_dir = repository.repo_path
os.chdir( repo_dir )
os.system( 'hg update > /dev/null 2>&1' )
os.chdir( current_working_dir )
+ """
+ # TODO: the following is useful if the repository files somehow include missing or
+ # untracked files. If this happens, we can enhance the following to clean things up.
+ # We're not currently doing any cleanup though since so far none of the repositories
+ # have problematic files for browsing.
+ # Get the tip change set.
+ repo = hg.repository( ui.ui(), repo_dir )
+ for changeset in repo.changelog:
+ ctx = repo.changectx( changeset )
+ ctx_parent = ctx.parents()[0]
+ break
+ modified, added, removed, deleted, unknown, ignored, clean = repo.status( node1=ctx_parent.node(), node2=ctx.node() )
+ """
--- a/lib/galaxy/webapps/community/controllers/repository.py Mon Jun 27 17:25:32 2011 -0400
+++ b/lib/galaxy/webapps/community/controllers/repository.py Tue Jun 28 10:24:49 2011 -0400
@@ -12,7 +12,7 @@
from galaxy.util.json import from_json_string, to_json_string
from galaxy.model.orm import *
from common import *
-from mercurial import hg, ui, patch
+from mercurial import hg, ui, patch, commands
log = logging.getLogger( __name__ )
@@ -117,7 +117,7 @@
model.User.table.c.email == column_filter ) )
class EmailAlertsColumn( grids.TextColumn ):
def get_value( self, trans, grid, repository ):
- if repository.email_alerts and trans.user.email in from_json_string( repository.email_alerts ):
+ if trans.user and repository.email_alerts and trans.user.email in from_json_string( repository.email_alerts ):
return 'yes'
return ''
# Grid definition
@@ -373,53 +373,18 @@
# allow_push = test
# name = convert_characters1
# push_ssl = False
- # Upon repository creation, only the owner can push to it ( allow_push setting ),
- # and since we support both http and https, we set push_ssl to False to override
+ # Since we support both http and https, we set push_ssl to False to override
# the default (which is True) in the mercurial api.
- hgrc_file = os.path.abspath( os.path.join( repository.repo_path, ".hg", "hgrc" ) )
- output = open( hgrc_file, 'w' )
- output.write( '[web]\n' )
- output.write( 'allow_push = %s\n' % repository.user.username )
- output.write( 'name = %s\n' % repository.name )
- output.write( 'push_ssl = false\n' )
- output.flush()
- output.close()
- def __get_allow_push( self, repository ):
- # TODO: Use the mercurial api to handle this
- hgrc_file = os.path.abspath( os.path.join( repository.repo_path, ".hg", "hgrc" ) )
- config = ConfigParser.ConfigParser()
- config.read( hgrc_file )
- for option in config.options( "web" ):
- if option == 'allow_push':
- return config.get( "web", option )
- raise Exception( "Repository %s missing allow_push entry under the [web] option in it's hgrc file." % repository.name )
- def __set_allow_push( self, repository, usernames, remove_auth='' ):
- """
- # TODO: Use the mercurial api to handle this, something like the following:
- items = repo.ui.configitems( section, untrusted=False )
- push_section = repo.ui.config( 'hgrc', 'allow_push' )
- for XXX (in name you want to add):
- repo.ui.updateconfig( section=extensions_section, name='XXX', value='YYY' )
- """
- hgrc_file = os.path.abspath( os.path.join( repository.repo_path, ".hg", "hgrc" ) )
- fh, fn = tempfile.mkstemp()
- for i, line in enumerate( open( hgrc_file ) ):
- if line.startswith( 'allow_push' ):
- value = line.split( ' = ' )[1].rstrip( '\n' )
- if remove_auth:
- current_usernames = value.split( ',' )
- new_usernames = []
- for current_username in current_usernames:
- if current_username != remove_auth:
- new_usernames.append( current_username )
- new_usernames = ','.join( new_usernames )
- line = 'allow_push = %s\n' % new_usernames
- else:
- value = '%s,%s\n' % ( value, usernames )
- line = 'allow_push = %s' % value
- os.write( fh, line )
- os.close( fh )
- shutil.move( fn, hgrc_file )
+ repo = hg.repository( ui.ui(), path=repository.repo_path )
+ fp = repo.opener( 'hgrc', 'wb' )
+ fp.write( '[paths]\n' )
+ fp.write( 'default = .\n' )
+ fp.write( 'default-push = .\n' )
+ fp.write( '[web]\n' )
+ fp.write( 'allow_push = %s\n' % repository.user.username )
+ fp.write( 'name = %s\n' % repository.name )
+ fp.write( 'push_ssl = false\n' )
+ fp.close()
@web.expose
def browse_repository( self, trans, id, **kwd ):
params = util.Params( kwd )
@@ -428,14 +393,8 @@
commit_message = util.restore_text( params.get( 'commit_message', 'Deleted selected files' ) )
repository = get_repository( trans, id )
repo = hg.repository( ui.ui(), repository.repo_path )
- # Our current support for browsing a repository requires copies of the
- # repository files to be in the repository root directory. We do the
- # following to ensure the latest files are being browsed.
current_working_dir = os.getcwd()
- repo_dir = repository.repo_path
- os.chdir( repo_dir )
- os.system( 'hg update > /dev/null 2>&1' )
- os.chdir( current_working_dir )
+ update_for_browsing( repository, current_working_dir )
return trans.fill_template( '/webapps/community/repository/browse_repository.mako',
repo=repo,
repository=repository,
@@ -449,9 +408,8 @@
status = params.get( 'status', 'done' )
commit_message = util.restore_text( params.get( 'commit_message', 'Deleted selected files' ) )
repository = get_repository( trans, id )
- _ui = ui.ui()
repo_dir = repository.repo_path
- repo = hg.repository( _ui, repo_dir )
+ repo = hg.repository( ui.ui(), repo_dir )
selected_files_to_delete = util.restore_text( params.get( 'selected_files_to_delete', '' ) )
if params.get( 'select_files_to_delete_button', False ):
if selected_files_to_delete:
@@ -459,25 +417,19 @@
current_working_dir = os.getcwd()
# Get the current repository tip.
tip = repo[ 'tip' ]
- # Clone the repository to a temporary location.
- tmp_dir, cloned_repo_dir = hg_clone( trans, repository, current_working_dir )
- # Delete the selected files from the repository.
- cloned_repo = hg.repository( _ui, cloned_repo_dir )
for selected_file in selected_files_to_delete:
- selected_file_path = selected_file.split( 'repo_%d' % repository.id )[ 1 ].lstrip( '/' )
- hg_remove( selected_file_path, current_working_dir, cloned_repo_dir )
+ repo_file = os.path.abspath( selected_file )
+ commands.remove( repo.ui, repo, repo_file )
# Commit the change set.
if not commit_message:
commit_message = 'Deleted selected files'
- hg_commit( commit_message, current_working_dir, cloned_repo_dir )
- # Push the change set from the cloned repository to the master repository.
- hg_push( trans, repository, current_working_dir, cloned_repo_dir )
- # Remove the temporary directory containing the cloned repository.
- shutil.rmtree( tmp_dir )
+ # Commit the changes.
+ commands.commit( repo.ui, repo, repo_dir, message=commit_message )
+ handle_email_alerts( trans, repository )
# Update the repository files for browsing.
update_for_browsing( repository, current_working_dir )
# Get the new repository tip.
- repo = hg.repository( _ui, repo_dir )
+ repo = hg.repository( ui.ui(), repo_dir )
if tip != repo[ 'tip' ]:
message = "The selected files were deleted from the repository."
else:
@@ -508,7 +460,7 @@
else:
email_alerts = []
user = trans.user
- if params.get( 'receive_email_alerts_button', False ):
+ if user and params.get( 'receive_email_alerts_button', False ):
flush_needed = False
if alerts_checked:
if user.email not in email_alerts:
@@ -523,7 +475,7 @@
if flush_needed:
trans.sa_session.add( repository )
trans.sa_session.flush()
- checked = alerts_checked or user.email in email_alerts
+ checked = alerts_checked or ( user and user.email in email_alerts )
alerts_check_box = CheckboxField( 'alerts', checked=checked )
return trans.fill_template( '/webapps/community/repository/view_repository.mako',
repo=repo,
@@ -592,7 +544,7 @@
user = trans.sa_session.query( trans.model.User ).get( trans.security.decode_id( user_id ) )
usernames.append( user.username )
usernames = ','.join( usernames )
- self.__set_allow_push( repository, usernames, remove_auth=remove_auth )
+ repository.set_allow_push( usernames, remove_auth=remove_auth )
elif params.get( 'receive_email_alerts_button', False ):
flush_needed = False
if alerts_checked:
@@ -610,7 +562,10 @@
trans.sa_session.flush()
if error:
status = 'error'
- current_allow_push_list = self.__get_allow_push( repository ).split( ',' )
+ if repository.allow_push:
+ current_allow_push_list = repository.allow_push.split( ',' )
+ else:
+ current_allow_push_list = []
allow_push_select_field = self.__build_allow_push_select_field( trans, current_allow_push_list )
checked = alerts_checked or user.email in email_alerts
alerts_check_box = CheckboxField( 'alerts', checked=checked )
--- a/lib/galaxy/webapps/community/controllers/upload.py Mon Jun 27 17:25:32 2011 -0400
+++ b/lib/galaxy/webapps/community/controllers/upload.py Tue Jun 28 10:24:49 2011 -0400
@@ -2,8 +2,8 @@
from galaxy.web.base.controller import *
from galaxy.model.orm import *
from galaxy.datatypes.checkers import *
-from common import get_categories, get_repository, hg_add, hg_clone, hg_commit, hg_push, hg_remove, update_for_browsing
-from mercurial import hg, ui
+from common import *
+from mercurial import hg, ui, commands
log = logging.getLogger( __name__ )
@@ -31,30 +31,10 @@
uncompress_file = util.string_as_bool( params.get( 'uncompress_file', 'true' ) )
remove_repo_files_not_in_tar = util.string_as_bool( params.get( 'remove_repo_files_not_in_tar', 'true' ) )
uploaded_file = None
- upload_point = params.get( 'upload_point', None )
- if upload_point is not None:
- # The value of upload_point will be something like: database/community_files/000/repo_12/1.bed
- if os.path.exists( upload_point ):
- if os.path.isfile( upload_point ):
- # Get the parent directory
- upload_point, not_needed = os.path.split( upload_point )
- # Now the value of uplaod_point will be something like: database/community_files/000/repo_12/
- upload_point = upload_point.split( 'repo_%d' % repository.id )[ 1 ]
- if upload_point:
- upload_point = upload_point.lstrip( '/' )
- upload_point = upload_point.rstrip( '/' )
- # Now the value of uplaod_point will be something like: /
- if upload_point == '/':
- upload_point = None
- else:
- # Must have been an error selecting something that didn't exist, so default to repository root
- # TODO: throw an exception????
- upload_point = None
- else:
- # Default to repository root
- upload_point = None
+ upload_point = self.__get_upload_point( repository, **kwd )
+ # Get the current repository tip.
+ tip = repo[ 'tip' ]
if params.get( 'upload_button', False ):
- ctx = repo.changectx( "tip" )
current_working_dir = os.getcwd()
file_data = params.get( 'file_data', '' )
if file_data == '':
@@ -66,12 +46,6 @@
uploaded_file_name = uploaded_file.name
uploaded_file_filename = file_data.filename
if uploaded_file:
- # Our current support for browsing repo contents requires a copy of the
- # repository files in the repo root directory. To eliminate these copies,
- # we update the repo, passing the "-r null" flag.
- os.chdir( repo_dir )
- os.system( 'hg update -r null > /dev/null 2>&1' )
- os.chdir( current_working_dir )
isgzip = False
isbz2 = False
if uncompress_file:
@@ -79,10 +53,9 @@
if not isgzip:
isbz2 = is_bz2( uploaded_file_name )
ok = True
- files_to_commit = []
# Determine what we have - a single file or an archive
try:
- if uncompress_file:
+ if ( isgzip or isbz2 ) and uncompress_file:
# Open for reading with transparent compression.
tar = tarfile.open( uploaded_file_name, 'r:*' )
else:
@@ -91,125 +64,52 @@
except tarfile.ReadError, e:
tar = None
istar = False
- if repository.is_new:
- if istar:
- # We have an archive ( a tarball ) in a new repository.
- ok, message = self.__check_archive( tar )
- if ok:
- tar.extractall( path=repo_dir )
- tar.close()
- uploaded_file.close()
- for root, dirs, files in os.walk( repo_dir, topdown=False ):
- # Don't visit .hg directories and don't include hgrc files in commit.
- if not root.find( '.hg' ) >= 0 and not root.find( 'hgrc' ) >= 0:
- if '.hg' in dirs:
- # Don't visit .hg directories
- dirs.remove( '.hg' )
- if 'hgrc' in files:
- # Don't include hgrc files in commit - should be impossible
- # since we don't visit .hg dirs, but just in case...
- files.remove( 'hgrc' )
- for name in files:
- relative_root = root.split( 'repo_%d' % repository.id )[ 1 ].lstrip ( '/' )
- if upload_point is not None:
- file_path = os.path.join( relative_root, upload_point, name )
- else:
- file_path = os.path.join( relative_root, name )
- # Check if the file is tracked and make it tracked if not.
- repo_contains = file_path in [ i for i in ctx.manifest() ]
- if not repo_contains:
- # Add the file to the dirstate
- repo.dirstate.add( file_path )
- files_to_commit.append( file_path )
- else:
- tar.close()
+ if istar:
+ ok, message, files_to_remove = self.upload_tar( trans,
+ repository,
+ tar,
+ uploaded_file,
+ upload_point,
+ remove_repo_files_not_in_tar,
+ commit_message )
+ else:
+ if ( isgzip or isbz2 ) and uncompress_file:
+ uploaded_file_filename = self.uncompress( repository, uploaded_file_name, uploaded_file_filename, isgzip, isbz2 )
+ if upload_point is not None:
+ full_path = os.path.abspath( os.path.join( repo_dir, upload_point, uploaded_file_filename ) )
else:
- # We have a single file in a new repository.
- if uncompress_file and ( isgzip or isbz2 ):
- uploaded_file_filename = self.uncompress( repository, uploaded_file_name, uploaded_file_filename, isgzip, isbz2 )
- if upload_point is not None:
- full_path = os.path.abspath( os.path.join( upload_point, uploaded_file_filename ) )
- file_path = os.path.join( upload_point, uploaded_file_filename )
- else:
- full_path = os.path.abspath( os.path.join( repo_dir, uploaded_file_filename ) )
- file_path = os.path.join( uploaded_file_filename )
- shutil.move( uploaded_file_name, full_path )
- repo.dirstate.add( file_path )
- files_to_commit.append( file_path )
- else:
- # We have a repository that is not new (it contains files).
- if uncompress_file and ( isgzip or isbz2 ):
- uploaded_file_filename = self.uncompress( repository, uploaded_file_name, uploaded_file_filename, isgzip, isbz2 )
- # Get the current repository tip.
- tip = repo[ 'tip' ]
- # Clone the repository to a temporary location.
- tmp_dir, cloned_repo_dir = hg_clone( trans, repository, current_working_dir )
- # Move the uploaded files to the upload_point within the cloned repository.
- files_to_remove = self.__move_to_upload_point( repository,
- upload_point,
- uploaded_file,
- uploaded_file_name,
- uploaded_file_filename,
- cloned_repo_dir,
- istar,
- tar,
- remove_repo_files_not_in_tar )
- if remove_repo_files_not_in_tar and files_to_remove:
- # Remove files in the repository (relative to the upload point)
- # that are not in the uploaded archive.
- for repo_file in files_to_remove:
- hg_remove( repo_file, current_working_dir, cloned_repo_dir )
- # Add the files in the uploaded archive to the cloned repository.
- hg_add( trans, current_working_dir, cloned_repo_dir )
- # Commit the files to the cloned repository.
- if not commit_message:
- commit_message = 'Uploaded'
- hg_commit( commit_message, current_working_dir, cloned_repo_dir )
- # Push the changes from the cloned repository to the master repository.
- hg_push( trans, repository, current_working_dir, cloned_repo_dir )
- # Remove the temporary directory containing the cloned repository.
- shutil.rmtree( tmp_dir )
- # Update the repository files for browsing.
+ full_path = os.path.abspath( os.path.join( repo_dir, uploaded_file_filename ) )
+ # Move the uploaded file to the load_point within the repository hierarchy.
+ shutil.move( uploaded_file_name, full_path )
+ commands.add( repo.ui, repo, full_path )
+ commands.commit( repo.ui, repo, full_path, message=commit_message )
+ handle_email_alerts( trans, repository )
+ if ok:
+ # Update the repository files for browsing, a by-product of doing this
+ # is eliminating unwanted files from the repository directory.
update_for_browsing( repository, current_working_dir )
# Get the new repository tip.
repo = hg.repository( ui.ui(), repo_dir )
if tip != repo[ 'tip' ]:
- if uncompress_file:
+ if ( isgzip or isbz2 ) and uncompress_file:
uncompress_str = ' uncompressed and '
else:
uncompress_str = ' '
message = "The file '%s' has been successfully%suploaded to the repository." % ( uploaded_file_filename, uncompress_str )
- if istar and remove_repo_files_not_in_tar:
- message += " %d files were removed from the repository." % len( files_to_remove )
+ if istar and remove_repo_files_not_in_tar and files_to_remove:
+ if upload_point is not None:
+ message += " %d files were removed from the repository relative to the selected upload point '%s'." % ( len( files_to_remove ), upload_point )
+ else:
+ message += " %d files were removed from the repository root." % len( files_to_remove )
else:
- message = 'No changes to repository.'
+ message = 'No changes to repository.'
trans.response.send_redirect( web.url_for( controller='repository',
action='browse_repository',
commit_message='Deleted selected files',
message=message,
id=trans.security.encode_id( repository.id ) ) )
- if ok:
- if files_to_commit:
- repo.dirstate.write()
- repo.commit( text=commit_message )
- os.chdir( repo_dir )
- os.system( 'hg update > /dev/null 2>&1' )
- os.chdir( current_working_dir )
- if uncompress_file:
- uncompress_str = ' uncompressed and '
- else:
- uncompress_str = ' '
- message = "The file '%s' has been successfully%suploaded to the repository." % ( uploaded_file_filename, uncompress_str )
- trans.response.send_redirect( web.url_for( controller='repository',
- action='browse_repository',
- commit_message='Deleted selected files',
- message=message,
- id=trans.security.encode_id( repository.id ) ) )
else:
status = 'error'
- os.chdir( repo_dir )
- os.system( 'hg update > /dev/null 2>&1' )
- os.chdir( current_working_dir )
selected_categories = [ trans.security.decode_id( id ) for id in category_ids ]
return trans.fill_template( '/webapps/community/repository/upload.mako',
repository=repository,
@@ -218,6 +118,53 @@
remove_repo_files_not_in_tar=remove_repo_files_not_in_tar,
message=message,
status=status )
+ def upload_tar( self, trans, repository, tar, uploaded_file, upload_point, remove_repo_files_not_in_tar, commit_message ):
+ # Upload a tar archive of files.
+ repo_dir = repository.repo_path
+ repo = hg.repository( ui.ui(), repo_dir )
+ files_to_remove = []
+ ok, message = self.__check_archive( tar )
+ if not ok:
+ tar.close()
+ uploaded_file.close()
+ return ok, message, files_to_remove
+ 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 )
+ filenames_in_archive = [ tarinfo_obj.name for tarinfo_obj in tar.getmembers() ]
+ filenames_in_archive = [ os.path.join( full_path, name ) for name in filenames_in_archive ]
+ # Extract the uploaded tar to the load_point within the repository hierarchy.
+ tar.extractall( path=full_path )
+ tar.close()
+ uploaded_file.close()
+ if remove_repo_files_not_in_tar and not repository.is_new:
+ # We have a repository that is not new (it contains files), so discover
+ # those files that are in the repository, but not in the uploaded archive.
+ for root, dirs, files in os.walk( full_path ):
+ if not root.find( '.hg' ) >= 0 and not root.find( 'hgrc' ) >= 0:
+ if '.hg' in dirs:
+ # Don't visit .hg directories - should be impossible since we don't
+ # allow uploaded archives that contain .hg dirs, but just in case...
+ dirs.remove( '.hg' )
+ if 'hgrc' in files:
+ # Don't include hgrc files in commit.
+ files.remove( 'hgrc' )
+ for name in files:
+ full_name = os.path.join( root, name )
+ 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.
+ commands.remove( repo.ui, repo, repo_file )
+ for filename_in_archive in filenames_in_archive:
+ commands.add( repo.ui, repo, filename_in_archive )
+ # Commit the changes.
+ commands.commit( repo.ui, repo, full_path, message=commit_message )
+ handle_email_alerts( trans, repository )
+ return True, '', files_to_remove
def uncompress( self, repository, uploaded_file_name, uploaded_file_filename, isgzip, isbz2 ):
if isgzip:
self.__handle_gzip( repository, uploaded_file_name )
@@ -259,44 +206,26 @@
os.close( fd )
bzipped_file.close()
shutil.move( uncompressed, uploaded_file_name )
- def __move_to_upload_point( self, repository, upload_point, uploaded_file, uploaded_file_name,
- uploaded_file_filename, cloned_repo_dir, istar, tar, remove_repo_files_not_in_tar ):
- files_to_remove = []
+ def __get_upload_point( self, repository, **kwd ):
+ upload_point = kwd.get( 'upload_point', None )
if upload_point is not None:
- if istar:
- full_path = os.path.abspath( os.path.join( cloned_repo_dir, upload_point ) )
+ # The value of upload_point will be something like: database/community_files/000/repo_12/1.bed
+ if os.path.exists( upload_point ):
+ if os.path.isfile( upload_point ):
+ # Get the parent directory
+ upload_point, not_needed = os.path.split( upload_point )
+ # Now the value of uplaod_point will be something like: database/community_files/000/repo_12/
+ upload_point = upload_point.split( 'repo_%d' % repository.id )[ 1 ]
+ if upload_point:
+ upload_point = upload_point.lstrip( '/' )
+ upload_point = upload_point.rstrip( '/' )
+ # Now the value of uplaod_point will be something like: /
+ if upload_point == '/':
+ upload_point = None
else:
- full_path = os.path.abspath( os.path.join( cloned_repo_dir, upload_point, uploaded_file_filename ) )
- else:
- if istar:
- full_path = os.path.abspath( os.path.join( cloned_repo_dir ) )
- else:
- full_path = os.path.abspath( os.path.join( cloned_repo_dir, uploaded_file_filename ) )
- if istar:
- if remove_repo_files_not_in_tar:
- # Discover those files that are in the repository, but not in the uploaded archive
- filenames_in_archive = [ tarinfo_obj.name for tarinfo_obj in tar.getmembers() ]
- for root, dirs, files in os.walk( full_path ):
- relative_dir = root.split( 'repo_%d' % repository.id )[1].lstrip( '/' )
- if not root.find( '.hg' ) >= 0 and not root.find( 'hgrc' ) >= 0:
- if '.hg' in dirs:
- # Don't visit .hg directories
- dirs.remove( '.hg' )
- if 'hgrc' in files:
- # Don't include hgrc files in commit - should be impossible
- # since we don't visit .hg dirs, but just in case...
- files.remove( 'hgrc' )
- for name in files:
- if name not in filenames_in_archive:
- files_to_remove.append( os.path.join( relative_dir, name ) )
- # Extract the uploaded tarball to the load_point within the cloned repository hierarchy
- tar.extractall( path=full_path )
- tar.close()
- uploaded_file.close()
- else:
- # Move the uploaded file to the load_point within the cloned repository hierarchy
- shutil.move( uploaded_file_name, full_path )
- return files_to_remove
+ # Must have been an error selecting something that didn't exist, so default to repository root
+ upload_point = None
+ return upload_point
def __check_archive( self, archive ):
for member in archive.getmembers():
# Allow regular files and directories only
--- a/lib/galaxy/webapps/community/model/__init__.py Mon Jun 27 17:25:32 2011 -0400
+++ b/lib/galaxy/webapps/community/model/__init__.py Tue Jun 28 10:24:49 2011 -0400
@@ -5,6 +5,7 @@
the relationship cardinalities are obvious (e.g. prefer Dataset to Data)
"""
import os.path, os, errno, sys, codecs, operator, tempfile, logging, tarfile, mimetypes, ConfigParser
+from galaxy import util
from galaxy.util.bunch import Bunch
from galaxy.util.hash_util import *
from galaxy.web.form_builder import *
@@ -115,163 +116,30 @@
repo = hg.repository( ui.ui(), self.repo_path )
tip_ctx = repo.changectx( repo.changelog.tip() )
return tip_ctx.rev() < 0
-class Tool( object ):
- file_path = '/tmp' # Overridden in mapping.__init__()
- states = Bunch( NEW = 'new',
- ERROR = 'error',
- DELETED = 'deleted',
- WAITING = 'waiting',
- APPROVED = 'approved',
- REJECTED = 'rejected',
- ARCHIVED = 'archived' )
- def __init__( self, guid=None, tool_id=None, name=None, description=None, user_description=None,
- category=None, version=None, user_id=None, external_filename=None, suite=False ):
- self.guid = guid
- self.tool_id = tool_id
- self.name = name or "Unnamed tool"
- self.description = description
- self.user_description = user_description
- self.version = version or "1.0.0"
- self.user_id = user_id
- self.external_filename = external_filename
- self.deleted = False
- self.__extension = None
- self.suite = suite
- def get_file_name( self ):
- if not self.external_filename:
- assert self.id is not None, "ID must be set before filename used (commit the object)"
- dir = os.path.join( self.file_path, 'tools', *directory_hash_id( self.id ) )
- # Create directory if it does not exist
- if not os.path.exists( dir ):
- os.makedirs( dir )
- # Return filename inside hashed directory
- filename = os.path.join( dir, "tool_%d.dat" % self.id )
+ @property
+ def allow_push( self ):
+ repo = hg.repository( ui.ui(), self.repo_path )
+ return repo.ui.config( 'web', 'allow_push' )
+ def set_allow_push( self, usernames, remove_auth='' ):
+ allow_push = util.listify( self.allow_push )
+ if remove_auth:
+ allow_push.remove( remove_auth )
else:
- filename = self.external_filename
- # Make filename absolute
- return os.path.abspath( filename )
- def set_file_name( self, filename ):
- if not filename:
- self.external_filename = None
- else:
- self.external_filename = filename
- file_name = property( get_file_name, set_file_name )
- def create_from_datatype( self, datatype_bunch ):
- # TODO: ensure guid is unique and generate a new one if not.
- self.guid = datatype_bunch.guid
- self.tool_id = datatype_bunch.id
- self.name = datatype_bunch.name
- self.description = datatype_bunch.description
- self.version = datatype_bunch.version
- self.user_id = datatype_bunch.user.id
- self.suite = datatype_bunch.suite
- @property
- def state( self ):
- latest_event = self.latest_event
- if latest_event:
- return latest_event.state
- return None
- @property
- def latest_event( self ):
- if self.events:
- events = [ tea.event for tea in self.events ]
- # Get the last event that occurred ( events mapper is sorted descending )
- return events[0]
- return None
- # Tool states
- @property
- def is_new( self ):
- return self.state == self.states.NEW
- @property
- def is_error( self ):
- return self.state == self.states.ERROR
- @property
- def is_deleted( self ):
- return self.state == self.states.DELETED
- @property
- def is_waiting( self ):
- return self.state == self.states.WAITING
- @property
- def is_approved( self ):
- return self.state == self.states.APPROVED
- @property
- def is_rejected( self ):
- return self.state == self.states.REJECTED
- @property
- def is_archived( self ):
- return self.state == self.states.ARCHIVED
- def get_state_message( self ):
- if self.is_suite:
- label = 'tool suite'
- else:
- label = 'tool'
- if self.is_new:
- return '<font color="red"><b><i>This is an unsubmitted version of this %s</i></b></font>' % label
- if self.is_error:
- return '<font color="red"><b><i>This %s is in an error state</i></b></font>' % label
- if self.is_deleted:
- return '<font color="red"><b><i>This is a deleted version of this %s</i></b></font>' % label
- if self.is_waiting:
- return '<font color="red"><b><i>This version of this %s is awaiting administrative approval</i></b></font>' % label
- if self.is_approved:
- return '<b><i>This is the latest approved version of this %s</i></b>' % label
- if self.is_rejected:
- return '<font color="red"><b><i>This version of this %s has been rejected by an administrator</i></b></font>' % label
- if self.is_archived:
- return '<font color="red"><b><i>This is an archived version of this %s</i></b></font>' % label
- @property
- def extension( self ):
- # if instantiated via a query, this unmapped property won't exist
- if '_Tool__extension' not in dir( self ):
- self.__extension = None
- if self.__extension is None:
- head = open( self.file_name, 'rb' ).read( 4 )
- try:
- assert head[:3] == 'BZh'
- assert int( head[-1] ) in range( 0, 10 )
- self.__extension = 'tar.bz2'
- except AssertionError:
- pass
- if self.__extension is None:
- try:
- assert head[:2] == '\037\213'
- self.__extension = 'tar.gz'
- except:
- pass
- if self.__extension is None:
- self.__extension = 'tar'
- return self.__extension
- @property
- def is_suite( self ):
- return self.suite
- @property
- def label( self ):
- if self.is_suite:
- return 'tool suite'
- else:
- return 'tool'
- @property
- def type( self ):
- # Hack
- if self.is_suite:
- return 'toolsuite'
- return 'tool'
- @property
- def download_file_name( self ):
- return '%s_%s.%s' % ( self.tool_id, self.version, self.extension )
- @property
- def mimetype( self ):
- return mimetypes.guess_type( self.download_file_name )[0]
-
-class Event( object ):
- def __init__( self, state=None, comment='' ):
- self.state = state
- self.comment = comment
-
-class ToolEventAssociation( object ):
- def __init__( self, tool=None, event=None ):
- self.tool = tool
- self.event = event
+ for username in util.listify( usernames ):
+ if username not in allow_push:
+ allow_push.append( username )
+ allow_push = '%s\n' % ','.join( allow_push )
+ repo = hg.repository( ui.ui(), path=self.repo_path )
+ # Why doesn't the following work?
+ #repo.ui.setconfig( 'web', 'allow_push', allow_push )
+ lines = repo.opener( 'hgrc', 'rb' ).readlines()
+ fp = repo.opener( 'hgrc', 'wb' )
+ for line in lines:
+ if line.startswith( 'allow_push' ):
+ fp.write( 'allow_push = %s' % allow_push )
+ else:
+ fp.write( line )
+ fp.close()
class ItemRatingAssociation( object ):
def __init__( self, id=None, user=None, item=None, rating=0, comment='' ):
@@ -284,10 +152,6 @@
""" Set association's item. """
pass
-class ToolRatingAssociation( ItemRatingAssociation ):
- def set_item( self, tool ):
- self.tool = tool
-
class RepositoryRatingAssociation( ItemRatingAssociation ):
def set_item( self, repository ):
self.repository = repository
@@ -298,11 +162,6 @@
self.description = description
self.deleted = deleted
-class ToolCategoryAssociation( object ):
- def __init__( self, tool=None, category=None ):
- self.tool = tool
- self.category = category
-
class RepositoryCategoryAssociation( object ):
def __init__( self, repository=None, category=None ):
self.repository = repository
@@ -326,12 +185,6 @@
self.user_tname = user_tname
self.value = None
self.user_value = None
-
-class ToolTagAssociation ( ItemTagAssociation ):
- pass
-
-class ToolAnnotationAssociation( object ):
- pass
## ---- Utility methods -------------------------------------------------------
def sort_by_attr( seq, attr ):
--- a/templates/webapps/community/repository/browse_repository.mako Mon Jun 27 17:25:32 2011 -0400
+++ b/templates/webapps/community/repository/browse_repository.mako Tue Jun 28 10:24:49 2011 -0400
@@ -9,7 +9,7 @@
can_push = trans.app.security_agent.can_push( trans.user, repository )
can_upload = can_push
can_browse_contents = not is_new
- can_rate = repository.user != trans.user
+ can_rate = trans.user and repository.user != trans.user
can_manage = repository.user == trans.user
can_view_change_log = not is_new
%>
--- a/templates/webapps/community/repository/manage_repository.mako Mon Jun 27 17:25:32 2011 -0400
+++ b/templates/webapps/community/repository/manage_repository.mako Tue Jun 28 10:24:49 2011 -0400
@@ -9,7 +9,7 @@
can_push = trans.app.security_agent.can_push( trans.user, repository )
can_upload = can_push
can_browse_contents = not is_new
- can_rate = not is_new and repository.user != trans.user
+ can_rate = not is_new and trans.user and repository.user != trans.user
can_view_change_log = not is_new
if can_push:
browse_label = 'Browse or delete repository files'
--- a/templates/webapps/community/repository/upload.mako Mon Jun 27 17:25:32 2011 -0400
+++ b/templates/webapps/community/repository/upload.mako Tue Jun 28 10:24:49 2011 -0400
@@ -93,7 +93,7 @@
Supported compression types are gz and bz2. If <b>Yes</b> is selected, the uploaded file will be uncompressed. However,
if the uploaded file is an archive that contains compressed files, the contained files will not be uncompressed. For
example, if the uploaded compressed file is some_file.tar.gz, some_file.tar will be uncompressed and extracted, but if
- some_file.tar contains 4.bed.gz, the contained file 4.bed.gz will not be uncompressed.
+ some_file.tar contains some_contained_file.gz, the contained file will not be uncompressed.
</div></div><div class="form-row">
@@ -105,7 +105,7 @@
yes_selected = ''
no_selected = 'selected'
%>
- <label>Remove files in the repository (relative to the upload point) that are not in the uploaded archive?</label>
+ <label>Remove files in the repository (relative to the root or selected upload point) that are not in the uploaded archive?</label><div class="form-row-input"><select name="remove_repo_files_not_in_tar"><option value="true" ${yes_selected}>Yes
@@ -114,9 +114,9 @@
</div><div class="toolParamHelp" style="clear: both;">
This selection pertains only to uploaded tar archives, not to single file uploads. If <b>Yes</b> is selected, files
- that exist in the repository (relative to the upload point) but that are not in the uploaded archive will be removed
- from the repository. Otherwise, all existing repository files will remain and the uploaded archive files will be added
- to the repository.
+ that exist in the repository (relative to the root or selected upload point) but that are not in the uploaded archive
+ will be removed from the repository. Otherwise, all existing repository files will remain and the uploaded archive
+ files will be added to the repository.
</div></div><div class="form-row">
@@ -141,8 +141,9 @@
</div><input type="hidden" id="upload_point" name="upload_point" value=""/><div class="toolParamHelp" style="clear: both;">
- Select a location within the repository to upload your files by clicking a check box next to the location. If a location
- is not selected, files will be uploaded to the repository root.
+ Select a location within the repository to upload your files by clicking a check box next to the location. The
+ selected location is considered the upload point. If a location is not selected, the upload point will be the
+ repository root.
</div><div style="clear: both"></div></div>
--- a/templates/webapps/community/repository/view_changelog.mako Mon Jun 27 17:25:32 2011 -0400
+++ b/templates/webapps/community/repository/view_changelog.mako Tue Jun 28 10:24:49 2011 -0400
@@ -9,7 +9,7 @@
can_browse_contents = not is_new
can_manage = trans.user == repository.user
can_push = trans.app.security_agent.can_push( trans.user, repository )
- can_rate = repository.user != trans.user
+ can_rate = trans.user and repository.user != trans.user
can_upload = can_push
if can_push:
browse_label = 'Browse or delete repository files'
--- a/templates/webapps/community/repository/view_changeset.mako Mon Jun 27 17:25:32 2011 -0400
+++ b/templates/webapps/community/repository/view_changeset.mako Tue Jun 28 10:24:49 2011 -0400
@@ -7,7 +7,7 @@
from galaxy.web.framework.helpers import time_ago
is_new = repository.is_new
can_browse_contents = not is_new
- can_rate = repository.user != trans.user
+ can_rate = trans.user and repository.user != trans.user
can_manage = trans.user == repository.user
can_push = trans.app.security_agent.can_push( trans.user, repository )
can_view_change_log = not is_new
--- a/templates/webapps/community/repository/view_repository.mako Mon Jun 27 17:25:32 2011 -0400
+++ b/templates/webapps/community/repository/view_repository.mako Tue Jun 28 10:24:49 2011 -0400
@@ -7,7 +7,7 @@
from galaxy.web.framework.helpers import time_ago
is_new = repository.is_new
can_push = trans.app.security_agent.can_push( trans.user, repository )
- can_rate = not is_new and repository.user != trans.user
+ can_rate = not is_new and trans.user and repository.user != trans.user
can_upload = can_push
can_browse_contents = not is_new
can_view_change_log = not is_new
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: Additional security for loading visualizations.
by Bitbucket 27 Jun '11
by Bitbucket 27 Jun '11
27 Jun '11
1 new changeset in galaxy-central:
http://bitbucket.org/galaxy/galaxy-central/changeset/e132a1398caa/
changeset: e132a1398caa
user: jgoecks
date: 2011-06-27 23:25:32
summary: Additional security for loading visualizations.
affected #: 1 file (60 bytes)
--- a/lib/galaxy/web/controllers/tracks.py Mon Jun 27 16:58:52 2011 -0400
+++ b/lib/galaxy/web/controllers/tracks.py Mon Jun 27 17:25:32 2011 -0400
@@ -229,9 +229,7 @@
"""
Display browser for the datasets listed in `dataset_ids`.
"""
- decoded_id = trans.security.decode_id( id )
- session = trans.sa_session
- vis = session.query( model.Visualization ).get( decoded_id )
+ vis = self.get_visualization( trans, id, check_ownership=False, check_accessible=True )
viz_config = self.get_visualization_config( trans, vis )
new_dataset = kwargs.get("dataset_id", None)
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