galaxy-commits
Threads by month
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- 15302 discussions
galaxy-dist commit f22b57fa537f: Filter datasets grid so that datasets in deleted histories are not shown.
by commits-noreply@bitbucket.org 07 Jun '10
by commits-noreply@bitbucket.org 07 Jun '10
07 Jun '10
# HG changeset patch -- Bitbucket.org
# Project galaxy-dist
# URL http://bitbucket.org/galaxy/galaxy-dist/overview
# User jeremy goecks <jeremy.goecks(a)emory.edu>
# Date 1275658986 14400
# Node ID f22b57fa537f9c2f3c458bf513bce2bd155239d1
# Parent f0c8355714e2b1fc1f70026485a4b24843609b2a
Filter datasets grid so that datasets in deleted histories are not shown.
--- a/lib/galaxy/web/controllers/dataset.py
+++ b/lib/galaxy/web/controllers/dataset.py
@@ -133,8 +133,9 @@ class HistoryDatasetAssociationListGrid(
num_rows_per_page = 50
def apply_query_filter( self, trans, query, **kwargs ):
# To filter HDAs by user, need to join HDA and History table and then filter histories by user. This is necessary because HDAs do not have
- # a user relation.
- return query.select_from( model.HistoryDatasetAssociation.table.join( model.History.table ) ).filter( model.History.user == trans.user )
+ # a user relation. TODO: move the base of this query to build_initial_query.
+ # Summary: filter by user, and deleted==False for both dataset and history
+ return query.select_from( model.HistoryDatasetAssociation.table.join( model.History.table ) ).filter( model.History.user == trans.user ).filter( self.model_class.deleted==False ).filter( model.History.deleted==False)
class DatasetInterface( BaseController, UsesAnnotations, UsesHistoryDatasetAssociation ):
1
0
galaxy-dist commit d285c65c66d3: BUGFIX: Removed console.logs from page and workflow editors.
by commits-noreply@bitbucket.org 07 Jun '10
by commits-noreply@bitbucket.org 07 Jun '10
07 Jun '10
# HG changeset patch -- Bitbucket.org
# Project galaxy-dist
# URL http://bitbucket.org/galaxy/galaxy-dist/overview
# User Dannon Baker <dannon.baker(a)emory.edu>
# Date 1275663873 14400
# Node ID d285c65c66d3d49f3ddd998fe2d28b60996581f1
# Parent f22b57fa537f9c2f3c458bf513bce2bd155239d1
BUGFIX: Removed console.logs from page and workflow editors.
--- a/templates/workflow/editor.mako
+++ b/templates/workflow/editor.mako
@@ -123,7 +123,7 @@
});
$(document).ajaxError( function ( e, x ) {
- console.log( e, x );
+ // console.log( e, x );
var message = x.responseText || x.statusText || "Could not connect to server";
show_modal( "Server error", message, { "Ignore error" : hide_modal } );
return false;
--- a/templates/page/editor.mako
+++ b/templates/page/editor.mako
@@ -573,7 +573,7 @@
$(function(){
## Generic error handling
$(document).ajaxError( function ( e, x ) {
- console.log( e, x );
+ // console.log( e, x );
var message = x.responseText || x.statusText || "Could not connect to server";
show_modal( "Server error", message, { "Ignore error" : hide_modal } );
return false;
1
0
galaxy-dist commit d01207f24908: Add a temporary fix to grid_common.mako, eliminating the use of the categorical-filter style for grid StateColumns so that the request will not be mangled before it reaches the server. Added several TODOs in the grid Javascript code outlining the problem.
by commits-noreply@bitbucket.org 07 Jun '10
by commits-noreply@bitbucket.org 07 Jun '10
07 Jun '10
# HG changeset patch -- Bitbucket.org
# Project galaxy-dist
# URL http://bitbucket.org/galaxy/galaxy-dist/overview
# User Greg Von Kuster <greg(a)bx.psu.edu>
# Date 1275671670 14400
# Node ID d01207f24908bc3f6d5323689f0aa46557f4d254
# Parent d285c65c66d3d49f3ddd998fe2d28b60996581f1
Add a temporary fix to grid_common.mako, eliminating the use of the categorical-filter style for grid StateColumns so that the request will not be mangled before it reaches the server. Added several TODOs in the grid Javascript code outlining the problem.
--- a/templates/grid_common.mako
+++ b/templates/grid_common.mako
@@ -1,5 +1,5 @@
<%!
- from galaxy.web.framework.helpers.grids import TextColumn, GridColumnFilter
+ from galaxy.web.framework.helpers.grids import TextColumn, StateColumn, GridColumnFilter
from galaxy.web.framework.helpers import iff
%>
@@ -15,81 +15,110 @@
<td align="left" style="padding-left: 10px">${column_label}:</td>
%endif
<td>
- %if isinstance(column, TextColumn):
- <form class="text-filter-form" column_key="${column.key}" action="${url( dict() )}" method="get" >
- ## Carry forward filtering criteria with hidden inputs.
- %for temp_column in grid.columns:
- %if temp_column.key in cur_filter_dict:
- <% value = cur_filter_dict[ temp_column.key ] %>
- %if value != "All":
+ %if isinstance(column, TextColumn):
+ <form class="text-filter-form" column_key="${column.key}" action="${url( dict() )}" method="get" >
+ ## Carry forward filtering criteria with hidden inputs.
+ %for temp_column in grid.columns:
+ %if temp_column.key in cur_filter_dict:
+ <% value = cur_filter_dict[ temp_column.key ] %>
+ %if value != "All":
+ <%
+ if isinstance( temp_column, TextColumn ):
+ value = h.to_json_string( value )
+ %>
+ <input type="hidden" id="${temp_column.key}" name="f-${temp_column.key}" value='${value}'/>
+ %endif
+ %endif
+ %endfor
+
+ ## Print current filtering criteria and links to delete.
+ <span id="${column.key}-filtering-criteria">
+ %if column.key in cur_filter_dict:
+ <% column_filter = cur_filter_dict[column.key] %>
+ %if isinstance( column_filter, basestring ):
+ %if column_filter != "All":
+ <span class='text-filter-val'>
+ ${cur_filter_dict[column.key]}
+ <% filter_all = GridColumnFilter( "", { column.key : "All" } ) %>
+ <a href="${url( filter_all.get_url_args() )}"><img src="${h.url_for('/static/images/delete_tag_icon_gray.png')}"/></a>
+ </span>
+ %endif
+ %elif isinstance( column_filter, list ):
+ %for i, filter in enumerate( column_filter ):
+ %if i > 0:
+ ,
+ %endif
+ <span class='text-filter-val'>${filter}
+ <%
+ new_filter = list( column_filter )
+ del new_filter[ i ]
+ new_column_filter = GridColumnFilter( "", { column.key : h.to_json_string( new_filter ) } )
+ %>
+ <a href="${url( new_column_filter.get_url_args() )}"><img src="${h.url_for('/static/images/delete_tag_icon_gray.png')}"/></a>
+ </span>
+ %endfor
+ %endif
+ %endif
+ </span>
+ ## Print input field for column.
+ <span>
+ <% value = iff( column.filterable == "standard", column.label.lower(), "") %>
+ <input class="no-padding-or-margin" id="input-${column.key}-filter" name="f-${column.key}" type="text" value="${value}" size="15"/>
+ <input class='submit-image' type='image' src='${h.url_for('/static/images/mag_glass.png')}' alt='Filter'/>
+ </span>
+ </form>
+ ######################
+ ## TODO: eliminate this elif condition when the categorical-filter style in grid_common.mako is fixed to that it no
+ ## longer mangles the request by eliminating parameters from it before it reaches the server. Since the categorical-filter
+ ## style is not used here, paging will not work...
+ ######################
+ %elif isinstance( column, StateColumn ):
+ kwargs: ${kwargs}<br/>
+ <span id="${column.key}-filtering-criteria">
+ %for i, filter in enumerate( column.get_accepted_filters() ):
+ <%
+ # HACK: we know that each filter will have only a single argument, so get that single argument.
+ for key, arg in filter.args.items():
+ filter_key = key
+ filter_arg = arg
+ %>
+ %if i > 0:
+ |
+ %endif
+ %if column.key in cur_filter_dict and column.key in filter.args and cur_filter_dict[column.key] == filter.args[column.key]:
+ <span class="categorical-filter ${column.key}-filter current-filter">${filter.label}</span>
+ %else:
<%
- if isinstance( temp_column, TextColumn ):
- value = h.to_json_string( value )
+ my_dict = {}
+ my_dict.update( kwargs )
+ my_dict.update( filter.get_url_args() )
%>
- <input type="hidden" id="${temp_column.key}" name="f-${temp_column.key}" value='${value}'/>
+ <a href="${url( my_dict )}" filter_key="${filter_key}" filter_val="${filter_arg}">${filter.label}</a>
%endif
- %endif
- %endfor
-
- ## Print current filtering criteria and links to delete.
+ %endfor
+ </span>
+ %else:
<span id="${column.key}-filtering-criteria">
- %if column.key in cur_filter_dict:
- <% column_filter = cur_filter_dict[column.key] %>
- %if isinstance( column_filter, basestring ):
- %if column_filter != "All":
- <span class='text-filter-val'>
- ${cur_filter_dict[column.key]}
- <% filter_all = GridColumnFilter( "", { column.key : "All" } ) %>
- <a href="${url( filter_all.get_url_args() )}"><img src="${h.url_for('/static/images/delete_tag_icon_gray.png')}"/></a>
+ %for i, filter in enumerate( column.get_accepted_filters() ):
+ <%
+ # HACK: we know that each filter will have only a single argument, so get that single argument.
+ for key, arg in filter.args.items():
+ filter_key = key
+ filter_arg = arg
+ %>
+ %if i > 0:
+ |
+ %endif
+ %if column.key in cur_filter_dict and column.key in filter.args and cur_filter_dict[column.key] == filter.args[column.key]:
+ <span class="categorical-filter ${column.key}-filter current-filter">${filter.label}</span>
+ %else:
+ <span class="categorical-filter ${column.key}-filter">
+ <a href="${url( filter.get_url_args() )}" filter_key="${filter_key}" filter_val="${filter_arg}">${filter.label}</a></span>
%endif
- %elif isinstance( column_filter, list ):
- %for i, filter in enumerate( column_filter ):
- %if i > 0:
- ,
- %endif
- <span class='text-filter-val'>${filter}
- <%
- new_filter = list( column_filter )
- del new_filter[ i ]
- new_column_filter = GridColumnFilter( "", { column.key : h.to_json_string( new_filter ) } )
- %>
- <a href="${url( new_column_filter.get_url_args() )}"><img src="${h.url_for('/static/images/delete_tag_icon_gray.png')}"/></a>
- </span>
- %endfor
-
- %endif
- %endif
+ %endfor
</span>
- ## Print input field for column.
- <span>
- <% value = iff( column.filterable == "standard", column.label.lower(), "") %>
- <input class="no-padding-or-margin" id="input-${column.key}-filter" name="f-${column.key}" type="text" value="${value}" size="15"/>
- <input class='submit-image' type='image' src='${h.url_for('/static/images/mag_glass.png')}' alt='Filter'/>
- </span>
- </form>
- %else:
- <span id="${column.key}-filtering-criteria">
- %for i, filter in enumerate( column.get_accepted_filters() ):
- <%
- # HACK: we know that each filter will have only a single argument, so get that single argument.
- for key, arg in filter.args.items():
- filter_key = key
- filter_arg = arg
- %>
- %if i > 0:
- |
- %endif
- %if column.key in cur_filter_dict and column.key in filter.args and cur_filter_dict[column.key] == filter.args[column.key]:
- <span class="categorical-filter ${column.key}-filter current-filter">${filter.label}</span>
- %else:
- <span class="categorical-filter ${column.key}-filter">
- <a href="${url( filter.get_url_args() )}" filter_key="${filter_key}" filter_val="${filter_arg}">${filter.label}</a>
- </span>
- %endif
- %endfor
- </span>
- %endif
+ %endif
</td></tr></%def>
--- a/templates/grid_base.mako
+++ b/templates/grid_base.mako
@@ -161,6 +161,16 @@
});
// Initialize categorical filters.
+ // ####################
+ // TODO: This style is used in grid_common.mako to wrap the links created for certain GridColumn
+ // subclasses ( e.g., DeletedColumn, StateColumn, etc ) where the link labels are generated in the
+ // class's get_accepted_filters() method. The problem is that when the link is clicked, this style
+ // will eliminate all request parameters except for those that are included in the cur_filter_dict
+ // dictionary that is used to build the url_args variable in this template. This process needs to
+ // be corrected so that the only changes made to the request are updating the values of parameters
+ // in the request with the new values obtained from cur_filter_dict, leaving all remaining request
+ // parameters alone. There is another related TODO in the set_categorical_filter() function below.
+ // ####################
$('.categorical-filter > a').each( function() {
$(this).click( function() {
var filter_key = $(this).attr('filter_key');
@@ -397,6 +407,11 @@
}
// Set new value for categorical filter.
+ // ####################
+ // TODO: this function mangles the initial request by eliminating many of the request parameters
+ // before calling update_grid(). This needs to be fixed - see the TODO in the categorical-filter
+ // style above.
+ // ####################
function set_categorical_filter(name, new_value) {
// Update filter hyperlinks to reflect new filter value.
var category_filter = categorical_filters[name];
@@ -423,7 +438,7 @@
$(this).append(t);
}
});
-
+
// Update grid.
url_args["f-" + name] = new_value;
go_page_one();
@@ -498,7 +513,7 @@
var href_parms = href_parms_str.split("&");
var operation = null;
var id = -1;
- var webapp = 'galaxy'
+ var webapp = 'galaxy';
for (var index = 0; index < href_parms.length; index++) {
if (href_parms[index].indexOf('operation') != -1) {
// Found operation parm; get operation value.
1
0
galaxy-dist commit f0c8355714e2: Update cufflinks wrapper and tests. Expression output files are now tabular and all outputs are evaluated in functional test.
by commits-noreply@bitbucket.org 07 Jun '10
by commits-noreply@bitbucket.org 07 Jun '10
07 Jun '10
# HG changeset patch -- Bitbucket.org
# Project galaxy-dist
# URL http://bitbucket.org/galaxy/galaxy-dist/overview
# User jeremy goecks <jeremy.goecks(a)emory.edu>
# Date 1275657576 14400
# Node ID f0c8355714e2b1fc1f70026485a4b24843609b2a
# Parent e924fd0ed0174300161577c30936c649d2cd2d08
Update cufflinks wrapper and tests. Expression output files are now tabular and all outputs are evaluated in functional test.
--- a/tools/ngs_rna/cufflinks_wrapper.xml
+++ b/tools/ngs_rna/cufflinks_wrapper.xml
@@ -50,12 +50,15 @@
</inputs><outputs>
- <data format="expr" name="genes_expression" label="${tool.name} on ${on_string}: gene expression"/>
- <data format="expr" name="transcripts_expression" label="${tool.name} on ${on_string}: transcript expression"/>
+ <data format="tabular" name="genes_expression" label="${tool.name} on ${on_string}: gene expression"/>
+ <data format="tabular" name="transcripts_expression" label="${tool.name} on ${on_string}: transcript expression"/><data format="gtf" name="assembled_isoforms" label="${tool.name} on ${on_string}: assembled transcripts"/></outputs><tests>
+ <!--
+ Simple test that uses test data included with cufflinks.
+ --><test><param name="sPaired" value="single"/><param name="input" value="cufflinks_in.sam"/>
@@ -65,12 +68,9 @@
<param name="pre_mrna_fraction" value="0.05"/><param name="min_map_quality" value="0"/><param name="use_ref" value="No"/>
- <output name="assembled_isoforms" file="cufflinks_out1.gtf"/>
- <!--
- Can't test these right now b/c .expr files aren't recognized. Need to add them?
<output name="genes_expression" format="tabular" file="cufflinks_out3.expr"/><output name="transcripts_expression" format="tabular" file="cufflinks_out2.expr"/>
- -->
+ <output name="assembled_isoforms" file="cufflinks_out1.gtf"/></test></tests>
1
0
galaxy-dist commit e924fd0ed017: trackster: Implemented drag-zooming by letting you drag a region in the top label track (where chrom position is shown). Refactored to not use zoom levels anymore.
by commits-noreply@bitbucket.org 07 Jun '10
by commits-noreply@bitbucket.org 07 Jun '10
07 Jun '10
# HG changeset patch -- Bitbucket.org
# Project galaxy-dist
# URL http://bitbucket.org/galaxy/galaxy-dist/overview
# User Kanwei Li <kanwei(a)gmail.com>
# Date 1275602338 14400
# Node ID e924fd0ed0174300161577c30936c649d2cd2d08
# Parent d25af565d085e19dccb8f20c857e633397e5da08
trackster: Implemented drag-zooming by letting you drag a region in the top label track (where chrom position is shown). Refactored to not use zoom levels anymore.
--- a/static/welcome.html
+++ b/static/welcome.html
@@ -7,7 +7,7 @@
</head><body><div class="document">
- <div class="warningmessagelarge">
+ <div class="donemessagelarge"><strong>Hello world! It's running...</strong><hr>
To customize this page edit <code>static/welcome.html</code>
--- a/static/scripts/packed/galaxy.base.js
+++ b/static/scripts/packed/galaxy.base.js
@@ -1,1 +1,1 @@
-$(document).ready(function(){replace_big_select_inputs()});$.fn.makeAbsolute=function(a){return this.each(function(){var b=$(this);var c=b.position();b.css({position:"absolute",marginLeft:0,marginTop:0,top:c.top,left:c.left,right:$(window).width()-(c.left+b.width())});if(a){b.remove().appendTo("body")}})};function ensure_popup_helper(){if($("#popup-helper").length===0){$("<div id='popup-helper'/>").css({background:"white",opacity:0,zIndex:15000,position:"absolute",top:0,left:0,width:"100%",height:"100%"}).appendTo("body").hide()}}function attach_popupmenu(b,d){var a=function(){d.unbind().hide();$("#popup-helper").unbind("click.popupmenu").hide()};var c=function(g){$("#popup-helper").bind("click.popupmenu",a).show();d.click(a).css({left:0,top:-1000}).show();var f=g.pageX-d.width()/2;f=Math.min(f,$(document).scrollLeft()+$(window).width()-$(d).width()-20);f=Math.max(f,$(document).scrollLeft()+20);d.css({top:g.pageY-5,left:f});return false};$(b).click(c)}function make_popupmenu
(c,b){ensure_popup_helper();var a=$("<ul id='"+c.attr("id")+"-menu'></ul>");$.each(b,function(f,e){if(e){$("<li/>").html(f).click(e).appendTo(a)}else{$("<li class='head'/>").html(f).appendTo(a)}});var d=$("<div class='popmenu-wrapper'>");d.append(a).append("<div class='overlay-border'>").css("position","absolute").appendTo("body").hide();attach_popupmenu(c,d)}function make_popup_menus(){jQuery("div[popupmenu]").each(function(){var c={};$(this).find("a").each(function(){var b=$(this).attr("confirm"),d=$(this).attr("href"),e=$(this).attr("target");c[$(this).text()]=function(){if(!b||confirm(b)){var g=window;if(e=="_parent"){g=window.parent}else{if(e=="_top"){g=window.top}}g.location=d}}});var a=$("#"+$(this).attr("popupmenu"));make_popupmenu(a,c);$(this).remove();a.addClass("popup").show()})}function array_length(b){if(b.length){return b.length}var c=0;for(var a in b){c++}return c}function naturalSort(i,g){var n=/(-?[0-9\.]+)/g,j=i.toString().toLowerCase()||"",f=g.toString().t
oLowerCase()||"",k=String.fromCharCode(0),l=j.replace(n,k+"$1"+k).split(k),e=f.replace(n,k+"$1"+k).split(k),d=(new Date(j)).getTime(),m=d?(new Date(f)).getTime():null;if(m){if(d<m){return -1}else{if(d>m){return 1}}}for(var h=0,c=Math.max(l.length,e.length);h<c;h++){oFxNcL=parseFloat(l[h])||l[h];oFyNcL=parseFloat(e[h])||e[h];if(oFxNcL<oFyNcL){return -1}else{if(oFxNcL>oFyNcL){return 1}}}return 0}function replace_big_select_inputs(a){if(typeof jQuery().autocomplete=="undefined"){return}if(a===undefined){a=20}$("select").each(function(){var d=$(this);if(d.find("option").length<a){return}if(d.attr("multiple")==true){return}var j=d.attr("value");var b=$("<input type='text' class='text-and-autocomplete-select'></input>");b.attr("size",40);b.attr("name",d.attr("name"));b.attr("id",d.attr("id"));b.click(function(){var k=$(this).attr("value");$(this).attr("value","Loading...");$(this).showAllInCache();$(this).attr("value",k);$(this).select()});var e=[];var g={};d.children("option").ea
ch(function(){var l=$(this).text();var k=$(this).attr("value");e.push(l);g[l]=k;g[k]=k;if(k==j){b.attr("value",l)}});if(j==""||j=="?"){b.attr("value","Click to Search or Select")}if(d.attr("name")=="dbkey"){e=e.sort(naturalSort)}var f={selectFirst:false,autoFill:false,mustMatch:false,matchContains:true,max:1000,minChars:0,hideForLessThanMinChars:false};b.autocomplete(e,f);d.replaceWith(b);var i=function(){var l=b.attr("value");var k=g[l];if(k!==null&&k!==undefined){b.attr("value",k)}else{if(j!=""){b.attr("value",j)}else{b.attr("value","?")}}};b.parents("form").submit(function(){i()});$(document).bind("convert_dbkeys",function(){i()});if(d.attr("refresh_on_change")=="true"){var c=d.attr("refresh_on_change_values");if(c!==undefined){c=c.split(",")}var h=function(){var m=b.attr("value");var l=g[m];if(l!==null&&l!==undefined){refresh=false;if(c!==undefined){for(var k=0;k<c.length;k++){if(l==c[k]){refresh=true;break}}}else{refresh=true}if(refresh){b.attr("value",l);b.parents("for
m").submit()}}};b.bind("result",h);b.keyup(function(k){h()})}})}function async_save_text(d,f,e,a,c,h,i,g,b){if(c===undefined){c=30}if(i===undefined){i=4}$("#"+d).live("click",function(){if($("#renaming-active").length>0){return}var l=$("#"+f),k=l.text(),j;if(h){j=$("<textarea></textarea>").attr({rows:i,cols:c}).text(k)}else{j=$("<input type='text'></input>").attr({value:k,size:c})}j.attr("id","renaming-active");j.blur(function(){$(this).remove();l.show();if(b){b(j)}});j.keyup(function(n){if(n.keyCode===27){$(this).trigger("blur")}else{if(n.keyCode===13){var m={};m[a]=$(this).val();$(this).trigger("blur");$.ajax({url:e,data:m,error:function(){alert("Text editing for elt "+f+" failed")},success:function(o){l.text(o);if(b){b(j)}}})}}});if(g){g(j)}l.hide();j.insertAfter(l);j.focus();j.select();return})}function init_history_items(d,a,c){var b=function(){try{var e=$.jStore.store("history_expand_state");if(e){for(var g in e){$("#"+g+" div.historyItemBody").show()}}}catch(f){$.jSto
re.remove("history_expand_state")}if($.browser.mozilla){$("div.historyItemBody").each(function(){if(!$(this).is(":visible")){$(this).find("pre.peek").css("overflow","hidden")}})}d.each(function(){var j=this.id;var h=$(this).children("div.historyItemBody");var i=h.find("pre.peek");$(this).find(".historyItemTitleBar > .historyItemTitle").wrap("<a href='javascript:void(0);'></a>").click(function(){if(h.is(":visible")){if($.browser.mozilla){i.css("overflow","hidden")}h.slideUp("fast");if(!c){var k=$.jStore.store("history_expand_state");if(k){delete k[j];$.jStore.store("history_expand_state",k)}}}else{h.slideDown("fast",function(){if($.browser.mozilla){i.css("overflow","auto")}});if(!c){var k=$.jStore.store("history_expand_state");if(k===undefined){k={}}k[j]=true;$.jStore.store("history_expand_state",k)}}return false})});$("#top-links > a.toggle").click(function(){var h=$.jStore.store("history_expand_state");if(h===undefined){h={}}$("div.historyItemBody:visible").each(function(){
if($.browser.mozilla){$(this).find("pre.peek").css("overflow","hidden")}$(this).slideUp("fast");if(h){delete h[$(this).parent().attr("id")]}});$.jStore.store("history_expand_state",h)}).show()};if(a){b()}else{$.jStore.init("galaxy");$.jStore.engineReady(function(){b()})}}$(document).ready(function(){$("a[confirm]").click(function(){return confirm($(this).attr("confirm"))});if($.fn.tipsy){$(".tooltip").tipsy({gravity:"s"})}make_popup_menus()});
+$(document).ready(function(){replace_big_select_inputs()});$.fn.makeAbsolute=function(a){return this.each(function(){var b=$(this);var c=b.position();b.css({position:"absolute",marginLeft:0,marginTop:0,top:c.top,left:c.left,right:$(window).width()-(c.left+b.width())});if(a){b.remove().appendTo("body")}})};function ensure_popup_helper(){if($("#popup-helper").length===0){$("<div id='popup-helper'/>").css({background:"white",opacity:0,zIndex:15000,position:"absolute",top:0,left:0,width:"100%",height:"100%"}).appendTo("body").hide()}}function attach_popupmenu(b,d){var a=function(){d.unbind().hide();$("#popup-helper").unbind("click.popupmenu").hide()};var c=function(g){$("#popup-helper").bind("click.popupmenu",a).show();d.click(a).css({left:0,top:-1000}).show();var f=g.pageX-d.width()/2;f=Math.min(f,$(document).scrollLeft()+$(window).width()-$(d).width()-20);f=Math.max(f,$(document).scrollLeft()+20);d.css({top:g.pageY-5,left:f});return false};$(b).click(c)}function make_popupmenu
(c,b){ensure_popup_helper();var a=$("<ul id='"+c.attr("id")+"-menu'></ul>");$.each(b,function(f,e){if(e){$("<li/>").html(f).click(e).appendTo(a)}else{$("<li class='head'/>").html(f).appendTo(a)}});var d=$("<div class='popmenu-wrapper'>");d.append(a).append("<div class='overlay-border'>").css("position","absolute").appendTo("body").hide();attach_popupmenu(c,d)}function make_popup_menus(){jQuery("div[popupmenu]").each(function(){var c={};$(this).find("a").each(function(){var b=$(this).attr("confirm"),d=$(this).attr("href"),e=$(this).attr("target");c[$(this).text()]=function(){if(!b||confirm(b)){var g=window;if(e=="_parent"){g=window.parent}else{if(e=="_top"){g=window.top}}g.location=d}}});var a=$("#"+$(this).attr("popupmenu"));make_popupmenu(a,c);$(this).remove();a.addClass("popup").show()})}function array_length(b){if(b.length){return b.length}var c=0;for(var a in b){c++}return c}function naturalSort(i,g){var n=/(-?[0-9\.]+)/g,j=i.toString().toLowerCase()||"",f=g.toString().t
oLowerCase()||"",k=String.fromCharCode(0),l=j.replace(n,k+"$1"+k).split(k),e=f.replace(n,k+"$1"+k).split(k),d=(new Date(j)).getTime(),m=d?(new Date(f)).getTime():null;if(m){if(d<m){return -1}else{if(d>m){return 1}}}for(var h=0,c=Math.max(l.length,e.length);h<c;h++){oFxNcL=parseFloat(l[h])||l[h];oFyNcL=parseFloat(e[h])||e[h];if(oFxNcL<oFyNcL){return -1}else{if(oFxNcL>oFyNcL){return 1}}}return 0}function replace_big_select_inputs(a){if(typeof jQuery().autocomplete=="undefined"){return}if(a===undefined){a=20}$("select").each(function(){var d=$(this);if(d.find("option").length<a){return}if(d.attr("multiple")==true){return}var j=d.attr("value");var b=$("<input type='text' class='text-and-autocomplete-select'></input>");b.attr("size",40);b.attr("name",d.attr("name"));b.attr("id",d.attr("id"));b.click(function(){var k=$(this).attr("value");$(this).attr("value","Loading...");$(this).showAllInCache();$(this).attr("value",k);$(this).select()});var e=[];var g={};d.children("option").ea
ch(function(){var l=$(this).text();var k=$(this).attr("value");e.push(l);g[l]=k;g[k]=k;if(k==j){b.attr("value",l)}});if(j==""||j=="?"){b.attr("value","Click to Search or Select")}if(d.attr("name")=="dbkey"){e=e.sort(naturalSort)}var f={selectFirst:false,autoFill:false,mustMatch:false,matchContains:true,max:1000,minChars:0,hideForLessThanMinChars:false};b.autocomplete(e,f);d.replaceWith(b);var i=function(){var l=b.attr("value");var k=g[l];if(k!==null&&k!==undefined){b.attr("value",k)}else{if(j!=""){b.attr("value",j)}else{b.attr("value","?")}}};b.parents("form").submit(function(){i()});$(document).bind("convert_dbkeys",function(){i()});if(d.attr("refresh_on_change")=="true"){var c=d.attr("refresh_on_change_values");if(c!==undefined){c=c.split(",")}var h=function(){var m=b.attr("value");var l=g[m];if(l!==null&&l!==undefined){refresh=false;if(c!==undefined){for(var k=0;k<c.length;k++){if(l==c[k]){refresh=true;break}}}else{refresh=true}if(refresh){b.attr("value",l);b.parents("for
m").submit()}}};b.bind("result",h);b.keyup(function(k){h()})}})}function async_save_text(d,f,e,a,c,h,i,g,b){if(c===undefined){c=30}if(i===undefined){i=4}$("#"+d).live("click",function(){if($("#renaming-active").length>0){return}var l=$("#"+f),k=l.text(),j;if(h){j=$("<textarea></textarea>").attr({rows:i,cols:c}).text(k)}else{j=$("<input type='text'></input>").attr({value:k,size:c})}j.attr("id","renaming-active");j.blur(function(){$(this).remove();l.show();if(b){b(j)}});j.keyup(function(n){if(n.keyCode===27){$(this).trigger("blur")}else{if(n.keyCode===13){var m={};m[a]=$(this).val();$(this).trigger("blur");$.ajax({url:e,data:m,error:function(){alert("Text editing for elt "+f+" failed")},success:function(o){l.text(o);if(b){b(j)}}})}}});if(g){g(j)}l.hide();j.insertAfter(l);j.focus();j.select();return})}function init_history_items(d,a,c){var b=function(){try{var e=$.jStore.store("history_expand_state");if(e){for(var g in e){$("#"+g+" div.historyItemBody").show()}}}catch(f){$.jSto
re.remove("history_expand_state")}if($.browser.mozilla){$("div.historyItemBody").each(function(){if(!$(this).is(":visible")){$(this).find("pre.peek").css("overflow","hidden")}})}d.each(function(){var j=this.id;var h=$(this).children("div.historyItemBody");var i=h.find("pre.peek");$(this).find(".historyItemTitleBar > .historyItemTitle").wrap("<a href='javascript:void(0);'></a>").click(function(){if(h.is(":visible")){if($.browser.mozilla){i.css("overflow","hidden")}h.slideUp("fast");if(!c){var k=$.jStore.store("history_expand_state");if(k){delete k[j];$.jStore.store("history_expand_state",k)}}}else{h.slideDown("fast",function(){if($.browser.mozilla){i.css("overflow","auto")}});if(!c){var k=$.jStore.store("history_expand_state");if(k===undefined){k={}}k[j]=true;$.jStore.store("history_expand_state",k)}}return false})});$("#top-links > a.toggle").click(function(){var h=$.jStore.store("history_expand_state");if(h===undefined){h={}}$("div.historyItemBody:visible").each(function(){
if($.browser.mozilla){$(this).find("pre.peek").css("overflow","hidden")}$(this).slideUp("fast");if(h){delete h[$(this).parent().attr("id")]}});$.jStore.store("history_expand_state",h)}).show()};if(a){b()}else{$.jStore.init("galaxy");$.jStore.engineReady(function(){b()})}}function commatize(b){b+="";var a=/(\d+)(\d{3})/;while(a.test(b)){b=b.replace(a,"$1,$2")}return b}$(document).ready(function(){$("a[confirm]").click(function(){return confirm($(this).attr("confirm"))});if($.fn.tipsy){$(".tooltip").tipsy({gravity:"s"})}make_popup_menus()});
--- a/static/scripts/packed/trackster.js
+++ b/static/scripts/packed/trackster.js
@@ -1,1 +1,1 @@
-var DEBUG=false;var DENSITY=200,FEATURE_LEVELS=10,DATA_ERROR="There was an error in indexing this dataset. ",DATA_NOCONVERTER="A converter for this dataset is not installed. Please check your datatypes_conf.xml file.",DATA_NONE="No data for this chrom/contig.",DATA_PENDING="Currently indexing... please wait",DATA_LOADING="Loading data...",CACHED_TILES_FEATURE=10,CACHED_TILES_LINE=30,CACHED_DATA=5,CONTEXT=$("<canvas></canvas>").get(0).getContext("2d"),RIGHT_STRAND,LEFT_STRAND;var right_img=new Image();right_img.src="/static/images/visualization/strand_right.png";right_img.onload=function(){RIGHT_STRAND=CONTEXT.createPattern(right_img,"repeat")};var left_img=new Image();left_img.src="/static/images/visualization/strand_left.png";left_img.onload=function(){LEFT_STRAND=CONTEXT.createPattern(left_img,"repeat")};var right_img_inv=new Image();right_img_inv.src="/static/images/visualization/strand_right_inv.png";right_img_inv.onload=function(){RIGHT_STRAND_INV=CONTEXT.createPattern(
right_img_inv,"repeat")};var left_img_inv=new Image();left_img_inv.src="/static/images/visualization/strand_left_inv.png";left_img_inv.onload=function(){LEFT_STRAND_INV=CONTEXT.createPattern(left_img_inv,"repeat")};function commatize(b){b+="";var a=/(\d+)(\d{3})/;while(a.test(b)){b=b.replace(a,"$1,$2")}return b}var Cache=function(a){this.num_elements=a;this.clear()};$.extend(Cache.prototype,{get:function(b){var a=this.key_ary.indexOf(b);if(a!=-1){this.key_ary.splice(a,1);this.key_ary.push(b)}return this.obj_cache[b]},set:function(b,c){if(!this.obj_cache[b]){if(this.key_ary.length>=this.num_elements){var a=this.key_ary.shift();delete this.obj_cache[a]}this.key_ary.push(b)}this.obj_cache[b]=c;return c},clear:function(){this.obj_cache={};this.key_ary=[]}});var View=function(b,d,c,a){this.vis_id=c;this.dbkey=a;this.title=d;this.chrom=b;this.tracks=[];this.label_tracks=[];this.max_low=0;this.max_high=0;this.center=(this.max_high-this.max_low)/2;this.zoom_factor=3;this.zoom_level=
0;this.track_id_counter=0;this.has_changes=false};$.extend(View.prototype,{add_track:function(a){a.view=this;a.track_id=this.track_id_counter;this.tracks.push(a);if(a.init){a.init()}a.container_div.attr("id","track_"+a.track_id);this.track_id_counter+=1},add_label_track:function(a){a.view=this;this.label_tracks.push(a)},remove_track:function(a){this.has_changes=true;a.container_div.fadeOut("slow",function(){$(this).remove()});delete this.tracks[this.tracks.indexOf(a)]},update_options:function(){this.has_changes=true;var b=$("ul#sortable-ul").sortable("toArray");for(var c in b){var e=b[c].split("_li")[0].split("track_")[1];$("#viewport").append($("#track_"+e))}for(var d in view.tracks){var a=view.tracks[d];if(a&&a.update_options){a.update_options(d)}}},reset:function(){this.low=this.max_low;this.high=this.max_high;this.center=this.center=(this.max_high-this.max_low)/2;this.zoom_level=0;$(".yaxislabel").remove()},redraw:function(f){this.span=this.max_high-this.max_low;var d=th
is.span/Math.pow(this.zoom_factor,this.zoom_level),b=this.center-(d/2),e=b+d;if(b<0){b=0;e=b+d}else{if(e>this.max_high){e=this.max_high;b=e-d}}this.low=Math.floor(b);this.high=Math.ceil(e);this.center=Math.round(this.low+(this.high-this.low)/2);this.resolution=Math.pow(10,Math.ceil(Math.log((this.high-this.low)/200)/Math.LN10));this.zoom_res=Math.pow(FEATURE_LEVELS,Math.max(0,Math.ceil(Math.log(this.resolution,FEATURE_LEVELS)/Math.log(FEATURE_LEVELS))));$("#overview-box").css({left:(this.low/this.span)*$("#overview-viewport").width(),width:Math.max(12,((this.high-this.low)/this.span)*$("#overview-viewport").width())}).show();$("#low").val(commatize(this.low));$("#high").val(commatize(this.high));if(!f){for(var c=0,a=this.tracks.length;c<a;c++){if(this.tracks[c]&&this.tracks[c].enabled){this.tracks[c].draw()}}for(var c=0,a=this.label_tracks.length;c<a;c++){this.label_tracks[c].draw()}}},zoom_in:function(a,b){if(this.max_high===0||this.high-this.low<30){return}if(a){this.cente
r=a/b.width()*(this.high-this.low)+this.low}this.zoom_level+=1;this.redraw()},zoom_out:function(){if(this.max_high===0){return}if(this.zoom_level<=0){this.zoom_level=0;return}this.zoom_level-=1;this.redraw()}});var Track=function(a,b){this.name=a;this.parent_element=b;this.init_global()};$.extend(Track.prototype,{init_global:function(){this.header_div=$("<div class='track-header'>").text(this.name);this.content_div=$("<div class='track-content'>");this.container_div=$("<div />").addClass("track").append(this.header_div).append(this.content_div);this.parent_element.append(this.container_div)},init_each:function(c,b){var a=this;a.enabled=false;a.data_queue={};a.tile_cache.clear();a.data_cache.clear();a.content_div.css("height","30px");if(!a.content_div.text()){a.content_div.text(DATA_LOADING)}a.container_div.removeClass("nodata error pending");if(a.view.chrom){$.getJSON(data_url,c,function(d){if(!d||d==="error"||d.kind==="error"){a.container_div.addClass("error");a.content_div
.text(DATA_ERROR);if(d.message){var f=a.view.tracks.indexOf(a);var e=$("<a href='javascript:void(0);'></a>").attr("id",f+"_error");e.text("Click to view error");$("#"+f+"_error").live("click",function(){show_modal("Trackster Error","<pre>"+d.message+"</pre>",{Close:hide_modal})});a.content_div.append(e)}}else{if(d==="no converter"){a.container_div.addClass("error");a.content_div.text(DATA_NOCONVERTER)}else{if(d.data!==undefined&&(d.data===null||d.data.length===0)){a.container_div.addClass("nodata");a.content_div.text(DATA_NONE)}else{if(d==="pending"){a.container_div.addClass("pending");a.content_div.text(DATA_PENDING);setTimeout(function(){a.init()},5000)}else{a.content_div.text("");a.content_div.css("height",a.height_px+"px");a.enabled=true;b(d);a.draw()}}}}})}else{a.container_div.addClass("nodata");a.content_div.text(DATA_NONE)}}});var TiledTrack=function(){};$.extend(TiledTrack.prototype,Track.prototype,{draw:function(){var i=this.view.low,e=this.view.high,f=e-i,d=this.vi
ew.resolution;if(DEBUG){$("#debug").text(d+" "+this.view.zoom_res)}var k=$("<div style='position: relative;'></div>"),l=this.content_div.width()/f,h;this.content_div.children(":first").remove();this.content_div.append(k),this.max_height=0;var a=Math.floor(i/d/DENSITY);while((a*DENSITY*d)<e){var j=this.content_div.width()+"_"+this.view.zoom_level+"_"+a;var c=this.tile_cache.get(j);if(c){var g=a*DENSITY*d;var b=(g-i)*l;if(this.left_offset){b-=this.left_offset}c.css({left:b});k.append(c);this.max_height=Math.max(this.max_height,c.height());this.content_div.css("height",this.max_height+"px")}else{this.delayed_draw(this,j,i,e,a,d,k,l)}a+=1}},delayed_draw:function(c,e,a,f,b,d,g,h){setTimeout(function(){if(!(a>c.view.high||f<c.view.low)){tile_element=c.draw_tile(d,b,g,h);if(tile_element){c.tile_cache.set(e,tile_element);c.max_height=Math.max(c.max_height,tile_element.height());c.content_div.css("height",c.max_height+"px")}}},50)}});var LabelTrack=function(a){Track.call(this,null,a)
;this.track_type="LabelTrack";this.hidden=true;this.container_div.addClass("label-track")};$.extend(LabelTrack.prototype,Track.prototype,{draw:function(){var c=this.view,d=c.high-c.low,g=Math.floor(Math.pow(10,Math.floor(Math.log(d)/Math.log(10)))),a=Math.floor(c.low/g)*g,e=this.content_div.width(),b=$("<div style='position: relative; height: 1.3em;'></div>");while(a<c.high){var f=(a-c.low)/d*e;b.append($("<div class='label'>"+commatize(a)+"</div>").css({position:"absolute",left:f-1}));a+=g}this.content_div.children(":first").remove();this.content_div.append(b)}});var LineTrack=function(c,a,b){this.track_type="LineTrack";Track.call(this,c,$("#viewport"));TiledTrack.call(this);this.height_px=100;this.dataset_id=a;this.data_cache=new Cache(CACHED_DATA);this.tile_cache=new Cache(CACHED_TILES_LINE);this.prefs={min_value:undefined,max_value:undefined,mode:"Line"};if(b.min_value!==undefined){this.prefs.min_value=b.min_value}if(b.max_value!==undefined){this.prefs.max_value=b.max_va
lue}if(b.mode!==undefined){this.prefs.mode=b.mode}};$.extend(LineTrack.prototype,TiledTrack.prototype,{init:function(){var a=this,b=a.view.tracks.indexOf(a);a.vertical_range=undefined;this.init_each({stats:true,chrom:a.view.chrom,low:null,high:null,dataset_id:a.dataset_id},function(c){a.container_div.addClass("line-track");data=c.data;if(isNaN(parseFloat(a.prefs.min_value))||isNaN(parseFloat(a.prefs.max_value))){a.prefs.min_value=data.min;a.prefs.max_value=data.max;$("#track_"+b+"_minval").val(a.prefs.min_value);$("#track_"+b+"_maxval").val(a.prefs.max_value)}a.vertical_range=a.prefs.max_value-a.prefs.min_value;a.total_frequency=data.total_frequency;$("#linetrack_"+b+"_minval").remove();$("#linetrack_"+b+"_maxval").remove();var e=$("<div />").addClass("yaxislabel").attr("id","linetrack_"+b+"_minval").text(a.prefs.min_value);var d=$("<div />").addClass("yaxislabel").attr("id","linetrack_"+b+"_maxval").text(a.prefs.max_value);d.css({position:"relative",top:"25px",left:"10px"})
;d.prependTo(a.container_div);e.css({position:"relative",top:a.height_px+55+"px",left:"10px"});e.prependTo(a.container_div)})},get_data:function(d,b){var c=this,a=b*DENSITY*d,f=(b+1)*DENSITY*d,e=d+"_"+b;if(!c.data_queue[e]){c.data_queue[e]=true;$.ajax({url:data_url,dataType:"json",data:{chrom:this.view.chrom,low:a,high:f,dataset_id:this.dataset_id,resolution:this.view.resolution},success:function(g){data=g.data;c.data_cache.set(e,data);delete c.data_queue[e];c.draw()},error:function(h,g,i){console.log(h,g,i)}})}},draw_tile:function(p,r,c,e){if(this.vertical_range===undefined){return}var s=r*DENSITY*p,a=DENSITY*p,b=$("<canvas class='tile'></canvas>"),v=p+"_"+r;if(this.data_cache.get(v)===undefined){this.get_data(p,r);return}var j=this.data_cache.get(v);if(j===null){return}b.css({position:"absolute",top:0,left:(s-this.view.low)*e});b.get(0).width=Math.ceil(a*e);b.get(0).height=this.height_px;var o=b.get(0).getContext("2d"),k=false,l=this.prefs.min_value,g=this.prefs.max_value,
n=this.vertical_range,t=this.total_frequency,d=this.height_px,m=this.prefs.mode;o.beginPath();if(data.length>1){var f=Math.ceil((data[1][0]-data[0][0])*e)}else{var f=10}var u,h;for(var q=0;q<data.length;q++){u=(data[q][0]-s)*e;h=data[q][1];if(m=="Intensity"){if(h===null){continue}if(h<=l){h=l}else{if(h>=g){h=g}}h=255-Math.floor((h-l)/n*255);o.fillStyle="rgb("+h+","+h+","+h+")";o.fillRect(u,0,f,this.height_px)}else{if(h===null){if(k&&m==="Filled"){o.lineTo(u,d)}k=false;continue}else{if(h<=l){h=l}else{if(h>=g){h=g}}h=Math.round(d-(h-l)/n*d);if(k){o.lineTo(u,h)}else{k=true;if(m==="Filled"){o.moveTo(u,d);o.lineTo(u,h)}else{o.moveTo(u,h)}}}}}if(m==="Filled"){if(k){o.lineTo(u,d)}o.fill()}else{o.stroke()}c.append(b);return b},gen_options:function(n){var a=$("<div />").addClass("form-row");var h="track_"+n+"_minval",l=$("<label></label>").attr("for",h).text("Min value:"),b=(this.prefs.min_value===undefined?"":this.prefs.min_value),m=$("<input></input>").attr("id",h).val(b),k="track_
"+n+"_maxval",g=$("<label></label>").attr("for",k).text("Max value:"),j=(this.prefs.max_value===undefined?"":this.prefs.max_value),f=$("<input></input>").attr("id",k).val(j),e="track_"+n+"_mode",d=$("<label></label>").attr("for",e).text("Display mode:"),i=(this.prefs.mode===undefined?"Line":this.prefs.mode),c=$('<select id="'+e+'"><option value="Line" id="mode_Line">Line</option><option value="Filled" id="mode_Filled">Filled</option><option value="Intensity" id="mode_Intensity">Intensity</option></select>');c.children("#mode_"+i).attr("selected","selected");return a.append(l).append(m).append(g).append(f).append(d).append(c)},update_options:function(d){var a=$("#track_"+d+"_minval").val(),c=$("#track_"+d+"_maxval").val(),b=$("#track_"+d+"_mode option:selected").val();if(a!==this.prefs.min_value||c!==this.prefs.max_value||b!==this.prefs.mode){this.prefs.min_value=parseFloat(a);this.prefs.max_value=parseFloat(c);this.prefs.mode=b;this.vertical_range=this.prefs.max_value-this.p
refs.min_value;$("#linetrack_"+d+"_minval").text(this.prefs.min_value);$("#linetrack_"+d+"_maxval").text(this.prefs.max_value);this.tile_cache.clear();this.draw()}}});var FeatureTrack=function(c,a,b){this.track_type="FeatureTrack";Track.call(this,c,$("#viewport"));TiledTrack.call(this);this.height_px=100;this.container_div.addClass("feature-track");this.dataset_id=a;this.zo_slots={};this.show_labels_scale=0.001;this.showing_details=false;this.vertical_detail_px=10;this.vertical_nodetail_px=3;this.default_font="9px Monaco, Lucida Console, monospace";this.left_offset=200;this.inc_slots={};this.data_queue={};this.s_e_by_tile={};this.tile_cache=new Cache(CACHED_TILES_FEATURE);this.data_cache=new Cache(20);this.prefs={block_color:"black",label_color:"black",show_counts:false};if(b.block_color!==undefined){this.prefs.block_color=b.block_color}if(b.label_color!==undefined){this.prefs.label_color=b.label_color}if(b.show_counts!==undefined){this.prefs.show_counts=b.show_counts}};$.ex
tend(FeatureTrack.prototype,TiledTrack.prototype,{init:function(){var a=this,b=a.view.max_low+"_"+a.view.max_high;a.mode="Auto";if(a.mode_div){a.mode_div.remove()}this.init_each({low:a.view.max_low,high:a.view.max_high,dataset_id:a.dataset_id,chrom:a.view.chrom,resolution:this.view.resolution},function(d){a.mode_div=$("<div class='right-float menubutton popup' />").text("Display Mode");a.header_div.append(a.mode_div);a.mode="Auto";var c=function(e){a.mode_div.text(e);a.mode=e;a.tile_cache.clear();a.draw()};make_popupmenu(a.mode_div,{Auto:function(){c("Auto")},Dense:function(){c("Dense")},Squish:function(){c("Squish")},Pack:function(){c("Pack")}});a.data_cache.set(b,d);a.draw()})},get_data:function(a,d){var b=this,c=a+"_"+d;if(!b.data_queue[c]){b.data_queue[c]=true;$.getJSON(data_url,{chrom:b.view.chrom,low:a,high:d,dataset_id:b.dataset_id,resolution:this.view.resolution,mode:this.mode},function(e){b.data_cache.set(c,e);delete b.data_queue[c];b.draw()})}},incremental_slots:fu
nction(a,h,c,r){if(!this.inc_slots[a]){this.inc_slots[a]={};this.inc_slots[a].w_scale=1/a;this.inc_slots[a].mode=r;this.s_e_by_tile[a]={}}var n=this.inc_slots[a].w_scale,z=[],l=0,b=$("<canvas></canvas>").get(0).getContext("2d"),o=this.view.max_low;var B=[];if(this.inc_slots[a].mode!==r){delete this.inc_slots[a];this.inc_slots[a]={mode:r,w_scale:n};delete this.s_e_by_tile[a];this.s_e_by_tile[a]={}}for(var w=0,x=h.length;w<x;w++){var g=h[w],m=g[0];if(this.inc_slots[a][m]!==undefined){l=Math.max(l,this.inc_slots[a][m]);B.push(this.inc_slots[a][m])}else{z.push(w)}}for(var w=0,x=z.length;w<x;w++){var g=h[z[w]],m=g[0],s=g[1],d=g[2],q=g[3],e=Math.floor((s-o)*n),f=Math.ceil((d-o)*n);if(q!==undefined&&!c){var t=b.measureText(q).width;if(e-t<0){f+=t}else{e-=t}}var v=0;while(true){var p=true;if(this.s_e_by_tile[a][v]!==undefined){for(var u=0,A=this.s_e_by_tile[a][v].length;u<A;u++){var y=this.s_e_by_tile[a][v][u];if(f>y[0]&&e<y[1]){p=false;break}}}if(p){if(this.s_e_by_tile[a][v]===unde
fined){this.s_e_by_tile[a][v]=[]}this.s_e_by_tile[a][v].push([e,f]);this.inc_slots[a][m]=v;l=Math.max(l,v);break}v++}}return l},rect_or_text:function(n,o,g,f,m,b,d,k,e,i){n.textAlign="center";var j=Math.round(o/2);if((this.mode==="Pack"||this.mode==="Auto")&&d!==undefined&&o>g){n.fillStyle=this.prefs.block_color;n.fillRect(k,i+1,e,9);n.fillStyle="#eee";for(var h=0,l=d.length;h<l;h++){if(b+h>=f&&b+h<=m){var a=Math.floor(Math.max(0,(b+h-f)*o));n.fillText(d[h],a+this.left_offset+j,i+9)}}}else{n.fillStyle=this.prefs.block_color;n.fillRect(k,i+4,e,3)}},draw_tile:function(X,h,n,al){var E=h*DENSITY*X,ad=(h+1)*DENSITY*X,D=DENSITY*X;var ae=E+"_"+ad;var z=this.data_cache.get(ae);if(z===undefined){this.data_queue[[E,ad]]=true;this.get_data(E,ad);return}var a=Math.ceil(D*al),L=$("<canvas class='tile'></canvas>"),Z=this.prefs.label_color,f=this.prefs.block_color,m=this.mode,V=(m==="Squish")||(m==="Dense")&&(m!=="Pack")||(m==="Auto"&&(z.extra_info==="no_detail")),P=this.left_offset,ak,s,a
m;if(z.dataset_type==="summary_tree"){s=30}else{if(m==="Dense"){s=15;am=10}else{am=(V?this.vertical_nodetail_px:this.vertical_detail_px);s=this.incremental_slots(this.view.zoom_res,z.data,V,m)*am+15;ak=this.inc_slots[this.view.zoom_res]}}L.css({position:"absolute",top:0,left:(E-this.view.low)*al-P});L.get(0).width=a+P;L.get(0).height=s;n.parent().css("height",Math.max(this.height_px,s)+"px");var A=L.get(0).getContext("2d"),ai=A.measureText("A").width;A.fillStyle=f;A.font=this.default_font;A.textAlign="right";if(z.dataset_type=="summary_tree"){var K,H=55,ac=255-H,g=ac*2/3,R=z.data,C=z.max,l=z.avg;if(R.length>2){var b=Math.ceil((R[1][0]-R[0][0])*al)}else{var b=50}for(var ag=0,w=R.length;ag<w;ag++){var T=Math.ceil((R[ag][0]-E)*al);var S=R[ag][1];if(!S){continue}K=Math.floor(ac-(S/C)*ac);A.fillStyle="rgb("+K+","+K+","+K+")";A.fillRect(T+P,0,b,20);if(this.prefs.show_counts){if(K>g){A.fillStyle="black"}else{A.fillStyle="#ddd"}A.textAlign="center";A.fillText(R[ag][1],T+P+(b/2),12)}
}n.append(L);return L}var aj=z.data;var af=0;for(var ag=0,w=aj.length;ag<w;ag++){var M=aj[ag],J=M[0],ah=M[1],U=M[2],F=M[3];if(ah<=ad&&U>=E){var W=Math.floor(Math.max(0,(ah-E)*al)),B=Math.ceil(Math.min(a,Math.max(0,(U-E)*al))),Q=(m==="Dense"?0:ak[J]*am);if(z.dataset_type==="bai"){A.fillStyle=f;if(M[4] instanceof Array){var t=Math.floor(Math.max(0,(M[4][0]-E)*al)),I=Math.ceil(Math.min(a,Math.max(0,(M[4][1]-E)*al))),r=Math.floor(Math.max(0,(M[5][0]-E)*al)),p=Math.ceil(Math.min(a,Math.max(0,(M[5][1]-E)*al)));if(M[4][1]>=E&&M[4][0]<=ad){this.rect_or_text(A,al,ai,E,ad,M[4][0],M[4][2],t+P,I-t,Q)}if(M[5][1]>=E&&M[5][0]<=ad){this.rect_or_text(A,al,ai,E,ad,M[5][0],M[5][2],r+P,p-r,Q)}if(r>I){A.fillStyle="#999";A.fillRect(I+P,Q+5,r-I,1)}}else{A.fillStyle=f;this.rect_or_text(A,al,ai,E,ad,ah,F,W+P,B-W,Q)}if(m!=="Dense"&&!V&&ah>E){A.fillStyle=this.prefs.label_color;if(h===0&&W-A.measureText(F).width<0){A.textAlign="left";A.fillText(J,B+2+P,Q+8)}else{A.textAlign="right";A.fillText(J,W-2+P,Q
+8)}A.fillStyle=f}}else{if(z.dataset_type==="interval_index"){if(V){A.fillRect(W+P,Q+5,B-W,1)}else{var v=M[4],O=M[5],Y=M[6],e=M[7];var u,aa,G=null,an=null;if(O&&Y){G=Math.floor(Math.max(0,(O-E)*al));an=Math.ceil(Math.min(a,Math.max(0,(Y-E)*al)))}if(m!=="Dense"&&F!==undefined&&ah>E){A.fillStyle=Z;if(h===0&&W-A.measureText(F).width<0){A.textAlign="left";A.fillText(F,B+2+P,Q+8)}else{A.textAlign="right";A.fillText(F,W-2+P,Q+8)}A.fillStyle=f}if(e){if(v){if(v=="+"){A.fillStyle=RIGHT_STRAND}else{if(v=="-"){A.fillStyle=LEFT_STRAND}}A.fillRect(W+P,Q,B-W,10);A.fillStyle=f}for(var ae=0,d=e.length;ae<d;ae++){var o=e[ae],c=Math.floor(Math.max(0,(o[0]-E)*al)),N=Math.ceil(Math.min(a,Math.max((o[1]-E)*al)));if(c>N){continue}u=5;aa=3;A.fillRect(c+P,Q+aa,N-c,u);if(G!==undefined&&!(c>an||N<G)){u=9;aa=1;var ab=Math.max(c,G),q=Math.min(N,an);A.fillRect(ab+P,Q+aa,q-ab,u)}}}else{u=9;aa=1;A.fillRect(W+P,Q+aa,B-W,u);if(M.strand){if(M.strand=="+"){A.fillStyle=RIGHT_STRAND_INV}else{if(M.strand=="-"){A
.fillStyle=LEFT_STRAND_INV}}A.fillRect(W+P,Q,B-W,10);A.fillStyle=prefs.block_color}}}}}af++}}n.append(L);return L},gen_options:function(i){var a=$("<div />").addClass("form-row");var e="track_"+i+"_block_color",k=$("<label />").attr("for",e).text("Block color:"),l=$("<input />").attr("id",e).attr("name",e).val(this.prefs.block_color),j="track_"+i+"_label_color",g=$("<label />").attr("for",j).text("Text color:"),h=$("<input />").attr("id",j).attr("name",j).val(this.prefs.label_color),f="track_"+i+"_show_count",c=$("<label />").attr("for",f).text("Show summary counts"),b=$('<input type="checkbox" style="float:left;"></input>').attr("id",f).attr("name",f).attr("checked",this.prefs.show_counts),d=$("<div />").append(b).append(c);return a.append(k).append(l).append(g).append(h).append(d)},update_options:function(e){var b=$("#track_"+e+"_block_color").val(),d=$("#track_"+e+"_label_color").val(),c=$("#track_"+e+"_mode option:selected").val(),a=$("#track_"+e+"_show_count").attr("che
cked");if(b!==this.prefs.block_color||d!==this.prefs.label_color||a!==this.prefs.show_counts){this.prefs.block_color=b;this.prefs.label_color=d;this.prefs.show_counts=a;this.tile_cache.clear();this.draw()}}});var ReadTrack=function(c,a,b){FeatureTrack.call(this,c,a,b);this.track_type="ReadTrack";this.vertical_detail_px=10;this.vertical_nodetail_px=5};$.extend(ReadTrack.prototype,TiledTrack.prototype,FeatureTrack.prototype,{});
+var DENSITY=200,FEATURE_LEVELS=10,DATA_ERROR="There was an error in indexing this dataset. ",DATA_NOCONVERTER="A converter for this dataset is not installed. Please check your datatypes_conf.xml file.",DATA_NONE="No data for this chrom/contig.",DATA_PENDING="Currently indexing... please wait",DATA_LOADING="Loading data...",CACHED_TILES_FEATURE=10,CACHED_TILES_LINE=30,CACHED_DATA=5,CONTEXT=$("<canvas></canvas>").get(0).getContext("2d"),RIGHT_STRAND,LEFT_STRAND;var right_img=new Image();right_img.src="/static/images/visualization/strand_right.png";right_img.onload=function(){RIGHT_STRAND=CONTEXT.createPattern(right_img,"repeat")};var left_img=new Image();left_img.src="/static/images/visualization/strand_left.png";left_img.onload=function(){LEFT_STRAND=CONTEXT.createPattern(left_img,"repeat")};var right_img_inv=new Image();right_img_inv.src="/static/images/visualization/strand_right_inv.png";right_img_inv.onload=function(){RIGHT_STRAND_INV=CONTEXT.createPattern(right_img_inv,"r
epeat")};var left_img_inv=new Image();left_img_inv.src="/static/images/visualization/strand_left_inv.png";left_img_inv.onload=function(){LEFT_STRAND_INV=CONTEXT.createPattern(left_img_inv,"repeat")};var Cache=function(a){this.num_elements=a;this.clear()};$.extend(Cache.prototype,{get:function(b){var a=this.key_ary.indexOf(b);if(a!=-1){this.key_ary.splice(a,1);this.key_ary.push(b)}return this.obj_cache[b]},set:function(b,c){if(!this.obj_cache[b]){if(this.key_ary.length>=this.num_elements){var a=this.key_ary.shift();delete this.obj_cache[a]}this.key_ary.push(b)}this.obj_cache[b]=c;return c},clear:function(){this.obj_cache={};this.key_ary=[]}});var View=function(b,d,c,a){this.vis_id=c;this.dbkey=a;this.title=d;this.chrom=b;this.tracks=[];this.label_tracks=[];this.max_low=0;this.max_high=0;this.track_id_counter=0;this.zoom_factor=3;this.min_separation=30;this.has_changes=false;this.reset()};$.extend(View.prototype,{add_track:function(a){a.view=this;a.track_id=this.track_id_count
er;this.tracks.push(a);if(a.init){a.init()}a.container_div.attr("id","track_"+a.track_id);this.track_id_counter+=1},add_label_track:function(a){a.view=this;this.label_tracks.push(a)},remove_track:function(a){this.has_changes=true;a.container_div.fadeOut("slow",function(){$(this).remove()});delete this.tracks[this.tracks.indexOf(a)]},update_options:function(){this.has_changes=true;var b=$("ul#sortable-ul").sortable("toArray");for(var c in b){var e=b[c].split("_li")[0].split("track_")[1];$("#viewport").append($("#track_"+e))}for(var d in view.tracks){var a=view.tracks[d];if(a&&a.update_options){a.update_options(d)}}},reset:function(){this.low=this.max_low;this.high=this.max_high;$(".yaxislabel").remove()},redraw:function(f){var d=this.high-this.low,b=this.low,e=this.high;if(b<this.max_low){b=this.max_low}if(e>this.max_high){e=this.max_high}if(d<this.min_separation){e=b+this.min_separation}this.low=Math.floor(b);this.high=Math.ceil(e);this.resolution=Math.pow(10,Math.ceil(Math.
log((this.high-this.low)/200)/Math.LN10));this.zoom_res=Math.pow(FEATURE_LEVELS,Math.max(0,Math.ceil(Math.log(this.resolution,FEATURE_LEVELS)/Math.log(FEATURE_LEVELS))));$("#overview-box").css({left:(this.low/(this.max_high-this.max_low))*$("#overview-viewport").width(),width:Math.max(12,(this.high-this.low)/(this.max_high-this.max_low)*$("#overview-viewport").width())}).show();$("#low").val(commatize(this.low));$("#high").val(commatize(this.high));if(!f){for(var c=0,a=this.tracks.length;c<a;c++){if(this.tracks[c]&&this.tracks[c].enabled){this.tracks[c].draw()}}for(var c=0,a=this.label_tracks.length;c<a;c++){this.label_tracks[c].draw()}}},zoom_in:function(b,c){if(this.max_high===0||this.high-this.low<this.min_separation){return}var d=this.high-this.low,e=d/2+this.low,a=(d/this.zoom_factor)/2;if(b){e=b/c.width()*(this.high-this.low)+this.low}this.low=Math.round(e-a);this.high=Math.round(e+a);this.redraw()},zoom_out:function(){if(this.max_high===0){return}var b=this.high-this.
low,c=b/2+this.low,a=(b*this.zoom_factor)/2;this.low=Math.round(c-a);this.high=Math.round(c+a);this.redraw()}});var Track=function(a,b){this.name=a;this.parent_element=b;this.init_global()};$.extend(Track.prototype,{init_global:function(){this.header_div=$("<div class='track-header'>").text(this.name);this.content_div=$("<div class='track-content'>");this.container_div=$("<div />").addClass("track").append(this.header_div).append(this.content_div);this.parent_element.append(this.container_div)},init_each:function(c,b){var a=this;a.enabled=false;a.data_queue={};a.tile_cache.clear();a.data_cache.clear();a.content_div.css("height","30px");if(!a.content_div.text()){a.content_div.text(DATA_LOADING)}a.container_div.removeClass("nodata error pending");if(a.view.chrom){$.getJSON(data_url,c,function(d){if(!d||d==="error"||d.kind==="error"){a.container_div.addClass("error");a.content_div.text(DATA_ERROR);if(d.message){var f=a.view.tracks.indexOf(a);var e=$("<a href='javascript:void(0)
;'></a>").attr("id",f+"_error");e.text("Click to view error");$("#"+f+"_error").live("click",function(){show_modal("Trackster Error","<pre>"+d.message+"</pre>",{Close:hide_modal})});a.content_div.append(e)}}else{if(d==="no converter"){a.container_div.addClass("error");a.content_div.text(DATA_NOCONVERTER)}else{if(d.data!==undefined&&(d.data===null||d.data.length===0)){a.container_div.addClass("nodata");a.content_div.text(DATA_NONE)}else{if(d==="pending"){a.container_div.addClass("pending");a.content_div.text(DATA_PENDING);setTimeout(function(){a.init()},5000)}else{a.content_div.text("");a.content_div.css("height",a.height_px+"px");a.enabled=true;b(d);a.draw()}}}}})}else{a.container_div.addClass("nodata");a.content_div.text(DATA_NONE)}}});var TiledTrack=function(){};$.extend(TiledTrack.prototype,Track.prototype,{draw:function(){var i=this.view.low,e=this.view.high,f=e-i,d=this.view.resolution;var k=$("<div style='position: relative;'></div>"),l=this.content_div.width()/f,h;thi
s.content_div.children(":first").remove();this.content_div.append(k),this.max_height=0;var a=Math.floor(i/d/DENSITY);while((a*DENSITY*d)<e){var j=this.content_div.width()+"_"+l+"_"+a;var c=this.tile_cache.get(j);if(c){var g=a*DENSITY*d;var b=(g-i)*l;if(this.left_offset){b-=this.left_offset}c.css({left:b});k.append(c);this.max_height=Math.max(this.max_height,c.height());this.content_div.css("height",this.max_height+"px")}else{this.delayed_draw(this,j,i,e,a,d,k,l)}a+=1}},delayed_draw:function(c,e,a,f,b,d,g,h){setTimeout(function(){if(!(a>c.view.high||f<c.view.low)){tile_element=c.draw_tile(d,b,g,h);if(tile_element){c.tile_cache.set(e,tile_element);c.max_height=Math.max(c.max_height,tile_element.height());c.content_div.css("height",c.max_height+"px")}}},50)}});var LabelTrack=function(a){Track.call(this,null,a);this.track_type="LabelTrack";this.hidden=true;this.container_div.addClass("label-track")};$.extend(LabelTrack.prototype,Track.prototype,{draw:function(){var c=this.view,d
=c.high-c.low,g=Math.floor(Math.pow(10,Math.floor(Math.log(d)/Math.log(10)))),a=Math.floor(c.low/g)*g,e=this.content_div.width(),b=$("<div style='position: relative; height: 1.3em;'></div>");while(a<c.high){var f=(a-c.low)/d*e;b.append($("<div class='label'>"+commatize(a)+"</div>").css({position:"absolute",left:f-1}));a+=g}this.content_div.children(":first").remove();this.content_div.append(b)}});var LineTrack=function(c,a,b){this.track_type="LineTrack";Track.call(this,c,$("#viewport"));TiledTrack.call(this);this.height_px=100;this.dataset_id=a;this.data_cache=new Cache(CACHED_DATA);this.tile_cache=new Cache(CACHED_TILES_LINE);this.prefs={min_value:undefined,max_value:undefined,mode:"Line"};if(b.min_value!==undefined){this.prefs.min_value=b.min_value}if(b.max_value!==undefined){this.prefs.max_value=b.max_value}if(b.mode!==undefined){this.prefs.mode=b.mode}};$.extend(LineTrack.prototype,TiledTrack.prototype,{init:function(){var a=this,b=a.view.tracks.indexOf(a);a.vertical_ran
ge=undefined;this.init_each({stats:true,chrom:a.view.chrom,low:null,high:null,dataset_id:a.dataset_id},function(c){a.container_div.addClass("line-track");data=c.data;if(isNaN(parseFloat(a.prefs.min_value))||isNaN(parseFloat(a.prefs.max_value))){a.prefs.min_value=data.min;a.prefs.max_value=data.max;$("#track_"+b+"_minval").val(a.prefs.min_value);$("#track_"+b+"_maxval").val(a.prefs.max_value)}a.vertical_range=a.prefs.max_value-a.prefs.min_value;a.total_frequency=data.total_frequency;$("#linetrack_"+b+"_minval").remove();$("#linetrack_"+b+"_maxval").remove();var e=$("<div />").addClass("yaxislabel").attr("id","linetrack_"+b+"_minval").text(a.prefs.min_value);var d=$("<div />").addClass("yaxislabel").attr("id","linetrack_"+b+"_maxval").text(a.prefs.max_value);d.css({position:"relative",top:"25px",left:"10px"});d.prependTo(a.container_div);e.css({position:"relative",top:a.height_px+55+"px",left:"10px"});e.prependTo(a.container_div)})},get_data:function(d,b){var c=this,a=b*DENSIT
Y*d,f=(b+1)*DENSITY*d,e=d+"_"+b;if(!c.data_queue[e]){c.data_queue[e]=true;$.ajax({url:data_url,dataType:"json",data:{chrom:this.view.chrom,low:a,high:f,dataset_id:this.dataset_id,resolution:this.view.resolution},success:function(g){data=g.data;c.data_cache.set(e,data);delete c.data_queue[e];c.draw()},error:function(h,g,i){console.log(h,g,i)}})}},draw_tile:function(p,r,c,e){if(this.vertical_range===undefined){return}var s=r*DENSITY*p,a=DENSITY*p,b=$("<canvas class='tile'></canvas>"),v=p+"_"+r;if(this.data_cache.get(v)===undefined){this.get_data(p,r);return}var j=this.data_cache.get(v);if(j===null){return}b.css({position:"absolute",top:0,left:(s-this.view.low)*e});b.get(0).width=Math.ceil(a*e);b.get(0).height=this.height_px;var o=b.get(0).getContext("2d"),k=false,l=this.prefs.min_value,g=this.prefs.max_value,n=this.vertical_range,t=this.total_frequency,d=this.height_px,m=this.prefs.mode;o.beginPath();if(data.length>1){var f=Math.ceil((data[1][0]-data[0][0])*e)}else{var f=10}va
r u,h;for(var q=0;q<data.length;q++){u=(data[q][0]-s)*e;h=data[q][1];if(m=="Intensity"){if(h===null){continue}if(h<=l){h=l}else{if(h>=g){h=g}}h=255-Math.floor((h-l)/n*255);o.fillStyle="rgb("+h+","+h+","+h+")";o.fillRect(u,0,f,this.height_px)}else{if(h===null){if(k&&m==="Filled"){o.lineTo(u,d)}k=false;continue}else{if(h<=l){h=l}else{if(h>=g){h=g}}h=Math.round(d-(h-l)/n*d);if(k){o.lineTo(u,h)}else{k=true;if(m==="Filled"){o.moveTo(u,d);o.lineTo(u,h)}else{o.moveTo(u,h)}}}}}if(m==="Filled"){if(k){o.lineTo(u,d)}o.fill()}else{o.stroke()}c.append(b);return b},gen_options:function(n){var a=$("<div />").addClass("form-row");var h="track_"+n+"_minval",l=$("<label></label>").attr("for",h).text("Min value:"),b=(this.prefs.min_value===undefined?"":this.prefs.min_value),m=$("<input></input>").attr("id",h).val(b),k="track_"+n+"_maxval",g=$("<label></label>").attr("for",k).text("Max value:"),j=(this.prefs.max_value===undefined?"":this.prefs.max_value),f=$("<input></input>").attr("id",k).val(
j),e="track_"+n+"_mode",d=$("<label></label>").attr("for",e).text("Display mode:"),i=(this.prefs.mode===undefined?"Line":this.prefs.mode),c=$('<select id="'+e+'"><option value="Line" id="mode_Line">Line</option><option value="Filled" id="mode_Filled">Filled</option><option value="Intensity" id="mode_Intensity">Intensity</option></select>');c.children("#mode_"+i).attr("selected","selected");return a.append(l).append(m).append(g).append(f).append(d).append(c)},update_options:function(d){var a=$("#track_"+d+"_minval").val(),c=$("#track_"+d+"_maxval").val(),b=$("#track_"+d+"_mode option:selected").val();if(a!==this.prefs.min_value||c!==this.prefs.max_value||b!==this.prefs.mode){this.prefs.min_value=parseFloat(a);this.prefs.max_value=parseFloat(c);this.prefs.mode=b;this.vertical_range=this.prefs.max_value-this.prefs.min_value;$("#linetrack_"+d+"_minval").text(this.prefs.min_value);$("#linetrack_"+d+"_maxval").text(this.prefs.max_value);this.tile_cache.clear();this.draw()}}});var
FeatureTrack=function(c,a,b){this.track_type="FeatureTrack";Track.call(this,c,$("#viewport"));TiledTrack.call(this);this.height_px=100;this.container_div.addClass("feature-track");this.dataset_id=a;this.zo_slots={};this.show_labels_scale=0.001;this.showing_details=false;this.vertical_detail_px=10;this.vertical_nodetail_px=3;this.default_font="9px Monaco, Lucida Console, monospace";this.left_offset=200;this.inc_slots={};this.data_queue={};this.s_e_by_tile={};this.tile_cache=new Cache(CACHED_TILES_FEATURE);this.data_cache=new Cache(20);this.prefs={block_color:"black",label_color:"black",show_counts:false};if(b.block_color!==undefined){this.prefs.block_color=b.block_color}if(b.label_color!==undefined){this.prefs.label_color=b.label_color}if(b.show_counts!==undefined){this.prefs.show_counts=b.show_counts}};$.extend(FeatureTrack.prototype,TiledTrack.prototype,{init:function(){var a=this,b=a.view.max_low+"_"+a.view.max_high;a.mode="Auto";if(a.mode_div){a.mode_div.remove()}this.ini
t_each({low:a.view.max_low,high:a.view.max_high,dataset_id:a.dataset_id,chrom:a.view.chrom,resolution:this.view.resolution},function(d){a.mode_div=$("<div class='right-float menubutton popup' />").text("Display Mode");a.header_div.append(a.mode_div);a.mode="Auto";var c=function(e){a.mode_div.text(e);a.mode=e;a.tile_cache.clear();a.draw()};make_popupmenu(a.mode_div,{Auto:function(){c("Auto")},Dense:function(){c("Dense")},Squish:function(){c("Squish")},Pack:function(){c("Pack")}});a.data_cache.set(b,d);a.draw()})},get_data:function(a,d){var b=this,c=a+"_"+d;if(!b.data_queue[c]){b.data_queue[c]=true;$.getJSON(data_url,{chrom:b.view.chrom,low:a,high:d,dataset_id:b.dataset_id,resolution:this.view.resolution,mode:this.mode},function(e){b.data_cache.set(c,e);delete b.data_queue[c];b.draw()})}},incremental_slots:function(a,h,c,r){if(!this.inc_slots[a]){this.inc_slots[a]={};this.inc_slots[a].w_scale=1/a;this.inc_slots[a].mode=r;this.s_e_by_tile[a]={}}var n=this.inc_slots[a].w_scale,z
=[],l=0,b=$("<canvas></canvas>").get(0).getContext("2d"),o=this.view.max_low;var B=[];if(this.inc_slots[a].mode!==r){delete this.inc_slots[a];this.inc_slots[a]={mode:r,w_scale:n};delete this.s_e_by_tile[a];this.s_e_by_tile[a]={}}for(var w=0,x=h.length;w<x;w++){var g=h[w],m=g[0];if(this.inc_slots[a][m]!==undefined){l=Math.max(l,this.inc_slots[a][m]);B.push(this.inc_slots[a][m])}else{z.push(w)}}for(var w=0,x=z.length;w<x;w++){var g=h[z[w]],m=g[0],s=g[1],d=g[2],q=g[3],e=Math.floor((s-o)*n),f=Math.ceil((d-o)*n);if(q!==undefined&&!c){var t=b.measureText(q).width;if(e-t<0){f+=t}else{e-=t}}var v=0;while(true){var p=true;if(this.s_e_by_tile[a][v]!==undefined){for(var u=0,A=this.s_e_by_tile[a][v].length;u<A;u++){var y=this.s_e_by_tile[a][v][u];if(f>y[0]&&e<y[1]){p=false;break}}}if(p){if(this.s_e_by_tile[a][v]===undefined){this.s_e_by_tile[a][v]=[]}this.s_e_by_tile[a][v].push([e,f]);this.inc_slots[a][m]=v;l=Math.max(l,v);break}v++}}return l},rect_or_text:function(n,o,g,f,m,b,d,k,e,i){
n.textAlign="center";var j=Math.round(o/2);if((this.mode==="Pack"||this.mode==="Auto")&&d!==undefined&&o>g){n.fillStyle=this.prefs.block_color;n.fillRect(k,i+1,e,9);n.fillStyle="#eee";for(var h=0,l=d.length;h<l;h++){if(b+h>=f&&b+h<=m){var a=Math.floor(Math.max(0,(b+h-f)*o));n.fillText(d[h],a+this.left_offset+j,i+9)}}}else{n.fillStyle=this.prefs.block_color;n.fillRect(k,i+4,e,3)}},draw_tile:function(X,h,n,al){var E=h*DENSITY*X,ad=(h+1)*DENSITY*X,D=DENSITY*X;var ae=E+"_"+ad;var z=this.data_cache.get(ae);if(z===undefined){this.data_queue[[E,ad]]=true;this.get_data(E,ad);return}var a=Math.ceil(D*al),L=$("<canvas class='tile'></canvas>"),Z=this.prefs.label_color,f=this.prefs.block_color,m=this.mode,V=(m==="Squish")||(m==="Dense")&&(m!=="Pack")||(m==="Auto"&&(z.extra_info==="no_detail")),P=this.left_offset,ak,s,am;if(z.dataset_type==="summary_tree"){s=30}else{if(m==="Dense"){s=15;am=10}else{am=(V?this.vertical_nodetail_px:this.vertical_detail_px);s=this.incremental_slots(this.view
.zoom_res,z.data,V,m)*am+15;ak=this.inc_slots[this.view.zoom_res]}}L.css({position:"absolute",top:0,left:(E-this.view.low)*al-P});L.get(0).width=a+P;L.get(0).height=s;n.parent().css("height",Math.max(this.height_px,s)+"px");var A=L.get(0).getContext("2d"),ai=A.measureText("A").width;A.fillStyle=f;A.font=this.default_font;A.textAlign="right";if(z.dataset_type=="summary_tree"){var K,H=55,ac=255-H,g=ac*2/3,R=z.data,C=z.max,l=z.avg;if(R.length>2){var b=Math.ceil((R[1][0]-R[0][0])*al)}else{var b=50}for(var ag=0,w=R.length;ag<w;ag++){var T=Math.ceil((R[ag][0]-E)*al);var S=R[ag][1];if(!S){continue}K=Math.floor(ac-(S/C)*ac);A.fillStyle="rgb("+K+","+K+","+K+")";A.fillRect(T+P,0,b,20);if(this.prefs.show_counts){if(K>g){A.fillStyle="black"}else{A.fillStyle="#ddd"}A.textAlign="center";A.fillText(R[ag][1],T+P+(b/2),12)}}n.append(L);return L}var aj=z.data;var af=0;for(var ag=0,w=aj.length;ag<w;ag++){var M=aj[ag],J=M[0],ah=M[1],U=M[2],F=M[3];if(ah<=ad&&U>=E){var W=Math.floor(Math.max(0,(ah
-E)*al)),B=Math.ceil(Math.min(a,Math.max(0,(U-E)*al))),Q=(m==="Dense"?0:ak[J]*am);if(z.dataset_type==="bai"){A.fillStyle=f;if(M[4] instanceof Array){var t=Math.floor(Math.max(0,(M[4][0]-E)*al)),I=Math.ceil(Math.min(a,Math.max(0,(M[4][1]-E)*al))),r=Math.floor(Math.max(0,(M[5][0]-E)*al)),p=Math.ceil(Math.min(a,Math.max(0,(M[5][1]-E)*al)));if(M[4][1]>=E&&M[4][0]<=ad){this.rect_or_text(A,al,ai,E,ad,M[4][0],M[4][2],t+P,I-t,Q)}if(M[5][1]>=E&&M[5][0]<=ad){this.rect_or_text(A,al,ai,E,ad,M[5][0],M[5][2],r+P,p-r,Q)}if(r>I){A.fillStyle="#999";A.fillRect(I+P,Q+5,r-I,1)}}else{A.fillStyle=f;this.rect_or_text(A,al,ai,E,ad,ah,F,W+P,B-W,Q)}if(m!=="Dense"&&!V&&ah>E){A.fillStyle=this.prefs.label_color;if(h===0&&W-A.measureText(F).width<0){A.textAlign="left";A.fillText(J,B+2+P,Q+8)}else{A.textAlign="right";A.fillText(J,W-2+P,Q+8)}A.fillStyle=f}}else{if(z.dataset_type==="interval_index"){if(V){A.fillRect(W+P,Q+5,B-W,1)}else{var v=M[4],O=M[5],Y=M[6],e=M[7];var u,aa,G=null,an=null;if(O&&Y){G=Math.
floor(Math.max(0,(O-E)*al));an=Math.ceil(Math.min(a,Math.max(0,(Y-E)*al)))}if(m!=="Dense"&&F!==undefined&&ah>E){A.fillStyle=Z;if(h===0&&W-A.measureText(F).width<0){A.textAlign="left";A.fillText(F,B+2+P,Q+8)}else{A.textAlign="right";A.fillText(F,W-2+P,Q+8)}A.fillStyle=f}if(e){if(v){if(v=="+"){A.fillStyle=RIGHT_STRAND}else{if(v=="-"){A.fillStyle=LEFT_STRAND}}A.fillRect(W+P,Q,B-W,10);A.fillStyle=f}for(var ae=0,d=e.length;ae<d;ae++){var o=e[ae],c=Math.floor(Math.max(0,(o[0]-E)*al)),N=Math.ceil(Math.min(a,Math.max((o[1]-E)*al)));if(c>N){continue}u=5;aa=3;A.fillRect(c+P,Q+aa,N-c,u);if(G!==undefined&&!(c>an||N<G)){u=9;aa=1;var ab=Math.max(c,G),q=Math.min(N,an);A.fillRect(ab+P,Q+aa,q-ab,u)}}}else{u=9;aa=1;A.fillRect(W+P,Q+aa,B-W,u);if(M.strand){if(M.strand=="+"){A.fillStyle=RIGHT_STRAND_INV}else{if(M.strand=="-"){A.fillStyle=LEFT_STRAND_INV}}A.fillRect(W+P,Q,B-W,10);A.fillStyle=prefs.block_color}}}}}af++}}n.append(L);return L},gen_options:function(i){var a=$("<div />").addClass("for
m-row");var e="track_"+i+"_block_color",k=$("<label />").attr("for",e).text("Block color:"),l=$("<input />").attr("id",e).attr("name",e).val(this.prefs.block_color),j="track_"+i+"_label_color",g=$("<label />").attr("for",j).text("Text color:"),h=$("<input />").attr("id",j).attr("name",j).val(this.prefs.label_color),f="track_"+i+"_show_count",c=$("<label />").attr("for",f).text("Show summary counts"),b=$('<input type="checkbox" style="float:left;"></input>').attr("id",f).attr("name",f).attr("checked",this.prefs.show_counts),d=$("<div />").append(b).append(c);return a.append(k).append(l).append(g).append(h).append(d)},update_options:function(e){var b=$("#track_"+e+"_block_color").val(),d=$("#track_"+e+"_label_color").val(),c=$("#track_"+e+"_mode option:selected").val(),a=$("#track_"+e+"_show_count").attr("checked");if(b!==this.prefs.block_color||d!==this.prefs.label_color||a!==this.prefs.show_counts){this.prefs.block_color=b;this.prefs.label_color=d;this.prefs.show_counts=a;th
is.tile_cache.clear();this.draw()}}});var ReadTrack=function(c,a,b){FeatureTrack.call(this,c,a,b);this.track_type="ReadTrack";this.vertical_detail_px=10;this.vertical_nodetail_px=5};$.extend(ReadTrack.prototype,TiledTrack.prototype,FeatureTrack.prototype,{});
--- a/static/scripts/trackster.js
+++ b/static/scripts/trackster.js
@@ -1,7 +1,6 @@
/* Trackster
2010, James Taylor, Kanwei Li
*/
-var DEBUG = false;
var DENSITY = 200,
FEATURE_LEVELS = 10,
@@ -37,15 +36,6 @@ left_img_inv.onload = function() {
LEFT_STRAND_INV = CONTEXT.createPattern(left_img_inv, "repeat");
};
-function commatize( number ) {
- number += ''; // Convert to string
- var rgx = /(\d+)(\d{3})/;
- while (rgx.test(number)) {
- number = number.replace(rgx, '$1' + ',' + '$2');
- }
- return number;
-}
-
var Cache = function( num_elements ) {
this.num_elements = num_elements;
this.clear();
@@ -87,11 +77,11 @@ var View = function( chrom, title, vis_i
this.label_tracks = [];
this.max_low = 0;
this.max_high = 0;
- this.center = (this.max_high - this.max_low) / 2;
+ this.track_id_counter = 0;
this.zoom_factor = 3;
- this.zoom_level = 0;
- this.track_id_counter = 0;
+ this.min_separation = 30;
this.has_changes = false;
+ this.reset();
};
$.extend( View.prototype, {
add_track: function ( track ) {
@@ -129,27 +119,24 @@ var View = function( chrom, title, vis_i
reset: function() {
this.low = this.max_low;
this.high = this.max_high;
- this.center = this.center = (this.max_high - this.max_low) / 2;
- this.zoom_level = 0;
$(".yaxislabel").remove();
},
redraw: function(nodraw) {
- this.span = this.max_high - this.max_low;
- var span = this.span / Math.pow(this.zoom_factor, this.zoom_level),
- low = this.center - (span / 2),
- high = low + span;
+ var span = this.high - this.low,
+ low = this.low,
+ high = this.high;
- if (low < 0) {
- low = 0;
- high = low + span;
-
- } else if (high > this.max_high) {
+ if (low < this.max_low) {
+ low = this.max_low;
+ }
+ if (high > this.max_high) {
high = this.max_high;
- low = high - span;
+ }
+ if (span < this.min_separation) {
+ high = low + this.min_separation;
}
this.low = Math.floor(low);
this.high = Math.ceil(high);
- this.center = Math.round( this.low + (this.high - this.low) / 2 );
// 10^log10(range / DENSITY) Close approximation for browser window, assuming DENSITY = window width
this.resolution = Math.pow( 10, Math.ceil( Math.log( (this.high - this.low) / 200 ) / Math.LN10 ) );
@@ -157,9 +144,9 @@ var View = function( chrom, title, vis_i
// Overview
$("#overview-box").css( {
- left: ( this.low / this.span ) * $("#overview-viewport").width(),
+ left: ( this.low / (this.max_high - this.max_low) ) * $("#overview-viewport").width(),
// Minimum width for usability
- width: Math.max( 12, ( ( this.high - this.low ) / this.span ) * $("#overview-viewport").width() )
+ width: Math.max( 12, (this.high - this.low)/(this.max_high - this.max_low) * $("#overview-viewport").width() )
}).show();
$("#low").val( commatize(this.low) );
$("#high").val( commatize(this.high) );
@@ -174,26 +161,29 @@ var View = function( chrom, title, vis_i
}
}
},
- zoom_in: function ( point, container ) {
- if (this.max_high === 0 || this.high - this.low < 30) {
+ zoom_in: function (point, container) {
+ if (this.max_high === 0 || this.high - this.low < this.min_separation) {
return;
}
-
- if ( point ) {
- this.center = point / container.width() * (this.high - this.low) + this.low;
+ var span = this.high - this.low,
+ cur_center = span / 2 + this.low,
+ new_half = (span / this.zoom_factor) / 2;
+ if (point) {
+ cur_center = point / container.width() * (this.high - this.low) + this.low;
}
- this.zoom_level += 1;
+ this.low = Math.round(cur_center - new_half);
+ this.high = Math.round(cur_center + new_half);
this.redraw();
},
zoom_out: function () {
if (this.max_high === 0) {
return;
}
- if (this.zoom_level <= 0) {
- this.zoom_level = 0;
- return;
- }
- this.zoom_level -= 1;
+ var span = this.high - this.low,
+ cur_center = span / 2 + this.low,
+ new_half = (span * this.zoom_factor) / 2;
+ this.low = Math.round(cur_center - new_half);
+ this.high = Math.round(cur_center + new_half);
this.redraw();
}
});
@@ -269,8 +259,6 @@ var TiledTrack = function() {
high = this.view.high,
range = high - low,
resolution = this.view.resolution;
-
- if (DEBUG) { $("#debug").text(resolution + " " + this.view.zoom_res); }
var parent_element = $("<div style='position: relative;'></div>"),
w_scale = this.content_div.width() / range,
@@ -283,7 +271,7 @@ var TiledTrack = function() {
var tile_index = Math.floor( low / resolution / DENSITY );
while ( ( tile_index * DENSITY * resolution ) < high ) {
// Check in cache
- var key = this.content_div.width() + '_' + this.view.zoom_level + '_' + tile_index;
+ var key = this.content_div.width() + '_' + w_scale + '_' + tile_index;
var cached = this.tile_cache.get(key);
if ( cached ) {
// console.log("cached tile " + tile_index);
--- a/static/scripts/galaxy.base.js
+++ b/static/scripts/galaxy.base.js
@@ -454,6 +454,15 @@ function init_history_items(historywrapp
}
}
+function commatize( number ) {
+ number += ''; // Convert to string
+ var rgx = /(\d+)(\d{3})/;
+ while (rgx.test(number)) {
+ number = number.replace(rgx, '$1' + ',' + '$2');
+ }
+ return number;
+}
+
$(document).ready( function() {
// Links with confirmation
$( "a[confirm]" ).click( function() {
--- a/templates/tracks/browser.mako
+++ b/templates/tracks/browser.mako
@@ -32,11 +32,11 @@
<div class="unified-panel-header" unselectable="on"><div class="unified-panel-header-inner">Trackster Visualization | ${config['title']}
<a id="save-button" class="panel-header-button right-float" href="javascript:void(0);">Save</a>
- <a id="refresh-button" class="panel-header-button right-float" href="javascript:void(0);">Refresh</a>
+ <a id="refresh-button" class="panel-header-button right-float" href="javascript:void(0);" onclick="view.update_options();return false;">Refresh</a></div></div><div id="content">
- <div id="top-labeltrack"></div>
+ <div id="top-labeltrack" style="position: relative;"></div><div id="viewport-container" style="overflow-x: hidden; overflow-y: auto;"><div id="viewport"></div></div>
@@ -63,7 +63,6 @@
<img src="${h.url_for('/static/images/fugue/magnifier-zoom-out.png')}" /></a></form>
- <div id="debug" style="float: right"></div></div></div></div>
@@ -146,6 +145,9 @@
});
$("#content").bind("mousewheel", function( e, delta ) {
+ if (Math.abs(delta) < 0.5) {
+ return;
+ }
if (delta > 0) {
view.zoom_in(e.pageX, $("#viewport-container"));
} else {
@@ -166,19 +168,19 @@
this.current_x = e.offsetX;
var delta_chrom = Math.round(delta / $(document).width() * view.span);
- view.center += delta_chrom;
+ view.high += delta_chrom;
+ view.low += delta_chrom;
view.redraw();
});
// To adjust the size of the viewport to fit the fixed-height footer
var refresh = function( e ) {
- $("#viewport-container").height( $(window).height() - 120 );
+ $("#viewport-container").height( $(window).height() - 100 );
$("#nav-container").width( $("#center").width() );
view.redraw();
};
$(window).bind( "resize", function(e) { refresh(e); } );
- $("#right-border").bind( "click", function(e) { refresh(e); } );
- $("#right-border").bind( "dragend", function(e) { refresh(e); } );
+ $("#right-border").bind( "click dragend", function(e) { refresh(e); } );
$(window).trigger( "resize" );
$("#viewport-container").bind( "dragstart", function( e ) {
@@ -195,8 +197,9 @@
this.current_height = e.clientY;
this.current_x = e.offsetX;
- var delta_chrom = Math.round(delta / $(document).width() * (view.high - view.low));
- view.center -= delta_chrom;
+ var delta_chrom = Math.round(delta / $("#viewport-container").width() * (view.high - view.low));
+ view.high -= delta_chrom;
+ view.low -= delta_chrom;
view.redraw();
});
@@ -286,6 +289,35 @@
view.add_label_track( new LabelTrack( $("#top-labeltrack") ) );
view.add_label_track( new LabelTrack( $("#nav-labeltrack") ) );
+ $("#top-labeltrack").bind( "dragstart", function(e) {
+ this.drag_origin_x = e.clientX;
+ this.drag_origin_pos = e.clientX / $("#viewport-container").width() * (view.high - view.low) + view.low;
+ this.drag_div = $("<div />").css( {
+ "height": $("#viewport-container").height(), "top": "0px", "position": "absolute",
+ "background-color": "#cfc", "border": "1px solid #6a6", "opacity": 0.5
+ } ).appendTo( $(this) );
+ }).bind( "drag", function(e) {
+ var min = Math.min(e.clientX, this.drag_origin_x),
+ max = Math.max(e.clientX, this.drag_origin_x),
+ span = (view.high - view.low),
+ width = $("#viewport-container").width();
+
+ $("#low").val(commatize(Math.round(min / width * span) + view.low));
+ $("#high").val(commatize(Math.round(max / width * span) + view.low));
+ this.drag_div.css( { "left": min + "px", "width": (max - min) + "px" } );
+ }).bind( "dragend", function(e) {
+ var min = Math.min(e.clientX, this.drag_origin_x),
+ max = Math.max(e.clientX, this.drag_origin_x),
+ span = (view.high - view.low),
+ width = $("#viewport-container").width(),
+ old_low = view.low;
+
+ view.low = Math.round(min / width * span) + old_low;
+ view.high = Math.round(max / width * span) + old_low;
+ this.drag_div.remove();
+ view.redraw();
+ });
+
$.ajax({
url: "${h.url_for( action='chroms' )}",
%if config.get('vis_id'):
--- a/static/trackster.css
+++ b/static/trackster.css
@@ -111,7 +111,6 @@
.label-track {
/* font-weight: bold; */
/* font-size: 10px; */
-
}
.label-track .label {
border-left: solid #999 1px;
1
0
galaxy-dist commit 170e2688d370: Improvements to history import/export archive: (a) use python tar file support (which may be more widely available than pax) and (b) perform some simple security checks to ensure that uploaded archive files are not malicious.
by commits-noreply@bitbucket.org 07 Jun '10
by commits-noreply@bitbucket.org 07 Jun '10
07 Jun '10
# HG changeset patch -- Bitbucket.org
# Project galaxy-dist
# URL http://bitbucket.org/galaxy/galaxy-dist/overview
# User jeremy goecks <jeremy.goecks(a)emory.edu>
# Date 1275595159 14400
# Node ID 170e2688d37043c9f1c4349f15d29ce6dd43e88b
# Parent e4d2a5c24b05e164dc37918574d7078f07fc6b67
Improvements to history import/export archive: (a) use python tar file support (which may be more widely available than pax) and (b) perform some simple security checks to ensure that uploaded archive files are not malicious.
--- a/lib/galaxy/web/controllers/history.py
+++ b/lib/galaxy/web/controllers/history.py
@@ -9,7 +9,7 @@ from galaxy.util.sanitize_html import sa
from galaxy.tools.actions import upload_common
from galaxy.tags.tag_handler import GalaxyTagHandler
from sqlalchemy.sql.expression import ClauseElement
-import webhelpers, logging, operator, tempfile, subprocess, shutil
+import webhelpers, logging, operator, tempfile, subprocess, shutil, tarfile
from datetime import datetime
from cgi import escape
@@ -449,17 +449,18 @@ class HistoryController( BaseController,
if archived_history is not None:
# Import archived history.
- try:
- archive_file = archived_history.file
-
+ try:
+ history_archive_file = tarfile.open( archived_history.file.name )
+
+ # Security check: make sure that members are relative, not absolute.
+ for tarinfo in history_archive_file.getmembers():
+ if tarinfo.name.startswith("/") or tarinfo.name.startswith(".."):
+ return trans.show_error_message( 'Error importing history archive: archive file is invalid.' )
+
# Unpack archive in temporary directory.
temp_output_dir = tempfile.mkdtemp()
- cmd = "pax -z -r < %s " % archive_file.name
- temp_stderr_name = tempfile.NamedTemporaryFile( dir=temp_output_dir ).name
- temp_stderr = open( temp_stderr_name, 'wb' )
- proc = subprocess.Popen( args=cmd, shell=True, cwd=temp_output_dir, stderr=temp_stderr.fileno() )
- returncode = proc.wait()
- temp_stderr.close()
+ history_archive_file.extractall( path=temp_output_dir )
+ history_archive_file.close()
# Read history attributes.
history_attr_in = open( '%s/%s' % ( temp_output_dir, 'history_attrs.txt'), 'rb' )
@@ -625,24 +626,14 @@ class HistoryController( BaseController,
os.rename( datasets_attrs_file_name, new_name )
datasets_attrs_file_name = new_name
- # Write temp file with all files to archive. These files are (a) history attributes file; (b) datasets attributes file; and (c)
- # datasets files.
- archive_list_file_name = tempfile.NamedTemporaryFile( dir=temp_output_dir ).name
- archive_list_out = open( archive_list_file_name, 'w' )
- archive_list_out.write( '%s\n' % history_attrs_file_name )
- archive_list_out.write( '%s\n' % datasets_attrs_file_name )
- for dataset in datasets:
- archive_list_out.write( '%s\n' % dataset.file_name )
- archive_list_out.close()
-
- # Use 'pax' to create compressed tar archive of history's datasets. -s options uses a regular expression to replace path
- # information.
- cmd = "pax -w -s ',.*history_attrs.txt,history_attrs.txt,' -s ',.*datasets_attrs.txt,datasets_attrs.txt,' -s ',/.*/,datasets/,' -x tar -z -f %s.tar.gz < %s" % ( trans.security.encode_id( history.id ), archive_list_file_name )
- temp_stderr_name = tempfile.NamedTemporaryFile( dir=temp_output_dir ).name
- temp_stderr = open( temp_stderr_name, 'wb' )
- proc = subprocess.Popen( args=cmd, shell=True, cwd=history_export_dir_name, stderr=temp_stderr.fileno() )
- returncode = proc.wait()
- temp_stderr.close()
+ # Write files to archive: (a) history attributes file; (b) datasets attributes file; and (c) datasets files.
+ history_archive_name = '%s/%s.tar.gz' % ( history_export_dir_name, trans.security.encode_id( history.id ) )
+ history_archive = tarfile.open( history_archive_name, "w:gz" )
+ history_archive.add( history_attrs_file_name, arcname="history_attrs.txt" )
+ history_archive.add( datasets_attrs_file_name, arcname="datasets_attrs.txt" )
+ for i, dataset in enumerate( datasets ) :
+ history_archive.add( dataset.file_name, arcname="datasets/%s" % datasets_attrs[i]['file_name'] )
+ history_archive.close()
# Remove temp directory.
if os.path.exists( temp_output_dir ):
@@ -652,14 +643,13 @@ class HistoryController( BaseController,
return trans.show_error_message( 'Error creating history archive. ' + str( e ) )
# Stream archive.
- archive_file_name = '%s/%s.tar.gz' % ( history_export_dir_name, trans.security.encode_id( history.id ) )
- if os.path.exists( archive_file_name ):
+ if os.path.exists( history_archive_name ):
valid_chars = '.,^_-()[]0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
hname = history.name
hname = ''.join(c in valid_chars and c or '_' for c in hname)[0:150]
trans.response.headers["Content-Disposition"] = "attachment; filename=Galaxy-History-%s.tar.gz" % ( hname )
trans.response.set_content_type( 'application/x-gzip' )
- return open( archive_file_name )
+ return open( history_archive_name )
else:
return
1
0
galaxy-dist commit d25af565d085: Bug fix for importing a history archive.
by commits-noreply@bitbucket.org 07 Jun '10
by commits-noreply@bitbucket.org 07 Jun '10
07 Jun '10
# HG changeset patch -- Bitbucket.org
# Project galaxy-dist
# URL http://bitbucket.org/galaxy/galaxy-dist/overview
# User jeremy goecks <jeremy.goecks(a)emory.edu>
# Date 1275599071 14400
# Node ID d25af565d085e19dccb8f20c857e633397e5da08
# Parent 170e2688d37043c9f1c4349f15d29ce6dd43e88b
Bug fix for importing a history archive.
--- a/lib/galaxy/web/controllers/history.py
+++ b/lib/galaxy/web/controllers/history.py
@@ -454,7 +454,7 @@ class HistoryController( BaseController,
# Security check: make sure that members are relative, not absolute.
for tarinfo in history_archive_file.getmembers():
- if tarinfo.name.startswith("/") or tarinfo.name.startswith(".."):
+ if tarinfo.name.startswith("/") or tarinfo.name.find("..") != -1:
return trans.show_error_message( 'Error importing history archive: archive file is invalid.' )
# Unpack archive in temporary directory.
1
0
galaxy-dist commit e4d2a5c24b05: Minor fix for changing datatype test.
by commits-noreply@bitbucket.org 07 Jun '10
by commits-noreply@bitbucket.org 07 Jun '10
07 Jun '10
# HG changeset patch -- Bitbucket.org
# Project galaxy-dist
# URL http://bitbucket.org/galaxy/galaxy-dist/overview
# User Dan Blankenberg <dan(a)bx.psu.edu>
# Date 1275586314 14400
# Node ID e4d2a5c24b05e164dc37918574d7078f07fc6b67
# Parent 6d218af7906af1f9524d02f785885bf1fd508f16
Minor fix for changing datatype test.
--- a/test/base/twilltestcase.py
+++ b/test/base/twilltestcase.py
@@ -626,7 +626,7 @@ class TwillTestCase( unittest.TestCase )
self.check_page_for_string( 'This will change the datatype of the existing dataset but' )
tc.fv( 'change_datatype', 'datatype', datatype )
tc.submit( 'change' )
- self.check_page_for_string( 'Edit Attributes' )
+ self.check_page_for_string( 'Changed the type of dataset' )
self.home()
def copy_history_item( self, source_dataset_ids='', target_history_ids=[], all_target_history_ids=[],
deleted_history_ids=[] ):
@@ -2080,4 +2080,3 @@ class TwillTestCase( unittest.TestCase )
def add_tag( self, item_id, item_class, context, new_tag, check_str='' ):
self.visit_url( "%s/tag/add_tag_async?item_id=%s&item_class=%s&context=%s&new_tag=%s" % \
( self.url, item_id, item_class, context, new_tag ) )
-
1
0
galaxy-dist commit 1dba26a363ab: Enhancements for the library dataset information page: display all metadata elements, and if in the admin view, display all undeleted history items and other undeleted library datasets that use the current library dataset's disk file.
by commits-noreply@bitbucket.org 07 Jun '10
by commits-noreply@bitbucket.org 07 Jun '10
07 Jun '10
# HG changeset patch -- Bitbucket.org
# Project galaxy-dist
# URL http://bitbucket.org/galaxy/galaxy-dist/overview
# User Greg Von Kuster <greg(a)bx.psu.edu>
# Date 1275503359 14400
# Node ID 1dba26a363abfb488b8021f3c86c75651fce81b0
# Parent ea2658d131b4c54fca14cdf2b5a66fbf128eaf40
Enhancements for the library dataset information page: display all metadata elements, and if in the admin view, display all undeleted history items and other undeleted library datasets that use the current library dataset's disk file.
--- a/templates/library/common/common.mako
+++ b/templates/library/common/common.mako
@@ -11,9 +11,9 @@
can_modify = trans.app.security_agent.can_modify_library_item( current_user_roles, item )
%>
%if widgets:
- <p/>
- <div class="toolForm">
- %if editable and ( cntrller=='library_admin' or trans.app.security_agent.can_modify_library_item( current_user_roles, item ) ):
+ %if editable and ( cntrller=='library_admin' or trans.app.security_agent.can_modify_library_item( current_user_roles, item ) ):
+ <p/>
+ <div class="toolForm"><div class="toolFormTitle">
%if inherited:
Other information <i>- this is an inherited template and is not required to be used with this ${item_type}</i>
@@ -54,20 +54,23 @@
</div></form></div>
- %else:
- <% contents = False %>
- %for i, field in enumerate( widgets ):
- %if field[ 'widget' ].value:
- <%
- contents = True
- break
- %>
- %endif
- %endfor
- %if contents:
- <div class="toolForm">
- <div class="toolFormTitle">Other information about ${item.name}</div>
- <div class="toolFormBody">
+ </div>
+ <p/>
+ %else:
+ <% contents = False %>
+ %for i, field in enumerate( widgets ):
+ %if field[ 'widget' ].value:
+ <%
+ contents = True
+ break
+ %>
+ %endif
+ %endfor
+ %if contents:
+ <p/>
+ <div class="toolForm">
+ <div class="toolFormTitle">Other information about ${item.name}</div>
+ <div class="toolFormBody">
%for i, field in enumerate( widgets ):
%if field[ 'widget' ].value:
<div class="form-row">
@@ -81,9 +84,10 @@
%endif
%endfor
</div>
- %endif
+ </div>
+ <p/>
%endif
- </div>
+ %endif
%endif
</%def>
--- a/lib/galaxy/web/controllers/library_common.py
+++ b/lib/galaxy/web/controllers/library_common.py
@@ -523,6 +523,20 @@ class LibraryCommon( BaseController ):
message=util.sanitize_text( message ),
status='error' ) )
library = trans.sa_session.query( trans.app.model.Library ).get( trans.security.decode_id( library_id ) )
+ if cntrller == 'library_admin':
+ # Get all associated hdas and lddas that use the same disk file.
+ associated_hdas = trans.sa_session.query( trans.model.HistoryDatasetAssociation ) \
+ .filter( and_( trans.model.HistoryDatasetAssociation.deleted == False,
+ trans.model.HistoryDatasetAssociation.dataset_id == ldda.dataset_id ) ) \
+ .all()
+ associated_lddas = trans.sa_session.query( trans.model.LibraryDatasetDatasetAssociation ) \
+ .filter( and_( trans.model.LibraryDatasetDatasetAssociation.deleted == False,
+ trans.model.LibraryDatasetDatasetAssociation.dataset_id == ldda.dataset_id,
+ trans.model.LibraryDatasetDatasetAssociation.id != ldda.id ) ) \
+ .all()
+ else:
+ associated_hdas = []
+ associated_lddas = []
# See if we have any associated templates
widgets = []
info_association, inherited = ldda.get_info_association()
@@ -534,6 +548,8 @@ class LibraryCommon( BaseController ):
use_panels=use_panels,
ldda=ldda,
library=library,
+ associated_hdas=associated_hdas,
+ associated_lddas=associated_lddas,
show_deleted=show_deleted,
widgets=widgets,
current_user_roles=current_user_roles,
@@ -702,15 +718,15 @@ class LibraryCommon( BaseController ):
if error:
status = 'error'
trans.response.send_redirect( web.url_for( controller='library_common',
- action='upload_library_dataset',
- cntrller=cntrller,
- library_id=library_id,
- folder_id=folder_id,
- replace_id=replace_id,
- upload_option=upload_option,
- show_deleted=show_deleted,
- message=util.sanitize_text( message ),
- status='error' ) )
+ action='upload_library_dataset',
+ cntrller=cntrller,
+ library_id=library_id,
+ folder_id=folder_id,
+ replace_id=replace_id,
+ upload_option=upload_option,
+ show_deleted=show_deleted,
+ message=util.sanitize_text( message ),
+ status='error' ) )
else:
# See if we have any inherited templates, but do not inherit contents.
@@ -722,13 +738,13 @@ class LibraryCommon( BaseController ):
template_id = 'None'
widgets = []
created_outputs_dict = trans.webapp.controllers[ 'library_common' ].upload_dataset( trans,
- cntrller=cntrller,
- library_id=library_id,
- folder_id=folder_id,
- template_id=template_id,
- widgets=widgets,
- replace_dataset=replace_dataset,
- **kwd )
+ cntrller=cntrller,
+ library_id=library_id,
+ folder_id=folder_id,
+ template_id=template_id,
+ widgets=widgets,
+ replace_dataset=replace_dataset,
+ **kwd )
if created_outputs_dict:
total_added = len( created_outputs_dict.keys() )
ldda_id_list = [ str( v.id ) for k, v in created_outputs_dict.items() ]
@@ -1094,6 +1110,8 @@ class LibraryCommon( BaseController ):
library = trans.sa_session.query( trans.app.model.Library ).get( trans.security.decode_id( library_id ) )
roles = trans.app.security_agent.get_legitimate_roles( trans, library, cntrller )
return trans.fill_template( "/library/common/upload.mako",
+ action='add_history_datasets_to_library',
+ cntrller=cntrller,
upload_option=upload_option,
library_id=library_id,
folder_id=folder_id,
@@ -1877,9 +1895,24 @@ def activatable_folders_and_lddas( trans
.all()
return folders, lddas
def branch_deleted( folder ):
- # Return True if a folder belongs to a branc that has been deleted
+ # Return True if a folder belongs to a branch that has been deleted
if folder.deleted:
return True
if folder.parent:
return branch_deleted( folder.parent )
return False
+def get_containing_library_from_library_dataset( trans, library_dataset ):
+ """Given a library_dataset, get the containing library"""
+ folder = library_dataset.folder
+ parent = folder
+ while folder.parent:
+ parent = folder.parent
+ # We have parent set to the library's root folder, which has the
+ # same name as the library
+ for library in trans.sa_session.query( trans.model.Library ) \
+ .filter( and_( trans.model.Library.table.c.deleted == False,
+ trans.model.Library.table.c.name == parent.name ) ):
+ if library.root_folder == parent:
+ return library
+ return None
+
--- a/templates/library/common/ldda_info.mako
+++ b/templates/library/common/ldda_info.mako
@@ -3,7 +3,8 @@
<%namespace file="/library/common/common.mako" import="render_template_info" /><%
from galaxy import util
- from galaxy.web.controllers.library_common import branch_deleted
+ from galaxy.web.controllers.library_common import branch_deleted, get_containing_library_from_library_dataset
+ from galaxy.web.framework.helpers import time_ago
if ldda == ldda.library_dataset.library_dataset_dataset_association:
current_version = True
@@ -64,11 +65,13 @@
%endif
</div><div class="toolFormBody">
- <div class="form-row">
- <label>Message:</label>
- <pre>${ldda.message}</pre>
- <div style="clear: both"></div>
- </div>
+ %if ldda.message:
+ <div class="form-row">
+ <label>Message:</label>
+ <pre>${ldda.message}</pre>
+ <div style="clear: both"></div>
+ </div>
+ %endif
<div class="form-row"><label>Uploaded by:</label>
${uploaded_by}
@@ -80,6 +83,11 @@
<div style="clear: both"></div></div><div class="form-row">
+ <label>File size:</label>
+ ${ldda.get_size( nice_size=True )}
+ <div style="clear: both"></div>
+ </div>
+ <div class="form-row"><label>Data type:</label>
${ldda.ext}
<div style="clear: both"></div>
@@ -97,6 +105,20 @@
<div class="form-row"><div>${ldda.blurb}</div></div>
+ %for name, spec in ldda.metadata.spec.items():
+ <div class="form-row">
+ <label>${spec.desc.replace( ' (click box & select)', '' )}:</label>
+ <%
+ metadata_val = ldda.metadata.get( name )
+ if isinstance( metadata_val, trans.model.MetadataFile ):
+ metadata_val = metadata_val.file_name
+ elif isinstance( metadata_val, list ):
+ metadata_val = ', '.join( metadata_val )
+ %>
+ ${metadata_val}
+ <div style="clear: both"></div>
+ </div>
+ %endfor
%if ldda.peek != "no peek":
<div class="form-row"><div id="info${ldda.id}" class="historyItemBody">
@@ -110,6 +132,79 @@
%if widgets:
${render_template_info( cntrller=cntrller, item_type='ldda', library_id=library_id, widgets=widgets, info_association=info_association, inherited=inherited, folder_id=trans.security.encode_id( ldda.library_dataset.folder.id ), ldda_id=trans.security.encode_id( ldda.id ), editable=False )}
%endif
+%if cntrller == 'library_admin':
+ %if associated_hdas:
+ <p/>
+ <b>History items that use this library dataset's disk file</b>
+ <div class="toolForm">
+ <table class="grid">
+ <thead>
+ <tr>
+ <th>History</th>
+ <th>History Item</th>
+ <th>Last Updated</th>
+ <th>User</th>
+ </tr>
+ </thead>
+ %for hda in associated_hdas:
+ <tr>
+ <td><a target="_blank" href="${h.url_for( controller='history', action='view', id=trans.security.encode_id( hda.history.id ) )}">${hda.history.get_display_name()}</a></td>
+ <td>${hda.get_display_name()}</td>
+ <td>${time_ago( hda.update_time )}</td>
+ <td>
+ %if hda.history.user:
+ ${hda.history.user.email}
+ %else:
+ anonymous
+ %endif
+ </td>
+ </tr>
+ %endfor
+ </table>
+ </div>
+ <p/>
+ %endif
+ %if associated_lddas:
+ <p/>
+ <b>Other library datasets that use this library dataset's disk file</b>
+ <div class="toolForm">
+ <table class="grid">
+ <thead>
+ <tr>
+ <th>Library</th>
+ <th>Library Folder</th>
+ <th>Library Dataset</th>
+ <th>Last Updated</th>
+ <th>User</th>
+ </tr>
+ </thead>
+ %for copied_ldda in associated_lddas:
+ <% containing_library = get_containing_library_from_library_dataset( trans, copied_ldda.library_dataset ) %>
+ <tr>
+ <td>
+ %if containing_library:
+ <a href="${h.url_for( controller='library_common', action='browse_library', id=trans.security.encode_id( containing_library.id ), cntrller=cntrller, use_panels=use_panels )}">${containing_library.get_display_name()}</a>
+ %else:
+ error finding library
+ %endif
+ </td>
+ <td>${copied_ldda.library_dataset.folder.get_display_name()}</td>
+ <td>${copied_ldda.get_display_name()}</td>
+ <td>${time_ago( copied_ldda.update_time )}</td>
+ <td>
+ %if copied_ldda.user:
+ ${copied_ldda.user.email}
+ %else:
+ anonymous
+ %endif
+ </td>
+ </tr>
+ %endfor
+ </table>
+ </div>
+ <p/>
+ %endif
+%endif
%if current_version:
<% expired_lddas = [ e_ldda for e_ldda in ldda.library_dataset.expired_datasets ] %>
%if expired_lddas:
1
0
galaxy-dist commit a12eeed213ff: Resync Annotation Profiler tests to current cached data.
by commits-noreply@bitbucket.org 07 Jun '10
by commits-noreply@bitbucket.org 07 Jun '10
07 Jun '10
# HG changeset patch -- Bitbucket.org
# Project galaxy-dist
# URL http://bitbucket.org/galaxy/galaxy-dist/overview
# User Dan Blankenberg <dan(a)bx.psu.edu>
# Date 1275511239 14400
# Node ID a12eeed213ff6d8581073ad77914b12dfc26f9bd
# Parent 1dba26a363abfb488b8021f3c86c75651fce81b0
Resync Annotation Profiler tests to current cached data.
--- a/test-data/annotation_profiler_1.out
+++ b/test-data/annotation_profiler_1.out
@@ -1,8 +1,8 @@
chr22 30128507 31828507 uc003bnx.1_cds_2_0_chr22_29227_f 0 + multiz17way 1700000 1
-chr22 30128507 31828507 uc003bnx.1_cds_2_0_chr22_29227_f 0 + knownAlt 14617 57
+chr22 30128507 31828507 uc003bnx.1_cds_2_0_chr22_29227_f 0 + mrna 1476531 12
chr22 30128507 31828507 uc003bnx.1_cds_2_0_chr22_29227_f 0 + multiz28way 1700000 1
chr22 30128507 31828507 uc003bnx.1_cds_2_0_chr22_29227_f 0 + refGene 1247808 15
-chr22 30128507 31828507 uc003bnx.1_cds_2_0_chr22_29227_f 0 + mrna 1476531 12
+chr22 30128507 31828507 uc003bnx.1_cds_2_0_chr22_29227_f 0 + knownAlt 14617 57
chr22 30128507 31828507 uc003bnx.1_cds_2_0_chr22_29227_f 0 + affyGnf1h 16218 2
chr22 30128507 31828507 uc003bnx.1_cds_2_0_chr22_29227_f 0 + snp126 8224 7262
chr22 30128507 31828507 uc003bnx.1_cds_2_0_chr22_29227_f 0 + acembly 1532618 20
--- a/tools/annotation_profiler/annotation_profiler.xml
+++ b/tools/annotation_profiler/annotation_profiler.xml
@@ -27,14 +27,14 @@
<param name="input1" value="4.bed" dbkey="hg18"/><param name="keep_empty" value=""/><param name="summary" value=""/>
- <param name="table_names" value="acembly,affyGnf1h,affyHuEx1,knownAlt,knownGene,mrna,multiz17way,multiz28way,refGene,snp126"/>
+ <param name="table_names" value="acembly,affyGnf1h,knownAlt,knownGene,mrna,multiz17way,multiz28way,refGene,snp126"/><output name="out_file1" file="annotation_profiler_1.out" /></test><test><param name="input1" value="3.bed" dbkey="hg18"/><param name="keep_empty" value=""/><param name="summary" value="Summary"/>
- <param name="table_names" value="acembly,affyGnf1h,affyHuEx1,knownAlt,knownGene,mrna,multiz17way,multiz28way,refGene,snp126"/>
+ <param name="table_names" value="acembly,affyGnf1h,knownAlt,knownGene,mrna,multiz17way,multiz28way,refGene,snp126"/><output name="out_file1" file="annotation_profiler_2.out" /></test></tests>
--- a/test-data/annotation_profiler_2.out
+++ b/test-data/annotation_profiler_2.out
@@ -1,9 +1,9 @@
#tableName tableChromosomeCoverage tableChromosomeCount tableRegionCoverage tableRegionCount allIntervalCount allIntervalSize allCoverage allTableRegionsOverlaped allIntervalsOverlapingTable nrIntervalCount nrIntervalSize nrCoverage nrTableRegionsOverlaped nrIntervalsOverlapingTable
multiz17way 1232617592 115 107496500 7 25 2178864 2178864 25 25 24 2178828 2178828 7 24
-knownAlt 8647368 20213 766619 1630 25 2178864 5612 31 11 24 2178828 5612 31 11
+mrna 610115393 8453 53577685 617 25 2178864 1904380 38 24 24 2178828 1904344 33 23
multiz28way 1233785185 143 107466479 10 25 2178864 2178864 25 25 24 2178828 2178828 8 24
refGene 496767116 7324 46112187 488 25 2178864 1677947 30 23 24 2178828 1677911 27 22
-mrna 610115393 8453 53577685 617 25 2178864 1904380 38 24 24 2178828 1904344 33 23
+knownAlt 8647368 20213 766619 1630 25 2178864 5612 31 11 24 2178828 5612 31 11
affyGnf1h 24034558 3995 2446754 307 25 2178864 191851 9 6 24 2178828 191851 9 6
snp126 5297125 4456213 382226 331523 25 2178864 9205 7074 25 24 2178828 9205 7074 24
acembly 710938193 13800 63146381 938 25 2178864 1903560 35 24 24 2178828 1903524 30 23
1
0