galaxy-commits
Threads by month
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- 15302 discussions
galaxy-dist commit 4187ae2fdb9e: Improved error handling in api methods.
by commits-noreply@bitbucket.org 20 Nov '10
by commits-noreply@bitbucket.org 20 Nov '10
20 Nov '10
# HG changeset patch -- Bitbucket.org
# Project galaxy-dist
# URL http://bitbucket.org/galaxy/galaxy-dist/overview
# User rc
# Date 1289186302 18000
# Node ID 4187ae2fdb9e3f8b7ff5878e7517a24868b8ffca
# Parent dcc68da403f0e8d3ae0da07529ff96327ca05489
Improved error handling in api methods.
--- a/scripts/api/common.py
+++ b/scripts/api/common.py
@@ -48,6 +48,13 @@ def put( api_key, url, data ):
req.get_method = lambda: 'PUT'
return simplejson.loads( urllib2.urlopen( req ).read() )
+def __del( api_key, url, data ):
+ # Do the actual DELETE
+ url = make_url( api_key, url )
+ req = urllib2.Request( url, headers = { 'Content-Type': 'application/json' }, data = simplejson.dumps( data ))
+ req.get_method = lambda: 'DELETE'
+ return simplejson.loads( urllib2.urlopen( req ).read() )
+
def display( api_key, url, return_formatted=True ):
# Sends an API GET request and acts as a generic formatter for the JSON response.
@@ -89,12 +96,12 @@ def submit( api_key, url, data, return_f
try:
r = post( api_key, url, data )
except urllib2.HTTPError, e:
- print e
- print e.read( 1024 )
if return_formatted:
+ print e
+ print e.read( 1024 )
sys.exit( 1 )
else:
- return 'Error. '+ str( e )
+ return 'Error. '+ str( e.read( 1024 ) )
if not return_formatted:
return r
print 'Response'
@@ -123,30 +130,35 @@ def update( api_key, url, data, return_f
try:
r = put( api_key, url, data )
except urllib2.HTTPError, e:
- print e
- print e.read( 1024 )
- sys.exit( 1 )
+ if return_formatted:
+ print e
+ print e.read( 1024 )
+ sys.exit( 1 )
+ else:
+ return 'Error. '+ str( e.read( 1024 ) )
if not return_formatted:
return r
print 'Response'
print '--------'
- if type( r ) == list:
- # Currently the only implemented responses are lists of dicts, because
- # submission creates some number of collection elements.
- for i in r:
- if type( i ) == dict:
- if 'url' in i:
- print i.pop( 'url' )
- else:
- print '----'
- if 'name' in i:
- print ' name: %s' % i.pop( 'name' )
- for k, v in i.items():
- print ' %s: %s' % ( k, v )
- else:
- print i
- else:
- print r
+ print r
+
+def delete( api_key, url, data, return_formatted=True ):
+ # Sends an API DELETE request and acts as a generic formatter for the JSON response.
+ # 'data' will become the JSON payload read by Galaxy.
+ try:
+ r = __del( api_key, url, data )
+ except urllib2.HTTPError, e:
+ if return_formatted:
+ print e
+ print e.read( 1024 )
+ sys.exit( 1 )
+ else:
+ return 'Error. '+ str( e.read( 1024 ) )
+ if not return_formatted:
+ return r
+ print 'Response'
+ print '--------'
+ print r
# utility method to encode ID's
def encode_id( config_id_secret, obj_id ):
--- a/scripts/galaxy_messaging/server/amqp_consumer.py
+++ b/scripts/galaxy_messaging/server/amqp_consumer.py
@@ -95,7 +95,7 @@ def update_request( api_key, request_id
try:
retval = api.update( api_key, url, data, return_formatted=False )
log.debug( str( retval ) )
- except urllib2.URLError, e:
+ except Exception, e:
log.debug( 'ERROR(update_request (%s)): %s' % ( str((self.api_key, url, data)), str(e) ) )
def recv_callback( message ):
--- a/lib/galaxy/web/controllers/requests_admin.py
+++ b/lib/galaxy/web/controllers/requests_admin.py
@@ -662,7 +662,7 @@ class RequestsAdmin( BaseController, Use
except Exception, e:
err_msg = "Error in sending the data transfer message to the Galaxy AMQP message queue:<br/>%s" % str(e)
if not err_msg:
- message = "%i datasets have been queued for transfer from the sequencer. Click the Refresh button above to monitor the transfer status." % len( selected_sample_datasets )
+ err_msg = "%i datasets have been queued for transfer from the sequencer. Click the Refresh button above to monitor the transfer status." % len( selected_sample_datasets )
status = "done"
else:
status = 'error'
@@ -670,7 +670,7 @@ class RequestsAdmin( BaseController, Use
action='manage_datasets',
sample_id=trans.security.encode_id( sample.id ),
status=status,
- message=message ) )
+ message=err_msg ) )
@web.expose
def update_sample_dataset_status(self, trans, cntrller, sample_dataset_ids, new_status, error_msg=None ):
# check if the new status is a valid transfer status
1
0
galaxy-dist commit dcc68da403f0: Fix for failing rgManQQ functional test - changed R outputs. cut down size of default png - much faster...
by commits-noreply@bitbucket.org 20 Nov '10
by commits-noreply@bitbucket.org 20 Nov '10
20 Nov '10
# HG changeset patch -- Bitbucket.org
# Project galaxy-dist
# URL http://bitbucket.org/galaxy/galaxy-dist/overview
# User Ross Lazarus <ross.lazarus(a)gmail.com>
# Date 1289178885 18000
# Node ID dcc68da403f0e8d3ae0da07529ff96327ca05489
# Parent 74620fac33c74b60c0a2faa69364dea0115e8815
Fix for failing rgManQQ functional test - changed R outputs. cut down size of default png - much faster...
Binary file test-data/rgtestouts/rgManQQ/Allelep_manhattan.png has changed
--- a/tools/rgenetics/rgManQQ.py
+++ b/tools/rgenetics/rgManQQ.py
@@ -6,6 +6,7 @@ from rgutils import timenow, RRun, galht
progname = os.path.split(sys.argv[0])[1]
myversion = 'V000.1 March 2010'
verbose = False
+debug = False
rcode="""
# license not stated so I'm assuming LGPL is ok for my derived work?
@@ -156,7 +157,7 @@ if (plen > 0) {
mytitle = paste('p=',cname,', ',title,sep='')
myfname = chartr(' ','_',cname)
myqqplot = qq(rawd[,pvalscolumn],title=mytitle)
- ggsave(filename=paste(myfname,"qqplot.png",sep='_'),myqqplot,width=11,height=8,dpi=100)
+ ggsave(filename=paste(myfname,"qqplot.png",sep='_'),myqqplot,width=6,height=4,dpi=100)
print(paste('## qqplot on',cname,'done'))
if ((chromcolumn > 0) & (offsetcolumn > 0)) {
if (doreorder) {
@@ -168,7 +169,7 @@ if (plen > 0) {
print(paste('## manhattan on',cname,'starting',chromcolumn,offsetcolumn,pvalscolumn))
mymanplot= manhattan(chrom=rawd[,chromcolumn],offset=rawd[,offsetcolumn],pvals=rawd[,pvalscolumn],title=mytitle,grey=grey)
print(paste('## manhattan plot on',cname,'done'))
- ggsave(filename=paste(myfname,"manhattan.png",sep='_'),mymanplot,width=11,height=8,dpi=100)
+ ggsave(filename=paste(myfname,"manhattan.png",sep='_'),mymanplot,width=6,height=4,dpi=100)
}
else {
print(paste('chrom column =',chromcolumn,'offset column = ',offsetcolumn,
@@ -196,6 +197,8 @@ def doManQQ(input_fname,chrom_col,offset
to make them do our bidding - and save the resulting code for posterity
this can be called externally, I guess...for QC eg?
"""
+ if debug:
+ print 'doManQQ',input_fname,chrom_col,offset_col,pval_cols,title,grey,ctitle,outdir
ffd,filtered_fname = tempfile.mkstemp(prefix='rgManQQtemp')
f = open(filtered_fname,'w')
inf = open(input_fname,'r')
@@ -232,6 +235,8 @@ def doManQQ(input_fname,chrom_col,offset
pvc = [x+3 for x in range(len(pval_cols))] # 2 for offset and chrom, 1 for r offset start
pvc = 'c(%s)' % (','.join(map(str,pvc)))
rcmd = '%s%s' % (rcode,rcode2 % (filtered_fname,'1','2',pvc,title,grey))
+ if debug:
+ print 'running\n%s\n' % rcmd
rlog,flist = RRun(rcmd=rcmd,title=ctitle,outdir=outdir)
rlog.append('## R script=')
rlog.append(rcmd)
--- a/test-data/rgtestouts/rgManQQ/rgManQQtest1.R
+++ b/test-data/rgtestouts/rgManQQ/rgManQQtest1.R
@@ -124,7 +124,7 @@ qq = function(pvector, title=NULL, spart
if (spartan) plot=plot+opts(panel.background=theme_rect(col="grey50"), panel.grid.minor=theme_blank())
qq
}
-rgqqMan = function(infile="/tmp/rgManQQtempcWfFkc",chromcolumn=1, offsetcolumn=2, pvalscolumns=c(3),
+rgqqMan = function(infile="/tmp/rgManQQtemplYC5wa",chromcolumn=1, offsetcolumn=2, pvalscolumns=c(3),
title="rgManQQtest1",grey=0) {
rawd = read.table(infile,head=T,sep='\t')
dn = names(rawd)
@@ -142,7 +142,7 @@ if (plen > 0) {
mytitle = paste('p=',cname,', ',title,sep='')
myfname = chartr(' ','_',cname)
myqqplot = qq(rawd[,pvalscolumn],title=mytitle)
- ggsave(filename=paste(myfname,"qqplot.png",sep='_'),myqqplot,width=11,height=8,dpi=100)
+ ggsave(filename=paste(myfname,"qqplot.png",sep='_'),myqqplot,width=6,height=4,dpi=100)
print(paste('## qqplot on',cname,'done'))
if ((chromcolumn > 0) & (offsetcolumn > 0)) {
if (doreorder) {
@@ -154,7 +154,7 @@ if (plen > 0) {
print(paste('## manhattan on',cname,'starting',chromcolumn,offsetcolumn,pvalscolumn))
mymanplot= manhattan(chrom=rawd[,chromcolumn],offset=rawd[,offsetcolumn],pvals=rawd[,pvalscolumn],title=mytitle,grey=grey)
print(paste('## manhattan plot on',cname,'done'))
- ggsave(filename=paste(myfname,"manhattan.png",sep='_'),mymanplot,width=11,height=8,dpi=100)
+ ggsave(filename=paste(myfname,"manhattan.png",sep='_'),mymanplot,width=6,height=4,dpi=100)
}
else {
print(paste('chrom column =',chromcolumn,'offset column = ',offsetcolumn,
@@ -171,4 +171,4 @@ if (plen > 0) {
rgqqMan()
# execute with defaults as substituted
-#R script autogenerated by rgenetics/rgutils.py on 18/09/2010 20:46:49
+#R script autogenerated by rgenetics/rgutils.py on 07/11/2010 20:03:37
--- a/test-data/rgtestouts/rgManQQ/rgManQQtest1.html
+++ b/test-data/rgtestouts/rgManQQ/rgManQQtest1.html
@@ -43,7 +43,7 @@ Loading required package: grid
Loading required package: proto
-[1] "### 101 values read from /tmp/rgManQQtempcWfFkc read - now running plots"
+[1] "### 101 values read from /tmp/rgManQQtemplYC5wa read - now running plots"
[1] "## qqplot on Allelep done"
@@ -178,7 +178,7 @@ qq = function(pvector, title=NULL, spart
if (spartan) plot=plot+opts(panel.background=theme_rect(col="grey50"), panel.grid.minor=theme_blank())
qq
}
-rgqqMan = function(infile="/tmp/rgManQQtempcWfFkc",chromcolumn=1, offsetcolumn=2, pvalscolumns=c(3),
+rgqqMan = function(infile="/tmp/rgManQQtemplYC5wa",chromcolumn=1, offsetcolumn=2, pvalscolumns=c(3),
title="rgManQQtest1",grey=0) {
rawd = read.table(infile,head=T,sep='\t')
dn = names(rawd)
@@ -196,7 +196,7 @@ if (plen > 0) {
mytitle = paste('p=',cname,', ',title,sep='')
myfname = chartr(' ','_',cname)
myqqplot = qq(rawd[,pvalscolumn],title=mytitle)
- ggsave(filename=paste(myfname,"qqplot.png",sep='_'),myqqplot,width=11,height=8,dpi=100)
+ ggsave(filename=paste(myfname,"qqplot.png",sep='_'),myqqplot,width=6,height=4,dpi=100)
print(paste('## qqplot on',cname,'done'))
if ((chromcolumn > 0) & (offsetcolumn > 0)) {
if (doreorder) {
@@ -208,7 +208,7 @@ if (plen > 0) {
print(paste('## manhattan on',cname,'starting',chromcolumn,offsetcolumn,pvalscolumn))
mymanplot= manhattan(chrom=rawd[,chromcolumn],offset=rawd[,offsetcolumn],pvals=rawd[,pvalscolumn],title=mytitle,grey=grey)
print(paste('## manhattan plot on',cname,'done'))
- ggsave(filename=paste(myfname,"manhattan.png",sep='_'),mymanplot,width=11,height=8,dpi=100)
+ ggsave(filename=paste(myfname,"manhattan.png",sep='_'),mymanplot,width=6,height=4,dpi=100)
}
else {
print(paste('chrom column =',chromcolumn,'offset column = ',offsetcolumn,
@@ -227,6 +227,6 @@ rgqqMan()
</pre>
-<h3><a href="http://rgenetics.org">Rgenetics</a> tool rgManQQ.py run at 18/09/2010 20:48:26</h3>
+<h3><a href="http://rgenetics.org">Rgenetics</a> tool rgManQQ.py run at 07/11/2010 20:04:20</h3></div></body></html>
--- a/tools/rgenetics/rgManQQ.xml
+++ b/tools/rgenetics/rgManQQ.xml
@@ -42,7 +42,7 @@
<param name='chrom_col' value='1' /><param name='offset_col' value='2' /><param name='grey' value='0' />
- <output name='out_html' file='rgtestouts/rgManQQ/rgManQQtest1.html' ftype='html' lines_diff='40'>
+ <output name='out_html' file='rgtestouts/rgManQQ/rgManQQtest1.html' ftype='html' lines_diff='60'><extra_files type="file" name='Allelep_manhattan.png' value='rgtestouts/rgManQQ/Allelep_manhattan.png' compare="sim_size"
delta = "10000"/><extra_files type="file" name='Allelep_qqplot.png' value='rgtestouts/rgManQQ/Allelep_qqplot.png' compare="sim_size"
Binary file test-data/rgtestouts/rgManQQ/Allelep_qqplot.png has changed
1
0
galaxy-dist commit fb55bfc792b1: Trackster UI tweaks, mainly moving the navigation to the top, still needs to be compressed and cleaned up. Also, getting borders and spacing a little more even. Some intial keyboard navigation
by commits-noreply@bitbucket.org 20 Nov '10
by commits-noreply@bitbucket.org 20 Nov '10
20 Nov '10
# HG changeset patch -- Bitbucket.org
# Project galaxy-dist
# URL http://bitbucket.org/galaxy/galaxy-dist/overview
# User James Taylor <james(a)jamestaylor.org>
# Date 1289163413 18000
# Node ID fb55bfc792b1d087783055a736d9fb439e5bb41c
# Parent d46ccc650084224553b3b48c11df64d43d7673ef
Trackster UI tweaks, mainly moving the navigation to the top, still needs to be compressed and cleaned up. Also, getting borders and spacing a little more even. Some intial keyboard navigation
--- a/templates/tracks/browser.mako
+++ b/templates/tracks/browser.mako
@@ -15,8 +15,8 @@
${h.css( "history", "autocomplete_tagging", "trackster", "overcast/jquery-ui-1.8.5.custom" )}
<style type="text/css">
- #center {
- overflow: auto;
+ #center, #browser-container {
+ overflow: none;
}
ul#sortable-ul {
list-style: none;
@@ -29,10 +29,7 @@
background: #eee;
}
.nav-container {
- position: fixed;
width: 100%;
- left: 0;
- bottom: 0;
}
# Styles for filters.
.filter-name {
@@ -57,6 +54,7 @@
<a id="add-track" class="panel-header-button right-float" href="javascript:void(0);">Add Tracks</a></div></div>
+<div id="browser-container" class="unified-panel-body"></div></%def>
@@ -79,7 +77,7 @@
$(function() {
%if config:
- view = new View( $("#center"), "${config.get('title') | h}", "${config.get('vis_id')}", "${config.get('dbkey')}" );
+ view = new View( $("#browser-container"), "${config.get('title') | h}", "${config.get('vis_id')}", "${config.get('dbkey')}" );
view.editor = true;
%for track in config.get('tracks'):
view.add_track(
@@ -215,6 +213,16 @@
error: function() { alert("Could not save visualization"); }
});
});
+
+ $(document).keydown( function( e ) {
+ // 37 == left
+ if ( e.which == 39 ) {
+ view.move_fraction( -0.25 );
+ // 39 == right
+ } else if ( e.which == 37 ) {
+ view.move_fraction( 0.25 );
+ }
+ });
};
});
--- a/static/scripts/trackster.js
+++ b/static/scripts/trackster.js
@@ -103,15 +103,25 @@ var View = function( container, title, v
// Create DOM elements
var parent_element = this.container,
view = this;
- this.top_labeltrack = $("<div/>").addClass("top-labeltrack").appendTo(parent_element);
+ // Top container for things that are fixed at the top
+ this.top_container = $("<div/>").addClass("top-container").appendTo(parent_element);
+ // Content container, primary tracks are contained in here
this.content_div = $("<div/>").addClass("content").css("position", "relative").appendTo(parent_element);
+ // Bottom container for things that are fixed at the bottom
+ this.bottom_container = $("<div/>").addClass("bottom-container").appendTo(parent_element);
+ // Label track fixed at top
+ this.top_labeltrack = $("<div/>").addClass("top-labeltrack").appendTo(this.top_container);
+ // Viewport for dragging tracks in center
this.viewport_container = $("<div/>").addClass("viewport-container").addClass("viewport-container").appendTo(this.content_div);
- this.intro_div = $("<div/>").addClass("intro").text("Select a chrom from the dropdown below").hide(); // Future overlay
-
- this.nav_container = $("<div/>").addClass("nav-container").appendTo(parent_element);
- this.nav_labeltrack = $("<div/>").addClass("nav-labeltrack").appendTo(this.nav_container);
+ // Future overlay?
+ this.intro_div = $("<div/>").addClass("intro").text("Select a chrom from the dropdown below").hide();
+ // Another label track at bottom
+ this.nav_labeltrack = $("<div/>").addClass("nav-labeltrack").appendTo(this.bottom_container);
+ // Navigation at top
+ this.nav_container = $("<div/>").addClass("nav-container").prependTo(this.top_container);
this.nav = $("<div/>").addClass("nav").appendTo(this.nav_container);
- this.overview = $("<div/>").addClass("overview").appendTo(this.nav);
+ // Overview (scrollbar and overview plot) at bottom
+ this.overview = $("<div/>").addClass("overview").appendTo(this.bottom_container);
this.overview_viewport = $("<div/>").addClass("overview-viewport").appendTo(this.overview);
this.overview_close = $("<a href='javascript:void(0);'>Close Overview</a>").addClass("overview-close").hide().appendTo(this.overview_viewport);
this.overview_highlight = $("<div />").addClass("overview-highlight").hide().appendTo(this.overview_viewport);
@@ -327,6 +337,11 @@ var View = function( container, title, v
}
view.change_chrom(chrom, new_low, new_high);
},
+ move_fraction : function( fraction ) {
+ var view = this;
+ var span = view.high - view.low;
+ this.move_delta( fraction * span );
+ },
move_delta: function(delta_chrom) {
var view = this;
var current_chrom_span = view.high - view.low;
@@ -439,7 +454,7 @@ var View = function( container, title, v
this.redraw();
},
resize_window: function() {
- this.viewport_container.height( this.container.height() - this.nav_container.height() - 45 );
+ this.viewport_container.height( this.container.height() - this.top_container.height() - this.bottom_container.height() );
this.nav_container.width( this.container.width() );
this.redraw();
},
--- a/static/june_2007_style/blue/trackster.css
+++ b/static/june_2007_style/blue/trackster.css
@@ -1,7 +1,7 @@
.viewport-container{overflow-x:hidden;overflow-y:auto;}
-.nav{padding:0 0;color:#333;font-weight:bold;}
-.content{font:9px verdana;}
-.nav-controls{text-align:center;position:relative;background:#cccccc;background-image:url(panel_header_bg.png);background-position:top center;background-repeat:repeat-x;padding:2px 0;}
+.nav{padding:0 0;color:#333;font-weight:bold;background:#cccccc;background-image:url(panel_header_bg.png);background-position:bottom center;background-repeat:repeat-x;height:2.5em;border-bottom:solid #333 1px;}
+.content{font:10px verdana;}
+.nav-controls{text-align:center;position:relative;padding:2px 0;}
.nav-controls input{margin:0 5px;}
.nav-controls a{padding:0 0.4em;}
.nav-input{font-size:12px;width:30em;z-index:1000;}
@@ -9,24 +9,23 @@
.draghandle{cursor:move;float:left;background:transparent url(../images/visualization/draggable_horizontal.png) center center no-repeat;width:10px;height:12px;}
.intro{z-index:1000;margin-left:auto;margin-right:auto;color:#555;text-align:center;font-size:16px;}
.overview{width:100%;margin:0px;color:white;}
-.overview-viewport{position:relative;height:14px;background:white;border-bottom:solid gray 1px;margin:0;}
+.overview-viewport{position:relative;height:14px;background:white;margin:0;}
.overview-close{font:9px verdana;position:absolute;top:0px;right:0px;padding:5px;z-index:500;background-color:white;}
-.overview-highlight{opacity:0.5;top:0px;position:absolute;z-index:100;border-style:solid;border-color:#484848;border-width:0px 1px;}
-.overview-boxback{width:100%;bottom:0px;z-index:50;position:absolute;height:14px;background:#eee;}
-.overview-box{cursor:pointer;opacity:0.5;bottom:0px;z-index:100;position:absolute;margin-top:0px;height:14px;background:#484848 url(../images/visualization/draggable_horizontal.png) center center no-repeat;border-style:solid;border-color:#484848;border-width:0px 1px;-moz-border-radius:3px;border-radius:3px;}
-.overview-box:hover{background-color:#838383;border-color:#838383;}
+.overview-highlight{top:0px;position:absolute;z-index:100;border-style:solid;border-color:#666;border-width:0px 1px;}
+.overview-boxback{width:100%;bottom:0px;z-index:50;position:absolute;height:14px;background:#eee;border:solid #999 1px;}
+.overview-box{cursor:pointer;bottom:0px;z-index:100;position:absolute;margin-top:0px;height:14px;background:#C1C9E5 url(../images/visualization/draggable_horizontal.png) center center no-repeat;border:solid #666 1px;}
.viewport-canvas{width:100%;height:100px;}
.yaxislabel{color:#777;z-index:100;}
.line-track .track-content{border-top:1px solid #ddd;border-bottom:1px solid #ddd;}
-.track{background:white;margin-bottom:1px;}
+.track{background:white;margin-bottom:1px;padding-bottom:4px;border-bottom:#eee solid 1px;}
.track-header{text-align:left;padding:4px 0px;color:#666;}
.track-header .menubutton{margin-left:3px;}
.track-content{overflow:hidden;text-align:center;}
-.track.error{background-color:#ECB4AF;}
-.track.nodata{background-color:#ddd;}
+.track.error .track-content{background-color:#ECB4AF;}
+.track.nodata .track-content{background-color:#ddd;}
.loading{min-height:100px;}
-.label-track{}
-.label-track .label{border-left:solid #999 1px;padding:1px;display:inline-block;}
+.label-track{font-size:10px;border:none;padding:0;margin:0;height:1.3em;}
+.label-track .label{border-left:solid #999 1px;padding:1px;padding-bottom:2px;display:inline-block;}
.right-float{float:right;margin-left:5px;}
.top-labeltrack{position:relative;border-bottom:solid #999 1px;}
-.nav-labeltrack{border-top:solid #999 1px;border-bottom:solid #999 1px;}
+.nav-labeltrack{border-top:solid #999 1px;border-bottom:solid #333 1px;}
--- a/static/june_2007_style/trackster.css.tmpl
+++ b/static/june_2007_style/trackster.css.tmpl
@@ -5,17 +5,19 @@
.nav {
padding: 0 0;
color:#333;font-weight:bold;
+ background:#cccccc;
+ background-image:url(panel_header_bg.png);
+ background-position: bottom center;
+ background-repeat:repeat-x;
+ height: 2.5em;
+ border-bottom: solid #333 1px;
}
.content {
- font: 9px verdana;
+ font: 10px verdana;
}
.nav-controls {
text-align: center;
position: relative;
- background:#cccccc;
- background-image:url(panel_header_bg.png);
- background-position:top center;
- background-repeat:repeat-x;
padding: 2px 0;
}
.nav-controls input {
@@ -61,7 +63,6 @@
/* border-top: solid #666 1px;*/
/* border-bottom: solid #aaa 1px;*/
background: white;
- border-bottom: solid gray 1px;
margin: 0;
}
.overview-close {
@@ -74,12 +75,11 @@
background-color: white;
}
.overview-highlight {
- opacity: 0.5;
top: 0px;
position: absolute;
z-index: 100;
border-style: solid;
- border-color: #484848;
+ border-color: #666;
border-width: 0px 1px;
}
.overview-boxback {
@@ -89,25 +89,17 @@
position: absolute;
height: 14px;
background: #eee;
+ border: solid #999 1px;
}
.overview-box {
cursor: pointer;
- opacity: 0.5;
bottom: 0px;
z-index: 100;
position: absolute;
margin-top: 0px;
height: 14px;
- background: #484848 url(../images/visualization/draggable_horizontal.png) center center no-repeat;
- border-style: solid;
- border-color: #484848;
- border-width: 0px 1px;
- -moz-border-radius: 3px;
- border-radius: 3px;
-}
-.overview-box:hover {
- background-color: #838383;
- border-color: #838383;
+ background: #C1C9E5 url(../images/visualization/draggable_horizontal.png) center center no-repeat;
+ border: solid #666 1px;
}
.viewport-canvas {
width: 100%;
@@ -129,6 +121,8 @@
/* border-bottom: solid #DDDDDD 1px; */
background: white;
margin-bottom: 1px;
+ padding-bottom: 4px;
+ border-bottom: #eee solid 1px;
}
.track-header {
@@ -146,10 +140,10 @@
text-align: center;
}
-.track.error {
+.track.error .track-content {
background-color: #ECB4AF;
}
-.track.nodata {
+.track.nodata .track-content {
background-color: #ddd;
}
@@ -159,11 +153,16 @@
.label-track {
/* font-weight: bold; */
- /* font-size: 10px; */
+ font-size: 10px;
+ border: none;
+ padding: 0;
+ margin: 0;
+ height: 1.3em;
}
.label-track .label {
border-left: solid #999 1px;
padding: 1px;
+ padding-bottom: 2px;
display: inline-block;
}
.right-float {
@@ -178,5 +177,5 @@
.nav-labeltrack {
border-top: solid #999 1px;
- border-bottom: solid #999 1px;
+ border-bottom: solid #333 1px;
}
1
0
galaxy-dist commit 4b78bad81e77: Trackster: save current viewport when saving viz
by commits-noreply@bitbucket.org 20 Nov '10
by commits-noreply@bitbucket.org 20 Nov '10
20 Nov '10
# HG changeset patch -- Bitbucket.org
# Project galaxy-dist
# URL http://bitbucket.org/galaxy/galaxy-dist/overview
# User James Taylor <james(a)jamestaylor.org>
# Date 1289169067 18000
# Node ID 4b78bad81e777cf503ac66acb5dbb01da841400f
# Parent fb55bfc792b1d087783055a736d9fb439e5bb41c
Trackster: save current viewport when saving viz
--- a/static/scripts/trackster.js
+++ b/static/scripts/trackster.js
@@ -81,7 +81,7 @@ var Cache = function( num_elements ) {
}
});
-var View = function( container, title, vis_id, dbkey ) {
+var View = function( container, title, vis_id, dbkey, callback ) {
this.container = container;
this.vis_id = vis_id;
this.dbkey = dbkey;
@@ -95,11 +95,11 @@ var View = function( container, title, v
this.zoom_factor = 3;
this.min_separation = 30;
this.has_changes = false;
- this.init();
+ this.init( callback );
this.reset();
};
$.extend( View.prototype, {
- init: function() {
+ init: function( callback ) {
// Create DOM elements
var parent_element = this.container,
view = this;
@@ -177,6 +177,9 @@ var View = function( container, title, v
view.chrom_select.bind("change", function() {
view.change_chrom(view.chrom_select.val());
});
+ if ( callback ) {
+ callback();
+ }
},
error: function() {
alert( "Could not load chroms for this dbkey:", view.dbkey );
@@ -244,8 +247,8 @@ var View = function( container, title, v
this.drag_origin_x = e.clientX;
this.drag_origin_pos = e.clientX / view.viewport_container.width() * (view.high - view.low) + view.low;
this.drag_div = $("<div />").css( {
- "height": view.content_div.height()+30, "top": "0px", "position": "absolute",
- "background-color": "#cfc", "border": "1px solid #6a6", "opacity": 0.5, "z-index": 1000
+ "height": view.content_div.height() + view.top_labeltrack.height() + view.nav_labeltrack.height(), "top": "0px", "position": "absolute",
+ "background-color": "#ccf", "opacity": 0.5, "z-index": 1000
} ).appendTo( $(this) );
}).bind( "drag", function(e) {
var min = Math.min(e.clientX, this.drag_origin_x) - view.container.offset().left,
@@ -1216,7 +1219,7 @@ var FeatureTrack = function ( name, view
this.show_labels_scale = 0.001;
this.showing_details = false;
this.vertical_detail_px = 10;
- this.vertical_nodetail_px = 2;
+ this.vertical_nodetail_px = 3;
this.summary_draw_height = 30;
this.default_font = "9px Monaco, Lucida Console, monospace";
this.inc_slots = {};
--- a/lib/galaxy/web/controllers/tracks.py
+++ b/lib/galaxy/web/controllers/tracks.py
@@ -1,12 +1,5 @@
"""
Support for constructing and viewing custom "track" browsers within Galaxy.
-
-Track browsers are currently transient -- nothing is stored to the database
-when a browser is created. Building a browser consists of selecting a set
-of datasets associated with the same dbkey to display. Once selected, jobs
-are started to create any necessary indexes in the background, and the user
-is redirected to the browser interface, which loads the appropriate datasets.
-
"""
import re, pkg_resources
@@ -317,7 +310,7 @@ class TracksController( BaseController,
if 'vis_id' in kwargs:
vis_id = kwargs['vis_id'].strip('"')
dbkey = kwargs['dbkey']
-
+ # Lookup or create Visualization object
if vis_id == "undefined": # new vis
vis = model.Visualization()
vis.user = trans.user
@@ -328,20 +321,30 @@ class TracksController( BaseController,
else:
decoded_id = trans.security.decode_id( vis_id )
vis = session.query( model.Visualization ).get( decoded_id )
-
+ # Decode the payload
decoded_payload = simplejson.loads( kwargs['payload'] )
+ # Create new VisualizationRevision that will be attached to the viz
vis_rev = model.VisualizationRevision()
vis_rev.visualization = vis
vis_rev.title = vis.title
vis_rev.dbkey = dbkey
+ # Tracks from payload
tracks = []
- for track in decoded_payload:
+ for track in decoded_payload['tracks']:
tracks.append( { "dataset_id": str(track['dataset_id']),
"name": track['name'],
"track_type": track['track_type'],
"prefs": track['prefs']
} )
- vis_rev.config = { "tracks": tracks }
+ # Viewport from payload
+ if 'viewport' in decoded_payload:
+ chrom = decoded_payload['viewport']['chrom']
+ start = decoded_payload['viewport']['start']
+ end = decoded_payload['viewport']['end']
+ vis_rev.config = { "tracks": tracks, "viewport": { 'chrom': chrom, 'start': start, 'end': end } }
+ else:
+ vis_rev.config = { "tracks": tracks }
+ print vis_rev.config
vis.latest_revision = vis_rev
session.add( vis_rev )
session.flush()
--- a/templates/tracks/browser.mako
+++ b/templates/tracks/browser.mako
@@ -77,7 +77,11 @@
$(function() {
%if config:
- view = new View( $("#browser-container"), "${config.get('title') | h}", "${config.get('vis_id')}", "${config.get('dbkey')}" );
+ var callback;
+ %if 'viewport' in config:
+ var callback = function() { view.change_chrom( '${config['viewport']['chrom']}', ${config['viewport']['start']}, ${config['viewport']['end']} ); }
+ %endif
+ view = new View( $("#browser-container"), "${config.get('title') | h}", "${config.get('vis_id')}", "${config.get('dbkey')}", callback );
view.editor = true;
%for track in config.get('tracks'):
view.add_track(
@@ -180,21 +184,25 @@
$("#save-button").bind("click", function(e) {
var sorted = $(".viewport-container").sortable('toArray'),
- payload = [];
+ tracks = [];
+
+ // Show saving dialog box
+ show_modal("Saving...", "<img src='${h.url_for('/static/images/yui/rel_interstitial_loading.gif')}'/>");
for (var i in sorted) {
var track_id = parseInt(sorted[i].split("track_")[1]),
track = view.tracks[track_id];
- payload.push( {
+ tracks.push( {
"track_type": track.track_type,
"name": track.name,
"dataset_id": track.dataset_id,
"prefs": track.prefs
});
}
- // Show saving dialog box
- show_modal("Saving...", "<img src='${h.url_for('/static/images/yui/rel_interstitial_loading.gif')}'/>");
+
+ var payload = { 'tracks': tracks, 'viewport': { 'chrom': view.chrom, 'start': view.low , 'end': view.high } }
+ console.log( payload );
$.ajax({
url: "${h.url_for( action='save' )}",
--- a/lib/galaxy/web/base/controller.py
+++ b/lib/galaxy/web/base/controller.py
@@ -185,6 +185,9 @@ class UsesVisualization( SharableItemSec
config = { "title": visualization.title, "vis_id": trans.security.encode_id( visualization.id ),
"tracks": tracks, "chrom": "", "dbkey": visualization.dbkey }
+
+ if 'viewport' in latest_revision.config:
+ config['viewport'] = latest_revision.config['viewport']
return config
1
0
galaxy-dist commit 32e5efb7a7d5: Remove the need for setup.sh - All configuration is done in run.sh/galaxy.config.
by commits-noreply@bitbucket.org 20 Nov '10
by commits-noreply@bitbucket.org 20 Nov '10
20 Nov '10
# HG changeset patch -- Bitbucket.org
# Project galaxy-dist
# URL http://bitbucket.org/galaxy/galaxy-dist/overview
# User Nate Coraor <nate(a)bx.psu.edu>
# Date 1288983302 14400
# Node ID 32e5efb7a7d5606a4dc1c8808fe4888ade2892e8
# Parent eb79ab327351e4789a89748269fc34428f791463
Remove the need for setup.sh - All configuration is done in run.sh/galaxy.config.
--- a/run.sh
+++ b/run.sh
@@ -2,6 +2,53 @@
cd `dirname $0`
+python ./scripts/check_python.py
+[ $? -ne 0 ] && exit 1
+
+FROM_SAMPLE="
+ datatypes_conf.xml
+ reports_wsgi.ini
+ tool_conf.xml
+ tool_data_table_conf.xml
+ universe_wsgi.ini
+ tool-data/add_scores.loc
+ tool-data/alignseq.loc
+ tool-data/annotation_profiler_options.xml
+ tool-data/annotation_profiler_valid_builds.txt
+ tool-data/bfast_indexes.loc
+ tool-data/binned_scores.loc
+ tool-data/blastdb.loc
+ tool-data/blastdb_p.loc
+ tool-data/bowtie_indices.loc
+ tool-data/bowtie_indices_color.loc
+ tool-data/codingSnps.loc
+ tool-data/encode_datasets.loc
+ tool-data/funDo.loc
+ tool-data/lastz_seqs.loc
+ tool-data/liftOver.loc
+ tool-data/maf_index.loc
+ tool-data/maf_pairwise.loc
+ tool-data/microbial_data.loc
+ tool-data/phastOdds.loc
+ tool-data/perm_base_index.loc
+ tool-data/perm_color_index.loc
+ tool-data/quality_scores.loc
+ tool-data/regions.loc
+ tool-data/sam_fa_indices.loc
+ tool-data/sift_db.loc
+ tool-data/srma_index.loc
+ tool-data/twobit.loc
+ tool-data/shared/ucsc/builds.txt
+"
+
+# Create any missing config/location files
+for file in $FROM_SAMPLE; do
+ if [ ! -f "$file" -a -f "$file.sample" ]; then
+ echo "Initializing $file from `basename $file`.sample"
+ cp $file.sample $file
+ fi
+done
+
# explicitly attempt to fetch eggs before running
FETCH_EGGS=1
for arg in "$@"; do
@@ -21,10 +68,4 @@ if [ $FETCH_EGGS -eq 1 ]; then
fi
fi
-# Temporary: since builds.txt is now removed from source control, create it
-# from the sample if necessary
-if [ ! -f "tool-data/shared/ucsc/builds.txt" ]; then
- cp tool-data/shared/ucsc/builds.txt.sample tool-data/shared/ucsc/builds.txt
-fi
-
python ./scripts/paster.py serve universe_wsgi.ini $@
--- a/lib/galaxy/config.py
+++ b/lib/galaxy/config.py
@@ -94,14 +94,8 @@ class Configuration( object ):
self.blog_url = kwargs.get( 'blog_url', None )
self.screencasts_url = kwargs.get( 'screencasts_url', None )
self.library_import_dir = kwargs.get( 'library_import_dir', None )
- if self.library_import_dir is not None and not os.path.exists( self.library_import_dir ):
- raise ConfigurationError( "library_import_dir specified in config (%s) does not exist" % self.library_import_dir )
self.user_library_import_dir = kwargs.get( 'user_library_import_dir', None )
- if self.user_library_import_dir is not None and not os.path.exists( self.user_library_import_dir ):
- raise ConfigurationError( "user_library_import_dir specified in config (%s) does not exist" % self.user_library_import_dir )
self.ftp_upload_dir = kwargs.get( 'ftp_upload_dir', None )
- if self.ftp_upload_dir is not None and not os.path.exists( self.ftp_upload_dir ):
- os.makedirs( self.ftp_upload_dir )
self.ftp_upload_site = kwargs.get( 'ftp_upload_site', None )
self.allow_library_path_paste = kwargs.get( 'allow_library_path_paste', False )
self.disable_library_comptypes = kwargs.get( 'disable_library_comptypes', '' ).lower().split( ',' )
@@ -159,9 +153,16 @@ class Configuration( object ):
return default
def check( self ):
# Check that required directories exist
- for path in self.root, self.file_path, self.tool_path, self.tool_data_path, self.template_path, self.job_working_directory, self.cluster_files_directory:
+ for path in self.root, self.tool_path, self.tool_data_path, self.template_path:
if not os.path.isdir( path ):
raise ConfigurationError("Directory does not exist: %s" % path )
+ # Create the directories that it makes sense to create
+ for path in self.file_path, self.new_file_path, self.job_working_directory, self.cluster_files_directory, self.template_cache, self.ftp_upload_dir, self.library_import_dir, self.user_library_import_dir, self.nginx_upload_store, './static/genetrack/plots', os.path.join( self.tool_data_path, 'shared', 'jars' ):
+ if path not in [ None, False ] and not os.path.isdir( path ):
+ try:
+ os.makedirs( path )
+ except Exception, e:
+ raise ConfigurationError( "Unable to create missing directory: %s\n%s" % ( path, e ) )
# Check that required files exist
for path in self.tool_config, self.datatypes_config:
if not os.path.isfile(path):
1
0
galaxy-dist commit 702f4717a8f3: Bugfix for the abstracted job runner
by commits-noreply@bitbucket.org 20 Nov '10
by commits-noreply@bitbucket.org 20 Nov '10
20 Nov '10
# HG changeset patch -- Bitbucket.org
# Project galaxy-dist
# URL http://bitbucket.org/galaxy/galaxy-dist/overview
# User Nate Coraor <nate(a)bx.psu.edu>
# Date 1288986871 14400
# Node ID 702f4717a8f3fe38758c54136f81935f7679c937
# Parent 6d94416b2ccf9205283ec197154d99522615cbf8
Bugfix for the abstracted job runner
--- a/lib/galaxy/jobs/runners/__init__.py
+++ b/lib/galaxy/jobs/runners/__init__.py
@@ -26,7 +26,7 @@ class BaseJobRunner( object ):
exec_dir = os.path.abspath( os.getcwd() ),
tmp_dir = self.app.config.new_file_path,
dataset_files_path = self.app.model.Dataset.file_path,
- output_fnames = output_fnames,
+ output_fnames = job_wrapper.get_output_fnames(),
set_extension = False,
kwds = { 'overwrite' : False } )
return commands
1
0
galaxy-dist commit 6d94416b2ccf: Automatically find new .sample files in tool-data/.
by commits-noreply@bitbucket.org 20 Nov '10
by commits-noreply@bitbucket.org 20 Nov '10
20 Nov '10
# HG changeset patch -- Bitbucket.org
# Project galaxy-dist
# URL http://bitbucket.org/galaxy/galaxy-dist/overview
# User Nate Coraor <nate(a)bx.psu.edu>
# Date 1288984386 14400
# Node ID 6d94416b2ccf9205283ec197154d99522615cbf8
# Parent 1e8d7c6ad88b074b33b2029f3baa15c2eb929e70
Automatically find new .sample files in tool-data/.
--- a/run.sh
+++ b/run.sh
@@ -5,47 +5,22 @@ cd `dirname $0`
python ./scripts/check_python.py
[ $? -ne 0 ] && exit 1
-FROM_SAMPLE="
- datatypes_conf.xml
- reports_wsgi.ini
- tool_conf.xml
- tool_data_table_conf.xml
- universe_wsgi.ini
- tool-data/add_scores.loc
- tool-data/alignseq.loc
- tool-data/annotation_profiler_options.xml
- tool-data/annotation_profiler_valid_builds.txt
- tool-data/bfast_indexes.loc
- tool-data/binned_scores.loc
- tool-data/blastdb.loc
- tool-data/blastdb_p.loc
- tool-data/bowtie_indices.loc
- tool-data/bowtie_indices_color.loc
- tool-data/codingSnps.loc
- tool-data/encode_datasets.loc
- tool-data/funDo.loc
- tool-data/lastz_seqs.loc
- tool-data/liftOver.loc
- tool-data/maf_index.loc
- tool-data/maf_pairwise.loc
- tool-data/microbial_data.loc
- tool-data/phastOdds.loc
- tool-data/perm_base_index.loc
- tool-data/perm_color_index.loc
- tool-data/quality_scores.loc
- tool-data/regions.loc
- tool-data/sam_fa_indices.loc
- tool-data/sift_db.loc
- tool-data/srma_index.loc
- tool-data/twobit.loc
- tool-data/shared/ucsc/builds.txt
+SAMPLES="
+ datatypes_conf.xml.sample
+ reports_wsgi.ini.sample
+ tool_conf.xml.sample
+ tool_data_table_conf.xml.sample
+ universe_wsgi.ini.sample
+ tool-data/shared/ucsc/builds.txt.sample
+ tool-data/*.sample
"
# Create any missing config/location files
-for file in $FROM_SAMPLE; do
- if [ ! -f "$file" -a -f "$file.sample" ]; then
- echo "Initializing $file from `basename $file`.sample"
- cp $file.sample $file
+for sample in $SAMPLES; do
+ file=`echo $sample | sed -e 's/\.sample$//'`
+ if [ ! -f "$file" -a -f "$sample" ]; then
+ echo "Initializing $file from `basename $sample`"
+ cp $sample $file
fi
done
1
0
galaxy-dist commit cdd6ce1f38b0: Enable filter tool to operate correctly on files with a variable number of columns (such as SAM files). Tool prepares and processes only columns up to and including the right-most column (i.e. column with the largest index) in the filtering condition, and subsequent columns are ignored. New functional test added for this functionality as well.
by commits-noreply@bitbucket.org 20 Nov '10
by commits-noreply@bitbucket.org 20 Nov '10
20 Nov '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 1288902634 14400
# Node ID cdd6ce1f38b0e22802ed63e3e0cb4f6a58cb93b2
# Parent f372ea5a601443a9b9cd1d3f7e04ddc24db5b57a
Enable filter tool to operate correctly on files with a variable number of columns (such as SAM files). Tool prepares and processes only columns up to and including the right-most column (i.e. column with the largest index) in the filtering condition, and subsequent columns are ignored. New functional test added for this functionality as well.
--- a/tools/stats/filtering.py
+++ b/tools/stats/filtering.py
@@ -60,10 +60,18 @@ for operand in operands:
except:
if operand in secured:
stop_err( "Illegal value '%s' in condition '%s'" % ( operand, cond_text ) )
+
+# Find the largest column used in the filter.
+largest_col_index = -1
+for match in re.finditer( 'c(\d)+', cond_text ):
+ col_index = int( match.group()[1:] )
+ if col_index > largest_col_index:
+ largest_col_index = col_index
-# Prepare the column variable names and wrappers for column data types
+# Prepare the column variable names and wrappers for column data types. Only
+# prepare columns up to largest column in condition.
cols, type_casts = [], []
-for col in range( 1, in_columns + 1 ):
+for col in range( 1, largest_col_index + 1 ):
col_name = "c%d" % col
cols.append( col_name )
col_type = in_column_types[ col - 1 ]
@@ -72,7 +80,7 @@ for col in range( 1, in_columns + 1 ):
col_str = ', '.join( cols ) # 'c1, c2, c3, c4'
type_cast_str = ', '.join( type_casts ) # 'str(c1), int(c2), int(c3), str(c4)'
-assign = "%s = line.split( '\\t' )" % col_str
+assign = "%s, = line.split( '\\t' )[:%i]" % ( col_str, largest_col_index )
wrap = "%s = %s" % ( col_str, type_cast_str )
skipped_lines = 0
first_invalid_line = 0
--- a/tools/stats/filtering.xml
+++ b/tools/stats/filtering.xml
@@ -23,6 +23,13 @@
<param name="cond" value="c1=='chr1' and c3-c2>=2000 and c6=='+'"/><output name="out_file1" file="filter1_test2.bed"/></test>
+ <!-- Test filtering of file with a variable number of columns. -->
+ <test>
+ <param name="input" value="filter1_in3.sam"/>
+ <param name="cond" value="c3=='chr1' and c5>5"/>
+ <output name="out_file1" file="filter1_test3.sam"/>
+ </test>
+
</tests><help>
--- /dev/null
+++ b/test-data/filter1_in3.sam
@@ -0,0 +1,100 @@
+HWI-EAS269B:8:34:797:623 145 chr1 16632182 255 27M = 16631977 0 CCATTTCCTGTATGCTGTAAAGTACAA IIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:0 NH:i:1
+HWI-EAS269B:8:40:39:1184 145 chr1 24620331 3 27M = 24620115 0 ATTTATGTGGTTTCGTTTACCTTCTAT IIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:0 NH:i:2 CC:Z:chrM CP:i:9060
+HWI-EAS269B:8:58:533:1198 81 chr1 88426079 255 27M = 88423429 0 GAAGAGGAAGAAGGTGGGGAGGAAGAG IIIG?IIIIIIIIIIIIIIIIIIIIII NM:i:0 NH:i:1
+HWI-EAS269:3:89:1776:1815 97 chr1 134085638 255 27M = 134085824 0 GAATGATTCTCTGGGTGTTACTTTGCA IIIIIIIIIIIIIIIDIII:IIII>F5 NM:i:0 NH:i:1
+HWI-EAS269B:8:74:1134:1670 161 chr1 138166886 255 27M = 138167084 0 TTACTAGTGTCTCTCTTACCATCATAT .IIIIIIIIIIIIIIIIIIIIIIIIII NM:i:1 NH:i:1
+HWI-EAS269:3:59:1321:1427 147 chr1 173149715 255 27M = 173149555 0 AAGGGCTAGGGTGACAGGCAGGGGACG -C<CID?IIIIIIIDIIIIIIIIIIII NM:i:0 NH:i:1
+HWI-EAS269B:8:8:164:1678 145 chr1 178660716 255 27M = 178660493 0 CAATTGGTGTTTTTCTTAAGAGACTCA IIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:0 NH:i:1
+HWI-EAS269:3:1:1048:638 137 chr10 12456478 1 27M * 0 0 TAAAANAAATAAAACAAAACAATAAAA $'&(+")'%$(&*&#&$$#%%$$%%$$ NM:i:2 NH:i:4 CC:Z:chr16 CP:i:21639623
+HWI-EAS269:3:62:1211:798 147 chr10 28135294 255 27M = 28135117 0 ACATGGTGTGGGGACAGAGATGTGAAG I;IIIIIIAIIIIIIIIIIIIIIIIII NM:i:1 NH:i:1
+HWI-EAS269:3:27:410:424 145 chr10 76950070 255 27M = 76949871 0 GAGTCTGTGTCCAGGCCAATTCACTAT 25-8I+.6B.IIIIIIIIIIIIIIIII NM:i:0 NH:i:1
+HWI-EAS269:3:48:1180:1122 73 chr10 83772157 0 27M * 0 0 GATCATCTTTTCTAAAACAATAAAGAC /IIIIIIIIIIIIIIIIIIIIIIIIII NM:i:0 NH:i:6 CC:Z:chr11 CP:i:93811140
+HWI-EAS269:3:77:654:131 99 chr10 93419810 255 27M = 93419993 0 TTGCATCCCTAGGAACTGGAGTTATAG IIIIIIGIHIIIED@CIIH5I3D9G6: NM:i:0 NH:i:1
+HWI-EAS269B:8:98:895:1810 177 chr11 3371472 255 27M = 37952212 0 CTACATAGTGGGAACCGGCGACCGCTG IIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:2 NH:i:1
+HWI-EAS269B:8:58:1126:883 97 chr11 30080486 255 27M = 30080702 0 TACTTCCACCAGGCTCCAGTTTTGTGA IIIIIIIIIIIIIIIIIIIIIIIIII5 NM:i:0 NH:i:1
+HWI-EAS269B:8:89:1763:1446 81 chr11 59589605 255 27M = 59589400 0 GTACCTGGCCACTGATGCAGCTTAGAA II<IIIIIIIIIIIIIIIIIIIIIIII NM:i:0 NH:i:1
+HWI-EAS269B:8:6:739:1329 161 chr11 68629628 3 27M = 68629835 0 GTTTTTGGTTGATAGTTGAGCAAACTG IIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:0 NH:i:2 CC:Z:chr4 CP:i:126661877
+HWI-EAS269:3:19:1683:1350 81 chr11 70846915 255 27M = 70846725 0 CACGGGCAGATAAGCTGCTGAGACTAA H50BB:IF=IIGIIIIIIIIIIIIIII NM:i:0 NH:i:1
+HWI-EAS269B:8:9:1691:1087 97 chr11 84640783 255 27M = 84641010 0 ACATTATCCATCTCTCTGTCATTGTCC IIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:0 NH:i:1
+HWI-EAS269B:8:48:1350:424 81 chr11 94150331 255 27M = 94150113 0 TTGCAAGCCAACCCTGAGTGAAGTGTC IIDHIIIIIIIIIIIIIIIIIIIIIII NM:i:0 NH:i:1
+HWI-EAS269:3:22:1176:1405 97 chr11 98629843 255 27M = 98630030 0 CCCTCGGAGGGCAACGGGAAAGGAGAA IIIIIIIIIIIDIIIII?III/79E14 NM:i:0 NH:i:1
+HWI-EAS269:3:67:1311:1512 97 chr11 100488190 255 27M = 100488374 0 CATGCCCTGAGACTTAGCAAGACTCTT IIIIIIIIIIIIIIIEIA3,I57GBI@ NM:i:0 NH:i:1
+HWI-EAS269B:8:41:1142:1307 161 chr11 101320424 255 27M = 101320625 0 GCCTCCCTACATAGCAAAGGAAAGAAA IIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:0 NH:i:1
+HWI-EAS269B:8:31:1101:21 97 chr11 116711287 255 27M = 116711485 0 CATAAGCAAAAGATACACCATGTTTTA IIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:0 NH:i:1
+HWI-EAS269:3:84:637:1203 145 chr12 35829424 255 27M = 35829229 0 CTCCCTCAAGGATCTTGTGGGGCATCA </'>I,I5B26$II;EB=%IIII1III NM:i:0 NH:i:1
+HWI-EAS269:3:65:1158:1081 163 chr12 52234332 255 27M = 52234505 0 TTTTTTTTTTAAGACAGGGAGTTTTTT IIIIIIIIIIIC4,,*>II%-,%III> NM:i:1 NH:i:1
+HWI-EAS269B:8:65:1325:1287 137 chr12 52234513 3 27M * 0 0 GCAGCACCTTGTGACATTTAATTTAGT IIIII+IIIIIIIIIIIIIIIIIIIII NM:i:0 NH:i:2 CC:Z:chr15 CP:i:98780443
+HWI-EAS269:3:38:488:1093 97 chr12 80471642 255 27M = 80471839 0 TGGAGAGATGACTCCTTGTTTGAGACA IIIIIIIIIIIIIIIIIIIBAE0B<7D NM:i:0 NH:i:1
+HWI-EAS269:3:76:290:1451 99 chr12 117745566 0 27M = 117745739 0 CAATCTGAAGATCCACAATCTTTTATA IIIIIIIIIIIIIIFII5I9IIII+I7 NM:i:0 NH:i:5 CC:Z:chr4 CP:i:133520935
+HWI-EAS269B:8:39:353:1526 65 chr13 18122558 255 27M = 18122761 0 ACTCTACTCAAAACCACACTAAGCCTC @IIIIII6IIIIIDII9IIIIII<III NM:i:0 NH:i:1
+HWI-EAS269:3:63:1260:365 99 chr13 41278147 255 27M = 41278319 0 AAGACAAGAACTTATCCACCAATATGT IIIIIIIIIIIIIII<IIA<CIIDII> NM:i:0 NH:i:1
+HWI-EAS269:3:70:152:1609 161 chr13 55421426 255 27M = 55421687 0 CGCTTGACCATTCCAGCCCAGACAAGA IIIIIIIII8IIII3IIII-C(3-%B' NM:i:0 NH:i:1
+HWI-EAS269:3:9:1343:1414 99 chr13 83721797 255 27M = 83721967 0 AACTACAGCTGAGGCAGCCTCCTGCCT IIIIIIIIIIIIIIIII;E+?7&819& NM:i:0 NH:i:1
+HWI-EAS269:3:4:1480:1956 137 chr14 46703849 0 27M * 0 0 GTGGAGCCCAGTGACACCATCGAGAAC IIIIIIIIIIIII?C3IH?1@I@@=27 NM:i:0 NH:i:8 CC:Z:= CP:i:46704077
+HWI-EAS269:3:86:616:1519 137 chr14 56244763 255 27M * 0 0 CATGGCCTGAAGTTCCTGAGCTTTATC IIIIIIIII3DIBI9II3)73BIG'G+ NM:i:0 NH:i:1
+HWI-EAS269:3:42:656:1216 97 chr14 100271567 255 27M = 100271751 0 ATAAGTCTCAGTTCTTGGGCCAGATCA IIIIIIIIICIIIIII3IA854I1C+) NM:i:0 NH:i:1
+HWI-EAS269:3:87:95:767 73 chr16 7368880 255 27M * 0 0 AATATCTGAAACATTCAAATGAGCAAT F>II/4I@9H=II?IIIIIIIIIIII- NM:i:0 NH:i:1
+HWI-EAS269B:8:50:1572:711 145 chr16 32230400 255 27M = 32230196 0 TACAGCAACAACAAATTCAACGACACG IIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:0 NH:i:1
+HWI-EAS269:3:56:1436:121 147 chr16 49887529 255 27M = 49887356 0 TTAAGGCCCAGCTCTACATAAAACACT IIIIAHIIIIIIIIIIIIIIIIIIIII NM:i:0 NH:i:1
+HWI-EAS269:3:53:584:1696 99 chr17 45705815 255 27M = 45705987 0 CCTTCTTGTCCAAGATCTCCTTCATGA IIIIIIIIIIIIBI6IIII=II:GI@< NM:i:0 NH:i:1
+HWI-EAS269B:8:16:643:1950 177 chr18 38000738 255 27M = 38000570 0 ATTCTGGTTCAGCCTGGGCAGCTTGGG III@==I0<IIGIII;IIIIIIIIIII NM:i:0 NH:i:1
+HWI-EAS269:3:66:1760:1539 137 chr18 38624681 3 27M * 0 0 TTTGGAACTTTTGAGAGGATCCCTAGC IIIIIIIIIIIIIII1II.IIIII1II NM:i:0 NH:i:2
+HWI-EAS269:3:2:1723:1277 163 chr19 16341705 255 27M = 16341870 0 ATGGGCTCGTCGCAGCTCAGCGGCTGG IIIIIIIIIIIIICI=8<&I7:F(+;2 NM:i:1 NH:i:1
+HWI-EAS269B:8:66:317:1676 97 chr19 47099316 255 27M = 47099535 0 ATCTGGTCAATCAACACCACCAGCAGA IIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:0 NH:i:1
+HWI-EAS269:3:10:1428:1315 81 chr2 22444224 3 27M = 22444039 0 GGAATTGCGATAATTATAGTGGCTGAT ?6>CI>GIIIIIIIIIIIIIIIIIIII NM:i:0 NH:i:2 CC:Z:chrM CP:i:6245
+HWI-EAS269:3:72:152:785 97 chr2 22796881 255 27M = 22797074 0 TGAGTACTCCAGATAATCGTTACACAA IIIIIIII6IIIIIIII0IA@?,7752 NM:i:0 NH:i:1
+HWI-EAS269:3:79:321:1095 99 chr2 62083760 255 27M = 62083938 0 CAAAAATTGAGATATCAAAAAGCTCTT IIIIIIIII2IGIBIIC8:4IB1H4I; NM:i:0 NH:i:1
+HWI-EAS269:3:93:1529:881 97 chr2 129998362 255 27M = 129998827 0 CGCATGCCAGGAGGGGGCATGCCCATT IIIFIIIIFIIIIIFII?72I.,020* NM:i:0 NH:i:1
+HWI-EAS269B:8:20:813:376 113 chr2 130534278 255 27M = 130534454 0 TGTATTAGCAGGAGGTGGGGAGGCTGA IIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:0 NH:i:1
+HWI-EAS269:3:89:1221:1082 83 chr2 151285071 0 27M = 151284944 0 ACCAGTGCACAGGTCTCCAGGGCTTCT -IC=B+8IIIEIIFI5IIIIIIIIIII NM:i:0 NH:i:5 CC:Z:chr9 CP:i:31743980
+HWI-EAS269:3:66:46:336 163 chr2 156679837 255 27M = 156680016 0 TATTTTCCTTTTGCTGTGGTTTGTGTT IIIIIIIIIIIIIEI@E-I?GI&B%3I NM:i:0 NH:i:1
+HWI-EAS269B:8:52:1139:1381 73 chr2 174953004 0 27M * 0 0 AATGCTCAACTCTTAGTTTCTTATTCA IIIIIIIIIIIIIIIIB@?IIIII?+0 NM:i:0 NH:i:19 CC:Z:= CP:i:175018018
+HWI-EAS269:3:98:585:19 161 chr3 26005087 255 27M = 26005271 0 ACCTAACACATGTAAACTTAAATTCAT I:IIIIIIII<IIE==DDI):,D1--8 NM:i:0 NH:i:1
+HWI-EAS269:3:74:447:1309 83 chr3 80492396 255 27M = 80492220 0 TCGGATGCCTCTCACCACTTTGACAAT )H():F=85IIIIEIIIIIIIIIIIII NM:i:0 NH:i:1
+HWI-EAS269B:8:74:425:1427 161 chr3 96447603 255 27M = 96447820 0 TGGAGTAGGAGTCTCAGGAGGAGTAGA IIIIIIIIIIIIIIIIIIIII:I?II< NM:i:0 NH:i:1
+HWI-EAS269:3:10:739:1474 163 chr3 124089371 255 27M = 124089535 0 AAAAAAACAATCTTATTCCGAGCATTC IIIIIIIIIIIIIIIIIIIIIIIGIII NM:i:0 NH:i:1
+HWI-EAS269:3:20:357:1709 65 chr4 128895987 255 27M = 128895822 0 CCTACCTTCTTCCCTTGGCAGCTGACT IIII>IIIBIIA:I18):,*3&,/*'+ NM:i:0 NH:i:1
+HWI-EAS269B:8:22:623:129 113 chr4 135492867 255 27M = 135490613 0 CCACTTTCCTGTACTGGCCAGAAAATG IIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:0 NH:i:1
+HWI-EAS269B:8:48:824:702 65 chr4 139584010 255 27M = 139582899 0 CTGGGCAGTGCAGCGGTACATGGAGCC IIIIIIIIIIIIIIIIII<AIIB;I>: NM:i:0 NH:i:1
+HWI-EAS269B:8:33:527:1211 73 chr5 37627410 255 27M * 0 0 GGGAAGGTGTGAGTACAACAGCCAAAG IIIIIIIIIIIIIIIIIIIIIIII@II NM:i:0 NH:i:1
+HWI-EAS269:3:2:1518:599 163 chr5 136908928 255 27M = 136909101 0 CTATTGCCAAAAAACTATGTTCACAAA IIIIIIIIIIIIIIIIIIIIIIIII=I NM:i:0 NH:i:1
+HWI-EAS269B:8:62:1493:1455 161 chr5 138715332 255 27M = 138715534 0 CCCAAATGAAAAAATAAATATTATGAA IIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:0 NH:i:1
+HWI-EAS269:3:69:384:1894 147 chr5 143665243 255 27M = 143665064 0 TGTTTGCTCCAACCAACTGCTGTCGCC &++*,2H-IGI+IFIGI?IIIIIIIII NM:i:0 NH:i:1
+HWI-EAS269:3:56:1358:762 113 chr6 15024174 255 7M12235N20M = 51485453 0 TGGGTACTTTCTCTAGCTCCTCCATTG /@)3I?IIIIIIIIIIIIIIIIIIIII NM:i:2 XS:A:- NH:i:1
+HWI-EAS269:3:100:228:1799 163 chr6 37756378 3 27M = 37756558 0 GTGTGGGGCTGCGTGGCCTGGCTGGTG DII4A+>5EI.)F634820&1(0%&&& NM:i:2 NH:i:2
+HWI-EAS269B:8:50:188:1253 161 chr6 52296684 1 27M = 52296901 0 ACTTTTCAGGGTTTTCAATAGTCACAC IIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:1 NH:i:3 CC:Z:= CP:i:140695441
+HWI-EAS269B:8:19:440:1687 161 chr6 52850377 255 27M = 52850580 0 TACAAAGATGGACTTTTAAAATTCATT IIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:0 NH:i:1
+HWI-EAS269:3:47:1555:1520 161 chr6 67231655 255 27M = 67233919 0 ATTCAGTTATGGACCATCATTTCCGGA IIIIIIIIIIIIIIIIIIIIII<AII1 NM:i:0 NH:i:1
+HWI-EAS269B:8:79:1563:1318 161 chr6 89267414 255 27M = 89267614 0 GTGCGTGTTCCAGGCAGAGCTGGAAGA IIIIIIIIIIIIIIIIIIIIIII=;IA NM:i:0 NH:i:1
+HWI-EAS269B:8:54:954:565 161 chr6 120882513 255 27M = 120882716 0 ACGTCATGGCTGACCAGGACAGAGGTG IIIIIIIIIIIIIII?IEG;II<II*8 NM:i:0 NH:i:1
+HWI-EAS269B:8:16:570:1775 145 chr7 26081268 255 27M = 26080313 0 GAAAGAGTGACACAAATCAATAGTAAA IIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:0 NH:i:1
+HWI-EAS269B:8:13:280:189 161 chr7 29184615 255 27M = 29184814 0 CTTTTCCAACAGCGAGAAAAATGTACA IIIIIIIIIIIIIIIIIIIIIIIIDII NM:i:0 NH:i:1
+HWI-EAS269B:8:19:72:273 137 chr7 52258521 255 27M * 0 0 ATCAGAGGCACAGGGACAGGGTAAGGA &&2IIIII;E(IIIIIIIIIIIIIIII NM:i:1 NH:i:1
+HWI-EAS269B:8:40:235:869 161 chr7 52631974 255 27M = 52632179 0 GGCGCTGACTCCATCAGATATCCATTC IIIIIII7IIIIIII6IIIIIIIBIII NM:i:1 NH:i:1
+HWI-EAS269B:8:18:304:346 129 chr7 107789557 255 27M = 33158390 0 CACGTACTGTCACCTTGTAACATTTGG IIIIIIIIIIIIIIIIIIIIIIIIIIF NM:i:0 NH:i:1
+HWI-EAS269B:8:3:698:297 161 chr7 110976065 255 27M = 110976385 0 GCAGTTATCACTTTCTTGCCATGGGCC IIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:0 NH:i:1
+HWI-EAS269B:8:50:1269:965 145 chr7 118217605 255 27M = 118216239 0 ACCTGTAGATCCACATGATCATGAAGA IIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:0 NH:i:1
+HWI-EAS269:3:38:1381:1429 83 chr7 136141344 255 27M = 136141280 0 ATCTGAAGTATCCCACATGTTGAGCTC <III@IIIIIIIII>IIIIIIIIIIII NM:i:1 NH:i:1
+HWI-EAS269:3:25:781:386 83 chr8 29844005 255 27M = 29843841 0 TAAGGGAGGAAAGTGTTTCAGAGTGTA ;83<159<<III@IIIIIIIIIIIIII NM:i:0 NH:i:1
+HWI-EAS269:3:25:979:679 163 chr8 72664237 255 27M = 72664413 0 CTGATGGGAGCCCTGCGTGGTAAGAGG IIIIIIIIIII=III@I(II$27I>I4 NM:i:0 NH:i:1
+HWI-EAS269B:8:23:1069:816 145 chr8 74704433 255 27M = 74704222 0 TGTTCTCAGTTGTGGACAAGTGACAGC I<GII@IIIIIIII;IIIIIIIIII0I NM:i:0 NH:i:1
+HWI-EAS269B:8:34:435:1679 73 chr8 87366211 3 27M * 0 0 AAGCCTAGGGCTTCTCCTCTACACCCC I556I;FCAIIIFI<IIIIIIIIIIII NM:i:0 NH:i:2
+HWI-EAS269B:8:32:1486:294 97 chr8 124121215 255 27M = 124121411 0 TGTTACCATACGCCCTTCTGCTGAGGC IIIIIIIIIIIIIIIIIIDIIIIGIII NM:i:0 NH:i:1
+HWI-EAS269B:8:32:142:1471 81 chr8 124496752 3 27M = 124496536 0 GGATCTGCTTCATGAGTTGCCACATTG IIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:1 NH:i:2
+HWI-EAS269B:8:60:82:1806 97 chr8 125945215 255 27M = 125945423 0 AGATGCTGGCCATCCAGAGTAAGAACA IIIIIIIIIIIIIIIIIIIHIIIIIII NM:i:0 NH:i:1
+HWI-EAS269B:8:16:1162:495 81 chr8 125945584 255 27M = 125945381 0 GTTGCTCGCAGCTGGGGTGTGGGGCCA <CIIIIIIIIIIIIIIIIIIIIIIIII NM:i:0 NH:i:1
+HWI-EAS269B:8:1:165:1889 81 chr8 126016885 255 27M = 126016469 0 TGAGCAGGAAAACACTTTAAACCAGAT IIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:0 NH:i:1
+HWI-EAS269B:8:66:939:1154 145 chr9 17537149 255 27M = 17536959 0 CTCCTTCAAGTACGCCTGGGTCTTAGA IDIIIIIIIIIIIIIIIIIIIIIIIII NM:i:0 NH:i:1
+HWI-EAS269:3:68:1189:285 81 chr9 61249807 255 27M = 61242460 0 AGTCAAGCTCACTTGGCGGTGAAGGAT @.0;;A,?-F5I;7IIIIGIIIIIIII NM:i:0 NH:i:1
+HWI-EAS269:3:15:784:1754 163 chr9 74846937 255 27M = 74847108 0 GCACAGCACTGAGGAAAGGATCATCTC IIIIIIIIIIIIIIIIIIGII1CI7II NM:i:0 NH:i:1
+HWI-EAS269B:8:26:126:1382 145 chrM 3413 255 27M = 3190 0 GTTATTCTTTATAGCAGAGTACACTAA IIII8IB328I9IIIIIIIIIIIIIII NM:i:0 NH:i:1
+HWI-EAS269:3:90:320:1336 73 chrM 6326 255 27M * 0 0 ATGATCTCCAGCTATCCTATGAGCCTT IIIIIIIIA.ICI.4'(=,C>7-*&@8 NM:i:1 NH:i:1
+HWI-EAS269B:8:23:469:1215 161 chrM 7472 3 27M = 7676 0 ATTTCATCTGAAGACGTCCTCCACTCA IIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:0 NH:i:2
+HWI-EAS269:3:73:36:783 161 chrM 7958 3 27M = 8152 0 CCCCAACAATAATAGGATTCCCAATCG IIIIIIIIIIIIIIIIIIIII09I>>I NM:i:0 NH:i:2
+HWI-EAS269:3:33:1528:954 99 chrM 8012 3 27M = 8186 0 TCCTATTCCCATCCTCAAAACGCCTAA IIIIIIIIIIIIIIIIIIIIIIIDII: NM:i:0 NH:i:2
+HWI-EAS269:3:2:192:1456 161 chrM 9071 3 27M = 9255 0 ACGAAACCACATAAATCAAGCCCTACT III;IEIIDI7III+III*?I@CH+5I NM:i:0 NH:i:2
+HWI-EAS269:3:63:192:470 97 chrM 14787 255 27M = 14982 0 GCAGATAAAATTCCATTTCACCCCTAC IIIIIIIIIIIIIIFIII=B5042:4E NM:i:0 NH:i:1
+HWI-EAS269B:8:49:528:63 83 chrM 14963 255 27M = 14829 0 TTTCCTATTTGCATACGCCATTCTACG IIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:0 NH:i:1
+HWI-EAS269B:8:98:856:1516 145 chrX 20257960 255 27M = 20256746 0 TACCCGGATTTAAGATGTACCCCATTG IIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:0 NH:i:1
+HWI-EAS269B:8:28:1174:110 145 chrX 53916348 255 27M = 53916153 0 TGAATGTCAGCATCATTGACCCACAAA IIIIFIIIIIIIIIIIIIIIIIIIIII NM:i:0 NH:i:1
+HWI-EAS269B:8:58:663:410 147 chrX 75006902 255 27M = 75006834 0 TCAGGTGGTTTACAGTGTTCTGACAAA IIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:0 NH:i:1
--- /dev/null
+++ b/test-data/filter1_test3.sam
@@ -0,0 +1,6 @@
+HWI-EAS269B:8:34:797:623 145 chr1 16632182 255 27M = 16631977 0 CCATTTCCTGTATGCTGTAAAGTACAA IIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:0 NH:i:1
+HWI-EAS269B:8:58:533:1198 81 chr1 88426079 255 27M = 88423429 0 GAAGAGGAAGAAGGTGGGGAGGAAGAG IIIG?IIIIIIIIIIIIIIIIIIIIII NM:i:0 NH:i:1
+HWI-EAS269:3:89:1776:1815 97 chr1 134085638 255 27M = 134085824 0 GAATGATTCTCTGGGTGTTACTTTGCA IIIIIIIIIIIIIIIDIII:IIII>F5 NM:i:0 NH:i:1
+HWI-EAS269B:8:74:1134:1670 161 chr1 138166886 255 27M = 138167084 0 TTACTAGTGTCTCTCTTACCATCATAT .IIIIIIIIIIIIIIIIIIIIIIIIII NM:i:1 NH:i:1
+HWI-EAS269:3:59:1321:1427 147 chr1 173149715 255 27M = 173149555 0 AAGGGCTAGGGTGACAGGCAGGGGACG -C<CID?IIIIIIIDIIIIIIIIIIII NM:i:0 NH:i:1
+HWI-EAS269B:8:8:164:1678 145 chr1 178660716 255 27M = 178660493 0 CAATTGGTGTTTTTCTTAAGAGACTCA IIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:0 NH:i:1
1
0
galaxy-dist commit 11abfc8eed60: Update cufflinks and cuffdiff wrappers to indicate that, as of version 0.9, setting parameters for paired-end reads is not recommended.
by commits-noreply@bitbucket.org 20 Nov '10
by commits-noreply@bitbucket.org 20 Nov '10
20 Nov '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 1288979059 14400
# Node ID 11abfc8eed60c0bdd231d06992f72001a2c785fa
# Parent 9545e8675a5d43408d75c66fcf3115cbdaf4af8a
Update cufflinks and cuffdiff wrappers to indicate that, as of version 0.9, setting parameters for paired-end reads is not recommended.
--- a/tools/ngs_rna/cuffdiff_wrapper.xml
+++ b/tools/ngs_rna/cuffdiff_wrapper.xml
@@ -25,6 +25,11 @@
--inputA=$gtf_input
--input1=$aligned_reads1
--input2=$aligned_reads2
+
+ #if $singlePaired.sPaired == "Yes":
+ -m $singlePaired.mean_inner_distance
+ -s $singlePaired.inner_distance_std_dev
+ #end if
</command><inputs><param format="gtf" name="gtf_input" type="data" label="Transcripts" help="A transcript GTF file produced by cufflinks, cuffcompare, or other source."/>
@@ -34,12 +39,12 @@
<param name="min_mapqual" type="integer" value="0" label="Min SAM Mapping Quality" help="Instructs Cufflinks to ignore alignments with a SAM mapping quality lower than this number."/><param name="min_alignment_count" type="integer" value="0" label="Min Alignment Count" help="The minimum number of alignments in a locus for needed to conduct significance testing on changes in that locus observed between samples."/><conditional name="singlePaired">
- <param name="sPaired" type="select" label="Is this library mate-paired?">
- <option value="single">Single-end</option>
- <option value="paired">Paired-end</option>
+ <param name="sPaired" type="select" label="Set Parameters for Paired-end Reads? (not recommended)">
+ <option value="No">No</option>
+ <option value="Yes">Yes</option></param>
- <when value="single"></when>
- <when value="paired">
+ <when value="No"></when>
+ <when value="Yes"><param name="mean_inner_distance" type="integer" value="20" label="Mean Inner Distance between Mate Pairs"/><param name="inner_distance_std_dev" type="integer" value="20" label="Standard Deviation for Inner Distance between Mate Pairs"/></when>
--- a/tools/ngs_rna/cufflinks_wrapper.xml
+++ b/tools/ngs_rna/cufflinks_wrapper.xml
@@ -17,7 +17,7 @@
#if $reference_annotation.use_ref == "Yes":
-G $reference_annotation.reference_annotation_file
#end if
- #if $singlePaired.sPaired == "paired":
+ #if $singlePaired.sPaired == "Yes":
-m $singlePaired.mean_inner_distance
-s $singlePaired.inner_distance_std_dev
#end if
@@ -39,12 +39,12 @@
</when></conditional><conditional name="singlePaired">
- <param name="sPaired" type="select" label="Is this library mate-paired?">
- <option value="single">Single-end</option>
- <option value="paired">Paired-end</option>
+ <param name="sPaired" type="select" label="Set Parameters for Paired-end Reads? (not recommended)">
+ <option value="No">No</option>
+ <option value="Yes">Yes</option></param>
- <when value="single"></when>
- <when value="paired">
+ <when value="No"></when>
+ <when value="Yes"><param name="mean_inner_distance" type="integer" value="20" label="Mean Inner Distance between Mate Pairs"/><param name="inner_distance_std_dev" type="integer" value="20" label="Standard Deviation for Inner Distance between Mate Pairs"/></when>
1
0
galaxy-dist commit 1e8d7c6ad88b: Add support for tool dependency injection to all cluster runners
by commits-noreply@bitbucket.org 20 Nov '10
by commits-noreply@bitbucket.org 20 Nov '10
20 Nov '10
# HG changeset patch -- Bitbucket.org
# Project galaxy-dist
# URL http://bitbucket.org/galaxy/galaxy-dist/overview
# User James Taylor <james(a)jamestaylor.org>
# Date 1288983797 14400
# Node ID 1e8d7c6ad88b074b33b2029f3baa15c2eb929e70
# Parent 32e5efb7a7d5606a4dc1c8808fe4888ade2892e8
Add support for tool dependency injection to all cluster runners
--- a/lib/galaxy/tools/deps/__init__.py
+++ b/lib/galaxy/tools/deps/__init__.py
@@ -51,7 +51,7 @@ class DependencyManager( object ):
if os.path.exists( script ):
return script, path, version
else:
- return None, None
+ return None, None, None
def _find_dep_default( self, name ):
version = None
@@ -64,6 +64,6 @@ class DependencyManager( object ):
if os.path.exists( script ):
return script, real_path, real_version
else:
- return None, None
+ return None, None, None
--- a/lib/galaxy/jobs/runners/__init__.py
+++ b/lib/galaxy/jobs/runners/__init__.py
@@ -0,0 +1,32 @@
+import os, os.path
+
+class BaseJobRunner( object ):
+
+ def build_command_line( self, job_wrapper, include_metadata=False ):
+ """
+ Compose the sequence of commands neccesary to execute a job. This will
+ currently include:
+ - environment settings corresponding to any requirement tags
+ - command line taken from job wrapper
+ - commands to set metadata (if include_metadata is True)
+ """
+ commands = job_wrapper.get_command_line()
+ # All job runners currently handle this case which should never
+ # occur
+ if not commands:
+ return None
+ # Prepend dependency injection
+ if job_wrapper.dependency_shell_commands:
+ commands = "; ".join( job_wrapper.dependency_shell_commands + [ commands ] )
+ # Append metadata setting commands, we don't want to overwrite metadata
+ # that was copied over in init_meta(), as per established behavior
+ if include_metadata and self.app.config.set_metadata_externally:
+ commands += "; cd %s; " % os.path.abspath( os.getcwd() )
+ commands += job_wrapper.setup_external_metadata(
+ exec_dir = os.path.abspath( os.getcwd() ),
+ tmp_dir = self.app.config.new_file_path,
+ dataset_files_path = self.app.model.Dataset.file_path,
+ output_fnames = output_fnames,
+ set_extension = False,
+ kwds = { 'overwrite' : False } )
+ return commands
--- a/lib/galaxy/jobs/runners/local.py
+++ b/lib/galaxy/jobs/runners/local.py
@@ -5,13 +5,14 @@ import threading
from galaxy import model
from galaxy.datatypes.data import nice_size
+from galaxy.jobs.runners import BaseJobRunner
import os, errno
from time import sleep
log = logging.getLogger( __name__ )
-class LocalJobRunner( object ):
+class LocalJobRunner( BaseJobRunner ):
"""
Job runner backed by a finite pool of worker threads. FIFO scheduling
"""
@@ -53,9 +54,7 @@ class LocalJobRunner( object ):
# Prepare the job to run
try:
job_wrapper.prepare()
- command_line = job_wrapper.get_command_line()
- if job_wrapper.dependency_shell_commands:
- command_line = "; ".join( job_wrapper.dependency_shell_commands + [ command_line ] )
+ command_line = self.build_command_line( job_wrapper )
except:
job_wrapper.fail( "failure preparing job", exception=True )
log.exception("failure running job %d" % job_wrapper.job_id)
--- a/lib/galaxy/jobs/runners/sge.py
+++ b/lib/galaxy/jobs/runners/sge.py
@@ -2,6 +2,8 @@ import os, logging, threading, time
from Queue import Queue, Empty
from galaxy import model
+from galaxy.jobs.runners import BaseJobRunner
+
from paste.deploy.converters import asbool
import pkg_resources
@@ -58,7 +60,7 @@ class SGEJobState( object ):
self.efile = None
self.runner_url = None
-class SGEJobRunner( object ):
+class SGEJobRunner( BaseJobRunner ):
"""
Job runner backed by a finite pool of worker threads. FIFO scheduling
"""
@@ -144,7 +146,7 @@ class SGEJobRunner( object ):
try:
job_wrapper.prepare()
- command_line = job_wrapper.get_command_line()
+ command_line = self.build_command_line( job_wrapper, include_metadata = True )
except:
job_wrapper.fail( "failure preparing job", exception=True )
log.exception("failure running job %d" % job_wrapper.job_id)
@@ -191,14 +193,7 @@ class SGEJobRunner( object ):
jt.nativeSpecification = ' '.join(nativeSpec)
script = sge_template % (job_wrapper.galaxy_lib_dir, os.path.abspath( job_wrapper.working_directory ), command_line)
- if self.app.config.set_metadata_externally:
- script += "cd %s\n" % os.path.abspath( os.getcwd() )
- script += "%s\n" % job_wrapper.setup_external_metadata( exec_dir = os.path.abspath( os.getcwd() ),
- tmp_dir = self.app.config.new_file_path,
- dataset_files_path = self.app.model.Dataset.file_path,
- output_fnames = job_wrapper.get_output_fnames(),
- set_extension = False,
- kwds = { 'overwrite' : False } ) #we don't want to overwrite metadata that was copied over in init_meta(), as per established behavior
+
fh = file( jt.remoteCommand, "w" )
fh.write( script )
fh.close()
--- a/lib/galaxy/jobs/runners/drmaa.py
+++ b/lib/galaxy/jobs/runners/drmaa.py
@@ -2,6 +2,8 @@ import os, logging, threading, time
from Queue import Queue, Empty
from galaxy import model
+from galaxy.jobs.runners import BaseJobRunner
+
from paste.deploy.converters import asbool
import pkg_resources
@@ -58,7 +60,7 @@ class DRMAAJobState( object ):
self.efile = None
self.runner_url = None
-class DRMAAJobRunner( object ):
+class DRMAAJobRunner( BaseJobRunner ):
"""
Job runner backed by a finite pool of worker threads. FIFO scheduling
"""
@@ -120,7 +122,7 @@ class DRMAAJobRunner( object ):
try:
job_wrapper.prepare()
- command_line = job_wrapper.get_command_line()
+ command_line = self.build_command_line( job_wrapper, include_metadata=True )
except:
job_wrapper.fail( "failure preparing job", exception=True )
log.exception("failure running job %d" % job_wrapper.job_id)
@@ -154,14 +156,6 @@ class DRMAAJobRunner( object ):
jt.nativeSpecification = native_spec
script = drm_template % (job_wrapper.galaxy_lib_dir, os.path.abspath( job_wrapper.working_directory ), command_line)
- if self.app.config.set_metadata_externally:
- script += "cd %s\n" % os.path.abspath( os.getcwd() )
- script += "%s\n" % job_wrapper.setup_external_metadata( exec_dir = os.path.abspath( os.getcwd() ),
- tmp_dir = self.app.config.new_file_path,
- dataset_files_path = self.app.model.Dataset.file_path,
- output_fnames = job_wrapper.get_output_fnames(),
- set_extension = False,
- kwds = { 'overwrite' : False } ) #we don't want to overwrite metadata that was copied over in init_meta(), as per established behavior
fh = file( jt.remoteCommand, "w" )
fh.write( script )
fh.close()
--- a/lib/galaxy/jobs/runners/pbs.py
+++ b/lib/galaxy/jobs/runners/pbs.py
@@ -5,6 +5,7 @@ from Queue import Queue, Empty
from galaxy import model
from galaxy.datatypes.data import nice_size
from galaxy.util.bunch import Bunch
+from galaxy.jobs.runners import BaseJobRunner
from paste.deploy.converters import asbool
@@ -80,7 +81,7 @@ class PBSJobState( object ):
self.check_count = 0
self.stop_job = False
-class PBSJobRunner( object ):
+class PBSJobRunner( BaseJobRunner ):
"""
Job runner backed by a finite pool of worker threads. FIFO scheduling
"""
@@ -183,7 +184,7 @@ class PBSJobRunner( object ):
try:
job_wrapper.prepare()
- command_line = job_wrapper.get_command_line()
+ command_line = self.build_command_line( job_wrapper, include_metadata=not( self.app.config.pbs_stage_path ) )
except:
job_wrapper.fail( "failure preparing job", exception=True )
log.exception("failure running job %d" % job_wrapper.job_id)
@@ -253,14 +254,6 @@ class PBSJobRunner( object ):
script = pbs_symlink_template % (job_wrapper.galaxy_lib_dir, " ".join(job_wrapper.get_input_fnames() + output_files), self.app.config.pbs_stage_path, exec_dir, command_line)
else:
script = pbs_template % ( job_wrapper.galaxy_lib_dir, exec_dir, command_line )
- if self.app.config.set_metadata_externally:
- script += "cd %s\n" % os.path.abspath( os.getcwd() )
- script += "%s\n" % job_wrapper.setup_external_metadata( exec_dir = os.path.abspath( os.getcwd() ),
- tmp_dir = self.app.config.new_file_path,
- dataset_files_path = self.app.model.Dataset.file_path,
- output_fnames = output_fnames,
- set_extension = False,
- kwds = { 'overwrite' : False } ) #we don't want to overwrite metadata that was copied over in init_meta(), as per established behavior
job_file = "%s/%s.sh" % (self.app.config.cluster_files_directory, job_wrapper.job_id)
fh = file(job_file, "w")
fh.write(script)
1
0
galaxy-dist commit 9545e8675a5d: Fix uploads when ftp_file is not defined.
by commits-noreply@bitbucket.org 20 Nov '10
by commits-noreply@bitbucket.org 20 Nov '10
20 Nov '10
# HG changeset patch -- Bitbucket.org
# Project galaxy-dist
# URL http://bitbucket.org/galaxy/galaxy-dist/overview
# User Nate Coraor <nate(a)bx.psu.edu>
# Date 1288978480 14400
# Node ID 9545e8675a5d43408d75c66fcf3115cbdaf4af8a
# Parent 7e9ae46051057d822aff82a9b1f3aec0200086f2
Fix uploads when ftp_file is not defined.
--- a/lib/galaxy/tools/parameters/grouping.py
+++ b/lib/galaxy/tools/parameters/grouping.py
@@ -287,7 +287,7 @@ class UploadDataset( Group ):
rval.append( file_bunch )
# look for files uploaded via FTP
valid_files = []
- if ftp_files:
+ if ftp_files is not None:
if trans.user is None:
log.warning( 'Anonymous user passed values in ftp_files: %s' % ftp_files )
ftp_files = []
@@ -299,6 +299,8 @@ class UploadDataset( Group ):
path = relpath( os.path.join( dirpath, filename ), user_ftp_dir )
if not os.path.islink( os.path.join( dirpath, filename ) ):
valid_files.append( path )
+ else:
+ ftp_files = []
for ftp_file in ftp_files:
if ftp_file not in valid_files:
log.warning( 'User passed an invalid file path in ftp_files: %s' % ftp_file )
1
0
galaxy-dist commit eb79ab327351: Remove missing hapmapmart tool from sample tool conf
by commits-noreply@bitbucket.org 20 Nov '10
by commits-noreply@bitbucket.org 20 Nov '10
20 Nov '10
# HG changeset patch -- Bitbucket.org
# Project galaxy-dist
# URL http://bitbucket.org/galaxy/galaxy-dist/overview
# User Nate Coraor <nate(a)bx.psu.edu>
# Date 1288983276 14400
# Node ID eb79ab327351e4789a89748269fc34428f791463
# Parent 11abfc8eed60c0bdd231d06992f72001a2c785fa
Remove missing hapmapmart tool from sample tool conf
--- a/tool_conf.xml.sample
+++ b/tool_conf.xml.sample
@@ -319,7 +319,6 @@
<label text="Data: Import and upload" id="rgimport" /><tool file="data_source/upload.xml"/><tool file="data_source/access_libraries.xml" />
- <tool file="data_source/hapmapmart.xml" /><label text="Data: Filter and Clean" id="rgfilter" /><tool file="rgenetics/rgClean.xml"/><tool file="rgenetics/rgPedSub.xml"/>
1
0
galaxy-dist commit 7e9ae4605105: Add a new "Files uploaded via FTP" grid to the upload form and related parameter types, form fields, etc.
by commits-noreply@bitbucket.org 20 Nov '10
by commits-noreply@bitbucket.org 20 Nov '10
20 Nov '10
# HG changeset patch -- Bitbucket.org
# Project galaxy-dist
# URL http://bitbucket.org/galaxy/galaxy-dist/overview
# User Nate Coraor <nate(a)bx.psu.edu>
# Date 1288969490 14400
# Node ID 7e9ae46051057d822aff82a9b1f3aec0200086f2
# Parent cdd6ce1f38b0e22802ed63e3e0cb4f6a58cb93b2
Add a new "Files uploaded via FTP" grid to the upload form and related parameter types, form fields, etc.
--- a/tools/data_source/upload.xml
+++ b/tools/data_source/upload.xml
@@ -1,6 +1,6 @@
<?xml version="1.0"?>
-<tool name="Upload File" id="upload1" version="1.1.1">
+<tool name="Upload File" id="upload1" version="1.1.2"><description>
from your computer
</description>
@@ -29,6 +29,7 @@
<validator type="expression" message="You will need to reselect the file you specified (%s)." substitute_value_in_message="True">not ( ( isinstance( value, unicode ) or isinstance( value, str ) ) and value != "" )</validator><!-- use validator to post message to user about needing to reselect the file, since most browsers won't accept the value attribute for file inputs --></param><param name="url_paste" type="text" area="true" size="5x35" label="URL/Text" help="Here you may specify a list of URLs (one per line) or paste the contents of a file."/>
+ <param name="ftp_files" type="ftpfile" label="Files uploaded via FTP"/><param name="space_to_tab" type="select" display="checkboxes" multiple="True" label="Convert spaces to tabs" help="Use this option if you are entering intervals by hand."><option value="Yes">Yes</option></param>
--- a/lib/galaxy/web/form_builder.py
+++ b/lib/galaxy/web/form_builder.py
@@ -2,9 +2,10 @@
Classes for generating HTML forms
"""
-import logging,sys
+import logging, sys, os, time
from cgi import escape
-from galaxy.util import restore_text
+from galaxy.util import restore_text, relpath, nice_size
+from galaxy.web import url_for
log = logging.getLogger(__name__)
@@ -145,6 +146,68 @@ class FileField(BaseField):
ajax_text = ' galaxy-ajax-upload="true"'
return '<input type="file" name="%s%s"%s%s>' % ( prefix, self.name, ajax_text, value_text )
+class FTPFileField(BaseField):
+ """
+ An FTP file upload input.
+ """
+ thead = '''
+ <table id="grid-table" class="grid">
+ <thead id="grid-table-header">
+ <tr>
+ <th id="select-header"></th>
+ <th id="name-header">
+ File
+ </th>
+ <th id="size-header">
+ Size
+ </th>
+ <th id="date-header">
+ Date
+ </th>
+ </tr>
+ </thead>
+ <tbody id="grid-table-body">
+ '''
+ trow = '''
+ <tr>
+ <td><input type="checkbox" name="%s%s" value="%s"/></td>
+ <td>%s</td>
+ <td>%s</td>
+ <td>%s</td>
+ </tr>
+ '''
+ tfoot = '''
+ </tbody>
+ </table>
+ '''
+ def __init__( self, name, dir, ftp_site, value = None ):
+ self.name = name
+ self.dir = dir
+ self.ftp_site = ftp_site
+ self.value = value
+ def get_html( self, prefix="" ):
+ rval = FTPFileField.thead
+ if self.dir is None:
+ rval += '<tr><td colspan="3"><em>Please <a href="%s">create</a> or <a href="%s">log in to</a> a Galaxy account to view files uploaded via FTP.</em></td></tr>' % ( url_for( controller='user', action='create', referer=url_for( controller='root' ) ), url_for( controller='user', action='login', referer=url_for( controller='root' ) ) )
+ elif not os.path.exists( self.dir ):
+ rval += '<tr><td colspan="3"><em>Your FTP upload directory contains no files.</em></td></tr>'
+ else:
+ uploads = []
+ for ( dirpath, dirnames, filenames ) in os.walk( self.dir ):
+ for filename in filenames:
+ path = relpath( os.path.join( dirpath, filename ), self.dir )
+ statinfo = os.lstat( os.path.join( dirpath, filename ) )
+ uploads.append( dict( path=path,
+ size=nice_size( statinfo.st_size ),
+ ctime=time.strftime( "%m/%d/%Y %I:%M:%S %p", time.localtime( statinfo.st_ctime ) ) ) )
+ if not uploads:
+ rval += '<tr><td colspan="3"><em>Your FTP upload directory contains no files.</em></td></tr>'
+ for upload in uploads:
+ rval += FTPFileField.trow % ( prefix, self.name, upload['path'], upload['path'], upload['size'], upload['ctime'] )
+ rval += FTPFileField.tfoot
+ rval += '<div class="toolParamHelp">This Galaxy server allows you to upload files via FTP. To upload some files, log in to the FTP server at <strong>%s</strong> using your Galaxy credentials (email address and password).</div>' % self.ftp_site
+ return rval
+
class HiddenField(BaseField):
"""
A hidden field.
--- a/lib/galaxy/tools/parameters/basic.py
+++ b/lib/galaxy/tools/parameters/basic.py
@@ -40,6 +40,11 @@ class ToolParameter( object ):
for elem in param.findall("validator"):
self.validators.append( validation.Validator.from_element( self, elem ) )
+ @property
+ def visible( self ):
+ """Return true if the parameter should be rendered on the form"""
+ return True
+
def get_label( self ):
"""Return user friendly name for the parameter"""
if self.label: return self.label
@@ -362,6 +367,41 @@ class FileToolParameter( ToolParameter )
def get_initial_value( self, trans, context ):
return None
+class FTPFileToolParameter( ToolParameter ):
+ """
+ Parameter that takes a file uploaded via FTP as a value.
+ """
+ def __init__( self, tool, elem ):
+ """
+ Example: C{<param name="bins" type="file" />}
+ """
+ ToolParameter.__init__( self, tool, elem )
+ @property
+ def visible( self ):
+ if self.tool.app.config.ftp_upload_dir is None or self.tool.app.config.ftp_upload_site is None:
+ return False
+ return True
+ def get_html_field( self, trans=None, value=None, other_values={} ):
+ if trans is None or trans.user is None:
+ user_ftp_dir = None
+ else:
+ user_ftp_dir = os.path.join( trans.app.config.ftp_upload_dir, trans.user.email )
+ return form_builder.FTPFileField( self.name, user_ftp_dir, trans.app.config.ftp_upload_site, value = value )
+ def from_html( self, value, trans=None, other_values={} ):
+ return util.listify( value )
+ def to_string( self, value, app ):
+ if value in [ None, '' ]:
+ return None
+ elif isinstance( value, unicode ) or isinstance( value, str ) or isinstance( value, list ):
+ return value
+ def to_python( self, value, app ):
+ if value is None:
+ return None
+ elif isinstance( value, unicode ) or isinstance( value, str ) or isinstance( value, list ):
+ return value
+ def get_initial_value( self, trans, context ):
+ return None
+
class HiddenToolParameter( ToolParameter ):
"""
Parameter that takes one of two values.
@@ -1427,6 +1467,7 @@ parameter_types = dict( text = Te
hidden = HiddenToolParameter,
baseurl = BaseURLToolParameter,
file = FileToolParameter,
+ ftpfile = FTPFileToolParameter,
data = DataToolParameter,
drill_down = DrillDownSelectToolParameter )
--- a/lib/galaxy/util/__init__.py
+++ b/lib/galaxy/util/__init__.py
@@ -480,6 +480,32 @@ def umask_fix_perms( path, umask, unmask
current_group,
e ) )
+def nice_size(size):
+ """
+ Returns a readably formatted string with the size
+
+ >>> nice_size(100)
+ '100.0 bytes'
+ >>> nice_size(10000)
+ '9.8 Kb'
+ >>> nice_size(1000000)
+ '976.6 Kb'
+ >>> nice_size(100000000)
+ '95.4 Mb'
+ """
+ words = [ 'bytes', 'Kb', 'Mb', 'Gb' ]
+ try:
+ size = float( size )
+ except:
+ return '??? bytes'
+ for ind, word in enumerate(words):
+ step = 1024 ** (ind + 1)
+ if step > size:
+ size = size / float(1024 ** ind)
+ out = "%.1f %s" % (size, word)
+ return out
+ return '??? bytes'
+
galaxy_root_path = os.path.join(__path__[0], "..","..","..")
# The dbnames list is used in edit attributes and the upload tool
dbnames = read_dbnames( os.path.join( galaxy_root_path, "tool-data", "shared", "ucsc", "builds.txt" ) )
--- a/universe_wsgi.ini.sample
+++ b/universe_wsgi.ini.sample
@@ -324,6 +324,18 @@ use_interactive = True
# Enable the (experimental! beta!) Web API. Documentation forthcoming.
#enable_api = False
+# Enable Galaxy's "Upload via FTP" interface. You'll need to install and
+# configure an FTP server (we've used ProFTPd since it can use Galaxy's
+# database for authentication) and set the following two options.
+
+# This should point to a directory containing subdirectories matching users'
+# email addresses, where Galaxy will look for files.
+#ftp_upload_dir = None
+
+# This should be the hostname of your FTP server, which will be provided to
+# users in the help text.
+#ftp_upload_site = None
+
# -- Job Execution
# If running multiple Galaxy processes, one can be designated as the job
--- a/templates/tool_form.mako
+++ b/templates/tool_form.mako
@@ -51,7 +51,9 @@ function checkUncheckAll( name, check )
<%def name="do_inputs( inputs, tool_state, errors, prefix, other_values=None )"><% other_values = ExpressionContext( tool_state, other_values ) %>
%for input_index, input in enumerate( inputs.itervalues() ):
- %if input.type == "repeat":
+ %if not input.visible:
+ <% pass %>
+ %elif input.type == "repeat":
<div class="repeat-group"><div class="form-title-row"><b>${input.title_plural}</b></div><% repeat_state = tool_state[input.name] %>
--- a/lib/galaxy/tools/__init__.py
+++ b/lib/galaxy/tools/__init__.py
@@ -929,7 +929,11 @@ class Tool:
assert isinstance( out_data, odict )
return 'tool_executed.mako', dict( out_data=out_data )
except:
- return 'message.mako', dict( status='error', message='odict not returned from tool execution', refresh_frames=[] )
+ if isinstance( out_data, str ):
+ message = out_data
+ else:
+ message = 'Failure executing tool (odict not returned from tool execution)'
+ return 'message.mako', dict( status='error', message=message, refresh_frames=[] )
# Otherwise move on to the next page
else:
state.page += 1
--- a/lib/galaxy/tools/parameters/grouping.py
+++ b/lib/galaxy/tools/parameters/grouping.py
@@ -12,11 +12,14 @@ import StringIO, os, urllib
from galaxy.datatypes import sniff
from galaxy.util.bunch import Bunch
from galaxy.util.odict import odict
-from galaxy.util import json
+from galaxy.util import json, relpath
class Group( object ):
def __init__( self ):
self.name = None
+ @property
+ def visible( self ):
+ return True
def value_to_basic( self, value, app ):
"""
Convert value to a (possibly nested) representation using only basic
@@ -267,6 +270,7 @@ class UploadDataset( Group ):
rval = []
data_file = context['file_data']
url_paste = context['url_paste']
+ ftp_files = context['ftp_files']
name = context.get( 'NAME', None )
info = context.get( 'INFO', None )
space_to_tab = False
@@ -281,6 +285,31 @@ class UploadDataset( Group ):
if file_bunch.path:
file_bunch.space_to_tab = space_to_tab
rval.append( file_bunch )
+ # look for files uploaded via FTP
+ valid_files = []
+ if ftp_files:
+ if trans.user is None:
+ log.warning( 'Anonymous user passed values in ftp_files: %s' % ftp_files )
+ ftp_files = []
+ # TODO: warning to the user (could happen if session has become invalid)
+ else:
+ user_ftp_dir = os.path.join( trans.app.config.ftp_upload_dir, trans.user.email )
+ for ( dirpath, dirnames, filenames ) in os.walk( user_ftp_dir ):
+ for filename in filenames:
+ path = relpath( os.path.join( dirpath, filename ), user_ftp_dir )
+ if not os.path.islink( os.path.join( dirpath, filename ) ):
+ valid_files.append( path )
+ for ftp_file in ftp_files:
+ if ftp_file not in valid_files:
+ log.warning( 'User passed an invalid file path in ftp_files: %s' % ftp_file )
+ continue
+ # TODO: warning to the user (could happen if file is already imported)
+ ftp_data_file = { 'local_filename' : os.path.abspath( os.path.join( user_ftp_dir, ftp_file ) ),
+ 'filename' : os.path.basename( ftp_file ) }
+ file_bunch = get_data_file_filename( ftp_data_file, override_name = name, override_info = info )
+ if file_bunch.path:
+ file_bunch.space_to_tab = space_to_tab
+ rval.append( file_bunch )
return rval
file_type = self.get_file_type( context )
d_type = self.get_datatype( trans, context )
--- a/static/june_2007_style/blue/base.css
+++ b/static/june_2007_style/blue/base.css
@@ -39,8 +39,7 @@ div.form-title-row{padding:5px 10px;}
div.repeat-group-item{border-left:solid #d8b365 5px;margin-left:10px;margin-bottom:10px;}
div.form-row-error{background:#FFCCCC;}
div.form-row label{font-weight:bold;display:block;margin-bottom:.2em;}
-div.form-row-input{float:left;width:300px;}
-div.form-row-input > input{max-width:300px;}
+div.form-row-input{float:left;}
div.form-row-input label{font-weight:normal;display:inline;}
div.form-row-error-message{width:300px;float:left;color:red;font-weight:bold;padding:3px 0 0 1em;}
select,input,textarea{font:inherit;font-size:115%;}
--- a/lib/galaxy/datatypes/data.py
+++ b/lib/galaxy/datatypes/data.py
@@ -419,36 +419,16 @@ class Newick( Text ):
# ------------- Utility methods --------------
+# nice_size used to be here, but to resolve cyclical dependencies it's been
+# moved to galaxy.util. It belongs there anyway since it's used outside
+# datatypes.
+nice_size = util.nice_size
+
def get_test_fname( fname ):
"""Returns test data filename"""
path, name = os.path.split(__file__)
full_path = os.path.join( path, 'test', fname )
return full_path
-def nice_size(size):
- """
- Returns a readably formatted string with the size
-
- >>> nice_size(100)
- '100.0 bytes'
- >>> nice_size(10000)
- '9.8 Kb'
- >>> nice_size(1000000)
- '976.6 Kb'
- >>> nice_size(100000000)
- '95.4 Mb'
- """
- words = [ 'bytes', 'Kb', 'Mb', 'Gb' ]
- try:
- size = float( size )
- except:
- return '??? bytes'
- for ind, word in enumerate(words):
- step = 1024 ** (ind + 1)
- if step > size:
- size = size / float(1024 ** ind)
- out = "%.1f %s" % (size, word)
- return out
- return '??? bytes'
def get_file_peek( file_name, is_multi_byte=False, WIDTH=256, LINE_COUNT=5 ):
"""
Returns the first LINE_COUNT lines wrapped to WIDTH
--- a/lib/galaxy/tools/actions/upload.py
+++ b/lib/galaxy/tools/actions/upload.py
@@ -21,7 +21,7 @@ class UploadToolAction( ToolAction ):
upload_common.cleanup_unused_precreated_datasets( precreated_datasets )
if not uploaded_datasets:
- return 'No data was entered in the upload form, please go back and choose data to upload.'
+ return None, 'No data was entered in the upload form, please go back and choose data to upload.'
json_file_path = upload_common.create_paramfile( trans, uploaded_datasets )
data_list = [ ud.data for ud in uploaded_datasets ]
--- a/lib/galaxy/config.py
+++ b/lib/galaxy/config.py
@@ -99,6 +99,10 @@ class Configuration( object ):
self.user_library_import_dir = kwargs.get( 'user_library_import_dir', None )
if self.user_library_import_dir is not None and not os.path.exists( self.user_library_import_dir ):
raise ConfigurationError( "user_library_import_dir specified in config (%s) does not exist" % self.user_library_import_dir )
+ self.ftp_upload_dir = kwargs.get( 'ftp_upload_dir', None )
+ if self.ftp_upload_dir is not None and not os.path.exists( self.ftp_upload_dir ):
+ os.makedirs( self.ftp_upload_dir )
+ self.ftp_upload_site = kwargs.get( 'ftp_upload_site', None )
self.allow_library_path_paste = kwargs.get( 'allow_library_path_paste', False )
self.disable_library_comptypes = kwargs.get( 'disable_library_comptypes', '' ).lower().split( ',' )
# Location for dependencies
--- a/static/june_2007_style/base.css.tmpl
+++ b/static/june_2007_style/base.css.tmpl
@@ -212,11 +212,6 @@ div.form-row label {
div.form-row-input {
float: left;
- width: 300px;
-}
-
-div.form-row-input > input {
- max-width: 300px;
}
div.form-row-input label {
1
0
galaxy-dist commit b1ec8342053f: Adding NGS simulation tool
by commits-noreply@bitbucket.org 20 Nov '10
by commits-noreply@bitbucket.org 20 Nov '10
20 Nov '10
# HG changeset patch -- Bitbucket.org
# Project galaxy-dist
# URL http://bitbucket.org/galaxy/galaxy-dist/overview
# User Kelly Vincent <kpvincent(a)bx.psu.edu>
# Date 1288806772 14400
# Node ID b1ec8342053f3cdcd0a081ff28f077a76bd188cc
# Parent 9d68027b01096e2b32101234878d11946c03d08c
Adding NGS simulation tool
--- /dev/null
+++ b/tool-data/ngs_sim_fasta.loc.sample
@@ -0,0 +1,20 @@
+#This is a sample file distributed with Galaxy that enables the NGS simulation
+#tool to use some FASTA files. You will need to make sure that these FASTA files
+#are in place and then create the ngs_sim.loc file similar to this one (store it
+#in this directory) that points to the locations of those files. The ngs_sim.loc
+#file has this format (white space characters are TAB characters):
+#
+#<unique_build_id><dbkey><display_name><file_base_path>
+#
+#So, for example, if you had hg18chrM.fa in
+#/data/path/hg18/seq/,
+#then the ngs_sim.loc entry would look like this:
+#
+#hg18chrM hg18 hg18chrM /data/path/hg18/seq/hg18chrM.fa
+#
+#Your ngs_sim.loc file should include an entry per line for each FASTA file you
+#have stored.
+#
+#hg18chrM hg18 hg18chrM /data/path/hg18/seq/hg18chrM.fa
+#phiX174 phiX phiX174 /data/path/genome/phiX/seq/phiX.fa
+#pUC18 pUC18 pUC18 /data/path/genome/pUC18/seq/pUC18.fa
Binary file test-data/ngs_simulation_out3.png has changed
--- /dev/null
+++ b/tools/ngs_simulation/ngs_simulation.xml
@@ -0,0 +1,217 @@
+<tool id="ngs_simulation" name="Simulate" version="1.0.0">
+<!--<tool id="ngs_simulation" name="Simulate" force_history_refresh="True" version="1.0.0">-->
+ <description>Illumina runs</description>
+ <command interpreter="python">
+ ngs_simulation.py
+ #if $in_type.input_type == "built-in"
+ --input="${ filter( lambda x: str( x[0] ) == str( $in_type.genome ), $__app__.tool_data_tables[ 'ngs_sim_fasta' ].get_fields() )[0][-1] }"
+ --genome=$genome
+ #else
+ --input=$in_type.input1
+ #end if
+ --read_len=$read_len
+ --avg_coverage=$avg_coverage
+ --error_rate=$error_rate
+ --num_sims=$num_sims
+ --polymorphism=$polymorphism
+ --detection_thresh=$detection_thresh
+ --output_png=$output_png
+ --summary_out=$summary_out
+ --output_summary=$output_summary
+ --new_file_path=$__new_file_path__
+ </command>
+<!-- If want to include all simulation results file
+ sim_results=$sim_results
+ output=$output.id
+-->
+ <inputs>
+ <conditional name="in_type">
+ <param name="input_type" type="select" label="Use a built-in FASTA file or one from the history?">
+ <option value="built-in">Built-in</option>
+ <option value="history">History file</option>
+ </param>
+ <when value="built-in">
+ <param name="genome" type="select" label="Select a built-in genome" help="if your genome of interest is not listed - contact Galaxy team">
+ <options from_data_table="ngs_sim_fasta" />
+ </param>
+ </when>
+ <when value="history">
+ <param name="input1" type="data" format="fasta" label="Input genome (FASTA format)" />
+ </when>
+ </conditional>
+ <param name="read_len" type="integer" value="76" label="Read length" />
+ <param name="avg_coverage" type="integer" value="200" label="Average coverage" />
+ <param name="error_rate" type="float" value="0.001" label="Error rate or quality score" help="Quality score if integer 1 or greater; error rate if between 0 and 1" />
+ <param name="num_sims" type="integer" value="100" label="The number of simulations to run" />
+ <param name="polymorphism" type="select" multiple="true" label="Frequency/ies for minor allele">
+ <option value="0.001">0.001</option>
+ <option value="0.002">0.002</option>
+ <option value="0.003">0.003</option>
+ <option value="0.004">0.004</option>
+ <option value="0.005">0.005</option>
+ <option value="0.006">0.006</option>
+ <option value="0.007">0.007</option>
+ <option value="0.008">0.008</option>
+ <option value="0.009">0.009</option>
+ <option value="0.01">0.01</option>
+ <option value="0.02">0.02</option>
+ <option value="0.03">0.03</option>
+ <option value="0.04">0.04</option>
+ <option value="0.05">0.05</option>
+ <option value="0.06">0.06</option>
+ <option value="0.07">0.07</option>
+ <option value="0.08">0.08</option>
+ <option value="0.09">0.09</option>
+ <option value="0.1">0.1</option>
+ <option value="0.2">0.2</option>
+ <option value="0.3">0.3</option>
+ <option value="0.4">0.4</option>
+ <option value="0.5">0.5</option>
+ <option value="0.6">0.6</option>
+ <option value="0.7">0.7</option>
+ <option value="0.8">0.8</option>
+ <option value="0.9">0.9</option>
+ <option value="1.0">1.0</option>
+ </param>
+ <param name="detection_thresh" type="select" multiple="true" label="Detection thresholds">
+ <option value="0.001">0.001</option>
+ <option value="0.002">0.002</option>
+ <option value="0.003">0.003</option>
+ <option value="0.004">0.004</option>
+ <option value="0.005">0.005</option>
+ <option value="0.006">0.006</option>
+ <option value="0.007">0.007</option>
+ <option value="0.008">0.008</option>
+ <option value="0.009">0.009</option>
+ <option value="0.01">0.01</option>
+ <option value="0.02">0.02</option>
+ <option value="0.03">0.03</option>
+ <option value="0.04">0.04</option>
+ <option value="0.05">0.05</option>
+ <option value="0.06">0.06</option>
+ <option value="0.07">0.07</option>
+ <option value="0.08">0.08</option>
+ <option value="0.09">0.09</option>
+ <option value="0.1">0.1</option>
+ <option value="0.2">0.2</option>
+ <option value="0.3">0.3</option>
+ <option value="0.4">0.4</option>
+ <option value="0.5">0.5</option>
+ <option value="0.6">0.6</option>
+ <option value="0.7">0.7</option>
+ <option value="0.8">0.8</option>
+ <option value="0.9">0.9</option>
+ <option value="1.0">1.0</option>
+ </param>
+ <param name="summary_out" type="boolean" truevalue="true" falsevalue="false" checked="true" label="Include a (text) summary file for all the simulations" />
+<!-- <param name="sim_results" type="boolean" truevalue="true" falsevalue="false" checked="false" label="Output all tabular simulation results" help="Number of polymorphisms times number of detection thresholds"/>
+-->
+ </inputs>
+ <outputs>
+ <data format="png" name="output_png" />
+ <data format="tabular" name="output_summary">
+ <filter>summary_out == True</filter>
+ </data>
+<!--
+ <data format="tabular" name="output">
+ <filter>sim_files_out</filter>
+ </data>
+-->
+ </outputs>
+ <tests>
+ <!--
+ Tests cannot be run because of the non-deterministic element of the simulation.
+ But if you run the following "tests" manually in the browser and check against
+ the output files, they should be very similar to the listed output files.
+ -->
+ <!--
+ <test>
+ <param name="input_type" value="history" />
+ <param name="input1" value="ngs_simulation_in1.fasta" ftype="fasta" />
+ <param name="read_len" value="76" />
+ <param name="avg_coverage" value="200" />
+ <param name="error_rate" value="0.001" />
+ <param name="num_sims" value="25" />
+ <param name="polymorphism" value="0.02,0.04,0.1" />
+ <param name="detection_thresh" value="0.01,0.02" />
+ <param name="summary_out" value="true" />
+ <output name="output_png" file="ngs_simulation_out1.png" />
+ <output name="output_summary" file="ngs_simulation_out2.tabular" />
+ </test>
+ <test>
+ <param name="input_type" value="built-in" />
+ <param name="genome" value="pUC18" />
+ <param name="read_len" value="50" />
+ <param name="avg_coverage" value="150" />
+ <param name="error_rate" value="0.005" />
+ <param name="num_sims" value="25" />
+ <param name="polymorphism" value="0.001,0.005" />
+ <param name="detection_thresh" value="0.001,0.002" />
+ <param name="summary_out" value="false" />
+ <output name="output_png" file="ngs_simulation_out3.png" />
+ </test>
+ -->
+ </tests>
+ <help>
+
+**What it does**
+
+This tool simulates an Illumina run and provides plots of false positives and false negatives. It allows for a range of simulation parameters to be set. Note that this simulation sets only one (randomly chosen) position in the genome as polymorphic, according to the value specified. Superimposed on this are "sequencing errors", which are uniformly (and randomly) distributed. Polymorphisms are assigned using the detection threshold, so if the detection threshold is set to the same as the minor allele frequency, the expected false negative rate is 50%.
+
+**Parameter list**
+
+These are the parameters that should be set for the simulation::
+
+ Read length (which is the same for all reads)
+ Average Coverage
+ Frequency for Minor Allele
+ Sequencing Error Rate
+ Detection Threshold
+ Number of Simulations
+
+You also should choose to use either a built-in genome or supply your own FASTA file.
+
+**Output**
+
+There are one or two. The first is a png that contains two different plots and is always generated. The second is optional and is a text file with some summary information about the simulations that were run. Below are some example outputs for a 10-simulation run on phiX with the default settings::
+
+ Read length 76
+ Average coverage 200
+ Error rate/quality score 0.001
+ Number of simulations 100
+ Frequencies for minor allele 0.002
+ 0.004
+ Detection thresholds 0.003
+ 0.005
+ 0.007
+ Include summary file Yes
+
+Plot output (png):
+
+.. image:: ../static/images/ngs_simulation.png
+
+Summary output (txt)::
+
+ FP FN GENOMESIZE.5386 fprate hetcol errcol
+ Min. : 71.0 Min. :0.0 Mode:logical Min. :0.01318 Min. :0.004 Min. :0.007
+ 1st Qu.:86.0 1st Qu.:1.0 NA's:10 1st Qu.:0.01597 1st Qu.:0.004 1st Qu.:0.007
+ Median :92.5 Median :1.0 NA Median :0.01717 Median :0.004 Median :0.007
+ Mean :93.6 Mean :0.9 NA Mean :0.01738 Mean :0.004 Mean :0.007
+ 3rd Qu.:100.8 3rd Qu.:1.0 NA 3rd Qu.:0.01871 3rd Qu.:0.004 3rd Qu.:0.007
+ Max. :123.0 Max. :1.0 NA Max. :0.02284 Max. :0.004 Max. :0.007
+
+ False Positive Rate Summary
+ 0.003 0.005 0.007
+ 0.001 0.17711 0.10854 0.01673
+ 0.009 0.18049 0.10791 0.01738
+
+ False Negative Rate Summary
+ 0.003 0.005 0.007
+ 0.001 1.0 0.8 1.0
+ 0.009 0.4 0.7 0.9
+
+
+ </help>
+</tool>
+
+
Binary file test-data/ngs_simulation_out1.png has changed
--- a/tool_conf.xml.sample
+++ b/tool_conf.xml.sample
@@ -312,6 +312,9 @@
<tool file="genetrack/genetrack_indexer.xml" /><tool file="genetrack/genetrack_peak_prediction.xml" /></section>
+ <section name="NGS: Simulation" id="ngs-simulation">
+ <tool file="ngs_simulation/ngs_simulation.xml" />
+ </section><section name="SNP/WGA: Data; Filters" id="rgdat"><label text="Data: Import and upload" id="rgimport" /><tool file="data_source/upload.xml"/>
--- /dev/null
+++ b/test-data/ngs_simulation_in1.fasta
@@ -0,0 +1,41 @@
+>gi|209210|gb|L09136.1|SYNPUC18CV pUC18c cloning vector (beta-galactosidase mRNA on complementary strand)
+TCGCGCGTTTCGGTGATGACGGTGAAAACCTCTGACACATGCAGCTCCCGGAGACGGTCACAGCTTGTCT
+GTAAGCGGATGCCGGGAGCAGACAAGCCCGTCAGGGCGCGTCAGCGGGTGTTGGCGGGTGTCGGGGCTGG
+CTTAACTATGCGGCATCAGAGCAGATTGTACTGAGAGTGCACCATATGCGGTGTGAAATACCGCACAGAT
+GCGTAAGGAGAAAATACCGCATCAGGCGCCATTCGCCATTCAGGCTGCGCAACTGTTGGGAAGGGCGATC
+GGTGCGGGCCTCTTCGCTATTACGCCAGCTGGCGAAAGGGGGATGTGCTGCAAGGCGATTAAGTTGGGTA
+ACGCCAGGGTTTTCCCAGTCACGACGTTGTAAAACGACGGCCAGTGCCAAGCTTGCATGCCTGCAGGTCG
+ACTCTAGAGGATCCCCGGGTACCGAGCTCGAATTCGTAATCATGGTCATAGCTGTTTCCTGTGTGAAATT
+GTTATCCGCTCACAATTCCACACAACATACGAGCCGGAAGCATAAAGTGTAAAGCCTGGGGTGCCTAATG
+AGTGAGCTAACTCACATTAATTGCGTTGCGCTCACTGCCCGCTTTCCAGTCGGGAAACCTGTCGTGCCAG
+CTGCATTAATGAATCGGCCAACGCGCGGGGAGAGGCGGTTTGCGTATTGGGCGCTCTTCCGCTTCCTCGC
+TCACTGACTCGCTGCGCTCGGTCGTTCGGCTGCGGCGAGCGGTATCAGCTCACTCAAAGGCGGTAATACG
+GTTATCCACAGAATCAGGGGATAACGCAGGAAAGAACATGTGAGCAAAAGGCCAGCAAAAGGCCAGGAAC
+CGTAAAAAGGCCGCGTTGCTGGCGTTTTTCCATAGGCTCCGCCCCCCTGACGAGCATCACAAAAATCGAC
+GCTCAAGTCAGAGGTGGCGAAACCCGACAGGACTATAAAGATACCAGGCGTTTCCCCCTGGAAGCTCCCT
+CGTGCGCTCTCCTGTTCCGACCCTGCCGCTTACCGGATACCTGTCCGCCTTTCTCCCTTCGGGAAGCGTG
+GCGCTTTCTCATAGCTCACGCTGTAGGTATCTCAGTTCGGTGTAGGTCGTTCGCTCCAAGCTGGGCTGTG
+TGCACGAACCCCCCGTTCAGCCCGACCGCTGCGCCTTATCCGGTAACTATCGTCTTGAGTCCAACCCGGT
+AAGACACGACTTATCGCCACTGGCAGCAGCCACTGGTAACAGGATTAGCAGAGCGAGGTATGTAGGCGGT
+GCTACAGAGTTCTTGAAGTGGTGGCCTAACTACGGCTACACTAGAAGGACAGTATTTGGTATCTGCGCTC
+TGCTGAAGCCAGTTACCTTCGGAAAAAGAGTTGGTAGCTCTTGATCCGGCAAACAAACCACCGCTGGTAG
+CGGTGGTTTTTTTGTTTGCAAGCAGCAGATTACGCGCAGAAAAAAAGGATCTCAAGAAGATCCTTTGATC
+TTTTCTACGGGGTCTGACGCTCAGTGGAACGAAAACTCACGTTAAGGGATTTTGGTCATGAGATTATCAA
+AAAGGATCTTCACCTAGATCCTTTTAAATTAAAAATGAAGTTTTAAATCAATCTAAAGTATATATGAGTA
+AACTTGGTCTGACAGTTACCAATGCTTAATCAGTGAGGCACCTATCTCAGCGATCTGTCTATTTCGTTCA
+TCCATAGTTGCCTGACTCCCCGTCGTGTAGATAACTACGATACGGGAGGGCTTACCATCTGGCCCCAGTG
+CTGCAATGATACCGCGAGACCCACGCTCACCGGCTCCAGATTTATCAGCAATAAACCAGCCAGCCGGAAG
+GGCCGAGCGCAGAAGTGGTCCTGCAACTTTATCCGCCTCCATCCAGTCTATTAATTGTTGCCGGGAAGCT
+AGAGTAAGTAGTTCGCCAGTTAATAGTTTGCGCAACGTTGTTGCCATTGCTACAGGCATCGTGGTGTCAC
+GCTCGTCGTTTGGTATGGCTTCATTCAGCTCCGGTTCCCAACGATCAAGGCGAGTTACATGATCCCCCAT
+GTTGTGCAAAAAAGCGGTTAGCTCCTTCGGTCCTCCGATCGTTGTCAGAAGTAAGTTGGCCGCAGTGTTA
+TCACTCATGGTTATGGCAGCACTGCATAATTCTCTTACTGTCATGCCATCCGTAAGATGCTTTTCTGTGA
+CTGGTGAGTACTCAACCAAGTCATTCTGAGAATAGTGTATGCGGCGACCGAGTTGCTCTTGCCCGGCGTC
+AATACGGGATAATACCGCGCCACATAGCAGAACTTTAAAAGTGCTCATCATTGGAAAACGTTCTTCGGGG
+CGAAAACTCTCAAGGATCTTACCGCTGTTGAGATCCAGTTCGATGTAACCCACTCGTGCACCCAACTGAT
+CTTCAGCATCTTTTACTTTCACCAGCGTTTCTGGGTGAGCAAAAACAGGAAGGCAAAATGCCGCAAAAAA
+GGGAATAAGGGCGACACGGAAATGTTGAATACTCATACTCTTCCTTTTTCAATATTATTGAAGCATTTAT
+CAGGGTTATTGTCTCATGAGCGGATACATATTTGAATGTATTTAGAAAAATAAACAAATAGGGGTTCCGC
+GCACATTTCCCCGAAAAGTGCCACCTGACGTCTAAGAAACCATTATTATCATGACATTAACCTATAAAAA
+TAGGCGTATCACGAGGCCCTTTCGTC
+
--- a/tool_data_table_conf.xml.sample
+++ b/tool_data_table_conf.xml.sample
@@ -1,22 +1,27 @@
<tables>
- <!-- Locations of MAF files that have been indexed with bx-python -->
- <table name="indexed_maf_files">
- <columns>name, value, dbkey, species</columns>
- <file path="tool-data/maf_index.loc" />
+ <!-- Locations of indexes in the BFAST mapper format -->
+ <table name="bfast_indexes" comment_char="#">
+ <columns>value, dbkey, formats, name, path</columns>
+ <file path="tool-data/bfast_indexes.loc" />
+ </table>
+ <!-- Locations of indexes in the Bowtie mapper format -->
+ <table name="bowtie_indexes">
+ <columns>name, value</columns>
+ <file path="tool-data/bowtie_indices.loc" /></table><!-- Locations of indexes in the BWA mapper format --><table name="bwa_indexes"><columns>name, value</columns><file path="tool-data/bwa_index.loc" /></table>
- <!-- Locations of indexes in the Bowtie mapper format -->
- <table name="bowtie_indexes">
- <columns>name, value</columns>
- <file path="tool-data/bowtie_indices.loc" />
+ <!-- Locations of MAF files that have been indexed with bx-python -->
+ <table name="indexed_maf_files">
+ <columns>name, value, dbkey, species</columns>
+ <file path="tool-data/maf_index.loc" /></table>
- <!-- Locations of indexes in the BFAST mapper format -->
- <table name="bfast_indexes" comment_char="#">
- <columns>value, dbkey, formats, name, path</columns>
- <file path="tool-data/bfast_indexes.loc" />
+ <!-- Locations of fasta files appropriate for NGS simulation -->
+ <table name="ngs_sim_fasta" comment_char="#">
+ <columns>value, dbkey, name, path</columns>
+ <file path="tool-data/ngs_sim_fasta.loc" /></table></tables>
--- /dev/null
+++ b/tools/ngs_simulation/ngs_simulation.py
@@ -0,0 +1,280 @@
+#!/usr/bin/env python
+
+"""
+Runs Ben's simulation.
+
+usage: %prog [options]
+ -i, --input=i: Input genome (FASTA format)
+ -g, --genome=g: If built-in, the genome being used
+ -l, --read_len=l: Read length
+ -c, --avg_coverage=c: Average coverage
+ -e, --error_rate=e: Error rate (0-1)
+ -n, --num_sims=n: Number of simulations to run
+ -p, --polymorphism=p: Frequency/ies for minor allele (comma-separate list of 0-1)
+ -d, --detection_thresh=d: Detection thresholds (comma-separate list of 0-1)
+ -p, --output_png=p: Plot output
+ -s, --summary_out=s: Whether or not to output a file with summary of all simulations
+ -m, --output_summary=m: File name for output summary of all simulations
+ -f, --new_file_path=f: Directory for summary output files
+
+"""
+# removed output of all simulation results on request (not working)
+# -r, --sim_results=r: Output all tabular simulation results (number of polymorphisms times number of detection thresholds)
+# -o, --output=o: Base name for summary output for each run
+
+from rpy import *
+import os
+import random, sys, tempfile
+from galaxy import eggs
+import pkg_resources; pkg_resources.require( "bx-python" )
+from bx.cookbook import doc_optparse
+
+def stop_err( msg ):
+ sys.stderr.write( '%s\n' % msg )
+ sys.exit()
+
+def __main__():
+ #Parse Command Line
+ options, args = doc_optparse.parse( __doc__ )
+ # validate parameters
+ error = ''
+ try:
+ read_len = int( options.read_len )
+ if read_len <= 0:
+ raise Exception, ' greater than 0'
+ except TypeError, e:
+ error = ': %s' % str( e )
+ if error:
+ stop_err( 'Make sure your number of reads is an integer value%s' % error )
+ error = ''
+ try:
+ avg_coverage = int( options.avg_coverage )
+ if avg_coverage <= 0:
+ raise Exception, ' greater than 0'
+ except Exception, e:
+ error = ': %s' % str( e )
+ if error:
+ stop_err( 'Make sure your average coverage is an integer value%s' % error )
+ error = ''
+ try:
+ error_rate = float( options.error_rate )
+ if error_rate >= 1.0:
+ error_rate = 10 ** ( -error_rate / 10.0 )
+ elif error_rate < 0:
+ raise Exception, ' between 0 and 1'
+ except Exception, e:
+ error = ': %s' % str( e )
+ if error:
+ stop_err( 'Make sure the error rate is a decimal value%s or the quality score is at least 1' % error )
+ try:
+ num_sims = int( options.num_sims )
+ except TypeError, e:
+ stop_err( 'Make sure the number of simulations is an integer value: %s' % str( e ) )
+ if len( options.polymorphism ) > 0:
+ polymorphisms = [ float( p ) for p in options.polymorphism.split( ',' ) ]
+ else:
+ stop_err( 'Select at least one polymorphism value to use' )
+ if len( options.detection_thresh ) > 0:
+ detection_threshes = [ float( dt ) for dt in options.detection_thresh.split( ',' ) ]
+ else:
+ stop_err( 'Select at least one detection threshold to use' )
+
+ # mutation dictionaries
+ hp_dict = { 'A':'G', 'G':'A', 'C':'T', 'T':'C', 'N':'N' } # heteroplasmy dictionary
+ mt_dict = { 'A':'C', 'C':'A', 'G':'T', 'T':'G', 'N':'N'} # misread dictionary
+
+ # read fasta file to seq string
+ all_lines = open( options.input, 'rb' ).readlines()
+ seq = ''
+ for line in all_lines:
+ line = line.rstrip()
+ if line.startswith('>'):
+ pass
+ else:
+ seq += line.upper()
+ seq_len = len( seq )
+
+ # output file name template
+# removed output of all simulation results on request (not working)
+# if options.sim_results == "true":
+# out_name_template = os.path.join( options.new_file_path, 'primary_output%s_' + options.output + '_visible_tabular' )
+# else:
+# out_name_template = tempfile.NamedTemporaryFile().name + '_%s'
+ out_name_template = tempfile.NamedTemporaryFile().name + '_%s'
+ print 'out_name_template:', out_name_template
+
+ # set up output files
+ outputs = {}
+ i = 1
+ for p in polymorphisms:
+ outputs[ p ] = {}
+ for d in detection_threshes:
+ outputs[ p ][ d ] = out_name_template % i
+ i += 1
+
+ # run sims
+ for polymorphism in polymorphisms:
+ for detection_thresh in detection_threshes:
+ output = open( outputs[ polymorphism ][ detection_thresh ], 'wb' )
+ output.write( 'FP\tFN\tGENOMESIZE=%s\n' % seq_len )
+ sim_count = 0
+ while sim_count < num_sims:
+ # randomly pick heteroplasmic base index
+ hbase = random.choice( range( 0, seq_len ) )
+ #hbase = seq_len/2#random.randrange( 0, seq_len )
+ # create 2D quasispecies list
+ qspec = map( lambda x: [], [0] * seq_len )
+ # simulate read indices and assign to quasispecies
+ i = 0
+ while i < ( avg_coverage * ( seq_len / read_len ) ): # number of reads (approximates coverage)
+ start = random.choice( range( 0, seq_len ) )
+ #start = seq_len/2#random.randrange( 0, seq_len ) # assign read start
+ if random.random() < 0.5: # positive sense read
+ end = start + read_len # assign read end
+ if end > seq_len: # overshooting origin
+ read = range( start, seq_len ) + range( 0, ( end - seq_len ) )
+ else: # regular read
+ read = range( start, end )
+ else: # negative sense read
+ end = start - read_len # assign read end
+ if end < -1: # overshooting origin
+ read = range( start, -1, -1) + range( ( seq_len - 1 ), ( seq_len + end ), -1 )
+ else: # regular read
+ read = range( start, end, -1 )
+ # assign read to quasispecies list by index
+ for j in read:
+ if j == hbase and random.random() < polymorphism: # heteroplasmic base is variant with p = het
+ ref = hp_dict[ seq[ j ] ]
+ else: # ref is the verbatim reference nucleotide (all positions)
+ ref = seq[ j ]
+ if random.random() < error_rate: # base in read is misread with p = err
+ qspec[ j ].append( mt_dict[ ref ] )
+ else: # otherwise we carry ref through to the end
+ qspec[ j ].append(ref)
+ # last but not least
+ i += 1
+ bases, fpos, fneg = {}, 0, 0 # last two will be outputted to summary file later
+ for i, nuc in enumerate( seq ):
+ cov = len( qspec[ i ] )
+ bases[ 'A' ] = qspec[ i ].count( 'A' )
+ bases[ 'C' ] = qspec[ i ].count( 'C' )
+ bases[ 'G' ] = qspec[ i ].count( 'G' )
+ bases[ 'T' ] = qspec[ i ].count( 'T' )
+ # calculate max NON-REF deviation
+ del bases[ nuc ]
+ maxdev = float( max( bases.values() ) ) / cov
+ # deal with non-het sites
+ if i != hbase:
+ if maxdev >= detection_thresh: # greater than detection threshold = false positive
+ fpos += 1
+ # deal with het sites
+ if i == hbase:
+ hnuc = hp_dict[ nuc ] # let's recover het variant
+ if ( float( bases[ hnuc ] ) / cov ) < detection_thresh: # less than detection threshold = false negative
+ fneg += 1
+ del bases[ hnuc ] # ignore het variant
+ maxdev = float( max( bases.values() ) ) / cov # check other non-ref bases at het site
+ if maxdev >= detection_thresh: # greater than detection threshold = false positive (possible)
+ fpos += 1
+ # output error sums and genome size to summary file
+ output.write( '%d\t%d\n' % ( fpos, fneg ) )
+ sim_count += 1
+ # close output up
+ output.close()
+
+ # Parameters (heteroplasmy, error threshold, colours)
+ r( '''
+ het=c(%s)
+ err=c(%s)
+ grade = (0:32)/32
+ hues = rev(gray(grade))
+ ''' % ( ','.join( [ str( p ) for p in polymorphisms ] ), ','.join( [ str( d ) for d in detection_threshes ] ) ) )
+
+ # Suppress warnings
+ r( 'options(warn=-1)' )
+
+ # Create allsum (for FP) and allneg (for FN) objects
+ r( 'allsum <- data.frame()' )
+ for polymorphism in polymorphisms:
+ for detection_thresh in detection_threshes:
+ output = outputs[ polymorphism ][ detection_thresh ]
+ cmd = '''
+ ngsum = read.delim('%s', header=T)
+ ngsum$fprate <- ngsum$FP/%s
+ ngsum$hetcol <- %s
+ ngsum$errcol <- %s
+ allsum <- rbind(allsum, ngsum)
+ ''' % ( output, seq_len, polymorphism, detection_thresh )
+ r( cmd )
+
+ if os.path.getsize( output ) == 0:
+ for p in outputs.keys():
+ for d in outputs[ p ].keys():
+ sys.stderr.write(outputs[ p ][ d ] + ' '+str( os.path.getsize( outputs[ p ][ d ] ) )+'\n')
+
+ if options.summary_out == "true":
+ r( 'write.table(summary(ngsum), file="%s", quote=FALSE, sep="\t", row.names=FALSE)' % options.output_summary )
+
+ # Summary objects (these could be printed)
+ r( '''
+ tr_pos <- tapply(allsum$fprate,list(allsum$hetcol,allsum$errcol), mean)
+ tr_neg <- tapply(allsum$FN,list(allsum$hetcol,allsum$errcol), mean)
+ cat('\nFalse Positive Rate Summary\n\t', file='%s', append=T, sep='\t')
+ write.table(format(tr_pos, digits=4), file='%s', append=T, quote=F, sep='\t')
+ cat('\nFalse Negative Rate Summary\n\t', file='%s', append=T, sep='\t')
+ write.table(format(tr_neg, digits=4), file='%s', append=T, quote=F, sep='\t')
+ ''' % tuple( [ options.output_summary ] * 4 ) )
+
+ # Setup graphs
+ #pdf(paste(prefix,'_jointgraph.pdf',sep=''), 15, 10)
+ r( '''
+ png('%s', width=800, height=500, units='px', res=250)
+ layout(matrix(data=c(1,2,1,3,1,4), nrow=2, ncol=3), widths=c(4,6,2), heights=c(1,10,10))
+ ''' % options.output_png )
+
+ # Main title
+ genome = ''
+ if options.genome:
+ genome = '%s: ' % options.genome
+ r( '''
+ par(mar=c(0,0,0,0))
+ plot(1, type='n', axes=F, xlab='', ylab='')
+ text(1,1,paste('%sVariation in False Positives and Negatives (', %s, ' simulations, coverage ', %s,')', sep=''), font=2, family='sans', cex=0.7)
+ ''' % ( genome, options.num_sims, options.avg_coverage ) )
+
+ # False positive boxplot
+ r( '''
+ par(mar=c(5,4,2,2), las=1, cex=0.35)
+ boxplot(allsum$fprate ~ allsum$errcol, horizontal=T, ylim=rev(range(allsum$fprate)), cex.axis=0.85)
+ title(main='False Positives', xlab='false positive rate', ylab='')
+ ''' )
+
+ # False negative heatmap (note zlim command!)
+ num_polys = len( polymorphisms )
+ num_dets = len( detection_threshes )
+ r( '''
+ par(mar=c(5,4,2,1), las=1, cex=0.35)
+ image(1:%s, 1:%s, tr_neg, zlim=c(0,1), col=hues, xlab='', ylab='', axes=F, border=1)
+ axis(1, at=1:%s, labels=rownames(tr_neg), lwd=1, cex.axis=0.85, axs='i')
+ axis(2, at=1:%s, labels=colnames(tr_neg), lwd=1, cex.axis=0.85)
+ title(main='False Negatives', xlab='minor allele frequency', ylab='detection threshold')
+ ''' % ( num_polys, num_dets, num_polys, num_dets ) )
+
+ # Scale alongside
+ r( '''
+ par(mar=c(2,2,2,3), las=1)
+ image(1, grade, matrix(grade, ncol=length(grade), nrow=1), col=hues, xlab='', ylab='', xaxt='n', las=1, cex.axis=0.85)
+ title(main='Key', cex=0.35)
+ mtext('false negative rate', side=1, cex=0.35)
+ ''' )
+
+ # Close graphics
+ r( '''
+ layout(1)
+ dev.off()
+ ''' )
+
+ # Tidy up
+# r( 'rm(folder,prefix,sim,cov,het,err,grade,hues,i,j,ngsum)' )
+
+if __name__ == "__main__" : __main__()
--- /dev/null
+++ b/test-data/ngs_simulation_out2.tabular
@@ -0,0 +1,19 @@
+ FP FN GENOMESIZE.2686 fprate hetcol errcol
+Min. :0.00 Min. :0 Mode:logical Min. :0.000e+00 Min. :0.1 Min. :0.02
+1st Qu.:0.00 1st Qu.:0 NA's:25 1st Qu.:0.000e+00 1st Qu.:0.1 1st Qu.:0.02
+Median :0.00 Median :0 NA Median :0.000e+00 Median :0.1 Median :0.02
+Mean :0.04 Mean :0 NA Mean :1.489e-05 Mean :0.1 Mean :0.02
+3rd Qu.:0.00 3rd Qu.:0 NA 3rd Qu.:0.000e+00 3rd Qu.:0.1 3rd Qu.:0.02
+Max. :1.00 Max. :0 NA Max. :3.723e-04 Max. :0.1 Max. :0.02
+
+False Positive Rate Summary
+ 0.01 0.02
+0.02 9.710e-03 4.468e-05
+0.04 9.680e-03 1.489e-05
+0.1 9.695e-03 1.489e-05
+
+False Negative Rate Summary
+ 0.01 0.02
+0.02 0.16 0.52
+0.04 0.00 0.04
+0.1 0.00 0.00
1
0
galaxy-dist commit 9d68027b0109: Add options to Tophat wrapper for specifying own splice junctions.
by commits-noreply@bitbucket.org 20 Nov '10
by commits-noreply@bitbucket.org 20 Nov '10
20 Nov '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 1288805582 14400
# Node ID 9d68027b01096e2b32101234878d11946c03d08c
# Parent 49f0e8441a4da6b1ec03250448ab84854f07aa77
Add options to Tophat wrapper for specifying own splice junctions.
--- a/tools/ngs_rna/tophat_wrapper.py
+++ b/tools/ngs_rna/tophat_wrapper.py
@@ -29,6 +29,24 @@ def __main__():
help='The maximum intron length. When searching for junctions ab initio, TopHat will ignore donor/acceptor pairs farther than this many bases apart, except when such a pair is supported by a split segment alignment of a long read.' )
parser.add_option( '-F', '--junction_filter', dest='junction_filter', help='Filter out junctions supported by too few alignments (number of reads divided by average depth of coverage)' )
parser.add_option( '-g', '--max_multihits', dest='max_multihits', help='Maximum number of alignments to be allowed' )
+ parser.add_option( '', '--seg-mismatches', dest='seg_mismatches', help='Number of mismatches allowed in each segment alignment for reads mapped independently' )
+ parser.add_option( '', '--seg-length', dest='seg_length', help='Minimum length of read segments' )
+
+ # Options for supplying own junctions
+ parser.add_option( '-G', '--GTF', dest='gene_model_annotations', help='Supply TopHat with a list of gene model annotations. \
+ TopHat will use the exon records in this file to build \
+ a set of known splice junctions for each gene, and will \
+ attempt to align reads to these junctions even if they \
+ would not normally be covered by the initial mapping.')
+ parser.add_option( '-j', '--raw-juncs', dest='raw_juncs', help='Supply TopHat with a list of raw junctions. Junctions are \
+ specified one per line, in a tab-delimited format. Records \
+ look like: <chrom><left><right><+/-> left and right are \
+ zero-based coordinates, and specify the last character of the \
+ left sequenced to be spliced to the first character of the right \
+ sequence, inclusive.')
+ parser.add_option( '', '--no-novel-juncs', action="store_true", dest='no_novel_juncs', help="Only look for junctions indicated in the \
+ supplied GFF file. (ignored without -G)")
+ # Types of search.
parser.add_option( '', '--microexon-search', action="store_true", dest='microexon_search', help='With this option, the pipeline will attempt to find alignments incident to microexons. Works only for reads 50bp or longer.')
parser.add_option( '', '--closure-search', action="store_true", dest='closure_search', help='Enables the mate pair closure-based search for junctions. Closure-based search should only be used when the expected inner distance between mates is small (<= 50bp)')
parser.add_option( '', '--no-closure-search', action="store_false", dest='closure_search' )
@@ -41,8 +59,6 @@ def __main__():
parser.add_option( '', '--max-closure-intron', dest='max_closure_intron', help='Maximum intron length that may be found during closure search' )
parser.add_option( '', '--min-coverage-intron', dest='min_coverage_intron', help='Minimum intron length that may be found during coverage search' )
parser.add_option( '', '--max-coverage-intron', dest='max_coverage_intron', help='Maximum intron length that may be found during coverage search' )
- parser.add_option( '', '--seg-mismatches', dest='seg_mismatches', help='Number of mismatches allowed in each segment alignment for reads mapped independently' )
- parser.add_option( '', '--seg-length', dest='seg_length', help='Minimum length of read segments' )
# Wrapper options.
parser.add_option( '-1', '--input1', dest='input1', help='The (forward or single-end) reads file in Sanger FASTQ format' )
@@ -107,6 +123,15 @@ def __main__():
if float( options.junction_filter ) != 0.0:
opts += ' -F %s' % options.junction_filter
opts += ' -g %s' % options.max_multihits
+ # Custom junctions options.
+ if options.gene_model_annotations:
+ opts += ' -G %s' % options.gene_model_annotations
+ if options.raw_juncs:
+ opts += ' -j %s' % options.raw_juncs
+ if options.no_novel_juncs:
+ opts += ' --no-novel-juncs'
+
+ # Search type options.
if options.coverage_search:
opts += ' --coverage-search --min-coverage-intron %s --max-coverage-intron %s' % ( options.min_coverage_intron, options.max_coverage_intron )
else:
--- a/tools/ngs_rna/tophat_wrapper.xml
+++ b/tools/ngs_rna/tophat_wrapper.xml
@@ -45,6 +45,21 @@
--max-segment-intron $singlePaired.sParams.max_segment_intron
--seg-mismatches=$singlePaired.sParams.seg_mismatches
--seg-length=$singlePaired.sParams.seg_length
+
+ ## Supplying junctions parameters.
+ #if $singlePaired.sParams.own_junctions.use_junctions == "Yes":
+ #if $singlePaired.sParams.own_junctions.gene_model_ann.use_annotations == "Yes":
+ -G $singlePaired.sParams.own_junctions.gene_model_ann.gene_annotation_model
+ #end if
+ #if $singlePaired.sParams.own_junctions.raw_juncs.use_juncs == "Yes":
+ -j $singlePaired.sParams.own_junctions.raw_juncs.raw_juncs
+ #end if
+ ## TODO: No idea why a string cast is necessary, but it is:
+ #if str($singlePaired.sParams.own_junctions.no_novel_juncs) == "Yes":
+ --no-novel-juncs
+ #end if
+ #end if
+
#if $singlePaired.sParams.closure_search.use_search == "Yes":
--closure-search
--min-closure-exon $singlePaired.sParams.closure_search.min_closure_exon
@@ -60,8 +75,8 @@
#else:
--no-coverage-search
#end if
- ## No idea why the type conversion is necessary, but it seems to be.
- #if str ($singlePaired.sParams.microexon_search) == "Yes":
+ ## TODO: No idea why the type conversion is necessary, but it seems to be.
+ #if str($singlePaired.sParams.microexon_search) == "Yes":
--microexon-search
#end if
#end if
@@ -81,6 +96,21 @@
--max-segment-intron $singlePaired.pParams.max_segment_intron
--seg-mismatches=$singlePaired.pParams.seg_mismatches
--seg-length=$singlePaired.pParams.seg_length
+
+ ## Supplying junctions parameters.
+ #if $singlePaired.pParams.own_junctions.use_junctions == "Yes":
+ #if $singlePaired.pParams.own_junctions.gene_model_ann.use_annotations == "Yes":
+ -G $singlePaired.pParams.own_junctions.gene_model_ann.gene_annotation_model
+ #end if
+ #if $singlePaired.pParams.own_junctions.raw_juncs.use_juncs == "Yes":
+ -j $singlePaired.pParams.own_junctions.raw_juncs.raw_juncs
+ #end if
+ ## TODO: No idea why type cast is necessary, but it is:
+ #if str($singlePaired.pParams.own_junctions.no_novel_juncs) == "Yes":
+ --no-novel-juncs
+ #end if
+ #end if
+
#if $singlePaired.pParams.closure_search.use_search == "Yes":
--closure-search
--min-closure-exon $singlePaired.pParams.closure_search.min_closure_exon
@@ -96,7 +126,7 @@
#else:
--no-coverage-search
#end if
- ## No idea why the type conversion is necessary, but it seems to be.
+ ## TODO: No idea why the type conversion is necessary, but it seems to be.
#if str ($singlePaired.pParams.microexon_search) == "Yes":
--microexon-search
#end if
@@ -146,6 +176,42 @@
<param name="max_segment_intron" type="integer" value="500000" label="Maximum intron length that may be found during split-segment (default) search" /><param name="seg_mismatches" type="integer" value="2" label="Number of mismatches allowed in each segment alignment for reads mapped independently" /><param name="seg_length" type="integer" value="25" label="Minimum length of read segments" />
+
+ <!-- Options for supplying own junctions. -->
+ <conditional name="own_junctions">
+ <param name="use_junctions" type="select" label="Use Own Junctions">
+ <option value="No">No</option>
+ <option value="Yes">Yes</option>
+ </param>
+ <when value="Yes">
+ <conditional name="gene_model_ann">
+ <param name="use_annotations" type="select" label="Use Gene Annotation Model">
+ <option value="No">No</option>
+ <option value="Yes">Yes</option>
+ </param>
+ <when value="No" />
+ <when value="Yes">
+ <param format="gtf" name="gene_annotation_model" type="data" label="Gene Model Annotations" help="TopHat will use the exon records in this file to build a set of known splice junctions for each gene, and will attempt to align reads to these junctions even if they would not normally be covered by the initial mapping."/>
+ </when>
+ </conditional>
+ <conditional name="raw_juncs">
+ <param name="use_juncs" type="select" label="Use Raw Junctions">
+ <option value="No">No</option>
+ <option value="Yes">Yes</option>
+ </param>
+ <when value="No" />
+ <when value="Yes">
+ <param format="interval" name="raw_juncs" type="data" label="Raw Junctions" help="Supply TopHat with a list of raw junctions. Junctions are specified one per line, in a tab-delimited format. Records look like: [chrom] [left] [right] [+/-] left and right are zero-based coordinates, and specify the last character of the left sequenced to be spliced to the first character of the right sequence, inclusive."/>
+ </when>
+ </conditional>
+ <param name="no_novel_juncs" type="select" label="Only look for supplied junctions">
+ <option value="No">No</option>
+ <option value="Yes">Yes</option>
+ </param>
+ </when>
+ <when value="No" />
+ </conditional><!-- /own_junctions -->
+
<!-- Closure search. --><conditional name="closure_search"><param name="use_search" type="select" label="Use Closure Search">
@@ -201,6 +267,41 @@
<param name="max_segment_intron" type="integer" value="500000" label="Maximum intron length that may be found during split-segment (default) search" /><param name="seg_mismatches" type="integer" value="2" label="Number of mismatches allowed in each segment alignment for reads mapped independently" /><param name="seg_length" type="integer" value="25" label="Minimum length of read segments" />
+ <!-- Options for supplying own junctions. -->
+ <conditional name="own_junctions">
+ <param name="use_junctions" type="select" label="Use Own Junctions">
+ <option value="No">No</option>
+ <option value="Yes">Yes</option>
+ </param>
+ <when value="Yes">
+ <conditional name="gene_model_ann">
+ <param name="use_annotations" type="select" label="Use Gene Annotation Model">
+ <option value="No">No</option>
+ <option value="Yes">Yes</option>
+ </param>
+ <when value="No" />
+ <when value="Yes">
+ <param format="gtf" name="gene_annotation_model" type="data" label="Gene Model Annotations" help="TopHat will use the exon records in this file to build a set of known splice junctions for each gene, and will attempt to align reads to these junctions even if they would not normally be covered by the initial mapping."/>
+ </when>
+ </conditional>
+ <conditional name="raw_juncs">
+ <param name="use_juncs" type="select" label="Use Raw Junctions">
+ <option value="No">No</option>
+ <option value="Yes">Yes</option>
+ </param>
+ <when value="No" />
+ <when value="Yes">
+ <param format="interval" name="raw_juncs" type="data" label="Raw Junctions" help="Supply TopHat with a list of raw junctions. Junctions are specified one per line, in a tab-delimited format. Records look like: [chrom] [left] [right] [+/-] left and right are zero-based coordinates, and specify the last character of the left sequenced to be spliced to the first character of the right sequence, inclusive."/>
+ </when>
+ </conditional>
+ <param name="no_novel_juncs" type="select" label="Only look for supplied junctions">
+ <option value="No">No</option>
+ <option value="Yes">Yes</option>
+ </param>
+ </when>
+ <when value="No" />
+ </conditional><!-- /own_junctions -->
+
<!-- Closure search. --><conditional name="closure_search"><param name="use_search" type="select" label="Use Closure Search">
@@ -385,8 +486,11 @@ This is a list of implemented Tophat opt
-F/--min-isoform-fraction 0.0-1.0 TopHat filters out junctions supported by too few alignments. Suppose a junction spanning two exons, is supported by S reads. Let the average depth of coverage of
exon A be D, and assume that it is higher than B. If S / D is less than the minimum isoform fraction, the junction is not reported. A value of zero disables the
filter. The default is 0.15.
- -g/--max-multihits INT Instructs TopHat to allow up to this many alignments to the reference for a given read, and suppresses all alignments for reads with more than this many
+ -g/--max-multihits INT Instructs TopHat to allow up to this many alignments to the reference for a given read, and suppresses all alignments for reads with more than this many
alignments. The default is 40.
+ -G/--GTF [GTF 2.2 file] Supply TopHat with a list of gene model annotations. TopHat will use the exon records in this file to build a set of known splice junctions for each gene, and will attempt to align reads to these junctions even if they would not normally be covered by the initial mapping.
+ -j/--raw-juncs [juncs file] Supply TopHat with a list of raw junctions. Junctions are specified one per line, in a tab-delimited format. Records look like: [chrom] [left] [right] [+/-], left and right are zero-based coordinates, and specify the last character of the left sequenced to be spliced to the first character of the right sequence, inclusive.
+ -no-novel-juncs Only look for junctions indicated in the supplied GFF file. (ignored without -G)
--no-closure-search Disables the mate pair closure-based search for junctions. Currently, has no effect - closure search is off by default.
--closure-search Enables the mate pair closure-based search for junctions. Closure-based search should only be used when the expected inner distance between mates is small (about or less than 50bp)
--no-coverage-search Disables the coverage based search for junctions.
1
0
galaxy-dist commit cdf8d61425cc: Fix typo when running a workflow that contains an updated tool.
by commits-noreply@bitbucket.org 20 Nov '10
by commits-noreply@bitbucket.org 20 Nov '10
20 Nov '10
# HG changeset patch -- Bitbucket.org
# Project galaxy-dist
# URL http://bitbucket.org/galaxy/galaxy-dist/overview
# User Daniel Blankenberg <dan(a)bx.psu.edu>
# Date 1288898016 14400
# Node ID cdf8d61425cce011f98b1f24bd9fe19dc59b10ab
# Parent bc690ccf23396e1c7e29e8ee801996ac3e3d3409
Fix typo when running a workflow that contains an updated tool.
--- a/templates/workflow/run.mako
+++ b/templates/workflow/run.mako
@@ -123,7 +123,7 @@ from galaxy.jobs.actions.post import Act
%if has_upgrade_messages:
<div class="warningmessage">
- Problems were encourered when loading this workflow, likely due to tool
+ Problems were encountered when loading this workflow, likely due to tool
version changes. Missing parameter values have been replaced with default.
Please review the parameter values below.
</div>
1
0
galaxy-dist commit cf8bef68e8be: Correction to docstring for Tool.build_param_dict() -- from peter@maubp.freeserve.co.uk
by commits-noreply@bitbucket.org 20 Nov '10
by commits-noreply@bitbucket.org 20 Nov '10
20 Nov '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 1288810958 14400
# Node ID cf8bef68e8befb8b6631578b71ff69f701fc0d4d
# Parent b1ec8342053f3cdcd0a081ff28f077a76bd188cc
Correction to docstring for Tool.build_param_dict() -- from peter(a)maubp.freeserve.co.uk
--- a/lib/galaxy/tools/__init__.py
+++ b/lib/galaxy/tools/__init__.py
@@ -1333,7 +1333,7 @@ class Tool:
line. Each value is wrapped in a `InputValueWrapper`, which allows
all the attributes of the value to be used in the template, *but*
when the __str__ method is called it actually calls the
- `to_param_dict_value` method of the associated input.
+ `to_param_dict_string` method of the associated input.
"""
param_dict = dict()
# All parameters go into the param_dict
1
0
galaxy-dist commit f372ea5a6014: Fix interpreter for the FASTX Barcode Splitter.
by commits-noreply@bitbucket.org 20 Nov '10
by commits-noreply@bitbucket.org 20 Nov '10
20 Nov '10
# HG changeset patch -- Bitbucket.org
# Project galaxy-dist
# URL http://bitbucket.org/galaxy/galaxy-dist/overview
# User Nate Coraor <nate(a)bx.psu.edu>
# Date 1288902351 14400
# Node ID f372ea5a601443a9b9cd1d3f7e04ddc24db5b57a
# Parent cdf8d61425cce011f98b1f24bd9fe19dc59b10ab
Fix interpreter for the FASTX Barcode Splitter.
--- a/tools/fastx_toolkit/fastx_barcode_splitter.xml
+++ b/tools/fastx_toolkit/fastx_barcode_splitter.xml
@@ -1,7 +1,7 @@
<tool id="cshl_fastx_barcode_splitter" name="Barcode Splitter"><description></description><requirements><requirement type="package">fastx_toolkit</requirement></requirements>
- <command interpreter="sh">fastx_barcode_splitter_galaxy_wrapper.sh $BARCODE $input "$input.name" "$output.files_path" --mismatches $mismatches --partial $partial $EOL > $output </command>
+ <command interpreter="bash">fastx_barcode_splitter_galaxy_wrapper.sh $BARCODE $input "$input.name" "$output.files_path" --mismatches $mismatches --partial $partial $EOL > $output </command><inputs><param format="txt" name="BARCODE" type="data" label="Barcodes to use" />
1
0
galaxy-dist commit 6838e10e5912: Fix for TextToolParameter.get_html_field when provided value is an empty string but default value specified in tool is non-empty string. Fixes issue with rerun button where if a user had input an empty string, the form displayed when rerun would have the default value from the tool and not the actual previously specified value.
by commits-noreply@bitbucket.org 20 Nov '10
by commits-noreply@bitbucket.org 20 Nov '10
20 Nov '10
# HG changeset patch -- Bitbucket.org
# Project galaxy-dist
# URL http://bitbucket.org/galaxy/galaxy-dist/overview
# User Daniel Blankenberg <dan(a)bx.psu.edu>
# Date 1288818754 14400
# Node ID 6838e10e5912cec46060bda189841edba305ac1d
# Parent 16bd91a548887fb0be24b981c2d66fb7ef7b1922
Fix for TextToolParameter.get_html_field when provided value is an empty string but default value specified in tool is non-empty string. Fixes issue with rerun button where if a user had input an empty string, the form displayed when rerun would have the default value from the tool and not the actual previously specified value.
--- a/lib/galaxy/tools/parameters/basic.py
+++ b/lib/galaxy/tools/parameters/basic.py
@@ -165,10 +165,11 @@ class TextToolParameter( ToolParameter )
self.value = elem.get( 'value' )
self.area = string_as_bool( elem.get( 'area', False ) )
def get_html_field( self, trans=None, value=None, other_values={} ):
+ if value is None: value = self.value
if self.area:
- return form_builder.TextArea( self.name, self.size, value or self.value )
+ return form_builder.TextArea( self.name, self.size, value )
else:
- return form_builder.TextField( self.name, self.size, value or self.value )
+ return form_builder.TextField( self.name, self.size, value )
def get_initial_value( self, trans, context ):
return self.value
1
0
galaxy-dist commit 16bd91a54888: Must be logged in to use api keys. Fix small typo in error messages
by commits-noreply@bitbucket.org 20 Nov '10
by commits-noreply@bitbucket.org 20 Nov '10
20 Nov '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 1288813870 14400
# Node ID 16bd91a548887fb0be24b981c2d66fb7ef7b1922
# Parent cf8bef68e8befb8b6631578b71ff69f701fc0d4d
Must be logged in to use api keys. Fix small typo in error messages
--- a/lib/galaxy/web/controllers/user.py
+++ b/lib/galaxy/web/controllers/user.py
@@ -984,6 +984,7 @@ class User( BaseController, UsesFormDefi
message=message,
lines_skipped=lines_skipped )
@web.expose
+ @web.require_login()
def api_keys( self, trans, **kwd ):
params = util.Params( kwd )
message = util.restore_text( params.get( 'message', '' ) )
--- a/lib/galaxy/web/framework/__init__.py
+++ b/lib/galaxy/web/framework/__init__.py
@@ -84,7 +84,7 @@ def require_login( verb="perform this ac
return func( self, trans, *args, **kwargs )
else:
return trans.show_error_message(
- 'You must be <a target="_top" href="%s">logged in</a> to %s</div>.'
+ 'You must be <a target="_top" href="%s">logged in</a> to %s.'
% ( url_for( controller='user', action='login', webapp=webapp ), verb ), use_panels=use_panels )
return decorator
return argcatcher
1
0
galaxy-dist commit bc690ccf2339: Have rerun action make use of tool.check_and_update_param_values(). Fixes Server Error issue when trying to rerun updated tools.
by commits-noreply@bitbucket.org 20 Nov '10
by commits-noreply@bitbucket.org 20 Nov '10
20 Nov '10
# HG changeset patch -- Bitbucket.org
# Project galaxy-dist
# URL http://bitbucket.org/galaxy/galaxy-dist/overview
# User Daniel Blankenberg <dan(a)bx.psu.edu>
# Date 1288897385 14400
# Node ID bc690ccf23396e1c7e29e8ee801996ac3e3d3409
# Parent 6838e10e5912cec46060bda189841edba305ac1d
Have rerun action make use of tool.check_and_update_param_values(). Fixes Server Error issue when trying to rerun updated tools.
--- a/lib/galaxy/web/controllers/tool_runner.py
+++ b/lib/galaxy/web/controllers/tool_runner.py
@@ -123,6 +123,7 @@ class ToolRunner( BaseController ):
params_objects = job.get_param_values( trans.app )
except:
raise Exception( "Failed to get paramemeters for dataset id %d " % data.id )
+ upgrade_messages = tool.check_and_update_param_values( params_objects, trans )
# Need to remap dataset parameters. Job parameters point to original
# dataset used; parameter should be the analygous dataset in the
# current history.
@@ -152,7 +153,7 @@ class ToolRunner( BaseController ):
state.inputs = params_objects
tool_state_string = util.object_to_string(state.encode(tool, trans.app))
# Setup context for template
- vars = dict( tool_state=state, errors = {} )
+ vars = dict( tool_state=state, errors = upgrade_messages )
# Is the "add frame" stuff neccesary here?
add_frame = AddFrameData()
add_frame.debug = trans.debug
1
0
galaxy-dist commit 569483091092: Keep the sample's bar code incormation when editn the sample row in the non-admin user view.
by commits-noreply@bitbucket.org 20 Nov '10
by commits-noreply@bitbucket.org 20 Nov '10
20 Nov '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 1288731289 14400
# Node ID 56948309109207f932a113e464409432c7a38df7
# Parent 27c152bb441a0136720dbbc0c7cb293e581b8f5f
Keep the sample's bar code incormation when editn the sample row in the non-admin user view.
--- a/templates/requests/common/common.mako
+++ b/templates/requests/common/common.mako
@@ -153,6 +153,7 @@
<input type="text" name="sample_${current_sample_index}_barcode" value="${current_sample['barcode']}" size="10"/>
%else:
${current_sample['barcode']}
+ <input type="hidden" name="sample_${current_sample_index}_barcode" value="${current_sample['barcode']}"/>
%endif
</td>
%endif
@@ -261,7 +262,7 @@
%elif sample:
<tr><td>${current_sample_name}</td>
- %if is_submitted or is_complete:
+ %if display_bar_code:
<td>${current_sample_barcode}</td>
%endif
%if is_unsubmitted:
1
0
galaxy-dist commit 27c152bb441a: More sample tracking bug fixes - tweaked permissions on displaying buttons, and fixed exceptions thrown when ddata transfer congid file is incorrect.
by commits-noreply@bitbucket.org 20 Nov '10
by commits-noreply@bitbucket.org 20 Nov '10
20 Nov '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 1288730067 14400
# Node ID 27c152bb441a0136720dbbc0c7cb293e581b8f5f
# Parent 6497a8cfd12e477e9c92dd183c4abb81d469ba51
More sample tracking bug fixes - tweaked permissions on displaying buttons, and fixed exceptions thrown when ddata transfer congid file is incorrect.
--- a/lib/galaxy/web/controllers/requests_admin.py
+++ b/lib/galaxy/web/controllers/requests_admin.py
@@ -541,7 +541,7 @@ class RequestsAdmin( BaseController, Use
return sample.request.name + '_' + sample.name + '_' + name
if opt == options.EXPERIMENT_NAME:
return sample.request.name + '_' + name
- def __setup_datatx_user( self, trans, library, folder ):
+ def __setup_datatx_user( self, trans, sample ):
"""
Sets up the datatx user:
- Checks if the user exists, if not creates them.
@@ -550,9 +550,25 @@ class RequestsAdmin( BaseController, Use
"""
# Retrieve the upload user login information from the config file
config = ConfigParser.ConfigParser()
- config.read( 'transfer_datasets.ini' )
- email = config.get( "data_transfer_user_login_info", "email" )
- password = config.get( "data_transfer_user_login_info", "password" )
+ ok = True
+ try:
+ config.read( 'transfer_datasets.ini' )
+ except Exception, e:
+ message = "Error attempting to read config file named 'transfer_datasets.ini'. Make sure this file is correct."
+ ok = False
+ try:
+ email = config.get( "data_transfer_user_login_info", "email" )
+ password = config.get( "data_transfer_user_login_info", "password" )
+ except Exception, e:
+ message = "The 'data_transfer_user_login_info' section is missing from the 'transfer_datasets.ini'. Make sure this file is correct."
+ ok = False
+ if not ok:
+ status = 'error'
+ return trans.response.send_redirect( web.url_for( controller='requests_admin',
+ action='manage_datasets',
+ sample_id=trans.security.encode_id( sample.id ),
+ status=status,
+ message=message ) )
# check if the user already exists
datatx_user = trans.sa_session.query( trans.model.User ) \
.filter( trans.model.User.table.c.email==email ) \
@@ -570,14 +586,14 @@ class RequestsAdmin( BaseController, Use
datatx_user_private_role = trans.app.security_agent.get_private_user_role( datatx_user )
# Make sure this user has LIBRARY_ADD permissions on the target library and folder.
# If not, give them permission.
- if not trans.app.security_agent.can_add_library_item( datatx_user_roles, library ):
+ if not trans.app.security_agent.can_add_library_item( datatx_user_roles, sample.library ):
lp = trans.model.LibraryPermissions( trans.app.security_agent.permitted_actions.LIBRARY_ADD.action,
- library,
+ sample.library,
datatx_user_private_role )
trans.sa_session.add( lp )
- if not trans.app.security_agent.can_add_library_item( datatx_user_roles, folder ):
+ if not trans.app.security_agent.can_add_library_item( datatx_user_roles, sample.folder ):
lfp = trans.model.LibraryFolderPermissions( trans.app.security_agent.permitted_actions.LIBRARY_ADD.action,
- folder,
+ sample.folder,
datatx_user_private_role )
trans.sa_session.add( lfp )
trans.sa_session.flush()
@@ -646,7 +662,7 @@ class RequestsAdmin( BaseController, Use
message=message) )
def __start_datatx( self, trans, sample, selected_sample_datasets ):
- datatx_user = self.__setup_datatx_user( trans, sample.library, sample.folder )
+ datatx_user = self.__setup_datatx_user( trans, sample )
# Validate sequencer information
datatx_info = sample.request.type.datatx_info
if not datatx_info['host'] or not datatx_info['username'] or not datatx_info['password']:
@@ -660,7 +676,7 @@ class RequestsAdmin( BaseController, Use
action='manage_datasets',
sample_id=trans.security.encode_id( sample.id ),
status=status,
- message=message) )
+ message=message ) )
@web.expose
def update_sample_dataset_status(self, trans, cntrller, sample_dataset_ids, new_status, error_msg=None ):
# check if the new status is a valid transfer status
--- a/templates/requests/common/common.mako
+++ b/templates/requests/common/common.mako
@@ -120,20 +120,25 @@
if sample:
trans.sa_session.refresh( sample.request )
is_complete = sample.request.is_complete
+ is_rejected = request.is_rejected
is_submitted = sample.request.is_submitted
is_unsubmitted = sample.request.is_unsubmitted
+ display_checkboxes = editing_samples and ( is_complete or is_rejected or is_submitted )
+ display_bar_code = request.samples and ( is_complete or is_rejected or is_submitted )
+ display_datasets = request.samples and ( is_complete or is_rejected or is_submitted )
else:
is_complete = False
is_submitted = False
is_unsubmitted = False
+ display_checkboxes = False
%><%
- if is_submitted and editing_samples and trans.security.encode_id( sample.id ) in encoded_selected_sample_ids:
+ if display_checkboxes and trans.security.encode_id( sample.id ) in encoded_selected_sample_ids:
checked_str = "checked"
else:
checked_str = ""
%>
- %if is_submitted and editing_samples:
+ %if display_checkboxes:
<td><input type="checkbox" name=select_sample_${sample.id} id="sample_checkbox" value="true" ${checked_str}/><input type="hidden" name=select_sample_${sample.id} id="sample_checkbox" value="true"/></td>
%endif
<td valign="top">
@@ -142,12 +147,14 @@
<i>${' (required)' }</i></div></td>
- %if sample and is_submitted or is_complete:
- %if is_admin:
- <td valign="top"><input type="text" name="sample_${current_sample_index}_barcode" value="${current_sample['barcode']}" size="10"/></td>
- %else:
- ${current_sample['barcode']}
- %endif
+ %if display_bar_code:
+ <td valign="top">
+ %if is_admin:
+ <input type="text" name="sample_${current_sample_index}_barcode" value="${current_sample['barcode']}" size="10"/>
+ %else:
+ ${current_sample['barcode']}
+ %endif
+ </td>
%endif
%if sample:
%if is_unsubmitted:
@@ -160,7 +167,7 @@
%endif
<td valign="top">${current_sample['library_select_field'].get_html()}</td><td valign="top">${current_sample['folder_select_field'].get_html()}</td>
- %if is_submitted or is_complete:
+ %if display_datasets:
<%
if sample:
label = str( len( sample.datasets ) )
@@ -182,11 +189,15 @@
trans.sa_session.refresh( request )
is_admin = cntrller == 'requests_admin' and trans.user_is_admin()
is_complete = request.is_complete
+ is_rejected = request.is_rejected
is_submitted = request.is_submitted
is_unsubmitted = request.is_unsubmitted
can_add_samples = request.is_unsubmitted
can_delete_samples = request.samples and not is_complete
can_edit_samples = request.samples and ( is_admin or not is_complete )
+ display_checkboxes = editing_samples and ( is_complete or is_rejected or is_submitted )
+ display_bar_code = request.samples and ( is_complete or is_rejected or is_submitted )
+ display_datasets = request.samples and ( is_complete or is_rejected or is_submitted )
%>
${grid_header}
%if render_buttons and ( can_add_samples or can_edit_samples ):
@@ -202,22 +213,22 @@
<table class="grid"><thead><tr>
- %if is_submitted and editing_samples:
+ %if display_checkboxes:
<th><input type="checkbox" id="checkAll" name=select_all_samples_checkbox value="true" onclick='checkAllFields(1);'/><input type="hidden" name=select_all_samples_checkbox value="true"/></th>
%endif
<th>Name</th>
- %if is_submitted or is_complete:
+ %if display_bar_code:
<th>Barcode</th>
%endif
<th>State</th><th>Data Library</th><th>Folder</th>
- %if is_submitted or is_complete:
+ %if display_datasets:
<th>Datasets Selected</th><th>Datasets Transferred</th>
%endif
<th>
- %if editing_samples:
+ %if can_delete_samples:
Delete
%endif
</th>
@@ -245,7 +256,7 @@
except:
sample = None
%>
- %if not is_complete and editing_samples:
+ %if editing_samples:
<tr>${render_editable_sample_row( is_admin, sample, current_sample_index, current_sample, encoded_selected_sample_ids )}</tr>
%elif sample:
<tr>
1
0
galaxy-dist commit 37477f7d10e7: Data Libraries: Pre-generate and cache variables so that expensive functions like jQuery.siblings, jQuery.filter and jQuery.find only have to be called a minimum amount of times. Provides significant speedup to loading of large data libraries.
by commits-noreply@bitbucket.org 20 Nov '10
by commits-noreply@bitbucket.org 20 Nov '10
20 Nov '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 1288749068 14400
# Node ID 37477f7d10e7407186bd189fdec9e114e4b8f3d2
# Parent 4053c425b536b9878f6f8bdfac75453adec7bdf3
Data Libraries: Pre-generate and cache variables so that expensive functions like jQuery.siblings, jQuery.filter and jQuery.find only have to be called a minimum amount of times. Provides significant speedup to loading of large data libraries.
--- a/templates/library/common/browse_library.mako
+++ b/templates/library/common/browse_library.mako
@@ -68,7 +68,7 @@
}
}
};
-
+
var save_folder_state = function() {
var state = {};
$("tr.folderRow").each( function() {
@@ -79,12 +79,17 @@
};
$("#library-grid").each(function() {
- // Recursively fill in children and descendents of each row
- var process_row = function(q, parents) {
+
+ var child_of_parent_cache = {};
+ // Recursively fill in children and descendents of each row
+ var process_row = function(q, parents) {
// Find my index
- var index = q.parent().children().index(q);
+ var parent = q.parent(),
+ this_level = child_of_parent_cache[parent] || (child_of_parent_cache[parent] = parent.children());
+
+ var index = this_level.index(q);
// Find my immediate children
- var children = q.siblings().filter("[parent='" + index + "']");
+ var children = $(par_child_dict[index]);
// Recursively handle them
var descendents = children;
children.each( function() {
@@ -103,8 +108,7 @@
}
save_folder_state();
};
- $(q).find("span.expandLink").click(expand_fn);
- $(q).find("span.expandLink a").click(expand_fn);
+ $("." + q.attr("id") + "-click").click(expand_fn);
// Check/uncheck boxes in subfolders.
q.children("td").children("input[type=checkbox]").click( function() {
if ( $(this).is(":checked") ) {
@@ -112,15 +116,32 @@
} else {
descendents.find("input[type=checkbox]").attr("checked", false);
// If you uncheck a lower level checkbox, uncheck the boxes above it
- // (since deselecting a child means the parent is not fully selected any
- // more).
+ // (since deselecting a child means the parent is not fully selected any more).
parents.children("td").children("input[type=checkbox]").attr("checked", false);
}
});
// return descendents for use by parent
return descendents;
- }
- $(this).find("tbody tr").not("[parent]").each( function() {
+ }
+
+ // Initialize dict[parent_id] = rows_which_have_that_parent_id_as_parent_attr
+ var par_child_dict = {},
+ no_parent = [];
+
+ $(this).find("tbody tr").each( function() {
+ if (this.hasAttribute("parent")) {
+ var parent = this.getAttribute("parent");
+ if (par_child_dict[parent] !== undefined) {
+ par_child_dict[parent].push(this);
+ } else {
+ par_child_dict[parent] = [this];
+ }
+ } else {
+ no_parent.push(this);
+ }
+ });
+
+ $(no_parent).each( function() {
descendents = process_row( $(this), $([]) );
descendents.hide();
});
@@ -338,7 +359,8 @@
info_association, inherited = folder.get_info_association( restrict=True )
%>
%if not root_folder and ( not folder.deleted or show_deleted ):
- <tr id="folder-${trans.security.encode_id(folder.id)}" class="folderRow libraryOrFolderRow"
+ <% encoded_id = trans.security.encode_id(folder.id) %>
+ <tr id="folder-${encoded_id}" class="folderRow libraryOrFolderRow"
%if parent is not None:
parent="${parent}"
style="display: none;"
@@ -349,9 +371,9 @@
%if folder.deleted:
<span class="libraryItem-error">
%endif
- <span class="expandLink"><span class="rowIcon"></span>
+ <span class="expandLink folder-${encoded_id}-click"><span class="rowIcon"></span><div style="float: left; margin-left: 2px;" class="menubutton split popup" id="folder_img-${folder.id}-popup">
- <a href="javascript:void(0);">${folder.name}</a>
+ <a class="folder-${encoded_id}-click" href="javascript:void(0);">${folder.name}</a></div>
%if folder.deleted:
</span>
1
0
20 Nov '10
# HG changeset patch -- Bitbucket.org
# Project galaxy-dist
# URL http://bitbucket.org/galaxy/galaxy-dist/overview
# User rc
# Date 1288760547 14400
# Node ID 49f0e8441a4da6b1ec03250448ab84854f07aa77
# Parent 37477f7d10e7407186bd189fdec9e114e4b8f3d2
sample tracking
- new file browser for selecting datasets in the sequencer
--- a/templates/admin/requests/get_data.mako
+++ b/templates/admin/requests/get_data.mako
@@ -1,71 +1,71 @@
<%inherit file="/base.mako"/><%namespace file="/message.mako" import="render_msg" />
+${h.js( "ui.core", "jquery.cookie" )}
+<link href='/static/june_2007_style/blue/dynatree_skin/ui.dynatree.css' rel='stylesheet' type='text/css'>
+${h.js( "jquery.dynatree" )}
<script type="text/javascript">
- $(document).ready(function(){
- //hide the all of the element with class msg_body
- $(".msg_body").hide();
- //toggle the component with class msg_body
- $(".msg_head").click(function(){
- $(this).next(".msg_body").slideToggle(450);
- });
+ $(function(){
+ $("#tree").ajaxComplete(function(event, XMLHttpRequest, ajaxOptions) {
+ _log("debug", "ajaxComplete: %o", this); // dom element listening
+ });
+ // --- Initialize sample trees
+ $("#tree").dynatree({
+ title: "${request.type.datatx_info['data_dir']}",
+ rootVisible: true,
+ minExpandLevel: 0, // 1: root node is not collapsible
+ persist: false,
+ checkbox: true,
+ selectMode: 3,
+ onPostInit: function(isReloading, isError) {
+// alert("reloading: "+isReloading+", error:"+isError);
+ logMsg("onPostInit(%o, %o) - %o", isReloading, isError, this);
+ // Re-fire onActivate, so the text is updated
+ this.reactivate();
+ },
+ fx: { height: "toggle", duration: 200 },
+ // initAjax is hard to fake, so we pass the children as object array:
+ initAjax: {url: "${h.url_for( controller='requests_admin', action='open_folder' )}",
+ dataType: "json",
+ data: { id: "${request.id}", key: "${request.type.datatx_info['data_dir']}" },
+ },
+ onLazyRead: function(dtnode){
+ dtnode.appendAjax({
+ url: "${h.url_for( controller='requests_admin', action='open_folder' )}",
+ dataType: "json",
+ data: { id: "${request.id}", key: dtnode.data.key },
+ });
+ },
+ onSelect: function(select, dtnode) {
+ // Display list of selected nodes
+ var selNodes = dtnode.tree.getSelectedNodes();
+ // convert to title/key array
+ var selKeys = $.map(selNodes, function(node){
+ return node.data.key;
+ });
+ document.get_data.selected_files.value = selKeys.join(",")
+ },
+ onActivate: function(dtnode) {
+ var cell = $("#file_details");
+ var selected_value = dtnode.data.key
+ if(selected_value.charAt(selected_value.length-1) != '/') {
+ // Make ajax call
+ $.ajax( {
+ type: "POST",
+ url: "${h.url_for( controller='requests_admin', action='get_file_details' )}",
+ dataType: "json",
+ data: { id: "${request.id}", folder_path: dtnode.data.key },
+ success : function ( data ) {
+ cell.html( '<label>'+data+'</label>' )
+ }
+ });
+ } else {
+ cell.html( '' )
+ }
+ },
+ });
});
- function display_file_details(request_id, folder_path)
- {
- var w = document.get_data.files_list.selectedIndex;
- var selected_value = document.get_data.files_list.options[w].value;
- var cell = $("#file_details");
- if(selected_value.charAt(selected_value.length-1) != '/')
- {
- // Make ajax call
- $.ajax( {
- type: "POST",
- url: "${h.url_for( controller='requests_admin', action='get_file_details' )}",
- dataType: "json",
- data: { id: request_id, folder_path: document.get_data.folder_path.value + selected_value },
- success : function ( data ) {
- cell.html( '<label>'+data+'</label>' )
- }
- });
- }
- else
- {
- cell.html( '' )
- }
- }
-
- function open_folder1( request_id, folder_path )
- {
- var w = document.get_data.files_list.selectedIndex;
- var selected_value = document.get_data.files_list.options[w].value;
- var cell = $("#file_details");
- if(selected_value.charAt(selected_value.length-1) == '/')
- {
- document.get_data.folder_path.value = document.get_data.folder_path.value+selected_value
- // Make ajax call
- $.ajax( {
- type: "POST",
- url: "${h.url_for( controller='requests_admin', action='open_folder' )}",
- dataType: "json",
- data: { id: request_id, folder_path: document.get_data.folder_path.value },
- success : function ( data ) {
- document.get_data.files_list.options.length = 0
- for(i=0; i<data.length; i++)
- {
- var newOpt = new Option(data[i], data[i]);
- document.get_data.files_list.options[i] = newOpt;
- }
- //cell.html( '<label>'+data+'</label>' )
-
- }
- });
- }
- else
- {
- cell.html( '' )
- }
- }
</script><br/>
@@ -92,18 +92,16 @@
<div class="toolParamHelp" style="clear: both;">
Select the sample with which you want to associate the datasets
</div>
- <br/>
- <label>Folder path on the sequencer:</label>
- <input type="text" name="folder_path" value="${folder_path}" size="100"/>
- <input type="submit" name="browse_button" value="List contents"/>
- <input type="submit" name="folder_up" value="Up"/></div>
- <div class="form-row">
- <select name="files_list" id="files_list" style="max-width: 60%; width: 98%; height: 150px; font-size: 100%;" ondblclick="open_folder1(${request.id}, '${folder_path}')" onChange="display_file_details(${request.id}, '${folder_path}')" multiple>
- %for index, f in enumerate( files ):
- <option value="${f}">${f}</option>
- %endfor
- </select>
+ <div class="form-row" >
+ <label>Select dataset files in the sequencer:</label>
+ <div id="tree" >
+ Loading...
+ </div>
+ <input id="selected_files" name="selected_files" type="hidden" size=40"/>
+ <div class="toolParamHelp" style="clear: both;">
+ To select a folder, select all the individual files in that folder.
+ </div></div><div class="form-row"><div id="file_details" class="toolParamHelp" style="clear: both;background-color:#FAFAFA;"></div>
Binary file static/june_2007_style/blue/dynatree_skin/rbUnchecked_hover.gif has changed
Binary file static/june_2007_style/blue/dynatree_skin/cbChecked.gif has changed
Binary file static/june_2007_style/blue/dynatree_skin/ltError.gif has changed
Binary file static/june_2007_style/blue/dynatree_skin/cbIntermediate.gif has changed
--- a/lib/galaxy/web/controllers/requests_admin.py
+++ b/lib/galaxy/web/controllers/requests_admin.py
@@ -316,7 +316,6 @@ class RequestsAdmin( BaseController, Use
dict( controller='requests_admin',
action='get_data',
request_id=request_id,
- folder_path=sample.request.type.datatx_info[ 'data_dir' ],
sample_id=sample_id ) ),
grids.GridAction( "Browse target data library",
dict( controller='library_common',
@@ -383,67 +382,61 @@ class RequestsAdmin( BaseController, Use
request = trans.sa_session.query( trans.model.Request ).get( trans.security.decode_id( request_id ) )
except:
return invalid_id_redirect( trans, 'requests_admin', request_id )
- selected_files = util.listify( params.get( 'files_list', [] ) )
- folder_path = util.restore_text( params.get( 'folder_path', request.type.datatx_info[ 'data_dir' ] ) )
+ selected_files = util.restore_text( params.get( 'selected_files', '' ) )
+ if len( selected_files ):
+ selected_files = selected_files.split(',')
+ else:
+ selected_files = []
selected_sample_id = kwd.get( 'sample_id', 'none' )
sample_id_select_field = self.__build_sample_id_select_field( trans, request, selected_sample_id )
# The __get_files() method redirects here with a status of 'error' and a message if there
# was a problem retrieving the files.
- if folder_path and status != 'error':
- folder_path = self.__check_path( folder_path )
- if params.get( 'folder_up', False ):
- if folder_path[-1] == os.sep:
- folder_path = os.path.dirname( folder_path[:-1] )
- folder_path = self.__check_path( folder_path )
- elif params.get( 'open_folder', False ):
- if len(selected_files) == 1:
- folder_path = os.path.join(folder_path, selected_files[0])
- folder_path = self.__check_path( folder_path )
- elif params.get( 'select_show_datasets_button', False ) or params.get( 'select_more_button', False ):
- # get the sample these datasets are associated with
- try:
- sample = trans.sa_session.query( trans.model.Sample ).get( trans.security.decode_id( selected_sample_id ) )
- except:
- return invalid_id_redirect( trans, 'requests_admin', selected_sample_id )
- if sample in sample.request.samples_without_library_destinations:
- # Display an error if a sample has been selected that
- # has not yet been associated with a destination library.
- status = 'error'
- message = 'Select a sample with associated data library and folder before selecting the datasets.'
- return trans.response.send_redirect( web.url_for( controller='requests_admin',
- action='get_data',
- request_id=request_id,
- folder_path=folder_path,
- status=status,
- message=message ) )
- # Save the sample datasets
- sample_dataset_file_names = self.__save_sample_datasets( trans, sample, selected_files, folder_path )
- if sample_dataset_file_names:
- message = 'Datasets (%s) have been selected for sample (%s)' % \
- ( str( sample_dataset_file_names )[1:-1].replace( "'", "" ), sample.name )
- if params.get( 'select_show_datasets_button', False ):
- return trans.response.send_redirect( web.url_for( controller='requests_admin',
- action='manage_datasets',
- request_id=request_id,
- sample_id=selected_sample_id,
- message=message,
- status=status ) )
- else: # 'select_more_button' was clicked
- return trans.response.send_redirect( web.url_for( controller='requests_admin',
- action='get_data',
- request_id=request_id,
- folder_path=folder_path,
- sample_id=sample.id,
- message=message,
- status=status ) )
- # Get the filenames from the remote host
- files = self.__get_files( trans, request, folder_path )
+ if params.get( 'select_show_datasets_button', False ) or params.get( 'select_more_button', False ):
+ # get the sample these datasets are associated with
+ try:
+ sample = trans.sa_session.query( trans.model.Sample ).get( trans.security.decode_id( selected_sample_id ) )
+ except:
+ message = 'Select a sample before selecting its associated datasets.'
+ return trans.fill_template( '/admin/requests/get_data.mako',
+ cntrller='requests_admin',
+ request=request,
+ sample_id_select_field=sample_id_select_field,
+ status='error',
+ message=message )
+ if sample in sample.request.samples_without_library_destinations:
+ # Display an error if a sample has been selected that
+ # has not yet been associated with a destination library.
+ status = 'error'
+ message = 'Select a sample with associated data library and folder before selecting the datasets.'
+ return trans.response.send_redirect( web.url_for( controller='requests_admin',
+ action='get_data',
+ request_id=request_id,
+ sample_id=sample.id,
+ status=status,
+ message=message ) )
+ # Save the sample datasets
+ sample_dataset_file_names = self.__save_sample_datasets( trans, sample, selected_files )
+ if sample_dataset_file_names:
+ message = 'Datasets (%s) have been selected for sample (%s)' % \
+ ( str( sample_dataset_file_names )[1:-1].replace( "'", "" ), sample.name )
+ if params.get( 'select_show_datasets_button', False ):
+ return trans.response.send_redirect( web.url_for( controller='requests_admin',
+ action='manage_datasets',
+ request_id=request_id,
+ sample_id=selected_sample_id,
+ message=message,
+ status=status ) )
+ else: # 'select_more_button' was clicked
+ return trans.response.send_redirect( web.url_for( controller='requests_admin',
+ action='get_data',
+ request_id=request_id,
+ sample_id=sample.id,
+ message=message,
+ status=status ) )
return trans.fill_template( '/admin/requests/get_data.mako',
cntrller='requests_admin',
request=request,
sample_id_select_field=sample_id_select_field,
- files=files,
- folder_path=folder_path,
status=status,
message=message )
@web.json
@@ -464,15 +457,27 @@ class RequestsAdmin( BaseController, Use
timeout=10 )
return unicode( output.replace( '\n', '<br/>' ) )
@web.json
- def open_folder( self, trans, id, folder_path ):
- def print_ticks( d ):
- # pexpect timeout method
- pass
+ def open_folder( self, trans, id, key ):
# Avoid caching
trans.response.headers['Pragma'] = 'no-cache'
trans.response.headers['Expires'] = '0'
request = trans.sa_session.query( trans.model.Request ).get( int( id ) )
- return self.__get_files( trans, request, folder_path )
+ folder_path = key
+ files_list = self.__get_files( trans, request, folder_path )
+ folder_contents = []
+ for filename in files_list:
+ is_folder = False
+ if filename[-1] == os.sep:
+ is_folder = True
+ full_path = os.path.join(folder_path, filename)
+ node = {"title": filename,
+ "isFolder": is_folder,
+ "isLazy": is_folder,
+ "tooltip": full_path,
+ "key": full_path
+ }
+ folder_contents.append(node)
+ return folder_contents
def __get_files( self, trans, request, folder_path ):
# Retrieves the filenames to be transferred from the remote host.
ok = True
@@ -496,7 +501,6 @@ class RequestsAdmin( BaseController, Use
return trans.response.send_redirect( web.url_for( controller='requests_admin',
action='get_data',
request_id=trans.security.encode_id( request.id ),
- folder_path=folder_path,
status=status,
message=message ) )
def __check_path( self, a_path ):
@@ -504,20 +508,13 @@ class RequestsAdmin( BaseController, Use
if a_path and not a_path.endswith( os.sep ):
a_path += os.sep
return a_path
- def __save_sample_datasets( self, trans, sample, selected_files, folder_path ):
+ def __save_sample_datasets( self, trans, sample, selected_files ):
sample_dataset_file_names = []
if selected_files:
- for f in selected_files:
- filepath = os.path.join( folder_path, f )
- if f[-1] == os.sep:
- # FIXME: The selected item is a folder so transfer all the folder contents
- request_id = trans.security.ecnode_id( sample.request.id )
- return trans.response.send_redirect( web.url_for( controller='requests_admin',
- action='get_data',
- request_id=request_id,
- folder_path=folder_path,
- open_folder=True ) )
- else:
+ for filepath in selected_files:
+ # FIXME: handle folder selection
+ # ignore folders for now
+ if filepath[-1] != os.sep:
name = self.__dataset_name( sample, filepath.split( '/' )[-1] )
sample_dataset = trans.model.SampleDataset( sample=sample,
file_path=filepath,
Binary file static/june_2007_style/blue/dynatree_skin/ltP_nes.gif has changed
Binary file static/june_2007_style/blue/dynatree_skin/ltFld.gif has changed
Binary file static/june_2007_style/blue/dynatree_skin/rbIntermediate.gif has changed
--- /dev/null
+++ b/static/scripts/packed/ui.core.js
@@ -0,0 +1,1 @@
+jQuery.ui||(function(c){var i=c.fn.remove,d=c.browser.mozilla&&(parseFloat(c.browser.version)<1.9);c.ui={version:"1.7.1",plugin:{add:function(k,l,n){var m=c.ui[k].prototype;for(var j in n){m.plugins[j]=m.plugins[j]||[];m.plugins[j].push([l,n[j]])}},call:function(j,l,k){var n=j.plugins[l];if(!n||!j.element[0].parentNode){return}for(var m=0;m<n.length;m++){if(j.options[n[m][0]]){n[m][1].apply(j.element,k)}}}},contains:function(k,j){return document.compareDocumentPosition?k.compareDocumentPosition(j)&16:k!==j&&k.contains(j)},hasScroll:function(m,k){if(c(m).css("overflow")=="hidden"){return false}var j=(k&&k=="left")?"scrollLeft":"scrollTop",l=false;if(m[j]>0){return true}m[j]=1;l=(m[j]>0);m[j]=0;return l},isOverAxis:function(k,j,l){return(k>j)&&(k<(j+l))},isOver:function(o,k,n,m,j,l){return c.ui.isOverAxis(o,n,j)&&c.ui.isOverAxis(k,m,l)},keyCode:{BACKSPACE:8,CAPS_LOCK:20,COMMA:188,CONTROL:17,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,INSERT:45,LEFT:37,NUMPAD_ADD:107,NU
MPAD_DECIMAL:110,NUMPAD_DIVIDE:111,NUMPAD_ENTER:108,NUMPAD_MULTIPLY:106,NUMPAD_SUBTRACT:109,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SHIFT:16,SPACE:32,TAB:9,UP:38}};if(d){var f=c.attr,e=c.fn.removeAttr,h="http://www.w3.org/2005/07/aaa",a=/^aria-/,b=/^wairole:/;c.attr=function(k,j,l){var m=l!==undefined;return(j=="role"?(m?f.call(this,k,j,"wairole:"+l):(f.apply(this,arguments)||"").replace(b,"")):(a.test(j)?(m?k.setAttributeNS(h,j.replace(a,"aaa:"),l):f.call(this,k,j.replace(a,"aaa:"))):f.apply(this,arguments)))};c.fn.removeAttr=function(j){return(a.test(j)?this.each(function(){this.removeAttributeNS(h,j.replace(a,""))}):e.call(this,j))}}c.fn.extend({remove:function(){c("*",this).add(this).each(function(){c(this).triggerHandler("remove")});return i.apply(this,arguments)},enableSelection:function(){return this.attr("unselectable","off").css("MozUserSelect","").unbind("selectstart.ui")},disableSelection:function(){return this.attr("unselectable","on").css("MozUserSelect","no
ne").bind("selectstart.ui",function(){return false})},scrollParent:function(){var j;if((c.browser.msie&&(/(static|relative)/).test(this.css("position")))||(/absolute/).test(this.css("position"))){j=this.parents().filter(function(){return(/(relative|absolute|fixed)/).test(c.curCSS(this,"position",1))&&(/(auto|scroll)/).test(c.curCSS(this,"overflow",1)+c.curCSS(this,"overflow-y",1)+c.curCSS(this,"overflow-x",1))}).eq(0)}else{j=this.parents().filter(function(){return(/(auto|scroll)/).test(c.curCSS(this,"overflow",1)+c.curCSS(this,"overflow-y",1)+c.curCSS(this,"overflow-x",1))}).eq(0)}return(/fixed/).test(this.css("position"))||!j.length?c(document):j}});c.extend(c.expr[":"],{data:function(l,k,j){return !!c.data(l,j[3])},focusable:function(k){var l=k.nodeName.toLowerCase(),j=c.attr(k,"tabindex");return(/input|select|textarea|button|object/.test(l)?!k.disabled:"a"==l||"area"==l?k.href||!isNaN(j):!isNaN(j))&&!c(k)["area"==l?"parents":"closest"](":hidden").length},tabbable:function
(k){var j=c.attr(k,"tabindex");return(isNaN(j)||j>=0)&&c(k).is(":focusable")}});function g(m,n,o,l){function k(q){var p=c[m][n][q]||[];return(typeof p=="string"?p.split(/,?\s+/):p)}var j=k("getter");if(l.length==1&&typeof l[0]=="string"){j=j.concat(k("getterSetter"))}return(c.inArray(o,j)!=-1)}c.widget=function(k,j){var l=k.split(".")[0];k=k.split(".")[1];c.fn[k]=function(p){var n=(typeof p=="string"),o=Array.prototype.slice.call(arguments,1);if(n&&p.substring(0,1)=="_"){return this}if(n&&g(l,k,p,o)){var m=c.data(this[0],k);return(m?m[p].apply(m,o):undefined)}return this.each(function(){var q=c.data(this,k);(!q&&!n&&c.data(this,k,new c[l][k](this,p))._init());(q&&n&&c.isFunction(q[p])&&q[p].apply(q,o))})};c[l]=c[l]||{};c[l][k]=function(o,n){var m=this;this.namespace=l;this.widgetName=k;this.widgetEventPrefix=c[l][k].eventPrefix||k;this.widgetBaseClass=l+"-"+k;this.options=c.extend({},c.widget.defaults,c[l][k].defaults,c.metadata&&c.metadata.get(o)[k],n);this.element=c(o).bin
d("setData."+k,function(q,p,r){if(q.target==o){return m._setData(p,r)}}).bind("getData."+k,function(q,p){if(q.target==o){return m._getData(p)}}).bind("remove",function(){return m.destroy()})};c[l][k].prototype=c.extend({},c.widget.prototype,j);c[l][k].getterSetter="option"};c.widget.prototype={_init:function(){},destroy:function(){this.element.removeData(this.widgetName).removeClass(this.widgetBaseClass+"-disabled "+this.namespace+"-state-disabled").removeAttr("aria-disabled")},option:function(l,m){var k=l,j=this;if(typeof l=="string"){if(m===undefined){return this._getData(l)}k={};k[l]=m}c.each(k,function(n,o){j._setData(n,o)})},_getData:function(j){return this.options[j]},_setData:function(j,k){this.options[j]=k;if(j=="disabled"){this.element[k?"addClass":"removeClass"](this.widgetBaseClass+"-disabled "+this.namespace+"-state-disabled").attr("aria-disabled",k)}},enable:function(){this._setData("disabled",false)},disable:function(){this._setData("disabled",true)},_trigger:f
unction(l,m,n){var p=this.options[l],j=(l==this.widgetEventPrefix?l:this.widgetEventPrefix+l);m=c.Event(m);m.type=j;if(m.originalEvent){for(var k=c.event.props.length,o;k;){o=c.event.props[--k];m[o]=m.originalEvent[o]}}this.element.trigger(m,n);return !(c.isFunction(p)&&p.call(this.element[0],m,n)===false||m.isDefaultPrevented())}};c.widget.defaults={disabled:false};c.ui.mouse={_mouseInit:function(){var j=this;this.element.bind("mousedown."+this.widgetName,function(k){return j._mouseDown(k)}).bind("click."+this.widgetName,function(k){if(j._preventClickEvent){j._preventClickEvent=false;k.stopImmediatePropagation();return false}});if(c.browser.msie){this._mouseUnselectable=this.element.attr("unselectable");this.element.attr("unselectable","on")}this.started=false},_mouseDestroy:function(){this.element.unbind("."+this.widgetName);(c.browser.msie&&this.element.attr("unselectable",this._mouseUnselectable))},_mouseDown:function(l){l.originalEvent=l.originalEvent||{};if(l.originalE
vent.mouseHandled){return}(this._mouseStarted&&this._mouseUp(l));this._mouseDownEvent=l;var k=this,m=(l.which==1),j=(typeof this.options.cancel=="string"?c(l.target).parents().add(l.target).filter(this.options.cancel).length:false);if(!m||j||!this._mouseCapture(l)){return true}this.mouseDelayMet=!this.options.delay;if(!this.mouseDelayMet){this._mouseDelayTimer=setTimeout(function(){k.mouseDelayMet=true},this.options.delay)}if(this._mouseDistanceMet(l)&&this._mouseDelayMet(l)){this._mouseStarted=(this._mouseStart(l)!==false);if(!this._mouseStarted){l.preventDefault();return true}}this._mouseMoveDelegate=function(n){return k._mouseMove(n)};this._mouseUpDelegate=function(n){return k._mouseUp(n)};c(document).bind("mousemove."+this.widgetName,this._mouseMoveDelegate).bind("mouseup."+this.widgetName,this._mouseUpDelegate);(c.browser.safari||l.preventDefault());l.originalEvent.mouseHandled=true;return true},_mouseMove:function(j){if(c.browser.msie&&!j.button){return this._mouseUp(j
)}if(this._mouseStarted){this._mouseDrag(j);return j.preventDefault()}if(this._mouseDistanceMet(j)&&this._mouseDelayMet(j)){this._mouseStarted=(this._mouseStart(this._mouseDownEvent,j)!==false);(this._mouseStarted?this._mouseDrag(j):this._mouseUp(j))}return !this._mouseStarted},_mouseUp:function(j){c(document).unbind("mousemove."+this.widgetName,this._mouseMoveDelegate).unbind("mouseup."+this.widgetName,this._mouseUpDelegate);if(this._mouseStarted){this._mouseStarted=false;this._preventClickEvent=(j.target==this._mouseDownEvent.target);this._mouseStop(j)}return false},_mouseDistanceMet:function(j){return(Math.max(Math.abs(this._mouseDownEvent.pageX-j.pageX),Math.abs(this._mouseDownEvent.pageY-j.pageY))>=this.options.distance)},_mouseDelayMet:function(j){return this.mouseDelayMet},_mouseStart:function(j){},_mouseDrag:function(j){},_mouseStop:function(j){},_mouseCapture:function(j){return true}};c.ui.mouse.defaults={cancel:null,distance:1,delay:0}})(jQuery);
Binary file static/june_2007_style/blue/dynatree_skin/ltP_ne.gif has changed
Binary file static/june_2007_style/blue/dynatree_skin/cbIntermediate_hover.gif has changed
Binary file static/june_2007_style/blue/dynatree_skin/ltDoc.gif has changed
Binary file static/june_2007_style/blue/dynatree_skin/rbUnchecked.gif has changed
Binary file static/june_2007_style/blue/dynatree_skin/ltWait.gif has changed
Binary file static/june_2007_style/blue/dynatree_skin/cbChecked_hover.gif has changed
Binary file static/june_2007_style/blue/dynatree_skin/customDoc1.gif has changed
--- /dev/null
+++ b/static/scripts/ui.core.js
@@ -0,0 +1,519 @@
+/*
+ * jQuery UI 1.7.1
+ *
+ * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT (MIT-LICENSE.txt)
+ * and GPL (GPL-LICENSE.txt) licenses.
+ *
+ * http://docs.jquery.com/UI
+ */
+;jQuery.ui || (function($) {
+
+var _remove = $.fn.remove,
+ isFF2 = $.browser.mozilla && (parseFloat($.browser.version) < 1.9);
+
+//Helper functions and ui object
+$.ui = {
+ version: "1.7.1",
+
+ // $.ui.plugin is deprecated. Use the proxy pattern instead.
+ plugin: {
+ add: function(module, option, set) {
+ var proto = $.ui[module].prototype;
+ for(var i in set) {
+ proto.plugins[i] = proto.plugins[i] || [];
+ proto.plugins[i].push([option, set[i]]);
+ }
+ },
+ call: function(instance, name, args) {
+ var set = instance.plugins[name];
+ if(!set || !instance.element[0].parentNode) { return; }
+
+ for (var i = 0; i < set.length; i++) {
+ if (instance.options[set[i][0]]) {
+ set[i][1].apply(instance.element, args);
+ }
+ }
+ }
+ },
+
+ contains: function(a, b) {
+ return document.compareDocumentPosition
+ ? a.compareDocumentPosition(b) & 16
+ : a !== b && a.contains(b);
+ },
+
+ hasScroll: function(el, a) {
+
+ //If overflow is hidden, the element might have extra content, but the user wants to hide it
+ if ($(el).css('overflow') == 'hidden') { return false; }
+
+ var scroll = (a && a == 'left') ? 'scrollLeft' : 'scrollTop',
+ has = false;
+
+ if (el[scroll] > 0) { return true; }
+
+ // TODO: determine which cases actually cause this to happen
+ // if the element doesn't have the scroll set, see if it's possible to
+ // set the scroll
+ el[scroll] = 1;
+ has = (el[scroll] > 0);
+ el[scroll] = 0;
+ return has;
+ },
+
+ isOverAxis: function(x, reference, size) {
+ //Determines when x coordinate is over "b" element axis
+ return (x > reference) && (x < (reference + size));
+ },
+
+ isOver: function(y, x, top, left, height, width) {
+ //Determines when x, y coordinates is over "b" element
+ return $.ui.isOverAxis(y, top, height) && $.ui.isOverAxis(x, left, width);
+ },
+
+ keyCode: {
+ BACKSPACE: 8,
+ CAPS_LOCK: 20,
+ COMMA: 188,
+ CONTROL: 17,
+ DELETE: 46,
+ DOWN: 40,
+ END: 35,
+ ENTER: 13,
+ ESCAPE: 27,
+ HOME: 36,
+ INSERT: 45,
+ LEFT: 37,
+ NUMPAD_ADD: 107,
+ NUMPAD_DECIMAL: 110,
+ NUMPAD_DIVIDE: 111,
+ NUMPAD_ENTER: 108,
+ NUMPAD_MULTIPLY: 106,
+ NUMPAD_SUBTRACT: 109,
+ PAGE_DOWN: 34,
+ PAGE_UP: 33,
+ PERIOD: 190,
+ RIGHT: 39,
+ SHIFT: 16,
+ SPACE: 32,
+ TAB: 9,
+ UP: 38
+ }
+};
+
+// WAI-ARIA normalization
+if (isFF2) {
+ var attr = $.attr,
+ removeAttr = $.fn.removeAttr,
+ ariaNS = "http://www.w3.org/2005/07/aaa",
+ ariaState = /^aria-/,
+ ariaRole = /^wairole:/;
+
+ $.attr = function(elem, name, value) {
+ var set = value !== undefined;
+
+ return (name == 'role'
+ ? (set
+ ? attr.call(this, elem, name, "wairole:" + value)
+ : (attr.apply(this, arguments) || "").replace(ariaRole, ""))
+ : (ariaState.test(name)
+ ? (set
+ ? elem.setAttributeNS(ariaNS,
+ name.replace(ariaState, "aaa:"), value)
+ : attr.call(this, elem, name.replace(ariaState, "aaa:")))
+ : attr.apply(this, arguments)));
+ };
+
+ $.fn.removeAttr = function(name) {
+ return (ariaState.test(name)
+ ? this.each(function() {
+ this.removeAttributeNS(ariaNS, name.replace(ariaState, ""));
+ }) : removeAttr.call(this, name));
+ };
+}
+
+//jQuery plugins
+$.fn.extend({
+ remove: function() {
+ // Safari has a native remove event which actually removes DOM elements,
+ // so we have to use triggerHandler instead of trigger (#3037).
+ $("*", this).add(this).each(function() {
+ $(this).triggerHandler("remove");
+ });
+ return _remove.apply(this, arguments );
+ },
+
+ enableSelection: function() {
+ return this
+ .attr('unselectable', 'off')
+ .css('MozUserSelect', '')
+ .unbind('selectstart.ui');
+ },
+
+ disableSelection: function() {
+ return this
+ .attr('unselectable', 'on')
+ .css('MozUserSelect', 'none')
+ .bind('selectstart.ui', function() { return false; });
+ },
+
+ scrollParent: function() {
+ var scrollParent;
+ if(($.browser.msie && (/(static|relative)/).test(this.css('position'))) || (/absolute/).test(this.css('position'))) {
+ scrollParent = this.parents().filter(function() {
+ return (/(relative|absolute|fixed)/).test($.curCSS(this,'position',1)) && (/(auto|scroll)/).test($.curCSS(this,'overflow',1)+$.curCSS(this,'overflow-y',1)+$.curCSS(this,'overflow-x',1));
+ }).eq(0);
+ } else {
+ scrollParent = this.parents().filter(function() {
+ return (/(auto|scroll)/).test($.curCSS(this,'overflow',1)+$.curCSS(this,'overflow-y',1)+$.curCSS(this,'overflow-x',1));
+ }).eq(0);
+ }
+
+ return (/fixed/).test(this.css('position')) || !scrollParent.length ? $(document) : scrollParent;
+ }
+});
+
+
+//Additional selectors
+$.extend($.expr[':'], {
+ data: function(elem, i, match) {
+ return !!$.data(elem, match[3]);
+ },
+
+ focusable: function(element) {
+ var nodeName = element.nodeName.toLowerCase(),
+ tabIndex = $.attr(element, 'tabindex');
+ return (/input|select|textarea|button|object/.test(nodeName)
+ ? !element.disabled
+ : 'a' == nodeName || 'area' == nodeName
+ ? element.href || !isNaN(tabIndex)
+ : !isNaN(tabIndex))
+ // the element and all of its ancestors must be visible
+ // the browser may report that the area is hidden
+ && !$(element)['area' == nodeName ? 'parents' : 'closest'](':hidden').length;
+ },
+
+ tabbable: function(element) {
+ var tabIndex = $.attr(element, 'tabindex');
+ return (isNaN(tabIndex) || tabIndex >= 0) && $(element).is(':focusable');
+ }
+});
+
+
+// $.widget is a factory to create jQuery plugins
+// taking some boilerplate code out of the plugin code
+function getter(namespace, plugin, method, args) {
+ function getMethods(type) {
+ var methods = $[namespace][plugin][type] || [];
+ return (typeof methods == 'string' ? methods.split(/,?\s+/) : methods);
+ }
+
+ var methods = getMethods('getter');
+ if (args.length == 1 && typeof args[0] == 'string') {
+ methods = methods.concat(getMethods('getterSetter'));
+ }
+ return ($.inArray(method, methods) != -1);
+}
+
+$.widget = function(name, prototype) {
+ var namespace = name.split(".")[0];
+ name = name.split(".")[1];
+
+ // create plugin method
+ $.fn[name] = function(options) {
+ var isMethodCall = (typeof options == 'string'),
+ args = Array.prototype.slice.call(arguments, 1);
+
+ // prevent calls to internal methods
+ if (isMethodCall && options.substring(0, 1) == '_') {
+ return this;
+ }
+
+ // handle getter methods
+ if (isMethodCall && getter(namespace, name, options, args)) {
+ var instance = $.data(this[0], name);
+ return (instance ? instance[options].apply(instance, args)
+ : undefined);
+ }
+
+ // handle initialization and non-getter methods
+ return this.each(function() {
+ var instance = $.data(this, name);
+
+ // constructor
+ (!instance && !isMethodCall &&
+ $.data(this, name, new $[namespace][name](this, options))._init());
+
+ // method call
+ (instance && isMethodCall && $.isFunction(instance[options]) &&
+ instance[options].apply(instance, args));
+ });
+ };
+
+ // create widget constructor
+ $[namespace] = $[namespace] || {};
+ $[namespace][name] = function(element, options) {
+ var self = this;
+
+ this.namespace = namespace;
+ this.widgetName = name;
+ this.widgetEventPrefix = $[namespace][name].eventPrefix || name;
+ this.widgetBaseClass = namespace + '-' + name;
+
+ this.options = $.extend({},
+ $.widget.defaults,
+ $[namespace][name].defaults,
+ $.metadata && $.metadata.get(element)[name],
+ options);
+
+ this.element = $(element)
+ .bind('setData.' + name, function(event, key, value) {
+ if (event.target == element) {
+ return self._setData(key, value);
+ }
+ })
+ .bind('getData.' + name, function(event, key) {
+ if (event.target == element) {
+ return self._getData(key);
+ }
+ })
+ .bind('remove', function() {
+ return self.destroy();
+ });
+ };
+
+ // add widget prototype
+ $[namespace][name].prototype = $.extend({}, $.widget.prototype, prototype);
+
+ // TODO: merge getter and getterSetter properties from widget prototype
+ // and plugin prototype
+ $[namespace][name].getterSetter = 'option';
+};
+
+$.widget.prototype = {
+ _init: function() {},
+ destroy: function() {
+ this.element.removeData(this.widgetName)
+ .removeClass(this.widgetBaseClass + '-disabled' + ' ' + this.namespace + '-state-disabled')
+ .removeAttr('aria-disabled');
+ },
+
+ option: function(key, value) {
+ var options = key,
+ self = this;
+
+ if (typeof key == "string") {
+ if (value === undefined) {
+ return this._getData(key);
+ }
+ options = {};
+ options[key] = value;
+ }
+
+ $.each(options, function(key, value) {
+ self._setData(key, value);
+ });
+ },
+ _getData: function(key) {
+ return this.options[key];
+ },
+ _setData: function(key, value) {
+ this.options[key] = value;
+
+ if (key == 'disabled') {
+ this.element
+ [value ? 'addClass' : 'removeClass'](
+ this.widgetBaseClass + '-disabled' + ' ' +
+ this.namespace + '-state-disabled')
+ .attr("aria-disabled", value);
+ }
+ },
+
+ enable: function() {
+ this._setData('disabled', false);
+ },
+ disable: function() {
+ this._setData('disabled', true);
+ },
+
+ _trigger: function(type, event, data) {
+ var callback = this.options[type],
+ eventName = (type == this.widgetEventPrefix
+ ? type : this.widgetEventPrefix + type);
+
+ event = $.Event(event);
+ event.type = eventName;
+
+ // copy original event properties over to the new event
+ // this would happen if we could call $.event.fix instead of $.Event
+ // but we don't have a way to force an event to be fixed multiple times
+ if (event.originalEvent) {
+ for (var i = $.event.props.length, prop; i;) {
+ prop = $.event.props[--i];
+ event[prop] = event.originalEvent[prop];
+ }
+ }
+
+ this.element.trigger(event, data);
+
+ return !($.isFunction(callback) && callback.call(this.element[0], event, data) === false
+ || event.isDefaultPrevented());
+ }
+};
+
+$.widget.defaults = {
+ disabled: false
+};
+
+
+/** Mouse Interaction Plugin **/
+
+$.ui.mouse = {
+ _mouseInit: function() {
+ var self = this;
+
+ this.element
+ .bind('mousedown.'+this.widgetName, function(event) {
+ return self._mouseDown(event);
+ })
+ .bind('click.'+this.widgetName, function(event) {
+ if(self._preventClickEvent) {
+ self._preventClickEvent = false;
+ event.stopImmediatePropagation();
+ return false;
+ }
+ });
+
+ // Prevent text selection in IE
+ if ($.browser.msie) {
+ this._mouseUnselectable = this.element.attr('unselectable');
+ this.element.attr('unselectable', 'on');
+ }
+
+ this.started = false;
+ },
+
+ // TODO: make sure destroying one instance of mouse doesn't mess with
+ // other instances of mouse
+ _mouseDestroy: function() {
+ this.element.unbind('.'+this.widgetName);
+
+ // Restore text selection in IE
+ ($.browser.msie
+ && this.element.attr('unselectable', this._mouseUnselectable));
+ },
+
+ _mouseDown: function(event) {
+ // don't let more than one widget handle mouseStart
+ // TODO: figure out why we have to use originalEvent
+ event.originalEvent = event.originalEvent || {};
+ if (event.originalEvent.mouseHandled) { return; }
+
+ // we may have missed mouseup (out of window)
+ (this._mouseStarted && this._mouseUp(event));
+
+ this._mouseDownEvent = event;
+
+ var self = this,
+ btnIsLeft = (event.which == 1),
+ elIsCancel = (typeof this.options.cancel == "string" ? $(event.target).parents().add(event.target).filter(this.options.cancel).length : false);
+ if (!btnIsLeft || elIsCancel || !this._mouseCapture(event)) {
+ return true;
+ }
+
+ this.mouseDelayMet = !this.options.delay;
+ if (!this.mouseDelayMet) {
+ this._mouseDelayTimer = setTimeout(function() {
+ self.mouseDelayMet = true;
+ }, this.options.delay);
+ }
+
+ if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
+ this._mouseStarted = (this._mouseStart(event) !== false);
+ if (!this._mouseStarted) {
+ event.preventDefault();
+ return true;
+ }
+ }
+
+ // these delegates are required to keep context
+ this._mouseMoveDelegate = function(event) {
+ return self._mouseMove(event);
+ };
+ this._mouseUpDelegate = function(event) {
+ return self._mouseUp(event);
+ };
+ $(document)
+ .bind('mousemove.'+this.widgetName, this._mouseMoveDelegate)
+ .bind('mouseup.'+this.widgetName, this._mouseUpDelegate);
+
+ // preventDefault() is used to prevent the selection of text here -
+ // however, in Safari, this causes select boxes not to be selectable
+ // anymore, so this fix is needed
+ ($.browser.safari || event.preventDefault());
+
+ event.originalEvent.mouseHandled = true;
+ return true;
+ },
+
+ _mouseMove: function(event) {
+ // IE mouseup check - mouseup happened when mouse was out of window
+ if ($.browser.msie && !event.button) {
+ return this._mouseUp(event);
+ }
+
+ if (this._mouseStarted) {
+ this._mouseDrag(event);
+ return event.preventDefault();
+ }
+
+ if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
+ this._mouseStarted =
+ (this._mouseStart(this._mouseDownEvent, event) !== false);
+ (this._mouseStarted ? this._mouseDrag(event) : this._mouseUp(event));
+ }
+
+ return !this._mouseStarted;
+ },
+
+ _mouseUp: function(event) {
+ $(document)
+ .unbind('mousemove.'+this.widgetName, this._mouseMoveDelegate)
+ .unbind('mouseup.'+this.widgetName, this._mouseUpDelegate);
+
+ if (this._mouseStarted) {
+ this._mouseStarted = false;
+ this._preventClickEvent = (event.target == this._mouseDownEvent.target);
+ this._mouseStop(event);
+ }
+
+ return false;
+ },
+
+ _mouseDistanceMet: function(event) {
+ return (Math.max(
+ Math.abs(this._mouseDownEvent.pageX - event.pageX),
+ Math.abs(this._mouseDownEvent.pageY - event.pageY)
+ ) >= this.options.distance
+ );
+ },
+
+ _mouseDelayMet: function(event) {
+ return this.mouseDelayMet;
+ },
+
+ // These are placeholder methods, to be overriden by extending plugin
+ _mouseStart: function(event) {},
+ _mouseDrag: function(event) {},
+ _mouseStop: function(event) {},
+ _mouseCapture: function(event) { return true; }
+};
+
+$.ui.mouse.defaults = {
+ cancel: null,
+ distance: 1,
+ delay: 0
+};
+
+})(jQuery);
--- /dev/null
+++ b/static/scripts/jquery.cookie.js
@@ -0,0 +1,97 @@
+/**
+ * Cookie plugin
+ *
+ * Copyright (c) 2006 Klaus Hartl (stilbuero.de)
+ * Dual licensed under the MIT and GPL licenses:
+ * http://www.opensource.org/licenses/mit-license.php
+ * http://www.gnu.org/licenses/gpl.html
+ *
+ */
+
+/**
+ * Create a cookie with the given name and value and other optional parameters.
+ *
+ * @example $.cookie('the_cookie', 'the_value');
+ * @desc Set the value of a cookie.
+ * @example $.cookie('the_cookie', 'the_value', { expires: 7, path: '/', domain: 'jquery.com', secure: true });
+ * @desc Create a cookie with all available options.
+ * @example $.cookie('the_cookie', 'the_value');
+ * @desc Create a session cookie.
+ * @example $.cookie('the_cookie', null);
+ * @desc Delete a cookie by passing null as value. Keep in mind that you have to use the same path and domain
+ * used when the cookie was set.
+ *
+ * @param String name The name of the cookie.
+ * @param String value The value of the cookie.
+ * @param Object options An object literal containing key/value pairs to provide optional cookie attributes.
+ * @option Number|Date expires Either an integer specifying the expiration date from now on in days or a Date object.
+ * If a negative value is specified (e.g. a date in the past), the cookie will be deleted.
+ * If set to null or omitted, the cookie will be a session cookie and will not be retained
+ * when the the browser exits.
+ * @option String path The value of the path atribute of the cookie (default: path of page that created the cookie).
+ * @option String domain The value of the domain attribute of the cookie (default: domain of page that created the cookie).
+ * @option Boolean secure If true, the secure attribute of the cookie will be set and the cookie transmission will
+ * require a secure protocol (like HTTPS).
+ * @type undefined
+ *
+ * @name $.cookie
+ * @cat Plugins/Cookie
+ * @author Klaus Hartl/klaus.hartl(a)stilbuero.de
+ */
+
+/**
+ * Get the value of a cookie with the given name.
+ *
+ * @example $.cookie('the_cookie');
+ * @desc Get the value of a cookie.
+ *
+ * @param String name The name of the cookie.
+ * @return The value of the cookie.
+ * @type String
+ *
+ * @name $.cookie
+ * @cat Plugins/Cookie
+ * @author Klaus Hartl/klaus.hartl(a)stilbuero.de
+ */
+jQuery.cookie = function(name, value, options) {
+ if (typeof value != 'undefined') { // name and value given, set cookie
+ options = options || {};
+ if (value === null) {
+ value = '';
+ options = $.extend({}, options); // clone object since it's unexpected behavior if the expired property were changed
+ options.expires = -1;
+ }
+ var expires = '';
+ if (options.expires && (typeof options.expires == 'number' || options.expires.toUTCString)) {
+ var date;
+ if (typeof options.expires == 'number') {
+ date = new Date();
+ date.setTime(date.getTime() + (options.expires * 24 * 60 * 60 * 1000));
+ } else {
+ date = options.expires;
+ }
+ expires = '; expires=' + date.toUTCString(); // use expires attribute, max-age is not supported by IE
+ }
+ // NOTE Needed to parenthesize options.path and options.domain
+ // in the following expressions, otherwise they evaluate to undefined
+ // in the packed version for some reason...
+ var path = options.path ? '; path=' + (options.path) : '';
+ var domain = options.domain ? '; domain=' + (options.domain) : '';
+ var secure = options.secure ? '; secure' : '';
+ document.cookie = [name, '=', encodeURIComponent(value), expires, path, domain, secure].join('');
+ } else { // only name given, get cookie
+ var cookieValue = null;
+ if (document.cookie && document.cookie != '') {
+ var cookies = document.cookie.split(';');
+ for (var i = 0; i < cookies.length; i++) {
+ var cookie = jQuery.trim(cookies[i]);
+ // Does this cookie string begin with the name we want?
+ if (cookie.substring(0, name.length + 1) == (name + '=')) {
+ cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
+ break;
+ }
+ }
+ }
+ return cookieValue;
+ }
+};
Binary file static/june_2007_style/blue/dynatree_skin/ltM_ne.gif has changed
Binary file static/june_2007_style/blue/dynatree_skin/ltD_nes.gif has changed
Binary file static/june_2007_style/blue/dynatree_skin/ltFld_o.gif has changed
Binary file static/june_2007_style/blue/dynatree_skin/ltM_nes.gif has changed
--- /dev/null
+++ b/static/scripts/packed/jquery.dynatree.js
@@ -0,0 +1,1 @@
+var _canLog=true;function _log(g,f){if(!_canLog){return}var b=Array.prototype.slice.apply(arguments,[1]);var c=new Date();var a=c.getHours()+":"+c.getMinutes()+":"+c.getSeconds()+"."+c.getMilliseconds();b[0]=a+" - "+b[0];try{switch(g){case"info":window.console.info.apply(window.console,b);break;case"warn":window.console.warn.apply(window.console,b);break;default:window.console.log.apply(window.console,b)}}catch(d){if(!window.console){_canLog=false}}}function logMsg(a){Array.prototype.unshift.apply(arguments,["debug"]);_log.apply(this,arguments)}var getDynaTreePersistData=undefined;var DTNodeStatus_Error=-1;var DTNodeStatus_Loading=1;var DTNodeStatus_Ok=0;(function($){var Class={create:function(){return function(){this.initialize.apply(this,arguments)}}};var DynaTreeNode=Class.create();DynaTreeNode.prototype={initialize:function(parent,tree,data){this.parent=parent;this.tree=tree;if(typeof data=="string"){data={title:data}}if(data.key==undefined){data.key="_"+tree._nodeCount+
+}this.data=$.extend({},$.ui.dynatree.nodedatadefaults,data);this.div=null;this.span=null;this.childList=null;this.isLoading=false;this.hasSubSel=false},toString:function(){return"dtnode<"+this.data.key+">: '"+this.data.title+"'"},toDict:function(recursive,callback){var dict=$.extend({},this.data);dict.activate=(this.tree.activeNode===this);dict.focus=(this.tree.focusNode===this);dict.expand=this.bExpanded;dict.select=this.bSelected;if(callback){callback(dict)}if(recursive&&this.childList){dict.children=[];for(var i=0;i<this.childList.length;i++){dict.children.push(this.childList[i].toDict(true,callback))}}else{delete dict.children}return dict},_getInnerHtml:function(){var opts=this.tree.options;var cache=this.tree.cache;var rootParent=opts.rootVisible?null:this.tree.tnRoot;var bHideFirstExpander=(opts.rootVisible&&opts.minExpandLevel>0)||opts.minExpandLevel>1;var bHideFirstConnector=opts.rootVisible||opts.minExpandLevel>0;var res="";var p=this.parent;while(p){if(bHideFirstC
onnector&&p==rootParent){break}res=(p.isLastSibling()?cache.tagEmpty:cache.tagVline)+res;p=p.parent}if(bHideFirstExpander&&this.parent==rootParent){}else{if(this.childList||this.data.isLazy){res+=cache.tagExpander}else{res+=cache.tagConnector}}if(opts.checkbox&&this.data.hideCheckbox!=true&&!this.data.isStatusNode){res+=cache.tagCheckbox}if(this.data.icon){res+="<img src='"+opts.imagePath+this.data.icon+"' alt='' />"}else{if(this.data.icon==false){}else{res+=cache.tagNodeIcon}}var tooltip=(this.data&&typeof this.data.tooltip=="string")?" title='"+this.data.tooltip+"'":"";res+="<a href='#' class='"+opts.classNames.title+"'"+tooltip+">"+this.data.title+"</a>";return res},_fixOrder:function(){var cl=this.childList;if(!cl){return}var childDiv=this.div.firstChild.nextSibling;for(var i=0;i<cl.length-1;i++){var childNode1=cl[i];var childNode2=childDiv.firstChild.dtnode;if(childNode1!==childNode2){this.tree.logDebug("_fixOrder: mismatch at index "+i+": "+childNode1+" != "+childNode2
);this.div.insertBefore(childNode1.div,childNode2.div)}else{childDiv=childDiv.nextSibling}}},render:function(bDeep,bHidden){var opts=this.tree.options;var cn=opts.classNames;var isLastSib=this.isLastSibling();if(!this.div){this.span=document.createElement("span");this.span.dtnode=this;if(this.data.key){this.span.id=this.tree.options.idPrefix+this.data.key}this.div=document.createElement("div");this.div.appendChild(this.span);if(this.parent){this.parent.div.appendChild(this.div)}if(this.parent==null&&!this.tree.options.rootVisible){this.span.style.display="none"}}this.span.innerHTML=this._getInnerHtml();this.div.style.display=(this.parent==null||this.parent.bExpanded?"":"none");var cnList=[];cnList.push((this.data.isFolder)?cn.folder:cn.document);if(this.bExpanded){cnList.push(cn.expanded)}if(this.childList!=null){cnList.push(cn.hasChildren)}if(this.data.isLazy&&this.childList==null){cnList.push(cn.lazy)}if(isLastSib){cnList.push(cn.lastsib)}if(this.bSelected){cnList.push(cn.
selected)}if(this.hasSubSel){cnList.push(cn.partsel)}if(this.tree.activeNode===this){cnList.push(cn.active)}if(this.data.addClass){cnList.push(this.data.addClass)}cnList.push(cn.combinedExpanderPrefix+(this.bExpanded?"e":"c")+(this.data.isLazy&&this.childList==null?"d":"")+(isLastSib?"l":""));cnList.push(cn.combinedIconPrefix+(this.bExpanded?"e":"c")+(this.data.isFolder?"f":""));this.span.className=cnList.join(" ");if(bDeep&&this.childList&&(bHidden||this.bExpanded)){for(var i=0;i<this.childList.length;i++){this.childList[i].render(bDeep,bHidden)}this._fixOrder()}},hasChildren:function(){return this.childList!=null},isLastSibling:function(){var p=this.parent;if(!p){return true}return p.childList[p.childList.length-1]===this},prevSibling:function(){if(!this.parent){return null}var ac=this.parent.childList;for(var i=1;i<ac.length;i++){if(ac[i]===this){return ac[i-1]}}return null},nextSibling:function(){if(!this.parent){return null}var ac=this.parent.childList;for(var i=0;i<ac.
length-1;i++){if(ac[i]===this){return ac[i+1]}}return null},_setStatusNode:function(data){var firstChild=(this.childList?this.childList[0]:null);if(!data){if(firstChild){this.div.removeChild(firstChild.div);if(this.childList.length==1){this.childList=null}else{this.childList.shift()}}}else{if(firstChild){data.isStatusNode=true;firstChild.data=data;firstChild.render(false,false)}else{data.isStatusNode=true;firstChild=this.addChild(data)}}},setLazyNodeStatus:function(lts,opts){var tooltip=(opts&&opts.tooltip)?opts.tooltip:null;var info=(opts&&opts.info)?" ("+opts.info+")":"";switch(lts){case DTNodeStatus_Ok:this._setStatusNode(null);this.isLoading=false;this.render(false,false);if(this.tree.options.autoFocus){if(this===this.tree.tnRoot&&!this.tree.options.rootVisible&&this.childList){this.childList[0].focus()}else{this.focus()}}break;case DTNodeStatus_Loading:this.isLoading=true;this._setStatusNode({title:this.tree.options.strings.loading+info,tooltip:tooltip,addClass:this.tre
e.options.classNames.nodeWait});break;case DTNodeStatus_Error:this.isLoading=false;this._setStatusNode({title:this.tree.options.strings.loadError+info,tooltip:tooltip,addClass:this.tree.options.classNames.nodeError});break;default:throw"Bad LazyNodeStatus: '"+lts+"'."}},_parentList:function(includeRoot,includeSelf){var l=[];var dtn=includeSelf?this:this.parent;while(dtn){if(includeRoot||dtn.parent){l.unshift(dtn)}dtn=dtn.parent}return l},getLevel:function(){var level=0;var dtn=this.parent;while(dtn){level++;dtn=dtn.parent}return level},_getTypeForOuterNodeEvent:function(event){var cns=this.tree.options.classNames;var target=event.target;if(target.className.indexOf(cns.folder)<0&&target.className.indexOf(cns.document)<0){return null}var eventX=event.pageX-target.offsetLeft;var eventY=event.pageY-target.offsetTop;for(var i=0;i<target.childNodes.length;i++){var cn=target.childNodes[i];var x=cn.offsetLeft-target.offsetLeft;var y=cn.offsetTop-target.offsetTop;var nx=cn.clientWidt
h,ny=cn.clientHeight;if(eventX>=x&&eventX<=(x+nx)&&eventY>=y&&eventY<=(y+ny)){if(cn.className==cns.title){return"title"}else{if(cn.className==cns.expander){return"expander"}else{if(cn.className==cns.checkbox){return"checkbox"}else{if(cn.className==cns.nodeIcon){return"icon"}}}}}}return"prefix"},getEventTargetType:function(event){var tcn=event&&event.target?event.target.className:"";var cns=this.tree.options.classNames;if(tcn==cns.title){return"title"}else{if(tcn==cns.expander){return"expander"}else{if(tcn==cns.checkbox){return"checkbox"}else{if(tcn==cns.nodeIcon){return"icon"}else{if(tcn==cns.empty||tcn==cns.vline||tcn==cns.connector){return"prefix"}else{if(tcn.indexOf(cns.folder)>=0||tcn.indexOf(cns.document)>=0){return this._getTypeForOuterNodeEvent(event)}}}}}}return null},isVisible:function(){var parents=this._parentList(true,false);for(var i=0;i<parents.length;i++){if(!parents[i].bExpanded){return false}}return true},makeVisible:function(){var parents=this._parentList(t
rue,false);for(var i=0;i<parents.length;i++){parents[i]._expand(true)}},focus:function(){this.makeVisible();try{$(this.span).find(">a").focus()}catch(e){}},_activate:function(flag,fireEvents){this.tree.logDebug("dtnode._activate(%o, fireEvents=%o) - %o",flag,fireEvents,this);var opts=this.tree.options;if(this.data.isStatusNode){return}if(fireEvents&&opts.onQueryActivate&&opts.onQueryActivate.call(this.span,flag,this)==false){return}if(flag){if(this.tree.activeNode){if(this.tree.activeNode===this){return}this.tree.activeNode.deactivate()}if(opts.activeVisible){this.makeVisible()}this.tree.activeNode=this;if(opts.persist){$.cookie(opts.cookieId+"-active",this.data.key,opts.cookie)}this.tree.persistence.activeKey=this.data.key;$(this.span).addClass(opts.classNames.active);if(fireEvents&&opts.onActivate){opts.onActivate.call(this.span,this)}}else{if(this.tree.activeNode===this){var opts=this.tree.options;if(opts.onQueryActivate&&opts.onQueryActivate.call(this.span,false,this)==f
alse){return}$(this.span).removeClass(opts.classNames.active);if(opts.persist){$.cookie(opts.cookieId+"-active","",opts.cookie)}this.tree.persistence.activeKey=null;this.tree.activeNode=null;if(fireEvents&&opts.onDeactivate){opts.onDeactivate.call(this.span,this)}}}},activate:function(){this._activate(true,true)},deactivate:function(){this._activate(false,true)},isActive:function(){return(this.tree.activeNode===this)},_userActivate:function(){var activate=true;var expand=false;if(this.data.isFolder){switch(this.tree.options.clickFolderMode){case 2:activate=false;expand=true;break;case 3:activate=expand=true;break}}if(this.parent==null&&this.tree.options.minExpandLevel>0){expand=false}if(expand){this.toggleExpand();this.focus()}if(activate){this.activate()}},_setSubSel:function(hasSubSel){if(hasSubSel){this.hasSubSel=true;$(this.span).addClass(this.tree.options.classNames.partsel)}else{this.hasSubSel=false;$(this.span).removeClass(this.tree.options.classNames.partsel)}},_fixS
electionState:function(){if(this.bSelected){this.visit(function(dtnode){dtnode.parent._setSubSel(true);dtnode._select(true,false,false)});var p=this.parent;while(p){p._setSubSel(true);var allChildsSelected=true;for(var i=0;i<p.childList.length;i++){var n=p.childList[i];if(!n.bSelected&&!n.data.isStatusNode){allChildsSelected=false;break}}if(allChildsSelected){p._select(true,false,false)}p=p.parent}}else{this._setSubSel(false);this.visit(function(dtnode){dtnode._setSubSel(false);dtnode._select(false,false,false)});var p=this.parent;while(p){p._select(false,false,false);var isPartSel=false;for(var i=0;i<p.childList.length;i++){if(p.childList[i].bSelected||p.childList[i].hasSubSel){isPartSel=true;break}}p._setSubSel(isPartSel);p=p.parent}}},_select:function(sel,fireEvents,deep){var opts=this.tree.options;if(this.data.isStatusNode){return}if(this.bSelected==sel){return}if(fireEvents&&opts.onQuerySelect&&opts.onQuerySelect.call(this.span,sel,this)==false){return}if(opts.selectMod
e==1&&sel){this.tree.visit(function(dtnode){if(dtnode.bSelected){dtnode._select(false,false,false);return false}})}this.bSelected=sel;if(sel){if(opts.persist){this.tree.persistence.addSelect(this.data.key)}$(this.span).addClass(opts.classNames.selected);if(deep&&opts.selectMode==3){this._fixSelectionState()}if(fireEvents&&opts.onSelect){opts.onSelect.call(this.span,true,this)}}else{if(opts.persist){this.tree.persistence.clearSelect(this.data.key)}$(this.span).removeClass(opts.classNames.selected);if(deep&&opts.selectMode==3){this._fixSelectionState()}if(fireEvents&&opts.onSelect){opts.onSelect.call(this.span,false,this)}}},select:function(sel){if(this.data.unselectable){return this.bSelected}return this._select(sel!=false,true,true)},toggleSelect:function(){return this.select(!this.bSelected)},isSelected:function(){return this.bSelected},_loadContent:function(){try{var opts=this.tree.options;this.tree.logDebug("_loadContent: start - %o",this);this.setLazyNodeStatus(DTNodeSta
tus_Loading);if(true==opts.onLazyRead.call(this.span,this)){this.setLazyNodeStatus(DTNodeStatus_Ok);this.tree.logDebug("_loadContent: succeeded - %o",this)}}catch(e){this.setLazyNodeStatus(DTNodeStatus_Error);this.tree.logWarning("_loadContent: failed - %o",e)}},_expand:function(bExpand){if(this.bExpanded==bExpand){return}var opts=this.tree.options;if(!bExpand&&this.getLevel()<opts.minExpandLevel){this.tree.logDebug("dtnode._expand(%o) forced expand - %o",bExpand,this);return}if(opts.onQueryExpand&&opts.onQueryExpand.call(this.span,bExpand,this)==false){return}this.bExpanded=bExpand;if(opts.persist){if(bExpand){this.tree.persistence.addExpand(this.data.key)}else{this.tree.persistence.clearExpand(this.data.key)}}this.render(false);if(this.bExpanded&&this.parent&&opts.autoCollapse){var parents=this._parentList(false,true);for(var i=0;i<parents.length;i++){parents[i].collapseSiblings()}}if(opts.activeVisible&&this.tree.activeNode&&!this.tree.activeNode.isVisible()){this.tree.ac
tiveNode.deactivate()}if(bExpand&&this.data.isLazy&&this.childList==null&&!this.isLoading){this._loadContent();return}var fxDuration=opts.fx?(opts.fx.duration||200):0;if(this.childList){for(var i=0;i<this.childList.length;i++){var $child=$(this.childList[i].div);if(fxDuration){if(bExpand!=$child.is(":visible")){$child.animate(opts.fx,fxDuration)}}else{if(bExpand){$child.show()}else{$child.hide()}}}}if(opts.onExpand){opts.onExpand.call(this.span,bExpand,this)}},expand:function(flag){if(!this.childList&&!this.data.isLazy&&flag){return}if(this.parent==null&&this.tree.options.minExpandLevel>0&&!flag){return}this._expand(flag)},toggleExpand:function(){this.expand(!this.bExpanded)},collapseSiblings:function(){if(this.parent==null){return}var ac=this.parent.childList;for(var i=0;i<ac.length;i++){if(ac[i]!==this&&ac[i].bExpanded){ac[i]._expand(false)}}},onClick:function(event){var targetType=this.getEventTargetType(event);if(targetType=="expander"){this.toggleExpand();this.focus()}e
lse{if(targetType=="checkbox"){this.toggleSelect();this.focus()}else{this._userActivate();this.span.getElementsByTagName("a")[0].focus()}}return false},onDblClick:function(event){},onKeydown:function(event){var handled=true;switch(event.which){case 107:case 187:if(!this.bExpanded){this.toggleExpand()}break;case 109:case 189:if(this.bExpanded){this.toggleExpand()}break;case 32:this._userActivate();break;case 8:if(this.parent){this.parent.focus()}break;case 37:if(this.bExpanded){this.toggleExpand();this.focus()}else{if(this.parent&&(this.tree.options.rootVisible||this.parent.parent)){this.parent.focus()}}break;case 39:if(!this.bExpanded&&(this.childList||this.data.isLazy)){this.toggleExpand();this.focus()}else{if(this.childList){this.childList[0].focus()}}break;case 38:var sib=this.prevSibling();while(sib&&sib.bExpanded&&sib.childList){sib=sib.childList[sib.childList.length-1]}if(!sib&&this.parent&&(this.tree.options.rootVisible||this.parent.parent)){sib=this.parent}if(sib){si
b.focus()}break;case 40:var sib;if(this.bExpanded&&this.childList){sib=this.childList[0]}else{var parents=this._parentList(false,true);for(var i=parents.length-1;i>=0;i--){sib=parents[i].nextSibling();if(sib){break}}}if(sib){sib.focus()}break;default:handled=false}return !handled},onKeypress:function(event){},onFocus:function(event){var opts=this.tree.options;if(event.type=="blur"||event.type=="focusout"){if(opts.onBlur){opts.onBlur.call(this.span,this)}if(this.tree.tnFocused){$(this.tree.tnFocused.span).removeClass(opts.classNames.focused)}this.tree.tnFocused=null;if(opts.persist){$.cookie(opts.cookieId+"-focus","",opts.cookie)}}else{if(event.type=="focus"||event.type=="focusin"){if(this.tree.tnFocused&&this.tree.tnFocused!==this){this.tree.logDebug("dtnode.onFocus: out of sync: curFocus: %o",this.tree.tnFocused);$(this.tree.tnFocused.span).removeClass(opts.classNames.focused)}this.tree.tnFocused=this;if(opts.onFocus){opts.onFocus.call(this.span,this)}$(this.tree.tnFocused.
span).addClass(opts.classNames.focused);if(opts.persist){$.cookie(opts.cookieId+"-focus",this.data.key,opts.cookie)}}}},visit:function(fn,data,includeSelf){var n=0;if(includeSelf==true){if(fn(this,data)==false){return 1}n++}if(this.childList){for(var i=0;i<this.childList.length;i++){n+=this.childList[i].visit(fn,data,true)}}return n},remove:function(){if(this===this.tree.root){return false}return this.parent.removeChild(this)},removeChild:function(tn){var ac=this.childList;if(ac.length==1){if(tn!==ac[0]){throw"removeChild: invalid child"}return this.removeChildren()}if(tn===this.tree.activeNode){tn.deactivate()}if(this.tree.options.persist){if(tn.bSelected){this.tree.persistence.clearSelect(tn.data.key)}if(tn.bExpanded){this.tree.persistence.clearExpand(tn.data.key)}}tn.removeChildren(true);this.div.removeChild(tn.div);for(var i=0;i<ac.length;i++){if(ac[i]===tn){this.childList.splice(i,1);delete tn;break}}},removeChildren:function(isRecursiveCall,retainPersistence){var tree=
this.tree;var ac=this.childList;if(ac){for(var i=0;i<ac.length;i++){var tn=ac[i];if(tn===tree.activeNode&&!retainPersistence){tn.deactivate()}if(this.tree.options.persist&&!retainPersistence){if(tn.bSelected){this.tree.persistence.clearSelect(tn.data.key)}if(tn.bExpanded){this.tree.persistence.clearExpand(tn.data.key)}}tn.removeChildren(true,retainPersistence);this.div.removeChild(tn.div);delete tn}this.childList=null}if(!isRecursiveCall){this.isLoading=false;this.render(false,false)}},reload:function(force){if(this.parent==null){return this.tree.reload()}if(!this.data.isLazy){throw"node.reload() requires lazy nodes."}if(this.bExpanded){this.expand(false);this.removeChildren();this.expand(true)}else{this.removeChildren();if(force){this._loadContent()}}},_addChildNode:function(dtnode,beforeNode){var tree=this.tree;var opts=tree.options;var pers=tree.persistence;dtnode.parent=this;if(this.childList==null){this.childList=[]}else{if(!beforeNode){$(this.childList[this.childList.l
ength-1].span).removeClass(opts.classNames.lastsib)}}if(beforeNode){var iBefore=$.inArray(beforeNode,this.childList);if(iBefore<0){throw"<beforeNode> must be a child of <this>"}this.childList.splice(iBefore,0,dtnode)}else{this.childList.push(dtnode)}var isInitializing=tree.isInitializing();if(opts.persist&&pers.cookiesFound&&isInitializing){if(pers.activeKey==dtnode.data.key){tree.activeNode=dtnode}if(pers.focusedKey==dtnode.data.key){tree.focusNode=dtnode}dtnode.bExpanded=($.inArray(dtnode.data.key,pers.expandedKeyList)>=0);dtnode.bSelected=($.inArray(dtnode.data.key,pers.selectedKeyList)>=0)}else{if(dtnode.data.activate){tree.activeNode=dtnode;if(opts.persist){pers.activeKey=dtnode.data.key}}if(dtnode.data.focus){tree.focusNode=dtnode;if(opts.persist){pers.focusedKey=dtnode.data.key}}dtnode.bExpanded=(dtnode.data.expand==true);if(dtnode.bExpanded&&opts.persist){pers.addExpand(dtnode.data.key)}dtnode.bSelected=(dtnode.data.select==true);if(dtnode.bSelected&&opts.persist){pe
rs.addSelect(dtnode.data.key)}}if(opts.minExpandLevel>=dtnode.getLevel()){this.bExpanded=true}if(dtnode.bSelected&&opts.selectMode==3){var p=this;while(p){if(!p.hasSubSel){p._setSubSel(true)}p=p.parent}}if(tree.bEnableUpdate){this.render(true,true)}return dtnode},addChild:function(obj,beforeNode){if(!obj||obj.length==0){return}if(obj instanceof DynaTreeNode){return this._addChildNode(obj,beforeNode)}if(!obj.length){obj=[obj]}var prevFlag=this.tree.enableUpdate(false);var tnFirst=null;for(var i=0;i<obj.length;i++){var data=obj[i];var dtnode=this._addChildNode(new DynaTreeNode(this,this.tree,data),beforeNode);if(!tnFirst){tnFirst=dtnode}if(data.children){dtnode.addChild(data.children,null)}}this.tree.enableUpdate(prevFlag);return tnFirst},append:function(obj){this.tree.logWarning("node.append() is deprecated (use node.addChild() instead).");return this.addChild(obj,null)},appendAjax:function(ajaxOptions){this.removeChildren(false,true);this.setLazyNodeStatus(DTNodeStatus_Loadi
ng);var self=this;var orgSuccess=ajaxOptions.success;var orgError=ajaxOptions.error;var options=$.extend({},this.tree.options.ajaxDefaults,ajaxOptions,{success:function(data,textStatus){var prevPhase=self.tree.phase;self.tree.phase="init";self.addChild(data,null);self.tree.phase="postInit";self.setLazyNodeStatus(DTNodeStatus_Ok);if(orgSuccess){orgSuccess.call(options,self)}self.tree.phase=prevPhase},error:function(XMLHttpRequest,textStatus,errorThrown){self.tree.logWarning("appendAjax failed:",textStatus,":\n",XMLHttpRequest,"\n",errorThrown);self.setLazyNodeStatus(DTNodeStatus_Error,{info:textStatus,tooltip:""+errorThrown});if(orgError){orgError.call(options,self,XMLHttpRequest,textStatus,errorThrown)}}});$.ajax(options)},lastentry:undefined};var DynaTreeStatus=Class.create();DynaTreeStatus._getTreePersistData=function(cookieId,cookieOpts){var ts=new DynaTreeStatus(cookieId,cookieOpts);ts.read();return ts.toDict()};getDynaTreePersistData=DynaTreeStatus._getTreePersistData;D
ynaTreeStatus.prototype={initialize:function(cookieId,cookieOpts){this._log("DynaTreeStatus: initialize");if(cookieId===undefined){cookieId=$.ui.dynatree.defaults.cookieId}cookieOpts=$.extend({},$.ui.dynatree.defaults.cookie,cookieOpts);this.cookieId=cookieId;this.cookieOpts=cookieOpts;this.cookiesFound=undefined;this.activeKey=null;this.focusedKey=null;this.expandedKeyList=null;this.selectedKeyList=null},_log:function(msg){Array.prototype.unshift.apply(arguments,["debug"]);_log.apply(this,arguments)},read:function(){this._log("DynaTreeStatus: read");this.cookiesFound=false;var cookie=$.cookie(this.cookieId+"-active");this.activeKey=(cookie==null)?"":cookie;if(cookie!=null){this.cookiesFound=true}cookie=$.cookie(this.cookieId+"-focus");this.focusedKey=(cookie==null)?"":cookie;if(cookie!=null){this.cookiesFound=true}cookie=$.cookie(this.cookieId+"-expand");this.expandedKeyList=(cookie==null)?[]:cookie.split(",");if(cookie!=null){this.cookiesFound=true}cookie=$.cookie(this.coo
kieId+"-select");this.selectedKeyList=(cookie==null)?[]:cookie.split(",");if(cookie!=null){this.cookiesFound=true}},write:function(){this._log("DynaTreeStatus: write");$.cookie(this.cookieId+"-active",(this.activeKey==null)?"":this.activeKey,this.cookieOpts);$.cookie(this.cookieId+"-focus",(this.focusedKey==null)?"":this.focusedKey,this.cookieOpts);$.cookie(this.cookieId+"-expand",(this.expandedKeyList==null)?"":this.expandedKeyList.join(","),this.cookieOpts);$.cookie(this.cookieId+"-select",(this.selectedKeyList==null)?"":this.selectedKeyList.join(","),this.cookieOpts)},addExpand:function(key){this._log("addExpand(%o)",key);if($.inArray(key,this.expandedKeyList)<0){this.expandedKeyList.push(key);$.cookie(this.cookieId+"-expand",this.expandedKeyList.join(","),this.cookieOpts)}},clearExpand:function(key){this._log("clearExpand(%o)",key);var idx=$.inArray(key,this.expandedKeyList);if(idx>=0){this.expandedKeyList.splice(idx,1);$.cookie(this.cookieId+"-expand",this.expandedKeyLi
st.join(","),this.cookieOpts)}},addSelect:function(key){this._log("addSelect(%o)",key);if($.inArray(key,this.selectedKeyList)<0){this.selectedKeyList.push(key);$.cookie(this.cookieId+"-select",this.selectedKeyList.join(","),this.cookieOpts)}},clearSelect:function(key){this._log("clearSelect(%o)",key);var idx=$.inArray(key,this.selectedKeyList);if(idx>=0){this.selectedKeyList.splice(idx,1);$.cookie(this.cookieId+"-select",this.selectedKeyList.join(","),this.cookieOpts)}},isReloading:function(){return this.cookiesFound==true},toDict:function(){return{cookiesFound:this.cookiesFound,activeKey:this.activeKey,focusedKey:this.activeKey,expandedKeyList:this.expandedKeyList,selectedKeyList:this.selectedKeyList}},lastentry:undefined};var DynaTree=Class.create();DynaTree.version="$Version: 0.5.4$";DynaTree.prototype={initialize:function($widget){this.phase="init";this.$widget=$widget;this.options=$widget.options;this.$tree=$widget.element;this.divTree=this.$tree.get(0)},_load:function(
){var $widget=this.$widget;var opts=this.options;this.bEnableUpdate=true;this._nodeCount=1;this.activeNode=null;this.focusNode=null;if(opts.classNames!==$.ui.dynatree.defaults.classNames){opts.classNames=$.extend({},$.ui.dynatree.defaults.classNames,opts.classNames)}if(!opts.imagePath){$("script").each(function(){if(this.src.search(_rexDtLibName)>=0){if(this.src.indexOf("/")>=0){opts.imagePath=this.src.slice(0,this.src.lastIndexOf("/"))+"/skin/"}else{opts.imagePath="skin/"}return false}})}this.persistence=new DynaTreeStatus(opts.cookieId,opts.cookie);if(opts.persist){if(!$.cookie){_log("warn","Please include jquery.cookie.js to use persistence.")}this.persistence.read()}this.logDebug("DynaTree.persistence: %o",this.persistence.toDict());this.cache={tagEmpty:"<span class='"+opts.classNames.empty+"'></span>",tagVline:"<span class='"+opts.classNames.vline+"'></span>",tagExpander:"<span class='"+opts.classNames.expander+"'></span>",tagConnector:"<span class='"+opts.classNames.co
nnector+"'></span>",tagNodeIcon:"<span class='"+opts.classNames.nodeIcon+"'></span>",tagCheckbox:"<span class='"+opts.classNames.checkbox+"'></span>",lastentry:undefined};if(opts.children||(opts.initAjax&&opts.initAjax.url)||opts.initId){$(this.divTree).empty()}else{if(this.divRoot){$(this.divRoot).remove()}}this.tnRoot=new DynaTreeNode(null,this,{title:opts.title,key:"root"});this.tnRoot.data.isFolder=true;this.tnRoot.render(false,false);this.divRoot=this.tnRoot.div;this.divRoot.className=opts.classNames.container;this.divTree.appendChild(this.divRoot);var root=this.tnRoot;var isReloading=(opts.persist&&this.persistence.isReloading());var isLazy=false;var prevFlag=this.enableUpdate(false);this.logDebug("Dynatree._load(): read tree structure...");if(opts.children){root.addChild(opts.children)}else{if(opts.initAjax&&opts.initAjax.url){isLazy=true;root.data.isLazy=true;this._reloadAjax()}else{if(opts.initId){this._createFromTag(root,$("#"+opts.initId))}else{var $ul=this.$tree.
find(">ul").hide();this._createFromTag(root,$ul);$ul.remove()}}}this._checkConsistency();this.logDebug("Dynatree._load(): render nodes...");this.enableUpdate(prevFlag);this.logDebug("Dynatree._load(): bind events...");this.$widget.bind();this.logDebug("Dynatree._load(): postInit...");this.phase="postInit";if(opts.persist){this.persistence.write()}if(this.focusNode&&this.focusNode.isVisible()){this.logDebug("Focus on init: %o",this.focusNode);this.focusNode.focus()}if(!isLazy&&opts.onPostInit){opts.onPostInit.call(this,isReloading,false)}this.phase="idle"},_reloadAjax:function(){var opts=this.options;if(!opts.initAjax||!opts.initAjax.url){throw"tree.reload() requires 'initAjax' mode."}var pers=this.persistence;var ajaxOpts=$.extend({},opts.initAjax);if(ajaxOpts.addActiveKey){ajaxOpts.data.activeKey=pers.activeKey}if(ajaxOpts.addFocusedKey){ajaxOpts.data.focusedKey=pers.focusedKey}if(ajaxOpts.addExpandedKeyList){ajaxOpts.data.expandedKeyList=pers.expandedKeyList.join(",")}if(a
jaxOpts.addSelectedKeyList){ajaxOpts.data.selectedKeyList=pers.selectedKeyList.join(",")}if(opts.onPostInit){if(ajaxOpts.success){this.logWarning("initAjax: success callback is ignored when onPostInit was specified.")}if(ajaxOpts.error){this.logWarning("initAjax: error callback is ignored when onPostInit was specified.")}var isReloading=pers.isReloading();ajaxOpts.success=function(dtnode){opts.onPostInit.call(dtnode.tree,isReloading,false)};ajaxOpts.error=function(dtnode){opts.onPostInit.call(dtnode.tree,isReloading,true)}}this.logDebug("Dynatree._init(): send Ajax request...");this.tnRoot.appendAjax(ajaxOpts)},toString:function(){return"DynaTree '"+this.options.title+"'"},toDict:function(){return this.tnRoot.toDict(true)},getPersistData:function(){return this.persistence.toDict()},logDebug:function(msg){if(this.options.debugLevel>=2){Array.prototype.unshift.apply(arguments,["debug"]);_log.apply(this,arguments)}},logInfo:function(msg){if(this.options.debugLevel>=1){Array.pro
totype.unshift.apply(arguments,["info"]);_log.apply(this,arguments)}},logWarning:function(msg){Array.prototype.unshift.apply(arguments,["warn"]);_log.apply(this,arguments)},isInitializing:function(){return(this.phase=="init"||this.phase=="postInit")},isReloading:function(){return(this.phase=="init"||this.phase=="postInit")&&this.options.persist&&this.persistence.cookiesFound},isUserEvent:function(){return(this.phase=="userEvent")},redraw:function(){this.logDebug("dynatree.redraw()...");this.tnRoot.render(true,true);this.logDebug("dynatree.redraw() done.")},reloadAjax:function(){this.logWarning("tree.reloadAjax() is deprecated since v0.5.2 (use reload() instead).")},reload:function(){this._load()},getRoot:function(){return this.tnRoot},getNodeByKey:function(key){var el=document.getElementById(this.options.idPrefix+key);return(el&&el.dtnode)?el.dtnode:null},getActiveNode:function(){return this.activeNode},reactivate:function(setFocus){var node=this.activeNode;if(node){this.act
iveNode=null;node.activate();if(setFocus){node.focus()}}},getSelectedNodes:function(stopOnParents){var nodeList=[];this.tnRoot.visit(function(dtnode){if(dtnode.bSelected){nodeList.push(dtnode);if(stopOnParents==true){return false}}});return nodeList},activateKey:function(key){var dtnode=(key===null)?null:this.getNodeByKey(key);if(!dtnode){if(this.activeNode){this.activeNode.deactivate()}this.activeNode=null;return null}dtnode.focus();dtnode.activate();return dtnode},selectKey:function(key,select){var dtnode=this.getNodeByKey(key);if(!dtnode){return null}dtnode.select(select);return dtnode},enableUpdate:function(bEnable){if(this.bEnableUpdate==bEnable){return bEnable}this.bEnableUpdate=bEnable;if(bEnable){this.redraw()}return !bEnable},visit:function(fn,data,includeRoot){return this.tnRoot.visit(fn,data,includeRoot)},_createFromTag:function(parentTreeNode,$ulParent){var self=this;$ulParent.find(">li").each(function(){var $li=$(this);var $liSpan=$li.find(">span:first");var tit
le;if($liSpan.length){title=$liSpan.html()}else{title=$li.html();var iPos=title.search(/<ul/i);if(iPos>=0){title=$.trim(title.substring(0,iPos))}else{title=$.trim(title)}}var data={title:title,isFolder:$li.hasClass("folder"),isLazy:$li.hasClass("lazy"),expand:$li.hasClass("expanded"),select:$li.hasClass("selected"),activate:$li.hasClass("active"),focus:$li.hasClass("focused")};if($li.attr("title")){data.tooltip=$li.attr("title")}if($li.attr("id")){data.key=$li.attr("id")}if($li.attr("data")){var dataAttr=$.trim($li.attr("data"));if(dataAttr){if(dataAttr.charAt(0)!="{"){dataAttr="{"+dataAttr+"}"}try{$.extend(data,eval("("+dataAttr+")"))}catch(e){throw ("Error parsing node data: "+e+"\ndata:\n'"+dataAttr+"'")}}}childNode=parentTreeNode.addChild(data);var $ul=$li.find(">ul:first");if($ul.length){self._createFromTag(childNode,$ul)}})},_checkConsistency:function(){},lastentry:undefined};$.widget("ui.dynatree",{init:function(){_log("warn","ui.dynatree.init() was called; you should
upgrade to ui.core.js v1.6 or higher.");return this._init()},_init:function(){if(parseFloat($.ui.version)<1.8){_log("info","ui.dynatree._init() was called; consider upgrading to jquery.ui.core.js v1.8 or higher.");return this._create()}_log("debug","ui.dynatree._init() was called; no current default functionality.")},_create:function(){if(parseFloat($.ui.version)>=1.8){this.options=$.extend(true,{},$[this.namespace][this.widgetName].defaults,this.options)}logMsg("Dynatree._create(): version='%s', debugLevel=%o.",DynaTree.version,this.options.debugLevel);var opts=this.options;this.options.event+=".dynatree";var divTree=this.element.get(0);this.tree=new DynaTree(this);this.tree._load();this.tree.logDebug("Dynatree._create(): done.")},bind:function(){var $this=this.element;var o=this.options;this.unbind();function __getNodeFromElement(el){var iMax=5;while(el&&iMax--){if(el.dtnode){return el.dtnode}el=el.parentNode}return null}var eventNames="click.dynatree dblclick.dynatree";i
f(o.keyboard){eventNames+=" keypress.dynatree keydown.dynatree"}$this.bind(eventNames,function(event){var dtnode=__getNodeFromElement(event.target);if(!dtnode){return true}var prevPhase=dtnode.tree.phase;dtnode.tree.phase="userEvent";try{dtnode.tree.logDebug("bind(%o): dtnode: %o",event,dtnode);switch(event.type){case"click":return(o.onClick&&o.onClick(dtnode,event)===false)?false:dtnode.onClick(event);case"dblclick":return(o.onDblClick&&o.onDblClick(dtnode,event)===false)?false:dtnode.onDblClick(event);case"keydown":return(o.onKeydown&&o.onKeydown(dtnode,event)===false)?false:dtnode.onKeydown(event);case"keypress":return(o.onKeypress&&o.onKeypress(dtnode,event)===false)?false:dtnode.onKeypress(event)}}catch(e){var _=null}finally{dtnode.tree.phase=prevPhase}});function __focusHandler(event){event=arguments[0]=$.event.fix(event||window.event);var dtnode=__getNodeFromElement(event.target);return dtnode?dtnode.onFocus(event):false}var div=this.tree.divTree;if(div.addEventListen
er){div.addEventListener("focus",__focusHandler,true);div.addEventListener("blur",__focusHandler,true)}else{div.onfocusin=div.onfocusout=__focusHandler}},unbind:function(){this.element.unbind(".dynatree")},enable:function(){this.bind();$.widget.prototype.enable.apply(this,arguments)},disable:function(){this.unbind();$.widget.prototype.disable.apply(this,arguments)},getTree:function(){return this.tree},getRoot:function(){return this.tree.getRoot()},getActiveNode:function(){return this.tree.getActiveNode()},getSelectedNodes:function(){return this.tree.getSelectedNodes()},lastentry:undefined});$.ui.dynatree.getter="getTree getRoot getActiveNode getSelectedNodes";$.ui.dynatree.defaults={title:"Dynatree root",rootVisible:false,minExpandLevel:1,imagePath:null,children:null,initId:null,initAjax:null,autoFocus:true,keyboard:true,persist:false,autoCollapse:false,clickFolderMode:3,activeVisible:true,checkbox:false,selectMode:2,fx:null,onClick:null,onDblClick:null,onKeydown:null,onKeyp
ress:null,onFocus:null,onBlur:null,onQueryActivate:null,onQuerySelect:null,onQueryExpand:null,onPostInit:null,onActivate:null,onDeactivate:null,onSelect:null,onExpand:null,onLazyRead:null,ajaxDefaults:{cache:false,dataType:"json"},strings:{loading:"Loading…",loadError:"Load error!"},idPrefix:"ui-dynatree-id-",cookieId:"dynatree",cookie:{expires:null},classNames:{container:"ui-dynatree-container",folder:"ui-dynatree-folder",document:"ui-dynatree-document",empty:"ui-dynatree-empty",vline:"ui-dynatree-vline",expander:"ui-dynatree-expander",connector:"ui-dynatree-connector",checkbox:"ui-dynatree-checkbox",nodeIcon:"ui-dynatree-icon",title:"ui-dynatree-title",nodeError:"ui-dynatree-statusnode-error",nodeWait:"ui-dynatree-statusnode-wait",hidden:"ui-dynatree-hidden",combinedExpanderPrefix:"ui-dynatree-exp-",combinedIconPrefix:"ui-dynatree-ico-",hasChildren:"ui-dynatree-has-children",active:"ui-dynatree-active",selected:"ui-dynatree-selected",expanded:"ui-dynatree-expanded",l
azy:"ui-dynatree-lazy",focused:"ui-dynatree-focused",partsel:"ui-dynatree-partsel",lastsib:"ui-dynatree-lastsib"},debugLevel:1,lastentry:undefined};$.ui.dynatree.nodedatadefaults={title:null,key:null,isFolder:false,isLazy:false,tooltip:null,icon:null,addClass:null,activate:false,focus:false,expand:false,select:false,hideCheckbox:false,unselectable:false,children:null,lastentry:undefined}})(jQuery);var _rexDtLibName=/.*dynatree[^/]*\.js$/i;
Binary file static/june_2007_style/blue/dynatree_skin/rbChecked.gif has changed
--- /dev/null
+++ b/static/scripts/jquery.dynatree.js
@@ -0,0 +1,2034 @@
+/*************************************************************************
+ jquery.dynatree.js
+ Dynamic tree view control, with support for lazy loading of branches.
+
+ Copyright (c) 2008-2010, Martin Wendt (http://wwWendt.de)
+ Dual licensed under the MIT or GPL Version 2 licenses.
+ http://code.google.com/p/dynatree/wiki/LicenseInfo
+
+ A current version and some documentation is available at
+ http://dynatree.googlecode.com/
+
+ $Version: 0.5.4$
+ $Revision: 329, 2010-05-05 08:04:39$
+
+ @depends: jquery.js
+ @depends: ui.core.js
+ @depends: jquery.cookie.js
+*************************************************************************/
+
+
+/*************************************************************************
+ * Debug functions
+ */
+
+var _canLog = true;
+
+function _log(mode, msg) {
+ /**
+ * Usage: logMsg("%o was toggled", this);
+ */
+ if( !_canLog )
+ return;
+ // Remove first argument
+ var args = Array.prototype.slice.apply(arguments, [1]);
+ // Prepend timestamp
+ var dt = new Date();
+ var tag = dt.getHours()+":"+dt.getMinutes()+":"+dt.getSeconds()+"."+dt.getMilliseconds();
+ args[0] = tag + " - " + args[0];
+
+ try {
+ switch( mode ) {
+ case "info":
+ window.console.info.apply(window.console, args);
+ break;
+ case "warn":
+ window.console.warn.apply(window.console, args);
+ break;
+ default:
+ window.console.log.apply(window.console, args);
+ }
+ } catch(e) {
+ if( !window.console )
+ _canLog = false; // Permanently disable, when logging is not supported by the browser
+ }
+}
+
+function logMsg(msg) {
+ Array.prototype.unshift.apply(arguments, ["debug"]);
+ _log.apply(this, arguments);
+}
+
+
+// Forward declaration
+var getDynaTreePersistData = undefined;
+
+
+
+/*************************************************************************
+ * Constants
+ */
+var DTNodeStatus_Error = -1;
+var DTNodeStatus_Loading = 1;
+var DTNodeStatus_Ok = 0;
+
+
+// Start of local namespace
+;(function($) {
+
+/*************************************************************************
+ * Common tool functions.
+ */
+
+var Class = {
+ create: function() {
+ return function() {
+ this.initialize.apply(this, arguments);
+ }
+ }
+}
+
+/*************************************************************************
+ * Class DynaTreeNode
+ */
+var DynaTreeNode = Class.create();
+
+DynaTreeNode.prototype = {
+ initialize: function(parent, tree, data) {
+ /**
+ * @constructor
+ */
+ this.parent = parent;
+ this.tree = tree;
+ if ( typeof data == "string" )
+ data = { title: data };
+ if( data.key == undefined )
+ data.key = "_" + tree._nodeCount++;
+ this.data = $.extend({}, $.ui.dynatree.nodedatadefaults, data);
+ this.div = null; // not yet created
+ this.span = null; // not yet created
+ this.childList = null; // no subnodes yet
+// this.isRead = false; // Lazy content not yet read
+ this.isLoading = false; // Lazy content is being loaded
+ this.hasSubSel = false;
+ },
+
+ toString: function() {
+ return "dtnode<" + this.data.key + ">: '" + this.data.title + "'";
+ },
+
+ toDict: function(recursive, callback) {
+ var dict = $.extend({}, this.data);
+ dict.activate = ( this.tree.activeNode === this );
+ dict.focus = ( this.tree.focusNode === this );
+ dict.expand = this.bExpanded;
+ dict.select = this.bSelected;
+ if( callback )
+ callback(dict);
+ if( recursive && this.childList ) {
+ dict.children = [];
+ for(var i=0; i<this.childList.length; i++ )
+ dict.children.push(this.childList[i].toDict(true, callback));
+ } else {
+ delete dict.children;
+ }
+ return dict;
+ },
+
+ _getInnerHtml: function() {
+ var opts = this.tree.options;
+ var cache = this.tree.cache;
+ // parent connectors
+ var rootParent = opts.rootVisible ? null : this.tree.tnRoot;
+ var bHideFirstExpander = (opts.rootVisible && opts.minExpandLevel>0) || opts.minExpandLevel>1;
+ var bHideFirstConnector = opts.rootVisible || opts.minExpandLevel>0;
+
+ var res = "";
+ var p = this.parent;
+ while( p ) {
+ // Suppress first connector column, if visible top level is always expanded
+ if ( bHideFirstConnector && p==rootParent )
+ break;
+ res = ( p.isLastSibling() ? cache.tagEmpty : cache.tagVline) + res;
+ p = p.parent;
+ }
+
+ // connector (expanded, expandable or simple)
+ if( bHideFirstExpander && this.parent==rootParent ) {
+ // skip connector
+ } else if ( this.childList || this.data.isLazy ) {
+ res += cache.tagExpander;
+ } else {
+ res += cache.tagConnector;
+ }
+
+ // Checkbox mode
+ if( opts.checkbox && this.data.hideCheckbox!=true && !this.data.isStatusNode ) {
+ res += cache.tagCheckbox;
+ }
+
+ // folder or doctype icon
+ if ( this.data.icon ) {
+ res += "<img src='" + opts.imagePath + this.data.icon + "' alt='' />";
+ } else if ( this.data.icon == false ) {
+ // icon == false means 'no icon'
+ } else {
+ // icon == null means 'default icon'
+ res += cache.tagNodeIcon;
+ }
+
+ // node name
+ var tooltip = ( this.data && typeof this.data.tooltip == "string" ) ? " title='" + this.data.tooltip + "'" : "";
+ res += "<a href='#' class='" + opts.classNames.title + "'" + tooltip + ">" + this.data.title + "</a>";
+ return res;
+ },
+
+ _fixOrder: function() {
+ /**
+ * Make sure, that <div> order matches childList order.
+ */
+ var cl = this.childList;
+ if( !cl )
+ return;
+ var childDiv = this.div.firstChild.nextSibling;
+ for(var i=0; i<cl.length-1; i++) {
+ var childNode1 = cl[i];
+ var childNode2 = childDiv.firstChild.dtnode;
+ if( childNode1 !== childNode2 ) {
+ this.tree.logDebug("_fixOrder: mismatch at index " + i + ": " + childNode1 + " != " + childNode2);
+ this.div.insertBefore(childNode1.div, childNode2.div);
+ } else {
+ childDiv = childDiv.nextSibling;
+ }
+ }
+ },
+
+ render: function(bDeep, bHidden) {
+ /**
+ * Create HTML markup for this node.
+ *
+ * <div> // This div contains the node's span and list of child div's.
+ * <span id='key'>S S S A</span> // Span contains graphic spans and title <a> tag
+ * <div>child1</div>
+ * <div>child2</div>
+ * </div>
+ */
+// this.tree.logDebug("%o.render()", this);
+ var opts = this.tree.options;
+ var cn = opts.classNames;
+ var isLastSib = this.isLastSibling();
+ // ---
+ if( ! this.div ) {
+ this.span = document.createElement("span");
+ this.span.dtnode = this;
+ if( this.data.key )
+ this.span.id = this.tree.options.idPrefix + this.data.key;
+ this.div = document.createElement("div");
+ this.div.appendChild(this.span);
+
+ if ( this.parent ) {
+ this.parent.div.appendChild(this.div);
+ }
+
+ if( this.parent==null && !this.tree.options.rootVisible )
+ this.span.style.display = "none";
+ }
+ // set node connector images, links and text
+ this.span.innerHTML = this._getInnerHtml();
+
+ // hide this node, if parent is collapsed
+ this.div.style.display = ( this.parent==null || this.parent.bExpanded ? "" : "none");
+
+ // Set classes for current status
+ var cnList = [];
+ cnList.push( ( this.data.isFolder ) ? cn.folder : cn.document );
+ if( this.bExpanded )
+ cnList.push(cn.expanded);
+ if( this.childList != null )
+ cnList.push(cn.hasChildren);
+ if( this.data.isLazy && this.childList==null )
+ cnList.push(cn.lazy);
+ if( isLastSib )
+ cnList.push(cn.lastsib);
+ if( this.bSelected )
+ cnList.push(cn.selected);
+ if( this.hasSubSel )
+ cnList.push(cn.partsel);
+ if( this.tree.activeNode === this )
+ cnList.push(cn.active);
+ if( this.data.addClass )
+ cnList.push(this.data.addClass);
+ // IE6 doesn't correctly evaluate multiple class names,
+ // so we create combined class names that can be used in the CSS
+ cnList.push(cn.combinedExpanderPrefix
+ + (this.bExpanded ? "e" : "c")
+ + (this.data.isLazy && this.childList==null ? "d" : "")
+ + (isLastSib ? "l" : "")
+ );
+ cnList.push(cn.combinedIconPrefix
+ + (this.bExpanded ? "e" : "c")
+ + (this.data.isFolder ? "f" : "")
+ );
+ this.span.className = cnList.join(" ");
+
+ if( bDeep && this.childList && (bHidden || this.bExpanded) ) {
+ for(var i=0; i<this.childList.length; i++) {
+ this.childList[i].render(bDeep, bHidden)
+ }
+ this._fixOrder();
+ }
+ },
+
+ hasChildren: function() {
+ return this.childList != null;
+ },
+
+ isLastSibling: function() {
+ var p = this.parent;
+ if ( !p ) return true;
+ return p.childList[p.childList.length-1] === this;
+ },
+
+ prevSibling: function() {
+ if( !this.parent ) return null;
+ var ac = this.parent.childList;
+ for(var i=1; i<ac.length; i++) // start with 1, so prev(first) = null
+ if( ac[i] === this )
+ return ac[i-1];
+ return null;
+ },
+
+ nextSibling: function() {
+ if( !this.parent ) return null;
+ var ac = this.parent.childList;
+ for(var i=0; i<ac.length-1; i++) // up to length-2, so next(last) = null
+ if( ac[i] === this )
+ return ac[i+1];
+ return null;
+ },
+
+ _setStatusNode: function(data) {
+ // Create, modify or remove the status child node (pass 'null', to remove it).
+ var firstChild = ( this.childList ? this.childList[0] : null );
+ if( !data ) {
+ if ( firstChild ) {
+ this.div.removeChild(firstChild.div);
+ if( this.childList.length == 1 )
+ this.childList = null;
+ else
+ this.childList.shift();
+ }
+ } else if ( firstChild ) {
+ data.isStatusNode = true;
+ firstChild.data = data;
+ firstChild.render(false, false);
+ } else {
+ data.isStatusNode = true;
+ firstChild = this.addChild(data);
+ }
+ },
+
+ setLazyNodeStatus: function(lts, opts) {
+ var tooltip = (opts && opts.tooltip) ? opts.tooltip : null;
+ var info = (opts && opts.info) ? " (" + opts.info + ")" : "";
+ switch( lts ) {
+ case DTNodeStatus_Ok:
+ this._setStatusNode(null);
+// this.isRead = true;
+ this.isLoading = false;
+ this.render(false, false);
+ if( this.tree.options.autoFocus ) {
+ if( this === this.tree.tnRoot && !this.tree.options.rootVisible && this.childList ) {
+ // special case: using ajaxInit
+ this.childList[0].focus();
+ } else {
+ this.focus();
+ }
+ }
+ break;
+ case DTNodeStatus_Loading:
+ this.isLoading = true;
+ this._setStatusNode({
+ title: this.tree.options.strings.loading + info,
+ tooltip: tooltip,
+ addClass: this.tree.options.classNames.nodeWait
+ });
+ break;
+ case DTNodeStatus_Error:
+ this.isLoading = false;
+ this._setStatusNode({
+ title: this.tree.options.strings.loadError + info,
+ tooltip: tooltip,
+ addClass: this.tree.options.classNames.nodeError
+ });
+ break;
+ default:
+ throw "Bad LazyNodeStatus: '" + lts + "'.";
+ }
+ },
+
+ _parentList: function(includeRoot, includeSelf) {
+ var l = [];
+ var dtn = includeSelf ? this : this.parent;
+ while( dtn ) {
+ if( includeRoot || dtn.parent )
+ l.unshift(dtn);
+ dtn = dtn.parent;
+ };
+ return l;
+ },
+
+ getLevel: function() {
+ var level = 0;
+ var dtn = this.parent;
+ while( dtn ) {
+ level++;
+ dtn = dtn.parent;
+ };
+ return level;
+ },
+
+ _getTypeForOuterNodeEvent: function(event) {
+ /** Return the inner node span (title, checkbox or expander) if
+ * event.target points to the outer span.
+ * This function should fix issue #93:
+ * FF2 ignores empty spans, when generating events (returning the parent instead).
+ */
+ var cns = this.tree.options.classNames;
+ var target = event.target;
+ // Only process clicks on an outer node span (probably due to a FF2 event handling bug)
+ if( target.className.indexOf(cns.folder)<0
+ && target.className.indexOf(cns.document)<0 ) {
+ return null
+ }
+ // Event coordinates, relative to outer node span:
+ var eventX = event.pageX - target.offsetLeft;
+ var eventY = event.pageY - target.offsetTop;
+
+ for(var i=0; i<target.childNodes.length; i++) {
+ var cn = target.childNodes[i];
+ var x = cn.offsetLeft - target.offsetLeft;
+ var y = cn.offsetTop - target.offsetTop;
+ var nx = cn.clientWidth, ny = cn.clientHeight;
+// alert (cn.className + ": " + x + ", " + y + ", s:" + nx + ", " + ny);
+ if( eventX>=x && eventX<=(x+nx) && eventY>=y && eventY<=(y+ny) ) {
+// alert("HIT "+ cn.className);
+ if( cn.className==cns.title )
+ return "title";
+ else if( cn.className==cns.expander )
+ return "expander";
+ else if( cn.className==cns.checkbox )
+ return "checkbox";
+ else if( cn.className==cns.nodeIcon )
+ return "icon";
+ }
+ }
+ return "prefix";
+ },
+
+ getEventTargetType: function(event) {
+ // Return the part of a node, that a click event occured on.
+ // Note: there is no check, if the was fired on TIHS node.
+ var tcn = event && event.target ? event.target.className : "";
+ var cns = this.tree.options.classNames;
+
+ if( tcn == cns.title )
+ return "title";
+ else if( tcn==cns.expander )
+ return "expander";
+ else if( tcn==cns.checkbox )
+ return "checkbox";
+ else if( tcn==cns.nodeIcon )
+ return "icon";
+ else if( tcn==cns.empty || tcn==cns.vline || tcn==cns.connector )
+ return "prefix";
+ else if( tcn.indexOf(cns.folder)>=0 || tcn.indexOf(cns.document)>=0 )
+ // FIX issue #93
+ return this._getTypeForOuterNodeEvent(event);
+ return null;
+ },
+
+ isVisible: function() {
+ // Return true, if all parents are expanded.
+ var parents = this._parentList(true, false);
+ for(var i=0; i<parents.length; i++)
+ if( ! parents[i].bExpanded ) return false;
+ return true;
+ },
+
+ makeVisible: function() {
+ // Make sure, all parents are expanded
+ var parents = this._parentList(true, false);
+ for(var i=0; i<parents.length; i++)
+ parents[i]._expand(true);
+ },
+
+ focus: function() {
+ // TODO: check, if we already have focus
+// this.tree.logDebug("dtnode.focus(): %o", this);
+ this.makeVisible();
+ try {
+ $(this.span).find(">a").focus();
+ } catch(e) { }
+ },
+
+ _activate: function(flag, fireEvents) {
+ // (De)Activate - but not focus - this node.
+ this.tree.logDebug("dtnode._activate(%o, fireEvents=%o) - %o", flag, fireEvents, this);
+ var opts = this.tree.options;
+ if( this.data.isStatusNode )
+ return;
+ if ( fireEvents && opts.onQueryActivate && opts.onQueryActivate.call(this.span, flag, this) == false )
+ return; // Callback returned false
+
+ if( flag ) {
+ // Activate
+ if( this.tree.activeNode ) {
+ if( this.tree.activeNode === this )
+ return;
+ this.tree.activeNode.deactivate();
+ }
+ if( opts.activeVisible )
+ this.makeVisible();
+ this.tree.activeNode = this;
+ if( opts.persist )
+ $.cookie(opts.cookieId+"-active", this.data.key, opts.cookie);
+ this.tree.persistence.activeKey = this.data.key;
+ $(this.span).addClass(opts.classNames.active);
+ if ( fireEvents && opts.onActivate ) // Pass element as 'this' (jQuery convention)
+ opts.onActivate.call(this.span, this);
+ } else {
+ // Deactivate
+ if( this.tree.activeNode === this ) {
+ var opts = this.tree.options;
+ if ( opts.onQueryActivate && opts.onQueryActivate.call(this.span, false, this) == false )
+ return; // Callback returned false
+ $(this.span).removeClass(opts.classNames.active);
+ if( opts.persist ) {
+ // Note: we don't pass null, but ''. So the cookie is not deleted.
+ // If we pass null, we also have to pass a COPY of opts, because $cookie will override opts.expires (issue 84)
+ $.cookie(opts.cookieId+"-active", "", opts.cookie);
+ }
+ this.tree.persistence.activeKey = null;
+ this.tree.activeNode = null;
+ if ( fireEvents && opts.onDeactivate )
+ opts.onDeactivate.call(this.span, this);
+ }
+ }
+ },
+
+ activate: function() {
+ // Select - but not focus - this node.
+// this.tree.logDebug("dtnode.activate(): %o", this);
+ this._activate(true, true);
+ },
+
+ deactivate: function() {
+// this.tree.logDebug("dtnode.deactivate(): %o", this);
+ this._activate(false, true);
+ },
+
+ isActive: function() {
+ return (this.tree.activeNode === this);
+ },
+
+ _userActivate: function() {
+ // Handle user click / [space] / [enter], according to clickFolderMode.
+ var activate = true;
+ var expand = false;
+ if ( this.data.isFolder ) {
+ switch( this.tree.options.clickFolderMode ) {
+ case 2:
+ activate = false;
+ expand = true;
+ break;
+ case 3:
+ activate = expand = true;
+ break;
+ }
+ }
+ if( this.parent == null && this.tree.options.minExpandLevel>0 ) {
+ expand = false;
+ }
+ if( expand ) {
+ this.toggleExpand();
+ this.focus();
+ }
+ if( activate ) {
+ this.activate();
+ }
+ },
+
+ _setSubSel: function(hasSubSel) {
+ if( hasSubSel ) {
+ this.hasSubSel = true;
+ $(this.span).addClass(this.tree.options.classNames.partsel);
+ } else {
+ this.hasSubSel = false;
+ $(this.span).removeClass(this.tree.options.classNames.partsel);
+ }
+ },
+
+ _fixSelectionState: function() {
+ // fix selection status, for multi-hier mode
+// this.tree.logDebug("_fixSelectionState(%o) - %o", this.bSelected, this);
+ if( this.bSelected ) {
+ // Select all children
+ this.visit(function(dtnode){
+ dtnode.parent._setSubSel(true);
+ dtnode._select(true, false, false);
+ });
+ // Select parents, if all children are selected
+ var p = this.parent;
+ while( p ) {
+ p._setSubSel(true);
+ var allChildsSelected = true;
+ for(var i=0; i<p.childList.length; i++) {
+ var n = p.childList[i];
+ if( !n.bSelected && !n.data.isStatusNode ) {
+ allChildsSelected = false;
+ break;
+ }
+ }
+ if( allChildsSelected )
+ p._select(true, false, false);
+ p = p.parent;
+ }
+ } else {
+ // Deselect all children
+ this._setSubSel(false);
+ this.visit(function(dtnode){
+ dtnode._setSubSel(false);
+ dtnode._select(false, false, false);
+ });
+ // Deselect parents, and recalc hasSubSel
+ var p = this.parent;
+ while( p ) {
+ p._select(false, false, false);
+ var isPartSel = false;
+ for(var i=0; i<p.childList.length; i++) {
+ if( p.childList[i].bSelected || p.childList[i].hasSubSel ) {
+ isPartSel = true;
+ break;
+ }
+ }
+ p._setSubSel(isPartSel);
+ p = p.parent;
+ }
+ }
+ },
+
+ _select: function(sel, fireEvents, deep) {
+ // Select - but not focus - this node.
+// this.tree.logDebug("dtnode._select(%o) - %o", sel, this);
+ var opts = this.tree.options;
+ if( this.data.isStatusNode )
+ return;
+ //
+ if( this.bSelected == sel ) {
+// this.tree.logDebug("dtnode._select(%o) IGNORED - %o", sel, this);
+ return;
+ }
+ // Allow event listener to abort selection
+ if ( fireEvents && opts.onQuerySelect && opts.onQuerySelect.call(this.span, sel, this) == false )
+ return; // Callback returned false
+
+ // Force single-selection
+ if( opts.selectMode==1 && sel ) {
+ this.tree.visit(function(dtnode){
+ if( dtnode.bSelected ) {
+ // Deselect; assuming that in selectMode:1 there's max. one other selected node
+ dtnode._select(false, false, false);
+ return false;
+ }
+ });
+ }
+
+ this.bSelected = sel;
+// this.tree._changeNodeList("select", this, sel);
+
+ if( sel ) {
+ if( opts.persist )
+ this.tree.persistence.addSelect(this.data.key);
+
+ $(this.span).addClass(opts.classNames.selected);
+
+ if( deep && opts.selectMode==3 )
+ this._fixSelectionState();
+
+ if ( fireEvents && opts.onSelect )
+ opts.onSelect.call(this.span, true, this);
+
+ } else {
+ if( opts.persist )
+ this.tree.persistence.clearSelect(this.data.key);
+
+ $(this.span).removeClass(opts.classNames.selected);
+
+ if( deep && opts.selectMode==3 )
+ this._fixSelectionState();
+
+ if ( fireEvents && opts.onSelect )
+ opts.onSelect.call(this.span, false, this);
+ }
+ },
+
+ select: function(sel) {
+ // Select - but not focus - this node.
+// this.tree.logDebug("dtnode.select(%o) - %o", sel, this);
+ if( this.data.unselectable )
+ return this.bSelected;
+ return this._select(sel!=false, true, true);
+ },
+
+ toggleSelect: function() {
+// this.tree.logDebug("dtnode.toggleSelect() - %o", this);
+ return this.select(!this.bSelected);
+ },
+
+ isSelected: function() {
+ return this.bSelected;
+ },
+
+ _loadContent: function() {
+ try {
+ var opts = this.tree.options;
+ this.tree.logDebug("_loadContent: start - %o", this);
+ this.setLazyNodeStatus(DTNodeStatus_Loading);
+ if( true == opts.onLazyRead.call(this.span, this) ) {
+ // If function returns 'true', we assume that the loading is done:
+ this.setLazyNodeStatus(DTNodeStatus_Ok);
+ // Otherwise (i.e. if the loading was started as an asynchronous process)
+ // the onLazyRead(dtnode) handler is expected to call dtnode.setLazyNodeStatus(DTNodeStatus_Ok/_Error) when done.
+ this.tree.logDebug("_loadContent: succeeded - %o", this);
+ }
+ } catch(e) {
+// alert(e);
+ this.setLazyNodeStatus(DTNodeStatus_Error);
+ this.tree.logWarning("_loadContent: failed - %o", e);
+ }
+ },
+
+ _expand: function(bExpand) {
+// this.tree.logDebug("dtnode._expand(%o) - %o", bExpand, this);
+ if( this.bExpanded == bExpand ) {
+// this.tree.logDebug("dtnode._expand(%o) IGNORED - %o", bExpand, this);
+ return;
+ }
+ var opts = this.tree.options;
+ if( !bExpand && this.getLevel()<opts.minExpandLevel ) {
+ this.tree.logDebug("dtnode._expand(%o) forced expand - %o", bExpand, this);
+ return;
+ }
+ if ( opts.onQueryExpand && opts.onQueryExpand.call(this.span, bExpand, this) == false )
+ return; // Callback returned false
+ this.bExpanded = bExpand;
+
+ // Persist expand state
+ if( opts.persist ) {
+ if( bExpand )
+ this.tree.persistence.addExpand(this.data.key);
+ else
+ this.tree.persistence.clearExpand(this.data.key);
+ }
+
+ this.render(false);
+
+ // Auto-collapse mode: collapse all siblings
+ if( this.bExpanded && this.parent && opts.autoCollapse ) {
+ var parents = this._parentList(false, true);
+ for(var i=0; i<parents.length; i++)
+ parents[i].collapseSiblings();
+ }
+
+ // If the currently active node is now hidden, deactivate it
+ if( opts.activeVisible && this.tree.activeNode && ! this.tree.activeNode.isVisible() ) {
+ this.tree.activeNode.deactivate();
+ }
+ // Expanding a lazy node: set 'loading...' and call callback
+ if( bExpand && this.data.isLazy && this.childList==null && !this.isLoading ) {
+ this._loadContent();
+ return;
+ }
+// this.tree.logDebug("_expand: start div toggle - %o", this);
+
+ var fxDuration = opts.fx ? (opts.fx.duration || 200) : 0;
+ if( this.childList ) {
+ for(var i=0; i<this.childList.length; i++ ) {
+ var $child = $(this.childList[i].div);
+ if( fxDuration ) {
+ // This is a toggle, so only do it, if not already rendered (in)visible (issue 98)
+ if( bExpand != $child.is(':visible') )
+ $child.animate(opts.fx, fxDuration);
+ } else {
+ if( bExpand )
+ $child.show();
+ else
+ $child.hide(); // TODO: this seems to be slow, when called the first time for an element
+ }
+ }
+ }
+
+/* issue 109: using selector filter is really SLOW.
+ // issue 98: only toggle, if render hasn't set visibility already:
+ var filter = ">DIV" + (bExpand ? ":hidden" : ":visible");
+
+ if( opts.fx ) {
+ var duration = opts.fx.duration || 200;
+// $(">DIV", this.div).animate(opts.fx, duration);
+ $(filter, this.div).animate(opts.fx, duration);
+ } else {
+ $(filter, this.div).toggle();
+// var $d = $(">DIV", this.div);
+// this.tree.logDebug("_expand: got div, start toggle - %o", this);
+// $d.toggle();
+ }
+//*/
+// this.tree.logDebug("_expand: end div toggle - %o", this);
+
+ if ( opts.onExpand )
+ opts.onExpand.call(this.span, bExpand, this);
+ },
+
+ expand: function(flag) {
+ if( !this.childList && !this.data.isLazy && flag )
+ return; // Prevent expanding empty nodes
+ if( this.parent == null && this.tree.options.minExpandLevel>0 && !flag )
+ return; // Prevent collapsing the root
+ this._expand(flag);
+ },
+
+ toggleExpand: function() {
+ this.expand(!this.bExpanded);
+ },
+
+ collapseSiblings: function() {
+ if( this.parent == null )
+ return;
+ var ac = this.parent.childList;
+ for (var i=0; i<ac.length; i++) {
+ if ( ac[i] !== this && ac[i].bExpanded )
+ ac[i]._expand(false);
+ }
+ },
+
+ onClick: function(event) {
+// this.tree.logDebug("dtnode.onClick(" + event.type + "): dtnode:" + this + ", button:" + event.button + ", which: " + event.which);
+ var targetType = this.getEventTargetType(event);
+ if( targetType == "expander" ) {
+ // Clicking the expander icon always expands/collapses
+ this.toggleExpand();
+ this.focus(); // issue 95
+ } else if( targetType == "checkbox" ) {
+ // Clicking the checkbox always (de)selects
+ this.toggleSelect();
+ this.focus(); // issue 95
+ } else {
+ this._userActivate();
+ // Chrome and Safari don't focus the a-tag on click
+ this.span.getElementsByTagName("a")[0].focus();
+ }
+ // Make sure that clicks stop, otherwise <a href='#'> jumps to the top
+ return false;
+ },
+
+ onDblClick: function(event) {
+// this.tree.logDebug("dtnode.onDblClick(" + event.type + "): dtnode:" + this + ", button:" + event.button + ", which: " + event.which);
+ },
+
+ onKeydown: function(event) {
+// this.tree.logDebug("dtnode.onKeydown(" + event.type + "): dtnode:" + this + ", charCode:" + event.charCode + ", keyCode: " + event.keyCode + ", which: " + event.which);
+ var handled = true;
+// alert("keyDown" + event.which);
+
+ switch( event.which ) {
+ // charCodes:
+// case 43: // '+'
+ case 107: // '+'
+ case 187: // '+' @ Chrome, Safari
+ if( !this.bExpanded ) this.toggleExpand();
+ break;
+// case 45: // '-'
+ case 109: // '-'
+ case 189: // '+' @ Chrome, Safari
+ if( this.bExpanded ) this.toggleExpand();
+ break;
+ //~ case 42: // '*'
+ //~ break;
+ //~ case 47: // '/'
+ //~ break;
+ // case 13: // <enter>
+ // <enter> on a focused <a> tag seems to generate a click-event.
+ // this._userActivate();
+ // break;
+ case 32: // <space>
+ this._userActivate();
+ break;
+ case 8: // <backspace>
+ if( this.parent )
+ this.parent.focus();
+ break;
+ case 37: // <left>
+ if( this.bExpanded ) {
+ this.toggleExpand();
+ this.focus();
+ } else if( this.parent && (this.tree.options.rootVisible || this.parent.parent) ) {
+ this.parent.focus();
+ }
+ break;
+ case 39: // <right>
+ if( !this.bExpanded && (this.childList || this.data.isLazy) ) {
+ this.toggleExpand();
+ this.focus();
+ } else if( this.childList ) {
+ this.childList[0].focus();
+ }
+ break;
+ case 38: // <up>
+ var sib = this.prevSibling();
+ while( sib && sib.bExpanded && sib.childList )
+ sib = sib.childList[sib.childList.length-1];
+ if( !sib && this.parent && (this.tree.options.rootVisible || this.parent.parent) )
+ sib = this.parent;
+ if( sib ) sib.focus();
+ break;
+ case 40: // <down>
+ var sib;
+ if( this.bExpanded && this.childList ) {
+ sib = this.childList[0];
+ } else {
+ var parents = this._parentList(false, true);
+ for(var i=parents.length-1; i>=0; i--) {
+ sib = parents[i].nextSibling();
+ if( sib ) break;
+ }
+ }
+ if( sib ) sib.focus();
+ break;
+ default:
+ handled = false;
+ }
+ // Return false, if handled, to prevent default processing
+ return !handled;
+ },
+
+ onKeypress: function(event) {
+ // onKeypress is only hooked to allow user callbacks.
+ // We don't process it, because IE and Safari don't fire keypress for cursor keys.
+// this.tree.logDebug("dtnode.onKeypress(" + event.type + "): dtnode:" + this + ", charCode:" + event.charCode + ", keyCode: " + event.keyCode + ", which: " + event.which);
+ },
+
+ onFocus: function(event) {
+ // Handles blur and focus events.
+// this.tree.logDebug("dtnode.onFocus(%o): %o", event, this);
+ var opts = this.tree.options;
+ if ( event.type=="blur" || event.type=="focusout" ) {
+ if ( opts.onBlur ) // Pass element as 'this' (jQuery convention)
+ opts.onBlur.call(this.span, this);
+ if( this.tree.tnFocused )
+ $(this.tree.tnFocused.span).removeClass(opts.classNames.focused);
+ this.tree.tnFocused = null;
+ if( opts.persist )
+ $.cookie(opts.cookieId+"-focus", "", opts.cookie);
+ } else if ( event.type=="focus" || event.type=="focusin") {
+ // Fix: sometimes the blur event is not generated
+ if( this.tree.tnFocused && this.tree.tnFocused !== this ) {
+ this.tree.logDebug("dtnode.onFocus: out of sync: curFocus: %o", this.tree.tnFocused);
+ $(this.tree.tnFocused.span).removeClass(opts.classNames.focused);
+ }
+ this.tree.tnFocused = this;
+ if ( opts.onFocus ) // Pass element as 'this' (jQuery convention)
+ opts.onFocus.call(this.span, this);
+ $(this.tree.tnFocused.span).addClass(opts.classNames.focused);
+ if( opts.persist )
+ $.cookie(opts.cookieId+"-focus", this.data.key, opts.cookie);
+ }
+ // TODO: return anything?
+// return false;
+ },
+
+ visit: function(fn, data, includeSelf) {
+ // Call fn(dtnode, data) for all child nodes. Stop iteration, if fn() returns false.
+ var n = 0;
+ if( includeSelf == true ) {
+ if( fn(this, data) == false )
+ return 1;
+ n++;
+ }
+ if ( this.childList )
+ for (var i=0; i<this.childList.length; i++)
+ n += this.childList[i].visit(fn, data, true);
+ return n;
+ },
+
+ remove: function() {
+ // Remove this node
+// this.tree.logDebug ("%o.remove()", this);
+ if ( this === this.tree.root )
+ return false;
+ return this.parent.removeChild(this);
+ },
+
+ removeChild: function(tn) {
+ // Remove tn from list of direct children.
+ var ac = this.childList;
+ if( ac.length == 1 ) {
+ if( tn !== ac[0] )
+ throw "removeChild: invalid child";
+ return this.removeChildren();
+ }
+ if( tn === this.tree.activeNode )
+ tn.deactivate();
+ if( this.tree.options.persist ) {
+ if( tn.bSelected )
+ this.tree.persistence.clearSelect(tn.data.key);
+ if ( tn.bExpanded )
+ this.tree.persistence.clearExpand(tn.data.key);
+ }
+ tn.removeChildren(true);
+ this.div.removeChild(tn.div);
+ for(var i=0; i<ac.length; i++) {
+ if( ac[i] === tn ) {
+ this.childList.splice(i, 1);
+ delete tn;
+ break;
+ }
+ }
+ },
+
+ removeChildren: function(isRecursiveCall, retainPersistence) {
+ // Remove all child nodes (more efficiently than recursive remove())
+// this.tree.logDebug ("%o.removeChildren(%o)", this, isRecursiveCall);
+ var tree = this.tree;
+ var ac = this.childList;
+ if( ac ) {
+ for(var i=0; i<ac.length; i++) {
+ var tn=ac[i];
+// this.tree.logDebug ("del %o", tn);
+ if ( tn === tree.activeNode && !retainPersistence )
+ tn.deactivate();
+ if( this.tree.options.persist && !retainPersistence ) {
+ if( tn.bSelected )
+ this.tree.persistence.clearSelect(tn.data.key);
+ if ( tn.bExpanded )
+ this.tree.persistence.clearExpand(tn.data.key);
+ }
+ tn.removeChildren(true, retainPersistence);
+ this.div.removeChild(tn.div);
+ delete tn;
+ }
+ this.childList = null;
+ }
+ if( ! isRecursiveCall ) {
+// this._expand(false);
+// this.isRead = false;
+ this.isLoading = false;
+ this.render(false, false);
+ }
+ },
+
+ reload: function(force) {
+ // Discard lazy content (and reload, if node was expanded).
+ if( this.parent == null )
+ return this.tree.reload();
+
+ if( ! this.data.isLazy )
+ throw "node.reload() requires lazy nodes.";
+ if( this.bExpanded ) {
+ this.expand(false);
+ this.removeChildren();
+ this.expand(true);
+ } else {
+ this.removeChildren();
+ if( force )
+ this._loadContent();
+ }
+ },
+
+ _addChildNode: function(dtnode, beforeNode) {
+ /**
+ * Internal function to add one single DynatreeNode as a child.
+ *
+ */
+ var tree = this.tree;
+ var opts = tree.options;
+ var pers = tree.persistence;
+
+// tree.logDebug("%o._addChildNode(%o)", this, dtnode);
+
+ // --- Update and fix dtnode attributes if necessary
+ dtnode.parent = this;
+// if( beforeNode && (beforeNode.parent !== this || beforeNode === dtnode ) )
+// throw "<beforeNode> must be another child of <this>";
+
+ // --- Add dtnode as a child
+ if ( this.childList==null ) {
+ this.childList = [];
+ } else if( ! beforeNode ) {
+ // Fix 'lastsib'
+ $(this.childList[this.childList.length-1].span).removeClass(opts.classNames.lastsib);
+ }
+ if( beforeNode ) {
+ var iBefore = $.inArray(beforeNode, this.childList);
+ if( iBefore < 0 )
+ throw "<beforeNode> must be a child of <this>";
+ this.childList.splice(iBefore, 0, dtnode);
+// alert(this.childList);
+ } else {
+ // Append node
+ this.childList.push(dtnode);
+ }
+
+ // --- Handle persistence
+ // Initial status is read from cookies, if persistence is active and
+ // cookies are already present.
+ // Otherwise the status is read from the data attributes and then persisted.
+ var isInitializing = tree.isInitializing();
+ if( opts.persist && pers.cookiesFound && isInitializing ) {
+ // Init status from cookies
+// tree.logDebug("init from cookie, pa=%o, dk=%o", pers.activeKey, dtnode.data.key);
+ if( pers.activeKey == dtnode.data.key )
+ tree.activeNode = dtnode;
+ if( pers.focusedKey == dtnode.data.key )
+ tree.focusNode = dtnode;
+ dtnode.bExpanded = ($.inArray(dtnode.data.key, pers.expandedKeyList) >= 0);
+ dtnode.bSelected = ($.inArray(dtnode.data.key, pers.selectedKeyList) >= 0);
+// tree.logDebug(" key=%o, bSelected=%o", dtnode.data.key, dtnode.bSelected);
+ } else {
+ // Init status from data (Note: we write the cookies after the init phase)
+// tree.logDebug("init from data");
+ if( dtnode.data.activate ) {
+ tree.activeNode = dtnode;
+ if( opts.persist )
+ pers.activeKey = dtnode.data.key;
+ }
+ if( dtnode.data.focus ) {
+ tree.focusNode = dtnode;
+ if( opts.persist )
+ pers.focusedKey = dtnode.data.key;
+ }
+ dtnode.bExpanded = ( dtnode.data.expand == true ); // Collapsed by default
+ if( dtnode.bExpanded && opts.persist )
+ pers.addExpand(dtnode.data.key);
+ dtnode.bSelected = ( dtnode.data.select == true ); // Deselected by default
+/*
+ Doesn't work, cause pers.selectedKeyList may be null
+ if( dtnode.bSelected && opts.selectMode==1
+ && pers.selectedKeyList && pers.selectedKeyList.length>0 ) {
+ tree.logWarning("Ignored multi-selection in single-mode for %o", dtnode);
+ dtnode.bSelected = false; // Fixing bad input data (multi selection for mode:1)
+ }
+*/
+ if( dtnode.bSelected && opts.persist )
+ pers.addSelect(dtnode.data.key);
+ }
+
+ // Always expand, if it's below minExpandLevel
+// tree.logDebug ("%o._addChildNode(%o), l=%o", this, dtnode, dtnode.getLevel());
+ if ( opts.minExpandLevel >= dtnode.getLevel() ) {
+// tree.logDebug ("Force expand for %o", dtnode);
+ this.bExpanded = true;
+ }
+
+ // In multi-hier mode, update the parents selection state
+ // issue #82: only if not initializing, because the children may not exist yet
+// if( !dtnode.data.isStatusNode && opts.selectMode==3 && !isInitializing )
+// dtnode._fixSelectionState();
+
+ // In multi-hier mode, update the parents selection state
+ if( dtnode.bSelected && opts.selectMode==3 ) {
+ var p = this;
+ while( p ) {
+ if( !p.hasSubSel )
+ p._setSubSel(true);
+ p = p.parent;
+ }
+ }
+ // render this node and the new child
+ if ( tree.bEnableUpdate )
+ this.render(true, true);
+
+ return dtnode;
+ },
+
+ addChild: function(obj, beforeNode) {
+ /**
+ * Add a node object as child.
+ *
+ * This should be the only place, where a DynaTreeNode is constructed!
+ * (Except for the root node creation in the tree constructor)
+ *
+ * @param obj A JS object (may be recursive) or an array of those.
+ * @param {DynaTreeNode} beforeNode (optional) sibling node.
+ *
+ * Data format: array of node objects, with optional 'children' attributes.
+ * [
+ * { title: "t1", isFolder: true, ... }
+ * { title: "t2", isFolder: true, ...,
+ * children: [
+ * {title: "t2.1", ..},
+ * {..}
+ * ]
+ * }
+ * ]
+ * A simple object is also accepted instead of an array.
+ *
+ */
+// this.tree.logDebug("%o.addChild(%o, %o)", this, obj, beforeNode);
+ if( !obj || obj.length==0 ) // Passed null or undefined or empty array
+ return;
+ if( obj instanceof DynaTreeNode )
+ return this._addChildNode(obj, beforeNode);
+ if( !obj.length ) // Passed a single data object
+ obj = [ obj ];
+
+ var prevFlag = this.tree.enableUpdate(false);
+
+ var tnFirst = null;
+ for (var i=0; i<obj.length; i++) {
+ var data = obj[i];
+ var dtnode = this._addChildNode(new DynaTreeNode(this, this.tree, data), beforeNode);
+ if( !tnFirst ) tnFirst = dtnode;
+ // Add child nodes recursively
+ if( data.children )
+ dtnode.addChild(data.children, null);
+ }
+ this.tree.enableUpdate(prevFlag);
+ return tnFirst;
+ },
+
+ append: function(obj) {
+ this.tree.logWarning("node.append() is deprecated (use node.addChild() instead).");
+ return this.addChild(obj, null);
+ },
+
+ appendAjax: function(ajaxOptions) {
+ this.removeChildren(false, true);
+ this.setLazyNodeStatus(DTNodeStatus_Loading);
+ // Ajax option inheritance: $.ajaxSetup < $.ui.dynatree.defaults.ajaxDefaults < tree.options.ajaxDefaults < ajaxOptions
+ var self = this;
+ var orgSuccess = ajaxOptions.success;
+ var orgError = ajaxOptions.error;
+ var options = $.extend({}, this.tree.options.ajaxDefaults, ajaxOptions, {
+/*
+ complete: function(req, textStatus){
+ alert("ajax complete");
+ },
+ timeout: 5000, // 5 sec
+*/
+ success: function(data, textStatus){
+ // <this> is the request options
+// self.tree.logDebug("appendAjax().success");
+ var prevPhase = self.tree.phase;
+ self.tree.phase = "init";
+// self.append(data);
+ self.addChild(data, null);
+ self.tree.phase = "postInit";
+ self.setLazyNodeStatus(DTNodeStatus_Ok);
+ if( orgSuccess )
+ orgSuccess.call(options, self);
+ self.tree.phase = prevPhase;
+ },
+ error: function(XMLHttpRequest, textStatus, errorThrown){
+ // <this> is the request options
+// self.tree.logWarning("appendAjax failed: %o:\n%o\n%o", textStatus, XMLHttpRequest, errorThrown);
+ self.tree.logWarning("appendAjax failed:", textStatus, ":\n", XMLHttpRequest, "\n", errorThrown);
+ self.setLazyNodeStatus(DTNodeStatus_Error, {info: textStatus, tooltip: ""+errorThrown});
+ if( orgError )
+ orgError.call(options, self, XMLHttpRequest, textStatus, errorThrown);
+ }
+ });
+ $.ajax(options);
+ },
+ // --- end of class
+ lastentry: undefined
+}
+
+/*************************************************************************
+ * class DynaTreeStatus
+ */
+
+var DynaTreeStatus = Class.create();
+
+
+DynaTreeStatus._getTreePersistData = function(cookieId, cookieOpts) {
+ // Static member: Return persistence information from cookies
+ var ts = new DynaTreeStatus(cookieId, cookieOpts);
+ ts.read();
+ return ts.toDict();
+}
+// Make available in global scope
+getDynaTreePersistData = DynaTreeStatus._getTreePersistData;
+
+
+DynaTreeStatus.prototype = {
+ // Constructor
+ initialize: function(cookieId, cookieOpts) {
+ this._log("DynaTreeStatus: initialize");
+ if( cookieId === undefined )
+ cookieId = $.ui.dynatree.defaults.cookieId;
+ cookieOpts = $.extend({}, $.ui.dynatree.defaults.cookie, cookieOpts);
+
+ this.cookieId = cookieId;
+ this.cookieOpts = cookieOpts;
+ this.cookiesFound = undefined;
+ this.activeKey = null;
+ this.focusedKey = null;
+ this.expandedKeyList = null;
+ this.selectedKeyList = null;
+ },
+ // member functions
+ _log: function(msg) {
+ // this.logDebug("_changeNodeList(%o): nodeList:%o, idx:%o", mode, nodeList, idx);
+ Array.prototype.unshift.apply(arguments, ["debug"]);
+ _log.apply(this, arguments);
+ },
+ read: function() {
+ this._log("DynaTreeStatus: read");
+ // Read or init cookies.
+ this.cookiesFound = false;
+
+ var cookie = $.cookie(this.cookieId + "-active");
+ this.activeKey = ( cookie == null ) ? "" : cookie;
+ if( cookie != null ) this.cookiesFound = true;
+
+ cookie = $.cookie(this.cookieId + "-focus");
+ this.focusedKey = ( cookie == null ) ? "" : cookie;
+ if( cookie != null ) this.cookiesFound = true;
+
+ cookie = $.cookie(this.cookieId + "-expand");
+ this.expandedKeyList = ( cookie == null ) ? [] : cookie.split(",");
+ if( cookie != null ) this.cookiesFound = true;
+
+ cookie = $.cookie(this.cookieId + "-select");
+ this.selectedKeyList = ( cookie == null ) ? [] : cookie.split(",");
+ if( cookie != null ) this.cookiesFound = true;
+ },
+ write: function() {
+ this._log("DynaTreeStatus: write");
+ $.cookie(this.cookieId + "-active", ( this.activeKey == null ) ? "" : this.activeKey, this.cookieOpts);
+ $.cookie(this.cookieId + "-focus", ( this.focusedKey == null ) ? "" : this.focusedKey, this.cookieOpts);
+ $.cookie(this.cookieId + "-expand", ( this.expandedKeyList == null ) ? "" : this.expandedKeyList.join(","), this.cookieOpts);
+ $.cookie(this.cookieId + "-select", ( this.selectedKeyList == null ) ? "" : this.selectedKeyList.join(","), this.cookieOpts);
+ },
+ addExpand: function(key) {
+ this._log("addExpand(%o)", key);
+ if( $.inArray(key, this.expandedKeyList) < 0 ) {
+ this.expandedKeyList.push(key);
+ $.cookie(this.cookieId + "-expand", this.expandedKeyList.join(","), this.cookieOpts);
+ }
+ },
+ clearExpand: function(key) {
+ this._log("clearExpand(%o)", key);
+ var idx = $.inArray(key, this.expandedKeyList);
+ if( idx >= 0 ) {
+ this.expandedKeyList.splice(idx, 1);
+ $.cookie(this.cookieId + "-expand", this.expandedKeyList.join(","), this.cookieOpts);
+ }
+ },
+ addSelect: function(key) {
+ this._log("addSelect(%o)", key);
+ if( $.inArray(key, this.selectedKeyList) < 0 ) {
+ this.selectedKeyList.push(key);
+ $.cookie(this.cookieId + "-select", this.selectedKeyList.join(","), this.cookieOpts);
+ }
+ },
+ clearSelect: function(key) {
+ this._log("clearSelect(%o)", key);
+ var idx = $.inArray(key, this.selectedKeyList);
+ if( idx >= 0 ) {
+ this.selectedKeyList.splice(idx, 1);
+ $.cookie(this.cookieId + "-select", this.selectedKeyList.join(","), this.cookieOpts);
+ }
+ },
+ isReloading: function() {
+ return this.cookiesFound == true;
+ },
+ toDict: function() {
+ return {
+ cookiesFound: this.cookiesFound,
+ activeKey: this.activeKey,
+ focusedKey: this.activeKey,
+ expandedKeyList: this.expandedKeyList,
+ selectedKeyList: this.selectedKeyList
+ };
+ },
+ // --- end of class
+ lastentry: undefined
+};
+
+
+/*************************************************************************
+ * class DynaTree
+ */
+
+var DynaTree = Class.create();
+
+// --- Static members ----------------------------------------------------------
+
+DynaTree.version = "$Version: 0.5.4$";
+/*
+DynaTree._initTree = function() {
+};
+
+DynaTree._bind = function() {
+};
+*/
+//--- Class members ------------------------------------------------------------
+
+DynaTree.prototype = {
+ // Constructor
+// initialize: function(divContainer, options) {
+ initialize: function($widget) {
+ // instance members
+ this.phase = "init";
+ this.$widget = $widget;
+ this.options = $widget.options;
+ this.$tree = $widget.element;
+ // find container element
+ this.divTree = this.$tree.get(0);
+ },
+
+ // member functions
+
+ _load: function() {
+ var $widget = this.$widget;
+ var opts = this.options;
+ this.bEnableUpdate = true;
+ this._nodeCount = 1;
+ this.activeNode = null;
+ this.focusNode = null;
+
+ // If a 'options.classNames' dictionary was passed, still use defaults
+ // for undefined classes:
+ if( opts.classNames !== $.ui.dynatree.defaults.classNames ) {
+ opts.classNames = $.extend({}, $.ui.dynatree.defaults.classNames, opts.classNames);
+ }
+ // Guess skin path, if not specified
+ if(!opts.imagePath) {
+ $("script").each( function () {
+ // Eclipse syntax parser breaks on this expression, so put it at the bottom:
+ if( this.src.search(_rexDtLibName) >= 0 ) {
+ if( this.src.indexOf("/")>=0 ) // issue #47
+ opts.imagePath = this.src.slice(0, this.src.lastIndexOf("/")) + "/skin/";
+ else
+ opts.imagePath = "skin/";
+// logMsg("Guessing imagePath from '%s': '%s'", this.src, opts.imagePath);
+ return false; // first match
+ }
+ });
+ }
+
+ this.persistence = new DynaTreeStatus(opts.cookieId, opts.cookie);
+ if( opts.persist ) {
+ if( !$.cookie )
+ _log("warn", "Please include jquery.cookie.js to use persistence.");
+ this.persistence.read();
+ }
+ this.logDebug("DynaTree.persistence: %o", this.persistence.toDict());
+
+ // Cached tag strings
+ this.cache = {
+ tagEmpty: "<span class='" + opts.classNames.empty + "'></span>",
+ tagVline: "<span class='" + opts.classNames.vline + "'></span>",
+ tagExpander: "<span class='" + opts.classNames.expander + "'></span>",
+ tagConnector: "<span class='" + opts.classNames.connector + "'></span>",
+ tagNodeIcon: "<span class='" + opts.classNames.nodeIcon + "'></span>",
+ tagCheckbox: "<span class='" + opts.classNames.checkbox + "'></span>",
+ lastentry: undefined
+ };
+
+ // Clear container, in case it contained some 'waiting' or 'error' text
+ // for clients that don't support JS.
+ // We don't do this however, if we try to load from an embedded UL element.
+ if( opts.children || (opts.initAjax && opts.initAjax.url) || opts.initId )
+ $(this.divTree).empty();
+ else if( this.divRoot )
+ $(this.divRoot).remove();
+
+ // create the root element
+ this.tnRoot = new DynaTreeNode(null, this, {title: opts.title, key: "root"});
+ this.tnRoot.data.isFolder = true;
+ this.tnRoot.render(false, false);
+ this.divRoot = this.tnRoot.div;
+ this.divRoot.className = opts.classNames.container;
+ // add root to container
+ // TODO: this should be delayed until all children have been created for performance reasons
+ this.divTree.appendChild(this.divRoot);
+
+ var root = this.tnRoot;
+ var isReloading = ( opts.persist && this.persistence.isReloading() );
+ var isLazy = false;
+ var prevFlag = this.enableUpdate(false);
+
+ this.logDebug("Dynatree._load(): read tree structure...");
+
+ // Init tree structure
+ if( opts.children ) {
+ // Read structure from node array
+ root.addChild(opts.children);
+
+ } else if( opts.initAjax && opts.initAjax.url ) {
+ // Init tree from AJAX request
+ isLazy = true;
+ root.data.isLazy = true;
+ this._reloadAjax();
+
+ } else if( opts.initId ) {
+ // Init tree from another UL element
+ this._createFromTag(root, $("#"+opts.initId));
+
+ } else {
+ // Init tree from the first UL element inside the container <div>
+ var $ul = this.$tree.find(">ul").hide();
+ this._createFromTag(root, $ul);
+ $ul.remove();
+ }
+
+ this._checkConsistency();
+ // Render html markup
+ this.logDebug("Dynatree._load(): render nodes...");
+ this.enableUpdate(prevFlag);
+
+ // bind event handlers
+ this.logDebug("Dynatree._load(): bind events...");
+ this.$widget.bind();
+
+ // --- Post-load processing
+ this.logDebug("Dynatree._load(): postInit...");
+ this.phase = "postInit";
+
+ // In persist mode, make sure that cookies are written, even if they are empty
+ if( opts.persist ) {
+ this.persistence.write();
+ }
+
+ // Set focus, if possible (this will also fire an event and write a cookie)
+ if( this.focusNode && this.focusNode.isVisible() ) {
+ this.logDebug("Focus on init: %o", this.focusNode);
+ this.focusNode.focus();
+ }
+
+ if( !isLazy && opts.onPostInit ) {
+ opts.onPostInit.call(this, isReloading, false);
+ }
+
+ this.phase = "idle";
+ },
+
+ _reloadAjax: function() {
+ // Reload
+ var opts = this.options;
+ if( ! opts.initAjax || ! opts.initAjax.url )
+ throw "tree.reload() requires 'initAjax' mode.";
+ var pers = this.persistence;
+ var ajaxOpts = $.extend({}, opts.initAjax);
+ // Append cookie info to the request
+// this.logDebug("reloadAjax: key=%o, an.key:%o", pers.activeKey, this.activeNode?this.activeNode.data.key:"?");
+ if( ajaxOpts.addActiveKey )
+ ajaxOpts.data.activeKey = pers.activeKey;
+ if( ajaxOpts.addFocusedKey )
+ ajaxOpts.data.focusedKey = pers.focusedKey;
+ if( ajaxOpts.addExpandedKeyList )
+ ajaxOpts.data.expandedKeyList = pers.expandedKeyList.join(",");
+ if( ajaxOpts.addSelectedKeyList )
+ ajaxOpts.data.selectedKeyList = pers.selectedKeyList.join(",");
+
+ // Set up onPostInit callback to be called when Ajax returns
+ if( opts.onPostInit ) {
+ if( ajaxOpts.success )
+ this.logWarning("initAjax: success callback is ignored when onPostInit was specified.");
+ if( ajaxOpts.error )
+ this.logWarning("initAjax: error callback is ignored when onPostInit was specified.");
+ var isReloading = pers.isReloading();
+ ajaxOpts["success"] = function(dtnode) { opts.onPostInit.call(dtnode.tree, isReloading, false); };
+ ajaxOpts["error"] = function(dtnode) { opts.onPostInit.call(dtnode.tree, isReloading, true); };
+ }
+ this.logDebug("Dynatree._init(): send Ajax request...");
+ this.tnRoot.appendAjax(ajaxOpts);
+ },
+
+ toString: function() {
+ return "DynaTree '" + this.options.title + "'";
+ },
+
+ toDict: function() {
+ return this.tnRoot.toDict(true);
+ },
+
+ getPersistData: function() {
+ return this.persistence.toDict();
+ },
+
+ logDebug: function(msg) {
+ if( this.options.debugLevel >= 2 ) {
+ Array.prototype.unshift.apply(arguments, ["debug"]);
+ _log.apply(this, arguments);
+ }
+ },
+
+ logInfo: function(msg) {
+ if( this.options.debugLevel >= 1 ) {
+ Array.prototype.unshift.apply(arguments, ["info"]);
+ _log.apply(this, arguments);
+ }
+ },
+
+ logWarning: function(msg) {
+ Array.prototype.unshift.apply(arguments, ["warn"]);
+ _log.apply(this, arguments);
+ },
+
+ isInitializing: function() {
+ return ( this.phase=="init" || this.phase=="postInit" );
+ },
+ isReloading: function() {
+ return ( this.phase=="init" || this.phase=="postInit" ) && this.options.persist && this.persistence.cookiesFound;
+ },
+ isUserEvent: function() {
+ return ( this.phase=="userEvent" );
+ },
+
+ redraw: function() {
+ this.logDebug("dynatree.redraw()...");
+ this.tnRoot.render(true, true);
+ this.logDebug("dynatree.redraw() done.");
+ },
+
+ reloadAjax: function() {
+ this.logWarning("tree.reloadAjax() is deprecated since v0.5.2 (use reload() instead).");
+ },
+
+ reload: function() {
+ this._load();
+ },
+
+ getRoot: function() {
+ return this.tnRoot;
+ },
+
+ getNodeByKey: function(key) {
+ // $("#...") has problems, if the key contains '.', so we use getElementById()
+// return $("#" + this.options.idPrefix + key).attr("dtnode");
+ var el = document.getElementById(this.options.idPrefix + key);
+ return ( el && el.dtnode ) ? el.dtnode : null;
+ },
+
+ getActiveNode: function() {
+ return this.activeNode;
+ },
+
+ reactivate: function(setFocus) {
+ // Re-fire onQueryActivate and onActivate events.
+ var node = this.activeNode;
+// this.logDebug("reactivate %o", node);
+ if( node ) {
+ this.activeNode = null; // Force re-activating
+ node.activate();
+ if( setFocus )
+ node.focus();
+ }
+ },
+
+ getSelectedNodes: function(stopOnParents) {
+ var nodeList = [];
+ this.tnRoot.visit(function(dtnode){
+ if( dtnode.bSelected ) {
+ nodeList.push(dtnode);
+ if( stopOnParents == true )
+ return false; // stop processing this branch
+ }
+ });
+ return nodeList;
+ },
+
+ activateKey: function(key) {
+ var dtnode = (key === null) ? null : this.getNodeByKey(key);
+ if( !dtnode ) {
+ if( this.activeNode )
+ this.activeNode.deactivate();
+ this.activeNode = null;
+ return null;
+ }
+ dtnode.focus();
+ dtnode.activate();
+ return dtnode;
+ },
+
+ selectKey: function(key, select) {
+ var dtnode = this.getNodeByKey(key);
+ if( !dtnode )
+ return null;
+ dtnode.select(select);
+ return dtnode;
+ },
+
+ enableUpdate: function(bEnable) {
+ if ( this.bEnableUpdate==bEnable )
+ return bEnable;
+ this.bEnableUpdate = bEnable;
+ if ( bEnable )
+ this.redraw();
+ return !bEnable; // return previous value
+ },
+
+ visit: function(fn, data, includeRoot) {
+ return this.tnRoot.visit(fn, data, includeRoot);
+ },
+
+ _createFromTag: function(parentTreeNode, $ulParent) {
+ // Convert a <UL>...</UL> list into children of the parent tree node.
+ var self = this;
+/*
+TODO: better?
+ this.$lis = $("li:has(a[href])", this.element);
+ this.$tabs = this.$lis.map(function() { return $("a", this)[0]; });
+ */
+ $ulParent.find(">li").each(function() {
+ var $li = $(this);
+ var $liSpan = $li.find(">span:first");
+ var title;
+ if( $liSpan.length ) {
+ // If a <li><span> tag is specified, use it literally.
+ title = $liSpan.html();
+ } else {
+ // If only a <li> tag is specified, use the trimmed string up to the next child <ul> tag.
+ title = $li.html();
+ var iPos = title.search(/<ul/i);
+ if( iPos>=0 )
+ title = $.trim(title.substring(0, iPos));
+ else
+ title = $.trim(title);
+// self.logDebug("%o", title);
+ }
+ // Parse node options from ID, title and class attributes
+ var data = {
+ title: title,
+ isFolder: $li.hasClass("folder"),
+ isLazy: $li.hasClass("lazy"),
+ expand: $li.hasClass("expanded"),
+ select: $li.hasClass("selected"),
+ activate: $li.hasClass("active"),
+ focus: $li.hasClass("focused")
+ };
+ if( $li.attr("title") )
+ data.tooltip = $li.attr("title");
+ if( $li.attr("id") )
+ data.key = $li.attr("id");
+ // If a data attribute is present, evaluate as a JavaScript object
+ if( $li.attr("data") ) {
+ var dataAttr = $.trim($li.attr("data"));
+ if( dataAttr ) {
+ if( dataAttr.charAt(0) != "{" )
+ dataAttr = "{" + dataAttr + "}"
+ try {
+ $.extend(data, eval("(" + dataAttr + ")"));
+ } catch(e) {
+ throw ("Error parsing node data: " + e + "\ndata:\n'" + dataAttr + "'");
+ }
+ }
+ }
+ childNode = parentTreeNode.addChild(data);
+ // Recursive reading of child nodes, if LI tag contains an UL tag
+ var $ul = $li.find(">ul:first");
+ if( $ul.length ) {
+ self._createFromTag(childNode, $ul); // must use 'self', because 'this' is the each() context
+ }
+ });
+ },
+
+ _checkConsistency: function() {
+// this.logDebug("tree._checkConsistency() NOT IMPLEMENTED - %o", this);
+ },
+
+ // --- end of class
+ lastentry: undefined
+};
+
+/*************************************************************************
+ * widget $(..).dynatree
+ */
+
+$.widget("ui.dynatree", {
+ init: function() {
+ // ui.core 1.6 renamed init() to _init(): this stub assures backward compatibility
+ _log("warn", "ui.dynatree.init() was called; you should upgrade to ui.core.js v1.6 or higher.");
+ return this._init();
+ },
+
+ _init: function() {
+ if( parseFloat($.ui.version) < 1.8 ) {
+ // jquery.ui.core 1.8 renamed _init() to _create(): this stub assures backward compatibility
+ _log("info", "ui.dynatree._init() was called; consider upgrading to jquery.ui.core.js v1.8 or higher.");
+ return this._create();
+ }
+ // jquery.ui.core 1.8 still uses _init() to perform "default functionality"
+ _log("debug", "ui.dynatree._init() was called; no current default functionality.");
+ },
+
+ _create: function() {
+ if( parseFloat($.ui.version) >= 1.8 ) {
+ this.options = $.extend(true, {}, $[this.namespace][this.widgetName].defaults, this.options);
+ }
+ logMsg("Dynatree._create(): version='%s', debugLevel=%o.", DynaTree.version, this.options.debugLevel);
+ var opts = this.options;
+ // The widget framework supplies this.element and this.options.
+ this.options.event += ".dynatree"; // namespace event
+
+ var divTree = this.element.get(0);
+/* // Clear container, in case it contained some 'waiting' or 'error' text
+ // for clients that don't support JS
+ if( opts.children || (opts.initAjax && opts.initAjax.url) || opts.initId )
+ $(divTree).empty();
+*/
+ // Create the DynaTree object
+ this.tree = new DynaTree(this);
+ this.tree._load();
+ this.tree.logDebug("Dynatree._create(): done.");
+ },
+
+ bind: function() {
+ var $this = this.element;
+ var o = this.options;
+
+ // Prevent duplicate binding
+ this.unbind();
+
+ // Tool function to get dtnode from the event target:
+ function __getNodeFromElement(el) {
+ var iMax = 5;
+ while( el && iMax-- ) {
+ if( el.dtnode ) return el.dtnode;
+ el = el.parentNode;
+ };
+ return null;
+ }
+
+ var eventNames = "click.dynatree dblclick.dynatree";
+ if( o.keyboard ) // Note: leading ' '!
+ eventNames += " keypress.dynatree keydown.dynatree";
+ $this.bind(eventNames, function(event){
+ var dtnode = __getNodeFromElement(event.target);
+ if( !dtnode )
+ return true; // Allow bubbling of other events
+ var prevPhase = dtnode.tree.phase;
+ dtnode.tree.phase = "userEvent";
+ try {
+ dtnode.tree.logDebug("bind(%o): dtnode: %o", event, dtnode);
+
+ switch(event.type) {
+ case "click":
+ return ( o.onClick && o.onClick(dtnode, event)===false ) ? false : dtnode.onClick(event);
+ case "dblclick":
+ return ( o.onDblClick && o.onDblClick(dtnode, event)===false ) ? false : dtnode.onDblClick(event);
+ case "keydown":
+ return ( o.onKeydown && o.onKeydown(dtnode, event)===false ) ? false : dtnode.onKeydown(event);
+ case "keypress":
+ return ( o.onKeypress && o.onKeypress(dtnode, event)===false ) ? false : dtnode.onKeypress(event);
+ };
+ } catch(e) {
+ var _ = null; // issue 117
+// dtnode.tree.logError("bind(%o): dtnode: %o", event, dtnode);
+ } finally {
+ dtnode.tree.phase = prevPhase;
+ }
+ });
+
+ // focus/blur don't bubble, i.e. are not delegated to parent <div> tags,
+ // so we use the addEventListener capturing phase.
+ // See http://www.howtocreate.co.uk/tutorials/javascript/domevents
+ function __focusHandler(event) {
+ // Handles blur and focus.
+ // Fix event for IE:
+ event = arguments[0] = $.event.fix( event || window.event );
+ var dtnode = __getNodeFromElement(event.target);
+ return dtnode ? dtnode.onFocus(event) : false;
+ }
+ var div = this.tree.divTree;
+ if( div.addEventListener ) {
+ div.addEventListener("focus", __focusHandler, true);
+ div.addEventListener("blur", __focusHandler, true);
+ } else {
+ div.onfocusin = div.onfocusout = __focusHandler;
+ }
+ // EVENTS
+ // disable click if event is configured to something else
+// if (!(/^click/).test(o.event))
+// this.$tabs.bind("click.tabs", function() { return false; });
+
+ },
+
+ unbind: function() {
+ this.element.unbind(".dynatree");
+ },
+
+/* TODO: we could handle option changes during runtime here (maybe to re-render, ...)
+ setData: function(key, value) {
+ this.tree.logDebug("dynatree.setData('" + key + "', '" + value + "')");
+ },
+*/
+ enable: function() {
+ this.bind();
+ // Call default disable(): remove -disabled from css:
+ $.widget.prototype.enable.apply(this, arguments);
+ },
+
+ disable: function() {
+ this.unbind();
+ // Call default disable(): add -disabled to css:
+ $.widget.prototype.disable.apply(this, arguments);
+ },
+
+ // --- getter methods (i.e. NOT returning a reference to $)
+ getTree: function() {
+ return this.tree;
+ },
+
+ getRoot: function() {
+ return this.tree.getRoot();
+ },
+
+ getActiveNode: function() {
+ return this.tree.getActiveNode();
+ },
+
+ getSelectedNodes: function() {
+ return this.tree.getSelectedNodes();
+ },
+
+ // ------------------------------------------------------------------------
+ lastentry: undefined
+});
+
+
+// The following methods return a value (thus breaking the jQuery call chain):
+
+$.ui.dynatree.getter = "getTree getRoot getActiveNode getSelectedNodes";
+
+
+// Plugin default options:
+
+$.ui.dynatree.defaults = {
+ title: "Dynatree root", // Name of the root node.
+ rootVisible: false, // Set to true, to make the root node visible.
+ minExpandLevel: 1, // 1: root node is not collapsible
+ imagePath: null, // Path to a folder containing icons. Defaults to 'skin/' subdirectory.
+ children: null, // Init tree structure from this object array.
+ initId: null, // Init tree structure from a <ul> element with this ID.
+ initAjax: null, // Ajax options used to initialize the tree strucuture.
+ autoFocus: true, // Set focus to first child, when expanding or lazy-loading.
+ keyboard: true, // Support keyboard navigation.
+ persist: false, // Persist expand-status to a cookie
+ autoCollapse: false, // Automatically collapse all siblings, when a node is expanded.
+ clickFolderMode: 3, // 1:activate, 2:expand, 3:activate and expand
+ activeVisible: true, // Make sure, active nodes are visible (expanded).
+ checkbox: false, // Show checkboxes.
+ selectMode: 2, // 1:single, 2:multi, 3:multi-hier
+ fx: null, // Animations, e.g. null or { height: "toggle", duration: 200 }
+
+ // Low level event handlers: onEvent(dtnode, event): return false, to stop default processing
+ onClick: null, // null: generate focus, expand, activate, select events.
+ onDblClick: null, // (No default actions.)
+ onKeydown: null, // null: generate keyboard navigation (focus, expand, activate).
+ onKeypress: null, // (No default actions.)
+ onFocus: null, // null: set focus to node.
+ onBlur: null, // null: remove focus from node.
+
+ // Pre-event handlers onQueryEvent(flag, dtnode): return false, to stop processing
+ onQueryActivate: null, // Callback(flag, dtnode) before a node is (de)activated.
+ onQuerySelect: null, // Callback(flag, dtnode) before a node is (de)selected.
+ onQueryExpand: null, // Callback(flag, dtnode) before a node is expanded/collpsed.
+
+ // High level event handlers
+ onPostInit: null, // Callback(isReloading, isError) when tree was (re)loaded.
+ onActivate: null, // Callback(dtnode) when a node is activated.
+ onDeactivate: null, // Callback(dtnode) when a node is deactivated.
+ onSelect: null, // Callback(flag, dtnode) when a node is (de)selected.
+ onExpand: null, // Callback(dtnode) when a node is expanded/collapsed.
+ onLazyRead: null, // Callback(dtnode) when a lazy node is expanded for the first time.
+
+ ajaxDefaults: { // Used by initAjax option
+ cache: false, // false: Append random '_' argument to the request url to prevent caching.
+ dataType: "json" // Expect json format and pass json object to callbacks.
+ },
+ strings: {
+ loading: "Loading…",
+ loadError: "Load error!"
+ },
+ idPrefix: "ui-dynatree-id-", // Used to generate node id's like <span id="ui-dynatree-id-<key>">.
+// cookieId: "ui-dynatree-cookie", // Choose a more unique name, to allow multiple trees.
+ cookieId: "dynatree", // Choose a more unique name, to allow multiple trees.
+ cookie: {
+ expires: null //7, // Days or Date; null: session cookie
+// path: "/", // Defaults to current page
+// domain: "jquery.com",
+// secure: true
+ },
+ // Class names used, when rendering the HTML markup.
+ // Note: if only single entries are passed for options.classNames, all other
+ // values are still set to default.
+ classNames: {
+ container: "ui-dynatree-container",
+ folder: "ui-dynatree-folder",
+ document: "ui-dynatree-document",
+
+ empty: "ui-dynatree-empty",
+ vline: "ui-dynatree-vline",
+ expander: "ui-dynatree-expander",
+ connector: "ui-dynatree-connector",
+ checkbox: "ui-dynatree-checkbox",
+ nodeIcon: "ui-dynatree-icon",
+ title: "ui-dynatree-title",
+
+ nodeError: "ui-dynatree-statusnode-error",
+ nodeWait: "ui-dynatree-statusnode-wait",
+ hidden: "ui-dynatree-hidden",
+ combinedExpanderPrefix: "ui-dynatree-exp-",
+ combinedIconPrefix: "ui-dynatree-ico-",
+// disabled: "ui-dynatree-disabled",
+ hasChildren: "ui-dynatree-has-children",
+ active: "ui-dynatree-active",
+ selected: "ui-dynatree-selected",
+ expanded: "ui-dynatree-expanded",
+ lazy: "ui-dynatree-lazy",
+ focused: "ui-dynatree-focused",
+ partsel: "ui-dynatree-partsel",
+ lastsib: "ui-dynatree-lastsib"
+ },
+ debugLevel: 1,
+
+ // ------------------------------------------------------------------------
+ lastentry: undefined
+};
+
+/**
+ * Reserved data attributes for a tree node.
+ */
+$.ui.dynatree.nodedatadefaults = {
+ title: null, // (required) Displayed name of the node (html is allowed here)
+ key: null, // May be used with activate(), select(), find(), ...
+ isFolder: false, // Use a folder icon. Also the node is expandable but not selectable.
+ isLazy: false, // Call onLazyRead(), when the node is expanded for the first time to allow for delayed creation of children.
+ tooltip: null, // Show this popup text.
+ icon: null, // Use a custom image (filename relative to tree.options.imagePath). 'null' for default icon, 'false' for no icon.
+ addClass: null, // Class name added to the node's span tag.
+ activate: false, // Initial active status.
+ focus: false, // Initial focused status.
+ expand: false, // Initial expanded status.
+ select: false, // Initial selected status.
+ hideCheckbox: false, // Suppress checkbox display for this node.
+ unselectable: false, // Prevent selection.
+// disabled: false,
+ // The following attributes are only valid if passed to some functions:
+ children: null, // Array of child nodes.
+ // NOTE: we can also add custom attributes here.
+ // This may then also be used in the onActivate(), onSelect() or onLazyTree() callbacks.
+ // ------------------------------------------------------------------------
+ lastentry: undefined
+};
+
+// ---------------------------------------------------------------------------
+})(jQuery);
+
+// Eclipse syntax parser breaks on this expression, so we put it at the bottom.
+var _rexDtLibName = /.*dynatree[^/]*\.js$/i;
Binary file static/june_2007_style/blue/dynatree_skin/customFolder1.gif has changed
--- /dev/null
+++ b/static/june_2007_style/blue/dynatree_skin/ui.dynatree.css
@@ -0,0 +1,295 @@
+/*******************************************************************************
+ * Tree container
+ */
+div.ui-dynatree-container
+{
+ font-family: tahoma, arial, helvetica;
+ font-size: 10pt; /* font size should not be too big */
+ white-space: nowrap;
+ padding: 3px;
+
+ background-color: white;
+ border: none;
+}
+
+/* Style, when control is disabled */
+.ui-dynatree-disabled div.ui-dynatree-container
+{
+ opacity: 0.5;
+/* filter: alpha(opacity=50); /* Yields a css warning */
+ background-color: silver;
+}
+
+
+/*******************************************************************************
+ * Vertical line image
+ */
+div.ui-dynatree-container img
+{
+ width: 16px;
+ height: 16px;
+ margin-left: 3px;
+ vertical-align: top;
+ border-style: none;
+}
+
+/*******************************************************************************
+ * Common icon definitions
+ */
+span.ui-dynatree-empty,
+span.ui-dynatree-vline,
+span.ui-dynatree-connector,
+span.ui-dynatree-expander,
+span.ui-dynatree-icon,
+span.ui-dynatree-checkbox,
+span.ui-dynatree-radio
+{
+ width: 16px;
+ height: 16px;
+ display: -moz-inline-box; /* @ FF 1+2 */
+ display: inline-block; /* Required to make a span sizeable */
+ vertical-align: top;
+ background-repeat: no-repeat;
+ background-position: left;
+}
+
+/*******************************************************************************
+ * Lines and connectors
+ */
+span.ui-dynatree-empty
+{
+}
+span.ui-dynatree-vline
+{
+ background-image: url("ltL_ns.gif");
+}
+span.ui-dynatree-connector
+{
+ background-image: url("ltL_nes.gif");
+}
+.ui-dynatree-lastsib span.ui-dynatree-connector
+{
+ background-image: url("ltL_ne.gif");
+}
+
+/*******************************************************************************
+ * Expander icon
+ * Note: IE6 doesn't correctly evaluate multiples class names,
+ * so we create combined class names that can be used in the CSS.
+ *
+ * Prefix: ui-dynatree-exp-
+ * 1st character: 'e': expanded, 'c': collapsed
+ * 2nd character (optional): 'd': lazy (Delayed)
+ * 3rd character (optional): 'l': Last sibling
+ */
+
+span.ui-dynatree-expander
+{
+ background-image: url("ltP_nes.gif");
+ cursor: pointer;
+}
+.ui-dynatree-exp-cl span.ui-dynatree-expander /* Collapsed, not delayed, last sibling */
+{
+ background-image: url("ltP_ne.gif");
+}
+.ui-dynatree-exp-cd span.ui-dynatree-expander /* Collapsed, delayed, not last sibling */
+{
+ background-image: url("ltD_nes.gif");
+}
+.ui-dynatree-exp-cdl span.ui-dynatree-expander /* Collapsed, delayed, last sibling */
+{
+ background-image: url("ltD_ne.gif");
+}
+.ui-dynatree-exp-e span.ui-dynatree-expander, /* Expanded, not delayed, not last sibling */
+.ui-dynatree-exp-ed span.ui-dynatree-expander /* Expanded, delayed, not last sibling */
+{
+ background-image: url("ltM_nes.gif");
+}
+.ui-dynatree-exp-el span.ui-dynatree-expander, /* Expanded, not delayed, last sibling */
+.ui-dynatree-exp-edl span.ui-dynatree-expander /* Expanded, delayed, last sibling */
+{
+ background-image: url("ltM_ne.gif");
+}
+
+
+/*******************************************************************************
+ * Checkbox icon
+ */
+span.ui-dynatree-checkbox
+{
+ margin-left: 3px;
+ background-image: url("cbUnchecked.gif");
+}
+span.ui-dynatree-checkbox:hover
+{
+ background-image: url("cbUnchecked_hover.gif");
+}
+
+.ui-dynatree-partsel span.ui-dynatree-checkbox
+{
+ background-image: url("cbIntermediate.gif");
+}
+.ui-dynatree-partsel span.ui-dynatree-checkbox:hover
+{
+ background-image: url("cbIntermediate_hover.gif");
+}
+
+.ui-dynatree-selected span.ui-dynatree-checkbox
+{
+ background-image: url("cbChecked.gif");
+}
+.ui-dynatree-selected span.ui-dynatree-checkbox:hover
+{
+ background-image: url("cbChecked_hover.gif");
+}
+
+/*******************************************************************************
+ * Radiobutton icon
+ * This is a customization, that may be activated by overriding the 'checkbox'
+ * class name as 'ui-dynatree-radio' in the tree options.
+ */
+span.ui-dynatree-radio
+{
+ margin-left: 3px;
+ background-image: url("rbUnchecked.gif");
+}
+span.ui-dynatree-radio:hover
+{
+ background-image: url("rbUnchecked_hover.gif");
+}
+
+.ui-dynatree-partsel span.ui-dynatree-radio
+{
+ background-image: url("rbIntermediate.gif");
+}
+.ui-dynatree-partsel span.ui-dynatree-radio:hover
+{
+ background-image: url("rbIntermediate_hover.gif");
+}
+
+.ui-dynatree-selected span.ui-dynatree-radio
+{
+ background-image: url("rbChecked.gif");
+}
+.ui-dynatree-selected span.ui-dynatree-radio:hover
+{
+ background-image: url("rbChecked_hover.gif");
+}
+
+/*******************************************************************************
+ * Node type icon
+ * Note: IE6 doesn't correctly evaluate multiples class names,
+ * so we create combined class names that can be used in the CSS.
+ *
+ * Prefix: ui-dynatree-ico-
+ * 1st character: 'e': expanded, 'c': collapsed
+ * 2nd character (optional): 'f': folder
+ */
+
+span.ui-dynatree-icon /* Default icon */
+{
+ margin-left: 3px;
+ background-image: url("ltDoc.gif");
+}
+
+.ui-dynatree-ico-cf span.ui-dynatree-icon /* Collapsed Folder */
+{
+ background-image: url("ltFld.gif");
+}
+
+.ui-dynatree-ico-ef span.ui-dynatree-icon /* Expanded Folder */
+{
+ background-image: url("ltFld_o.gif");
+}
+
+/* Status node icons */
+
+.ui-dynatree-statusnode-wait span.ui-dynatree-icon
+{
+ background-image: url("ltWait.gif");
+}
+
+.ui-dynatree-statusnode-error span.ui-dynatree-icon
+{
+ background-image: url("ltError.gif");
+}
+
+/*******************************************************************************
+ * Node titles
+ */
+
+ /* @Chrome: fix broken hit area of node titles (issue 133) */
+span.ui-dynatree-document,
+span.ui-dynatree-folder
+{
+ display: -moz-inline-box; /* @ FF 1+2 */
+ display: inline-block; /* Required to make a span sizeable */
+}
+
+/* Remove blue color and underline from title links */
+div.ui-dynatree-container a
+/*, div.ui-dynatree-container a:visited*/
+{
+ color: black; /* inherit doesn't work on IE */
+ text-decoration: none;
+ vertical-align: top;
+ margin: 0px;
+ margin-left: 3px;
+/* outline: 0; /* @ Firefox, prevent dotted border after click */
+}
+
+div.ui-dynatree-container a:hover
+{
+ text-decoration: underline;
+}
+
+span.ui-dynatree-document a,
+span.ui-dynatree-folder a
+{
+ display: inline-block; /* Better alignment, when title contains <br> */
+/* vertical-align: top;*/
+ padding-left: 3px;
+ padding-right: 3px; /* Otherwise italic font will be outside bounds */
+ /* line-height: 16px; /* should be the same as img height, in case 16 px */
+}
+span.ui-dynatree-folder a
+{
+ font-weight: normal;
+}
+
+div.ui-dynatree-container a:focus,
+span.ui-dynatree-focused a:link /* @IE */
+{
+ background-color: #EFEBDE; /* gray */
+}
+
+
+span.ui-dynatree-has-children a
+{
+}
+
+span.ui-dynatree-expanded a
+{
+}
+
+span.ui-dynatree-selected a
+{
+ color: black;
+ font-style: italic;
+}
+
+span.ui-dynatree-active a
+{
+ background-color: #3169C6 !important;
+ color: white !important; /* @ IE6 */
+}
+
+/*******************************************************************************
+ * Custom node classes (sample)
+ */
+
+span.custom1 a
+{
+ background-color: maroon;
+ color: yellow;
+}
--- /dev/null
+++ b/static/scripts/packed/jquery.cookie.js
@@ -0,0 +1,1 @@
+jQuery.cookie=function(b,j,m){if(typeof j!="undefined"){m=m||{};if(j===null){j="";m=$.extend({},m);m.expires=-1}var e="";if(m.expires&&(typeof m.expires=="number"||m.expires.toUTCString)){var f;if(typeof m.expires=="number"){f=new Date();f.setTime(f.getTime()+(m.expires*24*60*60*1000))}else{f=m.expires}e="; expires="+f.toUTCString()}var l=m.path?"; path="+(m.path):"";var g=m.domain?"; domain="+(m.domain):"";var a=m.secure?"; secure":"";document.cookie=[b,"=",encodeURIComponent(j),e,l,g,a].join("")}else{var d=null;if(document.cookie&&document.cookie!=""){var k=document.cookie.split(";");for(var h=0;h<k.length;h++){var c=jQuery.trim(k[h]);if(c.substring(0,b.length+1)==(b+"=")){d=decodeURIComponent(c.substring(b.length+1));break}}}return d}};
Binary file static/june_2007_style/blue/dynatree_skin/ltL_nes.gif has changed
Binary file static/june_2007_style/blue/dynatree_skin/ltL_ns.gif has changed
Binary file static/june_2007_style/blue/dynatree_skin/ltL_ne.gif has changed
Binary file static/june_2007_style/blue/dynatree_skin/ltD_ne.gif has changed
Binary file static/june_2007_style/blue/dynatree_skin/rbIntermediate_hover.gif has changed
Binary file static/june_2007_style/blue/dynatree_skin/cbUnchecked.gif has changed
Binary file static/june_2007_style/blue/dynatree_skin/cbUnchecked_hover.gif has changed
Binary file static/june_2007_style/blue/dynatree_skin/ltL_.gif has changed
Binary file static/june_2007_style/blue/dynatree_skin/rbChecked_hover.gif has changed
1
0