galaxy-commits
Threads by month
- ----- 2025 -----
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- 15302 discussions

commit/galaxy-central: greg: Fix for managing sample datasets in the sample tracking admin UI.
by Bitbucket 29 Mar '12
by Bitbucket 29 Mar '12
29 Mar '12
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/changeset/9f5750e19c1e/
changeset: 9f5750e19c1e
user: greg
date: 2012-03-29 15:17:34
summary: Fix for managing sample datasets in the sample tracking admin UI.
affected #: 1 file
diff -r 04ed074ef9d21888bfd68235707b5ec0b9a70a10 -r 9f5750e19c1ea88fa0c694bb42642589659b0750 lib/galaxy/web/controllers/requests_admin.py
--- a/lib/galaxy/web/controllers/requests_admin.py
+++ b/lib/galaxy/web/controllers/requests_admin.py
@@ -199,6 +199,11 @@
params = util.Params( kwd )
message = util.restore_text( params.get( 'message', '' ) )
status = params.get( 'status', 'done' )
+ sample_id = params.get( 'sample_id', None )
+ try:
+ sample = trans.sa_session.query( trans.model.Sample ).get( trans.security.decode_id ( sample_id ) )
+ except:
+ return invalid_id_redirect( trans, 'requests_admin', sample_id, 'sample' )
if 'operation' in kwd:
operation = kwd[ 'operation' ].lower()
sample_dataset_id = params.get( 'id', None )
@@ -269,11 +274,6 @@
**kwd ) )
# Render the grid view
- sample_id = params.get( 'sample_id', None )
- try:
- sample = trans.sa_session.query( trans.model.Sample ).get( trans.security.decode_id ( sample_id ) )
- except:
- return invalid_id_redirect( trans, 'requests_admin', sample_id, 'sample' )
request_id = trans.security.encode_id( sample.request.id )
library_id = trans.security.encode_id( sample.library.id )
self.datatx_grid.title = 'Manage "%s" datasets' % sample.name
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0

commit/galaxy-central: dan: Make ldda.templates_json able to set use_name flag in call to templates_dict.
by Bitbucket 28 Mar '12
by Bitbucket 28 Mar '12
28 Mar '12
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/changeset/04ed074ef9d2/
changeset: 04ed074ef9d2
user: dan
date: 2012-03-28 18:05:00
summary: Make ldda.templates_json able to set use_name flag in call to templates_dict.
affected #: 1 file
diff -r 0c6cf4f53c4efad46fe7716587ca5a2dddff049c -r 04ed074ef9d21888bfd68235707b5ec0b9a70a10 lib/galaxy/model/__init__.py
--- a/lib/galaxy/model/__init__.py
+++ b/lib/galaxy/model/__init__.py
@@ -1554,8 +1554,8 @@
tmp_dict[ name ] = content[ field[ 'name' ] ]
template_data[template.name] = tmp_dict
return template_data
- def templates_json( self ):
- return simplejson.dumps( self.templates_dict() )
+ def templates_json( self, use_name=False ):
+ return simplejson.dumps( self.templates_dict( use_name=use_name ) )
def get_display_name( self ):
"""
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0

commit/galaxy-central: dan: Add use_name flag to ldda.templates_dict() that will return a dictionary using the form field names instead of labels.
by Bitbucket 28 Mar '12
by Bitbucket 28 Mar '12
28 Mar '12
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/changeset/0c6cf4f53c4e/
changeset: 0c6cf4f53c4e
user: dan
date: 2012-03-28 18:01:44
summary: Add use_name flag to ldda.templates_dict() that will return a dictionary using the form field names instead of labels.
affected #: 1 file
diff -r 15bd01c59c24eae40026470459c5577cba063768 -r 0c6cf4f53c4efad46fe7716587ca5a2dddff049c lib/galaxy/model/__init__.py
--- a/lib/galaxy/model/__init__.py
+++ b/lib/galaxy/model/__init__.py
@@ -1536,17 +1536,22 @@
else:
return template.get_widgets( trans.user )
return []
- def templates_dict( self ):
+ def templates_dict( self, use_name=False ):
"""
Returns a dict of template info
"""
+ #TODO: Should have a method that allows names and labels to be returned together in a structured way
template_data = {}
for temp_info in self.info_association:
template = temp_info.template
content = temp_info.info.content
tmp_dict = {}
for field in template.fields:
- tmp_dict[field['label']] = content[field['name']]
+ if use_name:
+ name = field[ 'name' ]
+ else:
+ name = field[ 'label' ]
+ tmp_dict[ name ] = content[ field[ 'name' ] ]
template_data[template.name] = tmp_dict
return template_data
def templates_json( self ):
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
2 new commits in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/changeset/cc2605facf6b/
changeset: cc2605facf6b
user: jgoecks
date: 2012-03-28 16:58:38
summary: Enable set_metadata tool to take job parameters and use parameters for set_metadata jobs within Trackster.
affected #: 2 files
diff -r a01497f68018ccc78b2a987b8514bae0e8cf70f1 -r cc2605facf6be23d0a84f81904650042374d398c lib/galaxy/tools/actions/metadata.py
--- a/lib/galaxy/tools/actions/metadata.py
+++ b/lib/galaxy/tools/actions/metadata.py
@@ -1,6 +1,7 @@
from __init__ import ToolAction
from galaxy.datatypes.metadata import JobExternalOutputMetadataWrapper
from galaxy.util.odict import odict
+from galaxy.util.json import to_json_string
import logging
log = logging.getLogger( __name__ )
@@ -8,7 +9,7 @@
class SetMetadataToolAction( ToolAction ):
"""Tool action used for setting external metadata on an existing dataset"""
- def execute( self, tool, trans, incoming = {}, set_output_hid = False, overwrite = True, history=None ):
+ def execute( self, tool, trans, incoming = {}, set_output_hid = False, overwrite = True, history=None, job_params=None ):
for name, value in incoming.iteritems():
if isinstance( value, trans.app.model.HistoryDatasetAssociation ):
dataset = value
@@ -30,6 +31,8 @@
job.tool_id = tool.id
if trans.user:
job.user_id = trans.user.id
+ if job_params:
+ job.params = to_json_string( job_params )
start_job_state = job.state #should be job.states.NEW
try:
# For backward compatibility, some tools may not have versions yet.
diff -r a01497f68018ccc78b2a987b8514bae0e8cf70f1 -r cc2605facf6be23d0a84f81904650042374d398c lib/galaxy/web/controllers/tracks.py
--- a/lib/galaxy/web/controllers/tracks.py
+++ b/lib/galaxy/web/controllers/tracks.py
@@ -974,12 +974,15 @@
new_dataset.set_dataset_state( trans.app.model.Dataset.states.OK )
# Set metadata.
+ # TODO: set meta internally if dataset is small enough?
if trans.app.config.set_metadata_externally:
- trans.app.datatypes_registry.set_external_metadata_tool.tool_action.execute( trans.app.datatypes_registry.set_external_metadata_tool, trans, incoming = { 'input1':new_dataset }, overwrite=False )
+ trans.app.datatypes_registry.set_external_metadata_tool.tool_action.execute( trans.app.datatypes_registry.set_external_metadata_tool,
+ trans, incoming = { 'input1':new_dataset },
+ overwrite=False, job_params={ "source" : "trackster" } )
else:
message = 'Attributes updated'
new_dataset.set_meta()
- new_dataset.datatype.after_setting_metadata( new_dataset )
+ new_dataset.datatype.after_setting_metadata( new_dataset )
trans.sa_session.flush()
https://bitbucket.org/galaxy/galaxy-central/changeset/15bd01c59c24/
changeset: 15bd01c59c24
user: jgoecks
date: 2012-03-28 16:59:03
summary: Merge
affected #: 1 file
diff -r cc2605facf6be23d0a84f81904650042374d398c -r 15bd01c59c24eae40026470459c5577cba063768 contrib/universe_merger.py
--- /dev/null
+++ b/contrib/universe_merger.py
@@ -0,0 +1,87 @@
+#! /usr/bin/env python
+'''
+universe_merger.py
+
+Created by Anne Pajon on 31 Jan 2012
+
+Copyright (c) 2012 Cancer Research UK - Cambridge Research Institute.
+
+This source file is licensed under the Academic Free License version
+3.0 available at http://www.opensource.org/licenses/AFL-3.0.
+
+Permission is hereby granted to reproduce, translate, adapt, alter,
+transform, modify, or arrange this source file (the "Original Work");
+to distribute or communicate copies of it under any license of your
+choice that does not contradict the terms and conditions; to perform
+or display the Original Work publicly.
+
+THE ORIGINAL WORK IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS
+AND WITHOUT WARRANTY, EITHER EXPRESS OR IMPLIED, INCLUDING, WITHOUT
+LIMITATION, THE WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY OR
+FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY OF
+THE ORIGINAL WORK IS WITH YOU.
+
+Script for merging specific local Galaxy config universe_wsgi.ini.cri with default Galaxy universe_wsgi.ini.sample
+'''
+import ConfigParser
+import sys
+import optparse
+import logging
+
+def main():
+ # logging configuration
+ logging.basicConfig(format='%(levelname)s: %(message)s', level=logging.INFO)
+
+ # get the options
+ parser = optparse.OptionParser()
+ parser.add_option("-s", "--sample", dest="sample", action="store", help="path to Galaxy universe_wsgi.ini.sample file")
+ parser.add_option("-c", "--config", dest="config", action="store", help="path to your own universe_wsgi.ini file")
+ parser.add_option("-o", "--output", dest="output", action="store", help="path to the new merged universe_wsgi.ini.new file")
+ (options, args) = parser.parse_args()
+
+ for option in ['sample', 'config']:
+ if getattr(options, option) == None:
+ print "Please supply a --%s parameter.\n" % (option)
+ parser.print_help()
+ sys.exit()
+
+ config_sample = ConfigParser.RawConfigParser()
+ config_sample.read(options.sample)
+ config_sample_content = open(options.sample, 'r').read()
+
+ config = ConfigParser.RawConfigParser()
+ config.read(options.config)
+
+ logging.info("Merging your own config file %s into the sample one %s." % (options.config, options.sample))
+ logging.info("---------- DIFFERENCE ANALYSIS BEGIN ----------")
+ for section in config.sections():
+ if not config_sample.has_section(section):
+ logging.warning("-MISSING- section [%s] not found in sample file. It will be ignored." % section)
+ else:
+ for (name, value) in config.items(section):
+ if not config_sample.has_option(section, name):
+ if not "#%s" % name in config_sample_content:
+ logging.warning("-MISSING- section [%s] option '%s' not found in sample file. It will be ignored." % (section, name))
+ else:
+ logging.info("-notset- section [%s] option '%s' not set in sample file. It will be added." % (section, name))
+ config_sample.set(section, name, value)
+ else:
+ if not config_sample.get(section, name) == value:
+ logging.info("- diff - section [%s] option '%s' has different value ('%s':'%s'). It will be modified." % (section, name, config_sample.get(section, name), value))
+ config_sample.set(section, name, value)
+ logging.info("---------- DIFFERENCE ANALYSIS END ----------")
+
+ if options.output:
+ outputfile = open(options.output, 'w')
+ config_sample.write(outputfile)
+ outputfile.close()
+ else:
+ #print "----------"
+ #config_sample.write(sys.stdout)
+ #print "----------"
+ logging.info("use -o OUTPUT to write the merged configuration into a file.")
+
+ logging.info("read Galaxy universe_wsgi.ini.sample for detailed information.")
+
+if __name__ == '__main__':
+ main()
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0

commit/galaxy-central: greg: Add script for merging specific local Galaxy config universe_wsgi.ini.cri with default Galaxy universe_wsgi.ini.sample contributed by Anne Pajon.
by Bitbucket 28 Mar '12
by Bitbucket 28 Mar '12
28 Mar '12
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/changeset/4b6cc14f1bb9/
changeset: 4b6cc14f1bb9
user: greg
date: 2012-03-28 16:58:19
summary: Add script for merging specific local Galaxy config universe_wsgi.ini.cri with default Galaxy universe_wsgi.ini.sample contributed by Anne Pajon.
affected #: 1 file
diff -r a01497f68018ccc78b2a987b8514bae0e8cf70f1 -r 4b6cc14f1bb9bffda9859f2857909d8708b5d86f contrib/universe_merger.py
--- /dev/null
+++ b/contrib/universe_merger.py
@@ -0,0 +1,87 @@
+#! /usr/bin/env python
+'''
+universe_merger.py
+
+Created by Anne Pajon on 31 Jan 2012
+
+Copyright (c) 2012 Cancer Research UK - Cambridge Research Institute.
+
+This source file is licensed under the Academic Free License version
+3.0 available at http://www.opensource.org/licenses/AFL-3.0.
+
+Permission is hereby granted to reproduce, translate, adapt, alter,
+transform, modify, or arrange this source file (the "Original Work");
+to distribute or communicate copies of it under any license of your
+choice that does not contradict the terms and conditions; to perform
+or display the Original Work publicly.
+
+THE ORIGINAL WORK IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS
+AND WITHOUT WARRANTY, EITHER EXPRESS OR IMPLIED, INCLUDING, WITHOUT
+LIMITATION, THE WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY OR
+FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY OF
+THE ORIGINAL WORK IS WITH YOU.
+
+Script for merging specific local Galaxy config universe_wsgi.ini.cri with default Galaxy universe_wsgi.ini.sample
+'''
+import ConfigParser
+import sys
+import optparse
+import logging
+
+def main():
+ # logging configuration
+ logging.basicConfig(format='%(levelname)s: %(message)s', level=logging.INFO)
+
+ # get the options
+ parser = optparse.OptionParser()
+ parser.add_option("-s", "--sample", dest="sample", action="store", help="path to Galaxy universe_wsgi.ini.sample file")
+ parser.add_option("-c", "--config", dest="config", action="store", help="path to your own universe_wsgi.ini file")
+ parser.add_option("-o", "--output", dest="output", action="store", help="path to the new merged universe_wsgi.ini.new file")
+ (options, args) = parser.parse_args()
+
+ for option in ['sample', 'config']:
+ if getattr(options, option) == None:
+ print "Please supply a --%s parameter.\n" % (option)
+ parser.print_help()
+ sys.exit()
+
+ config_sample = ConfigParser.RawConfigParser()
+ config_sample.read(options.sample)
+ config_sample_content = open(options.sample, 'r').read()
+
+ config = ConfigParser.RawConfigParser()
+ config.read(options.config)
+
+ logging.info("Merging your own config file %s into the sample one %s." % (options.config, options.sample))
+ logging.info("---------- DIFFERENCE ANALYSIS BEGIN ----------")
+ for section in config.sections():
+ if not config_sample.has_section(section):
+ logging.warning("-MISSING- section [%s] not found in sample file. It will be ignored." % section)
+ else:
+ for (name, value) in config.items(section):
+ if not config_sample.has_option(section, name):
+ if not "#%s" % name in config_sample_content:
+ logging.warning("-MISSING- section [%s] option '%s' not found in sample file. It will be ignored." % (section, name))
+ else:
+ logging.info("-notset- section [%s] option '%s' not set in sample file. It will be added." % (section, name))
+ config_sample.set(section, name, value)
+ else:
+ if not config_sample.get(section, name) == value:
+ logging.info("- diff - section [%s] option '%s' has different value ('%s':'%s'). It will be modified." % (section, name, config_sample.get(section, name), value))
+ config_sample.set(section, name, value)
+ logging.info("---------- DIFFERENCE ANALYSIS END ----------")
+
+ if options.output:
+ outputfile = open(options.output, 'w')
+ config_sample.write(outputfile)
+ outputfile.close()
+ else:
+ #print "----------"
+ #config_sample.write(sys.stdout)
+ #print "----------"
+ logging.info("use -o OUTPUT to write the merged configuration into a file.")
+
+ logging.info("read Galaxy universe_wsgi.ini.sample for detailed information.")
+
+if __name__ == '__main__':
+ main()
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0

commit/galaxy-central: natefoo: Have the cloud controller explicitly require boto.
by Bitbucket 28 Mar '12
by Bitbucket 28 Mar '12
28 Mar '12
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/changeset/a01497f68018/
changeset: a01497f68018
user: natefoo
date: 2012-03-28 16:02:55
summary: Have the cloud controller explicitly require boto.
affected #: 1 file
diff -r 377dd3efe3beb7f8d8ef06306fcadac0aafd6365 -r a01497f68018ccc78b2a987b8514bae0e8cf70f1 lib/galaxy/web/controllers/cloud.py
--- a/lib/galaxy/web/controllers/cloud.py
+++ b/lib/galaxy/web/controllers/cloud.py
@@ -6,10 +6,13 @@
"""
-import boto
import datetime
import logging
import time
+from galaxy import eggs
+import pkg_resources
+pkg_resources.require('boto')
+import boto
from galaxy import web
from galaxy.web.base.controller import BaseUIController
from boto.ec2.regioninfo import RegionInfo
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/changeset/377dd3efe3be/
changeset: 377dd3efe3be
user: dan
date: 2012-03-28 00:09:55
summary: Add FreeBayes to tool_conf.xml.main.
affected #: 3 files
diff -r 0282e24997db8e5b5a41a82b6e1904650af42934 -r 377dd3efe3beb7f8d8ef06306fcadac0aafd6365 tool_conf.xml.main
--- a/tool_conf.xml.main
+++ b/tool_conf.xml.main
@@ -208,6 +208,7 @@
<tool file="phenotype_association/lps.xml" /><tool file="phenotype_association/hilbertvis.xml" /><tool file="phenotype_association/freebayes.xml" />
+ <tool file="variant_detection/freebayes.xml" /><tool file="phenotype_association/master2pg.xml" /><tool file="phenotype_association/vcf2pgSnp.xml" /><tool file="phenotype_association/dividePgSnpAlleles.xml" />
@@ -326,6 +327,9 @@
<tool file="indels/indel_sam2interval.xml" /><tool file="indels/indel_analysis.xml" /></section>
+ <section name="NGS: Variant Detection" id="variant_detection">
+ <tool file="variant_detection/freebayes.xml" />
+ </section><section name="NGS: Peak Calling" id="peak_calling"><tool file="peak_calling/macs_wrapper.xml" /><tool file="peak_calling/sicer_wrapper.xml" />
diff -r 0282e24997db8e5b5a41a82b6e1904650af42934 -r 377dd3efe3beb7f8d8ef06306fcadac0aafd6365 tool_conf.xml.sample
--- a/tool_conf.xml.sample
+++ b/tool_conf.xml.sample
@@ -477,6 +477,7 @@
<tool file="phenotype_association/lps.xml" /><tool file="phenotype_association/hilbertvis.xml" /><tool file="phenotype_association/freebayes.xml" />
+ <tool file="variant_detection/freebayes.xml" /><tool file="phenotype_association/master2pg.xml" /><tool file="phenotype_association/vcf2pgSnp.xml" /><tool file="phenotype_association/dividePgSnpAlleles.xml" />
diff -r 0282e24997db8e5b5a41a82b6e1904650af42934 -r 377dd3efe3beb7f8d8ef06306fcadac0aafd6365 tools/phenotype_association/freebayes.xml
--- a/tools/phenotype_association/freebayes.xml
+++ b/tools/phenotype_association/freebayes.xml
@@ -1,5 +1,5 @@
<?xml version="1.0"?>
-<tool id="freebayes_wrapper" name="Call SNPS with Freebayes" version="0.5.0">
+<tool id="freebayes_wrapper" name="Call SNPS with Freebayes" version="0.5.0" hidden="True"><requirements><requirement type="package">freebayes</requirement></requirements>
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/changeset/0282e24997db/
changeset: 0282e24997db
user: dan
date: 2012-03-27 23:54:12
summary: Add FreeBayes to tool_conf.xml.main
affected #: 1 file
diff -r 8d1b7e28fd6027d7ef3c69d17592d6d49cdbcc57 -r 0282e24997db8e5b5a41a82b6e1904650af42934 tool_conf.xml.main
--- a/tool_conf.xml.main
+++ b/tool_conf.xml.main
@@ -318,6 +318,9 @@
<tool file="gatk/variant_eval.xml" /><tool file="gatk/variant_combine.xml" /></section>
+ <section name="NGS: Variant Detection" id="variant_detection">
+ <tool file="variant_detection/freebayes.xml" />
+ </section><section name="NGS: Indel Analysis" id="indel_analysis"><tool file="indels/sam_indel_filter.xml" /><tool file="indels/indel_sam2interval.xml" />
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0

27 Mar '12
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/changeset/8d1b7e28fd60/
changeset: 8d1b7e28fd60
user: jgoecks
date: 2012-03-27 19:03:21
summary: Basics for API access to tools: (a) enable tools, tool panel labels, and tool panel sections to be dictified; and (b) add RESTful UI controller tools. Once session-based authentication is enabled in API, controller will be moved to API.
affected #: 2 files
diff -r f6010ee7c7f8d5a021cba09bbfef937c28265c82 -r 8d1b7e28fd6027d7ef3c69d17592d6d49cdbcc57 lib/galaxy/tools/__init__.py
--- a/lib/galaxy/tools/__init__.py
+++ b/lib/galaxy/tools/__init__.py
@@ -485,6 +485,13 @@
self.id = elem.get( "id" )
self.version = elem.get( "version" ) or ''
self.elems = odict()
+
+ def to_dict( self ):
+ """ Return a dict that includes section's attributes. """
+ section_elts = []
+ for key, val in self.elems.items():
+ section_elts.append( val.to_dict() )
+ return { 'type': 'section', 'id': self.id, 'name': self.name, 'version': self.version, 'elems': section_elts }
class ToolSectionLabel( object ):
"""
@@ -495,6 +502,10 @@
self.text = elem.get( "text" )
self.id = elem.get( "id" )
self.version = elem.get( "version" ) or ''
+
+ def to_dict( self ):
+ """ Return a dict that includes label's attributes. """
+ return { 'type': 'label', 'id': self.id, 'name': self.text, 'version': self.version }
class DefaultToolState( object ):
"""
@@ -2238,6 +2249,11 @@
self.sa_session.add( new_data )
self.sa_session.flush()
return primary_datasets
+
+ def to_dict( self, **kwds ):
+ """ Return dict that includes tool's attributes. """
+ return { 'type': 'tool', 'id': self.id, 'name': self.name,
+ 'version': self.version, 'description': self.description }
class DataSourceTool( Tool ):
"""
diff -r f6010ee7c7f8d5a021cba09bbfef937c28265c82 -r 8d1b7e28fd6027d7ef3c69d17592d6d49cdbcc57 lib/galaxy/web/controllers/tools.py
--- /dev/null
+++ b/lib/galaxy/web/controllers/tools.py
@@ -0,0 +1,32 @@
+from galaxy import config, tools, web, util
+from galaxy.web.base.controller import BaseController, BaseUIController
+
+class ToolsController( BaseUIController ):
+ """
+ RESTful controller for interactions with tools. Once session-based
+ authentication can be done with API controllers, this will be moved
+ to be part of the API.
+ """
+
+ @web.json
+ def index( self, trans, **kwds ):
+ """
+ GET /api/tools: returns a list of tools defined by parameters
+ parameters:
+ in_panel - if true, tools are returned in panel structure, including sections and labels
+ """
+ in_panel = util.string_as_bool( kwds.get( 'in_panel', 'True' ) )
+ if in_panel:
+ panel_elts = []
+ # Taken from tool_menu.mako:
+ for key, val in self.app.toolbox.tool_panel.items():
+ panel_elts.append( val.to_dict() )
+ rval = panel_elts
+ else:
+ tools = []
+ for id, tool in self.app.toolbox.tools_by_id.items():
+ tools.append( tool.to_dict() )
+ rval = tools
+
+ return rval
+
\ No newline at end of file
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
3 new commits in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/changeset/70397647fad5/
changeset: 70397647fad5
user: jgoecks
date: 2012-03-27 16:59:31
summary: Add backbone.js, underscore.js, and handlebars.js libraries in a new /libs directory and modify pack scripts accordingly.
affected #: 8 files
diff -r cb5ff5b1bd67ca6333d808beefab24beedfeed94 -r 70397647fad54c50213e015aaedfed94e6b19eda static/scripts/libs/backbone.js
--- /dev/null
+++ b/static/scripts/libs/backbone.js
@@ -0,0 +1,1431 @@
+// Backbone.js 0.9.2
+
+// (c) 2010-2012 Jeremy Ashkenas, DocumentCloud Inc.
+// Backbone may be freely distributed under the MIT license.
+// For all details and documentation:
+// http://backbonejs.org
+
+(function(){
+
+ // Initial Setup
+ // -------------
+
+ // Save a reference to the global object (`window` in the browser, `global`
+ // on the server).
+ var root = this;
+
+ // Save the previous value of the `Backbone` variable, so that it can be
+ // restored later on, if `noConflict` is used.
+ var previousBackbone = root.Backbone;
+
+ // Create a local reference to slice/splice.
+ var slice = Array.prototype.slice;
+ var splice = Array.prototype.splice;
+
+ // The top-level namespace. All public Backbone classes and modules will
+ // be attached to this. Exported for both CommonJS and the browser.
+ var Backbone;
+ if (typeof exports !== 'undefined') {
+ Backbone = exports;
+ } else {
+ Backbone = root.Backbone = {};
+ }
+
+ // Current version of the library. Keep in sync with `package.json`.
+ Backbone.VERSION = '0.9.2';
+
+ // Require Underscore, if we're on the server, and it's not already present.
+ var _ = root._;
+ if (!_ && (typeof require !== 'undefined')) _ = require('underscore');
+
+ // For Backbone's purposes, jQuery, Zepto, or Ender owns the `$` variable.
+ var $ = root.jQuery || root.Zepto || root.ender;
+
+ // Set the JavaScript library that will be used for DOM manipulation and
+ // Ajax calls (a.k.a. the `$` variable). By default Backbone will use: jQuery,
+ // Zepto, or Ender; but the `setDomLibrary()` method lets you inject an
+ // alternate JavaScript library (or a mock library for testing your views
+ // outside of a browser).
+ Backbone.setDomLibrary = function(lib) {
+ $ = lib;
+ };
+
+ // Runs Backbone.js in *noConflict* mode, returning the `Backbone` variable
+ // to its previous owner. Returns a reference to this Backbone object.
+ Backbone.noConflict = function() {
+ root.Backbone = previousBackbone;
+ return this;
+ };
+
+ // Turn on `emulateHTTP` to support legacy HTTP servers. Setting this option
+ // will fake `"PUT"` and `"DELETE"` requests via the `_method` parameter and
+ // set a `X-Http-Method-Override` header.
+ Backbone.emulateHTTP = false;
+
+ // Turn on `emulateJSON` to support legacy servers that can't deal with direct
+ // `application/json` requests ... will encode the body as
+ // `application/x-www-form-urlencoded` instead and will send the model in a
+ // form param named `model`.
+ Backbone.emulateJSON = false;
+
+ // Backbone.Events
+ // -----------------
+
+ // Regular expression used to split event strings
+ var eventSplitter = /\s+/;
+
+ // A module that can be mixed in to *any object* in order to provide it with
+ // custom events. You may bind with `on` or remove with `off` callback functions
+ // to an event; trigger`-ing an event fires all callbacks in succession.
+ //
+ // var object = {};
+ // _.extend(object, Backbone.Events);
+ // object.on('expand', function(){ alert('expanded'); });
+ // object.trigger('expand');
+ //
+ var Events = Backbone.Events = {
+
+ // Bind one or more space separated events, `events`, to a `callback`
+ // function. Passing `"all"` will bind the callback to all events fired.
+ on: function(events, callback, context) {
+
+ var calls, event, node, tail, list;
+ if (!callback) return this;
+ events = events.split(eventSplitter);
+ calls = this._callbacks || (this._callbacks = {});
+
+ // Create an immutable callback list, allowing traversal during
+ // modification. The tail is an empty object that will always be used
+ // as the next node.
+ while (event = events.shift()) {
+ list = calls[event];
+ node = list ? list.tail : {};
+ node.next = tail = {};
+ node.context = context;
+ node.callback = callback;
+ calls[event] = {tail: tail, next: list ? list.next : node};
+ }
+
+ return this;
+ },
+
+ // Remove one or many callbacks. If `context` is null, removes all callbacks
+ // with that function. If `callback` is null, removes all callbacks for the
+ // event. If `events` is null, removes all bound callbacks for all events.
+ off: function(events, callback, context) {
+ var event, calls, node, tail, cb, ctx;
+
+ // No events, or removing *all* events.
+ if (!(calls = this._callbacks)) return;
+ if (!(events || callback || context)) {
+ delete this._callbacks;
+ return this;
+ }
+
+ // Loop through the listed events and contexts, splicing them out of the
+ // linked list of callbacks if appropriate.
+ events = events ? events.split(eventSplitter) : _.keys(calls);
+ while (event = events.shift()) {
+ node = calls[event];
+ delete calls[event];
+ if (!node || !(callback || context)) continue;
+ // Create a new list, omitting the indicated callbacks.
+ tail = node.tail;
+ while ((node = node.next) !== tail) {
+ cb = node.callback;
+ ctx = node.context;
+ if ((callback && cb !== callback) || (context && ctx !== context)) {
+ this.on(event, cb, ctx);
+ }
+ }
+ }
+
+ return this;
+ },
+
+ // Trigger one or many events, firing all bound callbacks. Callbacks are
+ // passed the same arguments as `trigger` is, apart from the event name
+ // (unless you're listening on `"all"`, which will cause your callback to
+ // receive the true name of the event as the first argument).
+ trigger: function(events) {
+ var event, node, calls, tail, args, all, rest;
+ if (!(calls = this._callbacks)) return this;
+ all = calls.all;
+ events = events.split(eventSplitter);
+ rest = slice.call(arguments, 1);
+
+ // For each event, walk through the linked list of callbacks twice,
+ // first to trigger the event, then to trigger any `"all"` callbacks.
+ while (event = events.shift()) {
+ if (node = calls[event]) {
+ tail = node.tail;
+ while ((node = node.next) !== tail) {
+ node.callback.apply(node.context || this, rest);
+ }
+ }
+ if (node = all) {
+ tail = node.tail;
+ args = [event].concat(rest);
+ while ((node = node.next) !== tail) {
+ node.callback.apply(node.context || this, args);
+ }
+ }
+ }
+
+ return this;
+ }
+
+ };
+
+ // Aliases for backwards compatibility.
+ Events.bind = Events.on;
+ Events.unbind = Events.off;
+
+ // Backbone.Model
+ // --------------
+
+ // Create a new model, with defined attributes. A client id (`cid`)
+ // is automatically generated and assigned for you.
+ var Model = Backbone.Model = function(attributes, options) {
+ var defaults;
+ attributes || (attributes = {});
+ if (options && options.parse) attributes = this.parse(attributes);
+ if (defaults = getValue(this, 'defaults')) {
+ attributes = _.extend({}, defaults, attributes);
+ }
+ if (options && options.collection) this.collection = options.collection;
+ this.attributes = {};
+ this._escapedAttributes = {};
+ this.cid = _.uniqueId('c');
+ this.changed = {};
+ this._silent = {};
+ this._pending = {};
+ this.set(attributes, {silent: true});
+ // Reset change tracking.
+ this.changed = {};
+ this._silent = {};
+ this._pending = {};
+ this._previousAttributes = _.clone(this.attributes);
+ this.initialize.apply(this, arguments);
+ };
+
+ // Attach all inheritable methods to the Model prototype.
+ _.extend(Model.prototype, Events, {
+
+ // A hash of attributes whose current and previous value differ.
+ changed: null,
+
+ // A hash of attributes that have silently changed since the last time
+ // `change` was called. Will become pending attributes on the next call.
+ _silent: null,
+
+ // A hash of attributes that have changed since the last `'change'` event
+ // began.
+ _pending: null,
+
+ // The default name for the JSON `id` attribute is `"id"`. MongoDB and
+ // CouchDB users may want to set this to `"_id"`.
+ idAttribute: 'id',
+
+ // Initialize is an empty function by default. Override it with your own
+ // initialization logic.
+ initialize: function(){},
+
+ // Return a copy of the model's `attributes` object.
+ toJSON: function(options) {
+ return _.clone(this.attributes);
+ },
+
+ // Get the value of an attribute.
+ get: function(attr) {
+ return this.attributes[attr];
+ },
+
+ // Get the HTML-escaped value of an attribute.
+ escape: function(attr) {
+ var html;
+ if (html = this._escapedAttributes[attr]) return html;
+ var val = this.get(attr);
+ return this._escapedAttributes[attr] = _.escape(val == null ? '' : '' + val);
+ },
+
+ // Returns `true` if the attribute contains a value that is not null
+ // or undefined.
+ has: function(attr) {
+ return this.get(attr) != null;
+ },
+
+ // Set a hash of model attributes on the object, firing `"change"` unless
+ // you choose to silence it.
+ set: function(key, value, options) {
+ var attrs, attr, val;
+
+ // Handle both `"key", value` and `{key: value}` -style arguments.
+ if (_.isObject(key) || key == null) {
+ attrs = key;
+ options = value;
+ } else {
+ attrs = {};
+ attrs[key] = value;
+ }
+
+ // Extract attributes and options.
+ options || (options = {});
+ if (!attrs) return this;
+ if (attrs instanceof Model) attrs = attrs.attributes;
+ if (options.unset) for (attr in attrs) attrs[attr] = void 0;
+
+ // Run validation.
+ if (!this._validate(attrs, options)) return false;
+
+ // Check for changes of `id`.
+ if (this.idAttribute in attrs) this.id = attrs[this.idAttribute];
+
+ var changes = options.changes = {};
+ var now = this.attributes;
+ var escaped = this._escapedAttributes;
+ var prev = this._previousAttributes || {};
+
+ // For each `set` attribute...
+ for (attr in attrs) {
+ val = attrs[attr];
+
+ // If the new and current value differ, record the change.
+ if (!_.isEqual(now[attr], val) || (options.unset && _.has(now, attr))) {
+ delete escaped[attr];
+ (options.silent ? this._silent : changes)[attr] = true;
+ }
+
+ // Update or delete the current value.
+ options.unset ? delete now[attr] : now[attr] = val;
+
+ // If the new and previous value differ, record the change. If not,
+ // then remove changes for this attribute.
+ if (!_.isEqual(prev[attr], val) || (_.has(now, attr) != _.has(prev, attr))) {
+ this.changed[attr] = val;
+ if (!options.silent) this._pending[attr] = true;
+ } else {
+ delete this.changed[attr];
+ delete this._pending[attr];
+ }
+ }
+
+ // Fire the `"change"` events.
+ if (!options.silent) this.change(options);
+ return this;
+ },
+
+ // Remove an attribute from the model, firing `"change"` unless you choose
+ // to silence it. `unset` is a noop if the attribute doesn't exist.
+ unset: function(attr, options) {
+ (options || (options = {})).unset = true;
+ return this.set(attr, null, options);
+ },
+
+ // Clear all attributes on the model, firing `"change"` unless you choose
+ // to silence it.
+ clear: function(options) {
+ (options || (options = {})).unset = true;
+ return this.set(_.clone(this.attributes), options);
+ },
+
+ // Fetch the model from the server. If the server's representation of the
+ // model differs from its current attributes, they will be overriden,
+ // triggering a `"change"` event.
+ fetch: function(options) {
+ options = options ? _.clone(options) : {};
+ var model = this;
+ var success = options.success;
+ options.success = function(resp, status, xhr) {
+ if (!model.set(model.parse(resp, xhr), options)) return false;
+ if (success) success(model, resp);
+ };
+ options.error = Backbone.wrapError(options.error, model, options);
+ return (this.sync || Backbone.sync).call(this, 'read', this, options);
+ },
+
+ // Set a hash of model attributes, and sync the model to the server.
+ // If the server returns an attributes hash that differs, the model's
+ // state will be `set` again.
+ save: function(key, value, options) {
+ var attrs, current;
+
+ // Handle both `("key", value)` and `({key: value})` -style calls.
+ if (_.isObject(key) || key == null) {
+ attrs = key;
+ options = value;
+ } else {
+ attrs = {};
+ attrs[key] = value;
+ }
+ options = options ? _.clone(options) : {};
+
+ // If we're "wait"-ing to set changed attributes, validate early.
+ if (options.wait) {
+ if (!this._validate(attrs, options)) return false;
+ current = _.clone(this.attributes);
+ }
+
+ // Regular saves `set` attributes before persisting to the server.
+ var silentOptions = _.extend({}, options, {silent: true});
+ if (attrs && !this.set(attrs, options.wait ? silentOptions : options)) {
+ return false;
+ }
+
+ // After a successful server-side save, the client is (optionally)
+ // updated with the server-side state.
+ var model = this;
+ var success = options.success;
+ options.success = function(resp, status, xhr) {
+ var serverAttrs = model.parse(resp, xhr);
+ if (options.wait) {
+ delete options.wait;
+ serverAttrs = _.extend(attrs || {}, serverAttrs);
+ }
+ if (!model.set(serverAttrs, options)) return false;
+ if (success) {
+ success(model, resp);
+ } else {
+ model.trigger('sync', model, resp, options);
+ }
+ };
+
+ // Finish configuring and sending the Ajax request.
+ options.error = Backbone.wrapError(options.error, model, options);
+ var method = this.isNew() ? 'create' : 'update';
+ var xhr = (this.sync || Backbone.sync).call(this, method, this, options);
+ if (options.wait) this.set(current, silentOptions);
+ return xhr;
+ },
+
+ // Destroy this model on the server if it was already persisted.
+ // Optimistically removes the model from its collection, if it has one.
+ // If `wait: true` is passed, waits for the server to respond before removal.
+ destroy: function(options) {
+ options = options ? _.clone(options) : {};
+ var model = this;
+ var success = options.success;
+
+ var triggerDestroy = function() {
+ model.trigger('destroy', model, model.collection, options);
+ };
+
+ if (this.isNew()) {
+ triggerDestroy();
+ return false;
+ }
+
+ options.success = function(resp) {
+ if (options.wait) triggerDestroy();
+ if (success) {
+ success(model, resp);
+ } else {
+ model.trigger('sync', model, resp, options);
+ }
+ };
+
+ options.error = Backbone.wrapError(options.error, model, options);
+ var xhr = (this.sync || Backbone.sync).call(this, 'delete', this, options);
+ if (!options.wait) triggerDestroy();
+ return xhr;
+ },
+
+ // Default URL for the model's representation on the server -- if you're
+ // using Backbone's restful methods, override this to change the endpoint
+ // that will be called.
+ url: function() {
+ var base = getValue(this, 'urlRoot') || getValue(this.collection, 'url') || urlError();
+ if (this.isNew()) return base;
+ return base + (base.charAt(base.length - 1) == '/' ? '' : '/') + encodeURIComponent(this.id);
+ },
+
+ // **parse** converts a response into the hash of attributes to be `set` on
+ // the model. The default implementation is just to pass the response along.
+ parse: function(resp, xhr) {
+ return resp;
+ },
+
+ // Create a new model with identical attributes to this one.
+ clone: function() {
+ return new this.constructor(this.attributes);
+ },
+
+ // A model is new if it has never been saved to the server, and lacks an id.
+ isNew: function() {
+ return this.id == null;
+ },
+
+ // Call this method to manually fire a `"change"` event for this model and
+ // a `"change:attribute"` event for each changed attribute.
+ // Calling this will cause all objects observing the model to update.
+ change: function(options) {
+ options || (options = {});
+ var changing = this._changing;
+ this._changing = true;
+
+ // Silent changes become pending changes.
+ for (var attr in this._silent) this._pending[attr] = true;
+
+ // Silent changes are triggered.
+ var changes = _.extend({}, options.changes, this._silent);
+ this._silent = {};
+ for (var attr in changes) {
+ this.trigger('change:' + attr, this, this.get(attr), options);
+ }
+ if (changing) return this;
+
+ // Continue firing `"change"` events while there are pending changes.
+ while (!_.isEmpty(this._pending)) {
+ this._pending = {};
+ this.trigger('change', this, options);
+ // Pending and silent changes still remain.
+ for (var attr in this.changed) {
+ if (this._pending[attr] || this._silent[attr]) continue;
+ delete this.changed[attr];
+ }
+ this._previousAttributes = _.clone(this.attributes);
+ }
+
+ this._changing = false;
+ return this;
+ },
+
+ // Determine if the model has changed since the last `"change"` event.
+ // If you specify an attribute name, determine if that attribute has changed.
+ hasChanged: function(attr) {
+ if (!arguments.length) return !_.isEmpty(this.changed);
+ return _.has(this.changed, attr);
+ },
+
+ // Return an object containing all the attributes that have changed, or
+ // false if there are no changed attributes. Useful for determining what
+ // parts of a view need to be updated and/or what attributes need to be
+ // persisted to the server. Unset attributes will be set to undefined.
+ // You can also pass an attributes object to diff against the model,
+ // determining if there *would be* a change.
+ changedAttributes: function(diff) {
+ if (!diff) return this.hasChanged() ? _.clone(this.changed) : false;
+ var val, changed = false, old = this._previousAttributes;
+ for (var attr in diff) {
+ if (_.isEqual(old[attr], (val = diff[attr]))) continue;
+ (changed || (changed = {}))[attr] = val;
+ }
+ return changed;
+ },
+
+ // Get the previous value of an attribute, recorded at the time the last
+ // `"change"` event was fired.
+ previous: function(attr) {
+ if (!arguments.length || !this._previousAttributes) return null;
+ return this._previousAttributes[attr];
+ },
+
+ // Get all of the attributes of the model at the time of the previous
+ // `"change"` event.
+ previousAttributes: function() {
+ return _.clone(this._previousAttributes);
+ },
+
+ // Check if the model is currently in a valid state. It's only possible to
+ // get into an *invalid* state if you're using silent changes.
+ isValid: function() {
+ return !this.validate(this.attributes);
+ },
+
+ // Run validation against the next complete set of model attributes,
+ // returning `true` if all is well. If a specific `error` callback has
+ // been passed, call that instead of firing the general `"error"` event.
+ _validate: function(attrs, options) {
+ if (options.silent || !this.validate) return true;
+ attrs = _.extend({}, this.attributes, attrs);
+ var error = this.validate(attrs, options);
+ if (!error) return true;
+ if (options && options.error) {
+ options.error(this, error, options);
+ } else {
+ this.trigger('error', this, error, options);
+ }
+ return false;
+ }
+
+ });
+
+ // Backbone.Collection
+ // -------------------
+
+ // Provides a standard collection class for our sets of models, ordered
+ // or unordered. If a `comparator` is specified, the Collection will maintain
+ // its models in sort order, as they're added and removed.
+ var Collection = Backbone.Collection = function(models, options) {
+ options || (options = {});
+ if (options.model) this.model = options.model;
+ if (options.comparator) this.comparator = options.comparator;
+ this._reset();
+ this.initialize.apply(this, arguments);
+ if (models) this.reset(models, {silent: true, parse: options.parse});
+ };
+
+ // Define the Collection's inheritable methods.
+ _.extend(Collection.prototype, Events, {
+
+ // The default model for a collection is just a **Backbone.Model**.
+ // This should be overridden in most cases.
+ model: Model,
+
+ // Initialize is an empty function by default. Override it with your own
+ // initialization logic.
+ initialize: function(){},
+
+ // The JSON representation of a Collection is an array of the
+ // models' attributes.
+ toJSON: function(options) {
+ return this.map(function(model){ return model.toJSON(options); });
+ },
+
+ // Add a model, or list of models to the set. Pass **silent** to avoid
+ // firing the `add` event for every new model.
+ add: function(models, options) {
+ var i, index, length, model, cid, id, cids = {}, ids = {}, dups = [];
+ options || (options = {});
+ models = _.isArray(models) ? models.slice() : [models];
+
+ // Begin by turning bare objects into model references, and preventing
+ // invalid models or duplicate models from being added.
+ for (i = 0, length = models.length; i < length; i++) {
+ if (!(model = models[i] = this._prepareModel(models[i], options))) {
+ throw new Error("Can't add an invalid model to a collection");
+ }
+ cid = model.cid;
+ id = model.id;
+ if (cids[cid] || this._byCid[cid] || ((id != null) && (ids[id] || this._byId[id]))) {
+ dups.push(i);
+ continue;
+ }
+ cids[cid] = ids[id] = model;
+ }
+
+ // Remove duplicates.
+ i = dups.length;
+ while (i--) {
+ models.splice(dups[i], 1);
+ }
+
+ // Listen to added models' events, and index models for lookup by
+ // `id` and by `cid`.
+ for (i = 0, length = models.length; i < length; i++) {
+ (model = models[i]).on('all', this._onModelEvent, this);
+ this._byCid[model.cid] = model;
+ if (model.id != null) this._byId[model.id] = model;
+ }
+
+ // Insert models into the collection, re-sorting if needed, and triggering
+ // `add` events unless silenced.
+ this.length += length;
+ index = options.at != null ? options.at : this.models.length;
+ splice.apply(this.models, [index, 0].concat(models));
+ if (this.comparator) this.sort({silent: true});
+ if (options.silent) return this;
+ for (i = 0, length = this.models.length; i < length; i++) {
+ if (!cids[(model = this.models[i]).cid]) continue;
+ options.index = i;
+ model.trigger('add', model, this, options);
+ }
+ return this;
+ },
+
+ // Remove a model, or a list of models from the set. Pass silent to avoid
+ // firing the `remove` event for every model removed.
+ remove: function(models, options) {
+ var i, l, index, model;
+ options || (options = {});
+ models = _.isArray(models) ? models.slice() : [models];
+ for (i = 0, l = models.length; i < l; i++) {
+ model = this.getByCid(models[i]) || this.get(models[i]);
+ if (!model) continue;
+ delete this._byId[model.id];
+ delete this._byCid[model.cid];
+ index = this.indexOf(model);
+ this.models.splice(index, 1);
+ this.length--;
+ if (!options.silent) {
+ options.index = index;
+ model.trigger('remove', model, this, options);
+ }
+ this._removeReference(model);
+ }
+ return this;
+ },
+
+ // Add a model to the end of the collection.
+ push: function(model, options) {
+ model = this._prepareModel(model, options);
+ this.add(model, options);
+ return model;
+ },
+
+ // Remove a model from the end of the collection.
+ pop: function(options) {
+ var model = this.at(this.length - 1);
+ this.remove(model, options);
+ return model;
+ },
+
+ // Add a model to the beginning of the collection.
+ unshift: function(model, options) {
+ model = this._prepareModel(model, options);
+ this.add(model, _.extend({at: 0}, options));
+ return model;
+ },
+
+ // Remove a model from the beginning of the collection.
+ shift: function(options) {
+ var model = this.at(0);
+ this.remove(model, options);
+ return model;
+ },
+
+ // Get a model from the set by id.
+ get: function(id) {
+ if (id == null) return void 0;
+ return this._byId[id.id != null ? id.id : id];
+ },
+
+ // Get a model from the set by client id.
+ getByCid: function(cid) {
+ return cid && this._byCid[cid.cid || cid];
+ },
+
+ // Get the model at the given index.
+ at: function(index) {
+ return this.models[index];
+ },
+
+ // Return models with matching attributes. Useful for simple cases of `filter`.
+ where: function(attrs) {
+ if (_.isEmpty(attrs)) return [];
+ return this.filter(function(model) {
+ for (var key in attrs) {
+ if (attrs[key] !== model.get(key)) return false;
+ }
+ return true;
+ });
+ },
+
+ // Force the collection to re-sort itself. You don't need to call this under
+ // normal circumstances, as the set will maintain sort order as each item
+ // is added.
+ sort: function(options) {
+ options || (options = {});
+ if (!this.comparator) throw new Error('Cannot sort a set without a comparator');
+ var boundComparator = _.bind(this.comparator, this);
+ if (this.comparator.length == 1) {
+ this.models = this.sortBy(boundComparator);
+ } else {
+ this.models.sort(boundComparator);
+ }
+ if (!options.silent) this.trigger('reset', this, options);
+ return this;
+ },
+
+ // Pluck an attribute from each model in the collection.
+ pluck: function(attr) {
+ return _.map(this.models, function(model){ return model.get(attr); });
+ },
+
+ // When you have more items than you want to add or remove individually,
+ // you can reset the entire set with a new list of models, without firing
+ // any `add` or `remove` events. Fires `reset` when finished.
+ reset: function(models, options) {
+ models || (models = []);
+ options || (options = {});
+ for (var i = 0, l = this.models.length; i < l; i++) {
+ this._removeReference(this.models[i]);
+ }
+ this._reset();
+ this.add(models, _.extend({silent: true}, options));
+ if (!options.silent) this.trigger('reset', this, options);
+ return this;
+ },
+
+ // Fetch the default set of models for this collection, resetting the
+ // collection when they arrive. If `add: true` is passed, appends the
+ // models to the collection instead of resetting.
+ fetch: function(options) {
+ options = options ? _.clone(options) : {};
+ if (options.parse === undefined) options.parse = true;
+ var collection = this;
+ var success = options.success;
+ options.success = function(resp, status, xhr) {
+ collection[options.add ? 'add' : 'reset'](collection.parse(resp, xhr), options);
+ if (success) success(collection, resp);
+ };
+ options.error = Backbone.wrapError(options.error, collection, options);
+ return (this.sync || Backbone.sync).call(this, 'read', this, options);
+ },
+
+ // Create a new instance of a model in this collection. Add the model to the
+ // collection immediately, unless `wait: true` is passed, in which case we
+ // wait for the server to agree.
+ create: function(model, options) {
+ var coll = this;
+ options = options ? _.clone(options) : {};
+ model = this._prepareModel(model, options);
+ if (!model) return false;
+ if (!options.wait) coll.add(model, options);
+ var success = options.success;
+ options.success = function(nextModel, resp, xhr) {
+ if (options.wait) coll.add(nextModel, options);
+ if (success) {
+ success(nextModel, resp);
+ } else {
+ nextModel.trigger('sync', model, resp, options);
+ }
+ };
+ model.save(null, options);
+ return model;
+ },
+
+ // **parse** converts a response into a list of models to be added to the
+ // collection. The default implementation is just to pass it through.
+ parse: function(resp, xhr) {
+ return resp;
+ },
+
+ // Proxy to _'s chain. Can't be proxied the same way the rest of the
+ // underscore methods are proxied because it relies on the underscore
+ // constructor.
+ chain: function () {
+ return _(this.models).chain();
+ },
+
+ // Reset all internal state. Called when the collection is reset.
+ _reset: function(options) {
+ this.length = 0;
+ this.models = [];
+ this._byId = {};
+ this._byCid = {};
+ },
+
+ // Prepare a model or hash of attributes to be added to this collection.
+ _prepareModel: function(model, options) {
+ options || (options = {});
+ if (!(model instanceof Model)) {
+ var attrs = model;
+ options.collection = this;
+ model = new this.model(attrs, options);
+ if (!model._validate(model.attributes, options)) model = false;
+ } else if (!model.collection) {
+ model.collection = this;
+ }
+ return model;
+ },
+
+ // Internal method to remove a model's ties to a collection.
+ _removeReference: function(model) {
+ if (this == model.collection) {
+ delete model.collection;
+ }
+ model.off('all', this._onModelEvent, this);
+ },
+
+ // Internal method called every time a model in the set fires an event.
+ // Sets need to update their indexes when models change ids. All other
+ // events simply proxy through. "add" and "remove" events that originate
+ // in other collections are ignored.
+ _onModelEvent: function(event, model, collection, options) {
+ if ((event == 'add' || event == 'remove') && collection != this) return;
+ if (event == 'destroy') {
+ this.remove(model, options);
+ }
+ if (model && event === 'change:' + model.idAttribute) {
+ delete this._byId[model.previous(model.idAttribute)];
+ this._byId[model.id] = model;
+ }
+ this.trigger.apply(this, arguments);
+ }
+
+ });
+
+ // Underscore methods that we want to implement on the Collection.
+ var methods = ['forEach', 'each', 'map', 'reduce', 'reduceRight', 'find',
+ 'detect', 'filter', 'select', 'reject', 'every', 'all', 'some', 'any',
+ 'include', 'contains', 'invoke', 'max', 'min', 'sortBy', 'sortedIndex',
+ 'toArray', 'size', 'first', 'initial', 'rest', 'last', 'without', 'indexOf',
+ 'shuffle', 'lastIndexOf', 'isEmpty', 'groupBy'];
+
+ // Mix in each Underscore method as a proxy to `Collection#models`.
+ _.each(methods, function(method) {
+ Collection.prototype[method] = function() {
+ return _[method].apply(_, [this.models].concat(_.toArray(arguments)));
+ };
+ });
+
+ // Backbone.Router
+ // -------------------
+
+ // Routers map faux-URLs to actions, and fire events when routes are
+ // matched. Creating a new one sets its `routes` hash, if not set statically.
+ var Router = Backbone.Router = function(options) {
+ options || (options = {});
+ if (options.routes) this.routes = options.routes;
+ this._bindRoutes();
+ this.initialize.apply(this, arguments);
+ };
+
+ // Cached regular expressions for matching named param parts and splatted
+ // parts of route strings.
+ var namedParam = /:\w+/g;
+ var splatParam = /\*\w+/g;
+ var escapeRegExp = /[-[\]{}()+?.,\\^$|#\s]/g;
+
+ // Set up all inheritable **Backbone.Router** properties and methods.
+ _.extend(Router.prototype, Events, {
+
+ // Initialize is an empty function by default. Override it with your own
+ // initialization logic.
+ initialize: function(){},
+
+ // Manually bind a single named route to a callback. For example:
+ //
+ // this.route('search/:query/p:num', 'search', function(query, num) {
+ // ...
+ // });
+ //
+ route: function(route, name, callback) {
+ Backbone.history || (Backbone.history = new History);
+ if (!_.isRegExp(route)) route = this._routeToRegExp(route);
+ if (!callback) callback = this[name];
+ Backbone.history.route(route, _.bind(function(fragment) {
+ var args = this._extractParameters(route, fragment);
+ callback && callback.apply(this, args);
+ this.trigger.apply(this, ['route:' + name].concat(args));
+ Backbone.history.trigger('route', this, name, args);
+ }, this));
+ return this;
+ },
+
+ // Simple proxy to `Backbone.history` to save a fragment into the history.
+ navigate: function(fragment, options) {
+ Backbone.history.navigate(fragment, options);
+ },
+
+ // Bind all defined routes to `Backbone.history`. We have to reverse the
+ // order of the routes here to support behavior where the most general
+ // routes can be defined at the bottom of the route map.
+ _bindRoutes: function() {
+ if (!this.routes) return;
+ var routes = [];
+ for (var route in this.routes) {
+ routes.unshift([route, this.routes[route]]);
+ }
+ for (var i = 0, l = routes.length; i < l; i++) {
+ this.route(routes[i][0], routes[i][1], this[routes[i][1]]);
+ }
+ },
+
+ // Convert a route string into a regular expression, suitable for matching
+ // against the current location hash.
+ _routeToRegExp: function(route) {
+ route = route.replace(escapeRegExp, '\\$&')
+ .replace(namedParam, '([^\/]+)')
+ .replace(splatParam, '(.*?)');
+ return new RegExp('^' + route + '$');
+ },
+
+ // Given a route, and a URL fragment that it matches, return the array of
+ // extracted parameters.
+ _extractParameters: function(route, fragment) {
+ return route.exec(fragment).slice(1);
+ }
+
+ });
+
+ // Backbone.History
+ // ----------------
+
+ // Handles cross-browser history management, based on URL fragments. If the
+ // browser does not support `onhashchange`, falls back to polling.
+ var History = Backbone.History = function() {
+ this.handlers = [];
+ _.bindAll(this, 'checkUrl');
+ };
+
+ // Cached regex for cleaning leading hashes and slashes .
+ var routeStripper = /^[#\/]/;
+
+ // Cached regex for detecting MSIE.
+ var isExplorer = /msie [\w.]+/;
+
+ // Has the history handling already been started?
+ History.started = false;
+
+ // Set up all inheritable **Backbone.History** properties and methods.
+ _.extend(History.prototype, Events, {
+
+ // The default interval to poll for hash changes, if necessary, is
+ // twenty times a second.
+ interval: 50,
+
+ // Gets the true hash value. Cannot use location.hash directly due to bug
+ // in Firefox where location.hash will always be decoded.
+ getHash: function(windowOverride) {
+ var loc = windowOverride ? windowOverride.location : window.location;
+ var match = loc.href.match(/#(.*)$/);
+ return match ? match[1] : '';
+ },
+
+ // Get the cross-browser normalized URL fragment, either from the URL,
+ // the hash, or the override.
+ getFragment: function(fragment, forcePushState) {
+ if (fragment == null) {
+ if (this._hasPushState || forcePushState) {
+ fragment = window.location.pathname;
+ var search = window.location.search;
+ if (search) fragment += search;
+ } else {
+ fragment = this.getHash();
+ }
+ }
+ if (!fragment.indexOf(this.options.root)) fragment = fragment.substr(this.options.root.length);
+ return fragment.replace(routeStripper, '');
+ },
+
+ // Start the hash change handling, returning `true` if the current URL matches
+ // an existing route, and `false` otherwise.
+ start: function(options) {
+ if (History.started) throw new Error("Backbone.history has already been started");
+ History.started = true;
+
+ // Figure out the initial configuration. Do we need an iframe?
+ // Is pushState desired ... is it available?
+ this.options = _.extend({}, {root: '/'}, this.options, options);
+ this._wantsHashChange = this.options.hashChange !== false;
+ this._wantsPushState = !!this.options.pushState;
+ this._hasPushState = !!(this.options.pushState && window.history && window.history.pushState);
+ var fragment = this.getFragment();
+ var docMode = document.documentMode;
+ var oldIE = (isExplorer.exec(navigator.userAgent.toLowerCase()) && (!docMode || docMode <= 7));
+
+ if (oldIE) {
+ this.iframe = $('<iframe src="javascript:0" tabindex="-1" />').hide().appendTo('body')[0].contentWindow;
+ this.navigate(fragment);
+ }
+
+ // Depending on whether we're using pushState or hashes, and whether
+ // 'onhashchange' is supported, determine how we check the URL state.
+ if (this._hasPushState) {
+ $(window).bind('popstate', this.checkUrl);
+ } else if (this._wantsHashChange && ('onhashchange' in window) && !oldIE) {
+ $(window).bind('hashchange', this.checkUrl);
+ } else if (this._wantsHashChange) {
+ this._checkUrlInterval = setInterval(this.checkUrl, this.interval);
+ }
+
+ // Determine if we need to change the base url, for a pushState link
+ // opened by a non-pushState browser.
+ this.fragment = fragment;
+ var loc = window.location;
+ var atRoot = loc.pathname == this.options.root;
+
+ // If we've started off with a route from a `pushState`-enabled browser,
+ // but we're currently in a browser that doesn't support it...
+ if (this._wantsHashChange && this._wantsPushState && !this._hasPushState && !atRoot) {
+ this.fragment = this.getFragment(null, true);
+ window.location.replace(this.options.root + '#' + this.fragment);
+ // Return immediately as browser will do redirect to new url
+ return true;
+
+ // Or if we've started out with a hash-based route, but we're currently
+ // in a browser where it could be `pushState`-based instead...
+ } else if (this._wantsPushState && this._hasPushState && atRoot && loc.hash) {
+ this.fragment = this.getHash().replace(routeStripper, '');
+ window.history.replaceState({}, document.title, loc.protocol + '//' + loc.host + this.options.root + this.fragment);
+ }
+
+ if (!this.options.silent) {
+ return this.loadUrl();
+ }
+ },
+
+ // Disable Backbone.history, perhaps temporarily. Not useful in a real app,
+ // but possibly useful for unit testing Routers.
+ stop: function() {
+ $(window).unbind('popstate', this.checkUrl).unbind('hashchange', this.checkUrl);
+ clearInterval(this._checkUrlInterval);
+ History.started = false;
+ },
+
+ // Add a route to be tested when the fragment changes. Routes added later
+ // may override previous routes.
+ route: function(route, callback) {
+ this.handlers.unshift({route: route, callback: callback});
+ },
+
+ // Checks the current URL to see if it has changed, and if it has,
+ // calls `loadUrl`, normalizing across the hidden iframe.
+ checkUrl: function(e) {
+ var current = this.getFragment();
+ if (current == this.fragment && this.iframe) current = this.getFragment(this.getHash(this.iframe));
+ if (current == this.fragment) return false;
+ if (this.iframe) this.navigate(current);
+ this.loadUrl() || this.loadUrl(this.getHash());
+ },
+
+ // Attempt to load the current URL fragment. If a route succeeds with a
+ // match, returns `true`. If no defined routes matches the fragment,
+ // returns `false`.
+ loadUrl: function(fragmentOverride) {
+ var fragment = this.fragment = this.getFragment(fragmentOverride);
+ var matched = _.any(this.handlers, function(handler) {
+ if (handler.route.test(fragment)) {
+ handler.callback(fragment);
+ return true;
+ }
+ });
+ return matched;
+ },
+
+ // Save a fragment into the hash history, or replace the URL state if the
+ // 'replace' option is passed. You are responsible for properly URL-encoding
+ // the fragment in advance.
+ //
+ // The options object can contain `trigger: true` if you wish to have the
+ // route callback be fired (not usually desirable), or `replace: true`, if
+ // you wish to modify the current URL without adding an entry to the history.
+ navigate: function(fragment, options) {
+ if (!History.started) return false;
+ if (!options || options === true) options = {trigger: options};
+ var frag = (fragment || '').replace(routeStripper, '');
+ if (this.fragment == frag) return;
+
+ // If pushState is available, we use it to set the fragment as a real URL.
+ if (this._hasPushState) {
+ if (frag.indexOf(this.options.root) != 0) frag = this.options.root + frag;
+ this.fragment = frag;
+ window.history[options.replace ? 'replaceState' : 'pushState']({}, document.title, frag);
+
+ // If hash changes haven't been explicitly disabled, update the hash
+ // fragment to store history.
+ } else if (this._wantsHashChange) {
+ this.fragment = frag;
+ this._updateHash(window.location, frag, options.replace);
+ if (this.iframe && (frag != this.getFragment(this.getHash(this.iframe)))) {
+ // Opening and closing the iframe tricks IE7 and earlier to push a history entry on hash-tag change.
+ // When replace is true, we don't want this.
+ if(!options.replace) this.iframe.document.open().close();
+ this._updateHash(this.iframe.location, frag, options.replace);
+ }
+
+ // If you've told us that you explicitly don't want fallback hashchange-
+ // based history, then `navigate` becomes a page refresh.
+ } else {
+ window.location.assign(this.options.root + fragment);
+ }
+ if (options.trigger) this.loadUrl(fragment);
+ },
+
+ // Update the hash location, either replacing the current entry, or adding
+ // a new one to the browser history.
+ _updateHash: function(location, fragment, replace) {
+ if (replace) {
+ location.replace(location.toString().replace(/(javascript:|#).*$/, '') + '#' + fragment);
+ } else {
+ location.hash = fragment;
+ }
+ }
+ });
+
+ // Backbone.View
+ // -------------
+
+ // Creating a Backbone.View creates its initial element outside of the DOM,
+ // if an existing element is not provided...
+ var View = Backbone.View = function(options) {
+ this.cid = _.uniqueId('view');
+ this._configure(options || {});
+ this._ensureElement();
+ this.initialize.apply(this, arguments);
+ this.delegateEvents();
+ };
+
+ // Cached regex to split keys for `delegate`.
+ var delegateEventSplitter = /^(\S+)\s*(.*)$/;
+
+ // List of view options to be merged as properties.
+ var viewOptions = ['model', 'collection', 'el', 'id', 'attributes', 'className', 'tagName'];
+
+ // Set up all inheritable **Backbone.View** properties and methods.
+ _.extend(View.prototype, Events, {
+
+ // The default `tagName` of a View's element is `"div"`.
+ tagName: 'div',
+
+ // jQuery delegate for element lookup, scoped to DOM elements within the
+ // current view. This should be prefered to global lookups where possible.
+ $: function(selector) {
+ return this.$el.find(selector);
+ },
+
+ // Initialize is an empty function by default. Override it with your own
+ // initialization logic.
+ initialize: function(){},
+
+ // **render** is the core function that your view should override, in order
+ // to populate its element (`this.el`), with the appropriate HTML. The
+ // convention is for **render** to always return `this`.
+ render: function() {
+ return this;
+ },
+
+ // Remove this view from the DOM. Note that the view isn't present in the
+ // DOM by default, so calling this method may be a no-op.
+ remove: function() {
+ this.$el.remove();
+ return this;
+ },
+
+ // For small amounts of DOM Elements, where a full-blown template isn't
+ // needed, use **make** to manufacture elements, one at a time.
+ //
+ // var el = this.make('li', {'class': 'row'}, this.model.escape('title'));
+ //
+ make: function(tagName, attributes, content) {
+ var el = document.createElement(tagName);
+ if (attributes) $(el).attr(attributes);
+ if (content) $(el).html(content);
+ return el;
+ },
+
+ // Change the view's element (`this.el` property), including event
+ // re-delegation.
+ setElement: function(element, delegate) {
+ if (this.$el) this.undelegateEvents();
+ this.$el = (element instanceof $) ? element : $(element);
+ this.el = this.$el[0];
+ if (delegate !== false) this.delegateEvents();
+ return this;
+ },
+
+ // Set callbacks, where `this.events` is a hash of
+ //
+ // *{"event selector": "callback"}*
+ //
+ // {
+ // 'mousedown .title': 'edit',
+ // 'click .button': 'save'
+ // 'click .open': function(e) { ... }
+ // }
+ //
+ // pairs. Callbacks will be bound to the view, with `this` set properly.
+ // Uses event delegation for efficiency.
+ // Omitting the selector binds the event to `this.el`.
+ // This only works for delegate-able events: not `focus`, `blur`, and
+ // not `change`, `submit`, and `reset` in Internet Explorer.
+ delegateEvents: function(events) {
+ if (!(events || (events = getValue(this, 'events')))) return;
+ this.undelegateEvents();
+ for (var key in events) {
+ var method = events[key];
+ if (!_.isFunction(method)) method = this[events[key]];
+ if (!method) throw new Error('Method "' + events[key] + '" does not exist');
+ var match = key.match(delegateEventSplitter);
+ var eventName = match[1], selector = match[2];
+ method = _.bind(method, this);
+ eventName += '.delegateEvents' + this.cid;
+ if (selector === '') {
+ this.$el.bind(eventName, method);
+ } else {
+ this.$el.delegate(selector, eventName, method);
+ }
+ }
+ },
+
+ // Clears all callbacks previously bound to the view with `delegateEvents`.
+ // You usually don't need to use this, but may wish to if you have multiple
+ // Backbone views attached to the same DOM element.
+ undelegateEvents: function() {
+ this.$el.unbind('.delegateEvents' + this.cid);
+ },
+
+ // Performs the initial configuration of a View with a set of options.
+ // Keys with special meaning *(model, collection, id, className)*, are
+ // attached directly to the view.
+ _configure: function(options) {
+ if (this.options) options = _.extend({}, this.options, options);
+ for (var i = 0, l = viewOptions.length; i < l; i++) {
+ var attr = viewOptions[i];
+ if (options[attr]) this[attr] = options[attr];
+ }
+ this.options = options;
+ },
+
+ // Ensure that the View has a DOM element to render into.
+ // If `this.el` is a string, pass it through `$()`, take the first
+ // matching element, and re-assign it to `el`. Otherwise, create
+ // an element from the `id`, `className` and `tagName` properties.
+ _ensureElement: function() {
+ if (!this.el) {
+ var attrs = getValue(this, 'attributes') || {};
+ if (this.id) attrs.id = this.id;
+ if (this.className) attrs['class'] = this.className;
+ this.setElement(this.make(this.tagName, attrs), false);
+ } else {
+ this.setElement(this.el, false);
+ }
+ }
+
+ });
+
+ // The self-propagating extend function that Backbone classes use.
+ var extend = function (protoProps, classProps) {
+ var child = inherits(this, protoProps, classProps);
+ child.extend = this.extend;
+ return child;
+ };
+
+ // Set up inheritance for the model, collection, and view.
+ Model.extend = Collection.extend = Router.extend = View.extend = extend;
+
+ // Backbone.sync
+ // -------------
+
+ // Map from CRUD to HTTP for our default `Backbone.sync` implementation.
+ var methodMap = {
+ 'create': 'POST',
+ 'update': 'PUT',
+ 'delete': 'DELETE',
+ 'read': 'GET'
+ };
+
+ // Override this function to change the manner in which Backbone persists
+ // models to the server. You will be passed the type of request, and the
+ // model in question. By default, makes a RESTful Ajax request
+ // to the model's `url()`. Some possible customizations could be:
+ //
+ // * Use `setTimeout` to batch rapid-fire updates into a single request.
+ // * Send up the models as XML instead of JSON.
+ // * Persist models via WebSockets instead of Ajax.
+ //
+ // Turn on `Backbone.emulateHTTP` in order to send `PUT` and `DELETE` requests
+ // as `POST`, with a `_method` parameter containing the true HTTP method,
+ // as well as all requests with the body as `application/x-www-form-urlencoded`
+ // instead of `application/json` with the model in a param named `model`.
+ // Useful when interfacing with server-side languages like **PHP** that make
+ // it difficult to read the body of `PUT` requests.
+ Backbone.sync = function(method, model, options) {
+ var type = methodMap[method];
+
+ // Default options, unless specified.
+ options || (options = {});
+
+ // Default JSON-request options.
+ var params = {type: type, dataType: 'json'};
+
+ // Ensure that we have a URL.
+ if (!options.url) {
+ params.url = getValue(model, 'url') || urlError();
+ }
+
+ // Ensure that we have the appropriate request data.
+ if (!options.data && model && (method == 'create' || method == 'update')) {
+ params.contentType = 'application/json';
+ params.data = JSON.stringify(model.toJSON());
+ }
+
+ // For older servers, emulate JSON by encoding the request into an HTML-form.
+ if (Backbone.emulateJSON) {
+ params.contentType = 'application/x-www-form-urlencoded';
+ params.data = params.data ? {model: params.data} : {};
+ }
+
+ // For older servers, emulate HTTP by mimicking the HTTP method with `_method`
+ // And an `X-HTTP-Method-Override` header.
+ if (Backbone.emulateHTTP) {
+ if (type === 'PUT' || type === 'DELETE') {
+ if (Backbone.emulateJSON) params.data._method = type;
+ params.type = 'POST';
+ params.beforeSend = function(xhr) {
+ xhr.setRequestHeader('X-HTTP-Method-Override', type);
+ };
+ }
+ }
+
+ // Don't process data on a non-GET request.
+ if (params.type !== 'GET' && !Backbone.emulateJSON) {
+ params.processData = false;
+ }
+
+ // Make the request, allowing the user to override any Ajax options.
+ return $.ajax(_.extend(params, options));
+ };
+
+ // Wrap an optional error callback with a fallback error event.
+ Backbone.wrapError = function(onError, originalModel, options) {
+ return function(model, resp) {
+ resp = model === originalModel ? resp : model;
+ if (onError) {
+ onError(originalModel, resp, options);
+ } else {
+ originalModel.trigger('error', originalModel, resp, options);
+ }
+ };
+ };
+
+ // Helpers
+ // -------
+
+ // Shared empty constructor function to aid in prototype-chain creation.
+ var ctor = function(){};
+
+ // Helper function to correctly set up the prototype chain, for subclasses.
+ // Similar to `goog.inherits`, but uses a hash of prototype properties and
+ // class properties to be extended.
+ var inherits = function(parent, protoProps, staticProps) {
+ var child;
+
+ // The constructor function for the new subclass is either defined by you
+ // (the "constructor" property in your `extend` definition), or defaulted
+ // by us to simply call the parent's constructor.
+ if (protoProps && protoProps.hasOwnProperty('constructor')) {
+ child = protoProps.constructor;
+ } else {
+ child = function(){ parent.apply(this, arguments); };
+ }
+
+ // Inherit class (static) properties from parent.
+ _.extend(child, parent);
+
+ // Set the prototype chain to inherit from `parent`, without calling
+ // `parent`'s constructor function.
+ ctor.prototype = parent.prototype;
+ child.prototype = new ctor();
+
+ // Add prototype properties (instance properties) to the subclass,
+ // if supplied.
+ if (protoProps) _.extend(child.prototype, protoProps);
+
+ // Add static properties to the constructor function, if supplied.
+ if (staticProps) _.extend(child, staticProps);
+
+ // Correctly set child's `prototype.constructor`.
+ child.prototype.constructor = child;
+
+ // Set a convenience property in case the parent's prototype is needed later.
+ child.__super__ = parent.prototype;
+
+ return child;
+ };
+
+ // Helper function to get a value from a Backbone object as a property
+ // or as a function.
+ var getValue = function(object, prop) {
+ if (!(object && object[prop])) return null;
+ return _.isFunction(object[prop]) ? object[prop]() : object[prop];
+ };
+
+ // Throw an error when a URL is needed, and none is supplied.
+ var urlError = function() {
+ throw new Error('A "url" property or function must be specified');
+ };
+
+}).call(this);
diff -r cb5ff5b1bd67ca6333d808beefab24beedfeed94 -r 70397647fad54c50213e015aaedfed94e6b19eda static/scripts/libs/handlebars-1.0.0.beta.6.js
--- /dev/null
+++ b/static/scripts/libs/handlebars-1.0.0.beta.6.js
@@ -0,0 +1,1550 @@
+// lib/handlebars/base.js
+var Handlebars = {};
+
+Handlebars.VERSION = "1.0.beta.6";
+
+Handlebars.helpers = {};
+Handlebars.partials = {};
+
+Handlebars.registerHelper = function(name, fn, inverse) {
+ if(inverse) { fn.not = inverse; }
+ this.helpers[name] = fn;
+};
+
+Handlebars.registerPartial = function(name, str) {
+ this.partials[name] = str;
+};
+
+Handlebars.registerHelper('helperMissing', function(arg) {
+ if(arguments.length === 2) {
+ return undefined;
+ } else {
+ throw new Error("Could not find property '" + arg + "'");
+ }
+});
+
+var toString = Object.prototype.toString, functionType = "[object Function]";
+
+Handlebars.registerHelper('blockHelperMissing', function(context, options) {
+ var inverse = options.inverse || function() {}, fn = options.fn;
+
+
+ var ret = "";
+ var type = toString.call(context);
+
+ if(type === functionType) { context = context.call(this); }
+
+ if(context === true) {
+ return fn(this);
+ } else if(context === false || context == null) {
+ return inverse(this);
+ } else if(type === "[object Array]") {
+ if(context.length > 0) {
+ for(var i=0, j=context.length; i<j; i++) {
+ ret = ret + fn(context[i]);
+ }
+ } else {
+ ret = inverse(this);
+ }
+ return ret;
+ } else {
+ return fn(context);
+ }
+});
+
+Handlebars.registerHelper('each', function(context, options) {
+ var fn = options.fn, inverse = options.inverse;
+ var ret = "";
+
+ if(context && context.length > 0) {
+ for(var i=0, j=context.length; i<j; i++) {
+ ret = ret + fn(context[i]);
+ }
+ } else {
+ ret = inverse(this);
+ }
+ return ret;
+});
+
+Handlebars.registerHelper('if', function(context, options) {
+ var type = toString.call(context);
+ if(type === functionType) { context = context.call(this); }
+
+ if(!context || Handlebars.Utils.isEmpty(context)) {
+ return options.inverse(this);
+ } else {
+ return options.fn(this);
+ }
+});
+
+Handlebars.registerHelper('unless', function(context, options) {
+ var fn = options.fn, inverse = options.inverse;
+ options.fn = inverse;
+ options.inverse = fn;
+
+ return Handlebars.helpers['if'].call(this, context, options);
+});
+
+Handlebars.registerHelper('with', function(context, options) {
+ return options.fn(context);
+});
+
+Handlebars.registerHelper('log', function(context) {
+ Handlebars.log(context);
+});
+;
+// lib/handlebars/compiler/parser.js
+/* Jison generated parser */
+var handlebars = (function(){
+
+var parser = {trace: function trace() { },
+yy: {},
+symbols_: {"error":2,"root":3,"program":4,"EOF":5,"statements":6,"simpleInverse":7,"statement":8,"openInverse":9,"closeBlock":10,"openBlock":11,"mustache":12,"partial":13,"CONTENT":14,"COMMENT":15,"OPEN_BLOCK":16,"inMustache":17,"CLOSE":18,"OPEN_INVERSE":19,"OPEN_ENDBLOCK":20,"path":21,"OPEN":22,"OPEN_UNESCAPED":23,"OPEN_PARTIAL":24,"params":25,"hash":26,"param":27,"STRING":28,"INTEGER":29,"BOOLEAN":30,"hashSegments":31,"hashSegment":32,"ID":33,"EQUALS":34,"pathSegments":35,"SEP":36,"$accept":0,"$end":1},
+terminals_: {2:"error",5:"EOF",14:"CONTENT",15:"COMMENT",16:"OPEN_BLOCK",18:"CLOSE",19:"OPEN_INVERSE",20:"OPEN_ENDBLOCK",22:"OPEN",23:"OPEN_UNESCAPED",24:"OPEN_PARTIAL",28:"STRING",29:"INTEGER",30:"BOOLEAN",33:"ID",34:"EQUALS",36:"SEP"},
+productions_: [0,[3,2],[4,3],[4,1],[4,0],[6,1],[6,2],[8,3],[8,3],[8,1],[8,1],[8,1],[8,1],[11,3],[9,3],[10,3],[12,3],[12,3],[13,3],[13,4],[7,2],[17,3],[17,2],[17,2],[17,1],[25,2],[25,1],[27,1],[27,1],[27,1],[27,1],[26,1],[31,2],[31,1],[32,3],[32,3],[32,3],[32,3],[21,1],[35,3],[35,1]],
+performAction: function anonymous(yytext,yyleng,yylineno,yy,yystate,$$,_$) {
+
+var $0 = $$.length - 1;
+switch (yystate) {
+case 1: return $$[$0-1]
+break;
+case 2: this.$ = new yy.ProgramNode($$[$0-2], $$[$0])
+break;
+case 3: this.$ = new yy.ProgramNode($$[$0])
+break;
+case 4: this.$ = new yy.ProgramNode([])
+break;
+case 5: this.$ = [$$[$0]]
+break;
+case 6: $$[$0-1].push($$[$0]); this.$ = $$[$0-1]
+break;
+case 7: this.$ = new yy.InverseNode($$[$0-2], $$[$0-1], $$[$0])
+break;
+case 8: this.$ = new yy.BlockNode($$[$0-2], $$[$0-1], $$[$0])
+break;
+case 9: this.$ = $$[$0]
+break;
+case 10: this.$ = $$[$0]
+break;
+case 11: this.$ = new yy.ContentNode($$[$0])
+break;
+case 12: this.$ = new yy.CommentNode($$[$0])
+break;
+case 13: this.$ = new yy.MustacheNode($$[$0-1][0], $$[$0-1][1])
+break;
+case 14: this.$ = new yy.MustacheNode($$[$0-1][0], $$[$0-1][1])
+break;
+case 15: this.$ = $$[$0-1]
+break;
+case 16: this.$ = new yy.MustacheNode($$[$0-1][0], $$[$0-1][1])
+break;
+case 17: this.$ = new yy.MustacheNode($$[$0-1][0], $$[$0-1][1], true)
+break;
+case 18: this.$ = new yy.PartialNode($$[$0-1])
+break;
+case 19: this.$ = new yy.PartialNode($$[$0-2], $$[$0-1])
+break;
+case 20:
+break;
+case 21: this.$ = [[$$[$0-2]].concat($$[$0-1]), $$[$0]]
+break;
+case 22: this.$ = [[$$[$0-1]].concat($$[$0]), null]
+break;
+case 23: this.$ = [[$$[$0-1]], $$[$0]]
+break;
+case 24: this.$ = [[$$[$0]], null]
+break;
+case 25: $$[$0-1].push($$[$0]); this.$ = $$[$0-1];
+break;
+case 26: this.$ = [$$[$0]]
+break;
+case 27: this.$ = $$[$0]
+break;
+case 28: this.$ = new yy.StringNode($$[$0])
+break;
+case 29: this.$ = new yy.IntegerNode($$[$0])
+break;
+case 30: this.$ = new yy.BooleanNode($$[$0])
+break;
+case 31: this.$ = new yy.HashNode($$[$0])
+break;
+case 32: $$[$0-1].push($$[$0]); this.$ = $$[$0-1]
+break;
+case 33: this.$ = [$$[$0]]
+break;
+case 34: this.$ = [$$[$0-2], $$[$0]]
+break;
+case 35: this.$ = [$$[$0-2], new yy.StringNode($$[$0])]
+break;
+case 36: this.$ = [$$[$0-2], new yy.IntegerNode($$[$0])]
+break;
+case 37: this.$ = [$$[$0-2], new yy.BooleanNode($$[$0])]
+break;
+case 38: this.$ = new yy.IdNode($$[$0])
+break;
+case 39: $$[$0-2].push($$[$0]); this.$ = $$[$0-2];
+break;
+case 40: this.$ = [$$[$0]]
+break;
+}
+},
+table: [{3:1,4:2,5:[2,4],6:3,8:4,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,11],22:[1,13],23:[1,14],24:[1,15]},{1:[3]},{5:[1,16]},{5:[2,3],7:17,8:18,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,19],20:[2,3],22:[1,13],23:[1,14],24:[1,15]},{5:[2,5],14:[2,5],15:[2,5],16:[2,5],19:[2,5],20:[2,5],22:[2,5],23:[2,5],24:[2,5]},{4:20,6:3,8:4,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,11],20:[2,4],22:[1,13],23:[1,14],24:[1,15]},{4:21,6:3,8:4,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,11],20:[2,4],22:[1,13],23:[1,14],24:[1,15]},{5:[2,9],14:[2,9],15:[2,9],16:[2,9],19:[2,9],20:[2,9],22:[2,9],23:[2,9],24:[2,9]},{5:[2,10],14:[2,10],15:[2,10],16:[2,10],19:[2,10],20:[2,10],22:[2,10],23:[2,10],24:[2,10]},{5:[2,11],14:[2,11],15:[2,11],16:[2,11],19:[2,11],20:[2,11],22:[2,11],23:[2,11],24:[2,11]},{5:[2,12],14:[2,12],15:[2,12],16:[2,12],19:[2,12],20:[2,12],22:[2,12],23:[2,12],24:[2,12]},{17:22,21:23,33:[1,25],35:24},{17:26,21:23,33:[1,25],35:24},{17:27,21:23,33:[1,25],35:24},{17:28,21:23,33:[1,25],35:24},{21:29,33:[1,25],35:24},{1:[2,1]},{6:30,8:4,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,11],22:[1,13],23:[1,14],24:[1,15]},{5:[2,6],14:[2,6],15:[2,6],16:[2,6],19:[2,6],20:[2,6],22:[2,6],23:[2,6],24:[2,6]},{17:22,18:[1,31],21:23,33:[1,25],35:24},{10:32,20:[1,33]},{10:34,20:[1,33]},{18:[1,35]},{18:[2,24],21:40,25:36,26:37,27:38,28:[1,41],29:[1,42],30:[1,43],31:39,32:44,33:[1,45],35:24},{18:[2,38],28:[2,38],29:[2,38],30:[2,38],33:[2,38],36:[1,46]},{18:[2,40],28:[2,40],29:[2,40],30:[2,40],33:[2,40],36:[2,40]},{18:[1,47]},{18:[1,48]},{18:[1,49]},{18:[1,50],21:51,33:[1,25],35:24},{5:[2,2],8:18,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,11],20:[2,2],22:[1,13],23:[1,14],24:[1,15]},{14:[2,20],15:[2,20],16:[2,20],19:[2,20],22:[2,20],23:[2,20],24:[2,20]},{5:[2,7],14:[2,7],15:[2,7],16:[2,7],19:[2,7],20:[2,7],22:[2,7],23:[2,7],24:[2,7]},{21:52,33:[1,25],35:24},{5:[2,8],14:[2,8],15:[2,8],16:[2,8],19:[2,8],20:[2,8],22:[2,8],23:[2,8],24:[2,8]},{14:[2,14],15:[2,14],16:[2,14],19:[2,14],20:[2,14],22:[2,14],23:[2,14],24:[2,14]},{18:[2,22],21:40,26:53,27:54,28:[1,41],29:[1,42],30:[1,43],31:39,32:44,33:[1,45],35:24},{18:[2,23]},{18:[2,26],28:[2,26],29:[2,26],30:[2,26],33:[2,26]},{18:[2,31],32:55,33:[1,56]},{18:[2,27],28:[2,27],29:[2,27],30:[2,27],33:[2,27]},{18:[2,28],28:[2,28],29:[2,28],30:[2,28],33:[2,28]},{18:[2,29],28:[2,29],29:[2,29],30:[2,29],33:[2,29]},{18:[2,30],28:[2,30],29:[2,30],30:[2,30],33:[2,30]},{18:[2,33],33:[2,33]},{18:[2,40],28:[2,40],29:[2,40],30:[2,40],33:[2,40],34:[1,57],36:[2,40]},{33:[1,58]},{14:[2,13],15:[2,13],16:[2,13],19:[2,13],20:[2,13],22:[2,13],23:[2,13],24:[2,13]},{5:[2,16],14:[2,16],15:[2,16],16:[2,16],19:[2,16],20:[2,16],22:[2,16],23:[2,16],24:[2,16]},{5:[2,17],14:[2,17],15:[2,17],16:[2,17],19:[2,17],20:[2,17],22:[2,17],23:[2,17],24:[2,17]},{5:[2,18],14:[2,18],15:[2,18],16:[2,18],19:[2,18],20:[2,18],22:[2,18],23:[2,18],24:[2,18]},{18:[1,59]},{18:[1,60]},{18:[2,21]},{18:[2,25],28:[2,25],29:[2,25],30:[2,25],33:[2,25]},{18:[2,32],33:[2,32]},{34:[1,57]},{21:61,28:[1,62],29:[1,63],30:[1,64],33:[1,25],35:24},{18:[2,39],28:[2,39],29:[2,39],30:[2,39],33:[2,39],36:[2,39]},{5:[2,19],14:[2,19],15:[2,19],16:[2,19],19:[2,19],20:[2,19],22:[2,19],23:[2,19],24:[2,19]},{5:[2,15],14:[2,15],15:[2,15],16:[2,15],19:[2,15],20:[2,15],22:[2,15],23:[2,15],24:[2,15]},{18:[2,34],33:[2,34]},{18:[2,35],33:[2,35]},{18:[2,36],33:[2,36]},{18:[2,37],33:[2,37]}],
+defaultActions: {16:[2,1],37:[2,23],53:[2,21]},
+parseError: function parseError(str, hash) {
+ throw new Error(str);
+},
+parse: function parse(input) {
+ var self = this, stack = [0], vstack = [null], lstack = [], table = this.table, yytext = "", yylineno = 0, yyleng = 0, recovering = 0, TERROR = 2, EOF = 1;
+ this.lexer.setInput(input);
+ this.lexer.yy = this.yy;
+ this.yy.lexer = this.lexer;
+ if (typeof this.lexer.yylloc == "undefined")
+ this.lexer.yylloc = {};
+ var yyloc = this.lexer.yylloc;
+ lstack.push(yyloc);
+ if (typeof this.yy.parseError === "function")
+ this.parseError = this.yy.parseError;
+ function popStack(n) {
+ stack.length = stack.length - 2 * n;
+ vstack.length = vstack.length - n;
+ lstack.length = lstack.length - n;
+ }
+ function lex() {
+ var token;
+ token = self.lexer.lex() || 1;
+ if (typeof token !== "number") {
+ token = self.symbols_[token] || token;
+ }
+ return token;
+ }
+ var symbol, preErrorSymbol, state, action, a, r, yyval = {}, p, len, newState, expected;
+ while (true) {
+ state = stack[stack.length - 1];
+ if (this.defaultActions[state]) {
+ action = this.defaultActions[state];
+ } else {
+ if (symbol == null)
+ symbol = lex();
+ action = table[state] && table[state][symbol];
+ }
+ if (typeof action === "undefined" || !action.length || !action[0]) {
+ if (!recovering) {
+ expected = [];
+ for (p in table[state])
+ if (this.terminals_[p] && p > 2) {
+ expected.push("'" + this.terminals_[p] + "'");
+ }
+ var errStr = "";
+ if (this.lexer.showPosition) {
+ errStr = "Parse error on line " + (yylineno + 1) + ":\n" + this.lexer.showPosition() + "\nExpecting " + expected.join(", ") + ", got '" + this.terminals_[symbol] + "'";
+ } else {
+ errStr = "Parse error on line " + (yylineno + 1) + ": Unexpected " + (symbol == 1?"end of input":"'" + (this.terminals_[symbol] || symbol) + "'");
+ }
+ this.parseError(errStr, {text: this.lexer.match, token: this.terminals_[symbol] || symbol, line: this.lexer.yylineno, loc: yyloc, expected: expected});
+ }
+ }
+ if (action[0] instanceof Array && action.length > 1) {
+ throw new Error("Parse Error: multiple actions possible at state: " + state + ", token: " + symbol);
+ }
+ switch (action[0]) {
+ case 1:
+ stack.push(symbol);
+ vstack.push(this.lexer.yytext);
+ lstack.push(this.lexer.yylloc);
+ stack.push(action[1]);
+ symbol = null;
+ if (!preErrorSymbol) {
+ yyleng = this.lexer.yyleng;
+ yytext = this.lexer.yytext;
+ yylineno = this.lexer.yylineno;
+ yyloc = this.lexer.yylloc;
+ if (recovering > 0)
+ recovering--;
+ } else {
+ symbol = preErrorSymbol;
+ preErrorSymbol = null;
+ }
+ break;
+ case 2:
+ len = this.productions_[action[1]][1];
+ yyval.$ = vstack[vstack.length - len];
+ yyval._$ = {first_line: lstack[lstack.length - (len || 1)].first_line, last_line: lstack[lstack.length - 1].last_line, first_column: lstack[lstack.length - (len || 1)].first_column, last_column: lstack[lstack.length - 1].last_column};
+ r = this.performAction.call(yyval, yytext, yyleng, yylineno, this.yy, action[1], vstack, lstack);
+ if (typeof r !== "undefined") {
+ return r;
+ }
+ if (len) {
+ stack = stack.slice(0, -1 * len * 2);
+ vstack = vstack.slice(0, -1 * len);
+ lstack = lstack.slice(0, -1 * len);
+ }
+ stack.push(this.productions_[action[1]][0]);
+ vstack.push(yyval.$);
+ lstack.push(yyval._$);
+ newState = table[stack[stack.length - 2]][stack[stack.length - 1]];
+ stack.push(newState);
+ break;
+ case 3:
+ return true;
+ }
+ }
+ return true;
+}
+};/* Jison generated lexer */
+var lexer = (function(){
+
+var lexer = ({EOF:1,
+parseError:function parseError(str, hash) {
+ if (this.yy.parseError) {
+ this.yy.parseError(str, hash);
+ } else {
+ throw new Error(str);
+ }
+ },
+setInput:function (input) {
+ this._input = input;
+ this._more = this._less = this.done = false;
+ this.yylineno = this.yyleng = 0;
+ this.yytext = this.matched = this.match = '';
+ this.conditionStack = ['INITIAL'];
+ this.yylloc = {first_line:1,first_column:0,last_line:1,last_column:0};
+ return this;
+ },
+input:function () {
+ var ch = this._input[0];
+ this.yytext+=ch;
+ this.yyleng++;
+ this.match+=ch;
+ this.matched+=ch;
+ var lines = ch.match(/\n/);
+ if (lines) this.yylineno++;
+ this._input = this._input.slice(1);
+ return ch;
+ },
+unput:function (ch) {
+ this._input = ch + this._input;
+ return this;
+ },
+more:function () {
+ this._more = true;
+ return this;
+ },
+pastInput:function () {
+ var past = this.matched.substr(0, this.matched.length - this.match.length);
+ return (past.length > 20 ? '...':'') + past.substr(-20).replace(/\n/g, "");
+ },
+upcomingInput:function () {
+ var next = this.match;
+ if (next.length < 20) {
+ next += this._input.substr(0, 20-next.length);
+ }
+ return (next.substr(0,20)+(next.length > 20 ? '...':'')).replace(/\n/g, "");
+ },
+showPosition:function () {
+ var pre = this.pastInput();
+ var c = new Array(pre.length + 1).join("-");
+ return pre + this.upcomingInput() + "\n" + c+"^";
+ },
+next:function () {
+ if (this.done) {
+ return this.EOF;
+ }
+ if (!this._input) this.done = true;
+
+ var token,
+ match,
+ col,
+ lines;
+ if (!this._more) {
+ this.yytext = '';
+ this.match = '';
+ }
+ var rules = this._currentRules();
+ for (var i=0;i < rules.length; i++) {
+ match = this._input.match(this.rules[rules[i]]);
+ if (match) {
+ lines = match[0].match(/\n.*/g);
+ if (lines) this.yylineno += lines.length;
+ this.yylloc = {first_line: this.yylloc.last_line,
+ last_line: this.yylineno+1,
+ first_column: this.yylloc.last_column,
+ last_column: lines ? lines[lines.length-1].length-1 : this.yylloc.last_column + match[0].length}
+ this.yytext += match[0];
+ this.match += match[0];
+ this.matches = match;
+ this.yyleng = this.yytext.length;
+ this._more = false;
+ this._input = this._input.slice(match[0].length);
+ this.matched += match[0];
+ token = this.performAction.call(this, this.yy, this, rules[i],this.conditionStack[this.conditionStack.length-1]);
+ if (token) return token;
+ else return;
+ }
+ }
+ if (this._input === "") {
+ return this.EOF;
+ } else {
+ this.parseError('Lexical error on line '+(this.yylineno+1)+'. Unrecognized text.\n'+this.showPosition(),
+ {text: "", token: null, line: this.yylineno});
+ }
+ },
+lex:function lex() {
+ var r = this.next();
+ if (typeof r !== 'undefined') {
+ return r;
+ } else {
+ return this.lex();
+ }
+ },
+begin:function begin(condition) {
+ this.conditionStack.push(condition);
+ },
+popState:function popState() {
+ return this.conditionStack.pop();
+ },
+_currentRules:function _currentRules() {
+ return this.conditions[this.conditionStack[this.conditionStack.length-1]].rules;
+ },
+topState:function () {
+ return this.conditionStack[this.conditionStack.length-2];
+ },
+pushState:function begin(condition) {
+ this.begin(condition);
+ }});
+lexer.performAction = function anonymous(yy,yy_,$avoiding_name_collisions,YY_START) {
+
+var YYSTATE=YY_START
+switch($avoiding_name_collisions) {
+case 0:
+ if(yy_.yytext.slice(-1) !== "\\") this.begin("mu");
+ if(yy_.yytext.slice(-1) === "\\") yy_.yytext = yy_.yytext.substr(0,yy_.yyleng-1), this.begin("emu");
+ if(yy_.yytext) return 14;
+
+break;
+case 1: return 14;
+break;
+case 2: this.popState(); return 14;
+break;
+case 3: return 24;
+break;
+case 4: return 16;
+break;
+case 5: return 20;
+break;
+case 6: return 19;
+break;
+case 7: return 19;
+break;
+case 8: return 23;
+break;
+case 9: return 23;
+break;
+case 10: yy_.yytext = yy_.yytext.substr(3,yy_.yyleng-5); this.popState(); return 15;
+break;
+case 11: return 22;
+break;
+case 12: return 34;
+break;
+case 13: return 33;
+break;
+case 14: return 33;
+break;
+case 15: return 36;
+break;
+case 16: /*ignore whitespace*/
+break;
+case 17: this.popState(); return 18;
+break;
+case 18: this.popState(); return 18;
+break;
+case 19: yy_.yytext = yy_.yytext.substr(1,yy_.yyleng-2).replace(/\\"/g,'"'); return 28;
+break;
+case 20: return 30;
+break;
+case 21: return 30;
+break;
+case 22: return 29;
+break;
+case 23: return 33;
+break;
+case 24: yy_.yytext = yy_.yytext.substr(1, yy_.yyleng-2); return 33;
+break;
+case 25: return 'INVALID';
+break;
+case 26: return 5;
+break;
+}
+};
+lexer.rules = [/^[^\x00]*?(?=(\{\{))/,/^[^\x00]+/,/^[^\x00]{2,}?(?=(\{\{))/,/^\{\{>/,/^\{\{#/,/^\{\{\//,/^\{\{\^/,/^\{\{\s*else\b/,/^\{\{\{/,/^\{\{&/,/^\{\{![\s\S]*?\}\}/,/^\{\{/,/^=/,/^\.(?=[} ])/,/^\.\./,/^[\/.]/,/^\s+/,/^\}\}\}/,/^\}\}/,/^"(\\["]|[^"])*"/,/^true(?=[}\s])/,/^false(?=[}\s])/,/^[0-9]+(?=[}\s])/,/^[a-zA-Z0-9_$-]+(?=[=}\s\/.])/,/^\[[^\]]*\]/,/^./,/^$/];
+lexer.conditions = {"mu":{"rules":[3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26],"inclusive":false},"emu":{"rules":[2],"inclusive":false},"INITIAL":{"rules":[0,1,26],"inclusive":true}};return lexer;})()
+parser.lexer = lexer;
+return parser;
+})();
+if (typeof require !== 'undefined' && typeof exports !== 'undefined') {
+exports.parser = handlebars;
+exports.parse = function () { return handlebars.parse.apply(handlebars, arguments); }
+exports.main = function commonjsMain(args) {
+ if (!args[1])
+ throw new Error('Usage: '+args[0]+' FILE');
+ if (typeof process !== 'undefined') {
+ var source = require('fs').readFileSync(require('path').join(process.cwd(), args[1]), "utf8");
+ } else {
+ var cwd = require("file").path(require("file").cwd());
+ var source = cwd.join(args[1]).read({charset: "utf-8"});
+ }
+ return exports.parser.parse(source);
+}
+if (typeof module !== 'undefined' && require.main === module) {
+ exports.main(typeof process !== 'undefined' ? process.argv.slice(1) : require("system").args);
+}
+};
+;
+// lib/handlebars/compiler/base.js
+Handlebars.Parser = handlebars;
+
+Handlebars.parse = function(string) {
+ Handlebars.Parser.yy = Handlebars.AST;
+ return Handlebars.Parser.parse(string);
+};
+
+Handlebars.print = function(ast) {
+ return new Handlebars.PrintVisitor().accept(ast);
+};
+
+Handlebars.logger = {
+ DEBUG: 0, INFO: 1, WARN: 2, ERROR: 3, level: 3,
+
+ // override in the host environment
+ log: function(level, str) {}
+};
+
+Handlebars.log = function(level, str) { Handlebars.logger.log(level, str); };
+;
+// lib/handlebars/compiler/ast.js
+(function() {
+
+ Handlebars.AST = {};
+
+ Handlebars.AST.ProgramNode = function(statements, inverse) {
+ this.type = "program";
+ this.statements = statements;
+ if(inverse) { this.inverse = new Handlebars.AST.ProgramNode(inverse); }
+ };
+
+ Handlebars.AST.MustacheNode = function(params, hash, unescaped) {
+ this.type = "mustache";
+ this.id = params[0];
+ this.params = params.slice(1);
+ this.hash = hash;
+ this.escaped = !unescaped;
+ };
+
+ Handlebars.AST.PartialNode = function(id, context) {
+ this.type = "partial";
+
+ // TODO: disallow complex IDs
+
+ this.id = id;
+ this.context = context;
+ };
+
+ var verifyMatch = function(open, close) {
+ if(open.original !== close.original) {
+ throw new Handlebars.Exception(open.original + " doesn't match " + close.original);
+ }
+ };
+
+ Handlebars.AST.BlockNode = function(mustache, program, close) {
+ verifyMatch(mustache.id, close);
+ this.type = "block";
+ this.mustache = mustache;
+ this.program = program;
+ };
+
+ Handlebars.AST.InverseNode = function(mustache, program, close) {
+ verifyMatch(mustache.id, close);
+ this.type = "inverse";
+ this.mustache = mustache;
+ this.program = program;
+ };
+
+ Handlebars.AST.ContentNode = function(string) {
+ this.type = "content";
+ this.string = string;
+ };
+
+ Handlebars.AST.HashNode = function(pairs) {
+ this.type = "hash";
+ this.pairs = pairs;
+ };
+
+ Handlebars.AST.IdNode = function(parts) {
+ this.type = "ID";
+ this.original = parts.join(".");
+
+ var dig = [], depth = 0;
+
+ for(var i=0,l=parts.length; i<l; i++) {
+ var part = parts[i];
+
+ if(part === "..") { depth++; }
+ else if(part === "." || part === "this") { this.isScoped = true; }
+ else { dig.push(part); }
+ }
+
+ this.parts = dig;
+ this.string = dig.join('.');
+ this.depth = depth;
+ this.isSimple = (dig.length === 1) && (depth === 0);
+ };
+
+ Handlebars.AST.StringNode = function(string) {
+ this.type = "STRING";
+ this.string = string;
+ };
+
+ Handlebars.AST.IntegerNode = function(integer) {
+ this.type = "INTEGER";
+ this.integer = integer;
+ };
+
+ Handlebars.AST.BooleanNode = function(bool) {
+ this.type = "BOOLEAN";
+ this.bool = bool;
+ };
+
+ Handlebars.AST.CommentNode = function(comment) {
+ this.type = "comment";
+ this.comment = comment;
+ };
+
+})();;
+// lib/handlebars/utils.js
+Handlebars.Exception = function(message) {
+ var tmp = Error.prototype.constructor.apply(this, arguments);
+
+ for (var p in tmp) {
+ if (tmp.hasOwnProperty(p)) { this[p] = tmp[p]; }
+ }
+
+ this.message = tmp.message;
+};
+Handlebars.Exception.prototype = new Error;
+
+// Build out our basic SafeString type
+Handlebars.SafeString = function(string) {
+ this.string = string;
+};
+Handlebars.SafeString.prototype.toString = function() {
+ return this.string.toString();
+};
+
+(function() {
+ var escape = {
+ "<": "<",
+ ">": ">",
+ '"': """,
+ "'": "'",
+ "`": "`"
+ };
+
+ var badChars = /&(?!\w+;)|[<>"'`]/g;
+ var possible = /[&<>"'`]/;
+
+ var escapeChar = function(chr) {
+ return escape[chr] || "&";
+ };
+
+ Handlebars.Utils = {
+ escapeExpression: function(string) {
+ // don't escape SafeStrings, since they're already safe
+ if (string instanceof Handlebars.SafeString) {
+ return string.toString();
+ } else if (string == null || string === false) {
+ return "";
+ }
+
+ if(!possible.test(string)) { return string; }
+ return string.replace(badChars, escapeChar);
+ },
+
+ isEmpty: function(value) {
+ if (typeof value === "undefined") {
+ return true;
+ } else if (value === null) {
+ return true;
+ } else if (value === false) {
+ return true;
+ } else if(Object.prototype.toString.call(value) === "[object Array]" && value.length === 0) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+ };
+})();;
+// lib/handlebars/compiler/compiler.js
+Handlebars.Compiler = function() {};
+Handlebars.JavaScriptCompiler = function() {};
+
+(function(Compiler, JavaScriptCompiler) {
+ Compiler.OPCODE_MAP = {
+ appendContent: 1,
+ getContext: 2,
+ lookupWithHelpers: 3,
+ lookup: 4,
+ append: 5,
+ invokeMustache: 6,
+ appendEscaped: 7,
+ pushString: 8,
+ truthyOrFallback: 9,
+ functionOrFallback: 10,
+ invokeProgram: 11,
+ invokePartial: 12,
+ push: 13,
+ assignToHash: 15,
+ pushStringParam: 16
+ };
+
+ Compiler.MULTI_PARAM_OPCODES = {
+ appendContent: 1,
+ getContext: 1,
+ lookupWithHelpers: 2,
+ lookup: 1,
+ invokeMustache: 3,
+ pushString: 1,
+ truthyOrFallback: 1,
+ functionOrFallback: 1,
+ invokeProgram: 3,
+ invokePartial: 1,
+ push: 1,
+ assignToHash: 1,
+ pushStringParam: 1
+ };
+
+ Compiler.DISASSEMBLE_MAP = {};
+
+ for(var prop in Compiler.OPCODE_MAP) {
+ var value = Compiler.OPCODE_MAP[prop];
+ Compiler.DISASSEMBLE_MAP[value] = prop;
+ }
+
+ Compiler.multiParamSize = function(code) {
+ return Compiler.MULTI_PARAM_OPCODES[Compiler.DISASSEMBLE_MAP[code]];
+ };
+
+ Compiler.prototype = {
+ compiler: Compiler,
+
+ disassemble: function() {
+ var opcodes = this.opcodes, opcode, nextCode;
+ var out = [], str, name, value;
+
+ for(var i=0, l=opcodes.length; i<l; i++) {
+ opcode = opcodes[i];
+
+ if(opcode === 'DECLARE') {
+ name = opcodes[++i];
+ value = opcodes[++i];
+ out.push("DECLARE " + name + " = " + value);
+ } else {
+ str = Compiler.DISASSEMBLE_MAP[opcode];
+
+ var extraParams = Compiler.multiParamSize(opcode);
+ var codes = [];
+
+ for(var j=0; j<extraParams; j++) {
+ nextCode = opcodes[++i];
+
+ if(typeof nextCode === "string") {
+ nextCode = "\"" + nextCode.replace("\n", "\\n") + "\"";
+ }
+
+ codes.push(nextCode);
+ }
+
+ str = str + " " + codes.join(" ");
+
+ out.push(str);
+ }
+ }
+
+ return out.join("\n");
+ },
+
+ guid: 0,
+
+ compile: function(program, options) {
+ this.children = [];
+ this.depths = {list: []};
+ this.options = options;
+
+ // These changes will propagate to the other compiler components
+ var knownHelpers = this.options.knownHelpers;
+ this.options.knownHelpers = {
+ 'helperMissing': true,
+ 'blockHelperMissing': true,
+ 'each': true,
+ 'if': true,
+ 'unless': true,
+ 'with': true,
+ 'log': true
+ };
+ if (knownHelpers) {
+ for (var name in knownHelpers) {
+ this.options.knownHelpers[name] = knownHelpers[name];
+ }
+ }
+
+ return this.program(program);
+ },
+
+ accept: function(node) {
+ return this[node.type](node);
+ },
+
+ program: function(program) {
+ var statements = program.statements, statement;
+ this.opcodes = [];
+
+ for(var i=0, l=statements.length; i<l; i++) {
+ statement = statements[i];
+ this[statement.type](statement);
+ }
+ this.isSimple = l === 1;
+
+ this.depths.list = this.depths.list.sort(function(a, b) {
+ return a - b;
+ });
+
+ return this;
+ },
+
+ compileProgram: function(program) {
+ var result = new this.compiler().compile(program, this.options);
+ var guid = this.guid++;
+
+ this.usePartial = this.usePartial || result.usePartial;
+
+ this.children[guid] = result;
+
+ for(var i=0, l=result.depths.list.length; i<l; i++) {
+ depth = result.depths.list[i];
+
+ if(depth < 2) { continue; }
+ else { this.addDepth(depth - 1); }
+ }
+
+ return guid;
+ },
+
+ block: function(block) {
+ var mustache = block.mustache;
+ var depth, child, inverse, inverseGuid;
+
+ var params = this.setupStackForMustache(mustache);
+
+ var programGuid = this.compileProgram(block.program);
+
+ if(block.program.inverse) {
+ inverseGuid = this.compileProgram(block.program.inverse);
+ this.declare('inverse', inverseGuid);
+ }
+
+ this.opcode('invokeProgram', programGuid, params.length, !!mustache.hash);
+ this.declare('inverse', null);
+ this.opcode('append');
+ },
+
+ inverse: function(block) {
+ var params = this.setupStackForMustache(block.mustache);
+
+ var programGuid = this.compileProgram(block.program);
+
+ this.declare('inverse', programGuid);
+
+ this.opcode('invokeProgram', null, params.length, !!block.mustache.hash);
+ this.declare('inverse', null);
+ this.opcode('append');
+ },
+
+ hash: function(hash) {
+ var pairs = hash.pairs, pair, val;
+
+ this.opcode('push', '{}');
+
+ for(var i=0, l=pairs.length; i<l; i++) {
+ pair = pairs[i];
+ val = pair[1];
+
+ this.accept(val);
+ this.opcode('assignToHash', pair[0]);
+ }
+ },
+
+ partial: function(partial) {
+ var id = partial.id;
+ this.usePartial = true;
+
+ if(partial.context) {
+ this.ID(partial.context);
+ } else {
+ this.opcode('push', 'depth0');
+ }
+
+ this.opcode('invokePartial', id.original);
+ this.opcode('append');
+ },
+
+ content: function(content) {
+ this.opcode('appendContent', content.string);
+ },
+
+ mustache: function(mustache) {
+ var params = this.setupStackForMustache(mustache);
+
+ this.opcode('invokeMustache', params.length, mustache.id.original, !!mustache.hash);
+
+ if(mustache.escaped && !this.options.noEscape) {
+ this.opcode('appendEscaped');
+ } else {
+ this.opcode('append');
+ }
+ },
+
+ ID: function(id) {
+ this.addDepth(id.depth);
+
+ this.opcode('getContext', id.depth);
+
+ this.opcode('lookupWithHelpers', id.parts[0] || null, id.isScoped || false);
+
+ for(var i=1, l=id.parts.length; i<l; i++) {
+ this.opcode('lookup', id.parts[i]);
+ }
+ },
+
+ STRING: function(string) {
+ this.opcode('pushString', string.string);
+ },
+
+ INTEGER: function(integer) {
+ this.opcode('push', integer.integer);
+ },
+
+ BOOLEAN: function(bool) {
+ this.opcode('push', bool.bool);
+ },
+
+ comment: function() {},
+
+ // HELPERS
+ pushParams: function(params) {
+ var i = params.length, param;
+
+ while(i--) {
+ param = params[i];
+
+ if(this.options.stringParams) {
+ if(param.depth) {
+ this.addDepth(param.depth);
+ }
+
+ this.opcode('getContext', param.depth || 0);
+ this.opcode('pushStringParam', param.string);
+ } else {
+ this[param.type](param);
+ }
+ }
+ },
+
+ opcode: function(name, val1, val2, val3) {
+ this.opcodes.push(Compiler.OPCODE_MAP[name]);
+ if(val1 !== undefined) { this.opcodes.push(val1); }
+ if(val2 !== undefined) { this.opcodes.push(val2); }
+ if(val3 !== undefined) { this.opcodes.push(val3); }
+ },
+
+ declare: function(name, value) {
+ this.opcodes.push('DECLARE');
+ this.opcodes.push(name);
+ this.opcodes.push(value);
+ },
+
+ addDepth: function(depth) {
+ if(depth === 0) { return; }
+
+ if(!this.depths[depth]) {
+ this.depths[depth] = true;
+ this.depths.list.push(depth);
+ }
+ },
+
+ setupStackForMustache: function(mustache) {
+ var params = mustache.params;
+
+ this.pushParams(params);
+
+ if(mustache.hash) {
+ this.hash(mustache.hash);
+ }
+
+ this.ID(mustache.id);
+
+ return params;
+ }
+ };
+
+ JavaScriptCompiler.prototype = {
+ // PUBLIC API: You can override these methods in a subclass to provide
+ // alternative compiled forms for name lookup and buffering semantics
+ nameLookup: function(parent, name, type) {
+ if (/^[0-9]+$/.test(name)) {
+ return parent + "[" + name + "]";
+ } else if (JavaScriptCompiler.isValidJavaScriptVariableName(name)) {
+ return parent + "." + name;
+ }
+ else {
+ return parent + "['" + name + "']";
+ }
+ },
+
+ appendToBuffer: function(string) {
+ if (this.environment.isSimple) {
+ return "return " + string + ";";
+ } else {
+ return "buffer += " + string + ";";
+ }
+ },
+
+ initializeBuffer: function() {
+ return this.quotedString("");
+ },
+
+ namespace: "Handlebars",
+ // END PUBLIC API
+
+ compile: function(environment, options, context, asObject) {
+ this.environment = environment;
+ this.options = options || {};
+
+ this.name = this.environment.name;
+ this.isChild = !!context;
+ this.context = context || {
+ programs: [],
+ aliases: { self: 'this' },
+ registers: {list: []}
+ };
+
+ this.preamble();
+
+ this.stackSlot = 0;
+ this.stackVars = [];
+
+ this.compileChildren(environment, options);
+
+ var opcodes = environment.opcodes, opcode;
+
+ this.i = 0;
+
+ for(l=opcodes.length; this.i<l; this.i++) {
+ opcode = this.nextOpcode(0);
+
+ if(opcode[0] === 'DECLARE') {
+ this.i = this.i + 2;
+ this[opcode[1]] = opcode[2];
+ } else {
+ this.i = this.i + opcode[1].length;
+ this[opcode[0]].apply(this, opcode[1]);
+ }
+ }
+
+ return this.createFunctionContext(asObject);
+ },
+
+ nextOpcode: function(n) {
+ var opcodes = this.environment.opcodes, opcode = opcodes[this.i + n], name, val;
+ var extraParams, codes;
+
+ if(opcode === 'DECLARE') {
+ name = opcodes[this.i + 1];
+ val = opcodes[this.i + 2];
+ return ['DECLARE', name, val];
+ } else {
+ name = Compiler.DISASSEMBLE_MAP[opcode];
+
+ extraParams = Compiler.multiParamSize(opcode);
+ codes = [];
+
+ for(var j=0; j<extraParams; j++) {
+ codes.push(opcodes[this.i + j + 1 + n]);
+ }
+
+ return [name, codes];
+ }
+ },
+
+ eat: function(opcode) {
+ this.i = this.i + opcode.length;
+ },
+
+ preamble: function() {
+ var out = [];
+
+ // this register will disambiguate helper lookup from finding a function in
+ // a context. This is necessary for mustache compatibility, which requires
+ // that context functions in blocks are evaluated by blockHelperMissing, and
+ // then proceed as if the resulting value was provided to blockHelperMissing.
+ this.useRegister('foundHelper');
+
+ if (!this.isChild) {
+ var namespace = this.namespace;
+ var copies = "helpers = helpers || " + namespace + ".helpers;";
+ if(this.environment.usePartial) { copies = copies + " partials = partials || " + namespace + ".partials;"; }
+ out.push(copies);
+ } else {
+ out.push('');
+ }
+
+ if (!this.environment.isSimple) {
+ out.push(", buffer = " + this.initializeBuffer());
+ } else {
+ out.push("");
+ }
+
+ // track the last context pushed into place to allow skipping the
+ // getContext opcode when it would be a noop
+ this.lastContext = 0;
+ this.source = out;
+ },
+
+ createFunctionContext: function(asObject) {
+ var locals = this.stackVars;
+ if (!this.isChild) {
+ locals = locals.concat(this.context.registers.list);
+ }
+
+ if(locals.length > 0) {
+ this.source[1] = this.source[1] + ", " + locals.join(", ");
+ }
+
+ // Generate minimizer alias mappings
+ if (!this.isChild) {
+ var aliases = []
+ for (var alias in this.context.aliases) {
+ this.source[1] = this.source[1] + ', ' + alias + '=' + this.context.aliases[alias];
+ }
+ }
+
+ if (this.source[1]) {
+ this.source[1] = "var " + this.source[1].substring(2) + ";";
+ }
+
+ // Merge children
+ if (!this.isChild) {
+ this.source[1] += '\n' + this.context.programs.join('\n') + '\n';
+ }
+
+ if (!this.environment.isSimple) {
+ this.source.push("return buffer;");
+ }
+
+ var params = this.isChild ? ["depth0", "data"] : ["Handlebars", "depth0", "helpers", "partials", "data"];
+
+ for(var i=0, l=this.environment.depths.list.length; i<l; i++) {
+ params.push("depth" + this.environment.depths.list[i]);
+ }
+
+ if (asObject) {
+ params.push(this.source.join("\n "));
+
+ return Function.apply(this, params);
+ } else {
+ var functionSource = 'function ' + (this.name || '') + '(' + params.join(',') + ') {\n ' + this.source.join("\n ") + '}';
+ Handlebars.log(Handlebars.logger.DEBUG, functionSource + "\n\n");
+ return functionSource;
+ }
+ },
+
+ appendContent: function(content) {
+ this.source.push(this.appendToBuffer(this.quotedString(content)));
+ },
+
+ append: function() {
+ var local = this.popStack();
+ this.source.push("if(" + local + " || " + local + " === 0) { " + this.appendToBuffer(local) + " }");
+ if (this.environment.isSimple) {
+ this.source.push("else { " + this.appendToBuffer("''") + " }");
+ }
+ },
+
+ appendEscaped: function() {
+ var opcode = this.nextOpcode(1), extra = "";
+ this.context.aliases.escapeExpression = 'this.escapeExpression';
+
+ if(opcode[0] === 'appendContent') {
+ extra = " + " + this.quotedString(opcode[1][0]);
+ this.eat(opcode);
+ }
+
+ this.source.push(this.appendToBuffer("escapeExpression(" + this.popStack() + ")" + extra));
+ },
+
+ getContext: function(depth) {
+ if(this.lastContext !== depth) {
+ this.lastContext = depth;
+ }
+ },
+
+ lookupWithHelpers: function(name, isScoped) {
+ if(name) {
+ var topStack = this.nextStack();
+
+ this.usingKnownHelper = false;
+
+ var toPush;
+ if (!isScoped && this.options.knownHelpers[name]) {
+ toPush = topStack + " = " + this.nameLookup('helpers', name, 'helper');
+ this.usingKnownHelper = true;
+ } else if (isScoped || this.options.knownHelpersOnly) {
+ toPush = topStack + " = " + this.nameLookup('depth' + this.lastContext, name, 'context');
+ } else {
+ this.register('foundHelper', this.nameLookup('helpers', name, 'helper'));
+ toPush = topStack + " = foundHelper || " + this.nameLookup('depth' + this.lastContext, name, 'context');
+ }
+
+ toPush += ';';
+ this.source.push(toPush);
+ } else {
+ this.pushStack('depth' + this.lastContext);
+ }
+ },
+
+ lookup: function(name) {
+ var topStack = this.topStack();
+ this.source.push(topStack + " = (" + topStack + " === null || " + topStack + " === undefined || " + topStack + " === false ? " +
+ topStack + " : " + this.nameLookup(topStack, name, 'context') + ");");
+ },
+
+ pushStringParam: function(string) {
+ this.pushStack('depth' + this.lastContext);
+ this.pushString(string);
+ },
+
+ pushString: function(string) {
+ this.pushStack(this.quotedString(string));
+ },
+
+ push: function(name) {
+ this.pushStack(name);
+ },
+
+ invokeMustache: function(paramSize, original, hasHash) {
+ this.populateParams(paramSize, this.quotedString(original), "{}", null, hasHash, function(nextStack, helperMissingString, id) {
+ if (!this.usingKnownHelper) {
+ this.context.aliases.helperMissing = 'helpers.helperMissing';
+ this.context.aliases.undef = 'void 0';
+ this.source.push("else if(" + id + "=== undef) { " + nextStack + " = helperMissing.call(" + helperMissingString + "); }");
+ if (nextStack !== id) {
+ this.source.push("else { " + nextStack + " = " + id + "; }");
+ }
+ }
+ });
+ },
+
+ invokeProgram: function(guid, paramSize, hasHash) {
+ var inverse = this.programExpression(this.inverse);
+ var mainProgram = this.programExpression(guid);
+
+ this.populateParams(paramSize, null, mainProgram, inverse, hasHash, function(nextStack, helperMissingString, id) {
+ if (!this.usingKnownHelper) {
+ this.context.aliases.blockHelperMissing = 'helpers.blockHelperMissing';
+ this.source.push("else { " + nextStack + " = blockHelperMissing.call(" + helperMissingString + "); }");
+ }
+ });
+ },
+
+ populateParams: function(paramSize, helperId, program, inverse, hasHash, fn) {
+ var needsRegister = hasHash || this.options.stringParams || inverse || this.options.data;
+ var id = this.popStack(), nextStack;
+ var params = [], param, stringParam, stringOptions;
+
+ if (needsRegister) {
+ this.register('tmp1', program);
+ stringOptions = 'tmp1';
+ } else {
+ stringOptions = '{ hash: {} }';
+ }
+
+ if (needsRegister) {
+ var hash = (hasHash ? this.popStack() : '{}');
+ this.source.push('tmp1.hash = ' + hash + ';');
+ }
+
+ if(this.options.stringParams) {
+ this.source.push('tmp1.contexts = [];');
+ }
+
+ for(var i=0; i<paramSize; i++) {
+ param = this.popStack();
+ params.push(param);
+
+ if(this.options.stringParams) {
+ this.source.push('tmp1.contexts.push(' + this.popStack() + ');');
+ }
+ }
+
+ if(inverse) {
+ this.source.push('tmp1.fn = tmp1;');
+ this.source.push('tmp1.inverse = ' + inverse + ';');
+ }
+
+ if(this.options.data) {
+ this.source.push('tmp1.data = data;');
+ }
+
+ params.push(stringOptions);
+
+ this.populateCall(params, id, helperId || id, fn, program !== '{}');
+ },
+
+ populateCall: function(params, id, helperId, fn, program) {
+ var paramString = ["depth0"].concat(params).join(", ");
+ var helperMissingString = ["depth0"].concat(helperId).concat(params).join(", ");
+
+ var nextStack = this.nextStack();
+
+ if (this.usingKnownHelper) {
+ this.source.push(nextStack + " = " + id + ".call(" + paramString + ");");
+ } else {
+ this.context.aliases.functionType = '"function"';
+ var condition = program ? "foundHelper && " : ""
+ this.source.push("if(" + condition + "typeof " + id + " === functionType) { " + nextStack + " = " + id + ".call(" + paramString + "); }");
+ }
+ fn.call(this, nextStack, helperMissingString, id);
+ this.usingKnownHelper = false;
+ },
+
+ invokePartial: function(context) {
+ params = [this.nameLookup('partials', context, 'partial'), "'" + context + "'", this.popStack(), "helpers", "partials"];
+
+ if (this.options.data) {
+ params.push("data");
+ }
+
+ this.pushStack("self.invokePartial(" + params.join(", ") + ");");
+ },
+
+ assignToHash: function(key) {
+ var value = this.popStack();
+ var hash = this.topStack();
+
+ this.source.push(hash + "['" + key + "'] = " + value + ";");
+ },
+
+ // HELPERS
+
+ compiler: JavaScriptCompiler,
+
+ compileChildren: function(environment, options) {
+ var children = environment.children, child, compiler;
+
+ for(var i=0, l=children.length; i<l; i++) {
+ child = children[i];
+ compiler = new this.compiler();
+
+ this.context.programs.push(''); // Placeholder to prevent name conflicts for nested children
+ var index = this.context.programs.length;
+ child.index = index;
+ child.name = 'program' + index;
+ this.context.programs[index] = compiler.compile(child, options, this.context);
+ }
+ },
+
+ programExpression: function(guid) {
+ if(guid == null) { return "self.noop"; }
+
+ var child = this.environment.children[guid],
+ depths = child.depths.list;
+ var programParams = [child.index, child.name, "data"];
+
+ for(var i=0, l = depths.length; i<l; i++) {
+ depth = depths[i];
+
+ if(depth === 1) { programParams.push("depth0"); }
+ else { programParams.push("depth" + (depth - 1)); }
+ }
+
+ if(depths.length === 0) {
+ return "self.program(" + programParams.join(", ") + ")";
+ } else {
+ programParams.shift();
+ return "self.programWithDepth(" + programParams.join(", ") + ")";
+ }
+ },
+
+ register: function(name, val) {
+ this.useRegister(name);
+ this.source.push(name + " = " + val + ";");
+ },
+
+ useRegister: function(name) {
+ if(!this.context.registers[name]) {
+ this.context.registers[name] = true;
+ this.context.registers.list.push(name);
+ }
+ },
+
+ pushStack: function(item) {
+ this.source.push(this.nextStack() + " = " + item + ";");
+ return "stack" + this.stackSlot;
+ },
+
+ nextStack: function() {
+ this.stackSlot++;
+ if(this.stackSlot > this.stackVars.length) { this.stackVars.push("stack" + this.stackSlot); }
+ return "stack" + this.stackSlot;
+ },
+
+ popStack: function() {
+ return "stack" + this.stackSlot--;
+ },
+
+ topStack: function() {
+ return "stack" + this.stackSlot;
+ },
+
+ quotedString: function(str) {
+ return '"' + str
+ .replace(/\\/g, '\\\\')
+ .replace(/"/g, '\\"')
+ .replace(/\n/g, '\\n')
+ .replace(/\r/g, '\\r') + '"';
+ }
+ };
+
+ var reservedWords = (
+ "break else new var" +
+ " case finally return void" +
+ " catch for switch while" +
+ " continue function this with" +
+ " default if throw" +
+ " delete in try" +
+ " do instanceof typeof" +
+ " abstract enum int short" +
+ " boolean export interface static" +
+ " byte extends long super" +
+ " char final native synchronized" +
+ " class float package throws" +
+ " const goto private transient" +
+ " debugger implements protected volatile" +
+ " double import public let yield"
+ ).split(" ");
+
+ var compilerWords = JavaScriptCompiler.RESERVED_WORDS = {};
+
+ for(var i=0, l=reservedWords.length; i<l; i++) {
+ compilerWords[reservedWords[i]] = true;
+ }
+
+ JavaScriptCompiler.isValidJavaScriptVariableName = function(name) {
+ if(!JavaScriptCompiler.RESERVED_WORDS[name] && /^[a-zA-Z_$][0-9a-zA-Z_$]+$/.test(name)) {
+ return true;
+ }
+ return false;
+ }
+
+})(Handlebars.Compiler, Handlebars.JavaScriptCompiler);
+
+Handlebars.precompile = function(string, options) {
+ options = options || {};
+
+ var ast = Handlebars.parse(string);
+ var environment = new Handlebars.Compiler().compile(ast, options);
+ return new Handlebars.JavaScriptCompiler().compile(environment, options);
+};
+
+Handlebars.compile = function(string, options) {
+ options = options || {};
+
+ var compiled;
+ function compile() {
+ var ast = Handlebars.parse(string);
+ var environment = new Handlebars.Compiler().compile(ast, options);
+ var templateSpec = new Handlebars.JavaScriptCompiler().compile(environment, options, undefined, true);
+ return Handlebars.template(templateSpec);
+ }
+
+ // Template is only compiled on first use and cached after that point.
+ return function(context, options) {
+ if (!compiled) {
+ compiled = compile();
+ }
+ return compiled.call(this, context, options);
+ };
+};
+;
+// lib/handlebars/runtime.js
+Handlebars.VM = {
+ template: function(templateSpec) {
+ // Just add water
+ var container = {
+ escapeExpression: Handlebars.Utils.escapeExpression,
+ invokePartial: Handlebars.VM.invokePartial,
+ programs: [],
+ program: function(i, fn, data) {
+ var programWrapper = this.programs[i];
+ if(data) {
+ return Handlebars.VM.program(fn, data);
+ } else if(programWrapper) {
+ return programWrapper;
+ } else {
+ programWrapper = this.programs[i] = Handlebars.VM.program(fn);
+ return programWrapper;
+ }
+ },
+ programWithDepth: Handlebars.VM.programWithDepth,
+ noop: Handlebars.VM.noop
+ };
+
+ return function(context, options) {
+ options = options || {};
+ return templateSpec.call(container, Handlebars, context, options.helpers, options.partials, options.data);
+ };
+ },
+
+ programWithDepth: function(fn, data, $depth) {
+ var args = Array.prototype.slice.call(arguments, 2);
+
+ return function(context, options) {
+ options = options || {};
+
+ return fn.apply(this, [context, options.data || data].concat(args));
+ };
+ },
+ program: function(fn, data) {
+ return function(context, options) {
+ options = options || {};
+
+ return fn(context, options.data || data);
+ };
+ },
+ noop: function() { return ""; },
+ invokePartial: function(partial, name, context, helpers, partials, data) {
+ options = { helpers: helpers, partials: partials, data: data };
+
+ if(partial === undefined) {
+ throw new Handlebars.Exception("The partial " + name + " could not be found");
+ } else if(partial instanceof Function) {
+ return partial(context, options);
+ } else if (!Handlebars.compile) {
+ throw new Handlebars.Exception("The partial " + name + " could not be compiled when running in runtime-only mode");
+ } else {
+ partials[name] = Handlebars.compile(partial);
+ return partials[name](context, options);
+ }
+ }
+};
+
+Handlebars.template = Handlebars.VM.template;
+;
diff -r cb5ff5b1bd67ca6333d808beefab24beedfeed94 -r 70397647fad54c50213e015aaedfed94e6b19eda static/scripts/libs/underscore.js
--- /dev/null
+++ b/static/scripts/libs/underscore.js
@@ -0,0 +1,999 @@
+// Underscore.js 1.3.1
+// (c) 2009-2012 Jeremy Ashkenas, DocumentCloud Inc.
+// Underscore is freely distributable under the MIT license.
+// Portions of Underscore are inspired or borrowed from Prototype,
+// Oliver Steele's Functional, and John Resig's Micro-Templating.
+// For all details and documentation:
+// http://documentcloud.github.com/underscore
+
+(function() {
+
+ // Baseline setup
+ // --------------
+
+ // Establish the root object, `window` in the browser, or `global` on the server.
+ var root = this;
+
+ // Save the previous value of the `_` variable.
+ var previousUnderscore = root._;
+
+ // Establish the object that gets returned to break out of a loop iteration.
+ var breaker = {};
+
+ // Save bytes in the minified (but not gzipped) version:
+ var ArrayProto = Array.prototype, ObjProto = Object.prototype, FuncProto = Function.prototype;
+
+ // Create quick reference variables for speed access to core prototypes.
+ var slice = ArrayProto.slice,
+ unshift = ArrayProto.unshift,
+ toString = ObjProto.toString,
+ hasOwnProperty = ObjProto.hasOwnProperty;
+
+ // All **ECMAScript 5** native function implementations that we hope to use
+ // are declared here.
+ var
+ nativeForEach = ArrayProto.forEach,
+ nativeMap = ArrayProto.map,
+ nativeReduce = ArrayProto.reduce,
+ nativeReduceRight = ArrayProto.reduceRight,
+ nativeFilter = ArrayProto.filter,
+ nativeEvery = ArrayProto.every,
+ nativeSome = ArrayProto.some,
+ nativeIndexOf = ArrayProto.indexOf,
+ nativeLastIndexOf = ArrayProto.lastIndexOf,
+ nativeIsArray = Array.isArray,
+ nativeKeys = Object.keys,
+ nativeBind = FuncProto.bind;
+
+ // Create a safe reference to the Underscore object for use below.
+ var _ = function(obj) { return new wrapper(obj); };
+
+ // Export the Underscore object for **Node.js**, with
+ // backwards-compatibility for the old `require()` API. If we're in
+ // the browser, add `_` as a global object via a string identifier,
+ // for Closure Compiler "advanced" mode.
+ if (typeof exports !== 'undefined') {
+ if (typeof module !== 'undefined' && module.exports) {
+ exports = module.exports = _;
+ }
+ exports._ = _;
+ } else {
+ root['_'] = _;
+ }
+
+ // Current version.
+ _.VERSION = '1.3.1';
+
+ // Collection Functions
+ // --------------------
+
+ // The cornerstone, an `each` implementation, aka `forEach`.
+ // Handles objects with the built-in `forEach`, arrays, and raw objects.
+ // Delegates to **ECMAScript 5**'s native `forEach` if available.
+ var each = _.each = _.forEach = function(obj, iterator, context) {
+ if (obj == null) return;
+ if (nativeForEach && obj.forEach === nativeForEach) {
+ obj.forEach(iterator, context);
+ } else if (obj.length === +obj.length) {
+ for (var i = 0, l = obj.length; i < l; i++) {
+ if (i in obj && iterator.call(context, obj[i], i, obj) === breaker) return;
+ }
+ } else {
+ for (var key in obj) {
+ if (_.has(obj, key)) {
+ if (iterator.call(context, obj[key], key, obj) === breaker) return;
+ }
+ }
+ }
+ };
+
+ // Return the results of applying the iterator to each element.
+ // Delegates to **ECMAScript 5**'s native `map` if available.
+ _.map = _.collect = function(obj, iterator, context) {
+ var results = [];
+ if (obj == null) return results;
+ if (nativeMap && obj.map === nativeMap) return obj.map(iterator, context);
+ each(obj, function(value, index, list) {
+ results[results.length] = iterator.call(context, value, index, list);
+ });
+ if (obj.length === +obj.length) results.length = obj.length;
+ return results;
+ };
+
+ // **Reduce** builds up a single result from a list of values, aka `inject`,
+ // or `foldl`. Delegates to **ECMAScript 5**'s native `reduce` if available.
+ _.reduce = _.foldl = _.inject = function(obj, iterator, memo, context) {
+ var initial = arguments.length > 2;
+ if (obj == null) obj = [];
+ if (nativeReduce && obj.reduce === nativeReduce) {
+ if (context) iterator = _.bind(iterator, context);
+ return initial ? obj.reduce(iterator, memo) : obj.reduce(iterator);
+ }
+ each(obj, function(value, index, list) {
+ if (!initial) {
+ memo = value;
+ initial = true;
+ } else {
+ memo = iterator.call(context, memo, value, index, list);
+ }
+ });
+ if (!initial) throw new TypeError('Reduce of empty array with no initial value');
+ return memo;
+ };
+
+ // The right-associative version of reduce, also known as `foldr`.
+ // Delegates to **ECMAScript 5**'s native `reduceRight` if available.
+ _.reduceRight = _.foldr = function(obj, iterator, memo, context) {
+ var initial = arguments.length > 2;
+ if (obj == null) obj = [];
+ if (nativeReduceRight && obj.reduceRight === nativeReduceRight) {
+ if (context) iterator = _.bind(iterator, context);
+ return initial ? obj.reduceRight(iterator, memo) : obj.reduceRight(iterator);
+ }
+ var reversed = _.toArray(obj).reverse();
+ if (context && !initial) iterator = _.bind(iterator, context);
+ return initial ? _.reduce(reversed, iterator, memo, context) : _.reduce(reversed, iterator);
+ };
+
+ // Return the first value which passes a truth test. Aliased as `detect`.
+ _.find = _.detect = function(obj, iterator, context) {
+ var result;
+ any(obj, function(value, index, list) {
+ if (iterator.call(context, value, index, list)) {
+ result = value;
+ return true;
+ }
+ });
+ return result;
+ };
+
+ // Return all the elements that pass a truth test.
+ // Delegates to **ECMAScript 5**'s native `filter` if available.
+ // Aliased as `select`.
+ _.filter = _.select = function(obj, iterator, context) {
+ var results = [];
+ if (obj == null) return results;
+ if (nativeFilter && obj.filter === nativeFilter) return obj.filter(iterator, context);
+ each(obj, function(value, index, list) {
+ if (iterator.call(context, value, index, list)) results[results.length] = value;
+ });
+ return results;
+ };
+
+ // Return all the elements for which a truth test fails.
+ _.reject = function(obj, iterator, context) {
+ var results = [];
+ if (obj == null) return results;
+ each(obj, function(value, index, list) {
+ if (!iterator.call(context, value, index, list)) results[results.length] = value;
+ });
+ return results;
+ };
+
+ // Determine whether all of the elements match a truth test.
+ // Delegates to **ECMAScript 5**'s native `every` if available.
+ // Aliased as `all`.
+ _.every = _.all = function(obj, iterator, context) {
+ var result = true;
+ if (obj == null) return result;
+ if (nativeEvery && obj.every === nativeEvery) return obj.every(iterator, context);
+ each(obj, function(value, index, list) {
+ if (!(result = result && iterator.call(context, value, index, list))) return breaker;
+ });
+ return result;
+ };
+
+ // Determine if at least one element in the object matches a truth test.
+ // Delegates to **ECMAScript 5**'s native `some` if available.
+ // Aliased as `any`.
+ var any = _.some = _.any = function(obj, iterator, context) {
+ iterator || (iterator = _.identity);
+ var result = false;
+ if (obj == null) return result;
+ if (nativeSome && obj.some === nativeSome) return obj.some(iterator, context);
+ each(obj, function(value, index, list) {
+ if (result || (result = iterator.call(context, value, index, list))) return breaker;
+ });
+ return !!result;
+ };
+
+ // Determine if a given value is included in the array or object using `===`.
+ // Aliased as `contains`.
+ _.include = _.contains = function(obj, target) {
+ var found = false;
+ if (obj == null) return found;
+ if (nativeIndexOf && obj.indexOf === nativeIndexOf) return obj.indexOf(target) != -1;
+ found = any(obj, function(value) {
+ return value === target;
+ });
+ return found;
+ };
+
+ // Invoke a method (with arguments) on every item in a collection.
+ _.invoke = function(obj, method) {
+ var args = slice.call(arguments, 2);
+ return _.map(obj, function(value) {
+ return (_.isFunction(method) ? method || value : value[method]).apply(value, args);
+ });
+ };
+
+ // Convenience version of a common use case of `map`: fetching a property.
+ _.pluck = function(obj, key) {
+ return _.map(obj, function(value){ return value[key]; });
+ };
+
+ // Return the maximum element or (element-based computation).
+ _.max = function(obj, iterator, context) {
+ if (!iterator && _.isArray(obj)) return Math.max.apply(Math, obj);
+ if (!iterator && _.isEmpty(obj)) return -Infinity;
+ var result = {computed : -Infinity};
+ each(obj, function(value, index, list) {
+ var computed = iterator ? iterator.call(context, value, index, list) : value;
+ computed >= result.computed && (result = {value : value, computed : computed});
+ });
+ return result.value;
+ };
+
+ // Return the minimum element (or element-based computation).
+ _.min = function(obj, iterator, context) {
+ if (!iterator && _.isArray(obj)) return Math.min.apply(Math, obj);
+ if (!iterator && _.isEmpty(obj)) return Infinity;
+ var result = {computed : Infinity};
+ each(obj, function(value, index, list) {
+ var computed = iterator ? iterator.call(context, value, index, list) : value;
+ computed < result.computed && (result = {value : value, computed : computed});
+ });
+ return result.value;
+ };
+
+ // Shuffle an array.
+ _.shuffle = function(obj) {
+ var shuffled = [], rand;
+ each(obj, function(value, index, list) {
+ if (index == 0) {
+ shuffled[0] = value;
+ } else {
+ rand = Math.floor(Math.random() * (index + 1));
+ shuffled[index] = shuffled[rand];
+ shuffled[rand] = value;
+ }
+ });
+ return shuffled;
+ };
+
+ // Sort the object's values by a criterion produced by an iterator.
+ _.sortBy = function(obj, iterator, context) {
+ return _.pluck(_.map(obj, function(value, index, list) {
+ return {
+ value : value,
+ criteria : iterator.call(context, value, index, list)
+ };
+ }).sort(function(left, right) {
+ var a = left.criteria, b = right.criteria;
+ return a < b ? -1 : a > b ? 1 : 0;
+ }), 'value');
+ };
+
+ // Groups the object's values by a criterion. Pass either a string attribute
+ // to group by, or a function that returns the criterion.
+ _.groupBy = function(obj, val) {
+ var result = {};
+ var iterator = _.isFunction(val) ? val : function(obj) { return obj[val]; };
+ each(obj, function(value, index) {
+ var key = iterator(value, index);
+ (result[key] || (result[key] = [])).push(value);
+ });
+ return result;
+ };
+
+ // Use a comparator function to figure out at what index an object should
+ // be inserted so as to maintain order. Uses binary search.
+ _.sortedIndex = function(array, obj, iterator) {
+ iterator || (iterator = _.identity);
+ var low = 0, high = array.length;
+ while (low < high) {
+ var mid = (low + high) >> 1;
+ iterator(array[mid]) < iterator(obj) ? low = mid + 1 : high = mid;
+ }
+ return low;
+ };
+
+ // Safely convert anything iterable into a real, live array.
+ _.toArray = function(iterable) {
+ if (!iterable) return [];
+ if (iterable.toArray) return iterable.toArray();
+ if (_.isArray(iterable)) return slice.call(iterable);
+ if (_.isArguments(iterable)) return slice.call(iterable);
+ return _.values(iterable);
+ };
+
+ // Return the number of elements in an object.
+ _.size = function(obj) {
+ return _.toArray(obj).length;
+ };
+
+ // Array Functions
+ // ---------------
+
+ // Get the first element of an array. Passing **n** will return the first N
+ // values in the array. Aliased as `head`. The **guard** check allows it to work
+ // with `_.map`.
+ _.first = _.head = function(array, n, guard) {
+ return (n != null) && !guard ? slice.call(array, 0, n) : array[0];
+ };
+
+ // Returns everything but the last entry of the array. Especcialy useful on
+ // the arguments object. Passing **n** will return all the values in
+ // the array, excluding the last N. The **guard** check allows it to work with
+ // `_.map`.
+ _.initial = function(array, n, guard) {
+ return slice.call(array, 0, array.length - ((n == null) || guard ? 1 : n));
+ };
+
+ // Get the last element of an array. Passing **n** will return the last N
+ // values in the array. The **guard** check allows it to work with `_.map`.
+ _.last = function(array, n, guard) {
+ if ((n != null) && !guard) {
+ return slice.call(array, Math.max(array.length - n, 0));
+ } else {
+ return array[array.length - 1];
+ }
+ };
+
+ // Returns everything but the first entry of the array. Aliased as `tail`.
+ // Especially useful on the arguments object. Passing an **index** will return
+ // the rest of the values in the array from that index onward. The **guard**
+ // check allows it to work with `_.map`.
+ _.rest = _.tail = function(array, index, guard) {
+ return slice.call(array, (index == null) || guard ? 1 : index);
+ };
+
+ // Trim out all falsy values from an array.
+ _.compact = function(array) {
+ return _.filter(array, function(value){ return !!value; });
+ };
+
+ // Return a completely flattened version of an array.
+ _.flatten = function(array, shallow) {
+ return _.reduce(array, function(memo, value) {
+ if (_.isArray(value)) return memo.concat(shallow ? value : _.flatten(value));
+ memo[memo.length] = value;
+ return memo;
+ }, []);
+ };
+
+ // Return a version of the array that does not contain the specified value(s).
+ _.without = function(array) {
+ return _.difference(array, slice.call(arguments, 1));
+ };
+
+ // Produce a duplicate-free version of the array. If the array has already
+ // been sorted, you have the option of using a faster algorithm.
+ // Aliased as `unique`.
+ _.uniq = _.unique = function(array, isSorted, iterator) {
+ var initial = iterator ? _.map(array, iterator) : array;
+ var result = [];
+ _.reduce(initial, function(memo, el, i) {
+ if (0 == i || (isSorted === true ? _.last(memo) != el : !_.include(memo, el))) {
+ memo[memo.length] = el;
+ result[result.length] = array[i];
+ }
+ return memo;
+ }, []);
+ return result;
+ };
+
+ // Produce an array that contains the union: each distinct element from all of
+ // the passed-in arrays.
+ _.union = function() {
+ return _.uniq(_.flatten(arguments, true));
+ };
+
+ // Produce an array that contains every item shared between all the
+ // passed-in arrays. (Aliased as "intersect" for back-compat.)
+ _.intersection = _.intersect = function(array) {
+ var rest = slice.call(arguments, 1);
+ return _.filter(_.uniq(array), function(item) {
+ return _.every(rest, function(other) {
+ return _.indexOf(other, item) >= 0;
+ });
+ });
+ };
+
+ // Take the difference between one array and a number of other arrays.
+ // Only the elements present in just the first array will remain.
+ _.difference = function(array) {
+ var rest = _.flatten(slice.call(arguments, 1));
+ return _.filter(array, function(value){ return !_.include(rest, value); });
+ };
+
+ // Zip together multiple lists into a single array -- elements that share
+ // an index go together.
+ _.zip = function() {
+ var args = slice.call(arguments);
+ var length = _.max(_.pluck(args, 'length'));
+ var results = new Array(length);
+ for (var i = 0; i < length; i++) results[i] = _.pluck(args, "" + i);
+ return results;
+ };
+
+ // If the browser doesn't supply us with indexOf (I'm looking at you, **MSIE**),
+ // we need this function. Return the position of the first occurrence of an
+ // item in an array, or -1 if the item is not included in the array.
+ // Delegates to **ECMAScript 5**'s native `indexOf` if available.
+ // If the array is large and already in sort order, pass `true`
+ // for **isSorted** to use binary search.
+ _.indexOf = function(array, item, isSorted) {
+ if (array == null) return -1;
+ var i, l;
+ if (isSorted) {
+ i = _.sortedIndex(array, item);
+ return array[i] === item ? i : -1;
+ }
+ if (nativeIndexOf && array.indexOf === nativeIndexOf) return array.indexOf(item);
+ for (i = 0, l = array.length; i < l; i++) if (i in array && array[i] === item) return i;
+ return -1;
+ };
+
+ // Delegates to **ECMAScript 5**'s native `lastIndexOf` if available.
+ _.lastIndexOf = function(array, item) {
+ if (array == null) return -1;
+ if (nativeLastIndexOf && array.lastIndexOf === nativeLastIndexOf) return array.lastIndexOf(item);
+ var i = array.length;
+ while (i--) if (i in array && array[i] === item) return i;
+ return -1;
+ };
+
+ // Generate an integer Array containing an arithmetic progression. A port of
+ // the native Python `range()` function. See
+ // [the Python documentation](http://docs.python.org/library/functions.html#range).
+ _.range = function(start, stop, step) {
+ if (arguments.length <= 1) {
+ stop = start || 0;
+ start = 0;
+ }
+ step = arguments[2] || 1;
+
+ var len = Math.max(Math.ceil((stop - start) / step), 0);
+ var idx = 0;
+ var range = new Array(len);
+
+ while(idx < len) {
+ range[idx++] = start;
+ start += step;
+ }
+
+ return range;
+ };
+
+ // Function (ahem) Functions
+ // ------------------
+
+ // Reusable constructor function for prototype setting.
+ var ctor = function(){};
+
+ // Create a function bound to a given object (assigning `this`, and arguments,
+ // optionally). Binding with arguments is also known as `curry`.
+ // Delegates to **ECMAScript 5**'s native `Function.bind` if available.
+ // We check for `func.bind` first, to fail fast when `func` is undefined.
+ _.bind = function bind(func, context) {
+ var bound, args;
+ if (func.bind === nativeBind && nativeBind) return nativeBind.apply(func, slice.call(arguments, 1));
+ if (!_.isFunction(func)) throw new TypeError;
+ args = slice.call(arguments, 2);
+ return bound = function() {
+ if (!(this instanceof bound)) return func.apply(context, args.concat(slice.call(arguments)));
+ ctor.prototype = func.prototype;
+ var self = new ctor;
+ var result = func.apply(self, args.concat(slice.call(arguments)));
+ if (Object(result) === result) return result;
+ return self;
+ };
+ };
+
+ // Bind all of an object's methods to that object. Useful for ensuring that
+ // all callbacks defined on an object belong to it.
+ _.bindAll = function(obj) {
+ var funcs = slice.call(arguments, 1);
+ if (funcs.length == 0) funcs = _.functions(obj);
+ each(funcs, function(f) { obj[f] = _.bind(obj[f], obj); });
+ return obj;
+ };
+
+ // Memoize an expensive function by storing its results.
+ _.memoize = function(func, hasher) {
+ var memo = {};
+ hasher || (hasher = _.identity);
+ return function() {
+ var key = hasher.apply(this, arguments);
+ return _.has(memo, key) ? memo[key] : (memo[key] = func.apply(this, arguments));
+ };
+ };
+
+ // Delays a function for the given number of milliseconds, and then calls
+ // it with the arguments supplied.
+ _.delay = function(func, wait) {
+ var args = slice.call(arguments, 2);
+ return setTimeout(function(){ return func.apply(func, args); }, wait);
+ };
+
+ // Defers a function, scheduling it to run after the current call stack has
+ // cleared.
+ _.defer = function(func) {
+ return _.delay.apply(_, [func, 1].concat(slice.call(arguments, 1)));
+ };
+
+ // Returns a function, that, when invoked, will only be triggered at most once
+ // during a given window of time.
+ _.throttle = function(func, wait) {
+ var context, args, timeout, throttling, more;
+ var whenDone = _.debounce(function(){ more = throttling = false; }, wait);
+ return function() {
+ context = this; args = arguments;
+ var later = function() {
+ timeout = null;
+ if (more) func.apply(context, args);
+ whenDone();
+ };
+ if (!timeout) timeout = setTimeout(later, wait);
+ if (throttling) {
+ more = true;
+ } else {
+ func.apply(context, args);
+ }
+ whenDone();
+ throttling = true;
+ };
+ };
+
+ // Returns a function, that, as long as it continues to be invoked, will not
+ // be triggered. The function will be called after it stops being called for
+ // N milliseconds.
+ _.debounce = function(func, wait) {
+ var timeout;
+ return function() {
+ var context = this, args = arguments;
+ var later = function() {
+ timeout = null;
+ func.apply(context, args);
+ };
+ clearTimeout(timeout);
+ timeout = setTimeout(later, wait);
+ };
+ };
+
+ // Returns a function that will be executed at most one time, no matter how
+ // often you call it. Useful for lazy initialization.
+ _.once = function(func) {
+ var ran = false, memo;
+ return function() {
+ if (ran) return memo;
+ ran = true;
+ return memo = func.apply(this, arguments);
+ };
+ };
+
+ // Returns the first function passed as an argument to the second,
+ // allowing you to adjust arguments, run code before and after, and
+ // conditionally execute the original function.
+ _.wrap = function(func, wrapper) {
+ return function() {
+ var args = [func].concat(slice.call(arguments, 0));
+ return wrapper.apply(this, args);
+ };
+ };
+
+ // Returns a function that is the composition of a list of functions, each
+ // consuming the return value of the function that follows.
+ _.compose = function() {
+ var funcs = arguments;
+ return function() {
+ var args = arguments;
+ for (var i = funcs.length - 1; i >= 0; i--) {
+ args = [funcs[i].apply(this, args)];
+ }
+ return args[0];
+ };
+ };
+
+ // Returns a function that will only be executed after being called N times.
+ _.after = function(times, func) {
+ if (times <= 0) return func();
+ return function() {
+ if (--times < 1) { return func.apply(this, arguments); }
+ };
+ };
+
+ // Object Functions
+ // ----------------
+
+ // Retrieve the names of an object's properties.
+ // Delegates to **ECMAScript 5**'s native `Object.keys`
+ _.keys = nativeKeys || function(obj) {
+ if (obj !== Object(obj)) throw new TypeError('Invalid object');
+ var keys = [];
+ for (var key in obj) if (_.has(obj, key)) keys[keys.length] = key;
+ return keys;
+ };
+
+ // Retrieve the values of an object's properties.
+ _.values = function(obj) {
+ return _.map(obj, _.identity);
+ };
+
+ // Return a sorted list of the function names available on the object.
+ // Aliased as `methods`
+ _.functions = _.methods = function(obj) {
+ var names = [];
+ for (var key in obj) {
+ if (_.isFunction(obj[key])) names.push(key);
+ }
+ return names.sort();
+ };
+
+ // Extend a given object with all the properties in passed-in object(s).
+ _.extend = function(obj) {
+ each(slice.call(arguments, 1), function(source) {
+ for (var prop in source) {
+ obj[prop] = source[prop];
+ }
+ });
+ return obj;
+ };
+
+ // Fill in a given object with default properties.
+ _.defaults = function(obj) {
+ each(slice.call(arguments, 1), function(source) {
+ for (var prop in source) {
+ if (obj[prop] == null) obj[prop] = source[prop];
+ }
+ });
+ return obj;
+ };
+
+ // Create a (shallow-cloned) duplicate of an object.
+ _.clone = function(obj) {
+ if (!_.isObject(obj)) return obj;
+ return _.isArray(obj) ? obj.slice() : _.extend({}, obj);
+ };
+
+ // Invokes interceptor with the obj, and then returns obj.
+ // The primary purpose of this method is to "tap into" a method chain, in
+ // order to perform operations on intermediate results within the chain.
+ _.tap = function(obj, interceptor) {
+ interceptor(obj);
+ return obj;
+ };
+
+ // Internal recursive comparison function.
+ function eq(a, b, stack) {
+ // Identical objects are equal. `0 === -0`, but they aren't identical.
+ // See the Harmony `egal` proposal: http://wiki.ecmascript.org/doku.php?id=harmony:egal.
+ if (a === b) return a !== 0 || 1 / a == 1 / b;
+ // A strict comparison is necessary because `null == undefined`.
+ if (a == null || b == null) return a === b;
+ // Unwrap any wrapped objects.
+ if (a._chain) a = a._wrapped;
+ if (b._chain) b = b._wrapped;
+ // Invoke a custom `isEqual` method if one is provided.
+ if (a.isEqual && _.isFunction(a.isEqual)) return a.isEqual(b);
+ if (b.isEqual && _.isFunction(b.isEqual)) return b.isEqual(a);
+ // Compare `[[Class]]` names.
+ var className = toString.call(a);
+ if (className != toString.call(b)) return false;
+ switch (className) {
+ // Strings, numbers, dates, and booleans are compared by value.
+ case '[object String]':
+ // Primitives and their corresponding object wrappers are equivalent; thus, `"5"` is
+ // equivalent to `new String("5")`.
+ return a == String(b);
+ case '[object Number]':
+ // `NaN`s are equivalent, but non-reflexive. An `egal` comparison is performed for
+ // other numeric values.
+ return a != +a ? b != +b : (a == 0 ? 1 / a == 1 / b : a == +b);
+ case '[object Date]':
+ case '[object Boolean]':
+ // Coerce dates and booleans to numeric primitive values. Dates are compared by their
+ // millisecond representations. Note that invalid dates with millisecond representations
+ // of `NaN` are not equivalent.
+ return +a == +b;
+ // RegExps are compared by their source patterns and flags.
+ case '[object RegExp]':
+ return a.source == b.source &&
+ a.global == b.global &&
+ a.multiline == b.multiline &&
+ a.ignoreCase == b.ignoreCase;
+ }
+ if (typeof a != 'object' || typeof b != 'object') return false;
+ // Assume equality for cyclic structures. The algorithm for detecting cyclic
+ // structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`.
+ var length = stack.length;
+ while (length--) {
+ // Linear search. Performance is inversely proportional to the number of
+ // unique nested structures.
+ if (stack[length] == a) return true;
+ }
+ // Add the first object to the stack of traversed objects.
+ stack.push(a);
+ var size = 0, result = true;
+ // Recursively compare objects and arrays.
+ if (className == '[object Array]') {
+ // Compare array lengths to determine if a deep comparison is necessary.
+ size = a.length;
+ result = size == b.length;
+ if (result) {
+ // Deep compare the contents, ignoring non-numeric properties.
+ while (size--) {
+ // Ensure commutative equality for sparse arrays.
+ if (!(result = size in a == size in b && eq(a[size], b[size], stack))) break;
+ }
+ }
+ } else {
+ // Objects with different constructors are not equivalent.
+ if ('constructor' in a != 'constructor' in b || a.constructor != b.constructor) return false;
+ // Deep compare objects.
+ for (var key in a) {
+ if (_.has(a, key)) {
+ // Count the expected number of properties.
+ size++;
+ // Deep compare each member.
+ if (!(result = _.has(b, key) && eq(a[key], b[key], stack))) break;
+ }
+ }
+ // Ensure that both objects contain the same number of properties.
+ if (result) {
+ for (key in b) {
+ if (_.has(b, key) && !(size--)) break;
+ }
+ result = !size;
+ }
+ }
+ // Remove the first object from the stack of traversed objects.
+ stack.pop();
+ return result;
+ }
+
+ // Perform a deep comparison to check if two objects are equal.
+ _.isEqual = function(a, b) {
+ return eq(a, b, []);
+ };
+
+ // Is a given array, string, or object empty?
+ // An "empty" object has no enumerable own-properties.
+ _.isEmpty = function(obj) {
+ if (_.isArray(obj) || _.isString(obj)) return obj.length === 0;
+ for (var key in obj) if (_.has(obj, key)) return false;
+ return true;
+ };
+
+ // Is a given value a DOM element?
+ _.isElement = function(obj) {
+ return !!(obj && obj.nodeType == 1);
+ };
+
+ // Is a given value an array?
+ // Delegates to ECMA5's native Array.isArray
+ _.isArray = nativeIsArray || function(obj) {
+ return toString.call(obj) == '[object Array]';
+ };
+
+ // Is a given variable an object?
+ _.isObject = function(obj) {
+ return obj === Object(obj);
+ };
+
+ // Is a given variable an arguments object?
+ _.isArguments = function(obj) {
+ return toString.call(obj) == '[object Arguments]';
+ };
+ if (!_.isArguments(arguments)) {
+ _.isArguments = function(obj) {
+ return !!(obj && _.has(obj, 'callee'));
+ };
+ }
+
+ // Is a given value a function?
+ _.isFunction = function(obj) {
+ return toString.call(obj) == '[object Function]';
+ };
+
+ // Is a given value a string?
+ _.isString = function(obj) {
+ return toString.call(obj) == '[object String]';
+ };
+
+ // Is a given value a number?
+ _.isNumber = function(obj) {
+ return toString.call(obj) == '[object Number]';
+ };
+
+ // Is the given value `NaN`?
+ _.isNaN = function(obj) {
+ // `NaN` is the only value for which `===` is not reflexive.
+ return obj !== obj;
+ };
+
+ // Is a given value a boolean?
+ _.isBoolean = function(obj) {
+ return obj === true || obj === false || toString.call(obj) == '[object Boolean]';
+ };
+
+ // Is a given value a date?
+ _.isDate = function(obj) {
+ return toString.call(obj) == '[object Date]';
+ };
+
+ // Is the given value a regular expression?
+ _.isRegExp = function(obj) {
+ return toString.call(obj) == '[object RegExp]';
+ };
+
+ // Is a given value equal to null?
+ _.isNull = function(obj) {
+ return obj === null;
+ };
+
+ // Is a given variable undefined?
+ _.isUndefined = function(obj) {
+ return obj === void 0;
+ };
+
+ // Has own property?
+ _.has = function(obj, key) {
+ return hasOwnProperty.call(obj, key);
+ };
+
+ // Utility Functions
+ // -----------------
+
+ // Run Underscore.js in *noConflict* mode, returning the `_` variable to its
+ // previous owner. Returns a reference to the Underscore object.
+ _.noConflict = function() {
+ root._ = previousUnderscore;
+ return this;
+ };
+
+ // Keep the identity function around for default iterators.
+ _.identity = function(value) {
+ return value;
+ };
+
+ // Run a function **n** times.
+ _.times = function (n, iterator, context) {
+ for (var i = 0; i < n; i++) iterator.call(context, i);
+ };
+
+ // Escape a string for HTML interpolation.
+ _.escape = function(string) {
+ return (''+string).replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"').replace(/'/g, ''').replace(/\//g,'/');
+ };
+
+ // Add your own custom functions to the Underscore object, ensuring that
+ // they're correctly added to the OOP wrapper as well.
+ _.mixin = function(obj) {
+ each(_.functions(obj), function(name){
+ addToWrapper(name, _[name] = obj[name]);
+ });
+ };
+
+ // Generate a unique integer id (unique within the entire client session).
+ // Useful for temporary DOM ids.
+ var idCounter = 0;
+ _.uniqueId = function(prefix) {
+ var id = idCounter++;
+ return prefix ? prefix + id : id;
+ };
+
+ // By default, Underscore uses ERB-style template delimiters, change the
+ // following template settings to use alternative delimiters.
+ _.templateSettings = {
+ evaluate : /<%([\s\S]+?)%>/g,
+ interpolate : /<%=([\s\S]+?)%>/g,
+ escape : /<%-([\s\S]+?)%>/g
+ };
+
+ // When customizing `templateSettings`, if you don't want to define an
+ // interpolation, evaluation or escaping regex, we need one that is
+ // guaranteed not to match.
+ var noMatch = /.^/;
+
+ // Within an interpolation, evaluation, or escaping, remove HTML escaping
+ // that had been previously added.
+ var unescape = function(code) {
+ return code.replace(/\\\\/g, '\\').replace(/\\'/g, "'");
+ };
+
+ // JavaScript micro-templating, similar to John Resig's implementation.
+ // Underscore templating handles arbitrary delimiters, preserves whitespace,
+ // and correctly escapes quotes within interpolated code.
+ _.template = function(str, data) {
+ var c = _.templateSettings;
+ var tmpl = 'var __p=[],print=function(){__p.push.apply(__p,arguments);};' +
+ 'with(obj||{}){__p.push(\'' +
+ str.replace(/\\/g, '\\\\')
+ .replace(/'/g, "\\'")
+ .replace(c.escape || noMatch, function(match, code) {
+ return "',_.escape(" + unescape(code) + "),'";
+ })
+ .replace(c.interpolate || noMatch, function(match, code) {
+ return "'," + unescape(code) + ",'";
+ })
+ .replace(c.evaluate || noMatch, function(match, code) {
+ return "');" + unescape(code).replace(/[\r\n\t]/g, ' ') + ";__p.push('";
+ })
+ .replace(/\r/g, '\\r')
+ .replace(/\n/g, '\\n')
+ .replace(/\t/g, '\\t')
+ + "');}return __p.join('');";
+ var func = new Function('obj', '_', tmpl);
+ if (data) return func(data, _);
+ return function(data) {
+ return func.call(this, data, _);
+ };
+ };
+
+ // Add a "chain" function, which will delegate to the wrapper.
+ _.chain = function(obj) {
+ return _(obj).chain();
+ };
+
+ // The OOP Wrapper
+ // ---------------
+
+ // If Underscore is called as a function, it returns a wrapped object that
+ // can be used OO-style. This wrapper holds altered versions of all the
+ // underscore functions. Wrapped objects may be chained.
+ var wrapper = function(obj) { this._wrapped = obj; };
+
+ // Expose `wrapper.prototype` as `_.prototype`
+ _.prototype = wrapper.prototype;
+
+ // Helper function to continue chaining intermediate results.
+ var result = function(obj, chain) {
+ return chain ? _(obj).chain() : obj;
+ };
+
+ // A method to easily add functions to the OOP wrapper.
+ var addToWrapper = function(name, func) {
+ wrapper.prototype[name] = function() {
+ var args = slice.call(arguments);
+ unshift.call(args, this._wrapped);
+ return result(func.apply(_, args), this._chain);
+ };
+ };
+
+ // Add all of the Underscore functions to the wrapper object.
+ _.mixin(_);
+
+ // Add all mutator Array functions to the wrapper.
+ each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) {
+ var method = ArrayProto[name];
+ wrapper.prototype[name] = function() {
+ var wrapped = this._wrapped;
+ method.apply(wrapped, arguments);
+ var length = wrapped.length;
+ if ((name == 'shift' || name == 'splice') && length === 0) delete wrapped[0];
+ return result(wrapped, this._chain);
+ };
+ });
+
+ // Add all accessor Array functions to the wrapper.
+ each(['concat', 'join', 'slice'], function(name) {
+ var method = ArrayProto[name];
+ wrapper.prototype[name] = function() {
+ return result(method.apply(this._wrapped, arguments), this._chain);
+ };
+ });
+
+ // Start chaining a wrapped Underscore object.
+ wrapper.prototype.chain = function() {
+ this._chain = true;
+ return this;
+ };
+
+ // Extracts the result from a wrapped and chained object.
+ wrapper.prototype.value = function() {
+ return this._wrapped;
+ };
+
+}).call(this);
diff -r cb5ff5b1bd67ca6333d808beefab24beedfeed94 -r 70397647fad54c50213e015aaedfed94e6b19eda static/scripts/pack_scripts.py
--- a/static/scripts/pack_scripts.py
+++ b/static/scripts/pack_scripts.py
@@ -20,6 +20,7 @@
to_pack = sys.argv[1:]
else:
to_pack = glob( "*.js" )
+ to_pack.extend( glob( "libs/*.js" ) )
for fname in to_pack:
d = dict( fname=fname )
diff -r cb5ff5b1bd67ca6333d808beefab24beedfeed94 -r 70397647fad54c50213e015aaedfed94e6b19eda static/scripts/packed/libs/backbone.js
--- /dev/null
+++ b/static/scripts/packed/libs/backbone.js
@@ -0,0 +1,1 @@
+(function(){var q=this;var o=q.Backbone;var p=Array.prototype.slice;var y=Array.prototype.splice;var c;if(typeof exports!=="undefined"){c=exports}else{c=q.Backbone={}}c.VERSION="0.9.2";var A=q._;if(!A&&(typeof require!=="undefined")){A=require("underscore")}var g=q.jQuery||q.Zepto||q.ender;c.setDomLibrary=function(C){g=C};c.noConflict=function(){q.Backbone=o;return this};c.emulateHTTP=false;c.emulateJSON=false;var a=/\s+/;var n=c.Events={on:function(F,J,E){var D,H,G,C,I;if(!J){return this}F=F.split(a);D=this._callbacks||(this._callbacks={});while(H=F.shift()){I=D[H];G=I?I.tail:{};G.next=C={};G.context=E;G.callback=J;D[H]={tail:C,next:I?I.next:G}}return this},off:function(J,H,D){var C,K,E,G,F,I;if(!(K=this._callbacks)){return}if(!(J||H||D)){delete this._callbacks;return this}J=J?J.split(a):A.keys(K);while(C=J.shift()){E=K[C];delete K[C];if(!E||!(H||D)){continue}G=E.tail;while((E=E.next)!==G){F=E.callback;I=E.context;if((H&&F!==H)||(D&&I!==D)){this.on(C,F,I)}}}return this},trigger:function(F){var J,I,E,D,C,H,G;if(!(E=this._callbacks)){return this}H=E.all;F=F.split(a);G=p.call(arguments,1);while(J=F.shift()){if(I=E[J]){D=I.tail;while((I=I.next)!==D){I.callback.apply(I.context||this,G)}}if(I=H){D=I.tail;C=[J].concat(G);while((I=I.next)!==D){I.callback.apply(I.context||this,C)}}}return this}};n.bind=n.on;n.unbind=n.off;var k=c.Model=function(C,D){var E;C||(C={});if(D&&D.parse){C=this.parse(C)}if(E=d(this,"defaults")){C=A.extend({},E,C)}if(D&&D.collection){this.collection=D.collection}this.attributes={};this._escapedAttributes={};this.cid=A.uniqueId("c");this.changed={};this._silent={};this._pending={};this.set(C,{silent:true});this.changed={};this._silent={};this._pending={};this._previousAttributes=A.clone(this.attributes);this.initialize.apply(this,arguments)};A.extend(k.prototype,n,{changed:null,_silent:null,_pending:null,idAttribute:"id",initialize:function(){},toJSON:function(C){return A.clone(this.attributes)},get:function(C){return this.attributes[C]},escape:function(C){var D;if(D=this._escapedAttributes[C]){return D}var E=this.get(C);return this._escapedAttributes[C]=A.escape(E==null?"":""+E)},has:function(C){return this.get(C)!=null},set:function(J,I,L){var K,G,E;if(A.isObject(J)||J==null){K=J;L=I}else{K={};K[J]=I}L||(L={});if(!K){return this}if(K instanceof k){K=K.attributes}if(L.unset){for(G in K){K[G]=void 0}}if(!this._validate(K,L)){return false}if(this.idAttribute in K){this.id=K[this.idAttribute]}var H=L.changes={};var D=this.attributes;var C=this._escapedAttributes;var F=this._previousAttributes||{};for(G in K){E=K[G];if(!A.isEqual(D[G],E)||(L.unset&&A.has(D,G))){delete C[G];(L.silent?this._silent:H)[G]=true}L.unset?delete D[G]:D[G]=E;if(!A.isEqual(F[G],E)||(A.has(D,G)!=A.has(F,G))){this.changed[G]=E;if(!L.silent){this._pending[G]=true}}else{delete this.changed[G];delete this._pending[G]}}if(!L.silent){this.change(L)}return this},unset:function(C,D){(D||(D={})).unset=true;return this.set(C,null,D)},clear:function(C){(C||(C={})).unset=true;return this.set(A.clone(this.attributes),C)},fetch:function(D){D=D?A.clone(D):{};var C=this;var E=D.success;D.success=function(H,F,G){if(!C.set(C.parse(H,G),D)){return false}if(E){E(C,H)}};D.error=c.wrapError(D.error,C,D);return(this.sync||c.sync).call(this,"read",this,D)},save:function(H,G,L){var I,F;if(A.isObject(H)||H==null){I=H;L=G}else{I={};I[H]=G}L=L?A.clone(L):{};if(L.wait){if(!this._validate(I,L)){return false}F=A.clone(this.attributes)}var D=A.extend({},L,{silent:true});if(I&&!this.set(I,L.wait?D:L)){return false}var E=this;var J=L.success;L.success=function(P,M,O){var N=E.parse(P,O);if(L.wait){delete L.wait;N=A.extend(I||{},N)}if(!E.set(N,L)){return false}if(J){J(E,P)}else{E.trigger("sync",E,P,L)}};L.error=c.wrapError(L.error,E,L);var C=this.isNew()?"create":"update";var K=(this.sync||c.sync).call(this,C,this,L);if(L.wait){this.set(F,D)}return K},destroy:function(D){D=D?A.clone(D):{};var C=this;var G=D.success;var F=function(){C.trigger("destroy",C,C.collection,D)};if(this.isNew()){F();return false}D.success=function(H){if(D.wait){F()}if(G){G(C,H)}else{C.trigger("sync",C,H,D)}};D.error=c.wrapError(D.error,C,D);var E=(this.sync||c.sync).call(this,"delete",this,D);if(!D.wait){F()}return E},url:function(){var C=d(this,"urlRoot")||d(this.collection,"url")||t();if(this.isNew()){return C}return C+(C.charAt(C.length-1)=="/"?"":"/")+encodeURIComponent(this.id)},parse:function(D,C){return D},clone:function(){return new this.constructor(this.attributes)},isNew:function(){return this.id==null},change:function(D){D||(D={});var F=this._changing;this._changing=true;for(var C in this._silent){this._pending[C]=true}var E=A.extend({},D.changes,this._silent);this._silent={};for(var C in E){this.trigger("change:"+C,this,this.get(C),D)}if(F){return this}while(!A.isEmpty(this._pending)){this._pending={};this.trigger("change",this,D);for(var C in this.changed){if(this._pending[C]||this._silent[C]){continue}delete this.changed[C]}this._previousAttributes=A.clone(this.attributes)}this._changing=false;return this},hasChanged:function(C){if(!arguments.length){return !A.isEmpty(this.changed)}return A.has(this.changed,C)},changedAttributes:function(E){if(!E){return this.hasChanged()?A.clone(this.changed):false}var G,F=false,D=this._previousAttributes;for(var C in E){if(A.isEqual(D[C],(G=E[C]))){continue}(F||(F={}))[C]=G}return F},previous:function(C){if(!arguments.length||!this._previousAttributes){return null}return this._previousAttributes[C]},previousAttributes:function(){return A.clone(this._previousAttributes)},isValid:function(){return !this.validate(this.attributes)},_validate:function(E,D){if(D.silent||!this.validate){return true}E=A.extend({},this.attributes,E);var C=this.validate(E,D);if(!C){return true}if(D&&D.error){D.error(this,C,D)}else{this.trigger("error",this,C,D)}return false}});var B=c.Collection=function(D,C){C||(C={});if(C.model){this.model=C.model}if(C.comparator){this.comparator=C.comparator}this._reset();this.initialize.apply(this,arguments);if(D){this.reset(D,{silent:true,parse:C.parse})}};A.extend(B.prototype,n,{model:k,initialize:function(){},toJSON:function(C){return this.map(function(D){return D.toJSON(C)})},add:function(D,M){var I,K,F,J,L,E,G={},C={},H=[];M||(M={});D=A.isArray(D)?D.slice():[D];for(I=0,F=D.length;I<F;I++){if(!(J=D[I]=this._prepareModel(D[I],M))){throw new Error("Can't add an invalid model to a collection")}L=J.cid;E=J.id;if(G[L]||this._byCid[L]||((E!=null)&&(C[E]||this._byId[E]))){H.push(I);continue}G[L]=C[E]=J}I=H.length;while(I--){D.splice(H[I],1)}for(I=0,F=D.length;I<F;I++){(J=D[I]).on("all",this._onModelEvent,this);this._byCid[J.cid]=J;if(J.id!=null){this._byId[J.id]=J}}this.length+=F;K=M.at!=null?M.at:this.models.length;y.apply(this.models,[K,0].concat(D));if(this.comparator){this.sort({silent:true})}if(M.silent){return this}for(I=0,F=this.models.length;I<F;I++){if(!G[(J=this.models[I]).cid]){continue}M.index=I;J.trigger("add",J,this,M)}return this},remove:function(H,F){var G,C,E,D;F||(F={});H=A.isArray(H)?H.slice():[H];for(G=0,C=H.length;G<C;G++){D=this.getByCid(H[G])||this.get(H[G]);if(!D){continue}delete this._byId[D.id];delete this._byCid[D.cid];E=this.indexOf(D);this.models.splice(E,1);this.length--;if(!F.silent){F.index=E;D.trigger("remove",D,this,F)}this._removeReference(D)}return this},push:function(D,C){D=this._prepareModel(D,C);this.add(D,C);return D},pop:function(D){var C=this.at(this.length-1);this.remove(C,D);return C},unshift:function(D,C){D=this._prepareModel(D,C);this.add(D,A.extend({at:0},C));return D},shift:function(D){var C=this.at(0);this.remove(C,D);return C},get:function(C){if(C==null){return void 0}return this._byId[C.id!=null?C.id:C]},getByCid:function(C){return C&&this._byCid[C.cid||C]},at:function(C){return this.models[C]},where:function(C){if(A.isEmpty(C)){return[]}return this.filter(function(D){for(var E in C){if(C[E]!==D.get(E)){return false}}return true})},sort:function(D){D||(D={});if(!this.comparator){throw new Error("Cannot sort a set without a comparator")}var C=A.bind(this.comparator,this);if(this.comparator.length==1){this.models=this.sortBy(C)}else{this.models.sort(C)}if(!D.silent){this.trigger("reset",this,D)}return this},pluck:function(C){return A.map(this.models,function(D){return D.get(C)})},reset:function(F,D){F||(F=[]);D||(D={});for(var E=0,C=this.models.length;E<C;E++){this._removeReference(this.models[E])}this._reset();this.add(F,A.extend({silent:true},D));if(!D.silent){this.trigger("reset",this,D)}return this},fetch:function(C){C=C?A.clone(C):{};if(C.parse===undefined){C.parse=true}var E=this;var D=C.success;C.success=function(H,F,G){E[C.add?"add":"reset"](E.parse(H,G),C);if(D){D(E,H)}};C.error=c.wrapError(C.error,E,C);return(this.sync||c.sync).call(this,"read",this,C)},create:function(D,C){var E=this;C=C?A.clone(C):{};D=this._prepareModel(D,C);if(!D){return false}if(!C.wait){E.add(D,C)}var F=C.success;C.success=function(G,I,H){if(C.wait){E.add(G,C)}if(F){F(G,I)}else{G.trigger("sync",D,I,C)}};D.save(null,C);return D},parse:function(D,C){return D},chain:function(){return A(this.models).chain()},_reset:function(C){this.length=0;this.models=[];this._byId={};this._byCid={}},_prepareModel:function(E,D){D||(D={});if(!(E instanceof k)){var C=E;D.collection=this;E=new this.model(C,D);if(!E._validate(E.attributes,D)){E=false}}else{if(!E.collection){E.collection=this}}return E},_removeReference:function(C){if(this==C.collection){delete C.collection}C.off("all",this._onModelEvent,this)},_onModelEvent:function(E,D,F,C){if((E=="add"||E=="remove")&&F!=this){return}if(E=="destroy"){this.remove(D,C)}if(D&&E==="change:"+D.idAttribute){delete this._byId[D.previous(D.idAttribute)];this._byId[D.id]=D}this.trigger.apply(this,arguments)}});var w=["forEach","each","map","reduce","reduceRight","find","detect","filter","select","reject","every","all","some","any","include","contains","invoke","max","min","sortBy","sortedIndex","toArray","size","first","initial","rest","last","without","indexOf","shuffle","lastIndexOf","isEmpty","groupBy"];A.each(w,function(C){B.prototype[C]=function(){return A[C].apply(A,[this.models].concat(A.toArray(arguments)))}});var z=c.Router=function(C){C||(C={});if(C.routes){this.routes=C.routes}this._bindRoutes();this.initialize.apply(this,arguments)};var i=/:\w+/g;var x=/\*\w+/g;var e=/[-[\]{}()+?.,\\^$|#\s]/g;A.extend(z.prototype,n,{initialize:function(){},route:function(C,D,E){c.history||(c.history=new b);if(!A.isRegExp(C)){C=this._routeToRegExp(C)}if(!E){E=this[D]}c.history.route(C,A.bind(function(G){var F=this._extractParameters(C,G);E&&E.apply(this,F);this.trigger.apply(this,["route:"+D].concat(F));c.history.trigger("route",this,D,F)},this));return this},navigate:function(D,C){c.history.navigate(D,C)},_bindRoutes:function(){if(!this.routes){return}var D=[];for(var E in this.routes){D.unshift([E,this.routes[E]])}for(var F=0,C=D.length;F<C;F++){this.route(D[F][0],D[F][1],this[D[F][1]])}},_routeToRegExp:function(C){C=C.replace(e,"\\$&").replace(i,"([^/]+)").replace(x,"(.*?)");return new RegExp("^"+C+"$")},_extractParameters:function(C,D){return C.exec(D).slice(1)}});var b=c.History=function(){this.handlers=[];A.bindAll(this,"checkUrl")};var m=/^[#\/]/;var j=/msie [\w.]+/;b.started=false;A.extend(b.prototype,n,{interval:50,getHash:function(E){var D=E?E.location:window.location;var C=D.href.match(/#(.*)$/);return C?C[1]:""},getFragment:function(D,C){if(D==null){if(this._hasPushState||C){D=window.location.pathname;var E=window.location.search;if(E){D+=E}}else{D=this.getHash()}}if(!D.indexOf(this.options.root)){D=D.substr(this.options.root.length)}return D.replace(m,"")},start:function(E){if(b.started){throw new Error("Backbone.history has already been started")}b.started=true;this.options=A.extend({},{root:"/"},this.options,E);this._wantsHashChange=this.options.hashChange!==false;this._wantsPushState=!!this.options.pushState;this._hasPushState=!!(this.options.pushState&&window.history&&window.history.pushState);var D=this.getFragment();var C=document.documentMode;var G=(j.exec(navigator.userAgent.toLowerCase())&&(!C||C<=7));if(G){this.iframe=g('<iframe src="javascript:0" tabindex="-1" />').hide().appendTo("body")[0].contentWindow;this.navigate(D)}if(this._hasPushState){g(window).bind("popstate",this.checkUrl)}else{if(this._wantsHashChange&&("onhashchange" in window)&&!G){g(window).bind("hashchange",this.checkUrl)}else{if(this._wantsHashChange){this._checkUrlInterval=setInterval(this.checkUrl,this.interval)}}}this.fragment=D;var H=window.location;var F=H.pathname==this.options.root;if(this._wantsHashChange&&this._wantsPushState&&!this._hasPushState&&!F){this.fragment=this.getFragment(null,true);window.location.replace(this.options.root+"#"+this.fragment);return true}else{if(this._wantsPushState&&this._hasPushState&&F&&H.hash){this.fragment=this.getHash().replace(m,"");window.history.replaceState({},document.title,H.protocol+"//"+H.host+this.options.root+this.fragment)}}if(!this.options.silent){return this.loadUrl()}},stop:function(){g(window).unbind("popstate",this.checkUrl).unbind("hashchange",this.checkUrl);clearInterval(this._checkUrlInterval);b.started=false},route:function(C,D){this.handlers.unshift({route:C,callback:D})},checkUrl:function(D){var C=this.getFragment();if(C==this.fragment&&this.iframe){C=this.getFragment(this.getHash(this.iframe))}if(C==this.fragment){return false}if(this.iframe){this.navigate(C)}this.loadUrl()||this.loadUrl(this.getHash())},loadUrl:function(E){var D=this.fragment=this.getFragment(E);var C=A.any(this.handlers,function(F){if(F.route.test(D)){F.callback(D);return true}});return C},navigate:function(D,C){if(!b.started){return false}if(!C||C===true){C={trigger:C}}var E=(D||"").replace(m,"");if(this.fragment==E){return}if(this._hasPushState){if(E.indexOf(this.options.root)!=0){E=this.options.root+E}this.fragment=E;window.history[C.replace?"replaceState":"pushState"]({},document.title,E)}else{if(this._wantsHashChange){this.fragment=E;this._updateHash(window.location,E,C.replace);if(this.iframe&&(E!=this.getFragment(this.getHash(this.iframe)))){if(!C.replace){this.iframe.document.open().close()}this._updateHash(this.iframe.location,E,C.replace)}}else{window.location.assign(this.options.root+D)}}if(C.trigger){this.loadUrl(D)}},_updateHash:function(C,D,E){if(E){C.replace(C.toString().replace(/(javascript:|#).*$/,"")+"#"+D)}else{C.hash=D}}});var s=c.View=function(C){this.cid=A.uniqueId("view");this._configure(C||{});this._ensureElement();this.initialize.apply(this,arguments);this.delegateEvents()};var f=/^(\S+)\s*(.*)$/;var u=["model","collection","el","id","attributes","className","tagName"];A.extend(s.prototype,n,{tagName:"div",$:function(C){return this.$el.find(C)},initialize:function(){},render:function(){return this},remove:function(){this.$el.remove();return this},make:function(D,C,F){var E=document.createElement(D);if(C){g(E).attr(C)}if(F){g(E).html(F)}return E},setElement:function(C,D){if(this.$el){this.undelegateEvents()}this.$el=(C instanceof g)?C:g(C);this.el=this.$el[0];if(D!==false){this.delegateEvents()}return this},delegateEvents:function(G){if(!(G||(G=d(this,"events")))){return}this.undelegateEvents();for(var F in G){var H=G[F];if(!A.isFunction(H)){H=this[G[F]]}if(!H){throw new Error('Method "'+G[F]+'" does not exist')}var E=F.match(f);var D=E[1],C=E[2];H=A.bind(H,this);D+=".delegateEvents"+this.cid;if(C===""){this.$el.bind(D,H)}else{this.$el.delegate(C,D,H)}}},undelegateEvents:function(){this.$el.unbind(".delegateEvents"+this.cid)},_configure:function(E){if(this.options){E=A.extend({},this.options,E)}for(var F=0,D=u.length;F<D;F++){var C=u[F];if(E[C]){this[C]=E[C]}}this.options=E},_ensureElement:function(){if(!this.el){var C=d(this,"attributes")||{};if(this.id){C.id=this.id}if(this.className){C["class"]=this.className}this.setElement(this.make(this.tagName,C),false)}else{this.setElement(this.el,false)}}});var v=function(C,D){var E=l(this,C,D);E.extend=this.extend;return E};k.extend=B.extend=z.extend=s.extend=v;var r={create:"POST",update:"PUT","delete":"DELETE",read:"GET"};c.sync=function(G,D,C){var E=r[G];C||(C={});var F={type:E,dataType:"json"};if(!C.url){F.url=d(D,"url")||t()}if(!C.data&&D&&(G=="create"||G=="update")){F.contentType="application/json";F.data=JSON.stringify(D.toJSON())}if(c.emulateJSON){F.contentType="application/x-www-form-urlencoded";F.data=F.data?{model:F.data}:{}}if(c.emulateHTTP){if(E==="PUT"||E==="DELETE"){if(c.emulateJSON){F.data._method=E}F.type="POST";F.beforeSend=function(H){H.setRequestHeader("X-HTTP-Method-Override",E)}}}if(F.type!=="GET"&&!c.emulateJSON){F.processData=false}return g.ajax(A.extend(F,C))};c.wrapError=function(D,E,C){return function(F,G){G=F===E?G:F;if(D){D(E,G,C)}else{E.trigger("error",E,G,C)}}};var h=function(){};var l=function(D,C,E){var F;if(C&&C.hasOwnProperty("constructor")){F=C.constructor}else{F=function(){D.apply(this,arguments)}}A.extend(F,D);h.prototype=D.prototype;F.prototype=new h();if(C){A.extend(F.prototype,C)}if(E){A.extend(F,E)}F.prototype.constructor=F;F.__super__=D.prototype;return F};var d=function(C,D){if(!(C&&C[D])){return null}return A.isFunction(C[D])?C[D]():C[D]};var t=function(){throw new Error('A "url" property or function must be specified')}}).call(this);
\ No newline at end of file
diff -r cb5ff5b1bd67ca6333d808beefab24beedfeed94 -r 70397647fad54c50213e015aaedfed94e6b19eda static/scripts/packed/libs/handlebars-1.0.0.beta.6.js
--- /dev/null
+++ b/static/scripts/packed/libs/handlebars-1.0.0.beta.6.js
@@ -0,0 +1,1 @@
+var Handlebars={};Handlebars.VERSION="1.0.beta.6";Handlebars.helpers={};Handlebars.partials={};Handlebars.registerHelper=function(b,c,a){if(a){c.not=a}this.helpers[b]=c};Handlebars.registerPartial=function(a,b){this.partials[a]=b};Handlebars.registerHelper("helperMissing",function(a){if(arguments.length===2){return undefined}else{throw new Error("Could not find property '"+a+"'")}});var toString=Object.prototype.toString,functionType="[object Function]";Handlebars.registerHelper("blockHelperMissing",function(f,d){var a=d.inverse||function(){},h=d.fn;var c="";var g=toString.call(f);if(g===functionType){f=f.call(this)}if(f===true){return h(this)}else{if(f===false||f==null){return a(this)}else{if(g==="[object Array]"){if(f.length>0){for(var e=0,b=f.length;e<b;e++){c=c+h(f[e])}}else{c=a(this)}return c}else{return h(f)}}}});Handlebars.registerHelper("each",function(f,d){var g=d.fn,a=d.inverse;var c="";if(f&&f.length>0){for(var e=0,b=f.length;e<b;e++){c=c+g(f[e])}}else{c=a(this)}return c});Handlebars.registerHelper("if",function(b,a){var c=toString.call(b);if(c===functionType){b=b.call(this)}if(!b||Handlebars.Utils.isEmpty(b)){return a.inverse(this)}else{return a.fn(this)}});Handlebars.registerHelper("unless",function(c,b){var d=b.fn,a=b.inverse;b.fn=a;b.inverse=d;return Handlebars.helpers["if"].call(this,c,b)});Handlebars.registerHelper("with",function(b,a){return a.fn(b)});Handlebars.registerHelper("log",function(a){Handlebars.log(a)});var handlebars=(function(){var f={trace:function c(){},yy:{},symbols_:{error:2,root:3,program:4,EOF:5,statements:6,simpleInverse:7,statement:8,openInverse:9,closeBlock:10,openBlock:11,mustache:12,partial:13,CONTENT:14,COMMENT:15,OPEN_BLOCK:16,inMustache:17,CLOSE:18,OPEN_INVERSE:19,OPEN_ENDBLOCK:20,path:21,OPEN:22,OPEN_UNESCAPED:23,OPEN_PARTIAL:24,params:25,hash:26,param:27,STRING:28,INTEGER:29,BOOLEAN:30,hashSegments:31,hashSegment:32,ID:33,EQUALS:34,pathSegments:35,SEP:36,"$accept":0,"$end":1},terminals_:{2:"error",5:"EOF",14:"CONTENT",15:"COMMENT",16:"OPEN_BLOCK",18:"CLOSE",19:"OPEN_INVERSE",20:"OPEN_ENDBLOCK",22:"OPEN",23:"OPEN_UNESCAPED",24:"OPEN_PARTIAL",28:"STRING",29:"INTEGER",30:"BOOLEAN",33:"ID",34:"EQUALS",36:"SEP"},productions_:[0,[3,2],[4,3],[4,1],[4,0],[6,1],[6,2],[8,3],[8,3],[8,1],[8,1],[8,1],[8,1],[11,3],[9,3],[10,3],[12,3],[12,3],[13,3],[13,4],[7,2],[17,3],[17,2],[17,2],[17,1],[25,2],[25,1],[27,1],[27,1],[27,1],[27,1],[26,1],[31,2],[31,1],[32,3],[32,3],[32,3],[32,3],[21,1],[35,3],[35,1]],performAction:function b(g,j,k,n,m,i,l){var h=i.length-1;switch(m){case 1:return i[h-1];break;case 2:this.$=new n.ProgramNode(i[h-2],i[h]);break;case 3:this.$=new n.ProgramNode(i[h]);break;case 4:this.$=new n.ProgramNode([]);break;case 5:this.$=[i[h]];break;case 6:i[h-1].push(i[h]);this.$=i[h-1];break;case 7:this.$=new n.InverseNode(i[h-2],i[h-1],i[h]);break;case 8:this.$=new n.BlockNode(i[h-2],i[h-1],i[h]);break;case 9:this.$=i[h];break;case 10:this.$=i[h];break;case 11:this.$=new n.ContentNode(i[h]);break;case 12:this.$=new n.CommentNode(i[h]);break;case 13:this.$=new n.MustacheNode(i[h-1][0],i[h-1][1]);break;case 14:this.$=new n.MustacheNode(i[h-1][0],i[h-1][1]);break;case 15:this.$=i[h-1];break;case 16:this.$=new n.MustacheNode(i[h-1][0],i[h-1][1]);break;case 17:this.$=new n.MustacheNode(i[h-1][0],i[h-1][1],true);break;case 18:this.$=new n.PartialNode(i[h-1]);break;case 19:this.$=new n.PartialNode(i[h-2],i[h-1]);break;case 20:break;case 21:this.$=[[i[h-2]].concat(i[h-1]),i[h]];break;case 22:this.$=[[i[h-1]].concat(i[h]),null];break;case 23:this.$=[[i[h-1]],i[h]];break;case 24:this.$=[[i[h]],null];break;case 25:i[h-1].push(i[h]);this.$=i[h-1];break;case 26:this.$=[i[h]];break;case 27:this.$=i[h];break;case 28:this.$=new n.StringNode(i[h]);break;case 29:this.$=new n.IntegerNode(i[h]);break;case 30:this.$=new n.BooleanNode(i[h]);break;case 31:this.$=new n.HashNode(i[h]);break;case 32:i[h-1].push(i[h]);this.$=i[h-1];break;case 33:this.$=[i[h]];break;case 34:this.$=[i[h-2],i[h]];break;case 35:this.$=[i[h-2],new n.StringNode(i[h])];break;case 36:this.$=[i[h-2],new n.IntegerNode(i[h])];break;case 37:this.$=[i[h-2],new n.BooleanNode(i[h])];break;case 38:this.$=new n.IdNode(i[h]);break;case 39:i[h-2].push(i[h]);this.$=i[h-2];break;case 40:this.$=[i[h]];break}},table:[{3:1,4:2,5:[2,4],6:3,8:4,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,11],22:[1,13],23:[1,14],24:[1,15]},{1:[3]},{5:[1,16]},{5:[2,3],7:17,8:18,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,19],20:[2,3],22:[1,13],23:[1,14],24:[1,15]},{5:[2,5],14:[2,5],15:[2,5],16:[2,5],19:[2,5],20:[2,5],22:[2,5],23:[2,5],24:[2,5]},{4:20,6:3,8:4,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,11],20:[2,4],22:[1,13],23:[1,14],24:[1,15]},{4:21,6:3,8:4,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,11],20:[2,4],22:[1,13],23:[1,14],24:[1,15]},{5:[2,9],14:[2,9],15:[2,9],16:[2,9],19:[2,9],20:[2,9],22:[2,9],23:[2,9],24:[2,9]},{5:[2,10],14:[2,10],15:[2,10],16:[2,10],19:[2,10],20:[2,10],22:[2,10],23:[2,10],24:[2,10]},{5:[2,11],14:[2,11],15:[2,11],16:[2,11],19:[2,11],20:[2,11],22:[2,11],23:[2,11],24:[2,11]},{5:[2,12],14:[2,12],15:[2,12],16:[2,12],19:[2,12],20:[2,12],22:[2,12],23:[2,12],24:[2,12]},{17:22,21:23,33:[1,25],35:24},{17:26,21:23,33:[1,25],35:24},{17:27,21:23,33:[1,25],35:24},{17:28,21:23,33:[1,25],35:24},{21:29,33:[1,25],35:24},{1:[2,1]},{6:30,8:4,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,11],22:[1,13],23:[1,14],24:[1,15]},{5:[2,6],14:[2,6],15:[2,6],16:[2,6],19:[2,6],20:[2,6],22:[2,6],23:[2,6],24:[2,6]},{17:22,18:[1,31],21:23,33:[1,25],35:24},{10:32,20:[1,33]},{10:34,20:[1,33]},{18:[1,35]},{18:[2,24],21:40,25:36,26:37,27:38,28:[1,41],29:[1,42],30:[1,43],31:39,32:44,33:[1,45],35:24},{18:[2,38],28:[2,38],29:[2,38],30:[2,38],33:[2,38],36:[1,46]},{18:[2,40],28:[2,40],29:[2,40],30:[2,40],33:[2,40],36:[2,40]},{18:[1,47]},{18:[1,48]},{18:[1,49]},{18:[1,50],21:51,33:[1,25],35:24},{5:[2,2],8:18,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,11],20:[2,2],22:[1,13],23:[1,14],24:[1,15]},{14:[2,20],15:[2,20],16:[2,20],19:[2,20],22:[2,20],23:[2,20],24:[2,20]},{5:[2,7],14:[2,7],15:[2,7],16:[2,7],19:[2,7],20:[2,7],22:[2,7],23:[2,7],24:[2,7]},{21:52,33:[1,25],35:24},{5:[2,8],14:[2,8],15:[2,8],16:[2,8],19:[2,8],20:[2,8],22:[2,8],23:[2,8],24:[2,8]},{14:[2,14],15:[2,14],16:[2,14],19:[2,14],20:[2,14],22:[2,14],23:[2,14],24:[2,14]},{18:[2,22],21:40,26:53,27:54,28:[1,41],29:[1,42],30:[1,43],31:39,32:44,33:[1,45],35:24},{18:[2,23]},{18:[2,26],28:[2,26],29:[2,26],30:[2,26],33:[2,26]},{18:[2,31],32:55,33:[1,56]},{18:[2,27],28:[2,27],29:[2,27],30:[2,27],33:[2,27]},{18:[2,28],28:[2,28],29:[2,28],30:[2,28],33:[2,28]},{18:[2,29],28:[2,29],29:[2,29],30:[2,29],33:[2,29]},{18:[2,30],28:[2,30],29:[2,30],30:[2,30],33:[2,30]},{18:[2,33],33:[2,33]},{18:[2,40],28:[2,40],29:[2,40],30:[2,40],33:[2,40],34:[1,57],36:[2,40]},{33:[1,58]},{14:[2,13],15:[2,13],16:[2,13],19:[2,13],20:[2,13],22:[2,13],23:[2,13],24:[2,13]},{5:[2,16],14:[2,16],15:[2,16],16:[2,16],19:[2,16],20:[2,16],22:[2,16],23:[2,16],24:[2,16]},{5:[2,17],14:[2,17],15:[2,17],16:[2,17],19:[2,17],20:[2,17],22:[2,17],23:[2,17],24:[2,17]},{5:[2,18],14:[2,18],15:[2,18],16:[2,18],19:[2,18],20:[2,18],22:[2,18],23:[2,18],24:[2,18]},{18:[1,59]},{18:[1,60]},{18:[2,21]},{18:[2,25],28:[2,25],29:[2,25],30:[2,25],33:[2,25]},{18:[2,32],33:[2,32]},{34:[1,57]},{21:61,28:[1,62],29:[1,63],30:[1,64],33:[1,25],35:24},{18:[2,39],28:[2,39],29:[2,39],30:[2,39],33:[2,39],36:[2,39]},{5:[2,19],14:[2,19],15:[2,19],16:[2,19],19:[2,19],20:[2,19],22:[2,19],23:[2,19],24:[2,19]},{5:[2,15],14:[2,15],15:[2,15],16:[2,15],19:[2,15],20:[2,15],22:[2,15],23:[2,15],24:[2,15]},{18:[2,34],33:[2,34]},{18:[2,35],33:[2,35]},{18:[2,36],33:[2,36]},{18:[2,37],33:[2,37]}],defaultActions:{16:[2,1],37:[2,23],53:[2,21]},parseError:function d(h,g){throw new Error(h)},parse:function e(o){var x=this,l=[0],G=[null],s=[],H=this.table,h="",q=0,E=0,j=0,n=2,u=1;this.lexer.setInput(o);this.lexer.yy=this.yy;this.yy.lexer=this.lexer;if(typeof this.lexer.yylloc=="undefined"){this.lexer.yylloc={}}var i=this.lexer.yylloc;s.push(i);if(typeof this.yy.parseError==="function"){this.parseError=this.yy.parseError}function w(p){l.length=l.length-2*p;G.length=G.length-p;s.length=s.length-p}function v(){var p;p=x.lexer.lex()||1;if(typeof p!=="number"){p=x.symbols_[p]||p}return p}var D,z,k,C,I,t,B={},y,F,g,m;while(true){k=l[l.length-1];if(this.defaultActions[k]){C=this.defaultActions[k]}else{if(D==null){D=v()}C=H[k]&&H[k][D]}if(typeof C==="undefined"||!C.length||!C[0]){if(!j){m=[];for(y in H[k]){if(this.terminals_[y]&&y>2){m.push("'"+this.terminals_[y]+"'")}}var A="";if(this.lexer.showPosition){A="Parse error on line "+(q+1)+":\n"+this.lexer.showPosition()+"\nExpecting "+m.join(", ")+", got '"+this.terminals_[D]+"'"}else{A="Parse error on line "+(q+1)+": Unexpected "+(D==1?"end of input":"'"+(this.terminals_[D]||D)+"'")}this.parseError(A,{text:this.lexer.match,token:this.terminals_[D]||D,line:this.lexer.yylineno,loc:i,expected:m})}}if(C[0] instanceof Array&&C.length>1){throw new Error("Parse Error: multiple actions possible at state: "+k+", token: "+D)}switch(C[0]){case 1:l.push(D);G.push(this.lexer.yytext);s.push(this.lexer.yylloc);l.push(C[1]);D=null;if(!z){E=this.lexer.yyleng;h=this.lexer.yytext;q=this.lexer.yylineno;i=this.lexer.yylloc;if(j>0){j--}}else{D=z;z=null}break;case 2:F=this.productions_[C[1]][1];B.$=G[G.length-F];B._$={first_line:s[s.length-(F||1)].first_line,last_line:s[s.length-1].last_line,first_column:s[s.length-(F||1)].first_column,last_column:s[s.length-1].last_column};t=this.performAction.call(B,h,E,q,this.yy,C[1],G,s);if(typeof t!=="undefined"){return t}if(F){l=l.slice(0,-1*F*2);G=G.slice(0,-1*F);s=s.slice(0,-1*F)}l.push(this.productions_[C[1]][0]);G.push(B.$);s.push(B._$);g=H[l[l.length-2]][l[l.length-1]];l.push(g);break;case 3:return true}}return true}};var a=(function(){var j=({EOF:1,parseError:function l(o,n){if(this.yy.parseError){this.yy.parseError(o,n)}else{throw new Error(o)}},setInput:function(n){this._input=n;this._more=this._less=this.done=false;this.yylineno=this.yyleng=0;this.yytext=this.matched=this.match="";this.conditionStack=["INITIAL"];this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0};return this},input:function(){var o=this._input[0];this.yytext+=o;this.yyleng++;this.match+=o;this.matched+=o;var n=o.match(/\n/);if(n){this.yylineno++}this._input=this._input.slice(1);return o},unput:function(n){this._input=n+this._input;return this},more:function(){this._more=true;return this},pastInput:function(){var n=this.matched.substr(0,this.matched.length-this.match.length);return(n.length>20?"...":"")+n.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var n=this.match;if(n.length<20){n+=this._input.substr(0,20-n.length)}return(n.substr(0,20)+(n.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var n=this.pastInput();var o=new Array(n.length+1).join("-");return n+this.upcomingInput()+"\n"+o+"^"},next:function(){if(this.done){return this.EOF}if(!this._input){this.done=true}var r,p,o,n;if(!this._more){this.yytext="";this.match=""}var s=this._currentRules();for(var q=0;q<s.length;q++){p=this._input.match(this.rules[s[q]]);if(p){n=p[0].match(/\n.*/g);if(n){this.yylineno+=n.length}this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:n?n[n.length-1].length-1:this.yylloc.last_column+p[0].length};this.yytext+=p[0];this.match+=p[0];this.matches=p;this.yyleng=this.yytext.length;this._more=false;this._input=this._input.slice(p[0].length);this.matched+=p[0];r=this.performAction.call(this,this.yy,this,s[q],this.conditionStack[this.conditionStack.length-1]);if(r){return r}else{return}}}if(this._input===""){return this.EOF}else{this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})}},lex:function g(){var n=this.next();if(typeof n!=="undefined"){return n}else{return this.lex()}},begin:function h(n){this.conditionStack.push(n)},popState:function m(){return this.conditionStack.pop()},_currentRules:function k(){return this.conditions[this.conditionStack[this.conditionStack.length-1]].rules},topState:function(){return this.conditionStack[this.conditionStack.length-2]},pushState:function h(n){this.begin(n)}});j.performAction=function i(r,o,q,n){var p=n;switch(q){case 0:if(o.yytext.slice(-1)!=="\\"){this.begin("mu")}if(o.yytext.slice(-1)==="\\"){o.yytext=o.yytext.substr(0,o.yyleng-1),this.begin("emu")}if(o.yytext){return 14}break;case 1:return 14;break;case 2:this.popState();return 14;break;case 3:return 24;break;case 4:return 16;break;case 5:return 20;break;case 6:return 19;break;case 7:return 19;break;case 8:return 23;break;case 9:return 23;break;case 10:o.yytext=o.yytext.substr(3,o.yyleng-5);this.popState();return 15;break;case 11:return 22;break;case 12:return 34;break;case 13:return 33;break;case 14:return 33;break;case 15:return 36;break;case 16:break;case 17:this.popState();return 18;break;case 18:this.popState();return 18;break;case 19:o.yytext=o.yytext.substr(1,o.yyleng-2).replace(/\\"/g,'"');return 28;break;case 20:return 30;break;case 21:return 30;break;case 22:return 29;break;case 23:return 33;break;case 24:o.yytext=o.yytext.substr(1,o.yyleng-2);return 33;break;case 25:return"INVALID";break;case 26:return 5;break}};j.rules=[/^[^\x00]*?(?=(\{\{))/,/^[^\x00]+/,/^[^\x00]{2,}?(?=(\{\{))/,/^\{\{>/,/^\{\{#/,/^\{\{\//,/^\{\{\^/,/^\{\{\s*else\b/,/^\{\{\{/,/^\{\{&/,/^\{\{![\s\S]*?\}\}/,/^\{\{/,/^=/,/^\.(?=[} ])/,/^\.\./,/^[\/.]/,/^\s+/,/^\}\}\}/,/^\}\}/,/^"(\\["]|[^"])*"/,/^true(?=[}\s])/,/^false(?=[}\s])/,/^[0-9]+(?=[}\s])/,/^[a-zA-Z0-9_$-]+(?=[=}\s\/.])/,/^\[[^\]]*\]/,/^./,/^$/];j.conditions={mu:{rules:[3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26],inclusive:false},emu:{rules:[2],inclusive:false},INITIAL:{rules:[0,1,26],inclusive:true}};return j})();f.lexer=a;return f})();if(typeof require!=="undefined"&&typeof exports!=="undefined"){exports.parser=handlebars;exports.parse=function(){return handlebars.parse.apply(handlebars,arguments)};exports.main=function commonjsMain(a){if(!a[1]){throw new Error("Usage: "+a[0]+" FILE")}if(typeof process!=="undefined"){var c=require("fs").readFileSync(require("path").join(process.cwd(),a[1]),"utf8")}else{var b=require("file").path(require("file").cwd());var c=b.join(a[1]).read({charset:"utf-8"})}return exports.parser.parse(c)};if(typeof module!=="undefined"&&require.main===module){exports.main(typeof process!=="undefined"?process.argv.slice(1):require("system").args)}}Handlebars.Parser=handlebars;Handlebars.parse=function(a){Handlebars.Parser.yy=Handlebars.AST;return Handlebars.Parser.parse(a)};Handlebars.print=function(a){return new Handlebars.PrintVisitor().accept(a)};Handlebars.logger={DEBUG:0,INFO:1,WARN:2,ERROR:3,level:3,log:function(b,a){}};Handlebars.log=function(b,a){Handlebars.logger.log(b,a)};(function(){Handlebars.AST={};Handlebars.AST.ProgramNode=function(c,b){this.type="program";this.statements=c;if(b){this.inverse=new Handlebars.AST.ProgramNode(b)}};Handlebars.AST.MustacheNode=function(d,c,b){this.type="mustache";this.id=d[0];this.params=d.slice(1);this.hash=c;this.escaped=!b};Handlebars.AST.PartialNode=function(c,b){this.type="partial";this.id=c;this.context=b};var a=function(b,c){if(b.original!==c.original){throw new Handlebars.Exception(b.original+" doesn't match "+c.original)}};Handlebars.AST.BlockNode=function(c,b,d){a(c.id,d);this.type="block";this.mustache=c;this.program=b};Handlebars.AST.InverseNode=function(c,b,d){a(c.id,d);this.type="inverse";this.mustache=c;this.program=b};Handlebars.AST.ContentNode=function(b){this.type="content";this.string=b};Handlebars.AST.HashNode=function(b){this.type="hash";this.pairs=b};Handlebars.AST.IdNode=function(f){this.type="ID";this.original=f.join(".");var d=[],g=0;for(var e=0,b=f.length;e<b;e++){var c=f[e];if(c===".."){g++}else{if(c==="."||c==="this"){this.isScoped=true}else{d.push(c)}}}this.parts=d;this.string=d.join(".");this.depth=g;this.isSimple=(d.length===1)&&(g===0)};Handlebars.AST.StringNode=function(b){this.type="STRING";this.string=b};Handlebars.AST.IntegerNode=function(b){this.type="INTEGER";this.integer=b};Handlebars.AST.BooleanNode=function(b){this.type="BOOLEAN";this.bool=b};Handlebars.AST.CommentNode=function(b){this.type="comment";this.comment=b}})();Handlebars.Exception=function(b){var a=Error.prototype.constructor.apply(this,arguments);for(var c in a){if(a.hasOwnProperty(c)){this[c]=a[c]}}this.message=a.message};Handlebars.Exception.prototype=new Error;Handlebars.SafeString=function(a){this.string=a};Handlebars.SafeString.prototype.toString=function(){return this.string.toString()};(function(){var c={"<":"<",">":">",'"':""","'":"'","`":"`"};var d=/&(?!\w+;)|[<>"'`]/g;var b=/[&<>"'`]/;var a=function(e){return c[e]||"&"};Handlebars.Utils={escapeExpression:function(e){if(e instanceof Handlebars.SafeString){return e.toString()}else{if(e==null||e===false){return""}}if(!b.test(e)){return e}return e.replace(d,a)},isEmpty:function(e){if(typeof e==="undefined"){return true}else{if(e===null){return true}else{if(e===false){return true}else{if(Object.prototype.toString.call(e)==="[object Array]"&&e.length===0){return true}else{return false}}}}}}})();Handlebars.Compiler=function(){};Handlebars.JavaScriptCompiler=function(){};(function(f,e){f.OPCODE_MAP={appendContent:1,getContext:2,lookupWithHelpers:3,lookup:4,append:5,invokeMustache:6,appendEscaped:7,pushString:8,truthyOrFallback:9,functionOrFallback:10,invokeProgram:11,invokePartial:12,push:13,assignToHash:15,pushStringParam:16};f.MULTI_PARAM_OPCODES={appendContent:1,getContext:1,lookupWithHelpers:2,lookup:1,invokeMustache:3,pushString:1,truthyOrFallback:1,functionOrFallback:1,invokeProgram:3,invokePartial:1,push:1,assignToHash:1,pushStringParam:1};f.DISASSEMBLE_MAP={};for(var h in f.OPCODE_MAP){var g=f.OPCODE_MAP[h];f.DISASSEMBLE_MAP[g]=h}f.multiParamSize=function(i){return f.MULTI_PARAM_OPCODES[f.DISASSEMBLE_MAP[i]]};f.prototype={compiler:f,disassemble:function(){var t=this.opcodes,r,n;var q=[],v,m,w;for(var s=0,o=t.length;s<o;s++){r=t[s];if(r==="DECLARE"){m=t[++s];w=t[++s];q.push("DECLARE "+m+" = "+w)}else{v=f.DISASSEMBLE_MAP[r];var u=f.multiParamSize(r);var k=[];for(var p=0;p<u;p++){n=t[++s];if(typeof n==="string"){n='"'+n.replace("\n","\\n")+'"'}k.push(n)}v=v+" "+k.join(" ");q.push(v)}}return q.join("\n")},guid:0,compile:function(i,k){this.children=[];this.depths={list:[]};this.options=k;var l=this.options.knownHelpers;this.options.knownHelpers={helperMissing:true,blockHelperMissing:true,each:true,"if":true,unless:true,"with":true,log:true};if(l){for(var j in l){this.options.knownHelpers[j]=l[j]}}return this.program(i)},accept:function(i){return this[i.type](i)},program:function(m){var k=m.statements,o;this.opcodes=[];for(var n=0,j=k.length;n<j;n++){o=k[n];this[o.type](o)}this.isSimple=j===1;this.depths.list=this.depths.list.sort(function(l,i){return l-i});return this},compileProgram:function(m){var j=new this.compiler().compile(m,this.options);var n=this.guid++;this.usePartial=this.usePartial||j.usePartial;this.children[n]=j;for(var o=0,k=j.depths.list.length;o<k;o++){depth=j.depths.list[o];if(depth<2){continue}else{this.addDepth(depth-1)}}return n},block:function(o){var l=o.mustache;var n,p,j,k;var m=this.setupStackForMustache(l);var i=this.compileProgram(o.program);if(o.program.inverse){k=this.compileProgram(o.program.inverse);this.declare("inverse",k)}this.opcode("invokeProgram",i,m.length,!!l.hash);this.declare("inverse",null);this.opcode("append")},inverse:function(k){var j=this.setupStackForMustache(k.mustache);var i=this.compileProgram(k.program);this.declare("inverse",i);this.opcode("invokeProgram",null,j.length,!!k.mustache.hash);this.declare("inverse",null);this.opcode("append")},hash:function(n){var m=n.pairs,p,o;this.opcode("push","{}");for(var k=0,j=m.length;k<j;k++){p=m[k];o=p[1];this.accept(o);this.opcode("assignToHash",p[0])}},partial:function(i){var j=i.id;this.usePartial=true;if(i.context){this.ID(i.context)}else{this.opcode("push","depth0")}this.opcode("invokePartial",j.original);this.opcode("append")},content:function(i){this.opcode("appendContent",i.string)},mustache:function(i){var j=this.setupStackForMustache(i);this.opcode("invokeMustache",j.length,i.id.original,!!i.hash);if(i.escaped&&!this.options.noEscape){this.opcode("appendEscaped")}else{this.opcode("append")}},ID:function(m){this.addDepth(m.depth);this.opcode("getContext",m.depth);this.opcode("lookupWithHelpers",m.parts[0]||null,m.isScoped||false);for(var k=1,j=m.parts.length;k<j;k++){this.opcode("lookup",m.parts[k])}},STRING:function(i){this.opcode("pushString",i.string)},INTEGER:function(i){this.opcode("push",i.integer)},BOOLEAN:function(i){this.opcode("push",i.bool)},comment:function(){},pushParams:function(l){var j=l.length,k;while(j--){k=l[j];if(this.options.stringParams){if(k.depth){this.addDepth(k.depth)}this.opcode("getContext",k.depth||0);this.opcode("pushStringParam",k.string)}else{this[k.type](k)}}},opcode:function(i,l,k,j){this.opcodes.push(f.OPCODE_MAP[i]);if(l!==undefined){this.opcodes.push(l)}if(k!==undefined){this.opcodes.push(k)}if(j!==undefined){this.opcodes.push(j)}},declare:function(i,j){this.opcodes.push("DECLARE");this.opcodes.push(i);this.opcodes.push(j)},addDepth:function(i){if(i===0){return}if(!this.depths[i]){this.depths[i]=true;this.depths.list.push(i)}},setupStackForMustache:function(i){var j=i.params;this.pushParams(j);if(i.hash){this.hash(i.hash)}this.ID(i.id);return j}};e.prototype={nameLookup:function(k,i,j){if(/^[0-9]+$/.test(i)){return k+"["+i+"]"}else{if(e.isValidJavaScriptVariableName(i)){return k+"."+i}else{return k+"['"+i+"']"}}},appendToBuffer:function(i){if(this.environment.isSimple){return"return "+i+";"}else{return"buffer += "+i+";"}},initializeBuffer:function(){return this.quotedString("")},namespace:"Handlebars",compile:function(i,j,l,k){this.environment=i;this.options=j||{};this.name=this.environment.name;this.isChild=!!l;this.context=l||{programs:[],aliases:{self:"this"},registers:{list:[]}};this.preamble();this.stackSlot=0;this.stackVars=[];this.compileChildren(i,j);var n=i.opcodes,m;this.i=0;for(b=n.length;this.i<b;this.i++){m=this.nextOpcode(0);if(m[0]==="DECLARE"){this.i=this.i+2;this[m[1]]=m[2]}else{this.i=this.i+m[1].length;this[m[0]].apply(this,m[1])}}return this.createFunctionContext(k)},nextOpcode:function(r){var o=this.environment.opcodes,m=o[this.i+r],l,p;var q,i;if(m==="DECLARE"){l=o[this.i+1];p=o[this.i+2];return["DECLARE",l,p]}else{l=f.DISASSEMBLE_MAP[m];q=f.multiParamSize(m);i=[];for(var k=0;k<q;k++){i.push(o[this.i+k+1+r])}return[l,i]}},eat:function(i){this.i=this.i+i.length},preamble:function(){var i=[];this.useRegister("foundHelper");if(!this.isChild){var j=this.namespace;var k="helpers = helpers || "+j+".helpers;";if(this.environment.usePartial){k=k+" partials = partials || "+j+".partials;"}i.push(k)}else{i.push("")}if(!this.environment.isSimple){i.push(", buffer = "+this.initializeBuffer())}else{i.push("")}this.lastContext=0;this.source=i},createFunctionContext:function(p){var q=this.stackVars;if(!this.isChild){q=q.concat(this.context.registers.list)}if(q.length>0){this.source[1]=this.source[1]+", "+q.join(", ")}if(!this.isChild){var k=[];for(var o in this.context.aliases){this.source[1]=this.source[1]+", "+o+"="+this.context.aliases[o]}}if(this.source[1]){this.source[1]="var "+this.source[1].substring(2)+";"}if(!this.isChild){this.source[1]+="\n"+this.context.programs.join("\n")+"\n"}if(!this.environment.isSimple){this.source.push("return buffer;")}var r=this.isChild?["depth0","data"]:["Handlebars","depth0","helpers","partials","data"];for(var n=0,j=this.environment.depths.list.length;n<j;n++){r.push("depth"+this.environment.depths.list[n])}if(p){r.push(this.source.join("\n "));return Function.apply(this,r)}else{var m="function "+(this.name||"")+"("+r.join(",")+") {\n "+this.source.join("\n ")+"}";Handlebars.log(Handlebars.logger.DEBUG,m+"\n\n");return m}},appendContent:function(i){this.source.push(this.appendToBuffer(this.quotedString(i)))},append:function(){var i=this.popStack();this.source.push("if("+i+" || "+i+" === 0) { "+this.appendToBuffer(i)+" }");if(this.environment.isSimple){this.source.push("else { "+this.appendToBuffer("''")+" }")}},appendEscaped:function(){var j=this.nextOpcode(1),i="";this.context.aliases.escapeExpression="this.escapeExpression";if(j[0]==="appendContent"){i=" + "+this.quotedString(j[1][0]);this.eat(j)}this.source.push(this.appendToBuffer("escapeExpression("+this.popStack()+")"+i))},getContext:function(i){if(this.lastContext!==i){this.lastContext=i}},lookupWithHelpers:function(k,l){if(k){var i=this.nextStack();this.usingKnownHelper=false;var j;if(!l&&this.options.knownHelpers[k]){j=i+" = "+this.nameLookup("helpers",k,"helper");this.usingKnownHelper=true}else{if(l||this.options.knownHelpersOnly){j=i+" = "+this.nameLookup("depth"+this.lastContext,k,"context")}else{this.register("foundHelper",this.nameLookup("helpers",k,"helper"));j=i+" = foundHelper || "+this.nameLookup("depth"+this.lastContext,k,"context")}}j+=";";this.source.push(j)}else{this.pushStack("depth"+this.lastContext)}},lookup:function(j){var i=this.topStack();this.source.push(i+" = ("+i+" === null || "+i+" === undefined || "+i+" === false ? "+i+" : "+this.nameLookup(i,j,"context")+");")},pushStringParam:function(i){this.pushStack("depth"+this.lastContext);this.pushString(i)},pushString:function(i){this.pushStack(this.quotedString(i))},push:function(i){this.pushStack(i)},invokeMustache:function(k,j,i){this.populateParams(k,this.quotedString(j),"{}",null,i,function(l,n,m){if(!this.usingKnownHelper){this.context.aliases.helperMissing="helpers.helperMissing";this.context.aliases.undef="void 0";this.source.push("else if("+m+"=== undef) { "+l+" = helperMissing.call("+n+"); }");if(l!==m){this.source.push("else { "+l+" = "+m+"; }")}}})},invokeProgram:function(k,l,j){var i=this.programExpression(this.inverse);var m=this.programExpression(k);this.populateParams(l,null,m,i,j,function(n,p,o){if(!this.usingKnownHelper){this.context.aliases.blockHelperMissing="helpers.blockHelperMissing";this.source.push("else { "+n+" = blockHelperMissing.call("+p+"); }")}})},populateParams:function(p,k,t,q,x,w){var l=x||this.options.stringParams||q||this.options.data;var j=this.popStack(),v;var n=[],m,o,u;if(l){this.register("tmp1",t);u="tmp1"}else{u="{ hash: {} }"}if(l){var s=(x?this.popStack():"{}");this.source.push("tmp1.hash = "+s+";")}if(this.options.stringParams){this.source.push("tmp1.contexts = [];")}for(var r=0;r<p;r++){m=this.popStack();n.push(m);if(this.options.stringParams){this.source.push("tmp1.contexts.push("+this.popStack()+");")}}if(q){this.source.push("tmp1.fn = tmp1;");this.source.push("tmp1.inverse = "+q+";")}if(this.options.data){this.source.push("tmp1.data = data;")}n.push(u);this.populateCall(n,j,k||j,w,t!=="{}")},populateCall:function(n,j,k,q,o){var m=["depth0"].concat(n).join(", ");var i=["depth0"].concat(k).concat(n).join(", ");var p=this.nextStack();if(this.usingKnownHelper){this.source.push(p+" = "+j+".call("+m+");")}else{this.context.aliases.functionType='"function"';var l=o?"foundHelper && ":"";this.source.push("if("+l+"typeof "+j+" === functionType) { "+p+" = "+j+".call("+m+"); }")}q.call(this,p,i,j);this.usingKnownHelper=false},invokePartial:function(i){params=[this.nameLookup("partials",i,"partial"),"'"+i+"'",this.popStack(),"helpers","partials"];if(this.options.data){params.push("data")}this.pushStack("self.invokePartial("+params.join(", ")+");")},assignToHash:function(i){var j=this.popStack();var k=this.topStack();this.source.push(k+"['"+i+"'] = "+j+";")},compiler:e,compileChildren:function(j,n){var p=j.children,r,q;for(var o=0,k=p.length;o<k;o++){r=p[o];q=new this.compiler();this.context.programs.push("");var m=this.context.programs.length;r.index=m;r.name="program"+m;this.context.programs[m]=q.compile(r,n,this.context)}},programExpression:function(k){if(k==null){return"self.noop"}var p=this.environment.children[k],o=p.depths.list;var n=[p.index,p.name,"data"];for(var m=0,j=o.length;m<j;m++){depth=o[m];if(depth===1){n.push("depth0")}else{n.push("depth"+(depth-1))}}if(o.length===0){return"self.program("+n.join(", ")+")"}else{n.shift();return"self.programWithDepth("+n.join(", ")+")"}},register:function(i,j){this.useRegister(i);this.source.push(i+" = "+j+";")},useRegister:function(i){if(!this.context.registers[i]){this.context.registers[i]=true;this.context.registers.list.push(i)}},pushStack:function(i){this.source.push(this.nextStack()+" = "+i+";");return"stack"+this.stackSlot},nextStack:function(){this.stackSlot++;if(this.stackSlot>this.stackVars.length){this.stackVars.push("stack"+this.stackSlot)}return"stack"+this.stackSlot},popStack:function(){return"stack"+this.stackSlot--},topStack:function(){return"stack"+this.stackSlot},quotedString:function(i){return'"'+i.replace(/\\/g,"\\\\").replace(/"/g,'\\"').replace(/\n/g,"\\n").replace(/\r/g,"\\r")+'"'}};var a=("break else new var case finally return void catch for switch while continue function this with default if throw delete in try do instanceof typeof abstract enum int short boolean export interface static byte extends long super char final native synchronized class float package throws const goto private transient debugger implements protected volatile double import public let yield").split(" ");var d=e.RESERVED_WORDS={};for(var c=0,b=a.length;c<b;c++){d[a[c]]=true}e.isValidJavaScriptVariableName=function(i){if(!e.RESERVED_WORDS[i]&&/^[a-zA-Z_$][0-9a-zA-Z_$]+$/.test(i)){return true}return false}})(Handlebars.Compiler,Handlebars.JavaScriptCompiler);Handlebars.precompile=function(d,c){c=c||{};var b=Handlebars.parse(d);var a=new Handlebars.Compiler().compile(b,c);return new Handlebars.JavaScriptCompiler().compile(a,c)};Handlebars.compile=function(b,a){a=a||{};var d;function c(){var g=Handlebars.parse(b);var f=new Handlebars.Compiler().compile(g,a);var e=new Handlebars.JavaScriptCompiler().compile(f,a,undefined,true);return Handlebars.template(e)}return function(f,e){if(!d){d=c()}return d.call(this,f,e)}};Handlebars.VM={template:function(a){var b={escapeExpression:Handlebars.Utils.escapeExpression,invokePartial:Handlebars.VM.invokePartial,programs:[],program:function(d,e,f){var c=this.programs[d];if(f){return Handlebars.VM.program(e,f)}else{if(c){return c}else{c=this.programs[d]=Handlebars.VM.program(e);return c}}},programWithDepth:Handlebars.VM.programWithDepth,noop:Handlebars.VM.noop};return function(d,c){c=c||{};return a.call(b,Handlebars,d,c.helpers,c.partials,c.data)}},programWithDepth:function(b,d,c){var a=Array.prototype.slice.call(arguments,2);return function(f,e){e=e||{};return b.apply(this,[f,e.data||d].concat(a))}},program:function(a,b){return function(d,c){c=c||{};return a(d,c.data||b)}},noop:function(){return""},invokePartial:function(a,b,d,e,c,f){options={helpers:e,partials:c,data:f};if(a===undefined){throw new Handlebars.Exception("The partial "+b+" could not be found")}else{if(a instanceof Function){return a(d,options)}else{if(!Handlebars.compile){throw new Handlebars.Exception("The partial "+b+" could not be compiled when running in runtime-only mode")}else{c[b]=Handlebars.compile(a);return c[b](d,options)}}}}};Handlebars.template=Handlebars.VM.template;
\ No newline at end of file
diff -r cb5ff5b1bd67ca6333d808beefab24beedfeed94 -r 70397647fad54c50213e015aaedfed94e6b19eda static/scripts/packed/libs/underscore.js
--- /dev/null
+++ b/static/scripts/packed/libs/underscore.js
@@ -0,0 +1,1 @@
+(function(){var x=this;var t=x._;var b={};var j=Array.prototype,D=Object.prototype,G=Function.prototype;var v=j.slice,z=j.unshift,y=D.toString,p=D.hasOwnProperty;var n=j.forEach,i=j.map,B=j.reduce,e=j.reduceRight,m=j.filter,a=j.every,A=j.some,w=j.indexOf,f=j.lastIndexOf,c=Array.isArray,C=Object.keys,k=G.bind;var F=function(I){return new g(I)};if(typeof exports!=="undefined"){if(typeof module!=="undefined"&&module.exports){exports=module.exports=F}exports._=F}else{x._=F}F.VERSION="1.3.1";var d=F.each=F.forEach=function(N,M,L){if(N==null){return}if(n&&N.forEach===n){N.forEach(M,L)}else{if(N.length===+N.length){for(var K=0,I=N.length;K<I;K++){if(K in N&&M.call(L,N[K],K,N)===b){return}}}else{for(var J in N){if(F.has(N,J)){if(M.call(L,N[J],J,N)===b){return}}}}}};F.map=F.collect=function(L,K,J){var I=[];if(L==null){return I}if(i&&L.map===i){return L.map(K,J)}d(L,function(O,M,N){I[I.length]=K.call(J,O,M,N)});if(L.length===+L.length){I.length=L.length}return I};F.reduce=F.foldl=F.inject=function(M,L,I,K){var J=arguments.length>2;if(M==null){M=[]}if(B&&M.reduce===B){if(K){L=F.bind(L,K)}return J?M.reduce(L,I):M.reduce(L)}d(M,function(P,N,O){if(!J){I=P;J=true}else{I=L.call(K,I,P,N,O)}});if(!J){throw new TypeError("Reduce of empty array with no initial value")}return I};F.reduceRight=F.foldr=function(M,L,I,K){var J=arguments.length>2;if(M==null){M=[]}if(e&&M.reduceRight===e){if(K){L=F.bind(L,K)}return J?M.reduceRight(L,I):M.reduceRight(L)}var N=F.toArray(M).reverse();if(K&&!J){L=F.bind(L,K)}return J?F.reduce(N,L,I,K):F.reduce(N,L)};F.find=F.detect=function(L,K,J){var I;r(L,function(O,M,N){if(K.call(J,O,M,N)){I=O;return true}});return I};F.filter=F.select=function(L,K,J){var I=[];if(L==null){return I}if(m&&L.filter===m){return L.filter(K,J)}d(L,function(O,M,N){if(K.call(J,O,M,N)){I[I.length]=O}});return I};F.reject=function(L,K,J){var I=[];if(L==null){return I}d(L,function(O,M,N){if(!K.call(J,O,M,N)){I[I.length]=O}});return I};F.every=F.all=function(L,K,J){var I=true;if(L==null){return I}if(a&&L.every===a){return L.every(K,J)}d(L,function(O,M,N){if(!(I=I&&K.call(J,O,M,N))){return b}});return I};var r=F.some=F.any=function(L,K,J){K||(K=F.identity);var I=false;if(L==null){return I}if(A&&L.some===A){return L.some(K,J)}d(L,function(O,M,N){if(I||(I=K.call(J,O,M,N))){return b}});return !!I};F.include=F.contains=function(K,J){var I=false;if(K==null){return I}if(w&&K.indexOf===w){return K.indexOf(J)!=-1}I=r(K,function(L){return L===J});return I};F.invoke=function(J,K){var I=v.call(arguments,2);return F.map(J,function(L){return(F.isFunction(K)?K||L:L[K]).apply(L,I)})};F.pluck=function(J,I){return F.map(J,function(K){return K[I]})};F.max=function(L,K,J){if(!K&&F.isArray(L)){return Math.max.apply(Math,L)}if(!K&&F.isEmpty(L)){return -Infinity}var I={computed:-Infinity};d(L,function(P,M,O){var N=K?K.call(J,P,M,O):P;N>=I.computed&&(I={value:P,computed:N})});return I.value};F.min=function(L,K,J){if(!K&&F.isArray(L)){return Math.min.apply(Math,L)}if(!K&&F.isEmpty(L)){return Infinity}var I={computed:Infinity};d(L,function(P,M,O){var N=K?K.call(J,P,M,O):P;N<I.computed&&(I={value:P,computed:N})});return I.value};F.shuffle=function(K){var I=[],J;d(K,function(N,L,M){if(L==0){I[0]=N}else{J=Math.floor(Math.random()*(L+1));I[L]=I[J];I[J]=N}});return I};F.sortBy=function(K,J,I){return F.pluck(F.map(K,function(N,L,M){return{value:N,criteria:J.call(I,N,L,M)}}).sort(function(O,N){var M=O.criteria,L=N.criteria;return M<L?-1:M>L?1:0}),"value")};F.groupBy=function(K,L){var I={};var J=F.isFunction(L)?L:function(M){return M[L]};d(K,function(O,M){var N=J(O,M);(I[N]||(I[N]=[])).push(O)});return I};F.sortedIndex=function(N,M,K){K||(K=F.identity);var I=0,L=N.length;while(I<L){var J=(I+L)>>1;K(N[J])<K(M)?I=J+1:L=J}return I};F.toArray=function(I){if(!I){return[]}if(I.toArray){return I.toArray()}if(F.isArray(I)){return v.call(I)}if(F.isArguments(I)){return v.call(I)}return F.values(I)};F.size=function(I){return F.toArray(I).length};F.first=F.head=function(K,J,I){return(J!=null)&&!I?v.call(K,0,J):K[0]};F.initial=function(K,J,I){return v.call(K,0,K.length-((J==null)||I?1:J))};F.last=function(K,J,I){if((J!=null)&&!I){return v.call(K,Math.max(K.length-J,0))}else{return K[K.length-1]}};F.rest=F.tail=function(K,I,J){return v.call(K,(I==null)||J?1:I)};F.compact=function(I){return F.filter(I,function(J){return !!J})};F.flatten=function(J,I){return F.reduce(J,function(K,L){if(F.isArray(L)){return K.concat(I?L:F.flatten(L))}K[K.length]=L;return K},[])};F.without=function(I){return F.difference(I,v.call(arguments,1))};F.uniq=F.unique=function(M,L,K){var J=K?F.map(M,K):M;var I=[];F.reduce(J,function(N,P,O){if(0==O||(L===true?F.last(N)!=P:!F.include(N,P))){N[N.length]=P;I[I.length]=M[O]}return N},[]);return I};F.union=function(){return F.uniq(F.flatten(arguments,true))};F.intersection=F.intersect=function(J){var I=v.call(arguments,1);return F.filter(F.uniq(J),function(K){return F.every(I,function(L){return F.indexOf(L,K)>=0})})};F.difference=function(J){var I=F.flatten(v.call(arguments,1));return F.filter(J,function(K){return !F.include(I,K)})};F.zip=function(){var I=v.call(arguments);var L=F.max(F.pluck(I,"length"));var K=new Array(L);for(var J=0;J<L;J++){K[J]=F.pluck(I,""+J)}return K};F.indexOf=function(M,K,L){if(M==null){return -1}var J,I;if(L){J=F.sortedIndex(M,K);return M[J]===K?J:-1}if(w&&M.indexOf===w){return M.indexOf(K)}for(J=0,I=M.length;J<I;J++){if(J in M&&M[J]===K){return J}}return -1};F.lastIndexOf=function(K,J){if(K==null){return -1}if(f&&K.lastIndexOf===f){return K.lastIndexOf(J)}var I=K.length;while(I--){if(I in K&&K[I]===J){return I}}return -1};F.range=function(N,L,M){if(arguments.length<=1){L=N||0;N=0}M=arguments[2]||1;var J=Math.max(Math.ceil((L-N)/M),0);var I=0;var K=new Array(J);while(I<J){K[I++]=N;N+=M}return K};var h=function(){};F.bind=function H(L,J){var K,I;if(L.bind===k&&k){return k.apply(L,v.call(arguments,1))}if(!F.isFunction(L)){throw new TypeError}I=v.call(arguments,2);return K=function(){if(!(this instanceof K)){return L.apply(J,I.concat(v.call(arguments)))}h.prototype=L.prototype;var N=new h;var M=L.apply(N,I.concat(v.call(arguments)));if(Object(M)===M){return M}return N}};F.bindAll=function(J){var I=v.call(arguments,1);if(I.length==0){I=F.functions(J)}d(I,function(K){J[K]=F.bind(J[K],J)});return J};F.memoize=function(K,J){var I={};J||(J=F.identity);return function(){var L=J.apply(this,arguments);return F.has(I,L)?I[L]:(I[L]=K.apply(this,arguments))}};F.delay=function(J,K){var I=v.call(arguments,2);return setTimeout(function(){return J.apply(J,I)},K)};F.defer=function(I){return F.delay.apply(F,[I,1].concat(v.call(arguments,1)))};F.throttle=function(N,P){var L,I,O,M,K;var J=F.debounce(function(){K=M=false},P);return function(){L=this;I=arguments;var Q=function(){O=null;if(K){N.apply(L,I)}J()};if(!O){O=setTimeout(Q,P)}if(M){K=true}else{N.apply(L,I)}J();M=true}};F.debounce=function(I,K){var J;return function(){var N=this,M=arguments;var L=function(){J=null;I.apply(N,M)};clearTimeout(J);J=setTimeout(L,K)}};F.once=function(K){var I=false,J;return function(){if(I){return J}I=true;return J=K.apply(this,arguments)}};F.wrap=function(I,J){return function(){var K=[I].concat(v.call(arguments,0));return J.apply(this,K)}};F.compose=function(){var I=arguments;return function(){var J=arguments;for(var K=I.length-1;K>=0;K--){J=[I[K].apply(this,J)]}return J[0]}};F.after=function(J,I){if(J<=0){return I()}return function(){if(--J<1){return I.apply(this,arguments)}}};F.keys=C||function(K){if(K!==Object(K)){throw new TypeError("Invalid object")}var J=[];for(var I in K){if(F.has(K,I)){J[J.length]=I}}return J};F.values=function(I){return F.map(I,F.identity)};F.functions=F.methods=function(K){var J=[];for(var I in K){if(F.isFunction(K[I])){J.push(I)}}return J.sort()};F.extend=function(I){d(v.call(arguments,1),function(J){for(var K in J){I[K]=J[K]}});return I};F.defaults=function(I){d(v.call(arguments,1),function(J){for(var K in J){if(I[K]==null){I[K]=J[K]}}});return I};F.clone=function(I){if(!F.isObject(I)){return I}return F.isArray(I)?I.slice():F.extend({},I)};F.tap=function(J,I){I(J);return J};function E(L,K,J){if(L===K){return L!==0||1/L==1/K}if(L==null||K==null){return L===K}if(L._chain){L=L._wrapped}if(K._chain){K=K._wrapped}if(L.isEqual&&F.isFunction(L.isEqual)){return L.isEqual(K)}if(K.isEqual&&F.isFunction(K.isEqual)){return K.isEqual(L)}var O=y.call(L);if(O!=y.call(K)){return false}switch(O){case"[object String]":return L==String(K);case"[object Number]":return L!=+L?K!=+K:(L==0?1/L==1/K:L==+K);case"[object Date]":case"[object Boolean]":return +L==+K;case"[object RegExp]":return L.source==K.source&&L.global==K.global&&L.multiline==K.multiline&&L.ignoreCase==K.ignoreCase}if(typeof L!="object"||typeof K!="object"){return false}var P=J.length;while(P--){if(J[P]==L){return true}}J.push(L);var N=0,I=true;if(O=="[object Array]"){N=L.length;I=N==K.length;if(I){while(N--){if(!(I=N in L==N in K&&E(L[N],K[N],J))){break}}}}else{if("constructor" in L!="constructor" in K||L.constructor!=K.constructor){return false}for(var M in L){if(F.has(L,M)){N++;if(!(I=F.has(K,M)&&E(L[M],K[M],J))){break}}}if(I){for(M in K){if(F.has(K,M)&&!(N--)){break}}I=!N}}J.pop();return I}F.isEqual=function(J,I){return E(J,I,[])};F.isEmpty=function(J){if(F.isArray(J)||F.isString(J)){return J.length===0}for(var I in J){if(F.has(J,I)){return false}}return true};F.isElement=function(I){return !!(I&&I.nodeType==1)};F.isArray=c||function(I){return y.call(I)=="[object Array]"};F.isObject=function(I){return I===Object(I)};F.isArguments=function(I){return y.call(I)=="[object Arguments]"};if(!F.isArguments(arguments)){F.isArguments=function(I){return !!(I&&F.has(I,"callee"))}}F.isFunction=function(I){return y.call(I)=="[object Function]"};F.isString=function(I){return y.call(I)=="[object String]"};F.isNumber=function(I){return y.call(I)=="[object Number]"};F.isNaN=function(I){return I!==I};F.isBoolean=function(I){return I===true||I===false||y.call(I)=="[object Boolean]"};F.isDate=function(I){return y.call(I)=="[object Date]"};F.isRegExp=function(I){return y.call(I)=="[object RegExp]"};F.isNull=function(I){return I===null};F.isUndefined=function(I){return I===void 0};F.has=function(J,I){return p.call(J,I)};F.noConflict=function(){x._=t;return this};F.identity=function(I){return I};F.times=function(L,K,J){for(var I=0;I<L;I++){K.call(J,I)}};F.escape=function(I){return(""+I).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'").replace(/\//g,"/")};F.mixin=function(I){d(F.functions(I),function(J){s(J,F[J]=I[J])})};var l=0;F.uniqueId=function(I){var J=l++;return I?I+J:J};F.templateSettings={evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g};var u=/.^/;var q=function(I){return I.replace(/\\\\/g,"\\").replace(/\\'/g,"'")};F.template=function(L,K){var M=F.templateSettings;var I="var __p=[],print=function(){__p.push.apply(__p,arguments);};with(obj||{}){__p.push('"+L.replace(/\\/g,"\\\\").replace(/'/g,"\\'").replace(M.escape||u,function(N,O){return"',_.escape("+q(O)+"),'"}).replace(M.interpolate||u,function(N,O){return"',"+q(O)+",'"}).replace(M.evaluate||u,function(N,O){return"');"+q(O).replace(/[\r\n\t]/g," ")+";__p.push('"}).replace(/\r/g,"\\r").replace(/\n/g,"\\n").replace(/\t/g,"\\t")+"');}return __p.join('');";var J=new Function("obj","_",I);if(K){return J(K,F)}return function(N){return J.call(this,N,F)}};F.chain=function(I){return F(I).chain()};var g=function(I){this._wrapped=I};F.prototype=g.prototype;var o=function(J,I){return I?F(J).chain():J};var s=function(I,J){g.prototype[I]=function(){var K=v.call(arguments);z.call(K,this._wrapped);return o(J.apply(F,K),this._chain)}};F.mixin(F);d(["pop","push","reverse","shift","sort","splice","unshift"],function(I){var J=j[I];g.prototype[I]=function(){var K=this._wrapped;J.apply(K,arguments);var L=K.length;if((I=="shift"||I=="splice")&&L===0){delete K[0]}return o(K,this._chain)}});d(["concat","join","slice"],function(I){var J=j[I];g.prototype[I]=function(){return o(J.apply(this._wrapped,arguments),this._chain)}});g.prototype.chain=function(){this._chain=true;return this};g.prototype.value=function(){return this._wrapped}}).call(this);
\ No newline at end of file
diff -r cb5ff5b1bd67ca6333d808beefab24beedfeed94 -r 70397647fad54c50213e015aaedfed94e6b19eda static/scripts/packed/trackster.js
--- a/static/scripts/packed/trackster.js
+++ b/static/scripts/packed/trackster.js
@@ -1,1 +1,1 @@
-var class_module=function(b,a){var c=function(){var f=arguments[0];for(var e=1;e<arguments.length;e++){var d=arguments[e];for(key in d){f[key]=d[key]}}return f};a.extend=c};var requestAnimationFrame=(function(){return window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.oRequestAnimationFrame||window.msRequestAnimationFrame||function(b,a){window.setTimeout(b,1000/60)}})();var BEFORE=1001,CONTAINS=1002,OVERLAP_START=1003,OVERLAP_END=1004,CONTAINED_BY=1005,AFTER=1006;var compute_overlap=function(e,b){var g=e[0],f=e[1],d=b[0],c=b[1],a;if(g<d){if(f<d){a=BEFORE}else{if(f<=c){a=OVERLAP_START}else{a=CONTAINS}}}else{if(g>c){a=AFTER}else{if(f<=c){a=CONTAINED_BY}else{a=OVERLAP_END}}}return a};var is_overlap=function(c,b){var a=compute_overlap(c,b);return(a!==BEFORE&&a!==AFTER)};var is_deferred=function(a){return("isResolved" in a)};var get_random_color=function(a){if(!a){a="#ffffff"}if(typeof(a)==="string"){a=[a]}for(var j=0;j<a.length;j++){a[j]=parseInt(a[j].slice(1),16)}var n=function(t,s,i){return((t*299)+(s*587)+(i*114))/1000};var e=function(v,u,w,s,i,t){return(Math.max(v,s)-Math.min(v,s))+(Math.max(u,i)-Math.min(u,i))+(Math.max(w,t)-Math.min(w,t))};var g,o,f,k,q,h,r,c,d,b,p,m=false,l=0;do{g=Math.round(Math.random()*16777215);o=(g&16711680)>>16;f=(g&65280)>>8;k=g&255;d=n(o,f,k);m=true;for(var j=0;j<a.length;j++){q=a[j];h=(q&16711680)>>16;r=(q&65280)>>8;c=q&255;b=n(h,r,c);p=e(o,f,k,h,r,c);if((Math.abs(d-b)<40)||(p<200)){m=false;break}}l++}while(!m&&l<=10);return"#"+(16777216+g).toString(16).substr(1,6)};var create_action_icon=function(c,b,a){return $("<a/>").attr("href","javascript:void(0);").attr("title",c).addClass("icon-button").addClass(b).tipsy({gravity:"s"}).click(a)};var trackster_module=function(e,U){var p=e("class").extend,s=e("slotting"),J=e("painters");var ab=function(ac,ad){this.document=ac;this.default_font=ad!==undefined?ad:"9px Monaco, Lucida Console, monospace";this.dummy_canvas=this.new_canvas();this.dummy_context=this.dummy_canvas.getContext("2d");this.dummy_context.font=this.default_font;this.char_width_px=this.dummy_context.measureText("A").width;this.patterns={};this.load_pattern("right_strand","/visualization/strand_right.png");this.load_pattern("left_strand","/visualization/strand_left.png");this.load_pattern("right_strand_inv","/visualization/strand_right_inv.png");this.load_pattern("left_strand_inv","/visualization/strand_left_inv.png")};p(ab.prototype,{load_pattern:function(ac,ag){var ad=this.patterns,ae=this.dummy_context,af=new Image();af.src=image_path+ag;af.onload=function(){ad[ac]=ae.createPattern(af,"repeat")}},get_pattern:function(ac){return this.patterns[ac]},new_canvas:function(){var ac=this.document.createElement("canvas");if(window.G_vmlCanvasManager){G_vmlCanvasManager.initElement(ac)}ac.manager=this;return ac}});var n={};var l=function(ac,ad){n[ac.attr("id")]=ad};var m=function(ac,ae,ag,af){ag=".group";var ad={};n[ac.attr("id")]=af;ac.bind("drag",{handle:"."+ae,relative:true},function(ao,ap){var an=$(this);var at=$(this).parent(),ak=at.children(),am=n[$(this).attr("id")],aj,ai,aq,ah,al;ai=$(this).parents(ag);if(ai.length!==0){aq=ai.position().top;ah=aq+ai.outerHeight();if(ap.offsetY<aq){$(this).insertBefore(ai);var ar=n[ai.attr("id")];ar.remove_drawable(am);ar.container.add_drawable_before(am,ar);return}else{if(ap.offsetY>ah){$(this).insertAfter(ai);var ar=n[ai.attr("id")];ar.remove_drawable(am);ar.container.add_drawable(am);return}}}ai=null;for(al=0;al<ak.length;al++){aj=$(ak.get(al));aq=aj.position().top;ah=aq+aj.outerHeight();if(aj.is(ag)&&this!==aj.get(0)&&ap.offsetY>=aq&&ap.offsetY<=ah){if(ap.offsetY-aq<ah-ap.offsetY){aj.find(".content-div").prepend(this)}else{aj.find(".content-div").append(this)}if(am.container){am.container.remove_drawable(am)}n[aj.attr("id")].add_drawable(am);return}}var aj;for(al=0;al<ak.length;al++){aj=$(ak.get(al));if(ap.offsetY<aj.position().top&&!(aj.hasClass("reference-track")||aj.hasClass("intro"))){break}}if(al===ak.length){if(this!==ak.get(al-1)){at.append(this);n[at.attr("id")].move_drawable(am,al)}}else{if(this!==ak.get(al)){$(this).insertBefore(ak.get(al));n[at.attr("id")].move_drawable(am,(ap.deltaY>0?al-1:al))}}}).bind("dragstart",function(){ad["border-top"]=ac.css("border-top");ad["border-bottom"]=ac.css("border-bottom");$(this).css({"border-top":"1px solid blue","border-bottom":"1px solid blue"})}).bind("dragend",function(){$(this).css(ad)})};U.moveable=m;var aa=16,D=9,A=20,x=100,G=12000,R=400,I=5000,u=100,o="There was an error in indexing this dataset. ",H="A converter for this dataset is not installed. Please check your datatypes_conf.xml file.",B="No data for this chrom/contig.",t="Preparing data. This takes seconds for a small dataset but longer for a large dataset.<br/> You can save and close the visualization and preparation will continue.<br/>",v="Tool cannot be rerun: ",a="Loading data...",V="Ready for display",O=10,F=20;function W(ad,ac){if(!ac){ac=0}var ae=Math.pow(10,ac);return Math.round(ad*ae)/ae}var c=function(ac){this.num_elements=ac;this.clear()};p(c.prototype,{get:function(ad){var ac=this.key_ary.indexOf(ad);if(ac!==-1){if(this.obj_cache[ad].stale){this.key_ary.splice(ac,1);delete this.obj_cache[ad]}else{this.move_key_to_end(ad,ac)}}return this.obj_cache[ad]},set:function(ad,ae){if(!this.obj_cache[ad]){if(this.key_ary.length>=this.num_elements){var ac=this.key_ary.shift();delete this.obj_cache[ac]}this.key_ary.push(ad)}this.obj_cache[ad]=ae;return ae},move_key_to_end:function(ad,ac){this.key_ary.splice(ac,1);this.key_ary.push(ad)},clear:function(){this.obj_cache={};this.key_ary=[]},size:function(){return this.key_ary.length}});var P=function(ad,ac){c.call(this,ad);this.track=ac};p(P.prototype,c.prototype,{load_data:function(al,ag,aj,ad,ai){var ak=this.track.view.chrom,af={chrom:ak,low:al,high:ag,mode:aj,resolution:ad,dataset_id:this.track.dataset_id,hda_ldda:this.track.hda_ldda};$.extend(af,ai);if(this.track.filters_manager){var am=[];var ac=this.track.filters_manager.filters;for(var ah=0;ah<ac.length;ah++){am.push(ac[ah].name)}af.filter_cols=JSON.stringify(am)}var ae=this;return $.getJSON(this.track.data_url,af,function(an){ae.set_data(al,ag,an)})},get_data:function(ak,ae,ai,ad,ah){var al=this.get(ak,ae);if(al&&(is_deferred(al)||this.track.data_and_mode_compatible(al,ai))){return al}var am,aj,ac,ag,ai,al;for(var af=0;af<this.key_ary.length;af++){am=this.key_ary[af];aj=this.split_key(am);ac=aj[0];ag=aj[1];if(ak>=ac&&ae<=ag){var al=this.obj_cache[am];if(is_deferred(al)||(this.track.data_and_mode_compatible(al,ai)&&this.track.can_subset(al))){this.move_key_to_end(am,af);return al}}}al=this.load_data(ak,ae,ai,ad,ah);this.set_data(ak,ae,al);return al},DEEP_DATA_REQ:"deep",BROAD_DATA_REQ:"breadth",get_more_data:function(ak,af,aj,ae,ai,ag){var al=this.get(ak,af);if(!(al&&this.track.data_and_mode_compatible(al,aj))){console.log("ERROR: no current data for: ",this.track,ak,af,aj,ae,ai);return}al.stale=true;var ad=ak;if(ag===this.DEEP_DATA_REQ){$.extend(ai,{start_val:al.data.length+1})}else{if(ag===this.BROAD_DATA_REQ){ad=(al.max_high?al.max_high:al.data[al.data.length-1][2])+1}}var ac=this,ah=this.load_data(ad,af,aj,ae,ai);new_data_available=$.Deferred();this.set_data(ak,af,new_data_available);$.when(ah).then(function(am){if(am.data){am.data=al.data.concat(am.data);if(am.max_low){am.max_low=al.max_low}if(am.message){am.message=am.message.replace(/[0-9]+/,am.data.length)}}ac.set_data(ak,af,am);new_data_available.resolve(am)});return new_data_available},get:function(ac,ad){return c.prototype.get.call(this,this.gen_key(ac,ad))},set_data:function(ad,ae,ac){return this.set(this.gen_key(ad,ae),ac)},gen_key:function(ac,ae){var ad=ac+"_"+ae;return ad},split_key:function(ac){return ac.split("_")}});var E=function(ad,ac,ae){P.call(this,ad,ac,ae)};p(E.prototype,P.prototype,c.prototype,{get:P.prototype.get,load_data:function(ac,af,ag,ad,ae){if(ad>1){return{data:null}}return P.prototype.load_data.call(this,ac,af,ag,ad,ae)}});var q=function(ad,ac,af){if(!q.id_counter){q.id_counter=0}this.id=q.id_counter++;this.name=af.name;this.view=ad;this.container=ac;this.config=new C({track:this,params:[{key:"name",label:"Name",type:"text",default_value:this.name}],saved_values:af.prefs,onchange:function(){this.track.set_name(this.track.config.values.name)}});this.prefs=this.config.values;this.drag_handle_class=af.drag_handle_class;this.is_overview=false;this.action_icons={};this.content_visible=true;this.container_div=this.build_container_div();this.header_div=this.build_header_div();if(this.header_div){this.container_div.append(this.header_div);this.icons_div=$("<div/>").css("float","left").hide().appendTo(this.header_div);this.build_action_icons(this.action_icons_def);this.header_div.append($("<div style='clear: both'/>"));this.header_div.dblclick(function(ag){ag.stopPropagation()});var ae=this;this.container_div.hover(function(){ae.icons_div.show()},function(){ae.icons_div.hide()});$("<div style='clear: both'/>").appendTo(this.container_div)}};q.prototype.action_icons_def=[{name:"toggle_icon",title:"Hide/show content",css_class:"toggle",on_click_fn:function(ac){if(ac.content_visible){ac.action_icons.toggle_icon.addClass("toggle-expand").removeClass("toggle");ac.hide_contents();ac.content_visible=false}else{ac.action_icons.toggle_icon.addClass("toggle").removeClass("toggle-expand");ac.content_visible=true;ac.show_contents()}}},{name:"settings_icon",title:"Edit settings",css_class:"settings-icon",on_click_fn:function(ad){var af=function(){hide_modal();$(window).unbind("keypress.check_enter_esc")},ac=function(){ad.config.update_from_form($(".dialog-box"));hide_modal();$(window).unbind("keypress.check_enter_esc")},ae=function(ag){if((ag.keyCode||ag.which)===27){af()}else{if((ag.keyCode||ag.which)===13){ac()}}};$(window).bind("keypress.check_enter_esc",ae);show_modal("Configure",ad.config.build_form(),{Cancel:af,OK:ac})}},{name:"remove_icon",title:"Remove",css_class:"remove-icon",on_click_fn:function(ac){$(".tipsy").remove();ac.remove()}}];p(q.prototype,{init:function(){},changed:function(){this.view.changed()},can_draw:function(){if(this.enabled&&this.content_visible){return true}return false},request_draw:function(){},_draw:function(){},to_dict:function(){},update_icons:function(){},set_name:function(ac){this.old_name=this.name;this.name=ac;this.name_div.text(this.name)},revert_name:function(){if(this.old_name){this.name=this.old_name;this.name_div.text(this.name)}},remove:function(){this.changed();this.container.remove_drawable(this);var ac=this.view;this.container_div.hide(0,function(){$(this).remove();ac.update_intro_div()})},build_container_div:function(){},build_header_div:function(){},add_action_icon:function(ad,ai,ah,ag,ac,af){var ae=this;this.action_icons[ad]=$("<a/>").attr("href","javascript:void(0);").attr("title",ai).addClass("icon-button").addClass(ah).tipsy({gravity:"s"}).click(function(){ag(ae)}).appendTo(this.icons_div);if(af){this.action_icons[ad].hide()}},build_action_icons:function(ac){var ae;for(var ad=0;ad<ac.length;ad++){ae=ac[ad];this.add_action_icon(ae.name,ae.title,ae.css_class,ae.on_click_fn,ae.prepend,ae.hide)}},update_icons:function(){},hide_contents:function(){},show_contents:function(){}});var w=function(ad,ac,ae){q.call(this,ad,ac,ae);this.obj_type=ae.obj_type;this.drawables=[]};p(w.prototype,q.prototype,{unpack_drawables:function(ae){this.drawables=[];var ad;for(var ac=0;ac<ae.length;ac++){ad=object_from_template(ae[ac],this);this.add_drawable(ad)}},init:function(){for(var ac=0;ac<this.drawables.length;ac++){this.drawables[ac].init()}},_draw:function(){for(var ac=0;ac<this.drawables.length;ac++){this.drawables[ac]._draw()}},to_dict:function(){var ad=[];for(var ac=0;ac<this.drawables.length;ac++){ad.push(this.drawables[ac].to_dict())}return{name:this.name,prefs:this.prefs,obj_type:this.obj_type,drawables:ad}},add_drawable:function(ac){this.drawables.push(ac);ac.container=this;this.changed()},add_drawable_before:function(ae,ac){this.changed();var ad=this.drawables.indexOf(ac);if(ad!==-1){this.drawables.splice(ad,0,ae);return true}return false},replace_drawable:function(ae,ac,ad){var af=this.drawables.indexOf(ae);if(af!==-1){this.drawables[af]=ac;if(ad){ae.container_div.replaceWith(ac.container_div)}this.changed()}return af},remove_drawable:function(ad){var ac=this.drawables.indexOf(ad);if(ac!==-1){this.drawables.splice(ac,1);ad.container=null;this.changed();return true}return false},move_drawable:function(ad,ae){var ac=this.drawables.indexOf(ad);if(ac!==-1){this.drawables.splice(ac,1);this.drawables.splice(ae,0,ad);this.changed();return true}return false}});var N=function(ad,ac,af){p(af,{obj_type:"DrawableGroup",drag_handle_class:"group-handle"});w.call(this,ad,ac,af);this.content_div=$("<div/>").addClass("content-div").attr("id","group_"+this.id+"_content_div").appendTo(this.container_div);l(this.container_div,this);l(this.content_div,this);m(this.container_div,this.drag_handle_class,".group",this);this.filters_manager=new X(this);this.header_div.after(this.filters_manager.parent_div);this.saved_filters_managers=[];if("drawables" in af){this.unpack_drawables(af.drawables)}if("filters" in af){var ae=this.filters_manager;this.filters_manager=new X(this,af.filters);ae.parent_div.replaceWith(this.filters_manager.parent_div);if(af.filters.visible){this.setup_multitrack_filtering()}}};p(N.prototype,q.prototype,w.prototype,{action_icons_def:[q.prototype.action_icons_def[0],q.prototype.action_icons_def[1],{name:"composite_icon",title:"Show composite track",css_class:"layers-stack",on_click_fn:function(ac){$(".tipsy").remove();ac.show_composite_track()}},{name:"filters_icon",title:"Filters",css_class:"filters-icon",on_click_fn:function(ac){if(ac.filters_manager.visible()){ac.filters_manager.clear_filters();ac._restore_filter_managers()}else{ac.setup_multitrack_filtering();ac.request_draw(true)}ac.filters_manager.toggle()}},q.prototype.action_icons_def[2]],build_container_div:function(){var ac=$("<div/>").addClass("group").attr("id","group_"+this.id);if(this.container){this.container.content_div.append(ac)}return ac},build_header_div:function(){var ac=$("<div/>").addClass("track-header");ac.append($("<div/>").addClass(this.drag_handle_class));this.name_div=$("<div/>").addClass("track-name").text(this.name).appendTo(ac);return ac},hide_contents:function(){this.tiles_div.hide()},show_contents:function(){this.tiles_div.show();this.request_draw()},update_icons:function(){var ae=this.drawables.length;if(ae===0){this.action_icons.composite_icon.hide();this.action_icons.filters_icon.hide()}else{if(ae===1){if(this.drawables[0] instanceof h){this.action_icons.composite_icon.show()}this.action_icons.filters_icon.hide()}else{var ai,ao=true,ag=this.drawables[0].get_type(),ac=0;for(var al=0;al<ae;al++){ai=this.drawables[al];if(ai.get_type()!==ag){can_composite=false;break}if(ai instanceof d){ac++}}if(ao||ac===1){this.action_icons.composite_icon.show()}else{this.action_icons.composite_icon.hide();$(".tipsy").remove()}if(ac>1&&ac===this.drawables.length){var ap={},ad;ai=this.drawables[0];for(var ak=0;ak<ai.filters_manager.filters.length;ak++){ad=ai.filters_manager.filters[ak];ap[ad.name]=[ad]}for(var al=1;al<this.drawables.length;al++){ai=this.drawables[al];for(var ak=0;ak<ai.filters_manager.filters.length;ak++){ad=ai.filters_manager.filters[ak];if(ad.name in ap){ap[ad.name].push(ad)}}}this.filters_manager.remove_all();var af,ah,aj,am;for(var an in ap){af=ap[an];if(af.length===ac){ah=new S({name:af[0].name,index:af[0].index});this.filters_manager.add_filter(ah)}}if(this.filters_manager.filters.length>0){this.action_icons.filters_icon.show()}else{this.action_icons.filters_icon.hide()}}else{this.action_icons.filters_icon.hide()}}}},_restore_filter_managers:function(){for(var ac=0;ac<this.drawables.length;ac++){this.drawables[ac].filters_manager=this.saved_filters_managers[ac]}this.saved_filters_managers=[]},setup_multitrack_filtering:function(){if(this.filters_manager.filters.length>0){this.saved_filters_managers=[];for(var ac=0;ac<this.drawables.length;ac++){drawable=this.drawables[ac];this.saved_filters_managers.push(drawable.filters_manager);drawable.filters_manager=this.filters_manager}}this.filters_manager.init_filters()},show_composite_track:function(){var ag=[];for(var ad=0;ad<this.drawables.length;ad++){ag.push(this.drawables[ad].name)}var ae="Composite Track of "+this.drawables.length+" tracks ("+ag.join(", ")+")";var af=new h(this.view,this.view,{name:ae,drawables:this.drawables});var ac=this.container.replace_drawable(this,af,true);af.request_draw()},add_drawable:function(ac){w.prototype.add_drawable.call(this,ac);this.update_icons()},remove_drawable:function(ac){w.prototype.remove_drawable.call(this,ac);this.update_icons()},to_dict:function(){if(this.filters_manager.visible()){this._restore_filter_managers()}var ac=p(w.prototype.to_dict.call(this),{filters:this.filters_manager.to_dict()});if(this.filters_manager.visible()){this.setup_multitrack_filtering()}return ac},request_draw:function(ac,ae){for(var ad=0;ad<this.drawables.length;ad++){this.drawables[ad].request_draw(ac,ae)}}});var Z=function(ac){p(ac,{obj_type:"View"});w.call(this,"View",ac.container,ac);this.chrom=null;this.vis_id=ac.vis_id;this.dbkey=ac.dbkey;this.label_tracks=[];this.tracks_to_be_redrawn=[];this.max_low=0;this.max_high=0;this.zoom_factor=3;this.min_separation=30;this.has_changes=false;this.load_chroms_deferred=null;this.init();this.canvas_manager=new ab(this.container.get(0).ownerDocument);this.reset()};p(Z.prototype,w.prototype,{init:function(){this.requested_redraw=false;var ae=this.container,ac=this;this.top_container=$("<div/>").addClass("top-container").appendTo(ae);this.browser_content_div=$("<div/>").addClass("content").css("position","relative").appendTo(ae);this.bottom_container=$("<div/>").addClass("bottom-container").appendTo(ae);this.top_labeltrack=$("<div/>").addClass("top-labeltrack").appendTo(this.top_container);this.viewport_container=$("<div/>").addClass("viewport-container").attr("id","viewport-container").appendTo(this.browser_content_div);this.content_div=this.viewport_container;l(this.viewport_container,ac);this.intro_div=$("<div/>").addClass("intro").appendTo(this.viewport_container).hide();var af=$("<div/>").text("Add Datasets to Visualization").addClass("action-button").appendTo(this.intro_div).click(function(){add_tracks()});this.nav_labeltrack=$("<div/>").addClass("nav-labeltrack").appendTo(this.bottom_container);this.nav_container=$("<div/>").addClass("trackster-nav-container").prependTo(this.top_container);this.nav=$("<div/>").addClass("trackster-nav").appendTo(this.nav_container);this.overview=$("<div/>").addClass("overview").appendTo(this.bottom_container);this.overview_viewport=$("<div/>").addClass("overview-viewport").appendTo(this.overview);this.overview_close=$("<a/>").attr("href","javascript:void(0);").attr("title","Close overview").addClass("icon-button overview-close tooltip").hide().appendTo(this.overview_viewport);this.overview_highlight=$("<div/>").addClass("overview-highlight").hide().appendTo(this.overview_viewport);this.overview_box_background=$("<div/>").addClass("overview-boxback").appendTo(this.overview_viewport);this.overview_box=$("<div/>").addClass("overview-box").appendTo(this.overview_viewport);this.default_overview_height=this.overview_box.height();this.nav_controls=$("<div/>").addClass("nav-controls").appendTo(this.nav);this.chrom_select=$("<select/>").attr({name:"chrom"}).css("width","15em").addClass("no-autocomplete").append("<option value=''>Loading</option>").appendTo(this.nav_controls);var ad=function(ag){if(ag.type==="focusout"||(ag.keyCode||ag.which)===13||(ag.keyCode||ag.which)===27){if((ag.keyCode||ag.which)!==27){ac.go_to($(this).val())}$(this).hide();$(this).val("");ac.location_span.show();ac.chrom_select.show()}};this.nav_input=$("<input/>").addClass("nav-input").hide().bind("keyup focusout",ad).appendTo(this.nav_controls);this.location_span=$("<span/>").addClass("location").attr("original-title","Click to change location").tipsy({gravity:"n"}).appendTo(this.nav_controls);this.location_span.click(function(){ac.location_span.hide();ac.chrom_select.hide();ac.nav_input.val(ac.chrom+":"+ac.low+"-"+ac.high);ac.nav_input.css("display","inline-block");ac.nav_input.select();ac.nav_input.focus()});if(this.vis_id!==undefined){this.hidden_input=$("<input/>").attr("type","hidden").val(this.vis_id).appendTo(this.nav_controls)}this.zo_link=$("<a/>").attr("id","zoom-out").attr("title","Zoom out").tipsy({gravity:"n"}).click(function(){ac.zoom_out();ac.request_redraw()}).appendTo(this.nav_controls);this.zi_link=$("<a/>").attr("id","zoom-in").attr("title","Zoom in").tipsy({gravity:"n"}).click(function(){ac.zoom_in();ac.request_redraw()}).appendTo(this.nav_controls);this.load_chroms_deferred=this.load_chroms({low:0});this.chrom_select.bind("change",function(){ac.change_chrom(ac.chrom_select.val())});this.browser_content_div.click(function(ag){$(this).find("input").trigger("blur")});this.browser_content_div.bind("dblclick",function(ag){ac.zoom_in(ag.pageX,this.viewport_container)});this.overview_box.bind("dragstart",function(ag,ah){this.current_x=ah.offsetX}).bind("drag",function(ag,ai){var aj=ai.offsetX-this.current_x;this.current_x=ai.offsetX;var ah=Math.round(aj/ac.viewport_container.width()*(ac.max_high-ac.max_low));ac.move_delta(-ah)});this.overview_close.click(function(){ac.reset_overview()});this.viewport_container.bind("draginit",function(ag,ah){if(ag.clientX>ac.viewport_container.width()-16){return false}}).bind("dragstart",function(ag,ah){ah.original_low=ac.low;ah.current_height=ag.clientY;ah.current_x=ah.offsetX}).bind("drag",function(ai,ak){var ag=$(this);var al=ak.offsetX-ak.current_x;var ah=ag.scrollTop()-(ai.clientY-ak.current_height);ag.scrollTop(ah);ak.current_height=ai.clientY;ak.current_x=ak.offsetX;var aj=Math.round(al/ac.viewport_container.width()*(ac.high-ac.low));ac.move_delta(aj)}).bind("mousewheel",function(ai,ak,ah,ag){if(ah){ah*=50;var aj=Math.round(-ah/ac.viewport_container.width()*(ac.high-ac.low));ac.move_delta(aj)}});this.top_labeltrack.bind("dragstart",function(ag,ah){return $("<div />").css({height:ac.browser_content_div.height()+ac.top_labeltrack.height()+ac.nav_labeltrack.height()+1,top:"0px",position:"absolute","background-color":"#ccf",opacity:0.5,"z-index":1000}).appendTo($(this))}).bind("drag",function(ak,al){$(al.proxy).css({left:Math.min(ak.pageX,al.startX)-ac.container.offset().left,width:Math.abs(ak.pageX-al.startX)});var ah=Math.min(ak.pageX,al.startX)-ac.container.offset().left,ag=Math.max(ak.pageX,al.startX)-ac.container.offset().left,aj=(ac.high-ac.low),ai=ac.viewport_container.width();ac.update_location(Math.round(ah/ai*aj)+ac.low,Math.round(ag/ai*aj)+ac.low)}).bind("dragend",function(al,am){var ah=Math.min(al.pageX,am.startX),ag=Math.max(al.pageX,am.startX),aj=(ac.high-ac.low),ai=ac.viewport_container.width(),ak=ac.low;ac.low=Math.round(ah/ai*aj)+ak;ac.high=Math.round(ag/ai*aj)+ak;$(am.proxy).remove();ac.request_redraw()});this.add_label_track(new Y(this,{content_div:this.top_labeltrack}));this.add_label_track(new Y(this,{content_div:this.nav_labeltrack}));$(window).bind("resize",function(){ac.resize_window()});$(document).bind("redraw",function(){ac.redraw()});this.reset();$(window).trigger("resize")},changed:function(){this.has_changes=true},update_intro_div:function(){if(this.drawables.length===0){this.intro_div.show()}else{this.intro_div.hide()}},update_location:function(ac,ad){this.location_span.text(commatize(ac)+" - "+commatize(ad));this.nav_input.val(this.chrom+":"+commatize(ac)+"-"+commatize(ad))},load_chroms:function(ae){ae.num=u;ae.dbkey=this.dbkey;var ac=this,ad=$.Deferred();$.ajax({url:chrom_url,data:ae,dataType:"json",success:function(ag){if(ag.chrom_info.length===0){alert("Invalid chromosome: "+ae.chrom);return}if(ag.reference){ac.add_label_track(new y(ac))}ac.chrom_data=ag.chrom_info;var aj='<option value="">Select Chrom/Contig</option>';for(var ai=0,af=ac.chrom_data.length;ai<af;ai++){var ah=ac.chrom_data[ai].chrom;aj+='<option value="'+ah+'">'+ah+"</option>"}if(ag.prev_chroms){aj+='<option value="previous">Previous '+u+"</option>"}if(ag.next_chroms){aj+='<option value="next">Next '+u+"</option>"}ac.chrom_select.html(aj);ac.chrom_start_index=ag.start_index;ad.resolve(ag)},error:function(){alert("Could not load chroms for this dbkey:",ac.dbkey)}});return ad},change_chrom:function(ah,ad,aj){if(!ah||ah==="None"){return}var ae=this;if(ah==="previous"){ae.load_chroms({low:this.chrom_start_index-u});return}if(ah==="next"){ae.load_chroms({low:this.chrom_start_index+u});return}var ai=$.grep(ae.chrom_data,function(ak,al){return ak.chrom===ah})[0];if(ai===undefined){ae.load_chroms({chrom:ah},function(){ae.change_chrom(ah,ad,aj)});return}else{if(ah!==ae.chrom){ae.chrom=ah;ae.chrom_select.val(ae.chrom);ae.max_high=ai.len-1;ae.reset();ae.request_redraw(true);for(var ag=0,ac=ae.drawables.length;ag<ac;ag++){var af=ae.drawables[ag];if(af.init){af.init()}}if(ae.reference_track){ae.reference_track.init()}}if(ad!==undefined&&aj!==undefined){ae.low=Math.max(ad,0);ae.high=Math.min(aj,ae.max_high)}ae.reset_overview();ae.request_redraw()}},go_to:function(ag){ag=ag.replace(/ |,/g,"");var ak=this,ac,af,ad=ag.split(":"),ai=ad[0],aj=ad[1];if(aj!==undefined){try{var ah=aj.split("-");ac=parseInt(ah[0],10);af=parseInt(ah[1],10)}catch(ae){return false}}ak.change_chrom(ai,ac,af)},move_fraction:function(ae){var ac=this;var ad=ac.high-ac.low;this.move_delta(ae*ad)},move_delta:function(ae){var ac=this;var ad=ac.high-ac.low;if(ac.low-ae<ac.max_low){ac.low=ac.max_low;ac.high=ac.max_low+ad}else{if(ac.high-ae>ac.max_high){ac.high=ac.max_high;ac.low=ac.max_high-ad}else{ac.high-=ae;ac.low-=ae}}ac.request_redraw()},add_drawable:function(ac){w.prototype.add_drawable.call(this,ac);ac.init();this.changed();this.update_intro_div()},add_label_track:function(ac){ac.view=this;ac.init();this.label_tracks.push(ac)},remove_drawable:function(ae,ad){w.prototype.remove_drawable.call(this,ae);if(ad){var ac=this;ae.container_div.hide(0,function(){$(this).remove();ac.update_intro_div()})}},reset:function(){this.low=this.max_low;this.high=this.max_high;this.viewport_container.find(".yaxislabel").remove()},request_redraw:function(ak,ac,aj,ad){var ai=this,ag=(ad?[ad]:ai.drawables),ae;var ad;for(var ah=0;ah<ag.length;ah++){ad=ag[ah];ae=-1;for(var af=0;af<ai.tracks_to_be_redrawn.length;af++){if(ai.tracks_to_be_redrawn[af][0]===ad){ae=af;break}}if(ae<0){ai.tracks_to_be_redrawn.push([ad,ac,aj])}else{ai.tracks_to_be_redrawn[ah][1]=ac;ai.tracks_to_be_redrawn[ah][2]=aj}}if(!this.requested_redraw){requestAnimationFrame(function(){ai._redraw(ak)});this.requested_redraw=true}},_redraw:function(am){this.requested_redraw=false;var aj=this.low,af=this.high;if(aj<this.max_low){aj=this.max_low}if(af>this.max_high){af=this.max_high}var al=this.high-this.low;if(this.high!==0&&al<this.min_separation){af=aj+this.min_separation}this.low=Math.floor(aj);this.high=Math.ceil(af);this.resolution_b_px=(this.high-this.low)/this.viewport_container.width();this.resolution_px_b=this.viewport_container.width()/(this.high-this.low);var ac=(this.low/(this.max_high-this.max_low)*this.overview_viewport.width())||0;var ai=((this.high-this.low)/(this.max_high-this.max_low)*this.overview_viewport.width())||0;var an=13;this.overview_box.css({left:ac,width:Math.max(an,ai)}).show();if(ai<an){this.overview_box.css("left",ac-(an-ai)/2)}if(this.overview_highlight){this.overview_highlight.css({left:ac,width:ai})}this.update_location(this.low,this.high);if(!am){var ae,ad,ak;for(var ag=0,ah=this.tracks_to_be_redrawn.length;ag<ah;ag++){ae=this.tracks_to_be_redrawn[ag][0];ad=this.tracks_to_be_redrawn[ag][1];ak=this.tracks_to_be_redrawn[ag][2];if(ae){ae._draw(ad,ak)}}this.tracks_to_be_redrawn=[];for(ag=0,ah=this.label_tracks.length;ag<ah;ag++){this.label_tracks[ag]._draw()}}},zoom_in:function(ad,ae){if(this.max_high===0||this.high-this.low<this.min_separation){return}var af=this.high-this.low,ag=af/2+this.low,ac=(af/this.zoom_factor)/2;if(ad){ag=ad/this.viewport_container.width()*(this.high-this.low)+this.low}this.low=Math.round(ag-ac);this.high=Math.round(ag+ac);this.changed();this.request_redraw()},zoom_out:function(){if(this.max_high===0){return}var ad=this.high-this.low,ae=ad/2+this.low,ac=(ad*this.zoom_factor)/2;this.low=Math.round(ae-ac);this.high=Math.round(ae+ac);this.changed();this.request_redraw()},resize_window:function(){this.viewport_container.height(this.container.height()-this.top_container.height()-this.bottom_container.height());this.request_redraw()},set_overview:function(ae){if(this.overview_drawable){if(this.overview_drawable.dataset_id===ae.dataset_id){return}this.overview_viewport.find(".track").remove()}var ad=ae.copy({content_div:this.overview_viewport}),ac=this;ad.header_div.hide();ad.is_overview=true;ac.overview_drawable=ad;this.overview_drawable.postdraw_actions=function(){ac.overview_highlight.show().height(ac.overview_drawable.content_div.height());ac.overview_viewport.height(ac.overview_drawable.content_div.height()+ac.overview_box.outerHeight());ac.overview_close.show();ac.resize_window()};ac.overview_drawable.request_draw();this.changed()},reset_overview:function(){$(".tipsy").remove();this.overview_viewport.find(".track-tile").remove();this.overview_viewport.height(this.default_overview_height);this.overview_box.height(this.default_overview_height);this.overview_close.hide();this.overview_highlight.hide();view.resize_window();view.overview_drawable=null}});var r=function(ae,aj,af){this.track=ae;this.name=aj.name;this.params=[];var aq=aj.params;for(var ag=0;ag<aq.length;ag++){var al=aq[ag],ad=al.name,ap=al.label,ah=unescape(al.html),ar=al.value,an=al.type;if(an==="number"){this.params.push(new f(ad,ap,ah,(ad in af?af[ad]:ar),al.min,al.max))}else{if(an==="select"){this.params.push(new L(ad,ap,ah,(ad in af?af[ad]:ar)))}else{console.log("WARNING: unrecognized tool parameter type:",ad,an)}}}this.parent_div=$("<div/>").addClass("dynamic-tool").hide();this.parent_div.bind("drag",function(au){au.stopPropagation()}).click(function(au){au.stopPropagation()}).bind("dblclick",function(au){au.stopPropagation()});var ao=$("<div class='tool-name'>").appendTo(this.parent_div).text(this.name);var am=this.params;var ak=this;$.each(this.params,function(av,ay){var ax=$("<div>").addClass("param-row").appendTo(ak.parent_div);var au=$("<div>").addClass("param-label").text(ay.label).appendTo(ax);var aw=$("<div/>").addClass("param-input").html(ay.html).appendTo(ax);aw.find(":input").val(ay.value);$("<div style='clear: both;'/>").appendTo(ax)});this.parent_div.find("input").click(function(){$(this).select()});var at=$("<div>").addClass("param-row").appendTo(this.parent_div);var ai=$("<input type='submit'>").attr("value","Run on complete dataset").appendTo(at);var ac=$("<input type='submit'>").attr("value","Run on visible region").css("margin-left","3em").appendTo(at);var ak=this;ac.click(function(){ak.run_on_region()});ai.click(function(){ak.run_on_dataset()});if("visible" in af&&af.visible){this.parent_div.show()}};p(r.prototype,{update_params:function(){for(var ac=0;ac<this.params.length;ac++){this.params[ac].update_value()}},state_dict:function(){var ad={};for(var ac=0;ac<this.params.length;ac++){ad[this.params[ac].name]=this.params[ac].value}ad.visible=this.parent_div.is(":visible");return ad},get_param_values_dict:function(){var ac={};this.parent_div.find(":input").each(function(){var ad=$(this).attr("name"),ae=$(this).val();ac[ad]=JSON.stringify(ae)});return ac},get_param_values:function(){var ad=[];var ac={};this.parent_div.find(":input").each(function(){var ae=$(this).attr("name"),af=$(this).val();if(ae){ad[ad.length]=af}});return ad},run_on_dataset:function(){var ac=this;ac.run({dataset_id:this.track.original_dataset_id,tool_id:ac.name},null,function(ad){show_modal(ac.name+" is Running",ac.name+" is running on the complete dataset. Tool outputs are in dataset's history.",{Close:hide_modal})})},run_on_region:function(){var ad={dataset_id:this.track.original_dataset_id,chrom:this.track.view.chrom,low:this.track.view.low,high:this.track.view.high,tool_id:this.name},ah=this.track,ae=ad.tool_id+ah.tool_region_and_parameters_str(ad.chrom,ad.low,ad.high),ac;if(ah.container===view){var ag=new N(view,view,{name:this.name});var af=ah.container.replace_drawable(ah,ag,false);ag.container_div.insertBefore(ah.view.content_div.children()[af]);ag.add_drawable(ah);ah.container_div.appendTo(ag.content_div);ac=ag}else{ac=ah.container}var ai=new ah.constructor(view,ac,{name:ae,hda_ldda:"hda"});ai.init_for_tool_data();ai.change_mode(ah.mode);ai.set_filters_manager(ah.filters_manager.copy(ai));ai.update_icons();ac.add_drawable(ai);ai.tiles_div.text("Starting job.");this.update_params();this.run(ad,ai,function(aj){ai.dataset_id=aj.dataset_id;ai.tiles_div.text("Running job.");ai.init()})},run:function(ad,ae,af){$.extend(ad,this.get_param_values_dict());var ac=function(){$.getJSON(rerun_tool_url,ad,function(ag){if(ag==="no converter"){ae.container_div.addClass("error");ae.content_div.text(H)}else{if(ag.error){ae.container_div.addClass("error");ae.content_div.text(v+ag.message)}else{if(ag==="pending"){ae.container_div.addClass("pending");ae.content_div.text("Converting input data so that it can be used quickly with tool.");setTimeout(ac,2000)}else{af(ag)}}}})};ac()}});var L=function(ad,ac,ae,af){this.name=ad;this.label=ac;this.html=$(ae);this.value=af};p(L.prototype,{update_value:function(){this.value=$(this.html).val()}});var f=function(ae,ad,ag,ah,af,ac){L.call(this,ae,ad,ag,ah);this.min=af;this.max=ac};p(f.prototype,L.prototype,{update_value:function(){L.prototype.update_value.call(this);this.value=parseFloat(this.value)}});var g=function(ac){this.manager=null;this.name=ac.name;this.index=ac.index;this.tool_id=ac.tool_id;this.tool_exp_name=ac.tool_exp_name};p(g.prototype,{to_dict:function(){return{name:this.name,index:this.index,tool_id:this.tool_id,tool_exp_name:this.tool_exp_name}}});var S=function(al){g.call(this,al);this.low=("low" in al?al.low:-Number.MAX_VALUE);this.high=("high" in al?al.high:Number.MAX_VALUE);this.min=("min" in al?al.min:Number.MAX_VALUE);this.max=("max" in al?al.max:-Number.MAX_VALUE);this.container=null;this.slider=null;this.slider_label=null;var ah=function(am,an,ao){am.click(function(){var au=an.text(),ar=parseFloat(ao.slider("option","max")),aq=(ar<=1?4:ar<=1000000?ar.toString().length:6),at=false,ap=$(this).parents(".slider-row");ap.addClass("input");if(ao.slider("option","values")){aq=2*aq+1;at=true}an.text("");$("<input type='text'/>").attr("size",aq).attr("maxlength",aq).attr("value",au).appendTo(an).focus().select().click(function(av){av.stopPropagation()}).blur(function(){$(this).remove();an.text(au);ap.removeClass("input")}).keyup(function(az){if(az.keyCode===27){$(this).trigger("blur")}else{if(az.keyCode===13){var ax=ao.slider("option","min"),av=ao.slider("option","max"),ay=function(aA){return(isNaN(aA)||aA>av||aA<ax)},aw=$(this).val();if(!at){aw=parseFloat(aw);if(ay(aw)){alert("Parameter value must be in the range ["+ax+"-"+av+"]");return $(this)}}else{aw=aw.split("-");aw=[parseFloat(aw[0]),parseFloat(aw[1])];if(ay(aw[0])||ay(aw[1])){alert("Parameter value must be in the range ["+ax+"-"+av+"]");return $(this)}}ao.slider((at?"values":"value"),aw);ap.removeClass("input")}}})})};var ad=this;ad.parent_div=$("<div/>").addClass("filter-row slider-row");var ac=$("<div/>").addClass("elt-label").appendTo(ad.parent_div),aj=$("<span/>").addClass("slider-name").text(ad.name+" ").appendTo(ac),ae=$("<span/>").text(this.low+"-"+this.high),af=$("<span/>").addClass("slider-value").appendTo(ac).append("[").append(ae).append("]");ad.values_span=ae;var ai=$("<div/>").addClass("slider").appendTo(ad.parent_div);ad.control_element=$("<div/>").attr("id",ad.name+"-filter-control").appendTo(ai);var ag=[0,0];ad.control_element.slider({range:true,min:this.min,max:this.max,step:this.get_slider_step(this.min,this.max),values:[this.low,this.high],slide:function(am,an){ad.slide(am,an)},change:function(am,an){ad.control_element.slider("option","slide").call(ad.control_element,am,an)}});ad.slider=ad.control_element;ad.slider_label=ae;ah(af,ae,ad.control_element);var ak=$("<div/>").addClass("display-controls").appendTo(ad.parent_div);this.transparency_icon=create_action_icon("Use filter for data transparency","layer-transparent",function(){if(ad.manager.alpha_filter!==ad){ad.manager.alpha_filter=ad;ad.manager.parent_div.find(".layer-transparent").removeClass("active").hide();ad.transparency_icon.addClass("active").show()}else{ad.manager.alpha_filter=null;ad.transparency_icon.removeClass("active")}ad.manager.track.request_draw(true,true)}).appendTo(ak).hide();this.height_icon=create_action_icon("Use filter for data height","arrow-resize-090",function(){if(ad.manager.height_filter!==ad){ad.manager.height_filter=ad;ad.manager.parent_div.find(".arrow-resize-090").removeClass("active").hide();ad.height_icon.addClass("active").show()}else{ad.manager.height_filter=null;ad.height_icon.removeClass("active")}ad.manager.track.request_draw(true,true)}).appendTo(ak).hide();ad.parent_div.hover(function(){ad.transparency_icon.show();ad.height_icon.show()},function(){if(ad.manager.alpha_filter!==ad){ad.transparency_icon.hide()}if(ad.manager.height_filter!==ad){ad.height_icon.hide()}});$("<div style='clear: both;'/>").appendTo(ad.parent_div)};p(S.prototype,{to_dict:function(){var ac=g.prototype.to_dict.call(this);return p(ac,{type:"number",min:this.min,max:this.max,low:this.low,high:this.high})},copy:function(){return new S({name:this.name,index:this.index,tool_id:this.tool_id,tool_exp_name:this.tool_exp_name})},get_slider_step:function(ae,ac){var ad=ac-ae;return(ad<=2?0.01:1)},slide:function(ad,ae){var ac=ae.values;this.values_span.text(ac[0]+"-"+ac[1]);this.low=ac[0];this.high=ac[1];this.manager.track.request_draw(true,true)},applies_to:function(ac){if(ac.length>this.index){return true}return false},_keep_val:function(ac){return(isNaN(ac)||(ac>=this.low&&ac<=this.high))},keep:function(ad){if(!this.applies_to(ad)){return true}var af=this;var ag=ad[this.index];if(ag instanceof Array){var ae=true;for(var ac=0;ac<ag.length;ac++){if(!this._keep_val(ag[ac])){ae=false;break}}return ae}else{return this._keep_val(ad[this.index])}},update_attrs:function(af){var ac=false;if(!this.applies_to(af)){return ac}var ad=af[this.index];if(!(ad instanceof Array)){ad=[ad]}for(var ae=0;ae<ad.length;ae++){var ag=ad[ae];if(ag<this.min){this.min=Math.floor(ag);ac=true}if(ag>this.max){this.max=Math.ceil(ag);ac=true}}return ac},update_ui_elt:function(){if(this.min!==this.max){this.parent_div.show()}else{this.parent_div.hide()}var ad=this.slider.slider("option","min"),ac=this.slider.slider("option","max");if(this.min<ad||this.max>ac){this.slider.slider("option","min",this.min);this.slider.slider("option","max",this.max);this.slider.slider("option","step",this.get_slider_step(this.min,this.max));this.slider.slider("option","values",[this.min,this.max])}}});var X=function(ae,ak){this.track=ae;this.alpha_filter=null;this.height_filter=null;this.filters=[];this.parent_div=$("<div/>").addClass("filters").hide();this.parent_div.bind("drag",function(am){am.stopPropagation()}).click(function(am){am.stopPropagation()}).bind("dblclick",function(am){am.stopPropagation()}).bind("keydown",function(am){am.stopPropagation()});if(ak&&"filters" in ak){var ac=("alpha_filter" in ak?ak.alpha_filter:null),af=("height_filter" in ak?ak.height_filter:null),ah=ak.filters,ad;for(var ai=0;ai<ah.length;ai++){if(ah[ai].type==="number"){ad=new S(ah[ai]);this.add_filter(ad);if(ad.name===ac){this.alpha_filter=ad;ad.transparency_icon.addClass("active").show()}if(ad.name===af){this.height_filter=ad;ad.height_icon.addClass("active").show()}}else{console.log("ERROR: unsupported filter: ",name,type)}}if("visible" in ak&&ak.visible){this.parent_div.show()}}if(this.filters.length!==0){var al=$("<div/>").addClass("param-row").appendTo(this.parent_div);var aj=$("<input type='submit'/>").attr("value","Run on complete dataset").appendTo(al);var ag=this;aj.click(function(){ag.run_on_dataset()})}};p(X.prototype,{show:function(){this.parent_div.show()},hide:function(){this.parent_div.hide()},toggle:function(){this.parent_div.toggle()},visible:function(){return this.parent_div.is(":visible")},to_dict:function(){var af={},ae=[],ad;for(var ac=0;ac<this.filters.length;ac++){ad=this.filters[ac];ae.push(ad.to_dict())}af.filters=ae;af.alpha_filter=(this.alpha_filter?this.alpha_filter.name:null);af.height_filter=(this.height_filter?this.height_filter.name:null);af.visible=this.parent_div.is(":visible");return af},copy:function(ad){var ae=new X(ad);for(var ac=0;ac<this.filters.length;ac++){ae.add_filter(this.filters[ac].copy())}return ae},add_filter:function(ac){ac.manager=this;this.parent_div.append(ac.parent_div);this.filters.push(ac)},remove_all:function(){this.filters=[];this.parent_div.children().remove()},init_filters:function(){for(var ac=0;ac<this.filters.length;ac++){var ad=this.filters[ac];ad.update_ui_elt()}},clear_filters:function(){for(var ac=0;ac<this.filters.length;ac++){var ad=this.filters[ac];ad.slider.slider("option","values",[ad.min,ad.max])}this.alpha_filter=null;this.height_filter=null;this.parent_div.find(".icon-button").hide()},run_on_dataset:function(){var ak=function(ao,am,an){if(!(am in ao)){ao[am]=an}return ao[am]};var ae={},ac,ad,af;for(var ag=0;ag<this.filters.length;ag++){ac=this.filters[ag];if(ac.tool_id){if(ac.min!==ac.low){ad=ak(ae,ac.tool_id,[]);ad[ad.length]=ac.tool_exp_name+" >= "+ac.low}if(ac.max!==ac.high){ad=ak(ae,ac.tool_id,[]);ad[ad.length]=ac.tool_exp_name+" <= "+ac.high}}}var ai=[];for(var al in ae){ai[ai.length]=[al,ae[al]]}var aj=ai.length;(function ah(at,ap){var an=ap[0],ao=an[0],ar=an[1],aq="("+ar.join(") and (")+")",am={cond:aq,input:at,target_dataset_id:at,tool_id:ao},ap=ap.slice(1);$.getJSON(run_tool_url,am,function(au){if(au.error){show_modal("Filter Dataset","Error running tool "+ao,{Close:hide_modal})}else{if(ap.length===0){show_modal("Filtering Dataset","Filter(s) are running on the complete dataset. Outputs are in dataset's history.",{Close:hide_modal})}else{ah(au.dataset_id,ap)}}})})(this.track.dataset_id,ai)}});var z=function(ac,ad){J.Scaler.call(this,ad);this.filter=ac};z.prototype.gen_val=function(ac){if(this.filter.high===Number.MAX_VALUE||this.filter.low===-Number.MAX_VALUE||this.filter.low===this.filter.high){return this.default_val}return((parseFloat(ac[this.filter.index])-this.filter.low)/(this.filter.high-this.filter.low))};var C=function(ac){this.track=ac.track;this.params=ac.params;this.values={};this.restore_values((ac.saved_values?ac.saved_values:{}));this.onchange=ac.onchange};p(C.prototype,{restore_values:function(ac){var ad=this;$.each(this.params,function(ae,af){if(ac[af.key]!==undefined){ad.values[af.key]=ac[af.key]}else{ad.values[af.key]=af.default_value}})},build_form:function(){var af=this;var ac=$("<div />");var ae;function ad(aj,ag){for(var an=0;an<aj.length;an++){ae=aj[an];if(ae.hidden){continue}var ah="param_"+an;var ar=af.values[ae.key];var av=$("<div class='form-row' />").appendTo(ag);av.append($("<label />").attr("for",ah).text(ae.label+":"));if(ae.type==="bool"){av.append($('<input type="checkbox" />').attr("id",ah).attr("name",ah).attr("checked",ar))}else{if(ae.type==="text"){av.append($('<input type="text"/>').attr("id",ah).val(ar).click(function(){$(this).select()}))}else{if(ae.type==="select"){var ap=$("<select />").attr("id",ah);for(var al=0;al<ae.options.length;al++){$("<option/>").text(ae.options[al].label).attr("value",ae.options[al].value).appendTo(ap)}ap.val(ar);av.append(ap)}else{if(ae.type==="color"){var au=$("<div/>").appendTo(av),ao=$("<input />").attr("id",ah).attr("name",ah).val(ar).css("float","left").appendTo(au).click(function(ax){$(".tipsy").hide();var aw=$(this).siblings(".tipsy");aw.css({left:$(this).position().left+$(this).width()+5,top:$(this).position().top-($(aw).height()/2)+($(this).height()/2)}).show();aw.click(function(ay){ay.stopPropagation()});$(document).bind("click.color-picker",function(){aw.hide();$(document).unbind("click.color-picker")});ax.stopPropagation()}),am=$("<a href='javascript:void(0)'/>").addClass("icon-button arrow-circle").appendTo(au).attr("title","Set new random color").tipsy({gravity:"s"}),aq=$("<div class='tipsy tipsy-west' style='position: absolute;' />").appendTo(au).hide(),ai=$("<div style='background-color: black; padding: 10px;'></div>").appendTo(aq),at=$("<div/>").appendTo(ai),ak=$.farbtastic(at,{width:100,height:100,callback:ao,color:ar});au.append($("<div/>").css("clear","both"));(function(aw){am.click(function(){aw.setColor(get_random_color())})})(ak)}else{av.append($("<input />").attr("id",ah).attr("name",ah).val(ar))}}}}if(ae.help){av.append($("<div class='help'/>").text(ae.help))}}}ad(this.params,ac);return ac},update_from_form:function(ac){var ae=this;var ad=false;$.each(this.params,function(af,ah){if(!ah.hidden){var ai="param_"+af;var ag=ac.find("#"+ai).val();if(ah.type==="float"){ag=parseFloat(ag)}else{if(ah.type==="int"){ag=parseInt(ag)}else{if(ah.type==="bool"){ag=ac.find("#"+ai).is(":checked")}}}if(ag!==ae.values[ah.key]){ae.values[ah.key]=ag;ad=true}}});if(ad){this.onchange();this.track.changed()}}});var b=function(ac,af,ae,ad,ag){this.track=ac;this.index=af;var ah=this.track._get_tile_bounds(af,ae);this.low=ah[0];this.high=ah[1];this.resolution=ae;this.html_elt=$("<div class='track-tile'/>").append(ad);this.data=ag;this.stale=false};b.prototype.predisplay_actions=function(){};var k=function(ac,af,ae,ad,ag,ah){b.call(this,ac,af,ae,ad,ag);this.max_val=ah};p(k.prototype,b.prototype);var M=function(af,ak,ag,ae,ai,ao,aj,ap,ad,am){b.call(this,af,ak,ag,ae,ai);this.mode=aj;this.all_slotted=ad;this.feature_mapper=am;this.has_icons=false;if(ap){this.has_icons=true;var al=this;ae=this.html_elt.children()[0],message_div=$("<div/>").addClass("tile-message").css({height:A-1,width:ae.width}).prependTo(this.html_elt);var an=ai.length,ah=$("<a href='javascript:void(0);'/>").addClass("icon more-down").attr("title","For speed, only the first "+an+" features in this region were obtained from server. Click to get more data including depth").tipsy({gravity:"s"}).appendTo(message_div),ac=$("<a href='javascript:void(0);'/>").addClass("icon more-across").attr("title","For speed, only the first "+an+" features in this region were obtained from server. Click to get more data excluding depth").tipsy({gravity:"s"}).appendTo(message_div);ah.click(function(){al.stale=true;af.data_manager.get_more_data(al.low,al.high,af.mode,al.resolution,{},af.data_manager.DEEP_DATA_REQ);$(".tipsy").hide();af.request_draw()}).dblclick(function(aq){aq.stopPropagation()});ac.click(function(){al.stale=true;af.data_manager.get_more_data(al.low,al.high,af.mode,al.resolution,{},af.data_manager.BROAD_DATA_REQ);$(".tipsy").hide();af.request_draw()}).dblclick(function(aq){aq.stopPropagation()})}};p(M.prototype,b.prototype);M.prototype.predisplay_actions=function(){var ad=this,ac={};if(ad.mode!=="Pack"){return}$(this.html_elt).hover(function(){this.hovered=true;$(this).mousemove()},function(){this.hovered=false;$(this).parents(".track-content").children(".overlay").children(".feature-popup").remove()}).mousemove(function(ao){if(!this.hovered){return}var aj=$(this).offset(),an=ao.pageX-aj.left,am=ao.pageY-aj.top,at=ad.feature_mapper.get_feature_data(an,am),ak=(at?at[0]:null);$(this).parents(".track-content").children(".overlay").children(".feature-popup").each(function(){if(!ak||$(this).attr("id")!==ak.toString()){$(this).remove()}});if(at){var af=ac[ak];if(!af){var ak=at[0],ap={name:at[3],start:at[1],end:at[2],strand:at[4]},ai=ad.track.filters_manager.filters,ah;for(var al=0;al<ai.length;al++){ah=ai[al];ap[ah.name]=at[ah.index]}var af=$("<div/>").attr("id",ak).addClass("feature-popup"),au=$("<table/>"),ar,aq,av;for(ar in ap){aq=ap[ar];av=$("<tr/>").appendTo(au);$("<th/>").appendTo(av).text(ar);$("<td/>").attr("align","left").appendTo(av).text(typeof(aq)==="number"?W(aq,2):aq)}af.append($("<div class='feature-popup-inner'>").append(au));ac[ak]=af}af.appendTo($(this).parents(".track-content").children(".overlay"));var ag=an+parseInt(ad.html_elt.css("left"))-af.width()/2,ae=am+parseInt(ad.html_elt.css("top"))+7;af.css("left",ag+"px").css("top",ae+"px")}else{if(!ao.isPropagationStopped()){ao.stopPropagation();$(this).siblings().each(function(){$(this).trigger(ao)})}}}).mouseleave(function(){$(this).parents(".track-content").children(".overlay").children(".feature-popup").remove()})};var i=function(ad,ac,ae){p(ae,{drag_handle_class:"draghandle"});q.call(this,ad,ac,ae);this.data_url=("data_url" in ae?ae.data_url:default_data_url);this.data_url_extra_params={};this.data_query_wait=("data_query_wait" in ae?ae.data_query_wait:I);this.dataset_check_url=converted_datasets_state_url;this.data_manager=("data_manager" in ae?ae.data_manager:new P(F,this));this.min_height_px=16;this.max_height_px=800;this.visible_height_px=0;this.content_div=$("<div class='track-content'>").appendTo(this.container_div);if(this.container){this.container.content_div.append(this.container_div);if(!("resize" in ae)||ae.resize){this.add_resize_handle()}}};p(i.prototype,q.prototype,{action_icons_def:[{name:"mode_icon",title:"Set display mode",css_class:"chevron-expand",on_click_fn:function(){}},q.prototype.action_icons_def[0],{name:"overview_icon",title:"Set as overview",css_class:"overview-icon",on_click_fn:function(ac){ac.view.set_overview(ac)}},q.prototype.action_icons_def[1],{name:"filters_icon",title:"Filters",css_class:"filters-icon",on_click_fn:function(ac){if(ac.filters_manager.visible()){ac.filters_manager.clear_filters()}else{ac.filters_manager.init_filters()}ac.filters_manager.toggle()}},{name:"tools_icon",title:"Tool",css_class:"hammer",on_click_fn:function(ac){ac.dynamic_tool_div.toggle();if(ac.dynamic_tool_div.is(":visible")){ac.set_name(ac.name+ac.tool_region_and_parameters_str())}else{ac.revert_name()}$(".tipsy").remove()}},q.prototype.action_icons_def[2]],can_draw:function(){if(this.dataset_id&&q.prototype.can_draw.call(this)){return true}return false},build_container_div:function(){return $("<div/>").addClass("track").attr("id","track_"+this.id).css("position","relative")},build_header_div:function(){var ac=$("<div class='track-header'/>");if(this.view.editor){this.drag_div=$("<div/>").addClass(this.drag_handle_class).appendTo(ac)}this.name_div=$("<div/>").addClass("track-name").appendTo(ac).text(this.name).attr("id",this.name.replace(/\s+/g,"-").replace(/[^a-zA-Z0-9\-]/g,"").toLowerCase());return ac},on_resize:function(){},add_resize_handle:function(){var ac=this;var af=false;var ae=false;var ad=$("<div class='track-resize'>");$(ac.container_div).hover(function(){if(ac.content_visible){af=true;ad.show()}},function(){af=false;if(!ae){ad.hide()}});ad.hide().bind("dragstart",function(ag,ah){ae=true;ah.original_height=$(ac.content_div).height()}).bind("drag",function(ah,ai){var ag=Math.min(Math.max(ai.original_height+ai.deltaY,ac.min_height_px),ac.max_height_px);$(ac.tiles_div).css("height",ag);ac.visible_height_px=(ac.max_height_px===ag?0:ag);ac.on_resize()}).bind("dragend",function(ag,ah){ac.tile_cache.clear();ae=false;if(!af){ad.hide()}ac.config.values.height=ac.visible_height_px;ac.changed()}).appendTo(ac.container_div)},set_display_modes:function(af,ai){this.display_modes=af;this.mode=(ai?ai:(this.config&&this.config.values.mode?this.config.values.mode:this.display_modes[0]));this.action_icons.mode_icon.attr("title","Set display mode (now: "+this.mode+")");var ad=this,ag={};for(var ae=0,ac=ad.display_modes.length;ae<ac;ae++){var ah=ad.display_modes[ae];ag[ah]=function(aj){return function(){ad.change_mode(aj);ad.icons_div.show();ad.container_div.mouseleave(function(){ad.icons_div.hide()})}}(ah)}make_popupmenu(this.action_icons.mode_icon,ag)},build_action_icons:function(){q.prototype.build_action_icons.call(this,this.action_icons_def);if(this.display_modes!==undefined){this.set_display_modes(this.display_modes)}},hide_contents:function(){this.content_div.children().remove();this.content_div.hide();this.container_div.find(".yaxislabel, .track-resize").hide()},show_contents:function(){this.content_div.show();this.container_div.find(".yaxislabel, .track-resize").show();this.request_draw()},get_type:function(){if(this instanceof Y){return"LabelTrack"}else{if(this instanceof y){return"ReferenceTrack"}else{if(this instanceof j){return"LineTrack"}else{if(this instanceof T){return"ReadTrack"}else{if(this instanceof Q){return"VcfTrack"}else{if(this instanceof h){return"CompositeTrack"}else{if(this instanceof d){return"FeatureTrack"}}}}}}}return""},init:function(){var ad=this;ad.enabled=false;ad.tile_cache.clear();ad.data_manager.clear();ad.content_div.css("height","auto");ad.tiles_div.children().remove();ad.container_div.removeClass("nodata error pending");if(!ad.dataset_id){return}var ac=$.Deferred();$.getJSON(converted_datasets_state_url,{hda_ldda:ad.hda_ldda,dataset_id:ad.dataset_id,chrom:ad.view.chrom},function(ae){if(!ae||ae==="error"||ae.kind==="error"){ad.container_div.addClass("error");ad.tiles_div.text(o);if(ae.message){var af=$(" <a href='javascript:void(0);'></a>").text("View error").click(function(){show_modal("Trackster Error","<pre>"+ae.message+"</pre>",{Close:hide_modal})});ad.tiles_div.append(af)}}else{if(ae==="no converter"){ad.container_div.addClass("error");ad.tiles_div.text(H)}else{if(ae==="no data"||(ae.data!==undefined&&(ae.data===null||ae.data.length===0))){ad.container_div.addClass("nodata");ad.tiles_div.text(B)}else{if(ae==="pending"){ad.container_div.addClass("pending");ad.tiles_div.html(t);setTimeout(function(){ad.init()},ad.data_query_wait)}else{if(ae.status==="data"){if(ae.valid_chroms){ad.valid_chroms=ae.valid_chroms;ad.update_icons()}ad.tiles_div.text(V);if(ad.view.chrom){ad.tiles_div.text("");ad.tiles_div.css("height",ad.visible_height_px+"px");ad.enabled=true;$.when(ad.predraw_init()).done(function(){ac.resolve();ad.container_div.removeClass("nodata error pending");ad.request_draw()})}else{ac.resolve()}}}}}}});this.update_icons();return ac},predraw_init:function(){}});var K=function(ae,ad,af){i.call(this,ae,ad,af);var ac=this,ae=ac.view;m(ac.container_div,ac.drag_handle_class,".group",ac);this.filters_manager=new X(this,("filters" in af?af.filters:null));this.filters_available=false;this.tool=("tool" in af&&af.tool?new r(this,af.tool,af.tool_state):null);this.tile_cache=new c(O);if(this.header_div){this.set_filters_manager(this.filters_manager);if(this.tool){this.dynamic_tool_div=this.tool.parent_div;this.header_div.after(this.dynamic_tool_div)}}this.tiles_div=$("<div/>").addClass("tiles").appendTo(this.content_div);this.overlay_div=$("<div/>").addClass("overlay").appendTo(this.content_div);if(af.mode){this.change_mode(af.mode)}};p(K.prototype,q.prototype,i.prototype,{action_icons_def:i.prototype.action_icons_def.concat([{name:"show_more_rows_icon",title:"To minimize track height, not all feature rows are displayed. Click to display more rows.",css_class:"exclamation",on_click_fn:function(ac){$(".tipsy").remove();ac.slotters[ac.view.resolution_px_b].max_rows*=2;ac.request_draw(true)},hide:true}]),copy:function(ac){var ad=this.to_dict();p(ad,{data_manager:this.data_manager});var ae=new this.constructor(this.view,ac,ad);ae.change_mode(this.mode);ae.enabled=this.enabled;return ae},set_filters_manager:function(ac){this.filters_manager=ac;this.header_div.after(this.filters_manager.parent_div)},to_dict:function(){return{track_type:this.get_type(),name:this.name,hda_ldda:this.hda_ldda,dataset_id:this.dataset_id,prefs:this.prefs,mode:this.mode,filters:this.filters_manager.to_dict(),tool_state:(this.tool?this.tool.state_dict():{})}},change_mode:function(ad){var ac=this;ac.mode=ad;ac.config.values.mode=ad;ac.tile_cache.clear();ac.request_draw();this.action_icons.mode_icon.attr("title","Set display mode (now: "+ac.mode+")");return ac},update_icons:function(){var ac=this;if(ac.filters_available){ac.action_icons.filters_icon.show()}else{ac.action_icons.filters_icon.hide()}if(ac.tool){ac.action_icons.tools_icon.show()}else{ac.action_icons.tools_icon.hide()}},_gen_tile_cache_key:function(ad,ae,ac){return ad+"_"+ae+"_"+ac},request_draw:function(ad,ac){this.view.request_redraw(false,ad,ac,this)},before_draw:function(){},_draw:function(ad,an){if(!this.can_draw()){return}var al=this.view.low,ah=this.view.high,aj=ah-al,ae=this.view.container.width(),ap=this.view.resolution_px_b,ag=this.view.resolution_b_px;if(this.is_overview){al=this.view.max_low;ah=this.view.max_high;ag=Math.pow(RESOLUTION,Math.ceil(Math.log((view.max_high-view.max_low)/R)/Math.log(RESOLUTION)));ap=ae/(view.max_high-view.max_low)}this.before_draw();this.tiles_div.children().addClass("remove");var ac=Math.floor(al/(ag*R)),ak=true,ao=[],ai=function(aq){return(aq&&"track" in aq)};while((ac*R*ag)<ah){var am=this.draw_helper(ad,ae,ac,ag,this.tiles_div,ap);if(ai(am)){ao.push(am)}else{ak=false}ac+=1}if(!an){this.tiles_div.children(".remove").remove()}var af=this;if(ak){this.tiles_div.children(".remove").remove();af.postdraw_actions(ao,ae,ap,an)}},postdraw_actions:function(af,ag,ai,ac){var ae=this;var ah=false;for(var ad=0;ad<af.length;ad++){if(af[ad].has_icons){ah=true;break}}if(ah){for(var ad=0;ad<af.length;ad++){tile=af[ad];if(!tile.has_icons){tile.html_elt.css("padding-top",A)}}}},draw_helper:function(ac,ao,au,ar,ah,ai,ap){var an=this,ax=this._gen_tile_cache_key(ao,ai,au),af=this._get_tile_bounds(au,ar),av=af[0],ad=af[1];if(!ap){ap={}}var aw=(ac?undefined:an.tile_cache.get(ax));if(aw){an.show_tile(aw,ah,ai);return aw}var al=true;var at=an.data_manager.get_data(av,ad,an.mode,ar,an.data_url_extra_params);if(is_deferred(at)){al=false}var aj;if(view.reference_track&&ai>view.canvas_manager.char_width_px){aj=view.reference_track.data_manager.get_data(av,ad,an.mode,ar,view.reference_track.data_url_extra_params);if(is_deferred(aj)){al=false}}if(al){p(at,ap.more_tile_data);var ak=an.mode;if(ak==="Auto"){ak=an.get_mode(at);an.update_auto_mode(ak)}var ae=an.view.canvas_manager.new_canvas(),af=an._get_tile_bounds(au,ar),av=af[0],ad=af[1],ao=Math.ceil((ad-av)*ai)+an.left_offset,am=an.get_canvas_height(at,ak,ai,ao);ae.width=ao;ae.height=am;var aq=ae.getContext("2d");aq.translate(this.left_offset,0);var aw=an.draw_tile(at,aq,ak,ar,au,ai,aj);if(aw!==undefined){an.tile_cache.set(ax,aw);an.show_tile(aw,ah,ai)}return aw}var ag=$.Deferred();$.when(at,aj).then(function(){view.request_redraw(false,false,false,an);ag.resolve()});return ag},get_canvas_height:function(ac,ae,af,ad){return this.visible_height_px},draw_tile:function(ac,ae,ah,ag,ad,ai,af){console.log("Warning: TiledTrack.draw_tile() not implemented.")},show_tile:function(ae,ag,ah){var ad=this,ac=ae.html_elt;ae.predisplay_actions();var af=(ae.low-(this.is_overview?this.view.max_low:this.view.low))*ah;if(this.left_offset){af-=this.left_offset}ac.css({position:"absolute",top:0,left:af,height:""});if(ac.hasClass("remove")){ac.removeClass("remove")}else{ag.append(ac)}ad.after_show_tile(ae)},after_show_tile:function(ac){},_get_tile_bounds:function(ac,ad){var af=Math.floor(ac*R*ad),ag=Math.ceil(R*ad),ae=(af+ag<=this.view.max_high?af+ag:this.view.max_high);return[af,ae]},tool_region_and_parameters_str:function(ae,ac,af){var ad=this,ag=(ae!==undefined&&ac!==undefined&&af!==undefined?ae+":"+ac+"-"+af:"all");return" - region=["+ag+"], parameters=["+ad.tool.get_param_values().join(", ")+"]"},data_and_mode_compatible:function(ac,ad){return true},can_subset:function(ac){return false},init_for_tool_data:function(){this.data_url=raw_data_url;this.data_query_wait=1000;this.dataset_check_url=dataset_state_url;this.predraw_init=function(){var ad=this;var ac=function(){if(ad.data_manager.size()===0){setTimeout(ac,300)}else{ad.data_url=default_data_url;ad.data_query_wait=I;ad.dataset_state_url=converted_datasets_state_url;$.getJSON(ad.dataset_state_url,{dataset_id:ad.dataset_id,hda_ldda:ad.hda_ldda},function(ae){})}};ac()}}});var Y=function(ad,ac){var ae={resize:false};i.call(this,ad,ac,ae);this.container_div.addClass("label-track")};p(Y.prototype,i.prototype,{build_header_div:function(){},init:function(){this.enabled=true},_draw:function(){var ae=this.view,af=ae.high-ae.low,ai=Math.floor(Math.pow(10,Math.floor(Math.log(af)/Math.log(10)))),ac=Math.floor(ae.low/ai)*ai,ag=this.view.container.width(),ad=$("<div style='position: relative; height: 1.3em;'></div>");while(ac<ae.high){var ah=(ac-ae.low)/af*ag;ad.append($("<div class='label'>"+commatize(ac)+"</div>").css({position:"absolute",left:ah-1}));ac+=ai}this.content_div.children(":first").remove();this.content_div.append(ad)}});var h=function(ad,ac,ag){K.call(this,ad,ac,ag);this.drawables=[];this.left_offset=0;if("drawables" in ag){var af;for(var ae=0;ae<ag.drawables.length;ae++){af=ag.drawables[ae];this.drawables[ae]=object_from_template(af);if(af.left_offset>this.left_offset){this.left_offset=af.left_offset}}this.enabled=true}if(this.drawables.length!==0){this.set_display_modes(this.drawables[0].display_modes,this.drawables[0].mode)}this.update_icons();this.obj_type="CompositeTrack"};p(h.prototype,K.prototype,{action_icons_def:[{name:"composite_icon",title:"Show individual tracks",css_class:"layers-stack",on_click_fn:function(ac){$(".tipsy").remove();ac.show_group()}}].concat(K.prototype.action_icons_def),to_dict:w.prototype.to_dict,add_drawable:w.prototype.add_drawable,unpack_drawables:w.prototype.unpack_drawables,change_mode:function(ac){K.prototype.change_mode.call(this,ac);for(var ad=0;ad<this.drawables.length;ad++){this.drawables[ad].change_mode(ac)}},init:function(){var ae=[];for(var ad=0;ad<this.drawables.length;ad++){ae.push(this.drawables[ad].init())}var ac=this;$.when.apply($,ae).then(function(){ac.enabled=true;ac.request_draw()})},update_icons:function(){this.action_icons.filters_icon.hide();this.action_icons.tools_icon.hide()},can_draw:q.prototype.can_draw,draw_helper:function(ad,ar,ay,av,aj,al,at){var aq=this,aC=this._gen_tile_cache_key(ar,al,ay),ah=this._get_tile_bounds(ay,av),az=ah[0],ae=ah[1];if(!at){at={}}var aB=(ad?undefined:aq.tile_cache.get(aC));if(aB){aq.show_tile(aB,aj,al);return aB}var ak=[],aq,ao=true,aw,am;for(var ax=0;ax<this.drawables.length;ax++){aq=this.drawables[ax];aw=aq.data_manager.get_data(az,ae,aq.mode,av,aq.data_url_extra_params);if(is_deferred(aw)){ao=false}ak.push(aw);am=null;if(view.reference_track&&al>view.canvas_manager.char_width_px){am=view.reference_track.data_manager.get_data(az,ae,aq.mode,av,view.reference_track.data_url_extra_params);if(is_deferred(am)){ao=false}}ak.push(am)}if(ao){p(aw,at.more_tile_data);this.tile_predraw_init();var ag=aq.view.canvas_manager.new_canvas(),ah=aq._get_tile_bounds(ay,av),az=ah[0],ae=ah[1],aA=0,ar=Math.ceil((ae-az)*al)+this.left_offset,ap=0,af=[];var ac=0;for(var ax=0;ax<this.drawables.length;ax++,aA+=2){aq=this.drawables[ax];aw=ak[aA];var an=aq.mode;if(an==="Auto"){an=aq.get_mode(aw);aq.update_auto_mode(an)}af.push(an);ac=aq.get_canvas_height(aw,an,al,ar);if(ac>ap){ap=ac}}ag.width=ar;ag.height=(at.height?at.height:ap);aA=0;var au=ag.getContext("2d");au.translate(this.left_offset,0);au.globalAlpha=0.5;au.globalCompositeOperation="source-over";for(var ax=0;ax<this.drawables.length;ax++,aA+=2){aq=this.drawables[ax];aw=ak[aA];am=ak[aA+1];aB=aq.draw_tile(aw,au,af[ax],av,ay,al,am)}this.tile_cache.set(aC,aB);this.show_tile(aB,aj,al);return aB}var ai=$.Deferred(),aq=this;$.when.apply($,ak).then(function(){view.request_redraw(false,false,false,aq);ai.resolve()});return ai},show_group:function(){var af=new N(this.view,this.container,{name:this.name}),ac;for(var ae=0;ae<this.drawables.length;ae++){ac=this.drawables[ae];af.add_drawable(ac);ac.container=af;af.content_div.append(ac.container_div)}var ad=this.container.replace_drawable(this,af,true);af.request_draw()},tile_predraw_init:function(){var af=Number.MAX_VALUE,ac=-af,ad;for(var ae=0;ae<this.drawables.length;ae++){ad=this.drawables[ae];if(ad instanceof j){if(ad.prefs.min_value<af){af=ad.prefs.min_value}if(ad.prefs.max_value>ac){ac=ad.prefs.max_value}}}for(var ae=0;ae<this.drawables.length;ae++){ad=this.drawables[ae];ad.prefs.min_value=af;ad.prefs.max_value=ac}},postdraw_actions:function(ae,ah,aj,ad){K.prototype.postdraw_actions.call(this,ae,ah,aj,ad);var ag=-1;for(var af=0;af<ae.length;af++){var ac=ae[af].html_elt.find("canvas").height();if(ac>ag){ag=ac}}for(var af=0;af<ae.length;af++){var ai=ae[af];if(ai.html_elt.find("canvas").height()!==ag){this.draw_helper(true,ah,ai.index,ai.resolution,ai.html_elt.parent(),aj,{height:ag});ai.html_elt.remove()}}}});var y=function(ac){K.call(this,ac,{content_div:ac.top_labeltrack,resize:false},{});ac.reference_track=this;this.left_offset=200;this.visible_height_px=12;this.container_div.addClass("reference-track");this.content_div.css("background","none");this.content_div.css("min-height","0px");this.content_div.css("border","none");this.data_url=reference_url;this.data_url_extra_params={dbkey:ac.dbkey};this.data_manager=new E(F,this,false)};p(y.prototype,q.prototype,K.prototype,{build_header_div:function(){},init:function(){this.data_manager.clear();this.enabled=true},can_draw:q.prototype.can_draw,draw_tile:function(ak,al,ah,ag,ad,am){var af=this;if(am>this.view.canvas_manager.char_width_px){if(ak.data===null){af.content_div.css("height","0px");return}var ae=al.canvas;al.font=al.canvas.manager.default_font;al.textAlign="center";ak=ak.data;for(var ai=0,aj=ak.length;ai<aj;ai++){var ac=Math.floor(ai*am);al.fillText(ak[ai],ac,10)}return new b(af,ad,ag,ae,ak)}this.content_div.css("height","0px")},after_show_tile:function(ac){if(ac){this.content_div.css("height","12px")}}});var j=function(ae,ad,af){var ac=this;this.display_modes=["Histogram","Line","Filled","Intensity"];this.mode="Histogram";K.call(this,ae,ad,af);this.hda_ldda=af.hda_ldda;this.dataset_id=af.dataset_id;this.original_dataset_id=this.dataset_id;this.left_offset=0;this.config=new C({track:this,params:[{key:"name",label:"Name",type:"text",default_value:this.name},{key:"color",label:"Color",type:"color",default_value:get_random_color()},{key:"min_value",label:"Min Value",type:"float",default_value:undefined},{key:"max_value",label:"Max Value",type:"float",default_value:undefined},{key:"mode",type:"string",default_value:this.mode,hidden:true},{key:"height",type:"int",default_value:32,hidden:true}],saved_values:af.prefs,onchange:function(){ac.set_name(ac.prefs.name);ac.vertical_range=ac.prefs.max_value-ac.prefs.min_value;ac.set_min_value(ac.prefs.min_value);ac.set_max_value(ac.prefs.max_value)}});this.prefs=this.config.values;this.visible_height_px=this.config.values.height;this.vertical_range=this.config.values.max_value-this.config.values.min_value};p(j.prototype,q.prototype,K.prototype,{on_resize:function(){this.request_draw(true)},set_min_value:function(ac){this.prefs.min_value=ac;$("#linetrack_"+this.dataset_id+"_minval").text(this.prefs.min_value);this.tile_cache.clear();this.request_draw()},set_max_value:function(ac){this.prefs.max_value=ac;$("#linetrack_"+this.dataset_id+"_maxval").text(this.prefs.max_value);this.tile_cache.clear();this.request_draw()},predraw_init:function(){var ac=this;ac.vertical_range=undefined;return $.getJSON(ac.data_url,{stats:true,chrom:ac.view.chrom,low:null,high:null,hda_ldda:ac.hda_ldda,dataset_id:ac.dataset_id},function(ad){ac.container_div.addClass("line-track");var ag=ad.data;if(isNaN(parseFloat(ac.prefs.min_value))||isNaN(parseFloat(ac.prefs.max_value))){var ae=ag.min;var ai=ag.max;ae=Math.floor(Math.min(0,Math.max(ae,ag.mean-2*ag.sd)));ai=Math.ceil(Math.max(0,Math.min(ai,ag.mean+2*ag.sd)));ac.prefs.min_value=ae;ac.prefs.max_value=ai;$("#track_"+ac.dataset_id+"_minval").val(ac.prefs.min_value);$("#track_"+ac.dataset_id+"_maxval").val(ac.prefs.max_value)}ac.vertical_range=ac.prefs.max_value-ac.prefs.min_value;ac.total_frequency=ag.total_frequency;ac.container_div.find(".yaxislabel").remove();var ah=$("<div/>").text(W(ac.prefs.min_value,3)).make_text_editable({num_cols:6,on_finish:function(aj){$(".tipsy").remove();var aj=parseFloat(aj);if(!isNaN(aj)){ac.set_min_value(aj)}},help_text:"Set min value"}).addClass("yaxislabel bottom").attr("id","linetrack_"+ac.dataset_id+"_minval").prependTo(ac.container_div),af=$("<div/>").text(W(ac.prefs.max_value,3)).make_text_editable({num_cols:6,on_finish:function(aj){$(".tipsy").remove();var aj=parseFloat(aj);if(!isNaN(aj)){ac.set_max_value(aj)}},help_text:"Set max value"}).addClass("yaxislabel top").attr("id","linetrack_"+ac.dataset_id+"_maxval").prependTo(ac.container_div)})},draw_tile:function(am,ak,ah,af,ad,al){var ae=ak.canvas,ac=this._get_tile_bounds(ad,af),ag=ac[0],aj=ac[1],ai=new J.LinePainter(am.data,ag,aj,this.prefs,ah);ai.draw(ak,ae.width,ae.height,al);return new b(this,ad,af,ae,am.data)},can_subset:function(ac){return false},});var d=function(ae,ad,af){var ac=this;this.display_modes=["Auto","Histogram","Dense","Squish","Pack"];K.call(this,ae,ad,af);this.config=new C({track:this,params:[{key:"name",label:"Name",type:"text",default_value:this.name},{key:"block_color",label:"Block color",type:"color",default_value:get_random_color()},{key:"label_color",label:"Label color",type:"color",default_value:"black"},{key:"show_counts",label:"Show summary counts",type:"bool",default_value:true,help:"Show the number of items in each bin when drawing summary histogram"},{key:"histogram_max",label:"Histogram maximum",type:"float",default_value:null,help:"clear value to set automatically"},{key:"connector_style",label:"Connector style",type:"select",default_value:"fishbones",options:[{label:"Line with arrows",value:"fishbone"},{label:"Arcs",value:"arcs"}]},{key:"mode",type:"string",default_value:this.mode,hidden:true},{key:"height",type:"int",default_value:this.visible_height_px,hidden:true}],saved_values:af.prefs,onchange:function(){ac.set_name(ac.prefs.name);ac.tile_cache.clear();ac.set_painter_from_config();ac.request_draw()}});this.prefs=this.config.values;this.visible_height_px=this.config.values.height;this.container_div.addClass("feature-track");this.hda_ldda=af.hda_ldda;this.dataset_id=af.dataset_id;this.original_dataset_id=af.dataset_id;this.show_labels_scale=0.001;this.showing_details=false;this.summary_draw_height=30;this.slotters={};this.start_end_dct={};this.left_offset=200;this.set_painter_from_config()};p(d.prototype,q.prototype,K.prototype,{set_painter_from_config:function(){if(this.config.values.connector_style==="arcs"){this.painter=J.ArcLinkedFeaturePainter}else{this.painter=J.LinkedFeaturePainter}},before_draw:function(){this.max_height_px=0},after_show_tile:function(ac){this.max_height_px=Math.max(this.max_height_px,ac.html_elt.height());ac.html_elt.parent().children().css("height",this.max_height_px+"px");var ad=this.max_height_px;if(this.visible_height_px!==0){ad=Math.min(this.max_height_px,this.visible_height_px)}this.tiles_div.css("height",ad+"px")},postdraw_actions:function(ar,am,ah,ag){K.prototype.postdraw_actions.call(this,ar,ag);var al=this;if(al.mode==="Histogram"){var ad=-1;for(var ao=0;ao<ar.length;ao++){var an=ar[ao].max_val;if(an>ad){ad=an}}for(var ao=0;ao<ar.length;ao++){var au=ar[ao];if(au.max_val!==ad){au.html_elt.remove();al.draw_helper(true,am,au.index,au.resolution,au.html_elt.parent(),ah,{more_tile_data:{max:ad}})}}}if(al.filters_manager){var ai=al.filters_manager.filters;for(var aq=0;aq<ai.length;aq++){ai[aq].update_ui_elt()}var at=false,ac,aj;for(var ao=0;ao<ar.length;ao++){if(ar[ao].data.length){ac=ar[ao].data[0];for(var aq=0;aq<ai.length;aq++){aj=ai[aq];if(aj.applies_to(ac)&&aj.min!==aj.max){at=true;break}}}}if(al.filters_available!==at){al.filters_available=at;if(!al.filters_available){al.filters_manager.hide()}al.update_icons()}}this.container_div.find(".yaxislabel").remove();var af=ar[0];if(af instanceof k){var ak=(this.prefs.histogram_max?this.prefs.histogram_max:af.max_val),ae=$("<div/>").text(ak).make_text_editable({num_cols:12,on_finish:function(av){$(".tipsy").remove();var av=parseFloat(av);al.prefs.histogram_max=(!isNaN(av)?av:null);al.tile_cache.clear();al.request_draw()},help_text:"Set max value; leave blank to use default"}).addClass("yaxislabel top").css("color",this.prefs.label_color);this.container_div.prepend(ae)}if(af instanceof M){var ap=true;for(var ao=0;ao<ar.length;ao++){if(!ar[ao].all_slotted){ap=false;break}}if(!ap){this.action_icons.show_more_rows_icon.show()}else{this.action_icons.show_more_rows_icon.hide()}}else{this.action_icons.show_more_rows_icon.hide()}},update_auto_mode:function(ac){var ac;if(this.mode==="Auto"){if(ac==="no_detail"){ac="feature spans"}else{if(ac==="summary_tree"){ac="coverage histogram"}}this.action_icons.mode_icon.attr("title","Set display mode (now: Auto/"+ac+")")}},incremental_slots:function(ag,ac,af){var ad=this.view.canvas_manager.dummy_context,ae=this.slotters[ag];if(!ae||(ae.mode!==af)){ae=new (s.FeatureSlotter)(ag,af,x,function(ah){return ad.measureText(ah)});this.slotters[ag]=ae}return ae.slot_features(ac)},get_summary_tree_data:function(ag,aj,ae,ar){if(ar>ae-aj){ar=ae-aj}var an=Math.floor((ae-aj)/ar),aq=[],af=0;var ah=0,ai=0,am,ap=0,ak=[],ao,al;var ad=function(av,au,aw,at){av[0]=au+aw*at;av[1]=au+(aw+1)*at};while(ap<ar&&ah!==ag.length){var ac=false;for(;ap<ar&&!ac;ap++){ad(ak,aj,ap,an);for(ai=ah;ai<ag.length;ai++){am=ag[ai].slice(1,3);if(is_overlap(am,ak)){ac=true;break}}if(ac){break}}data_start_index=ai;aq[aq.length]=ao=[ak[0],0];for(;ai<ag.length;ai++){am=ag[ai].slice(1,3);if(is_overlap(am,ak)){ao[1]++}else{break}}if(ao[1]>af){af=ao[1]}ap++}return{max:af,delta:an,data:aq}},get_mode:function(ac){if(ac.dataset_type==="summary_tree"){mode="summary_tree"}else{if(ac.extra_info==="no_detail"||this.is_overview){mode="no_detail"}else{if(this.view.high-this.view.low>G){mode="Squish"}else{mode="Pack"}}}return mode},get_canvas_height:function(ac,ag,ah,ad){if(ag==="summary_tree"||ag==="Histogram"){return this.summary_draw_height}else{var af=this.incremental_slots(ah,ac.data,ag);var ae=new (this.painter)(null,null,null,this.prefs,ag);return Math.max(aa,ae.get_required_height(af,ad))}},draw_tile:function(an,ar,ap,at,ax,aj,ae){var aq=this,ad=ar.canvas,ag=this._get_tile_bounds(ax,at),aA=ag[0],ac=ag[1],aF=25,af=this.left_offset;if(ap==="summary_tree"||ap==="Histogram"){if(an.dataset_type!=="summary_tree"){var ak=this.get_summary_tree_data(an.data,aA,ac,200);if(an.max){ak.max=an.max}an=ak}var aC=new J.SummaryTreePainter(an,aA,ac,this.prefs);aC.draw(ar,ad.width,ad.height,aj);return new k(aq,ax,at,ad,an.data,an.max)}var ai=[],ao=this.slotters[aj].slots;all_slotted=true;if(an.data){var al=this.filters_manager.filters;for(var au=0,aw=an.data.length;au<aw;au++){var ah=an.data[au];var av=false;var am;for(var az=0,aE=al.length;az<aE;az++){am=al[az];am.update_attrs(ah);if(!am.keep(ah)){av=true;break}}if(!av){ai.push(ah);if(!(ah[0] in ao)){all_slotted=false}}}}var aD=(this.filters_manager.alpha_filter?new z(this.filters_manager.alpha_filter):null);var aB=(this.filters_manager.height_filter?new z(this.filters_manager.height_filter):null);var aC=new (this.painter)(ai,aA,ac,this.prefs,ap,aD,aB,ae);var ay=null;ar.fillStyle=this.prefs.block_color;ar.font=ar.canvas.manager.default_font;ar.textAlign="right";if(an.data){ay=aC.draw(ar,ad.width,ad.height,aj,ao);ay.translation=-af}return new M(aq,ax,at,ad,an.data,aj,ap,an.message,all_slotted,ay)},data_and_mode_compatible:function(ac,ad){if(ad==="Auto"){return true}else{if(ac.extra_info==="no_detail"||ac.dataset_type==="summary_tree"){return false}else{return true}}},can_subset:function(ac){if(ac.dataset_type==="summary_tree"||ac.message){return false}return true},});var Q=function(ad,ac,ae){d.call(this,ad,ac,ae);this.config=new C({track:this,params:[{key:"name",label:"Name",type:"text",default_value:this.name},{key:"block_color",label:"Block color",type:"color",default_value:get_random_color()},{key:"label_color",label:"Label color",type:"color",default_value:"black"},{key:"show_insertions",label:"Show insertions",type:"bool",default_value:false},{key:"show_counts",label:"Show summary counts",type:"bool",default_value:true},{key:"mode",type:"string",default_value:this.mode,hidden:true},],saved_values:ae.prefs,onchange:function(){this.track.set_name(this.track.prefs.name);this.track.tile_cache.clear();this.track.request_draw()}});this.prefs=this.config.values;this.painter=J.ReadPainter};p(Q.prototype,q.prototype,K.prototype,d.prototype);var T=function(ae,ad,ag){d.call(this,ae,ad,ag);var af=get_random_color(),ac=get_random_color([af,"#ffffff"]);this.config=new C({track:this,params:[{key:"name",label:"Name",type:"text",default_value:this.name},{key:"block_color",label:"Block and sense strand color",type:"color",default_value:af},{key:"reverse_strand_color",label:"Antisense strand color",type:"color",default_value:ac},{key:"label_color",label:"Label color",type:"color",default_value:"black"},{key:"show_insertions",label:"Show insertions",type:"bool",default_value:false},{key:"show_differences",label:"Show differences only",type:"bool",default_value:true},{key:"show_counts",label:"Show summary counts",type:"bool",default_value:true},{key:"histogram_max",label:"Histogram maximum",type:"float",default_value:null,help:"Clear value to set automatically"},{key:"mode",type:"string",default_value:this.mode,hidden:true},],saved_values:ag.prefs,onchange:function(){this.track.set_name(this.track.prefs.name);this.track.tile_cache.clear();this.track.request_draw()}});this.prefs=this.config.values;this.painter=J.ReadPainter;this.update_icons()};p(T.prototype,q.prototype,K.prototype,d.prototype);U.View=Z;U.DrawableGroup=N;U.LineTrack=j;U.FeatureTrack=d;U.ReadTrack=T;U.VcfTrack=Q;U.CompositeTrack=h};var slotting_module=function(c,b){var e=c("class").extend;var d=2,a=5;b.FeatureSlotter=function(i,h,f,g){this.slots={};this.start_end_dct={};this.w_scale=i;this.mode=h;this.include_label=(h==="Pack");this.max_rows=f;this.measureText=g};e(b.FeatureSlotter.prototype,{slot_features:function(m){var p=this.w_scale,h=this.start_end_dct,x=[],z=[],n=0,y=this.max_rows;for(var v=0,w=m.length;v<w;v++){var k=m[v],o=k[0];if(this.slots[o]!==undefined){n=Math.max(n,this.slots[o]);z.push(this.slots[o])}else{x.push(v)}}var q=function(E,F){for(var D=0;D<=y;D++){var B=false,G=h[D];if(G!==undefined){for(var A=0,C=G.length;A<C;A++){var i=G[A];if(F>i[0]&&E<i[1]){B=true;break}}}if(!B){return D}}return -1};for(var v=0,w=x.length;v<w;v++){var k=m[x[v]],o=k[0],t=k[1],f=k[2],r=k[3],g=Math.floor(t*p),l=Math.ceil(f*p),u=this.measureText(r).width,j;if(r!==undefined&&this.include_label){u+=(d+a);if(g-u>=0){g-=u;j="left"}else{l+=u;j="right"}}var s=q(g,l);if(s>=0){if(h[s]===undefined){h[s]=[]}h[s].push([g,l]);this.slots[o]=s;n=Math.max(n,s)}}return n+1}})};var painters_module=function(i,x){var u=i("class").extend;var p=function(I,A,G,z,F,D){if(D===undefined){D=4}var C=z-A;var B=F-G;var E=Math.floor(Math.sqrt(C*C+B*B)/D);var J=C/E;var H=B/E;var y;for(y=0;y<E;y++,A+=J,G+=H){if(y%2!==0){continue}I.fillRect(A,G,D,1)}};var q=function(B,A,z,E){var D=A-E/2,C=A+E/2,F=z-Math.sqrt(E*3/2);B.beginPath();B.moveTo(D,F);B.lineTo(C,F);B.lineTo(A,z);B.lineTo(D,F);B.strokeStyle=this.fillStyle;B.fill();B.stroke();B.closePath()};var d=function(y){this.default_val=(y?y:1)};d.prototype.gen_val=function(y){return this.default_val};var l=function(A,C,y,z,B){this.data=A;this.view_start=C;this.view_end=y;this.prefs=u({},this.default_prefs,z);this.mode=B};l.prototype.default_prefs={};l.prototype.draw=function(z,A,y,B){};var v=function(A,C,y,z,B){l.call(this,A,C,y,z,B)};v.prototype.default_prefs={show_counts:false};v.prototype.draw=function(L,z,K,M){var E=this.view_start,N=this.view_end-this.view_start,I=this.data.data,G=(this.prefs.histogram_max?this.prefs.histogram_max:this.data.max),B=K;delta_x_px=Math.ceil(this.data.delta*M);L.save();for(var C=0,D=I.length;C<D;C++){var H=Math.floor((I[C][0]-E)*M);var F=I[C][1];if(!F){continue}var J=F/G*K;if(F!==0&&J<1){J=1}L.fillStyle=this.prefs.block_color;L.fillRect(H,B-J,delta_x_px,J);var A=4;if(this.prefs.show_counts&&(L.measureText(F).width+A)<delta_x_px){L.fillStyle=this.prefs.label_color;L.textAlign="center";L.fillText(F,H+(delta_x_px/2),10)}}L.restore()};var b=function(y,C,E,F,A){l.call(this,y,C,E,F,A);if(this.prefs.min_value===undefined){var G=Infinity;for(var z=0,B=this.data.length;z<B;z++){G=Math.min(G,this.data[z][1])}this.prefs.min_value=G}if(this.prefs.max_value===undefined){var D=-Infinity;for(var z=0,B=this.data.length;z<B;z++){D=Math.max(D,this.data[z][1])}this.prefs.max_value=D}};b.prototype.default_prefs={min_value:undefined,max_value:undefined,mode:"Histogram",color:"#000",overflow_color:"#F66"};b.prototype.draw=function(S,Q,N,D){var I=false,K=this.prefs.min_value,F=this.prefs.max_value,M=F-K,B=N,C=this.view_start,P=this.view_end-this.view_start,L=this.mode,aa=this.data;S.save();var ac=Math.round(N+K/M*N);if(L!=="Intensity"){S.fillStyle="#aaa";S.fillRect(0,ac,Q,1)}S.beginPath();var Y,G,E;if(aa.length>1){E=Math.ceil((aa[1][0]-aa[0][0])*D)}else{E=10}var A=parseInt(this.prefs.color.slice(1),16),H=(A&16711680)>>16,R=(A&65280)>>8,V=A&255;for(var T=0,U=aa.length;T<U;T++){S.fillStyle=S.strokeStyle=this.prefs.color;Y=Math.round((aa[T][0]-C)*D);G=aa[T][1];var W=false,J=false;if(G===null){if(I&&L==="Filled"){S.lineTo(Y,B)}I=false;continue}if(G<K){J=true;G=K}else{if(G>F){W=true;G=F}}if(L==="Histogram"){G=Math.round(G/M*B);S.fillRect(Y,ac,E,-G)}else{if(L==="Intensity"){var z=(G-K)/M,O=Math.round(H+(255-H)*(1-z)),X=Math.round(R+(255-R)*(1-z)),ab=Math.round(V+(255-V)*(1-z));S.fillStyle="rgb("+O+","+X+","+ab+")";S.fillRect(Y,0,E,B)}else{G=Math.round(B-(G-K)/M*B);if(I){S.lineTo(Y,G)}else{I=true;if(L==="Filled"){S.moveTo(Y,B);S.lineTo(Y,G)}else{S.moveTo(Y,G)}}}}S.fillStyle=this.prefs.overflow_color;if(W||J){var Z;if(L==="Histogram"||L==="Intensity"){Z=E}else{Y-=2;Z=4}if(W){S.fillRect(Y,0,Z,3)}if(J){S.fillRect(Y,B-3,Z,3)}}S.fillStyle=this.prefs.color}if(L==="Filled"){if(I){S.lineTo(Y,ac);S.lineTo(0,ac)}S.fill()}else{S.stroke()}S.restore()};var m=function(y){this.feature_positions={};this.slot_height=y;this.translation=0;this.y_translation=0};m.prototype.map_feature_data=function(z,B,y,A){if(!this.feature_positions[B]){this.feature_positions[B]=[]}this.feature_positions[B].push({data:z,x_start:y,x_end:A})};m.prototype.get_feature_data=function(z,D){var C=Math.floor((D-this.y_translation)/this.slot_height),B;if(!this.feature_positions[C]){return null}z+=this.translation;for(var A=0;A<this.feature_positions[C].length;A++){B=this.feature_positions[C][A];if(z>=B.x_start&&z<=B.x_end){return B.data}}};var o=function(A,D,y,z,C,E,B){l.call(this,A,D,y,z,C);this.alpha_scaler=(E?E:new d());this.height_scaler=(B?B:new d())};o.prototype.default_prefs={block_color:"#FFF",connector_color:"#FFF"};u(o.prototype,{get_required_height:function(A,z){var y=y_scale=this.get_row_height(),B=this.mode;if(B==="no_detail"||B==="Squish"||B==="Pack"){y=A*y_scale}return y+this.get_top_padding(z)+this.get_bottom_padding(z)},get_top_padding:function(y){return 0},get_bottom_padding:function(y){return Math.max(Math.round(this.get_row_height()/2),5)},draw:function(K,I,G,E,F){var Q=this.data,D=this.view_start,M=this.view_end;K.save();K.fillStyle=this.prefs.block_color;K.textAlign="right";var H=this.view_end-this.view_start,L=this.get_row_height(),P=new m(L),B;for(var N=0,O=Q.length;N<O;N++){var A=Q[N],C=A[0],J=A[1],y=A[2],z=(F&&F[C]!==undefined?F[C]:null);if((J<M&&y>D)&&(this.mode==="Dense"||z!==null)){B=this.draw_element(K,this.mode,A,z,D,M,E,L,I);P.map_feature_data(A,z,B[0],B[1])}}K.restore();P.y_translation=this.get_top_padding(I);return P},draw_element:function(E,A,G,C,B,D,F,z,y){console.log("WARNING: Unimplemented function.");return[0,0]}});var c=10,h=3,k=5,w=10,f=1,s=9,e=3,a=9,j=2,g="#ccc";var r=function(A,D,y,z,C,E,B){o.call(this,A,D,y,z,C,E,B);this.draw_background_connector=true;this.draw_individual_connectors=false};u(r.prototype,o.prototype,{get_row_height:function(){var z=this.mode,y;if(z==="Dense"){y=c}else{if(z==="no_detail"){y=h}else{if(z==="Squish"){y=k}else{y=w}}}return y},draw_element:function(M,D,X,H,O,aj,an,ap,y){var T=X[0],al=X[1],ad=X[2]-1,Q=X[3],ae=Math.floor(Math.max(0,(al-O)*an)),N=Math.ceil(Math.min(y,Math.max(0,(ad-O)*an))),ac=ae,ao=N,aa=(D==="Dense"?0:(0+H))*ap+this.get_top_padding(y),L,ah,R=null,ar=null,B=this.prefs.block_color,ag=this.prefs.label_color;M.globalAlpha=this.alpha_scaler.gen_val(X);if(D==="Dense"){H=1}if(D==="no_detail"){M.fillStyle=B;M.fillRect(ae,aa+5,N-ae,f)}else{var K=X[4],Z=X[5],af=X[6],C=X[7],V=true;if(Z&&af){R=Math.floor(Math.max(0,(Z-O)*an));ar=Math.ceil(Math.min(y,Math.max(0,(af-O)*an)))}var am,U;if(D==="Squish"){am=1;U=e;V=false}else{if(D==="Dense"){am=5;U=s}else{am=5;U=a}}if(!C){M.fillStyle=B;M.fillRect(ae,aa+1,N-ae,U);if(K&&V){if(K==="+"){M.fillStyle=M.canvas.manager.get_pattern("right_strand_inv")}else{if(K==="-"){M.fillStyle=M.canvas.manager.get_pattern("left_strand_inv")}}M.fillRect(ae,aa+1,N-ae,U)}}else{var J,W;if(D==="Squish"||D==="Dense"){J=aa+Math.floor(e/2)+1;W=1}else{if(K){J=aa;W=U}else{J+=(e/2)+1;W=1}}if(this.draw_background_connector){if(D==="Squish"||D==="Dense"){M.fillStyle=g}else{if(K){if(K==="+"){M.fillStyle=M.canvas.manager.get_pattern("right_strand")}else{if(K==="-"){M.fillStyle=M.canvas.manager.get_pattern("left_strand")}}}else{M.fillStyle=g}}M.fillRect(ae,J,N-ae,W)}var E;for(var ak=0,A=C.length;ak<A;ak++){var F=C[ak],z=Math.floor(Math.max(0,(F[0]-O)*an)),Y=Math.ceil(Math.min(y,Math.max((F[1]-1-O)*an))),S,ab;if(z>Y){continue}M.fillStyle=B;M.fillRect(z,aa+(U-am)/2+1,Y-z,am);if(R!==undefined&&af>Z&&!(z>ar||Y<R)){var ai=Math.max(z,R),I=Math.min(Y,ar);M.fillRect(ai,aa+1,I-ai,U);if(C.length===1&&D==="Pack"){if(K==="+"){M.fillStyle=M.canvas.manager.get_pattern("right_strand_inv")}else{if(K==="-"){M.fillStyle=M.canvas.manager.get_pattern("left_strand_inv")}}if(ai+14<I){ai+=2;I-=2}M.fillRect(ai,aa+1,I-ai,U)}}if(this.draw_individual_connectors&&S){this.draw_connector(M,S,ab,z,Y,aa)}S=z;ab=Y}if(D==="Pack"){M.globalAlpha=1;M.fillStyle="white";var G=this.height_scaler.gen_val(X),P=Math.ceil(U*G),aq=Math.round((U-P)/2);if(G!==1){M.fillRect(ae,J+1,N-ae,aq);M.fillRect(ae,J+U-aq+1,N-ae,aq)}}}M.globalAlpha=1;if(D==="Pack"&&al>O){M.fillStyle=ag;if(O===0&&ae-M.measureText(Q).width<0){M.textAlign="left";M.fillText(Q,N+j,aa+8);ao+=M.measureText(Q).width+j}else{M.textAlign="right";M.fillText(Q,ae-j,aa+8);ac-=M.measureText(Q).width+j}}}M.globalAlpha=1;return[ac,ao]}});var t=function(B,E,y,A,D,F,C,z){o.call(this,B,E,y,A,D,F,C);this.ref_seq=(z?z.data:null)};u(t.prototype,o.prototype,{get_row_height:function(){var y,z=this.mode;if(z==="Dense"){y=c}else{if(z==="Squish"){y=k}else{y=w;if(this.prefs.show_insertions){y*=2}}}return y},draw_read:function(K,A,ag,V,L,aa,ad,C,B,M){K.textAlign="center";var J=this,R=[L,aa],Z=0,W=0,D=0,F=K.canvas.manager.char_width_px,y=(B==="+"?this.prefs.block_color:this.prefs.reverse_strand_color);var O=[];if((A==="Pack"||this.mode==="Auto")&&M!==undefined&&ag>F){D=Math.round(ag/2)}if(!C){C=[[0,M.length]]}for(var G=0,I=C.length;G<I;G++){var z=C[G],E="MIDNSHP=X"[z[0]],S=z[1];if(E==="H"||E==="S"){Z-=S}var U=ad+Z,Y=Math.floor(Math.max(0,(U-L)*ag)),ab=Math.floor(Math.max(0,(U+S-L)*ag));if(Y===ab){ab+=1}switch(E){case"H":break;case"S":case"M":case"=":if(is_overlap([U,U+S],R)){var N=M.slice(W,W+S);if(D>0){K.fillStyle=y;K.fillRect(Y-D,V+1,ab-Y,9);K.fillStyle=g;for(var af=0,H=N.length;af<H;af++){if(this.prefs.show_differences){if(this.ref_seq){var P=this.ref_seq[U-L+af];if(!P||P.toLowerCase()===N[af].toLowerCase()){continue}}else{continue}}if(U+af>=L&&U+af<=aa){var X=Math.floor(Math.max(0,(U+af-L)*ag));K.fillText(N[af],X,V+9)}}}else{K.fillStyle=y;K.fillRect(Y,V+4,ab-Y,e)}}W+=S;Z+=S;break;case"N":K.fillStyle=g;K.fillRect(Y-D,V+5,ab-Y,1);Z+=S;break;case"D":K.fillStyle="red";K.fillRect(Y-D,V+4,ab-Y,3);Z+=S;break;case"P":break;case"I":var ah=Y-D;if(is_overlap([U,U+S],R)){var N=M.slice(W,W+S);if(this.prefs.show_insertions){var T=Y-(ab-Y)/2;if((A==="Pack"||this.mode==="Auto")&&M!==undefined&&ag>F){K.fillStyle="yellow";K.fillRect(T-D,V-9,ab-Y,9);O[O.length]={type:"triangle",data:[ah,V+4,5]};K.fillStyle=g;switch(compute_overlap([U,U+S],R)){case (OVERLAP_START):N=N.slice(L-U);break;case (OVERLAP_END):N=N.slice(0,U-aa);break;case (CONTAINED_BY):break;case (CONTAINS):N=N.slice(L-U,U-aa);break}for(var af=0,H=N.length;af<H;af++){var X=Math.floor(Math.max(0,(U+af-L)*ag));K.fillText(N[af],X-(ab-Y)/2,V)}}else{K.fillStyle="yellow";K.fillRect(T,V+(this.mode!=="Dense"?2:5),ab-Y,(A!=="Dense"?e:s))}}else{if((A==="Pack"||this.mode==="Auto")&&M!==undefined&&ag>F){O.push({type:"text",data:[N.length,ah,V+9]})}else{}}}W+=S;break;case"X":W+=S;break}}K.fillStyle="yellow";var Q,ai,ae;for(var ac=0;ac<O.length;ac++){Q=O[ac];ai=Q.type;ae=Q.data;if(ai==="text"){K.save();K.font="bold "+K.font;K.fillText(ae[0],ae[1],ae[2]);K.restore()}else{if(ai==="triangle"){q(K,ae[0],ae[1],ae[2])}}}},draw_element:function(R,M,E,B,U,z,I,S,P){var H=E[0],Q=E[1],A=E[2],J=E[3],D=Math.floor(Math.max(0,(Q-U)*I)),F=Math.ceil(Math.min(P,Math.max(0,(A-U)*I))),C=(M==="Dense"?0:(0+B))*S,G=this.prefs.label_color,O=0;if((M==="Pack"||this.mode==="Auto")&&I>R.canvas.manager.char_width_px){var O=Math.round(I/2)}if(E[5] instanceof Array){var N=Math.floor(Math.max(0,(E[4][0]-U)*I)),L=Math.ceil(Math.min(P,Math.max(0,(E[4][1]-U)*I))),K=Math.floor(Math.max(0,(E[5][0]-U)*I)),y=Math.ceil(Math.min(P,Math.max(0,(E[5][1]-U)*I)));if(E[4][1]>=U&&E[4][0]<=z&&E[4][2]){this.draw_read(R,M,I,C,U,z,E[4][0],E[4][2],E[4][3],E[4][4])}if(E[5][1]>=U&&E[5][0]<=z&&E[5][2]){this.draw_read(R,M,I,C,U,z,E[5][0],E[5][2],E[5][3],E[5][4])}if(K>L){R.fillStyle=g;p(R,L-O,C+5,K-O,C+5)}}else{this.draw_read(R,M,I,C,U,z,Q,E[4],E[5],E[6])}if(M==="Pack"&&Q>U&&J!=="."){R.fillStyle=this.prefs.label_color;var T=1;if(T===0&&D-R.measureText(J).width<0){R.textAlign="left";R.fillText(J,F+j-O,C+8)}else{R.textAlign="right";R.fillText(J,D-j-O,C+8)}}return[0,0]}});var n=function(A,D,y,z,C,E,B){r.call(this,A,D,y,z,C,E,B);this.longest_feature_length=this.calculate_longest_feature_length();this.draw_background_connector=false;this.draw_individual_connectors=true};u(n.prototype,o.prototype,r.prototype,{calculate_longest_feature_length:function(){var z=0;for(var C=0,y=this.data.length;C<y;C++){var B=this.data[C],A=B[1],D=B[2];z=Math.max(z,D-A)}return z},get_top_padding:function(z){var y=this.view_end-this.view_start,A=z/y;return Math.min(128,Math.ceil((this.longest_feature_length/2)*A))},draw_connector:function(G,B,F,H,E,D){var y=(F+H)/2,C=H-y;var A=Math.PI,z=0;if(C>0){G.beginPath();G.arc(y,D,H-y,Math.PI,0);G.stroke()}}});x.Scaler=d;x.SummaryTreePainter=v;x.LinePainter=b;x.LinkedFeaturePainter=r;x.ReadPainter=t;x.ArcLinkedFeaturePainter=n};(function(d){var c={};var b=function(e){return c[e]};var a=function(f,g){var e={};g(b,e);c[f]=e};a("class",class_module);a("slotting",slotting_module);a("painters",painters_module);a("trackster",trackster_module);for(key in c.trackster){d[key]=c.trackster[key]}})(window);
\ No newline at end of file
+var class_module=function(b,a){var c=function(){var f=arguments[0];for(var e=1;e<arguments.length;e++){var d=arguments[e];for(key in d){f[key]=d[key]}}return f};a.extend=c};var requestAnimationFrame=(function(){return window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.oRequestAnimationFrame||window.msRequestAnimationFrame||function(b,a){window.setTimeout(b,1000/60)}})();var BEFORE=1001,CONTAINS=1002,OVERLAP_START=1003,OVERLAP_END=1004,CONTAINED_BY=1005,AFTER=1006;var compute_overlap=function(e,b){var g=e[0],f=e[1],d=b[0],c=b[1],a;if(g<d){if(f<d){a=BEFORE}else{if(f<=c){a=OVERLAP_START}else{a=CONTAINS}}}else{if(g>c){a=AFTER}else{if(f<=c){a=CONTAINED_BY}else{a=OVERLAP_END}}}return a};var is_overlap=function(c,b){var a=compute_overlap(c,b);return(a!==BEFORE&&a!==AFTER)};var is_deferred=function(a){return("isResolved" in a)};var get_random_color=function(a){if(!a){a="#ffffff"}if(typeof(a)==="string"){a=[a]}for(var j=0;j<a.length;j++){a[j]=parseInt(a[j].slice(1),16)}var n=function(t,s,i){return((t*299)+(s*587)+(i*114))/1000};var e=function(v,u,w,s,i,t){return(Math.max(v,s)-Math.min(v,s))+(Math.max(u,i)-Math.min(u,i))+(Math.max(w,t)-Math.min(w,t))};var g,o,f,k,q,h,r,c,d,b,p,m=false,l=0;do{g=Math.round(Math.random()*16777215);o=(g&16711680)>>16;f=(g&65280)>>8;k=g&255;d=n(o,f,k);m=true;for(var j=0;j<a.length;j++){q=a[j];h=(q&16711680)>>16;r=(q&65280)>>8;c=q&255;b=n(h,r,c);p=e(o,f,k,h,r,c);if((Math.abs(d-b)<40)||(p<200)){m=false;break}}l++}while(!m&&l<=10);return"#"+(16777216+g).toString(16).substr(1,6)};var create_action_icon=function(c,b,a){return $("<a/>").attr("href","javascript:void(0);").attr("title",c).addClass("icon-button").addClass(b).tipsy({gravity:"s"}).click(a)};var trackster_module=function(e,U){var p=e("class").extend,s=e("slotting"),J=e("painters");var ab=function(ac,ad){this.document=ac;this.default_font=ad!==undefined?ad:"9px Monaco, Lucida Console, monospace";this.dummy_canvas=this.new_canvas();this.dummy_context=this.dummy_canvas.getContext("2d");this.dummy_context.font=this.default_font;this.char_width_px=this.dummy_context.measureText("A").width;this.patterns={};this.load_pattern("right_strand","/visualization/strand_right.png");this.load_pattern("left_strand","/visualization/strand_left.png");this.load_pattern("right_strand_inv","/visualization/strand_right_inv.png");this.load_pattern("left_strand_inv","/visualization/strand_left_inv.png")};p(ab.prototype,{load_pattern:function(ac,ag){var ad=this.patterns,ae=this.dummy_context,af=new Image();af.src=image_path+ag;af.onload=function(){ad[ac]=ae.createPattern(af,"repeat")}},get_pattern:function(ac){return this.patterns[ac]},new_canvas:function(){var ac=this.document.createElement("canvas");if(window.G_vmlCanvasManager){G_vmlCanvasManager.initElement(ac)}ac.manager=this;return ac}});var n={};var l=function(ac,ad){n[ac.attr("id")]=ad};var m=function(ac,ae,ag,af){ag=".group";var ad={};n[ac.attr("id")]=af;ac.bind("drag",{handle:"."+ae,relative:true},function(ao,ap){var an=$(this);var at=$(this).parent(),ak=at.children(),am=n[$(this).attr("id")],aj,ai,aq,ah,al;ai=$(this).parents(ag);if(ai.length!==0){aq=ai.position().top;ah=aq+ai.outerHeight();if(ap.offsetY<aq){$(this).insertBefore(ai);var ar=n[ai.attr("id")];ar.remove_drawable(am);ar.container.add_drawable_before(am,ar);return}else{if(ap.offsetY>ah){$(this).insertAfter(ai);var ar=n[ai.attr("id")];ar.remove_drawable(am);ar.container.add_drawable(am);return}}}ai=null;for(al=0;al<ak.length;al++){aj=$(ak.get(al));aq=aj.position().top;ah=aq+aj.outerHeight();if(aj.is(ag)&&this!==aj.get(0)&&ap.offsetY>=aq&&ap.offsetY<=ah){if(ap.offsetY-aq<ah-ap.offsetY){aj.find(".content-div").prepend(this)}else{aj.find(".content-div").append(this)}if(am.container){am.container.remove_drawable(am)}n[aj.attr("id")].add_drawable(am);return}}var aj;for(al=0;al<ak.length;al++){aj=$(ak.get(al));if(ap.offsetY<aj.position().top&&!(aj.hasClass("reference-track")||aj.hasClass("intro"))){break}}if(al===ak.length){if(this!==ak.get(al-1)){at.append(this);n[at.attr("id")].move_drawable(am,al)}}else{if(this!==ak.get(al)){$(this).insertBefore(ak.get(al));n[at.attr("id")].move_drawable(am,(ap.deltaY>0?al-1:al))}}}).bind("dragstart",function(){ad["border-top"]=ac.css("border-top");ad["border-bottom"]=ac.css("border-bottom");$(this).css({"border-top":"1px solid blue","border-bottom":"1px solid blue"})}).bind("dragend",function(){$(this).css(ad)})};U.moveable=m;var aa=16,D=9,A=20,x=100,G=12000,R=400,I=5000,u=100,o="There was an error in indexing this dataset. ",H="A converter for this dataset is not installed. Please check your datatypes_conf.xml file.",B="No data for this chrom/contig.",t="Preparing data. This is very fast for a small dataset but can take a long time for a large dataset. If visualization is saved and closed, preparation will continue in the background.",v="Tool cannot be rerun: ",a="Loading data...",V="Ready for display",O=10,F=20;function W(ad,ac){if(!ac){ac=0}var ae=Math.pow(10,ac);return Math.round(ad*ae)/ae}var c=function(ac){this.num_elements=ac;this.clear()};p(c.prototype,{get:function(ad){var ac=this.key_ary.indexOf(ad);if(ac!==-1){if(this.obj_cache[ad].stale){this.key_ary.splice(ac,1);delete this.obj_cache[ad]}else{this.move_key_to_end(ad,ac)}}return this.obj_cache[ad]},set:function(ad,ae){if(!this.obj_cache[ad]){if(this.key_ary.length>=this.num_elements){var ac=this.key_ary.shift();delete this.obj_cache[ac]}this.key_ary.push(ad)}this.obj_cache[ad]=ae;return ae},move_key_to_end:function(ad,ac){this.key_ary.splice(ac,1);this.key_ary.push(ad)},clear:function(){this.obj_cache={};this.key_ary=[]},size:function(){return this.key_ary.length}});var P=function(ad,ac){c.call(this,ad);this.track=ac};p(P.prototype,c.prototype,{load_data:function(al,ag,aj,ad,ai){var ak=this.track.view.chrom,af={chrom:ak,low:al,high:ag,mode:aj,resolution:ad,dataset_id:this.track.dataset_id,hda_ldda:this.track.hda_ldda};$.extend(af,ai);if(this.track.filters_manager){var am=[];var ac=this.track.filters_manager.filters;for(var ah=0;ah<ac.length;ah++){am.push(ac[ah].name)}af.filter_cols=JSON.stringify(am)}var ae=this;return $.getJSON(this.track.data_url,af,function(an){ae.set_data(al,ag,an)})},get_data:function(ak,ae,ai,ad,ah){var al=this.get(ak,ae);if(al&&(is_deferred(al)||this.track.data_and_mode_compatible(al,ai))){return al}var am,aj,ac,ag,ai,al;for(var af=0;af<this.key_ary.length;af++){am=this.key_ary[af];aj=this.split_key(am);ac=aj[0];ag=aj[1];if(ak>=ac&&ae<=ag){var al=this.obj_cache[am];if(is_deferred(al)||(this.track.data_and_mode_compatible(al,ai)&&this.track.can_subset(al))){this.move_key_to_end(am,af);return al}}}al=this.load_data(ak,ae,ai,ad,ah);this.set_data(ak,ae,al);return al},DEEP_DATA_REQ:"deep",BROAD_DATA_REQ:"breadth",get_more_data:function(ak,af,aj,ae,ai,ag){var al=this.get(ak,af);if(!(al&&this.track.data_and_mode_compatible(al,aj))){console.log("ERROR: no current data for: ",this.track,ak,af,aj,ae,ai);return}al.stale=true;var ad=ak;if(ag===this.DEEP_DATA_REQ){$.extend(ai,{start_val:al.data.length+1})}else{if(ag===this.BROAD_DATA_REQ){ad=(al.max_high?al.max_high:al.data[al.data.length-1][2])+1}}var ac=this,ah=this.load_data(ad,af,aj,ae,ai);new_data_available=$.Deferred();this.set_data(ak,af,new_data_available);$.when(ah).then(function(am){if(am.data){am.data=al.data.concat(am.data);if(am.max_low){am.max_low=al.max_low}if(am.message){am.message=am.message.replace(/[0-9]+/,am.data.length)}}ac.set_data(ak,af,am);new_data_available.resolve(am)});return new_data_available},get:function(ac,ad){return c.prototype.get.call(this,this.gen_key(ac,ad))},set_data:function(ad,ae,ac){return this.set(this.gen_key(ad,ae),ac)},gen_key:function(ac,ae){var ad=ac+"_"+ae;return ad},split_key:function(ac){return ac.split("_")}});var E=function(ad,ac,ae){P.call(this,ad,ac,ae)};p(E.prototype,P.prototype,c.prototype,{get:P.prototype.get,load_data:function(ac,af,ag,ad,ae){if(ad>1){return{data:null}}return P.prototype.load_data.call(this,ac,af,ag,ad,ae)}});var q=function(ad,ac,af){if(!q.id_counter){q.id_counter=0}this.id=q.id_counter++;this.name=af.name;this.view=ad;this.container=ac;this.config=new C({track:this,params:[{key:"name",label:"Name",type:"text",default_value:this.name}],saved_values:af.prefs,onchange:function(){this.track.set_name(this.track.config.values.name)}});this.prefs=this.config.values;this.drag_handle_class=af.drag_handle_class;this.is_overview=false;this.action_icons={};this.content_visible=true;this.container_div=this.build_container_div();this.header_div=this.build_header_div();if(this.header_div){this.container_div.append(this.header_div);this.icons_div=$("<div/>").css("float","left").hide().appendTo(this.header_div);this.build_action_icons(this.action_icons_def);this.header_div.append($("<div style='clear: both'/>"));this.header_div.dblclick(function(ag){ag.stopPropagation()});var ae=this;this.container_div.hover(function(){ae.icons_div.show()},function(){ae.icons_div.hide()});$("<div style='clear: both'/>").appendTo(this.container_div)}};q.prototype.action_icons_def=[{name:"toggle_icon",title:"Hide/show content",css_class:"toggle",on_click_fn:function(ac){if(ac.content_visible){ac.action_icons.toggle_icon.addClass("toggle-expand").removeClass("toggle");ac.hide_contents();ac.content_visible=false}else{ac.action_icons.toggle_icon.addClass("toggle").removeClass("toggle-expand");ac.content_visible=true;ac.show_contents()}}},{name:"settings_icon",title:"Edit settings",css_class:"settings-icon",on_click_fn:function(ad){var af=function(){hide_modal();$(window).unbind("keypress.check_enter_esc")},ac=function(){ad.config.update_from_form($(".dialog-box"));hide_modal();$(window).unbind("keypress.check_enter_esc")},ae=function(ag){if((ag.keyCode||ag.which)===27){af()}else{if((ag.keyCode||ag.which)===13){ac()}}};$(window).bind("keypress.check_enter_esc",ae);show_modal("Configure",ad.config.build_form(),{Cancel:af,OK:ac})}},{name:"remove_icon",title:"Remove",css_class:"remove-icon",on_click_fn:function(ac){$(".tipsy").remove();ac.remove()}}];p(q.prototype,{init:function(){},changed:function(){this.view.changed()},can_draw:function(){if(this.enabled&&this.content_visible){return true}return false},request_draw:function(){},_draw:function(){},to_dict:function(){},update_icons:function(){},set_name:function(ac){this.old_name=this.name;this.name=ac;this.name_div.text(this.name)},revert_name:function(){if(this.old_name){this.name=this.old_name;this.name_div.text(this.name)}},remove:function(){this.changed();this.container.remove_drawable(this);var ac=this.view;this.container_div.hide(0,function(){$(this).remove();ac.update_intro_div()})},build_container_div:function(){},build_header_div:function(){},add_action_icon:function(ad,ai,ah,ag,ac,af){var ae=this;this.action_icons[ad]=$("<a/>").attr("href","javascript:void(0);").attr("title",ai).addClass("icon-button").addClass(ah).tipsy({gravity:"s"}).click(function(){ag(ae)}).appendTo(this.icons_div);if(af){this.action_icons[ad].hide()}},build_action_icons:function(ac){var ae;for(var ad=0;ad<ac.length;ad++){ae=ac[ad];this.add_action_icon(ae.name,ae.title,ae.css_class,ae.on_click_fn,ae.prepend,ae.hide)}},update_icons:function(){},hide_contents:function(){},show_contents:function(){}});var w=function(ad,ac,ae){q.call(this,ad,ac,ae);this.obj_type=ae.obj_type;this.drawables=[]};p(w.prototype,q.prototype,{unpack_drawables:function(ae){this.drawables=[];var ad;for(var ac=0;ac<ae.length;ac++){ad=object_from_template(ae[ac],this);this.add_drawable(ad)}},init:function(){for(var ac=0;ac<this.drawables.length;ac++){this.drawables[ac].init()}},_draw:function(){for(var ac=0;ac<this.drawables.length;ac++){this.drawables[ac]._draw()}},to_dict:function(){var ad=[];for(var ac=0;ac<this.drawables.length;ac++){ad.push(this.drawables[ac].to_dict())}return{name:this.name,prefs:this.prefs,obj_type:this.obj_type,drawables:ad}},add_drawable:function(ac){this.drawables.push(ac);ac.container=this;this.changed()},add_drawable_before:function(ae,ac){this.changed();var ad=this.drawables.indexOf(ac);if(ad!==-1){this.drawables.splice(ad,0,ae);return true}return false},replace_drawable:function(ae,ac,ad){var af=this.drawables.indexOf(ae);if(af!==-1){this.drawables[af]=ac;if(ad){ae.container_div.replaceWith(ac.container_div)}this.changed()}return af},remove_drawable:function(ad){var ac=this.drawables.indexOf(ad);if(ac!==-1){this.drawables.splice(ac,1);ad.container=null;this.changed();return true}return false},move_drawable:function(ad,ae){var ac=this.drawables.indexOf(ad);if(ac!==-1){this.drawables.splice(ac,1);this.drawables.splice(ae,0,ad);this.changed();return true}return false}});var N=function(ad,ac,af){p(af,{obj_type:"DrawableGroup",drag_handle_class:"group-handle"});w.call(this,ad,ac,af);this.content_div=$("<div/>").addClass("content-div").attr("id","group_"+this.id+"_content_div").appendTo(this.container_div);l(this.container_div,this);l(this.content_div,this);m(this.container_div,this.drag_handle_class,".group",this);this.filters_manager=new X(this);this.header_div.after(this.filters_manager.parent_div);this.saved_filters_managers=[];if("drawables" in af){this.unpack_drawables(af.drawables)}if("filters" in af){var ae=this.filters_manager;this.filters_manager=new X(this,af.filters);ae.parent_div.replaceWith(this.filters_manager.parent_div);if(af.filters.visible){this.setup_multitrack_filtering()}}};p(N.prototype,q.prototype,w.prototype,{action_icons_def:[q.prototype.action_icons_def[0],q.prototype.action_icons_def[1],{name:"composite_icon",title:"Show composite track",css_class:"layers-stack",on_click_fn:function(ac){$(".tipsy").remove();ac.show_composite_track()}},{name:"filters_icon",title:"Filters",css_class:"filters-icon",on_click_fn:function(ac){if(ac.filters_manager.visible()){ac.filters_manager.clear_filters();ac._restore_filter_managers()}else{ac.setup_multitrack_filtering();ac.request_draw(true)}ac.filters_manager.toggle()}},q.prototype.action_icons_def[2]],build_container_div:function(){var ac=$("<div/>").addClass("group").attr("id","group_"+this.id);if(this.container){this.container.content_div.append(ac)}return ac},build_header_div:function(){var ac=$("<div/>").addClass("track-header");ac.append($("<div/>").addClass(this.drag_handle_class));this.name_div=$("<div/>").addClass("track-name").text(this.name).appendTo(ac);return ac},hide_contents:function(){this.tiles_div.hide()},show_contents:function(){this.tiles_div.show();this.request_draw()},update_icons:function(){var ae=this.drawables.length;if(ae===0){this.action_icons.composite_icon.hide();this.action_icons.filters_icon.hide()}else{if(ae===1){if(this.drawables[0] instanceof h){this.action_icons.composite_icon.show()}this.action_icons.filters_icon.hide()}else{var ai,ao=true,ag=this.drawables[0].get_type(),ac=0;for(var al=0;al<ae;al++){ai=this.drawables[al];if(ai.get_type()!==ag){can_composite=false;break}if(ai instanceof d){ac++}}if(ao||ac===1){this.action_icons.composite_icon.show()}else{this.action_icons.composite_icon.hide();$(".tipsy").remove()}if(ac>1&&ac===this.drawables.length){var ap={},ad;ai=this.drawables[0];for(var ak=0;ak<ai.filters_manager.filters.length;ak++){ad=ai.filters_manager.filters[ak];ap[ad.name]=[ad]}for(var al=1;al<this.drawables.length;al++){ai=this.drawables[al];for(var ak=0;ak<ai.filters_manager.filters.length;ak++){ad=ai.filters_manager.filters[ak];if(ad.name in ap){ap[ad.name].push(ad)}}}this.filters_manager.remove_all();var af,ah,aj,am;for(var an in ap){af=ap[an];if(af.length===ac){ah=new S({name:af[0].name,index:af[0].index});this.filters_manager.add_filter(ah)}}if(this.filters_manager.filters.length>0){this.action_icons.filters_icon.show()}else{this.action_icons.filters_icon.hide()}}else{this.action_icons.filters_icon.hide()}}}},_restore_filter_managers:function(){for(var ac=0;ac<this.drawables.length;ac++){this.drawables[ac].filters_manager=this.saved_filters_managers[ac]}this.saved_filters_managers=[]},setup_multitrack_filtering:function(){if(this.filters_manager.filters.length>0){this.saved_filters_managers=[];for(var ac=0;ac<this.drawables.length;ac++){drawable=this.drawables[ac];this.saved_filters_managers.push(drawable.filters_manager);drawable.filters_manager=this.filters_manager}}this.filters_manager.init_filters()},show_composite_track:function(){var ag=[];for(var ad=0;ad<this.drawables.length;ad++){ag.push(this.drawables[ad].name)}var ae="Composite Track of "+this.drawables.length+" tracks ("+ag.join(", ")+")";var af=new h(this.view,this.view,{name:ae,drawables:this.drawables});var ac=this.container.replace_drawable(this,af,true);af.request_draw()},add_drawable:function(ac){w.prototype.add_drawable.call(this,ac);this.update_icons()},remove_drawable:function(ac){w.prototype.remove_drawable.call(this,ac);this.update_icons()},to_dict:function(){if(this.filters_manager.visible()){this._restore_filter_managers()}var ac=p(w.prototype.to_dict.call(this),{filters:this.filters_manager.to_dict()});if(this.filters_manager.visible()){this.setup_multitrack_filtering()}return ac},request_draw:function(ac,ae){for(var ad=0;ad<this.drawables.length;ad++){this.drawables[ad].request_draw(ac,ae)}}});var Z=function(ac){p(ac,{obj_type:"View"});w.call(this,"View",ac.container,ac);this.chrom=null;this.vis_id=ac.vis_id;this.dbkey=ac.dbkey;this.label_tracks=[];this.tracks_to_be_redrawn=[];this.max_low=0;this.max_high=0;this.zoom_factor=3;this.min_separation=30;this.has_changes=false;this.load_chroms_deferred=null;this.init();this.canvas_manager=new ab(this.container.get(0).ownerDocument);this.reset()};p(Z.prototype,w.prototype,{init:function(){this.requested_redraw=false;var ae=this.container,ac=this;this.top_container=$("<div/>").addClass("top-container").appendTo(ae);this.browser_content_div=$("<div/>").addClass("content").css("position","relative").appendTo(ae);this.bottom_container=$("<div/>").addClass("bottom-container").appendTo(ae);this.top_labeltrack=$("<div/>").addClass("top-labeltrack").appendTo(this.top_container);this.viewport_container=$("<div/>").addClass("viewport-container").attr("id","viewport-container").appendTo(this.browser_content_div);this.content_div=this.viewport_container;l(this.viewport_container,ac);this.intro_div=$("<div/>").addClass("intro").appendTo(this.viewport_container).hide();var af=$("<div/>").text("Add Datasets to Visualization").addClass("action-button").appendTo(this.intro_div).click(function(){add_tracks()});this.nav_labeltrack=$("<div/>").addClass("nav-labeltrack").appendTo(this.bottom_container);this.nav_container=$("<div/>").addClass("trackster-nav-container").prependTo(this.top_container);this.nav=$("<div/>").addClass("trackster-nav").appendTo(this.nav_container);this.overview=$("<div/>").addClass("overview").appendTo(this.bottom_container);this.overview_viewport=$("<div/>").addClass("overview-viewport").appendTo(this.overview);this.overview_close=$("<a/>").attr("href","javascript:void(0);").attr("title","Close overview").addClass("icon-button overview-close tooltip").hide().appendTo(this.overview_viewport);this.overview_highlight=$("<div/>").addClass("overview-highlight").hide().appendTo(this.overview_viewport);this.overview_box_background=$("<div/>").addClass("overview-boxback").appendTo(this.overview_viewport);this.overview_box=$("<div/>").addClass("overview-box").appendTo(this.overview_viewport);this.default_overview_height=this.overview_box.height();this.nav_controls=$("<div/>").addClass("nav-controls").appendTo(this.nav);this.chrom_select=$("<select/>").attr({name:"chrom"}).css("width","15em").addClass("no-autocomplete").append("<option value=''>Loading</option>").appendTo(this.nav_controls);var ad=function(ag){if(ag.type==="focusout"||(ag.keyCode||ag.which)===13||(ag.keyCode||ag.which)===27){if((ag.keyCode||ag.which)!==27){ac.go_to($(this).val())}$(this).hide();$(this).val("");ac.location_span.show();ac.chrom_select.show()}};this.nav_input=$("<input/>").addClass("nav-input").hide().bind("keyup focusout",ad).appendTo(this.nav_controls);this.location_span=$("<span/>").addClass("location").attr("original-title","Click to change location").tipsy({gravity:"n"}).appendTo(this.nav_controls);this.location_span.click(function(){ac.location_span.hide();ac.chrom_select.hide();ac.nav_input.val(ac.chrom+":"+ac.low+"-"+ac.high);ac.nav_input.css("display","inline-block");ac.nav_input.select();ac.nav_input.focus()});if(this.vis_id!==undefined){this.hidden_input=$("<input/>").attr("type","hidden").val(this.vis_id).appendTo(this.nav_controls)}this.zo_link=$("<a/>").attr("id","zoom-out").attr("title","Zoom out").tipsy({gravity:"n"}).click(function(){ac.zoom_out();ac.request_redraw()}).appendTo(this.nav_controls);this.zi_link=$("<a/>").attr("id","zoom-in").attr("title","Zoom in").tipsy({gravity:"n"}).click(function(){ac.zoom_in();ac.request_redraw()}).appendTo(this.nav_controls);this.load_chroms_deferred=this.load_chroms({low:0});this.chrom_select.bind("change",function(){ac.change_chrom(ac.chrom_select.val())});this.browser_content_div.click(function(ag){$(this).find("input").trigger("blur")});this.browser_content_div.bind("dblclick",function(ag){ac.zoom_in(ag.pageX,this.viewport_container)});this.overview_box.bind("dragstart",function(ag,ah){this.current_x=ah.offsetX}).bind("drag",function(ag,ai){var aj=ai.offsetX-this.current_x;this.current_x=ai.offsetX;var ah=Math.round(aj/ac.viewport_container.width()*(ac.max_high-ac.max_low));ac.move_delta(-ah)});this.overview_close.click(function(){ac.reset_overview()});this.viewport_container.bind("draginit",function(ag,ah){if(ag.clientX>ac.viewport_container.width()-16){return false}}).bind("dragstart",function(ag,ah){ah.original_low=ac.low;ah.current_height=ag.clientY;ah.current_x=ah.offsetX}).bind("drag",function(ai,ak){var ag=$(this);var al=ak.offsetX-ak.current_x;var ah=ag.scrollTop()-(ai.clientY-ak.current_height);ag.scrollTop(ah);ak.current_height=ai.clientY;ak.current_x=ak.offsetX;var aj=Math.round(al/ac.viewport_container.width()*(ac.high-ac.low));ac.move_delta(aj)}).bind("mousewheel",function(ai,ak,ah,ag){if(ah){ah*=50;var aj=Math.round(-ah/ac.viewport_container.width()*(ac.high-ac.low));ac.move_delta(aj)}});this.top_labeltrack.bind("dragstart",function(ag,ah){return $("<div />").css({height:ac.browser_content_div.height()+ac.top_labeltrack.height()+ac.nav_labeltrack.height()+1,top:"0px",position:"absolute","background-color":"#ccf",opacity:0.5,"z-index":1000}).appendTo($(this))}).bind("drag",function(ak,al){$(al.proxy).css({left:Math.min(ak.pageX,al.startX)-ac.container.offset().left,width:Math.abs(ak.pageX-al.startX)});var ah=Math.min(ak.pageX,al.startX)-ac.container.offset().left,ag=Math.max(ak.pageX,al.startX)-ac.container.offset().left,aj=(ac.high-ac.low),ai=ac.viewport_container.width();ac.update_location(Math.round(ah/ai*aj)+ac.low,Math.round(ag/ai*aj)+ac.low)}).bind("dragend",function(al,am){var ah=Math.min(al.pageX,am.startX),ag=Math.max(al.pageX,am.startX),aj=(ac.high-ac.low),ai=ac.viewport_container.width(),ak=ac.low;ac.low=Math.round(ah/ai*aj)+ak;ac.high=Math.round(ag/ai*aj)+ak;$(am.proxy).remove();ac.request_redraw()});this.add_label_track(new Y(this,{content_div:this.top_labeltrack}));this.add_label_track(new Y(this,{content_div:this.nav_labeltrack}));$(window).bind("resize",function(){ac.resize_window()});$(document).bind("redraw",function(){ac.redraw()});this.reset();$(window).trigger("resize")},changed:function(){this.has_changes=true},update_intro_div:function(){if(this.drawables.length===0){this.intro_div.show()}else{this.intro_div.hide()}},update_location:function(ac,ad){this.location_span.text(commatize(ac)+" - "+commatize(ad));this.nav_input.val(this.chrom+":"+commatize(ac)+"-"+commatize(ad))},load_chroms:function(ae){ae.num=u;ae.dbkey=this.dbkey;var ac=this,ad=$.Deferred();$.ajax({url:chrom_url,data:ae,dataType:"json",success:function(ag){if(ag.chrom_info.length===0){alert("Invalid chromosome: "+ae.chrom);return}if(ag.reference){ac.add_label_track(new y(ac))}ac.chrom_data=ag.chrom_info;var aj='<option value="">Select Chrom/Contig</option>';for(var ai=0,af=ac.chrom_data.length;ai<af;ai++){var ah=ac.chrom_data[ai].chrom;aj+='<option value="'+ah+'">'+ah+"</option>"}if(ag.prev_chroms){aj+='<option value="previous">Previous '+u+"</option>"}if(ag.next_chroms){aj+='<option value="next">Next '+u+"</option>"}ac.chrom_select.html(aj);ac.chrom_start_index=ag.start_index;ad.resolve(ag)},error:function(){alert("Could not load chroms for this dbkey:",ac.dbkey)}});return ad},change_chrom:function(ah,ad,aj){if(!ah||ah==="None"){return}var ae=this;if(ah==="previous"){ae.load_chroms({low:this.chrom_start_index-u});return}if(ah==="next"){ae.load_chroms({low:this.chrom_start_index+u});return}var ai=$.grep(ae.chrom_data,function(ak,al){return ak.chrom===ah})[0];if(ai===undefined){ae.load_chroms({chrom:ah},function(){ae.change_chrom(ah,ad,aj)});return}else{if(ah!==ae.chrom){ae.chrom=ah;ae.chrom_select.val(ae.chrom);ae.max_high=ai.len-1;ae.reset();ae.request_redraw(true);for(var ag=0,ac=ae.drawables.length;ag<ac;ag++){var af=ae.drawables[ag];if(af.init){af.init()}}if(ae.reference_track){ae.reference_track.init()}}if(ad!==undefined&&aj!==undefined){ae.low=Math.max(ad,0);ae.high=Math.min(aj,ae.max_high)}ae.reset_overview();ae.request_redraw()}},go_to:function(ag){ag=ag.replace(/ |,/g,"");var ak=this,ac,af,ad=ag.split(":"),ai=ad[0],aj=ad[1];if(aj!==undefined){try{var ah=aj.split("-");ac=parseInt(ah[0],10);af=parseInt(ah[1],10)}catch(ae){return false}}ak.change_chrom(ai,ac,af)},move_fraction:function(ae){var ac=this;var ad=ac.high-ac.low;this.move_delta(ae*ad)},move_delta:function(ae){var ac=this;var ad=ac.high-ac.low;if(ac.low-ae<ac.max_low){ac.low=ac.max_low;ac.high=ac.max_low+ad}else{if(ac.high-ae>ac.max_high){ac.high=ac.max_high;ac.low=ac.max_high-ad}else{ac.high-=ae;ac.low-=ae}}ac.request_redraw()},add_drawable:function(ac){w.prototype.add_drawable.call(this,ac);ac.init();this.changed();this.update_intro_div()},add_label_track:function(ac){ac.view=this;ac.init();this.label_tracks.push(ac)},remove_drawable:function(ae,ad){w.prototype.remove_drawable.call(this,ae);if(ad){var ac=this;ae.container_div.hide(0,function(){$(this).remove();ac.update_intro_div()})}},reset:function(){this.low=this.max_low;this.high=this.max_high;this.viewport_container.find(".yaxislabel").remove()},request_redraw:function(ak,ac,aj,ad){var ai=this,ag=(ad?[ad]:ai.drawables),ae;var ad;for(var ah=0;ah<ag.length;ah++){ad=ag[ah];ae=-1;for(var af=0;af<ai.tracks_to_be_redrawn.length;af++){if(ai.tracks_to_be_redrawn[af][0]===ad){ae=af;break}}if(ae<0){ai.tracks_to_be_redrawn.push([ad,ac,aj])}else{ai.tracks_to_be_redrawn[ah][1]=ac;ai.tracks_to_be_redrawn[ah][2]=aj}}if(!this.requested_redraw){requestAnimationFrame(function(){ai._redraw(ak)});this.requested_redraw=true}},_redraw:function(am){this.requested_redraw=false;var aj=this.low,af=this.high;if(aj<this.max_low){aj=this.max_low}if(af>this.max_high){af=this.max_high}var al=this.high-this.low;if(this.high!==0&&al<this.min_separation){af=aj+this.min_separation}this.low=Math.floor(aj);this.high=Math.ceil(af);this.resolution_b_px=(this.high-this.low)/this.viewport_container.width();this.resolution_px_b=this.viewport_container.width()/(this.high-this.low);var ac=(this.low/(this.max_high-this.max_low)*this.overview_viewport.width())||0;var ai=((this.high-this.low)/(this.max_high-this.max_low)*this.overview_viewport.width())||0;var an=13;this.overview_box.css({left:ac,width:Math.max(an,ai)}).show();if(ai<an){this.overview_box.css("left",ac-(an-ai)/2)}if(this.overview_highlight){this.overview_highlight.css({left:ac,width:ai})}this.update_location(this.low,this.high);if(!am){var ae,ad,ak;for(var ag=0,ah=this.tracks_to_be_redrawn.length;ag<ah;ag++){ae=this.tracks_to_be_redrawn[ag][0];ad=this.tracks_to_be_redrawn[ag][1];ak=this.tracks_to_be_redrawn[ag][2];if(ae){ae._draw(ad,ak)}}this.tracks_to_be_redrawn=[];for(ag=0,ah=this.label_tracks.length;ag<ah;ag++){this.label_tracks[ag]._draw()}}},zoom_in:function(ad,ae){if(this.max_high===0||this.high-this.low<this.min_separation){return}var af=this.high-this.low,ag=af/2+this.low,ac=(af/this.zoom_factor)/2;if(ad){ag=ad/this.viewport_container.width()*(this.high-this.low)+this.low}this.low=Math.round(ag-ac);this.high=Math.round(ag+ac);this.changed();this.request_redraw()},zoom_out:function(){if(this.max_high===0){return}var ad=this.high-this.low,ae=ad/2+this.low,ac=(ad*this.zoom_factor)/2;this.low=Math.round(ae-ac);this.high=Math.round(ae+ac);this.changed();this.request_redraw()},resize_window:function(){this.viewport_container.height(this.container.height()-this.top_container.height()-this.bottom_container.height());this.request_redraw()},set_overview:function(ae){if(this.overview_drawable){if(this.overview_drawable.dataset_id===ae.dataset_id){return}this.overview_viewport.find(".track").remove()}var ad=ae.copy({content_div:this.overview_viewport}),ac=this;ad.header_div.hide();ad.is_overview=true;ac.overview_drawable=ad;this.overview_drawable.postdraw_actions=function(){ac.overview_highlight.show().height(ac.overview_drawable.content_div.height());ac.overview_viewport.height(ac.overview_drawable.content_div.height()+ac.overview_box.outerHeight());ac.overview_close.show();ac.resize_window()};ac.overview_drawable.request_draw();this.changed()},reset_overview:function(){$(".tipsy").remove();this.overview_viewport.find(".track-tile").remove();this.overview_viewport.height(this.default_overview_height);this.overview_box.height(this.default_overview_height);this.overview_close.hide();this.overview_highlight.hide();view.resize_window();view.overview_drawable=null}});var r=function(ae,aj,af){this.track=ae;this.name=aj.name;this.params=[];var aq=aj.params;for(var ag=0;ag<aq.length;ag++){var al=aq[ag],ad=al.name,ap=al.label,ah=unescape(al.html),ar=al.value,an=al.type;if(an==="number"){this.params.push(new f(ad,ap,ah,(ad in af?af[ad]:ar),al.min,al.max))}else{if(an==="select"){this.params.push(new L(ad,ap,ah,(ad in af?af[ad]:ar)))}else{console.log("WARNING: unrecognized tool parameter type:",ad,an)}}}this.parent_div=$("<div/>").addClass("dynamic-tool").hide();this.parent_div.bind("drag",function(au){au.stopPropagation()}).click(function(au){au.stopPropagation()}).bind("dblclick",function(au){au.stopPropagation()});var ao=$("<div class='tool-name'>").appendTo(this.parent_div).text(this.name);var am=this.params;var ak=this;$.each(this.params,function(av,ay){var ax=$("<div>").addClass("param-row").appendTo(ak.parent_div);var au=$("<div>").addClass("param-label").text(ay.label).appendTo(ax);var aw=$("<div/>").addClass("param-input").html(ay.html).appendTo(ax);aw.find(":input").val(ay.value);$("<div style='clear: both;'/>").appendTo(ax)});this.parent_div.find("input").click(function(){$(this).select()});var at=$("<div>").addClass("param-row").appendTo(this.parent_div);var ai=$("<input type='submit'>").attr("value","Run on complete dataset").appendTo(at);var ac=$("<input type='submit'>").attr("value","Run on visible region").css("margin-left","3em").appendTo(at);var ak=this;ac.click(function(){ak.run_on_region()});ai.click(function(){ak.run_on_dataset()});if("visible" in af&&af.visible){this.parent_div.show()}};p(r.prototype,{update_params:function(){for(var ac=0;ac<this.params.length;ac++){this.params[ac].update_value()}},state_dict:function(){var ad={};for(var ac=0;ac<this.params.length;ac++){ad[this.params[ac].name]=this.params[ac].value}ad.visible=this.parent_div.is(":visible");return ad},get_param_values_dict:function(){var ac={};this.parent_div.find(":input").each(function(){var ad=$(this).attr("name"),ae=$(this).val();ac[ad]=JSON.stringify(ae)});return ac},get_param_values:function(){var ad=[];var ac={};this.parent_div.find(":input").each(function(){var ae=$(this).attr("name"),af=$(this).val();if(ae){ad[ad.length]=af}});return ad},run_on_dataset:function(){var ac=this;ac.run({dataset_id:this.track.original_dataset_id,tool_id:ac.name},null,function(ad){show_modal(ac.name+" is Running",ac.name+" is running on the complete dataset. Tool outputs are in dataset's history.",{Close:hide_modal})})},run_on_region:function(){var ad={dataset_id:this.track.original_dataset_id,chrom:this.track.view.chrom,low:this.track.view.low,high:this.track.view.high,tool_id:this.name},ah=this.track,ae=ad.tool_id+ah.tool_region_and_parameters_str(ad.chrom,ad.low,ad.high),ac;if(ah.container===view){var ag=new N(view,view,{name:this.name});var af=ah.container.replace_drawable(ah,ag,false);ag.container_div.insertBefore(ah.view.content_div.children()[af]);ag.add_drawable(ah);ah.container_div.appendTo(ag.content_div);ac=ag}else{ac=ah.container}var ai=new ah.constructor(view,ac,{name:ae,hda_ldda:"hda"});ai.init_for_tool_data();ai.change_mode(ah.mode);ai.set_filters_manager(ah.filters_manager.copy(ai));ai.update_icons();ac.add_drawable(ai);ai.tiles_div.text("Starting job.");this.update_params();this.run(ad,ai,function(aj){ai.dataset_id=aj.dataset_id;ai.tiles_div.text("Running job.");ai.init()})},run:function(ad,ae,af){$.extend(ad,this.get_param_values_dict());var ac=function(){$.getJSON(rerun_tool_url,ad,function(ag){if(ag==="no converter"){ae.container_div.addClass("error");ae.content_div.text(H)}else{if(ag.error){ae.container_div.addClass("error");ae.content_div.text(v+ag.message)}else{if(ag==="pending"){ae.container_div.addClass("pending");ae.content_div.text("Converting input data so that it can be used quickly with tool.");setTimeout(ac,2000)}else{af(ag)}}}})};ac()}});var L=function(ad,ac,ae,af){this.name=ad;this.label=ac;this.html=$(ae);this.value=af};p(L.prototype,{update_value:function(){this.value=$(this.html).val()}});var f=function(ae,ad,ag,ah,af,ac){L.call(this,ae,ad,ag,ah);this.min=af;this.max=ac};p(f.prototype,L.prototype,{update_value:function(){L.prototype.update_value.call(this);this.value=parseFloat(this.value)}});var g=function(ac){this.manager=null;this.name=ac.name;this.index=ac.index;this.tool_id=ac.tool_id;this.tool_exp_name=ac.tool_exp_name};p(g.prototype,{to_dict:function(){return{name:this.name,index:this.index,tool_id:this.tool_id,tool_exp_name:this.tool_exp_name}}});var S=function(al){g.call(this,al);this.low=("low" in al?al.low:-Number.MAX_VALUE);this.high=("high" in al?al.high:Number.MAX_VALUE);this.min=("min" in al?al.min:Number.MAX_VALUE);this.max=("max" in al?al.max:-Number.MAX_VALUE);this.container=null;this.slider=null;this.slider_label=null;var ah=function(am,an,ao){am.click(function(){var au=an.text(),ar=parseFloat(ao.slider("option","max")),aq=(ar<=1?4:ar<=1000000?ar.toString().length:6),at=false,ap=$(this).parents(".slider-row");ap.addClass("input");if(ao.slider("option","values")){aq=2*aq+1;at=true}an.text("");$("<input type='text'/>").attr("size",aq).attr("maxlength",aq).attr("value",au).appendTo(an).focus().select().click(function(av){av.stopPropagation()}).blur(function(){$(this).remove();an.text(au);ap.removeClass("input")}).keyup(function(az){if(az.keyCode===27){$(this).trigger("blur")}else{if(az.keyCode===13){var ax=ao.slider("option","min"),av=ao.slider("option","max"),ay=function(aA){return(isNaN(aA)||aA>av||aA<ax)},aw=$(this).val();if(!at){aw=parseFloat(aw);if(ay(aw)){alert("Parameter value must be in the range ["+ax+"-"+av+"]");return $(this)}}else{aw=aw.split("-");aw=[parseFloat(aw[0]),parseFloat(aw[1])];if(ay(aw[0])||ay(aw[1])){alert("Parameter value must be in the range ["+ax+"-"+av+"]");return $(this)}}ao.slider((at?"values":"value"),aw);ap.removeClass("input")}}})})};var ad=this;ad.parent_div=$("<div/>").addClass("filter-row slider-row");var ac=$("<div/>").addClass("elt-label").appendTo(ad.parent_div),aj=$("<span/>").addClass("slider-name").text(ad.name+" ").appendTo(ac),ae=$("<span/>").text(this.low+"-"+this.high),af=$("<span/>").addClass("slider-value").appendTo(ac).append("[").append(ae).append("]");ad.values_span=ae;var ai=$("<div/>").addClass("slider").appendTo(ad.parent_div);ad.control_element=$("<div/>").attr("id",ad.name+"-filter-control").appendTo(ai);var ag=[0,0];ad.control_element.slider({range:true,min:this.min,max:this.max,step:this.get_slider_step(this.min,this.max),values:[this.low,this.high],slide:function(am,an){ad.slide(am,an)},change:function(am,an){ad.control_element.slider("option","slide").call(ad.control_element,am,an)}});ad.slider=ad.control_element;ad.slider_label=ae;ah(af,ae,ad.control_element);var ak=$("<div/>").addClass("display-controls").appendTo(ad.parent_div);this.transparency_icon=create_action_icon("Use filter for data transparency","layer-transparent",function(){if(ad.manager.alpha_filter!==ad){ad.manager.alpha_filter=ad;ad.manager.parent_div.find(".layer-transparent").removeClass("active").hide();ad.transparency_icon.addClass("active").show()}else{ad.manager.alpha_filter=null;ad.transparency_icon.removeClass("active")}ad.manager.track.request_draw(true,true)}).appendTo(ak).hide();this.height_icon=create_action_icon("Use filter for data height","arrow-resize-090",function(){if(ad.manager.height_filter!==ad){ad.manager.height_filter=ad;ad.manager.parent_div.find(".arrow-resize-090").removeClass("active").hide();ad.height_icon.addClass("active").show()}else{ad.manager.height_filter=null;ad.height_icon.removeClass("active")}ad.manager.track.request_draw(true,true)}).appendTo(ak).hide();ad.parent_div.hover(function(){ad.transparency_icon.show();ad.height_icon.show()},function(){if(ad.manager.alpha_filter!==ad){ad.transparency_icon.hide()}if(ad.manager.height_filter!==ad){ad.height_icon.hide()}});$("<div style='clear: both;'/>").appendTo(ad.parent_div)};p(S.prototype,{to_dict:function(){var ac=g.prototype.to_dict.call(this);return p(ac,{type:"number",min:this.min,max:this.max,low:this.low,high:this.high})},copy:function(){return new S({name:this.name,index:this.index,tool_id:this.tool_id,tool_exp_name:this.tool_exp_name})},get_slider_step:function(ae,ac){var ad=ac-ae;return(ad<=2?0.01:1)},slide:function(ad,ae){var ac=ae.values;this.values_span.text(ac[0]+"-"+ac[1]);this.low=ac[0];this.high=ac[1];this.manager.track.request_draw(true,true)},applies_to:function(ac){if(ac.length>this.index){return true}return false},_keep_val:function(ac){return(isNaN(ac)||(ac>=this.low&&ac<=this.high))},keep:function(ad){if(!this.applies_to(ad)){return true}var af=this;var ag=ad[this.index];if(ag instanceof Array){var ae=true;for(var ac=0;ac<ag.length;ac++){if(!this._keep_val(ag[ac])){ae=false;break}}return ae}else{return this._keep_val(ad[this.index])}},update_attrs:function(af){var ac=false;if(!this.applies_to(af)){return ac}var ad=af[this.index];if(!(ad instanceof Array)){ad=[ad]}for(var ae=0;ae<ad.length;ae++){var ag=ad[ae];if(ag<this.min){this.min=Math.floor(ag);ac=true}if(ag>this.max){this.max=Math.ceil(ag);ac=true}}return ac},update_ui_elt:function(){if(this.min!==this.max){this.parent_div.show()}else{this.parent_div.hide()}var ad=this.slider.slider("option","min"),ac=this.slider.slider("option","max");if(this.min<ad||this.max>ac){this.slider.slider("option","min",this.min);this.slider.slider("option","max",this.max);this.slider.slider("option","step",this.get_slider_step(this.min,this.max));this.slider.slider("option","values",[this.min,this.max])}}});var X=function(ae,ak){this.track=ae;this.alpha_filter=null;this.height_filter=null;this.filters=[];this.parent_div=$("<div/>").addClass("filters").hide();this.parent_div.bind("drag",function(am){am.stopPropagation()}).click(function(am){am.stopPropagation()}).bind("dblclick",function(am){am.stopPropagation()}).bind("keydown",function(am){am.stopPropagation()});if(ak&&"filters" in ak){var ac=("alpha_filter" in ak?ak.alpha_filter:null),af=("height_filter" in ak?ak.height_filter:null),ah=ak.filters,ad;for(var ai=0;ai<ah.length;ai++){if(ah[ai].type==="number"){ad=new S(ah[ai]);this.add_filter(ad);if(ad.name===ac){this.alpha_filter=ad;ad.transparency_icon.addClass("active").show()}if(ad.name===af){this.height_filter=ad;ad.height_icon.addClass("active").show()}}else{console.log("ERROR: unsupported filter: ",name,type)}}if("visible" in ak&&ak.visible){this.parent_div.show()}}if(this.filters.length!==0){var al=$("<div/>").addClass("param-row").appendTo(this.parent_div);var aj=$("<input type='submit'/>").attr("value","Run on complete dataset").appendTo(al);var ag=this;aj.click(function(){ag.run_on_dataset()})}};p(X.prototype,{show:function(){this.parent_div.show()},hide:function(){this.parent_div.hide()},toggle:function(){this.parent_div.toggle()},visible:function(){return this.parent_div.is(":visible")},to_dict:function(){var af={},ae=[],ad;for(var ac=0;ac<this.filters.length;ac++){ad=this.filters[ac];ae.push(ad.to_dict())}af.filters=ae;af.alpha_filter=(this.alpha_filter?this.alpha_filter.name:null);af.height_filter=(this.height_filter?this.height_filter.name:null);af.visible=this.parent_div.is(":visible");return af},copy:function(ad){var ae=new X(ad);for(var ac=0;ac<this.filters.length;ac++){ae.add_filter(this.filters[ac].copy())}return ae},add_filter:function(ac){ac.manager=this;this.parent_div.append(ac.parent_div);this.filters.push(ac)},remove_all:function(){this.filters=[];this.parent_div.children().remove()},init_filters:function(){for(var ac=0;ac<this.filters.length;ac++){var ad=this.filters[ac];ad.update_ui_elt()}},clear_filters:function(){for(var ac=0;ac<this.filters.length;ac++){var ad=this.filters[ac];ad.slider.slider("option","values",[ad.min,ad.max])}this.alpha_filter=null;this.height_filter=null;this.parent_div.find(".icon-button").hide()},run_on_dataset:function(){var ak=function(ao,am,an){if(!(am in ao)){ao[am]=an}return ao[am]};var ae={},ac,ad,af;for(var ag=0;ag<this.filters.length;ag++){ac=this.filters[ag];if(ac.tool_id){if(ac.min!==ac.low){ad=ak(ae,ac.tool_id,[]);ad[ad.length]=ac.tool_exp_name+" >= "+ac.low}if(ac.max!==ac.high){ad=ak(ae,ac.tool_id,[]);ad[ad.length]=ac.tool_exp_name+" <= "+ac.high}}}var ai=[];for(var al in ae){ai[ai.length]=[al,ae[al]]}var aj=ai.length;(function ah(at,ap){var an=ap[0],ao=an[0],ar=an[1],aq="("+ar.join(") and (")+")",am={cond:aq,input:at,target_dataset_id:at,tool_id:ao},ap=ap.slice(1);$.getJSON(run_tool_url,am,function(au){if(au.error){show_modal("Filter Dataset","Error running tool "+ao,{Close:hide_modal})}else{if(ap.length===0){show_modal("Filtering Dataset","Filter(s) are running on the complete dataset. Outputs are in dataset's history.",{Close:hide_modal})}else{ah(au.dataset_id,ap)}}})})(this.track.dataset_id,ai)}});var z=function(ac,ad){J.Scaler.call(this,ad);this.filter=ac};z.prototype.gen_val=function(ac){if(this.filter.high===Number.MAX_VALUE||this.filter.low===-Number.MAX_VALUE||this.filter.low===this.filter.high){return this.default_val}return((parseFloat(ac[this.filter.index])-this.filter.low)/(this.filter.high-this.filter.low))};var C=function(ac){this.track=ac.track;this.params=ac.params;this.values={};this.restore_values((ac.saved_values?ac.saved_values:{}));this.onchange=ac.onchange};p(C.prototype,{restore_values:function(ac){var ad=this;$.each(this.params,function(ae,af){if(ac[af.key]!==undefined){ad.values[af.key]=ac[af.key]}else{ad.values[af.key]=af.default_value}})},build_form:function(){var af=this;var ac=$("<div />");var ae;function ad(aj,ag){for(var an=0;an<aj.length;an++){ae=aj[an];if(ae.hidden){continue}var ah="param_"+an;var ar=af.values[ae.key];var av=$("<div class='form-row' />").appendTo(ag);av.append($("<label />").attr("for",ah).text(ae.label+":"));if(ae.type==="bool"){av.append($('<input type="checkbox" />').attr("id",ah).attr("name",ah).attr("checked",ar))}else{if(ae.type==="text"){av.append($('<input type="text"/>').attr("id",ah).val(ar).click(function(){$(this).select()}))}else{if(ae.type==="select"){var ap=$("<select />").attr("id",ah);for(var al=0;al<ae.options.length;al++){$("<option/>").text(ae.options[al].label).attr("value",ae.options[al].value).appendTo(ap)}ap.val(ar);av.append(ap)}else{if(ae.type==="color"){var au=$("<div/>").appendTo(av),ao=$("<input />").attr("id",ah).attr("name",ah).val(ar).css("float","left").appendTo(au).click(function(ax){$(".tipsy").hide();var aw=$(this).siblings(".tipsy");aw.css({left:$(this).position().left+$(this).width()+5,top:$(this).position().top-($(aw).height()/2)+($(this).height()/2)}).show();aw.click(function(ay){ay.stopPropagation()});$(document).bind("click.color-picker",function(){aw.hide();$(document).unbind("click.color-picker")});ax.stopPropagation()}),am=$("<a href='javascript:void(0)'/>").addClass("icon-button arrow-circle").appendTo(au).attr("title","Set new random color").tipsy({gravity:"s"}),aq=$("<div class='tipsy tipsy-west' style='position: absolute;' />").appendTo(au).hide(),ai=$("<div style='background-color: black; padding: 10px;'></div>").appendTo(aq),at=$("<div/>").appendTo(ai),ak=$.farbtastic(at,{width:100,height:100,callback:ao,color:ar});au.append($("<div/>").css("clear","both"));(function(aw){am.click(function(){aw.setColor(get_random_color())})})(ak)}else{av.append($("<input />").attr("id",ah).attr("name",ah).val(ar))}}}}if(ae.help){av.append($("<div class='help'/>").text(ae.help))}}}ad(this.params,ac);return ac},update_from_form:function(ac){var ae=this;var ad=false;$.each(this.params,function(af,ah){if(!ah.hidden){var ai="param_"+af;var ag=ac.find("#"+ai).val();if(ah.type==="float"){ag=parseFloat(ag)}else{if(ah.type==="int"){ag=parseInt(ag)}else{if(ah.type==="bool"){ag=ac.find("#"+ai).is(":checked")}}}if(ag!==ae.values[ah.key]){ae.values[ah.key]=ag;ad=true}}});if(ad){this.onchange();this.track.changed()}}});var b=function(ac,af,ae,ad,ag){this.track=ac;this.index=af;var ah=this.track._get_tile_bounds(af,ae);this.low=ah[0];this.high=ah[1];this.resolution=ae;this.html_elt=$("<div class='track-tile'/>").append(ad);this.data=ag;this.stale=false};b.prototype.predisplay_actions=function(){};var k=function(ac,af,ae,ad,ag,ah){b.call(this,ac,af,ae,ad,ag);this.max_val=ah};p(k.prototype,b.prototype);var M=function(af,ak,ag,ae,ai,ao,aj,ap,ad,am){b.call(this,af,ak,ag,ae,ai);this.mode=aj;this.all_slotted=ad;this.feature_mapper=am;this.has_icons=false;if(ap){this.has_icons=true;var al=this;ae=this.html_elt.children()[0],message_div=$("<div/>").addClass("tile-message").css({height:A-1,width:ae.width}).prependTo(this.html_elt);var an=ai.length,ah=$("<a href='javascript:void(0);'/>").addClass("icon more-down").attr("title","For speed, only the first "+an+" features in this region were obtained from server. Click to get more data including depth").tipsy({gravity:"s"}).appendTo(message_div),ac=$("<a href='javascript:void(0);'/>").addClass("icon more-across").attr("title","For speed, only the first "+an+" features in this region were obtained from server. Click to get more data excluding depth").tipsy({gravity:"s"}).appendTo(message_div);ah.click(function(){al.stale=true;af.data_manager.get_more_data(al.low,al.high,af.mode,al.resolution,{},af.data_manager.DEEP_DATA_REQ);$(".tipsy").hide();af.request_draw()}).dblclick(function(aq){aq.stopPropagation()});ac.click(function(){al.stale=true;af.data_manager.get_more_data(al.low,al.high,af.mode,al.resolution,{},af.data_manager.BROAD_DATA_REQ);$(".tipsy").hide();af.request_draw()}).dblclick(function(aq){aq.stopPropagation()})}};p(M.prototype,b.prototype);M.prototype.predisplay_actions=function(){var ad=this,ac={};if(ad.mode!=="Pack"){return}$(this.html_elt).hover(function(){this.hovered=true;$(this).mousemove()},function(){this.hovered=false;$(this).parents(".track-content").children(".overlay").children(".feature-popup").remove()}).mousemove(function(ao){if(!this.hovered){return}var aj=$(this).offset(),an=ao.pageX-aj.left,am=ao.pageY-aj.top,at=ad.feature_mapper.get_feature_data(an,am),ak=(at?at[0]:null);$(this).parents(".track-content").children(".overlay").children(".feature-popup").each(function(){if(!ak||$(this).attr("id")!==ak.toString()){$(this).remove()}});if(at){var af=ac[ak];if(!af){var ak=at[0],ap={name:at[3],start:at[1],end:at[2],strand:at[4]},ai=ad.track.filters_manager.filters,ah;for(var al=0;al<ai.length;al++){ah=ai[al];ap[ah.name]=at[ah.index]}var af=$("<div/>").attr("id",ak).addClass("feature-popup"),au=$("<table/>"),ar,aq,av;for(ar in ap){aq=ap[ar];av=$("<tr/>").appendTo(au);$("<th/>").appendTo(av).text(ar);$("<td/>").attr("align","left").appendTo(av).text(typeof(aq)==="number"?W(aq,2):aq)}af.append($("<div class='feature-popup-inner'>").append(au));ac[ak]=af}af.appendTo($(this).parents(".track-content").children(".overlay"));var ag=an+parseInt(ad.html_elt.css("left"))-af.width()/2,ae=am+parseInt(ad.html_elt.css("top"))+7;af.css("left",ag+"px").css("top",ae+"px")}else{if(!ao.isPropagationStopped()){ao.stopPropagation();$(this).siblings().each(function(){$(this).trigger(ao)})}}}).mouseleave(function(){$(this).parents(".track-content").children(".overlay").children(".feature-popup").remove()})};var i=function(ad,ac,ae){p(ae,{drag_handle_class:"draghandle"});q.call(this,ad,ac,ae);this.data_url=("data_url" in ae?ae.data_url:default_data_url);this.data_url_extra_params={};this.data_query_wait=("data_query_wait" in ae?ae.data_query_wait:I);this.dataset_check_url=converted_datasets_state_url;this.data_manager=("data_manager" in ae?ae.data_manager:new P(F,this));this.min_height_px=16;this.max_height_px=800;this.visible_height_px=0;this.content_div=$("<div class='track-content'>").appendTo(this.container_div);if(this.container){this.container.content_div.append(this.container_div);if(!("resize" in ae)||ae.resize){this.add_resize_handle()}}};p(i.prototype,q.prototype,{action_icons_def:[{name:"mode_icon",title:"Set display mode",css_class:"chevron-expand",on_click_fn:function(){}},q.prototype.action_icons_def[0],{name:"overview_icon",title:"Set as overview",css_class:"overview-icon",on_click_fn:function(ac){ac.view.set_overview(ac)}},q.prototype.action_icons_def[1],{name:"filters_icon",title:"Filters",css_class:"filters-icon",on_click_fn:function(ac){if(ac.filters_manager.visible()){ac.filters_manager.clear_filters()}else{ac.filters_manager.init_filters()}ac.filters_manager.toggle()}},{name:"tools_icon",title:"Tool",css_class:"hammer",on_click_fn:function(ac){ac.dynamic_tool_div.toggle();if(ac.dynamic_tool_div.is(":visible")){ac.set_name(ac.name+ac.tool_region_and_parameters_str())}else{ac.revert_name()}$(".tipsy").remove()}},q.prototype.action_icons_def[2]],can_draw:function(){if(this.dataset_id&&q.prototype.can_draw.call(this)){return true}return false},build_container_div:function(){return $("<div/>").addClass("track").attr("id","track_"+this.id).css("position","relative")},build_header_div:function(){var ac=$("<div class='track-header'/>");if(this.view.editor){this.drag_div=$("<div/>").addClass(this.drag_handle_class).appendTo(ac)}this.name_div=$("<div/>").addClass("track-name").appendTo(ac).text(this.name).attr("id",this.name.replace(/\s+/g,"-").replace(/[^a-zA-Z0-9\-]/g,"").toLowerCase());return ac},on_resize:function(){},add_resize_handle:function(){var ac=this;var af=false;var ae=false;var ad=$("<div class='track-resize'>");$(ac.container_div).hover(function(){if(ac.content_visible){af=true;ad.show()}},function(){af=false;if(!ae){ad.hide()}});ad.hide().bind("dragstart",function(ag,ah){ae=true;ah.original_height=$(ac.content_div).height()}).bind("drag",function(ah,ai){var ag=Math.min(Math.max(ai.original_height+ai.deltaY,ac.min_height_px),ac.max_height_px);$(ac.tiles_div).css("height",ag);ac.visible_height_px=(ac.max_height_px===ag?0:ag);ac.on_resize()}).bind("dragend",function(ag,ah){ac.tile_cache.clear();ae=false;if(!af){ad.hide()}ac.config.values.height=ac.visible_height_px;ac.changed()}).appendTo(ac.container_div)},set_display_modes:function(af,ai){this.display_modes=af;this.mode=(ai?ai:(this.config&&this.config.values.mode?this.config.values.mode:this.display_modes[0]));this.action_icons.mode_icon.attr("title","Set display mode (now: "+this.mode+")");var ad=this,ag={};for(var ae=0,ac=ad.display_modes.length;ae<ac;ae++){var ah=ad.display_modes[ae];ag[ah]=function(aj){return function(){ad.change_mode(aj);ad.icons_div.show();ad.container_div.mouseleave(function(){ad.icons_div.hide()})}}(ah)}make_popupmenu(this.action_icons.mode_icon,ag)},build_action_icons:function(){q.prototype.build_action_icons.call(this,this.action_icons_def);if(this.display_modes!==undefined){this.set_display_modes(this.display_modes)}},hide_contents:function(){this.tiles_div.hide();this.container_div.find(".yaxislabel, .track-resize").hide()},show_contents:function(){this.tiles_div.show();this.container_div.find(".yaxislabel, .track-resize").show();this.request_draw()},get_type:function(){if(this instanceof Y){return"LabelTrack"}else{if(this instanceof y){return"ReferenceTrack"}else{if(this instanceof j){return"LineTrack"}else{if(this instanceof T){return"ReadTrack"}else{if(this instanceof Q){return"VcfTrack"}else{if(this instanceof h){return"CompositeTrack"}else{if(this instanceof d){return"FeatureTrack"}}}}}}}return""},init:function(){var ad=this;ad.enabled=false;ad.tile_cache.clear();ad.data_manager.clear();ad.content_div.css("height","auto");ad.tiles_div.children().remove();ad.container_div.removeClass("nodata error pending");if(!ad.dataset_id){return}var ac=$.Deferred();$.getJSON(converted_datasets_state_url,{hda_ldda:ad.hda_ldda,dataset_id:ad.dataset_id,chrom:ad.view.chrom},function(ae){if(!ae||ae==="error"||ae.kind==="error"){ad.container_div.addClass("error");ad.tiles_div.text(o);if(ae.message){var af=$(" <a href='javascript:void(0);'></a>").text("View error").click(function(){show_modal("Trackster Error","<pre>"+ae.message+"</pre>",{Close:hide_modal})});ad.tiles_div.append(af)}}else{if(ae==="no converter"){ad.container_div.addClass("error");ad.tiles_div.text(H)}else{if(ae==="no data"||(ae.data!==undefined&&(ae.data===null||ae.data.length===0))){ad.container_div.addClass("nodata");ad.tiles_div.text(B)}else{if(ae==="pending"){ad.container_div.addClass("pending");ad.tiles_div.html(t);setTimeout(function(){ad.init()},ad.data_query_wait)}else{if(ae.status==="data"){if(ae.valid_chroms){ad.valid_chroms=ae.valid_chroms;ad.update_icons()}ad.tiles_div.text(V);if(ad.view.chrom){ad.tiles_div.text("");ad.tiles_div.css("height",ad.visible_height_px+"px");ad.enabled=true;$.when(ad.predraw_init()).done(function(){ac.resolve();ad.container_div.removeClass("nodata error pending");ad.request_draw()})}else{ac.resolve()}}}}}}});this.update_icons();return ac},predraw_init:function(){}});var K=function(ae,ad,af){i.call(this,ae,ad,af);var ac=this,ae=ac.view;m(ac.container_div,ac.drag_handle_class,".group",ac);this.filters_manager=new X(this,("filters" in af?af.filters:null));this.filters_available=false;this.tool=("tool" in af&&af.tool?new r(this,af.tool,af.tool_state):null);this.tile_cache=new c(O);if(this.header_div){this.set_filters_manager(this.filters_manager);if(this.tool){this.dynamic_tool_div=this.tool.parent_div;this.header_div.after(this.dynamic_tool_div)}}this.tiles_div=$("<div/>").addClass("tiles").appendTo(this.content_div);this.overlay_div=$("<div/>").addClass("overlay").appendTo(this.content_div);if(af.mode){this.change_mode(af.mode)}};p(K.prototype,q.prototype,i.prototype,{action_icons_def:i.prototype.action_icons_def.concat([{name:"show_more_rows_icon",title:"To minimize track height, not all feature rows are displayed. Click to display more rows.",css_class:"exclamation",on_click_fn:function(ac){$(".tipsy").remove();ac.slotters[ac.view.resolution_px_b].max_rows*=2;ac.request_draw(true)},hide:true}]),copy:function(ac){var ad=this.to_dict();p(ad,{data_manager:this.data_manager});var ae=new this.constructor(this.view,ac,ad);ae.change_mode(this.mode);ae.enabled=this.enabled;return ae},set_filters_manager:function(ac){this.filters_manager=ac;this.header_div.after(this.filters_manager.parent_div)},to_dict:function(){return{track_type:this.get_type(),name:this.name,hda_ldda:this.hda_ldda,dataset_id:this.dataset_id,prefs:this.prefs,mode:this.mode,filters:this.filters_manager.to_dict(),tool_state:(this.tool?this.tool.state_dict():{})}},change_mode:function(ad){var ac=this;ac.mode=ad;ac.config.values.mode=ad;ac.tile_cache.clear();ac.request_draw();this.action_icons.mode_icon.attr("title","Set display mode (now: "+ac.mode+")");return ac},update_icons:function(){var ac=this;if(ac.filters_available){ac.action_icons.filters_icon.show()}else{ac.action_icons.filters_icon.hide()}if(ac.tool){ac.action_icons.tools_icon.show()}else{ac.action_icons.tools_icon.hide()}},_gen_tile_cache_key:function(ad,ae,ac){return ad+"_"+ae+"_"+ac},request_draw:function(ad,ac){this.view.request_redraw(false,ad,ac,this)},before_draw:function(){},_draw:function(ad,an){if(!this.can_draw()){return}var al=this.view.low,ah=this.view.high,aj=ah-al,ae=this.view.container.width(),ap=this.view.resolution_px_b,ag=this.view.resolution_b_px;if(this.is_overview){al=this.view.max_low;ah=this.view.max_high;ag=Math.pow(RESOLUTION,Math.ceil(Math.log((view.max_high-view.max_low)/R)/Math.log(RESOLUTION)));ap=ae/(view.max_high-view.max_low)}this.before_draw();this.tiles_div.children().addClass("remove");var ac=Math.floor(al/(ag*R)),ak=true,ao=[],ai=function(aq){return(aq&&"track" in aq)};while((ac*R*ag)<ah){var am=this.draw_helper(ad,ae,ac,ag,this.tiles_div,ap);if(ai(am)){ao.push(am)}else{ak=false}ac+=1}if(!an){this.tiles_div.children(".remove").remove()}var af=this;if(ak){this.tiles_div.children(".remove").remove();af.postdraw_actions(ao,ae,ap,an)}},postdraw_actions:function(af,ag,ai,ac){var ae=this;var ah=false;for(var ad=0;ad<af.length;ad++){if(af[ad].has_icons){ah=true;break}}if(ah){for(var ad=0;ad<af.length;ad++){tile=af[ad];if(!tile.has_icons){tile.html_elt.css("padding-top",A)}}}},draw_helper:function(ac,ao,au,ar,ah,ai,ap){var an=this,ax=this._gen_tile_cache_key(ao,ai,au),af=this._get_tile_bounds(au,ar),av=af[0],ad=af[1];if(!ap){ap={}}var aw=(ac?undefined:an.tile_cache.get(ax));if(aw){an.show_tile(aw,ah,ai);return aw}var al=true;var at=an.data_manager.get_data(av,ad,an.mode,ar,an.data_url_extra_params);if(is_deferred(at)){al=false}var aj;if(view.reference_track&&ai>view.canvas_manager.char_width_px){aj=view.reference_track.data_manager.get_data(av,ad,an.mode,ar,view.reference_track.data_url_extra_params);if(is_deferred(aj)){al=false}}if(al){p(at,ap.more_tile_data);var ak=an.mode;if(ak==="Auto"){ak=an.get_mode(at);an.update_auto_mode(ak)}var ae=an.view.canvas_manager.new_canvas(),af=an._get_tile_bounds(au,ar),av=af[0],ad=af[1],ao=Math.ceil((ad-av)*ai)+an.left_offset,am=an.get_canvas_height(at,ak,ai,ao);ae.width=ao;ae.height=am;var aq=ae.getContext("2d");aq.translate(this.left_offset,0);var aw=an.draw_tile(at,aq,ak,ar,au,ai,aj);if(aw!==undefined){an.tile_cache.set(ax,aw);an.show_tile(aw,ah,ai)}return aw}var ag=$.Deferred();$.when(at,aj).then(function(){view.request_redraw(false,false,false,an);ag.resolve()});return ag},get_canvas_height:function(ac,ae,af,ad){return this.visible_height_px},draw_tile:function(ac,ae,ah,ag,ad,ai,af){console.log("Warning: TiledTrack.draw_tile() not implemented.")},show_tile:function(ae,ag,ah){var ad=this,ac=ae.html_elt;ae.predisplay_actions();var af=(ae.low-(this.is_overview?this.view.max_low:this.view.low))*ah;if(this.left_offset){af-=this.left_offset}ac.css({position:"absolute",top:0,left:af,height:""});if(ac.hasClass("remove")){ac.removeClass("remove")}else{ag.append(ac)}ad.after_show_tile(ae)},after_show_tile:function(ac){},_get_tile_bounds:function(ac,ad){var af=Math.floor(ac*R*ad),ag=Math.ceil(R*ad),ae=(af+ag<=this.view.max_high?af+ag:this.view.max_high);return[af,ae]},tool_region_and_parameters_str:function(ae,ac,af){var ad=this,ag=(ae!==undefined&&ac!==undefined&&af!==undefined?ae+":"+ac+"-"+af:"all");return" - region=["+ag+"], parameters=["+ad.tool.get_param_values().join(", ")+"]"},data_and_mode_compatible:function(ac,ad){return true},can_subset:function(ac){return false},init_for_tool_data:function(){this.data_url=raw_data_url;this.data_query_wait=1000;this.dataset_check_url=dataset_state_url;this.predraw_init=function(){var ad=this;var ac=function(){if(ad.data_manager.size()===0){setTimeout(ac,300)}else{ad.data_url=default_data_url;ad.data_query_wait=I;ad.dataset_state_url=converted_datasets_state_url;$.getJSON(ad.dataset_state_url,{dataset_id:ad.dataset_id,hda_ldda:ad.hda_ldda},function(ae){})}};ac()}}});var Y=function(ad,ac){var ae={resize:false};i.call(this,ad,ac,ae);this.container_div.addClass("label-track")};p(Y.prototype,i.prototype,{build_header_div:function(){},init:function(){this.enabled=true},_draw:function(){var ae=this.view,af=ae.high-ae.low,ai=Math.floor(Math.pow(10,Math.floor(Math.log(af)/Math.log(10)))),ac=Math.floor(ae.low/ai)*ai,ag=this.view.container.width(),ad=$("<div style='position: relative; height: 1.3em;'></div>");while(ac<ae.high){var ah=(ac-ae.low)/af*ag;ad.append($("<div class='label'>"+commatize(ac)+"</div>").css({position:"absolute",left:ah-1}));ac+=ai}this.content_div.children(":first").remove();this.content_div.append(ad)}});var h=function(ad,ac,ag){K.call(this,ad,ac,ag);this.drawables=[];this.left_offset=0;if("drawables" in ag){var af;for(var ae=0;ae<ag.drawables.length;ae++){af=ag.drawables[ae];this.drawables[ae]=object_from_template(af);if(af.left_offset>this.left_offset){this.left_offset=af.left_offset}}this.enabled=true}if(this.drawables.length!==0){this.set_display_modes(this.drawables[0].display_modes,this.drawables[0].mode)}this.update_icons();this.obj_type="CompositeTrack"};p(h.prototype,K.prototype,{action_icons_def:[{name:"composite_icon",title:"Show individual tracks",css_class:"layers-stack",on_click_fn:function(ac){$(".tipsy").remove();ac.show_group()}}].concat(K.prototype.action_icons_def),to_dict:w.prototype.to_dict,add_drawable:w.prototype.add_drawable,unpack_drawables:w.prototype.unpack_drawables,change_mode:function(ac){K.prototype.change_mode.call(this,ac);for(var ad=0;ad<this.drawables.length;ad++){this.drawables[ad].change_mode(ac)}},init:function(){var ae=[];for(var ad=0;ad<this.drawables.length;ad++){ae.push(this.drawables[ad].init())}var ac=this;$.when.apply($,ae).then(function(){ac.enabled=true;ac.request_draw()})},update_icons:function(){this.action_icons.filters_icon.hide();this.action_icons.tools_icon.hide()},can_draw:q.prototype.can_draw,draw_helper:function(ad,ar,ay,av,aj,al,at){var aq=this,aC=this._gen_tile_cache_key(ar,al,ay),ah=this._get_tile_bounds(ay,av),az=ah[0],ae=ah[1];if(!at){at={}}var aB=(ad?undefined:aq.tile_cache.get(aC));if(aB){aq.show_tile(aB,aj,al);return aB}var ak=[],aq,ao=true,aw,am;for(var ax=0;ax<this.drawables.length;ax++){aq=this.drawables[ax];aw=aq.data_manager.get_data(az,ae,aq.mode,av,aq.data_url_extra_params);if(is_deferred(aw)){ao=false}ak.push(aw);am=null;if(view.reference_track&&al>view.canvas_manager.char_width_px){am=view.reference_track.data_manager.get_data(az,ae,aq.mode,av,view.reference_track.data_url_extra_params);if(is_deferred(am)){ao=false}}ak.push(am)}if(ao){p(aw,at.more_tile_data);this.tile_predraw_init();var ag=aq.view.canvas_manager.new_canvas(),ah=aq._get_tile_bounds(ay,av),az=ah[0],ae=ah[1],aA=0,ar=Math.ceil((ae-az)*al)+this.left_offset,ap=0,af=[];var ac=0;for(var ax=0;ax<this.drawables.length;ax++,aA+=2){aq=this.drawables[ax];aw=ak[aA];var an=aq.mode;if(an==="Auto"){an=aq.get_mode(aw);aq.update_auto_mode(an)}af.push(an);ac=aq.get_canvas_height(aw,an,al,ar);if(ac>ap){ap=ac}}ag.width=ar;ag.height=(at.height?at.height:ap);aA=0;var au=ag.getContext("2d");au.translate(this.left_offset,0);au.globalAlpha=0.5;au.globalCompositeOperation="source-over";for(var ax=0;ax<this.drawables.length;ax++,aA+=2){aq=this.drawables[ax];aw=ak[aA];am=ak[aA+1];aB=aq.draw_tile(aw,au,af[ax],av,ay,al,am)}this.tile_cache.set(aC,aB);this.show_tile(aB,aj,al);return aB}var ai=$.Deferred(),aq=this;$.when.apply($,ak).then(function(){view.request_redraw(false,false,false,aq);ai.resolve()});return ai},show_group:function(){var af=new N(this.view,this.container,{name:this.name}),ac;for(var ae=0;ae<this.drawables.length;ae++){ac=this.drawables[ae];af.add_drawable(ac);ac.container=af;af.content_div.append(ac.container_div)}var ad=this.container.replace_drawable(this,af,true);af.request_draw()},tile_predraw_init:function(){var af=Number.MAX_VALUE,ac=-af,ad;for(var ae=0;ae<this.drawables.length;ae++){ad=this.drawables[ae];if(ad instanceof j){if(ad.prefs.min_value<af){af=ad.prefs.min_value}if(ad.prefs.max_value>ac){ac=ad.prefs.max_value}}}for(var ae=0;ae<this.drawables.length;ae++){ad=this.drawables[ae];ad.prefs.min_value=af;ad.prefs.max_value=ac}},postdraw_actions:function(ae,ah,aj,ad){K.prototype.postdraw_actions.call(this,ae,ah,aj,ad);var ag=-1;for(var af=0;af<ae.length;af++){var ac=ae[af].html_elt.find("canvas").height();if(ac>ag){ag=ac}}for(var af=0;af<ae.length;af++){var ai=ae[af];if(ai.html_elt.find("canvas").height()!==ag){this.draw_helper(true,ah,ai.index,ai.resolution,ai.html_elt.parent(),aj,{height:ag});ai.html_elt.remove()}}}});var y=function(ac){K.call(this,ac,{content_div:ac.top_labeltrack,resize:false},{});ac.reference_track=this;this.left_offset=200;this.visible_height_px=12;this.container_div.addClass("reference-track");this.content_div.css("background","none");this.content_div.css("min-height","0px");this.content_div.css("border","none");this.data_url=reference_url;this.data_url_extra_params={dbkey:ac.dbkey};this.data_manager=new E(F,this,false);this.hide_contents()};p(y.prototype,q.prototype,K.prototype,{build_header_div:function(){},init:function(){this.data_manager.clear();this.enabled=true},can_draw:q.prototype.can_draw,draw_tile:function(ak,al,ah,ag,ad,am){var af=this;if(am>this.view.canvas_manager.char_width_px){if(ak.data===null){this.hide_contents();return}var ae=al.canvas;al.font=al.canvas.manager.default_font;al.textAlign="center";ak=ak.data;for(var ai=0,aj=ak.length;ai<aj;ai++){var ac=Math.floor(ai*am);al.fillText(ak[ai],ac,10)}this.show_contents();return new b(af,ad,ag,ae,ak)}this.hide_contents()}});var j=function(ae,ad,af){var ac=this;this.display_modes=["Histogram","Line","Filled","Intensity"];this.mode="Histogram";K.call(this,ae,ad,af);this.hda_ldda=af.hda_ldda;this.dataset_id=af.dataset_id;this.original_dataset_id=this.dataset_id;this.left_offset=0;this.config=new C({track:this,params:[{key:"name",label:"Name",type:"text",default_value:this.name},{key:"color",label:"Color",type:"color",default_value:get_random_color()},{key:"min_value",label:"Min Value",type:"float",default_value:undefined},{key:"max_value",label:"Max Value",type:"float",default_value:undefined},{key:"mode",type:"string",default_value:this.mode,hidden:true},{key:"height",type:"int",default_value:32,hidden:true}],saved_values:af.prefs,onchange:function(){ac.set_name(ac.prefs.name);ac.vertical_range=ac.prefs.max_value-ac.prefs.min_value;ac.set_min_value(ac.prefs.min_value);ac.set_max_value(ac.prefs.max_value)}});this.prefs=this.config.values;this.visible_height_px=this.config.values.height;this.vertical_range=this.config.values.max_value-this.config.values.min_value};p(j.prototype,q.prototype,K.prototype,{on_resize:function(){this.request_draw(true)},set_min_value:function(ac){this.prefs.min_value=ac;$("#linetrack_"+this.dataset_id+"_minval").text(this.prefs.min_value);this.tile_cache.clear();this.request_draw()},set_max_value:function(ac){this.prefs.max_value=ac;$("#linetrack_"+this.dataset_id+"_maxval").text(this.prefs.max_value);this.tile_cache.clear();this.request_draw()},predraw_init:function(){var ac=this;ac.vertical_range=undefined;return $.getJSON(ac.data_url,{stats:true,chrom:ac.view.chrom,low:null,high:null,hda_ldda:ac.hda_ldda,dataset_id:ac.dataset_id},function(ad){ac.container_div.addClass("line-track");var ag=ad.data;if(isNaN(parseFloat(ac.prefs.min_value))||isNaN(parseFloat(ac.prefs.max_value))){var ae=ag.min;var ai=ag.max;ae=Math.floor(Math.min(0,Math.max(ae,ag.mean-2*ag.sd)));ai=Math.ceil(Math.max(0,Math.min(ai,ag.mean+2*ag.sd)));ac.prefs.min_value=ae;ac.prefs.max_value=ai;$("#track_"+ac.dataset_id+"_minval").val(ac.prefs.min_value);$("#track_"+ac.dataset_id+"_maxval").val(ac.prefs.max_value)}ac.vertical_range=ac.prefs.max_value-ac.prefs.min_value;ac.total_frequency=ag.total_frequency;ac.container_div.find(".yaxislabel").remove();var ah=$("<div/>").text(W(ac.prefs.min_value,3)).make_text_editable({num_cols:6,on_finish:function(aj){$(".tipsy").remove();var aj=parseFloat(aj);if(!isNaN(aj)){ac.set_min_value(aj)}},help_text:"Set min value"}).addClass("yaxislabel bottom").attr("id","linetrack_"+ac.dataset_id+"_minval").prependTo(ac.container_div),af=$("<div/>").text(W(ac.prefs.max_value,3)).make_text_editable({num_cols:6,on_finish:function(aj){$(".tipsy").remove();var aj=parseFloat(aj);if(!isNaN(aj)){ac.set_max_value(aj)}},help_text:"Set max value"}).addClass("yaxislabel top").attr("id","linetrack_"+ac.dataset_id+"_maxval").prependTo(ac.container_div)})},draw_tile:function(am,ak,ah,af,ad,al){var ae=ak.canvas,ac=this._get_tile_bounds(ad,af),ag=ac[0],aj=ac[1],ai=new J.LinePainter(am.data,ag,aj,this.prefs,ah);ai.draw(ak,ae.width,ae.height,al);return new b(this,ad,af,ae,am.data)},can_subset:function(ac){return false},});var d=function(ae,ad,af){var ac=this;this.display_modes=["Auto","Histogram","Dense","Squish","Pack"];K.call(this,ae,ad,af);this.config=new C({track:this,params:[{key:"name",label:"Name",type:"text",default_value:this.name},{key:"block_color",label:"Block color",type:"color",default_value:get_random_color()},{key:"label_color",label:"Label color",type:"color",default_value:"black"},{key:"show_counts",label:"Show summary counts",type:"bool",default_value:true,help:"Show the number of items in each bin when drawing summary histogram"},{key:"histogram_max",label:"Histogram maximum",type:"float",default_value:null,help:"clear value to set automatically"},{key:"connector_style",label:"Connector style",type:"select",default_value:"fishbones",options:[{label:"Line with arrows",value:"fishbone"},{label:"Arcs",value:"arcs"}]},{key:"mode",type:"string",default_value:this.mode,hidden:true},{key:"height",type:"int",default_value:this.visible_height_px,hidden:true}],saved_values:af.prefs,onchange:function(){ac.set_name(ac.prefs.name);ac.tile_cache.clear();ac.set_painter_from_config();ac.request_draw()}});this.prefs=this.config.values;this.visible_height_px=this.config.values.height;this.container_div.addClass("feature-track");this.hda_ldda=af.hda_ldda;this.dataset_id=af.dataset_id;this.original_dataset_id=af.dataset_id;this.show_labels_scale=0.001;this.showing_details=false;this.summary_draw_height=30;this.slotters={};this.start_end_dct={};this.left_offset=200;this.set_painter_from_config()};p(d.prototype,q.prototype,K.prototype,{set_painter_from_config:function(){if(this.config.values.connector_style==="arcs"){this.painter=J.ArcLinkedFeaturePainter}else{this.painter=J.LinkedFeaturePainter}},before_draw:function(){this.max_height_px=0},after_show_tile:function(ac){this.max_height_px=Math.max(this.max_height_px,ac.html_elt.height());ac.html_elt.parent().children().css("height",this.max_height_px+"px");var ad=this.max_height_px;if(this.visible_height_px!==0){ad=Math.min(this.max_height_px,this.visible_height_px)}this.tiles_div.css("height",ad+"px")},postdraw_actions:function(ar,am,ah,ag){K.prototype.postdraw_actions.call(this,ar,ag);var al=this;if(al.mode==="Histogram"){var ad=-1;for(var ao=0;ao<ar.length;ao++){var an=ar[ao].max_val;if(an>ad){ad=an}}for(var ao=0;ao<ar.length;ao++){var au=ar[ao];if(au.max_val!==ad){au.html_elt.remove();al.draw_helper(true,am,au.index,au.resolution,au.html_elt.parent(),ah,{more_tile_data:{max:ad}})}}}if(al.filters_manager){var ai=al.filters_manager.filters;for(var aq=0;aq<ai.length;aq++){ai[aq].update_ui_elt()}var at=false,ac,aj;for(var ao=0;ao<ar.length;ao++){if(ar[ao].data.length){ac=ar[ao].data[0];for(var aq=0;aq<ai.length;aq++){aj=ai[aq];if(aj.applies_to(ac)&&aj.min!==aj.max){at=true;break}}}}if(al.filters_available!==at){al.filters_available=at;if(!al.filters_available){al.filters_manager.hide()}al.update_icons()}}this.container_div.find(".yaxislabel").remove();var af=ar[0];if(af instanceof k){var ak=(this.prefs.histogram_max?this.prefs.histogram_max:af.max_val),ae=$("<div/>").text(ak).make_text_editable({num_cols:12,on_finish:function(av){$(".tipsy").remove();var av=parseFloat(av);al.prefs.histogram_max=(!isNaN(av)?av:null);al.tile_cache.clear();al.request_draw()},help_text:"Set max value; leave blank to use default"}).addClass("yaxislabel top").css("color",this.prefs.label_color);this.container_div.prepend(ae)}if(af instanceof M){var ap=true;for(var ao=0;ao<ar.length;ao++){if(!ar[ao].all_slotted){ap=false;break}}if(!ap){this.action_icons.show_more_rows_icon.show()}else{this.action_icons.show_more_rows_icon.hide()}}else{this.action_icons.show_more_rows_icon.hide()}},update_auto_mode:function(ac){var ac;if(this.mode==="Auto"){if(ac==="no_detail"){ac="feature spans"}else{if(ac==="summary_tree"){ac="coverage histogram"}}this.action_icons.mode_icon.attr("title","Set display mode (now: Auto/"+ac+")")}},incremental_slots:function(ag,ac,af){var ad=this.view.canvas_manager.dummy_context,ae=this.slotters[ag];if(!ae||(ae.mode!==af)){ae=new (s.FeatureSlotter)(ag,af,x,function(ah){return ad.measureText(ah)});this.slotters[ag]=ae}return ae.slot_features(ac)},get_summary_tree_data:function(ag,aj,ae,ar){if(ar>ae-aj){ar=ae-aj}var an=Math.floor((ae-aj)/ar),aq=[],af=0;var ah=0,ai=0,am,ap=0,ak=[],ao,al;var ad=function(av,au,aw,at){av[0]=au+aw*at;av[1]=au+(aw+1)*at};while(ap<ar&&ah!==ag.length){var ac=false;for(;ap<ar&&!ac;ap++){ad(ak,aj,ap,an);for(ai=ah;ai<ag.length;ai++){am=ag[ai].slice(1,3);if(is_overlap(am,ak)){ac=true;break}}if(ac){break}}data_start_index=ai;aq[aq.length]=ao=[ak[0],0];for(;ai<ag.length;ai++){am=ag[ai].slice(1,3);if(is_overlap(am,ak)){ao[1]++}else{break}}if(ao[1]>af){af=ao[1]}ap++}return{max:af,delta:an,data:aq}},get_mode:function(ac){if(ac.dataset_type==="summary_tree"){mode="summary_tree"}else{if(ac.extra_info==="no_detail"||this.is_overview){mode="no_detail"}else{if(this.view.high-this.view.low>G){mode="Squish"}else{mode="Pack"}}}return mode},get_canvas_height:function(ac,ag,ah,ad){if(ag==="summary_tree"||ag==="Histogram"){return this.summary_draw_height}else{var af=this.incremental_slots(ah,ac.data,ag);var ae=new (this.painter)(null,null,null,this.prefs,ag);return Math.max(aa,ae.get_required_height(af,ad))}},draw_tile:function(an,ar,ap,at,ax,aj,ae){var aq=this,ad=ar.canvas,ag=this._get_tile_bounds(ax,at),aA=ag[0],ac=ag[1],aF=25,af=this.left_offset;if(ap==="summary_tree"||ap==="Histogram"){if(an.dataset_type!=="summary_tree"){var ak=this.get_summary_tree_data(an.data,aA,ac,200);if(an.max){ak.max=an.max}an=ak}var aC=new J.SummaryTreePainter(an,aA,ac,this.prefs);aC.draw(ar,ad.width,ad.height,aj);return new k(aq,ax,at,ad,an.data,an.max)}var ai=[],ao=this.slotters[aj].slots;all_slotted=true;if(an.data){var al=this.filters_manager.filters;for(var au=0,aw=an.data.length;au<aw;au++){var ah=an.data[au];var av=false;var am;for(var az=0,aE=al.length;az<aE;az++){am=al[az];am.update_attrs(ah);if(!am.keep(ah)){av=true;break}}if(!av){ai.push(ah);if(!(ah[0] in ao)){all_slotted=false}}}}var aD=(this.filters_manager.alpha_filter?new z(this.filters_manager.alpha_filter):null);var aB=(this.filters_manager.height_filter?new z(this.filters_manager.height_filter):null);var aC=new (this.painter)(ai,aA,ac,this.prefs,ap,aD,aB,ae);var ay=null;ar.fillStyle=this.prefs.block_color;ar.font=ar.canvas.manager.default_font;ar.textAlign="right";if(an.data){ay=aC.draw(ar,ad.width,ad.height,aj,ao);ay.translation=-af}return new M(aq,ax,at,ad,an.data,aj,ap,an.message,all_slotted,ay)},data_and_mode_compatible:function(ac,ad){if(ad==="Auto"){return true}else{if(ac.extra_info==="no_detail"||ac.dataset_type==="summary_tree"){return false}else{return true}}},can_subset:function(ac){if(ac.dataset_type==="summary_tree"||ac.message){return false}return true},});var Q=function(ad,ac,ae){d.call(this,ad,ac,ae);this.config=new C({track:this,params:[{key:"name",label:"Name",type:"text",default_value:this.name},{key:"block_color",label:"Block color",type:"color",default_value:get_random_color()},{key:"label_color",label:"Label color",type:"color",default_value:"black"},{key:"show_insertions",label:"Show insertions",type:"bool",default_value:false},{key:"show_counts",label:"Show summary counts",type:"bool",default_value:true},{key:"mode",type:"string",default_value:this.mode,hidden:true},],saved_values:ae.prefs,onchange:function(){this.track.set_name(this.track.prefs.name);this.track.tile_cache.clear();this.track.request_draw()}});this.prefs=this.config.values;this.painter=J.ReadPainter};p(Q.prototype,q.prototype,K.prototype,d.prototype);var T=function(ae,ad,ag){d.call(this,ae,ad,ag);var af=get_random_color(),ac=get_random_color([af,"#ffffff"]);this.config=new C({track:this,params:[{key:"name",label:"Name",type:"text",default_value:this.name},{key:"block_color",label:"Block and sense strand color",type:"color",default_value:af},{key:"reverse_strand_color",label:"Antisense strand color",type:"color",default_value:ac},{key:"label_color",label:"Label color",type:"color",default_value:"black"},{key:"show_insertions",label:"Show insertions",type:"bool",default_value:false},{key:"show_differences",label:"Show differences only",type:"bool",default_value:true},{key:"show_counts",label:"Show summary counts",type:"bool",default_value:true},{key:"histogram_max",label:"Histogram maximum",type:"float",default_value:null,help:"Clear value to set automatically"},{key:"mode",type:"string",default_value:this.mode,hidden:true},],saved_values:ag.prefs,onchange:function(){this.track.set_name(this.track.prefs.name);this.track.tile_cache.clear();this.track.request_draw()}});this.prefs=this.config.values;this.painter=J.ReadPainter;this.update_icons()};p(T.prototype,q.prototype,K.prototype,d.prototype);U.View=Z;U.DrawableGroup=N;U.LineTrack=j;U.FeatureTrack=d;U.ReadTrack=T;U.VcfTrack=Q;U.CompositeTrack=h};var slotting_module=function(c,b){var e=c("class").extend;var d=2,a=5;b.FeatureSlotter=function(i,h,f,g){this.slots={};this.start_end_dct={};this.w_scale=i;this.mode=h;this.include_label=(h==="Pack");this.max_rows=f;this.measureText=g};e(b.FeatureSlotter.prototype,{slot_features:function(m){var p=this.w_scale,h=this.start_end_dct,x=[],z=[],n=0,y=this.max_rows;for(var v=0,w=m.length;v<w;v++){var k=m[v],o=k[0];if(this.slots[o]!==undefined){n=Math.max(n,this.slots[o]);z.push(this.slots[o])}else{x.push(v)}}var q=function(E,F){for(var D=0;D<=y;D++){var B=false,G=h[D];if(G!==undefined){for(var A=0,C=G.length;A<C;A++){var i=G[A];if(F>i[0]&&E<i[1]){B=true;break}}}if(!B){return D}}return -1};for(var v=0,w=x.length;v<w;v++){var k=m[x[v]],o=k[0],t=k[1],f=k[2],r=k[3],g=Math.floor(t*p),l=Math.ceil(f*p),u=this.measureText(r).width,j;if(r!==undefined&&this.include_label){u+=(d+a);if(g-u>=0){g-=u;j="left"}else{l+=u;j="right"}}var s=q(g,l);if(s>=0){if(h[s]===undefined){h[s]=[]}h[s].push([g,l]);this.slots[o]=s;n=Math.max(n,s)}}return n+1}})};var painters_module=function(i,x){var u=i("class").extend;var p=function(I,A,G,z,F,D){if(D===undefined){D=4}var C=z-A;var B=F-G;var E=Math.floor(Math.sqrt(C*C+B*B)/D);var J=C/E;var H=B/E;var y;for(y=0;y<E;y++,A+=J,G+=H){if(y%2!==0){continue}I.fillRect(A,G,D,1)}};var q=function(B,A,z,E){var D=A-E/2,C=A+E/2,F=z-Math.sqrt(E*3/2);B.beginPath();B.moveTo(D,F);B.lineTo(C,F);B.lineTo(A,z);B.lineTo(D,F);B.strokeStyle=this.fillStyle;B.fill();B.stroke();B.closePath()};var d=function(y){this.default_val=(y?y:1)};d.prototype.gen_val=function(y){return this.default_val};var l=function(A,C,y,z,B){this.data=A;this.view_start=C;this.view_end=y;this.prefs=u({},this.default_prefs,z);this.mode=B};l.prototype.default_prefs={};l.prototype.draw=function(z,A,y,B){};var v=function(A,C,y,z,B){l.call(this,A,C,y,z,B)};v.prototype.default_prefs={show_counts:false};v.prototype.draw=function(L,z,K,M){var E=this.view_start,N=this.view_end-this.view_start,I=this.data.data,G=(this.prefs.histogram_max?this.prefs.histogram_max:this.data.max),B=K;delta_x_px=Math.ceil(this.data.delta*M);L.save();for(var C=0,D=I.length;C<D;C++){var H=Math.floor((I[C][0]-E)*M);var F=I[C][1];if(!F){continue}var J=F/G*K;if(F!==0&&J<1){J=1}L.fillStyle=this.prefs.block_color;L.fillRect(H,B-J,delta_x_px,J);var A=4;if(this.prefs.show_counts&&(L.measureText(F).width+A)<delta_x_px){L.fillStyle=this.prefs.label_color;L.textAlign="center";L.fillText(F,H+(delta_x_px/2),10)}}L.restore()};var b=function(y,C,E,F,A){l.call(this,y,C,E,F,A);if(this.prefs.min_value===undefined){var G=Infinity;for(var z=0,B=this.data.length;z<B;z++){G=Math.min(G,this.data[z][1])}this.prefs.min_value=G}if(this.prefs.max_value===undefined){var D=-Infinity;for(var z=0,B=this.data.length;z<B;z++){D=Math.max(D,this.data[z][1])}this.prefs.max_value=D}};b.prototype.default_prefs={min_value:undefined,max_value:undefined,mode:"Histogram",color:"#000",overflow_color:"#F66"};b.prototype.draw=function(S,Q,N,D){var I=false,K=this.prefs.min_value,F=this.prefs.max_value,M=F-K,B=N,C=this.view_start,P=this.view_end-this.view_start,L=this.mode,aa=this.data;S.save();var ac=Math.round(N+K/M*N);if(L!=="Intensity"){S.fillStyle="#aaa";S.fillRect(0,ac,Q,1)}S.beginPath();var Y,G,E;if(aa.length>1){E=Math.ceil((aa[1][0]-aa[0][0])*D)}else{E=10}var A=parseInt(this.prefs.color.slice(1),16),H=(A&16711680)>>16,R=(A&65280)>>8,V=A&255;for(var T=0,U=aa.length;T<U;T++){S.fillStyle=S.strokeStyle=this.prefs.color;Y=Math.round((aa[T][0]-C)*D);G=aa[T][1];var W=false,J=false;if(G===null){if(I&&L==="Filled"){S.lineTo(Y,B)}I=false;continue}if(G<K){J=true;G=K}else{if(G>F){W=true;G=F}}if(L==="Histogram"){G=Math.round(G/M*B);S.fillRect(Y,ac,E,-G)}else{if(L==="Intensity"){var z=(G-K)/M,O=Math.round(H+(255-H)*(1-z)),X=Math.round(R+(255-R)*(1-z)),ab=Math.round(V+(255-V)*(1-z));S.fillStyle="rgb("+O+","+X+","+ab+")";S.fillRect(Y,0,E,B)}else{G=Math.round(B-(G-K)/M*B);if(I){S.lineTo(Y,G)}else{I=true;if(L==="Filled"){S.moveTo(Y,B);S.lineTo(Y,G)}else{S.moveTo(Y,G)}}}}S.fillStyle=this.prefs.overflow_color;if(W||J){var Z;if(L==="Histogram"||L==="Intensity"){Z=E}else{Y-=2;Z=4}if(W){S.fillRect(Y,0,Z,3)}if(J){S.fillRect(Y,B-3,Z,3)}}S.fillStyle=this.prefs.color}if(L==="Filled"){if(I){S.lineTo(Y,ac);S.lineTo(0,ac)}S.fill()}else{S.stroke()}S.restore()};var m=function(y){this.feature_positions={};this.slot_height=y;this.translation=0;this.y_translation=0};m.prototype.map_feature_data=function(z,B,y,A){if(!this.feature_positions[B]){this.feature_positions[B]=[]}this.feature_positions[B].push({data:z,x_start:y,x_end:A})};m.prototype.get_feature_data=function(z,D){var C=Math.floor((D-this.y_translation)/this.slot_height),B;if(!this.feature_positions[C]){return null}z+=this.translation;for(var A=0;A<this.feature_positions[C].length;A++){B=this.feature_positions[C][A];if(z>=B.x_start&&z<=B.x_end){return B.data}}};var o=function(A,D,y,z,C,E,B){l.call(this,A,D,y,z,C);this.alpha_scaler=(E?E:new d());this.height_scaler=(B?B:new d())};o.prototype.default_prefs={block_color:"#FFF",connector_color:"#FFF"};u(o.prototype,{get_required_height:function(A,z){var y=y_scale=this.get_row_height(),B=this.mode;if(B==="no_detail"||B==="Squish"||B==="Pack"){y=A*y_scale}return y+this.get_top_padding(z)+this.get_bottom_padding(z)},get_top_padding:function(y){return 0},get_bottom_padding:function(y){return Math.max(Math.round(this.get_row_height()/2),5)},draw:function(K,I,G,E,F){var Q=this.data,D=this.view_start,M=this.view_end;K.save();K.fillStyle=this.prefs.block_color;K.textAlign="right";var H=this.view_end-this.view_start,L=this.get_row_height(),P=new m(L),B;for(var N=0,O=Q.length;N<O;N++){var A=Q[N],C=A[0],J=A[1],y=A[2],z=(F&&F[C]!==undefined?F[C]:null);if((J<M&&y>D)&&(this.mode==="Dense"||z!==null)){B=this.draw_element(K,this.mode,A,z,D,M,E,L,I);P.map_feature_data(A,z,B[0],B[1])}}K.restore();P.y_translation=this.get_top_padding(I);return P},draw_element:function(E,A,G,C,B,D,F,z,y){console.log("WARNING: Unimplemented function.");return[0,0]}});var c=10,h=3,k=5,w=10,f=1,s=9,e=3,a=9,j=2,g="#ccc";var r=function(A,D,y,z,C,E,B){o.call(this,A,D,y,z,C,E,B);this.draw_background_connector=true;this.draw_individual_connectors=false};u(r.prototype,o.prototype,{get_row_height:function(){var z=this.mode,y;if(z==="Dense"){y=c}else{if(z==="no_detail"){y=h}else{if(z==="Squish"){y=k}else{y=w}}}return y},draw_element:function(M,D,X,H,O,aj,an,ap,y){var T=X[0],al=X[1],ad=X[2]-1,Q=X[3],ae=Math.floor(Math.max(0,(al-O)*an)),N=Math.ceil(Math.min(y,Math.max(0,(ad-O)*an))),ac=ae,ao=N,aa=(D==="Dense"?0:(0+H))*ap+this.get_top_padding(y),L,ah,R=null,ar=null,B=this.prefs.block_color,ag=this.prefs.label_color;M.globalAlpha=this.alpha_scaler.gen_val(X);if(D==="Dense"){H=1}if(D==="no_detail"){M.fillStyle=B;M.fillRect(ae,aa+5,N-ae,f)}else{var K=X[4],Z=X[5],af=X[6],C=X[7],V=true;if(Z&&af){R=Math.floor(Math.max(0,(Z-O)*an));ar=Math.ceil(Math.min(y,Math.max(0,(af-O)*an)))}var am,U;if(D==="Squish"){am=1;U=e;V=false}else{if(D==="Dense"){am=5;U=s}else{am=5;U=a}}if(!C){M.fillStyle=B;M.fillRect(ae,aa+1,N-ae,U);if(K&&V){if(K==="+"){M.fillStyle=M.canvas.manager.get_pattern("right_strand_inv")}else{if(K==="-"){M.fillStyle=M.canvas.manager.get_pattern("left_strand_inv")}}M.fillRect(ae,aa+1,N-ae,U)}}else{var J,W;if(D==="Squish"||D==="Dense"){J=aa+Math.floor(e/2)+1;W=1}else{if(K){J=aa;W=U}else{J+=(e/2)+1;W=1}}if(this.draw_background_connector){if(D==="Squish"||D==="Dense"){M.fillStyle=g}else{if(K){if(K==="+"){M.fillStyle=M.canvas.manager.get_pattern("right_strand")}else{if(K==="-"){M.fillStyle=M.canvas.manager.get_pattern("left_strand")}}}else{M.fillStyle=g}}M.fillRect(ae,J,N-ae,W)}var E;for(var ak=0,A=C.length;ak<A;ak++){var F=C[ak],z=Math.floor(Math.max(0,(F[0]-O)*an)),Y=Math.ceil(Math.min(y,Math.max((F[1]-1-O)*an))),S,ab;if(z>Y){continue}M.fillStyle=B;M.fillRect(z,aa+(U-am)/2+1,Y-z,am);if(R!==undefined&&af>Z&&!(z>ar||Y<R)){var ai=Math.max(z,R),I=Math.min(Y,ar);M.fillRect(ai,aa+1,I-ai,U);if(C.length===1&&D==="Pack"){if(K==="+"){M.fillStyle=M.canvas.manager.get_pattern("right_strand_inv")}else{if(K==="-"){M.fillStyle=M.canvas.manager.get_pattern("left_strand_inv")}}if(ai+14<I){ai+=2;I-=2}M.fillRect(ai,aa+1,I-ai,U)}}if(this.draw_individual_connectors&&S){this.draw_connector(M,S,ab,z,Y,aa)}S=z;ab=Y}if(D==="Pack"){M.globalAlpha=1;M.fillStyle="white";var G=this.height_scaler.gen_val(X),P=Math.ceil(U*G),aq=Math.round((U-P)/2);if(G!==1){M.fillRect(ae,J+1,N-ae,aq);M.fillRect(ae,J+U-aq+1,N-ae,aq)}}}M.globalAlpha=1;if(D==="Pack"&&al>O){M.fillStyle=ag;if(O===0&&ae-M.measureText(Q).width<0){M.textAlign="left";M.fillText(Q,N+j,aa+8);ao+=M.measureText(Q).width+j}else{M.textAlign="right";M.fillText(Q,ae-j,aa+8);ac-=M.measureText(Q).width+j}}}M.globalAlpha=1;return[ac,ao]}});var t=function(B,E,y,A,D,F,C,z){o.call(this,B,E,y,A,D,F,C);this.ref_seq=(z?z.data:null)};u(t.prototype,o.prototype,{get_row_height:function(){var y,z=this.mode;if(z==="Dense"){y=c}else{if(z==="Squish"){y=k}else{y=w;if(this.prefs.show_insertions){y*=2}}}return y},draw_read:function(K,A,ag,V,L,aa,ad,C,B,M){K.textAlign="center";var J=this,R=[L,aa],Z=0,W=0,D=0,F=K.canvas.manager.char_width_px,y=(B==="+"?this.prefs.block_color:this.prefs.reverse_strand_color);var O=[];if((A==="Pack"||this.mode==="Auto")&&M!==undefined&&ag>F){D=Math.round(ag/2)}if(!C){C=[[0,M.length]]}for(var G=0,I=C.length;G<I;G++){var z=C[G],E="MIDNSHP=X"[z[0]],S=z[1];if(E==="H"||E==="S"){Z-=S}var U=ad+Z,Y=Math.floor(Math.max(0,(U-L)*ag)),ab=Math.floor(Math.max(0,(U+S-L)*ag));if(Y===ab){ab+=1}switch(E){case"H":break;case"S":case"M":case"=":if(is_overlap([U,U+S],R)){var N=M.slice(W,W+S);if(D>0){K.fillStyle=y;K.fillRect(Y-D,V+1,ab-Y,9);K.fillStyle=g;for(var af=0,H=N.length;af<H;af++){if(this.prefs.show_differences){if(this.ref_seq){var P=this.ref_seq[U-L+af];if(!P||P.toLowerCase()===N[af].toLowerCase()){continue}}else{continue}}if(U+af>=L&&U+af<=aa){var X=Math.floor(Math.max(0,(U+af-L)*ag));K.fillText(N[af],X,V+9)}}}else{K.fillStyle=y;K.fillRect(Y,V+4,ab-Y,e)}}W+=S;Z+=S;break;case"N":K.fillStyle=g;K.fillRect(Y-D,V+5,ab-Y,1);Z+=S;break;case"D":K.fillStyle="red";K.fillRect(Y-D,V+4,ab-Y,3);Z+=S;break;case"P":break;case"I":var ah=Y-D;if(is_overlap([U,U+S],R)){var N=M.slice(W,W+S);if(this.prefs.show_insertions){var T=Y-(ab-Y)/2;if((A==="Pack"||this.mode==="Auto")&&M!==undefined&&ag>F){K.fillStyle="yellow";K.fillRect(T-D,V-9,ab-Y,9);O[O.length]={type:"triangle",data:[ah,V+4,5]};K.fillStyle=g;switch(compute_overlap([U,U+S],R)){case (OVERLAP_START):N=N.slice(L-U);break;case (OVERLAP_END):N=N.slice(0,U-aa);break;case (CONTAINED_BY):break;case (CONTAINS):N=N.slice(L-U,U-aa);break}for(var af=0,H=N.length;af<H;af++){var X=Math.floor(Math.max(0,(U+af-L)*ag));K.fillText(N[af],X-(ab-Y)/2,V)}}else{K.fillStyle="yellow";K.fillRect(T,V+(this.mode!=="Dense"?2:5),ab-Y,(A!=="Dense"?e:s))}}else{if((A==="Pack"||this.mode==="Auto")&&M!==undefined&&ag>F){O.push({type:"text",data:[N.length,ah,V+9]})}else{}}}W+=S;break;case"X":W+=S;break}}K.fillStyle="yellow";var Q,ai,ae;for(var ac=0;ac<O.length;ac++){Q=O[ac];ai=Q.type;ae=Q.data;if(ai==="text"){K.save();K.font="bold "+K.font;K.fillText(ae[0],ae[1],ae[2]);K.restore()}else{if(ai==="triangle"){q(K,ae[0],ae[1],ae[2])}}}},draw_element:function(R,M,E,B,U,z,I,S,P){var H=E[0],Q=E[1],A=E[2],J=E[3],D=Math.floor(Math.max(0,(Q-U)*I)),F=Math.ceil(Math.min(P,Math.max(0,(A-U)*I))),C=(M==="Dense"?0:(0+B))*S,G=this.prefs.label_color,O=0;if((M==="Pack"||this.mode==="Auto")&&I>R.canvas.manager.char_width_px){var O=Math.round(I/2)}if(E[5] instanceof Array){var N=Math.floor(Math.max(0,(E[4][0]-U)*I)),L=Math.ceil(Math.min(P,Math.max(0,(E[4][1]-U)*I))),K=Math.floor(Math.max(0,(E[5][0]-U)*I)),y=Math.ceil(Math.min(P,Math.max(0,(E[5][1]-U)*I)));if(E[4][1]>=U&&E[4][0]<=z&&E[4][2]){this.draw_read(R,M,I,C,U,z,E[4][0],E[4][2],E[4][3],E[4][4])}if(E[5][1]>=U&&E[5][0]<=z&&E[5][2]){this.draw_read(R,M,I,C,U,z,E[5][0],E[5][2],E[5][3],E[5][4])}if(K>L){R.fillStyle=g;p(R,L-O,C+5,K-O,C+5)}}else{this.draw_read(R,M,I,C,U,z,Q,E[4],E[5],E[6])}if(M==="Pack"&&Q>U&&J!=="."){R.fillStyle=this.prefs.label_color;var T=1;if(T===0&&D-R.measureText(J).width<0){R.textAlign="left";R.fillText(J,F+j-O,C+8)}else{R.textAlign="right";R.fillText(J,D-j-O,C+8)}}return[0,0]}});var n=function(A,D,y,z,C,E,B){r.call(this,A,D,y,z,C,E,B);this.longest_feature_length=this.calculate_longest_feature_length();this.draw_background_connector=false;this.draw_individual_connectors=true};u(n.prototype,o.prototype,r.prototype,{calculate_longest_feature_length:function(){var z=0;for(var C=0,y=this.data.length;C<y;C++){var B=this.data[C],A=B[1],D=B[2];z=Math.max(z,D-A)}return z},get_top_padding:function(z){var y=this.view_end-this.view_start,A=z/y;return Math.min(128,Math.ceil((this.longest_feature_length/2)*A))},draw_connector:function(G,B,F,H,E,D){var y=(F+H)/2,C=H-y;var A=Math.PI,z=0;if(C>0){G.beginPath();G.arc(y,D,H-y,Math.PI,0);G.stroke()}}});x.Scaler=d;x.SummaryTreePainter=v;x.LinePainter=b;x.LinkedFeaturePainter=r;x.ReadPainter=t;x.ArcLinkedFeaturePainter=n};(function(d){var c={};var b=function(e){return c[e]};var a=function(f,g){var e={};g(b,e);c[f]=e};a("class",class_module);a("slotting",slotting_module);a("painters",painters_module);a("trackster",trackster_module);for(key in c.trackster){d[key]=c.trackster[key]}})(window);
\ No newline at end of file
https://bitbucket.org/galaxy/galaxy-central/changeset/a9ad7d60fc48/
changeset: a9ad7d60fc48
user: jgoecks
date: 2012-03-27 17:06:28
summary: Add CSS build artifacts to .hgignore
affected #: 1 file
diff -r 70397647fad54c50213e015aaedfed94e6b19eda -r a9ad7d60fc48fe4da3174753a3497ba0f555d6f2 .hgignore
--- a/.hgignore
+++ b/.hgignore
@@ -64,8 +64,12 @@
# Jars
tool-data/shared/jars/
+# CSS build artifacts.
+*/variables.less
+static/june_2007_style/blue/base_sprites.less
+
# Misc
*.orig
.DS_Store
*.rej
-*~
+*~
\ No newline at end of file
https://bitbucket.org/galaxy/galaxy-central/changeset/f6010ee7c7f8/
changeset: f6010ee7c7f8
user: jgoecks
date: 2012-03-27 17:06:56
summary: Merge.
affected #: 1 file
diff -r a9ad7d60fc48fe4da3174753a3497ba0f555d6f2 -r f6010ee7c7f8d5a021cba09bbfef937c28265c82 lib/galaxy/webapps/community/controllers/common.py
--- a/lib/galaxy/webapps/community/controllers/common.py
+++ b/lib/galaxy/webapps/community/controllers/common.py
@@ -997,16 +997,24 @@
"""
repo = hg.repository( get_configured_ui(), repository.repo_path )
options = []
+ changeset_tups = []
refresh_on_change_values = []
for repository_metadata in repository.downloadable_revisions:
changeset_revision = repository_metadata.changeset_revision
- revision_label = get_revision_label( trans, repository, changeset_revision )
- options.append( ( revision_label, changeset_revision ) )
+ ctx = get_changectx_for_changeset( trans, repo, changeset_revision )
+ if ctx:
+ rev = '%04d' % ctx.rev()
+ label = "%s:%s" % ( str( ctx.rev() ), changeset_revision )
+ else:
+ rev = '-1'
+ label = "-1:%s" % changeset_revision
+ changeset_tups.append( ( rev, label, changeset_revision ) )
refresh_on_change_values.append( changeset_revision )
# Sort options by the revision label. Even though the downloadable_revisions query sorts by update_time,
- # the changeset revisions may not be sorted correctly because setting metadata over time will reset update_time,
- # screwing up the order.
- sorted_options = sorted( options )
+ # the changeset revisions may not be sorted correctly because setting metadata over time will reset update_time.
+ for changeset_tup in sorted( changeset_tups ):
+ # Display the latest revision first.
+ options.insert( 0, ( changeset_tup[1], changeset_tup[2] ) )
if add_id_to_name:
name = 'changeset_revision_%d' % repository.id
else:
@@ -1014,7 +1022,7 @@
select_field = SelectField( name=name,
refresh_on_change=True,
refresh_on_change_values=refresh_on_change_values )
- for option_tup in sorted_options:
+ for option_tup in options:
selected = selected_value and option_tup[1] == selected_value
select_field.add_option( option_tup[0], option_tup[1], selected=selected )
return select_field
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0

commit/galaxy-central: greg: Missed the copyright - removed from the distribution.
by Bitbucket 27 Mar '12
by Bitbucket 27 Mar '12
27 Mar '12
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/changeset/241353a85198/
changeset: 241353a85198
user: greg
date: 2012-03-27 16:53:45
summary: Missed the copyright - removed from the distribution.
affected #: 1 file
diff -r 28641bb419101ca7d83f9d1ca92b134866155cf2 -r 241353a8519857a4db755a7cad8227f825b98d4e contrib/universe_merger.py
--- a/contrib/universe_merger.py
+++ /dev/null
@@ -1,71 +0,0 @@
-#! /usr/bin/env python
-'''
-universe_merger.py
-
-Created by Anne Pajon on 31 Jan 2012
-Copyright (c) 2012 Cancer Research UK - Cambridge Research Institute. All rights reserved.
-
-Script for merging specific local Galaxy config universe_wsgi.ini.cri with default Galaxy universe_wsgi.ini.sample
-'''
-import ConfigParser
-import sys
-import optparse
-import logging
-
-def main():
- # logging configuration
- logging.basicConfig(format='%(levelname)s: %(message)s', level=logging.INFO)
-
- # get the options
- parser = optparse.OptionParser()
- parser.add_option("-s", "--sample", dest="sample", action="store", help="the path to the Galaxy universe_wsgi.ini.sample file")
- parser.add_option("-c", "--config", dest="config", action="store", help="the path to your own universe_wsgi.ini.cri file")
- parser.add_option("-o", "--output", dest="output", action="store", help="the path to the new merged universe_wsgi.ini file")
- (options, args) = parser.parse_args()
-
- for option in ['sample', 'config']:
- if getattr(options, option) == None:
- print "Please supply a --%s parameter.\n" % (option)
- parser.print_help()
- sys.exit()
-
- config_sample = ConfigParser.RawConfigParser()
- config_sample.read(options.sample)
- config_sample_content = open(options.sample, 'r').read()
-
- config = ConfigParser.RawConfigParser()
- config.read(options.config)
-
- logging.info("Merging your own config file %s into the sample one %s." % (options.config, options.sample))
- logging.info("---------- DIFFERENCE ANALYSIS BEGIN ----------")
- for section in config.sections():
- if not config_sample.has_section(section):
- logging.warning("-MISSING- section [%s] not found in sample file. It will be ignored." % section)
- else:
- for (name, value) in config.items(section):
- if not config_sample.has_option(section, name):
- if not "#%s" % name in config_sample_content:
- logging.warning("-MISSING- section [%s] option '%s' not found in sample file. It will be ignored." % (section, name))
- else:
- logging.info("-notset- section [%s] option '%s' not set in sample file. It will be added." % (section, name))
- config_sample.set(section, name, value)
- else:
- if not config_sample.get(section, name) == value:
- logging.info("- diff - section [%s] option '%s' has different value ('%s':'%s'). It will be modified." % (section, name, config_sample.get(section, name), value))
- config_sample.set(section, name, value)
- logging.info("---------- DIFFERENCE ANALYSIS END ----------")
-
- if options.output:
- outputfile = open(options.output, 'w')
- config_sample.write(outputfile)
- outputfile.close()
- else:
- #print "----------"
- #config_sample.write(sys.stdout)
- #print "----------"
- logging.info("use -o OUTPUT to write the merged configuration into a file.")
-
- logging.info("read Galaxy universe_wsgi.ini.sample for detailed information.")
-
-if __name__ == '__main__':
- main()
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0

commit/galaxy-central: greg: Add script for merging specific local Galaxy config universe_wsgi.ini.cri with default Galaxy universe_wsgi.ini.sample contributed by Anne Pajon.
by Bitbucket 27 Mar '12
by Bitbucket 27 Mar '12
27 Mar '12
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/changeset/28641bb41910/
changeset: 28641bb41910
user: greg
date: 2012-03-27 16:19:04
summary: Add script for merging specific local Galaxy config universe_wsgi.ini.cri with default Galaxy universe_wsgi.ini.sample contributed by Anne Pajon.
affected #: 1 file
diff -r 7dc0e48e9105f19a564263c54684d51bee8ac16e -r 28641bb419101ca7d83f9d1ca92b134866155cf2 contrib/universe_merger.py
--- /dev/null
+++ b/contrib/universe_merger.py
@@ -0,0 +1,71 @@
+#! /usr/bin/env python
+'''
+universe_merger.py
+
+Created by Anne Pajon on 31 Jan 2012
+Copyright (c) 2012 Cancer Research UK - Cambridge Research Institute. All rights reserved.
+
+Script for merging specific local Galaxy config universe_wsgi.ini.cri with default Galaxy universe_wsgi.ini.sample
+'''
+import ConfigParser
+import sys
+import optparse
+import logging
+
+def main():
+ # logging configuration
+ logging.basicConfig(format='%(levelname)s: %(message)s', level=logging.INFO)
+
+ # get the options
+ parser = optparse.OptionParser()
+ parser.add_option("-s", "--sample", dest="sample", action="store", help="the path to the Galaxy universe_wsgi.ini.sample file")
+ parser.add_option("-c", "--config", dest="config", action="store", help="the path to your own universe_wsgi.ini.cri file")
+ parser.add_option("-o", "--output", dest="output", action="store", help="the path to the new merged universe_wsgi.ini file")
+ (options, args) = parser.parse_args()
+
+ for option in ['sample', 'config']:
+ if getattr(options, option) == None:
+ print "Please supply a --%s parameter.\n" % (option)
+ parser.print_help()
+ sys.exit()
+
+ config_sample = ConfigParser.RawConfigParser()
+ config_sample.read(options.sample)
+ config_sample_content = open(options.sample, 'r').read()
+
+ config = ConfigParser.RawConfigParser()
+ config.read(options.config)
+
+ logging.info("Merging your own config file %s into the sample one %s." % (options.config, options.sample))
+ logging.info("---------- DIFFERENCE ANALYSIS BEGIN ----------")
+ for section in config.sections():
+ if not config_sample.has_section(section):
+ logging.warning("-MISSING- section [%s] not found in sample file. It will be ignored." % section)
+ else:
+ for (name, value) in config.items(section):
+ if not config_sample.has_option(section, name):
+ if not "#%s" % name in config_sample_content:
+ logging.warning("-MISSING- section [%s] option '%s' not found in sample file. It will be ignored." % (section, name))
+ else:
+ logging.info("-notset- section [%s] option '%s' not set in sample file. It will be added." % (section, name))
+ config_sample.set(section, name, value)
+ else:
+ if not config_sample.get(section, name) == value:
+ logging.info("- diff - section [%s] option '%s' has different value ('%s':'%s'). It will be modified." % (section, name, config_sample.get(section, name), value))
+ config_sample.set(section, name, value)
+ logging.info("---------- DIFFERENCE ANALYSIS END ----------")
+
+ if options.output:
+ outputfile = open(options.output, 'w')
+ config_sample.write(outputfile)
+ outputfile.close()
+ else:
+ #print "----------"
+ #config_sample.write(sys.stdout)
+ #print "----------"
+ logging.info("use -o OUTPUT to write the merged configuration into a file.")
+
+ logging.info("read Galaxy universe_wsgi.ini.sample for detailed information.")
+
+if __name__ == '__main__':
+ main()
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0

commit/galaxy-central: greg: Fixes for tool shed changeset revision select field generation.
by Bitbucket 27 Mar '12
by Bitbucket 27 Mar '12
27 Mar '12
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/changeset/7dc0e48e9105/
changeset: 7dc0e48e9105
user: greg
date: 2012-03-27 15:45:18
summary: Fixes for tool shed changeset revision select field generation.
affected #: 1 file
diff -r cb5ff5b1bd67ca6333d808beefab24beedfeed94 -r 7dc0e48e9105f19a564263c54684d51bee8ac16e lib/galaxy/webapps/community/controllers/common.py
--- a/lib/galaxy/webapps/community/controllers/common.py
+++ b/lib/galaxy/webapps/community/controllers/common.py
@@ -997,16 +997,24 @@
"""
repo = hg.repository( get_configured_ui(), repository.repo_path )
options = []
+ changeset_tups = []
refresh_on_change_values = []
for repository_metadata in repository.downloadable_revisions:
changeset_revision = repository_metadata.changeset_revision
- revision_label = get_revision_label( trans, repository, changeset_revision )
- options.append( ( revision_label, changeset_revision ) )
+ ctx = get_changectx_for_changeset( trans, repo, changeset_revision )
+ if ctx:
+ rev = '%04d' % ctx.rev()
+ label = "%s:%s" % ( str( ctx.rev() ), changeset_revision )
+ else:
+ rev = '-1'
+ label = "-1:%s" % changeset_revision
+ changeset_tups.append( ( rev, label, changeset_revision ) )
refresh_on_change_values.append( changeset_revision )
# Sort options by the revision label. Even though the downloadable_revisions query sorts by update_time,
- # the changeset revisions may not be sorted correctly because setting metadata over time will reset update_time,
- # screwing up the order.
- sorted_options = sorted( options )
+ # the changeset revisions may not be sorted correctly because setting metadata over time will reset update_time.
+ for changeset_tup in sorted( changeset_tups ):
+ # Display the latest revision first.
+ options.insert( 0, ( changeset_tup[1], changeset_tup[2] ) )
if add_id_to_name:
name = 'changeset_revision_%d' % repository.id
else:
@@ -1014,7 +1022,7 @@
select_field = SelectField( name=name,
refresh_on_change=True,
refresh_on_change_values=refresh_on_change_values )
- for option_tup in sorted_options:
+ for option_tup in options:
selected = selected_value and option_tup[1] == selected_value
select_field.add_option( option_tup[0], option_tup[1], selected=selected )
return select_field
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0

commit/galaxy-central: jgoecks: Remove duplicate hr style; this reinstates dashed lines between sections in help text.
by Bitbucket 27 Mar '12
by Bitbucket 27 Mar '12
27 Mar '12
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/changeset/cb5ff5b1bd67/
changeset: cb5ff5b1bd67
user: jgoecks
date: 2012-03-27 14:49:44
summary: Remove duplicate hr style; this reinstates dashed lines between sections in help text.
affected #: 2 files
diff -r 8aa5dfcbbb0815cb2b41eb381ff0202bff4bb517 -r cb5ff5b1bd67ca6333d808beefab24beedfeed94 static/june_2007_style/base.less
--- a/static/june_2007_style/base.less
+++ b/static/june_2007_style/base.less
@@ -1616,13 +1616,6 @@
margin-left: 10px;
}
-hr
-{
- border: none;
- height: 0px;
- margin-top: 0px;
-}
-
div.toolSectionPad
{
margin: 0;
diff -r 8aa5dfcbbb0815cb2b41eb381ff0202bff4bb517 -r cb5ff5b1bd67ca6333d808beefab24beedfeed94 static/june_2007_style/blue/base.css
--- a/static/june_2007_style/blue/base.css
+++ b/static/june_2007_style/blue/base.css
@@ -734,7 +734,6 @@
pre.peek{background:white;color:black;width:100%;font-size:10px;overflow:auto;}pre.peek th{color:white;background:#023858;}
pre.peek table,pre.peek th,pre.peek tr,pre.peek td{font-family:Menlo,Monaco,"Courier New",monospace;font-size:10px;}
body.toolMenuPage{background:white;color:#303030;background:#dfe5f9;margin:5px;margin-right:10px;margin-left:10px;}
-hr{border:none;height:0px;margin-top:0px;}
div.toolSectionPad{margin:0;padding:0;height:5px;font-size:0px;}
div.toolSectionDetailsInner{margin-left:5px;margin-right:5px;}
div.toolSectionTitle{font-weight:bold;}
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0

commit/galaxy-central: greg: Fix for ordering the options of the select list displaying change sets for a tool shed repository.
by Bitbucket 26 Mar '12
by Bitbucket 26 Mar '12
26 Mar '12
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/changeset/8aa5dfcbbb08/
changeset: 8aa5dfcbbb08
user: greg
date: 2012-03-26 21:43:27
summary: Fix for ordering the options of the select list displaying change sets for a tool shed repository.
affected #: 1 file
diff -r 29f8601357203ad282f3848b2fa2c144ef6980f2 -r 8aa5dfcbbb0815cb2b41eb381ff0202bff4bb517 lib/galaxy/webapps/community/controllers/common.py
--- a/lib/galaxy/webapps/community/controllers/common.py
+++ b/lib/galaxy/webapps/community/controllers/common.py
@@ -1003,6 +1003,10 @@
revision_label = get_revision_label( trans, repository, changeset_revision )
options.append( ( revision_label, changeset_revision ) )
refresh_on_change_values.append( changeset_revision )
+ # Sort options by the revision label. Even though the downloadable_revisions query sorts by update_time,
+ # the changeset revisions may not be sorted correctly because setting metadata over time will reset update_time,
+ # screwing up the order.
+ sorted_options = sorted( options )
if add_id_to_name:
name = 'changeset_revision_%d' % repository.id
else:
@@ -1010,7 +1014,7 @@
select_field = SelectField( name=name,
refresh_on_change=True,
refresh_on_change_values=refresh_on_change_values )
- for option_tup in options:
+ for option_tup in sorted_options:
selected = selected_value and option_tup[1] == selected_value
select_field.add_option( option_tup[0], option_tup[1], selected=selected )
return select_field
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0

commit/galaxy-central: richard_burhans: allow limiting the number of data lines used to determine column data types while still counting all data lines
by Bitbucket 26 Mar '12
by Bitbucket 26 Mar '12
26 Mar '12
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/changeset/29f860135720/
changeset: 29f860135720
user: richard_burhans
date: 2012-03-26 19:55:05
summary: allow limiting the number of data lines used to determine column data types while still counting all data lines
affected #: 1 file
diff -r 6b8535e5b03001cc25e55f05b391fafacbf56b8e -r 29f8601357203ad282f3848b2fa2c144ef6980f2 lib/galaxy/datatypes/tabular.py
--- a/lib/galaxy/datatypes/tabular.py
+++ b/lib/galaxy/datatypes/tabular.py
@@ -26,7 +26,7 @@
def init_meta( self, dataset, copy_from=None ):
data.Text.init_meta( self, dataset, copy_from=copy_from )
- def set_meta( self, dataset, overwrite = True, skip = None, max_data_lines = 100000, **kwd ):
+ def set_meta( self, dataset, overwrite = True, skip = None, max_data_lines = 100000, max_guess_type_data_lines = None, **kwd ):
"""
Tries to determine the number of columns as well as those columns
that contain numerical values in the dataset. A skip parameter is
@@ -116,13 +116,14 @@
comment_lines += 1
else:
data_lines += 1
- fields = line.split( '\t' )
- for field_count, field in enumerate( fields ):
- if field_count >= len( column_types ): #found a previously unknown column, we append None
- column_types.append( None )
- column_type = guess_column_type( field )
- if type_overrules_type( column_type, column_types[field_count] ):
- column_types[field_count] = column_type
+ if max_guess_type_data_lines is None or data_lines <= max_guess_type_data_lines:
+ fields = line.split( '\t' )
+ for field_count, field in enumerate( fields ):
+ if field_count >= len( column_types ): #found a previously unknown column, we append None
+ column_types.append( None )
+ column_type = guess_column_type( field )
+ if type_overrules_type( column_type, column_types[field_count] ):
+ column_types[field_count] = column_type
if i == 0 and requested_skip is None:
# This is our first line, people seem to like to upload files that have a header line, but do not
# start with '#' (i.e. all column types would then most likely be detected as str). We will assume
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0

commit/galaxy-central: greg: Don't create the default path for installing tools from the tool shed until the time of installation, at which time the admin whll have over-ridden the default if they wanted to.
by Bitbucket 26 Mar '12
by Bitbucket 26 Mar '12
26 Mar '12
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/changeset/6b8535e5b030/
changeset: 6b8535e5b030
user: greg
date: 2012-03-26 19:27:17
summary: Don't create the default path for installing tools from the tool shed until the time of installation, at which time the admin whll have over-ridden the default if they wanted to.
affected #: 1 file
diff -r ba51ed3cf08491362d42e2d02dbb91d73a0f1dd3 -r 6b8535e5b03001cc25e55f05b391fafacbf56b8e lib/galaxy/config.py
--- a/lib/galaxy/config.py
+++ b/lib/galaxy/config.py
@@ -238,16 +238,6 @@
return default
def check( self ):
paths_to_check = [ self.root, self.tool_path, self.tool_data_path, self.template_path ]
- # Look for any tool shed configs and retrieve the tool_path attribute from the <toolbox> tag.
- tool_configs = self.tool_configs
- if self.migrated_tools_config not in tool_configs:
- tool_configs.append( self.migrated_tools_config )
- for config_filename in tool_configs:
- tree = parse_xml( config_filename )
- root = tree.getroot()
- tool_path = root.get( 'tool_path' )
- if tool_path not in [ None, False ]:
- paths_to_check.append( resolve_path( tool_path, self.root ) )
# Check that required directories exist
for path in paths_to_check:
if path not in [ None, False ] and not os.path.isdir( path ):
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0

commit/galaxy-central: jgoecks: Refactor changeset 164eef0d7693 to use less templates.
by Bitbucket 26 Mar '12
by Bitbucket 26 Mar '12
26 Mar '12
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/changeset/ba51ed3cf084/
changeset: ba51ed3cf084
user: jgoecks
date: 2012-03-26 18:34:15
summary: Refactor changeset 164eef0d7693 to use less templates.
affected #: 2 files
diff -r c401bfbbdcc70d50491e87c91fe18d5fb8fa18f7 -r ba51ed3cf08491362d42e2d02dbb91d73a0f1dd3 static/june_2007_style/blue/base.css
--- a/static/june_2007_style/blue/base.css
+++ b/static/june_2007_style/blue/base.css
@@ -9,12 +9,12 @@
sub{bottom:-0.25em;}
img{max-width:100%;height:auto;border:0;-ms-interpolation-mode:bicubic;}
button,input,select,textarea{margin:0;font-size:100%;vertical-align:middle;}
+input[type="checkbox"],input[type="radio"]{margin-left:0.5ex;margin-right:0.5ex;}
button,input{*overflow:visible;line-height:normal;}
button::-moz-focus-inner,input::-moz-focus-inner{padding:0;border:0;}
button,input[type="button"],input[type="reset"],input[type="submit"]{cursor:pointer;-webkit-appearance:button;}
input[type="search"]{-webkit-appearance:textfield;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;}
input[type="search"]::-webkit-search-decoration,input[type="search"]::-webkit-search-cancel-button{-webkit-appearance:none;}
-input[type="checkbox"],input[type="radio"]{margin-left:0.5ex;margin-right:0.5ex;}
textarea{overflow:auto;vertical-align:top;}
body{margin:0;font-family:"Lucida Grande",verdana,arial,helvetica,sans-serif;font-size:12px;line-height:16px;color:#111111;background-color:#ffffff;}
a{color:#303030;text-decoration:none;}
@@ -225,7 +225,7 @@
.navbar-form .radio,.navbar-form .checkbox{margin-top:5px;}
.navbar-form input[type="image"],.navbar-form input[type="checkbox"],.navbar-form input[type="radio"]{margin-top:3px;}
.navbar-search{position:relative;float:left;margin-top:6px;margin-bottom:0;}.navbar-search .search-query{padding:4px 9px;font-family:"Lucida Grande",verdana,arial,helvetica,sans-serif;font-size:13px;font-weight:normal;line-height:1;color:#ffffff;color:rgba(255, 255, 255, 0.75);background:#666;background:rgba(255, 255, 255, 0.3);border:1px solid #111;-webkit-box-shadow:inset 0 1px 2px rgba(0, 0, 0, 0.1),0 1px 0px rgba(255, 255, 255, 0.15);-moz-box-shadow:inset 0 1px 2px rgba(0, 0, 0, 0.1),0 1px 0px rgba(255, 255, 255, 0.15);box-shadow:inset 0 1px 2px rgba(0, 0, 0, 0.1),0 1px 0px rgba(255, 255, 255, 0.15);-webkit-transition:none;-moz-transition:none;-ms-transition:none;-o-transition:none;transition:none;}.navbar-search .search-query :-moz-placeholder{color:#eeeeee;}
-.navbar-search .search-query::-webkit-input-placeholder{color:#eeeeee;}
+.navbar-search .search-query ::-webkit-input-placeholder{color:#eeeeee;}
.navbar-search .search-query:hover{color:#ffffff;background-color:#999999;background-color:rgba(255, 255, 255, 0.5);}
.navbar-search .search-query:focus,.navbar-search .search-query.focused{padding:5px 10px;color:#333333;text-shadow:0 1px 0 #ffffff;background-color:#ffffff;border:0;-webkit-box-shadow:0 0 3px rgba(0, 0, 0, 0.15);-moz-box-shadow:0 0 3px rgba(0, 0, 0, 0.15);box-shadow:0 0 3px rgba(0, 0, 0, 0.15);outline:0;}
.navbar-fixed-top{position:fixed;top:0;right:0;left:0;z-index:1030;}
diff -r c401bfbbdcc70d50491e87c91fe18d5fb8fa18f7 -r ba51ed3cf08491362d42e2d02dbb91d73a0f1dd3 static/june_2007_style/bootstrap/reset.less
--- a/static/june_2007_style/bootstrap/reset.less
+++ b/static/june_2007_style/bootstrap/reset.less
@@ -93,6 +93,11 @@
font-size: 100%;
vertical-align: middle;
}
+// Use Webkit margins for checkboxs and radio buttons.
+input[type="checkbox"],input[type="radio"] {
+ margin-left: 0.5ex;
+ margin-right: 0.5ex;
+}
button,
input {
*overflow: visible; // Inner spacing ie IE6/7
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0

commit/galaxy-central: jgoecks: Trackster: use show/hide framework to manage reference track.
by Bitbucket 26 Mar '12
by Bitbucket 26 Mar '12
26 Mar '12
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/changeset/c401bfbbdcc7/
changeset: c401bfbbdcc7
user: jgoecks
date: 2012-03-26 16:50:31
summary: Trackster: use show/hide framework to manage reference track.
affected #: 1 file
diff -r b17faef8f1f36dda41f44206805b35896ce57cdc -r c401bfbbdcc70d50491e87c91fe18d5fb8fa18f7 static/scripts/trackster.js
--- a/static/scripts/trackster.js
+++ b/static/scripts/trackster.js
@@ -4249,6 +4249,7 @@
this.data_url = reference_url;
this.data_url_extra_params = {dbkey: view.dbkey};
this.data_manager = new ReferenceTrackDataManager(DATA_CACHE_SIZE, this, false);
+ this.hide_contents();
};
extend(ReferenceTrack.prototype, Drawable.prototype, TiledTrack.prototype, {
build_header_div: function() {},
@@ -4266,7 +4267,7 @@
if (w_scale > this.view.canvas_manager.char_width_px) {
if (seq.data === null) {
- track.content_div.css("height", "0px");
+ this.hide_contents();
return;
}
var canvas = ctx.canvas;
@@ -4277,17 +4278,10 @@
var c_start = Math.floor(c * w_scale);
ctx.fillText(seq[c], c_start, 10);
}
+ this.show_contents();
return new Tile(track, tile_index, resolution, canvas, seq);
}
- track.content_div.css("height", "0px");
- },
- /**
- * If there is a tile with sequence data, set content div so that data is visible.
- */
- after_show_tile: function(tile) {
- if (tile) {
- this.content_div.css("height", "12px");
- }
+ this.hide_contents();
}
});
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
3 new commits in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/changeset/e5a58a1d3d90/
changeset: e5a58a1d3d90
user: jgoecks
date: 2012-03-26 16:16:39
summary: Trackster: make show/hide content compatible with 8e9d2b492c4c.
affected #: 1 file
diff -r 4a23e38b7a12d65b50ff274272305f89fb5d0309 -r e5a58a1d3d900105cdedd6ee9249d958834f60c3 static/scripts/trackster.js
--- a/static/scripts/trackster.js
+++ b/static/scripts/trackster.js
@@ -393,8 +393,8 @@
DATA_ERROR = "There was an error in indexing this dataset. ",
DATA_NOCONVERTER = "A converter for this dataset is not installed. Please check your datatypes_conf.xml file.",
DATA_NONE = "No data for this chrom/contig.",
- DATA_PENDING = "Preparing data. This takes seconds for a small dataset but longer for a large dataset.<br/>\
- You can save and close the visualization and preparation will continue.<br/>",
+ DATA_PENDING = "Preparing data. This is very fast for a small dataset but can take a long time for a large dataset. \
+ If visualization is saved and closed, preparation will continue in the background.",
DATA_CANNOT_RUN_TOOL = "Tool cannot be rerun: ",
DATA_LOADING = "Loading data...",
DATA_OK = "Ready for display",
@@ -3329,18 +3329,15 @@
* Hide any elements that are part of the tracks contents area. Should
* remove as approprite, the track will be redrawn by show_contents.
*/
- hide_contents : function () {
- // Clear contents by removing any elements that are contained in
- // the tracks content_div
- this.content_div.children().remove();
- // Hide the content div
- this.content_div.hide();
- // And any y axis labels (common to several track types)
+ hide_contents: function () {
+ // Hide tiles.
+ this.tiles_div.hide();
+ // Hide any y axis labels (common to several track types)
this.container_div.find(".yaxislabel, .track-resize").hide()
},
- show_contents : function() {
+ show_contents: function() {
// Show the contents div and labels (if present)
- this.content_div.show();
+ this.tiles_div.show();
this.container_div.find(".yaxislabel, .track-resize").show()
// Request a redraw of the content
this.request_draw();
@@ -4282,7 +4279,7 @@
}
return new Tile(track, tile_index, resolution, canvas, seq);
}
- this.content_div.css("height", "0px");
+ track.content_div.css("height", "0px");
},
/**
* If there is a tile with sequence data, set content div so that data is visible.
https://bitbucket.org/galaxy/galaxy-central/changeset/3b396a26aaf6/
changeset: 3b396a26aaf6
user: jgoecks
date: 2012-03-26 16:17:22
summary: Merge.
affected #: 1 file
diff -r e5a58a1d3d900105cdedd6ee9249d958834f60c3 -r 3b396a26aaf6d78480750e0a8d038a034153f887 lib/galaxy/jobs/__init__.py
--- a/lib/galaxy/jobs/__init__.py
+++ b/lib/galaxy/jobs/__init__.py
@@ -1183,7 +1183,7 @@
self.job_runners = {}
start_job_runners = ["local"]
if app.config.start_job_runners is not None:
- start_job_runners.extend( app.config.start_job_runners.split(",") )
+ start_job_runners.extend( [ x.strip() for x in util.listify( app.config.start_job_runners ) ] )
if app.config.use_tasked_jobs:
start_job_runners.append("tasks")
for name in start_job_runners:
https://bitbucket.org/galaxy/galaxy-central/changeset/b17faef8f1f3/
changeset: b17faef8f1f3
user: jgoecks
date: 2012-03-26 16:18:09
summary: Add open ID config to .hgignore
affected #: 1 file
diff -r 3b396a26aaf6d78480750e0a8d038a034153f887 -r b17faef8f1f36dda41f44206805b35896ce57cdc .hgignore
--- a/.hgignore
+++ b/.hgignore
@@ -36,6 +36,7 @@
tool_data_table_conf.xml
tool_sheds_conf.xml
integrated_tool_panel.xml
+openid_conf.xml
static/welcome.html.*
static/welcome.html
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0

commit/galaxy-central: natefoo: Strip whitespace around separators in start_job_runners
by Bitbucket 26 Mar '12
by Bitbucket 26 Mar '12
26 Mar '12
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/changeset/3fb39b478590/
changeset: 3fb39b478590
user: natefoo
date: 2012-03-26 16:12:37
summary: Strip whitespace around separators in start_job_runners
affected #: 1 file
diff -r 4a23e38b7a12d65b50ff274272305f89fb5d0309 -r 3fb39b478590de7f4547766bbd60f3c6f686ab60 lib/galaxy/jobs/__init__.py
--- a/lib/galaxy/jobs/__init__.py
+++ b/lib/galaxy/jobs/__init__.py
@@ -1183,7 +1183,7 @@
self.job_runners = {}
start_job_runners = ["local"]
if app.config.start_job_runners is not None:
- start_job_runners.extend( app.config.start_job_runners.split(",") )
+ start_job_runners.extend( [ x.strip() for x in util.listify( app.config.start_job_runners ) ] )
if app.config.use_tasked_jobs:
start_job_runners.append("tasks")
for name in start_job_runners:
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0

commit/galaxy-central: dan: Fix for bug introduced into Tool Shed with last OpenID commit.
by Bitbucket 23 Mar '12
by Bitbucket 23 Mar '12
23 Mar '12
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/changeset/4a23e38b7a12/
changeset: 4a23e38b7a12
user: dan
date: 2012-03-24 02:47:14
summary: Fix for bug introduced into Tool Shed with last OpenID commit.
affected #: 1 file
diff -r 2b27b1e42fc90c4077c9ddcb963612efab28d940 -r 4a23e38b7a12d65b50ff274272305f89fb5d0309 lib/galaxy/webapps/community/app.py
--- a/lib/galaxy/webapps/community/app.py
+++ b/lib/galaxy/webapps/community/app.py
@@ -3,6 +3,7 @@
import galaxy.quota
import galaxy.datatypes.registry
import galaxy.webapps.community.model
+from galaxy.openid.providers import OpenIDProviders
from galaxy.web import security
from galaxy.tags.tag_handler import CommunityTagHandler
@@ -42,5 +43,6 @@
# Load security policy
self.security_agent = self.model.security_agent
self.quota_agent = galaxy.quota.NoQuotaAgent( self.model )
+ self.openid_providers = OpenIDProviders() #TODO: Add OpenID support
def shutdown( self ):
pass
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/changeset/2b27b1e42fc9/
changeset: 2b27b1e42fc9
user: dan
date: 2012-03-24 01:50:32
summary: Remove print debug.
affected #: 1 file
diff -r b9e188c4ecba66b5e065ac88b6b9d301a4879156 -r 2b27b1e42fc90c4077c9ddcb963612efab28d940 lib/galaxy/openid/providers.py
--- a/lib/galaxy/openid/providers.py
+++ b/lib/galaxy/openid/providers.py
@@ -76,7 +76,6 @@
for store_pref_name, store_pref_value_name in self.store_user_preference.iteritems():
if store_pref_value_name in ( self.sreg_optional + self.sreg_required ):
trans.user.preferences[ store_pref_name ] = sreg_attributes.get( store_pref_value_name )
- print 'setting',store_pref_name,'to',trans.user.preferences[ store_pref_name ]
else:
raise Exception( 'Only sreg is currently supported.' )
trans.sa_session.add( trans.user )
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0

23 Mar '12
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/changeset/b9e188c4ecba/
changeset: b9e188c4ecba
user: dan
date: 2012-03-23 18:41:01
summary: Abstract OpenID providers to be defined outside of the Python code and to allow customization of actions. See individual examples in openid/ and the list of enabled OpenID providers in openid_conf.xml.sample. Feedback is welcomed.
affected #: 17 files
diff -r 463fc935b97cf697f0fb0a48aae052a35c8e95c7 -r b9e188c4ecba66b5e065ac88b6b9d301a4879156 lib/galaxy/app.py
--- a/lib/galaxy/app.py
+++ b/lib/galaxy/app.py
@@ -13,6 +13,7 @@
from galaxy.tags.tag_handler import GalaxyTagHandler
from galaxy.tools.imp_exp import load_history_imp_exp_tools
from galaxy.sample_tracking import external_service_types
+from galaxy.openid.providers import OpenIDProviders
class UniverseApplication( object ):
"""Encapsulates the state of a Universe application"""
@@ -105,6 +106,9 @@
if self.config.enable_openid:
from galaxy.web.framework import openid_manager
self.openid_manager = openid_manager.OpenIDManager( self.config.openid_consumer_cache_path )
+ self.openid_providers = OpenIDProviders.from_file( self.config.openid_config )
+ else:
+ self.openid_providers = OpenIDProviders()
# Start the heartbeat process if configured and available
if self.config.use_heartbeat:
from galaxy.util import heartbeat
diff -r 463fc935b97cf697f0fb0a48aae052a35c8e95c7 -r b9e188c4ecba66b5e065ac88b6b9d301a4879156 lib/galaxy/config.py
--- a/lib/galaxy/config.py
+++ b/lib/galaxy/config.py
@@ -44,7 +44,9 @@
self.cookie_path = kwargs.get( "cookie_path", "/" )
# web API
self.enable_api = string_as_bool( kwargs.get( 'enable_api', False ) )
+ # Galaxy OpenID settings
self.enable_openid = string_as_bool( kwargs.get( 'enable_openid', False ) )
+ self.openid_config = kwargs.get( 'openid_config_file', 'openid_conf.xml' )
self.enable_quotas = string_as_bool( kwargs.get( 'enable_quotas', False ) )
self.tool_sheds_config = kwargs.get( 'tool_sheds_config_file', 'tool_sheds_conf.xml' )
self.enable_unique_workflow_defaults = string_as_bool( kwargs.get( 'enable_unique_workflow_defaults', False ) )
diff -r 463fc935b97cf697f0fb0a48aae052a35c8e95c7 -r b9e188c4ecba66b5e065ac88b6b9d301a4879156 lib/galaxy/openid/__init__.py
--- /dev/null
+++ b/lib/galaxy/openid/__init__.py
@@ -0,0 +1,3 @@
+"""
+OpenID functionality
+"""
\ No newline at end of file
diff -r 463fc935b97cf697f0fb0a48aae052a35c8e95c7 -r b9e188c4ecba66b5e065ac88b6b9d301a4879156 lib/galaxy/openid/providers.py
--- /dev/null
+++ b/lib/galaxy/openid/providers.py
@@ -0,0 +1,118 @@
+"""
+Contains OpenID provider functionality
+"""
+
+import logging, os
+from galaxy.util import parse_xml, string_as_bool
+from galaxy.util.odict import odict
+
+
+log = logging.getLogger( __name__ )
+
+class OpenIDProvider( object ):
+ '''An OpenID Provider object.'''
+ @classmethod
+ def from_file( cls, filename ):
+ return cls.from_elem( parse_xml( filename ).getroot() )
+ @classmethod
+ def from_elem( cls, xml_root ):
+ provider_elem = xml_root
+ provider_id = provider_elem.get( 'id', None )
+ provider_name = provider_elem.get( 'name', provider_id )
+ op_endpoint_url = provider_elem.find( 'op_endpoint_url' )
+ if op_endpoint_url is not None:
+ op_endpoint_url = op_endpoint_url.text
+ assert (provider_id and provider_name and op_endpoint_url), Exception( "OpenID Provider improperly configured" )
+ sreg_required = []
+ sreg_optional = []
+ use_for = {}
+ store_user_preference = {}
+ use_default_sreg = True
+ for elem in provider_elem.findall( 'sreg' ):
+ use_default_sreg = False
+ for field_elem in elem.findall( 'field' ):
+ sreg_name = field_elem.get( 'name' )
+ assert sreg_name, Exception( 'A name is required for a sreg element' )
+ if string_as_bool( field_elem.get( 'required' ) ):
+ sreg_required.append( sreg_name )
+ else:
+ sreg_optional.append( sreg_name )
+ for use_elem in field_elem.findall( 'use_for' ):
+ use_for[ use_elem.get( 'name' ) ] = sreg_name
+ for store_user_preference_elem in field_elem.findall( 'store_user_preference' ):
+ store_user_preference[ store_user_preference_elem.get( 'name' ) ] = sreg_name
+ if use_default_sreg:
+ sreg_required = None
+ sreg_optional = None
+ use_for = None
+ return cls( provider_id, provider_name, op_endpoint_url, sreg_required, sreg_optional, use_for, store_user_preference )
+ def __init__( self, id, name, op_endpoint_url, sreg_required=None, sreg_optional=None, use_for=None, store_user_preference=None ):
+ '''When sreg options are not specified, defaults are used.'''
+ self.id = id
+ self.name = name
+ self.op_endpoint_url = op_endpoint_url
+ if sreg_optional is None:
+ self.sreg_optional = [ 'nickname', 'email' ]
+ else:
+ self.sreg_optional = sreg_optional
+ if sreg_required:
+ self.sreg_required = sreg_required
+ else:
+ self.sreg_required = []
+ if use_for is not None:
+ self.use_for = use_for
+ else:
+ self.use_for = {}
+ if 'nickname' in ( self.sreg_optional + self.sreg_required ):
+ self.use_for[ 'username' ] = 'nickname'
+ if 'email' in ( self.sreg_optional + self.sreg_required ):
+ self.use_for[ 'email' ] = 'email'
+ if store_user_preference:
+ self.store_user_preference = store_user_preference
+ else:
+ self.store_user_preference = {}
+ def post_authentication( self, trans, openid_manager, info ):
+ sreg_attributes = openid_manager.get_sreg( info )
+ for store_pref_name, store_pref_value_name in self.store_user_preference.iteritems():
+ if store_pref_value_name in ( self.sreg_optional + self.sreg_required ):
+ trans.user.preferences[ store_pref_name ] = sreg_attributes.get( store_pref_value_name )
+ print 'setting',store_pref_name,'to',trans.user.preferences[ store_pref_name ]
+ else:
+ raise Exception( 'Only sreg is currently supported.' )
+ trans.sa_session.add( trans.user )
+ trans.sa_session.flush()
+
+class OpenIDProviders( object ):
+ '''Collection of OpenID Providers'''
+ @classmethod
+ def from_file( cls, filename ):
+ try:
+ return cls.from_elem( parse_xml( filename ).getroot() )
+ except Exception, e:
+ log.error( 'Failed to load OpenID Providers: %s' % ( e ) )
+ return cls()
+ @classmethod
+ def from_elem( cls, xml_root ):
+ oid_elem = xml_root
+ providers = odict()
+ for elem in oid_elem.findall( 'provider' ):
+ try:
+ provider = OpenIDProvider.from_file( os.path.join( 'openid', elem.get( 'file' ) ) )
+ providers[ provider.id ] = provider
+ log.debug( 'Loaded OpenID provider: %s (%s)' % ( provider.name, provider.id ) )
+ except Exception, e:
+ log.error( 'Failed to add OpenID provider: %s' % ( e ) )
+ return cls( providers )
+ def __init__( self, providers=None ):
+ if providers:
+ self.providers = providers
+ else:
+ self.providers = odict()
+ def __iter__( self ):
+ for provider in self.providers.itervalues():
+ yield provider
+ def get( self, name, default=None ):
+ if name in self.providers:
+ return self.providers[ name ]
+ else:
+ return default
diff -r 463fc935b97cf697f0fb0a48aae052a35c8e95c7 -r b9e188c4ecba66b5e065ac88b6b9d301a4879156 lib/galaxy/web/controllers/user.py
--- a/lib/galaxy/web/controllers/user.py
+++ b/lib/galaxy/web/controllers/user.py
@@ -11,6 +11,7 @@
from galaxy.util.json import from_json_string, to_json_string
from galaxy.web.framework.helpers import iff
from galaxy.security.validate_user_input import validate_email, validate_publicname, validate_password
+from galaxy.openid.providers import OpenIDProvider
log = logging.getLogger( __name__ )
@@ -21,12 +22,6 @@
<p/>
"""
-OPENID_PROVIDERS = { 'Google' : 'https://www.google.com/accounts/o8/id',
- 'Yahoo!' : 'http://yahoo.com',
- 'AOL/AIM' : 'http://openid.aol.com',
- 'Launchpad' : 'http://login.launchpad.net',
- }
-
class UserOpenIDGrid( grids.Grid ):
use_panels = False
title = "OpenIDs linked to your account"
@@ -68,19 +63,26 @@
if not referer:
referer = url_for( '/' )
consumer = trans.app.openid_manager.get_consumer( trans )
- process_url = trans.request.base.rstrip( '/' ) + url_for( controller='user', action='openid_process', referer=referer, auto_associate=auto_associate )
- if not openid_url and openid_provider and openid_provider in OPENID_PROVIDERS:
- openid_url = OPENID_PROVIDERS[openid_provider]
- if openid_url:
+ openid_provider_obj = None
+ if not openid_url and openid_provider and trans.app.openid_providers.get( openid_provider ):
+ openid_provider_obj = trans.app.openid_providers.get( openid_provider )
+ elif openid_url:
+ openid_provider_obj = OpenIDProvider( openid_url, openid_url, openid_url ) #for manually entered links use the link for id, name and url
+ elif openid_provider:
+ message = 'Invalid OpenID provider specified: %s' % ( openid_provider )
+ else:
+ message = 'An OpenID provider was not specified'
+ process_url = trans.request.base.rstrip( '/' ) + url_for( controller='user', action='openid_process', referer=referer, auto_associate=auto_associate, openid_provider=openid_provider )
+ if openid_provider_obj is not None:
request = None
try:
- request = consumer.begin( openid_url )
+ request = consumer.begin( openid_provider_obj.op_endpoint_url )
if request is None:
- message = 'No OpenID services are available at %s' % openid_url
+ message = 'No OpenID services are available at %s' % openid_provider_obj.op_endpoint_url
except Exception, e:
message = 'Failed to begin OpenID authentication: %s' % str( e )
if request is not None:
- trans.app.openid_manager.add_sreg( trans, request, optional=[ 'nickname', 'email' ] )
+ sreg_request = trans.app.openid_manager.add_sreg( trans, request, required=openid_provider_obj.sreg_required, optional=openid_provider_obj.sreg_optional )
if request.shouldSendRedirect():
redirect_url = request.redirectURL(
trans.request.base, process_url )
@@ -114,6 +116,7 @@
info = consumer.complete( kwd, trans.request.url )
display_identifier = info.getDisplayIdentifier()
redirect_url = kwd.get( 'referer', url_for( '/' ) )
+ openid_provider = kwd.get( 'openid_provider', '' )
if info.status == trans.app.openid_manager.FAILURE and display_identifier:
message = "Login via OpenID failed. The technical reason for this follows, please include this message in your email if you need to %s to resolve this problem: %s" % ( contact, info.message )
return trans.response.send_redirect( url_for( controller='user',
@@ -125,6 +128,9 @@
if info.endpoint.canonicalID:
display_identifier = info.endpoint.canonicalID
user_openid = trans.sa_session.query( trans.app.model.UserOpenID ).filter( trans.app.model.UserOpenID.table.c.openid == display_identifier ).first()
+ openid_provider_obj = trans.app.openid_providers.get( openid_provider )
+ if not openid_provider_obj:
+ openid_provider_obj = OpenIDProvider( display_identifier, display_identifier, display_identifier )
if not user_openid:
user_openid = trans.app.model.UserOpenID( session=trans.galaxy_session, openid=display_identifier )
elif not user_openid.user and user_openid.session.id != trans.galaxy_session.id:
@@ -132,6 +138,7 @@
elif user_openid.user and not auto_associate:
trans.handle_user_login( user_openid.user, webapp )
trans.log_event( "User logged in via OpenID: %s" % display_identifier )
+ openid_provider_obj.post_authentication( trans, trans.app.openid_manager, info )
trans.response.send_redirect( redirect_url )
return
if auto_associate and trans.user:
@@ -151,6 +158,7 @@
trans.log_event( "User associated OpenID: %s" % display_identifier )
message = "The OpenID <strong>%s</strong> has been associated with your Galaxy account, <strong>%s</strong>." % ( display_identifier, trans.user.email )
status = "done"
+ openid_provider_obj.post_authentication( trans, trans.app.openid_manager, info )
trans.response.send_redirect( url_for( controller='user',
action='openid_manage',
use_panels=True,
@@ -162,15 +170,18 @@
message = "OpenID authentication was successful, but you need to associate your OpenID with a Galaxy account."
sreg_resp = trans.app.openid_manager.get_sreg( info )
try:
- username = sreg_resp.get( 'nickname', '' )
+ sreg_username_name = openid_provider_obj.use_for.get( 'username' )
+ username = sreg_resp.get( sreg_username_name, '' )
except AttributeError:
username = ''
try:
- email = sreg_resp.get( 'email', '' )
+ sreg_email_name = openid_provider_obj.use_for.get( 'email' )
+ email = sreg_resp.get( sreg_email_name, '' )
except AttributeError:
email = ''
trans.response.send_redirect( url_for( controller='user',
action='openid_associate',
+ openid_provider=openid_provider,
use_panels=True,
username=username,
email=email,
@@ -199,6 +210,8 @@
email = kwd.get( 'email', '' )
username = kwd.get( 'username', '' )
referer = kwd.get( 'referer', trans.request.referer )
+ openid_provider = kwd.get( 'openid_provider', '' )
+ openid_provider_obj = trans.app.openid_providers.get( openid_provider )
params = util.Params( kwd )
is_admin = cntrller == 'admin' and trans.user_is_admin()
openids = trans.galaxy_session.openids
@@ -219,8 +232,9 @@
redirect_url = referer
if not redirect_url:
redirect_url = url_for( '/' )
- trans.response.send_redirect( redirect_url )
- return
+ if openid_provider_obj:
+ return trans.response.send_redirect( url_for( controller='user', action='openid_auth', openid_provider=openid_provider, referer=redirect_url ) )
+ return trans.response.send_redirect( redirect_url )
if kwd.get( 'create_user_button', False ):
password = kwd.get( 'password', '' )
confirm = kwd.get( 'confirm', '' )
@@ -251,7 +265,9 @@
redirect_url = referer
if not redirect_url:
redirect_url = url_for( '/' )
- trans.response.send_redirect( redirect_url )
+ if openid_provider_obj:
+ return trans.response.send_redirect( url_for( controller='user', action='openid_auth', openid_provider=openid_provider, referer=redirect_url ) )
+ return trans.response.send_redirect( redirect_url )
else:
message = error
status = 'error'
@@ -285,7 +301,8 @@
user_type_fd_id_select_field=user_type_fd_id_select_field,
user_type_form_definition=user_type_form_definition,
widgets=widgets,
- openids=openids )
+ openids=openids,
+ openid_provider=openid_provider )
@web.expose
@web.require_login( 'manage OpenIDs' )
def openid_disassociate( self, trans, webapp='galaxy', **kwd ):
@@ -340,7 +357,7 @@
use_panels=use_panels,
id=kwd['id'] ) )
kwd['referer'] = url_for( controller='user', action='openid_manage', use_panels=True )
- kwd['openid_providers'] = OPENID_PROVIDERS
+ kwd['openid_providers'] = trans.app.openid_providers
return self.user_openid_grid( trans, **kwd )
@web.expose
def login( self, trans, webapp='galaxy', redirect_url='', refresh_frames=[], **kwd ):
@@ -351,6 +368,7 @@
header = ''
user = None
email = kwd.get( 'email', '' )
+ openid_provider = kwd.get( 'openid_provider', '' )
if kwd.get( 'login_button', False ):
if webapp == 'galaxy' and not refresh_frames:
if trans.app.config.require_login:
@@ -385,7 +403,7 @@
refresh_frames=refresh_frames,
message=message,
status=status,
- openid_providers=OPENID_PROVIDERS,
+ openid_providers=trans.app.openid_providers,
active_view="user" )
def __validate_login( self, trans, webapp='galaxy', **kwd ):
message = kwd.get( 'message', '' )
diff -r 463fc935b97cf697f0fb0a48aae052a35c8e95c7 -r b9e188c4ecba66b5e065ac88b6b9d301a4879156 lib/galaxy/web/framework/openid_manager.py
--- a/lib/galaxy/web/framework/openid_manager.py
+++ b/lib/galaxy/web/framework/openid_manager.py
@@ -1,5 +1,5 @@
"""
-Mange the OpenID consumer and related data stores.
+Manage the OpenID consumer and related data stores.
"""
import os, pickle, logging
diff -r 463fc935b97cf697f0fb0a48aae052a35c8e95c7 -r b9e188c4ecba66b5e065ac88b6b9d301a4879156 openid/aol.xml
--- /dev/null
+++ b/openid/aol.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0"?>
+<provider id="aol" name="AOL/AIM">
+ <op_endpoint_url>http://openid.aol.com</op_endpoint_url>
+</provider>
diff -r 463fc935b97cf697f0fb0a48aae052a35c8e95c7 -r b9e188c4ecba66b5e065ac88b6b9d301a4879156 openid/genomespace.xml
--- /dev/null
+++ b/openid/genomespace.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0"?>
+<provider id="genomespace" name="GenomeSpace">
+ <op_endpoint_url>https://identity.genomespace.org/identityServer/xrd.jsp</op_endpoint_url>
+ <sreg>
+ <field name="nickname" required="True">
+ <use_for name="username"/>
+ <store_user_preference name="genomespace_username"/>
+ </field>
+ <field name="email" required="False">
+ <use_for name="email"/>
+ </field>
+ <field name="gender" required="True">
+ <store_user_preference name="genomespace_token"/>
+ </field>
+ </sreg>
+</provider>
diff -r 463fc935b97cf697f0fb0a48aae052a35c8e95c7 -r b9e188c4ecba66b5e065ac88b6b9d301a4879156 openid/google.xml
--- /dev/null
+++ b/openid/google.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0"?>
+<provider id="google" name="Google">
+ <op_endpoint_url>https://www.google.com/accounts/o8/id</op_endpoint_url>
+</provider>
diff -r 463fc935b97cf697f0fb0a48aae052a35c8e95c7 -r b9e188c4ecba66b5e065ac88b6b9d301a4879156 openid/launchpad.xml
--- /dev/null
+++ b/openid/launchpad.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0"?>
+<provider id="launchpad" name="Launchpad">
+ <op_endpoint_url>http://login.launchpad.net</op_endpoint_url>
+</provider>
diff -r 463fc935b97cf697f0fb0a48aae052a35c8e95c7 -r b9e188c4ecba66b5e065ac88b6b9d301a4879156 openid/yahoo.xml
--- /dev/null
+++ b/openid/yahoo.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0"?>
+<provider id="yahoo" name="Yahoo!">
+ <op_endpoint_url>http://yahoo.com</op_endpoint_url>
+</provider>
diff -r 463fc935b97cf697f0fb0a48aae052a35c8e95c7 -r b9e188c4ecba66b5e065ac88b6b9d301a4879156 openid_conf.xml.sample
--- /dev/null
+++ b/openid_conf.xml.sample
@@ -0,0 +1,8 @@
+<?xml version="1.0"?>
+<openid>
+ <provider file="google.xml" />
+ <provider file="yahoo.xml" />
+ <provider file="aol.xml" />
+ <provider file="launchpad.xml" />
+ <provider file="genomespace.xml" />
+</openid>
diff -r 463fc935b97cf697f0fb0a48aae052a35c8e95c7 -r b9e188c4ecba66b5e065ac88b6b9d301a4879156 run.sh
--- a/run.sh
+++ b/run.sh
@@ -15,6 +15,7 @@
tool_conf.xml.sample
tool_data_table_conf.xml.sample
tool_sheds_conf.xml.sample
+ openid_conf.xml.sample
universe_wsgi.ini.sample
tool-data/shared/ucsc/builds.txt.sample
tool-data/shared/igv/igv_build_sites.txt.sample
diff -r 463fc935b97cf697f0fb0a48aae052a35c8e95c7 -r b9e188c4ecba66b5e065ac88b6b9d301a4879156 templates/user/login.mako
--- a/templates/user/login.mako
+++ b/templates/user/login.mako
@@ -59,7 +59,7 @@
</%def>
-<%def name="render_login_form( form_action=None )">
+<%def name="render_login_form( form_action=None, openid_provider='' )"><%
if form_action is None:
@@ -77,6 +77,7 @@
<input type="text" name="email" value="${email}" size="40"/><input type="hidden" name="webapp" value="${webapp}" size="40"/><input type="hidden" name="referer" value="${referer}" size="40"/>
+ <input type="hidden" name="openid_provider" value="${openid_provider}" /></div><div class="form-row"><label>Password:</label>
@@ -94,10 +95,9 @@
</%def><%def name="render_openid_form( referer, auto_associate, openid_providers )">
-
<div class="toolForm"><div class="toolFormTitle">OpenID Login</div>
- <form name="openid" id="openid" action="${h.url_for( controller='user', action='openid_auth' )}" method="post" >
+ <form name="openid" id="openid" action="${h.url_for( controller='user', action='openid_auth' )}" method="post" target="_parent" ><div class="form-row"><label>OpenID URL:</label><input type="text" name="openid_url" size="60" style="background-image:url('${h.url_for( '/static/images/openid-16x16.gif' )}' ); background-repeat: no-repeat; padding-right: 20px; background-position: 99% 50%;"/>
@@ -107,8 +107,8 @@
</div><div class="form-row">
Or, authenticate with your <select name="openid_provider">
- %for provider in openid_providers.keys():
- <option>${provider}</option>
+ %for provider in openid_providers:
+ <option value="${provider.id}">${provider.name}</option>
%endfor
</select> account.
</div>
diff -r 463fc935b97cf697f0fb0a48aae052a35c8e95c7 -r b9e188c4ecba66b5e065ac88b6b9d301a4879156 templates/user/openid_associate.mako
--- a/templates/user/openid_associate.mako
+++ b/templates/user/openid_associate.mako
@@ -65,11 +65,11 @@
<% form_action = h.url_for( cntrller=cntrller, use_panels=use_panels ) %>
- ${render_login_form( form_action=form_action )}
+ ${render_login_form( form_action=form_action, openid_provider=openid_provider )}
<br/>
- ${render_registration_form( form_action=form_action )}
+ ${render_registration_form( form_action=form_action, openid_provider=openid_provider )}
</div></div>
diff -r 463fc935b97cf697f0fb0a48aae052a35c8e95c7 -r b9e188c4ecba66b5e065ac88b6b9d301a4879156 templates/user/register.mako
--- a/templates/user/register.mako
+++ b/templates/user/register.mako
@@ -21,7 +21,7 @@
${render_registration_form()}
%endif
-<%def name="render_registration_form( form_action=None )">
+<%def name="render_registration_form( form_action=None, openid_provider='' )"><%
if form_action is None:
@@ -38,6 +38,7 @@
<input type="text" name="email" value="${email}" size="40"/><input type="hidden" name="webapp" value="${webapp}" size="40"/><input type="hidden" name="referer" value="${referer}" size="40"/>
+ <input type="hidden" name="openid_provider" value="${openid_provider}" /></div><div class="form-row"><label>Password:</label>
diff -r 463fc935b97cf697f0fb0a48aae052a35c8e95c7 -r b9e188c4ecba66b5e065ac88b6b9d301a4879156 universe_wsgi.ini.sample
--- a/universe_wsgi.ini.sample
+++ b/universe_wsgi.ini.sample
@@ -495,6 +495,7 @@
# Enable authentication via OpenID. Allows users to log in to their Galaxy
# account by authenticating with an OpenID provider.
#enable_openid = False
+#openid_config_file = openid_conf.xml
# Enable the (experimental! beta!) Web API. Documentation forthcoming.
#enable_api = False
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0

commit/galaxy-central: dannon: Convert loc file examples to use tabs instead of spaces.
by Bitbucket 23 Mar '12
by Bitbucket 23 Mar '12
23 Mar '12
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/changeset/463fc935b97c/
changeset: 463fc935b97c
user: dannon
date: 2012-03-23 13:59:34
summary: Convert loc file examples to use tabs instead of spaces.
affected #: 22 files
diff -r 732c10115fdf807ada88bf83cfe8a03f0c1c599e -r 463fc935b97cf697f0fb0a48aae052a35c8e95c7 tool-data/all_fasta.loc.sample
--- a/tool-data/all_fasta.loc.sample
+++ b/tool-data/all_fasta.loc.sample
@@ -4,13 +4,13 @@
#all_fasta.loc. This file has the format (white space characters are
#TAB characters):
#
-#<unique_build_id><dbkey><display_name><file_path>
+#<unique_build_id><dbkey><display_name><file_path>
#
#So, all_fasta.loc could look something like this:
#
-#apiMel3 apiMel3 Honeybee (Apis mellifera): apiMel3 /path/to/genome/apiMel3/apiMel3.fa
-#hg19canon hg19 Human (Homo sapiens): hg19 Canonical /path/to/genome/hg19/hg19canon.fa
-#hg19full hg19 Human (Homo sapiens): hg19 Full /path/to/genome/hg19/hg19full.fa
+#apiMel3 apiMel3 Honeybee (Apis mellifera): apiMel3 /path/to/genome/apiMel3/apiMel3.fa
+#hg19canon hg19 Human (Homo sapiens): hg19 Canonical /path/to/genome/hg19/hg19canon.fa
+#hg19full hg19 Human (Homo sapiens): hg19 Full /path/to/genome/hg19/hg19full.fa
#
#Your all_fasta.loc file should contain an entry for each individual
#fasta file. So there will be multiple fasta files for each build,
diff -r 732c10115fdf807ada88bf83cfe8a03f0c1c599e -r 463fc935b97cf697f0fb0a48aae052a35c8e95c7 tool-data/blastdb.loc.sample
--- a/tool-data/blastdb.loc.sample
+++ b/tool-data/blastdb.loc.sample
@@ -2,7 +2,7 @@
#list of nucleotide BLAST databases, using three columns tab separated
#(longer whitespace are TAB characters):
#
-#<unique_id><database_caption><base_name_path>
+#<unique_id><database_caption><base_name_path>
#
#The captions typically contain spaces and might end with the build date.
#It is important that the actual database name does not have a space in it,
@@ -25,9 +25,9 @@
#Your blastdb.loc file should include an entry per line for each "base name"
#you have stored. For example:
#
-#nt_02_Dec_2009 nt 02 Dec 2009 /depot/data2/galaxy/blastdb/nt/nt.chunk
-#wgs_30_Nov_2009 wgs 30 Nov 2009 /depot/data2/galaxy/blastdb/wgs/wgs.chunk
-#test_20_Sep_2008 test 20 Sep 2008 /depot/data2/galaxy/blastdb/test/test
+#nt_02_Dec_2009 nt 02 Dec 2009 /depot/data2/galaxy/blastdb/nt/nt.chunk
+#wgs_30_Nov_2009 wgs 30 Nov 2009 /depot/data2/galaxy/blastdb/wgs/wgs.chunk
+#test_20_Sep_2008 test 20 Sep 2008 /depot/data2/galaxy/blastdb/test/test
#...etc...
#
#See also blastdb_p.loc which is for any protein BLAST database.
diff -r 732c10115fdf807ada88bf83cfe8a03f0c1c599e -r 463fc935b97cf697f0fb0a48aae052a35c8e95c7 tool-data/blastdb_p.loc.sample
--- a/tool-data/blastdb_p.loc.sample
+++ b/tool-data/blastdb_p.loc.sample
@@ -2,25 +2,25 @@
#list of protein BLAST databases, using three columns tab separated
#(longer whitespace are TAB characters):
#
-#<unique_id><database_caption><base_name_path>
+#<unique_id><database_caption><base_name_path>
#
#The captions typically contain spaces and might end with the build date.
#It is important that the actual database name does not have a space in it,
#and that the first tab that appears in the line is right before the path.
#
-#So, for example, if your database is NR and the path to your base name
+#So, for example, if your database is NR and the path to your base name
#is /data/blastdb/nr, then the blastdb_p.loc entry would look like this:
#
-#nr NCBI NR (non redundant) /data/blastdb/nr
+#nr NCBI NR (non redundant) /data/blastdb/nr
#
#and your /data/blastdb directory would contain all of the files associated
#with the database, /data/blastdb/nr.*.
#
-#Your blastdb_p.loc file should include an entry per line for each "base name"
+#Your blastdb_p.loc file should include an entry per line for each "base name"
#you have stored. For example:
#
-#nr_05Jun2010 NCBI NR (non redundant) 05 Jun 2010 /data/blastdb/05Jun2010/nr
-#nr_15Aug2010 NCBI NR (non redundant) 15 Aug 2010 /data/blastdb/15Aug2010/nr
+#nr_05Jun2010 NCBI NR (non redundant) 05 Jun 2010 /data/blastdb/05Jun2010/nr
+#nr_15Aug2010 NCBI NR (non redundant) 15 Aug 2010 /data/blastdb/15Aug2010/nr
#...etc...
#
#See also blastdb.loc which is for any nucleotide BLAST database.
diff -r 732c10115fdf807ada88bf83cfe8a03f0c1c599e -r 463fc935b97cf697f0fb0a48aae052a35c8e95c7 tool-data/bowtie_indices_color.loc.sample
--- a/tool-data/bowtie_indices_color.loc.sample
+++ b/tool-data/bowtie_indices_color.loc.sample
@@ -5,7 +5,7 @@
#the directories in which those files are stored. The bowtie_indices.loc
#file has this format (longer white space characters are TAB characters):
#
-#<unique_build_id><dbkey><display_name><file_base_path>
+#<unique_build_id><dbkey><display_name><file_base_path>
#
#So, for example, if you had hg18 indexed stored in
#/depot/data2/galaxy/bowtie/hg18/,
@@ -25,9 +25,9 @@
#index set you have stored. The "file" in the path does not actually
#exist, but it is the prefix for the actual index files. For example:
#
-#hg18canon hg18 hg18 Canonical /depot/data2/galaxy/bowtie/hg18/hg18canon
-#hg18full hg18 hg18 Full /depot/data2/galaxy/bowtie/hg18/hg18full
-#/orig/path/hg19 hg19 hg19 /depot/data2/galaxy/bowtie/hg19/hg19
+#hg18canon hg18 hg18 Canonical /depot/data2/galaxy/bowtie/hg18/hg18canon
+#hg18full hg18 hg18 Full /depot/data2/galaxy/bowtie/hg18/hg18full
+#/orig/path/hg19 hg19 hg19 /depot/data2/galaxy/bowtie/hg19/hg19
#...etc...
#
#Note that for backwards compatibility with workflows, the unique ID of
diff -r 732c10115fdf807ada88bf83cfe8a03f0c1c599e -r 463fc935b97cf697f0fb0a48aae052a35c8e95c7 tool-data/bwa_index.loc.sample
--- a/tool-data/bwa_index.loc.sample
+++ b/tool-data/bwa_index.loc.sample
@@ -25,10 +25,10 @@
#index set you have stored. The "file" in the path does not actually
#exist, but it is the prefix for the actual index files. For example:
#
-#phiX174 phiX phiX174 /depot/data2/galaxy/phiX/base/phiX.fa
-#hg18canon hg18 hg18 Canonical /depot/data2/galaxy/hg18/base/hg18canon.fa
-#hg18full hg18 hg18 Full /depot/data2/galaxy/hg18/base/hg18full.fa
-#/orig/path/hg19.fa hg19 hg19 /depot/data2/galaxy/hg19/base/hg19.fa
+#phiX174 phiX phiX174 /depot/data2/galaxy/phiX/base/phiX.fa
+#hg18canon hg18 hg18 Canonical /depot/data2/galaxy/hg18/base/hg18canon.fa
+#hg18full hg18 hg18 Full /depot/data2/galaxy/hg18/base/hg18full.fa
+#/orig/path/hg19.fa hg19 hg19 /depot/data2/galaxy/hg19/base/hg19.fa
#...etc...
#
#Note that for backwards compatibility with workflows, the unique ID of
diff -r 732c10115fdf807ada88bf83cfe8a03f0c1c599e -r 463fc935b97cf697f0fb0a48aae052a35c8e95c7 tool-data/bwa_index_color.loc.sample
--- a/tool-data/bwa_index_color.loc.sample
+++ b/tool-data/bwa_index_color.loc.sample
@@ -5,7 +5,7 @@
#the directories in which those files are stored. The bwa_index_color.loc
#file has this format (longer white space characters are TAB characters):
#
-#<unique_build_id><dbkey><display_name><file_path>
+#<unique_build_id><dbkey><display_name><file_path>
#
#So, for example, if you had phiX indexed stored in
#/depot/data2/galaxy/phiX/color/,
@@ -25,10 +25,10 @@
#index set you have stored. The "file" in the path does not actually
#exist, but it is the prefix for the actual index files. For example:
#
-#phiX174 phiX phiX174 /depot/data2/galaxy/phiX/color/phiX.fa
-#hg18canon hg18 hg18 Canonical /depot/data2/galaxy/hg18/color/hg18canon.fa
-#hg18full hg18 hg18 Full /depot/data2/galaxy/hg18/color/hg18full.fa
-#/orig/path/hg19.fa hg19 hg19 /depot/data2/galaxy/hg19/color/hg19.fa
+#phiX174 phiX phiX174 /depot/data2/galaxy/phiX/color/phiX.fa
+#hg18canon hg18 hg18 Canonical /depot/data2/galaxy/hg18/color/hg18canon.fa
+#hg18full hg18 hg18 Full /depot/data2/galaxy/hg18/color/hg18full.fa
+#/orig/path/hg19.fa hg19 hg19 /depot/data2/galaxy/hg19/color/hg19.fa
#...etc...
#
#Note that for backwards compatibility with workflows, the unique ID of
diff -r 732c10115fdf807ada88bf83cfe8a03f0c1c599e -r 463fc935b97cf697f0fb0a48aae052a35c8e95c7 tool-data/faseq.loc.sample
--- a/tool-data/faseq.loc.sample
+++ b/tool-data/faseq.loc.sample
@@ -20,7 +20,7 @@
#Your faseq.loc file should include an entry per line for each set of fasta
#sequence files you have stored. For example:
#
-#hg18 /depot/data2/galaxy/faseq/hg18
-#mm9 /depot/data2/galaxy/faseq/mm9
-#Arabidopsis /depot/data2/galaxy/faseq/Arabidopsis
+#hg18 /depot/data2/galaxy/faseq/hg18
+#mm9 /depot/data2/galaxy/faseq/mm9
+#Arabidopsis /depot/data2/galaxy/faseq/Arabidopsis
#...etc...
diff -r 732c10115fdf807ada88bf83cfe8a03f0c1c599e -r 463fc935b97cf697f0fb0a48aae052a35c8e95c7 tool-data/gatk_sorted_picard_index.loc.sample
--- a/tool-data/gatk_sorted_picard_index.loc.sample
+++ b/tool-data/gatk_sorted_picard_index.loc.sample
@@ -5,13 +5,13 @@
#the directories in which those files are stored. The picard_index.loc
#file has this format (longer white space is the TAB character):
#
-#<unique_build_id><dbkey><display_name><fasta_file_path>
+#<unique_build_id><dbkey><display_name><fasta_file_path>
#
#So, for example, if you had hg18 indexed and stored in
-#/depot/data2/galaxy/srma/hg18/,
+#/depot/data2/galaxy/srma/hg18/,
#then the srma_index.loc entry would look like this:
#
-#hg18 hg18 hg18 Pretty /depot/data2/galaxy/picard/hg18/hg18.fa
+#hg18 hg18 hg18 Pretty /depot/data2/galaxy/picard/hg18/hg18.fa
#
#and your /depot/data2/galaxy/srma/hg18/ directory
#would contain the following three files:
diff -r 732c10115fdf807ada88bf83cfe8a03f0c1c599e -r 463fc935b97cf697f0fb0a48aae052a35c8e95c7 tool-data/gd.chrlens.loc.sample
--- a/tool-data/gd.chrlens.loc.sample
+++ b/tool-data/gd.chrlens.loc.sample
@@ -6,17 +6,17 @@
# file has the following format (white space characters are TAB
# characters):
#
-#<species><reference_species_file_path>
+#<species><reference_species_file_path>
#
# So, for example, if you used Monodelphis domestica as the reference
# species for a collection of Sarcophilus harrisii SNPs, then the
# gd.chrlens.loc entry would look like this:
#
-#tasmanian_devil /galaxy/data/location/gd/chrlens/mondom_chr_lengths.txt
+#tasmanian_devil /galaxy/data/location/gd/chrlens/mondom_chr_lengths.txt
#
# Your gd.chrlens.loc file should include an entry for each pair of
# species SNPs and reference species. For example:
#
-#bighorn /galaxy/data/location/gd/chrlens/cow_chr_lengths.txt
-#tasmanian_devil /galaxy/data/location/gd/chrlens/mondom_chr_lengths.txt
+#bighorn /galaxy/data/location/gd/chrlens/cow_chr_lengths.txt
+#tasmanian_devil /galaxy/data/location/gd/chrlens/mondom_chr_lengths.txt
#...etc...
diff -r 732c10115fdf807ada88bf83cfe8a03f0c1c599e -r 463fc935b97cf697f0fb0a48aae052a35c8e95c7 tool-data/gd.primers.loc.sample
--- a/tool-data/gd.primers.loc.sample
+++ b/tool-data/gd.primers.loc.sample
@@ -5,18 +5,18 @@
# primers files are stored. The gd.primers.loc file has the following
# format (white space characters are TAB characters):
#
-#<species><primers_file_path>
+#<species><primers_file_path>
#
# So, for example, if you had a primers file located at
# /galaxy/data/location/gd/primers/bighorn_primers.txt for a collection of
# Ovis canadensis SNPs, then the gd.primers.loc entry would look like
# this:
#
-#bighorn /galaxy/data/location/gd/primers/bighorn_primers.txt
+#bighorn /galaxy/data/location/gd/primers/bighorn_primers.txt
#
# Your gd.primers.loc file should include an entry for each pair of
# species SNPs and primers file. For example:
#
-#bighorn /galaxy/data/location/gd/primers/bighorn_primers.txt
-#tasmanian_devil /galaxy/data/location/gd/primers/tasmanian_devil_primers.txt
+#bighorn /galaxy/data/location/gd/primers/bighorn_primers.txt
+#tasmanian_devil /galaxy/data/location/gd/primers/tasmanian_devil_primers.txt
#...etc...
diff -r 732c10115fdf807ada88bf83cfe8a03f0c1c599e -r 463fc935b97cf697f0fb0a48aae052a35c8e95c7 tool-data/gd.snps.loc.sample
--- a/tool-data/gd.snps.loc.sample
+++ b/tool-data/gd.snps.loc.sample
@@ -5,17 +5,17 @@
# SNP call files are stored. The gd.snps.loc file has the following
# format (white space characters are TAB characters):
#
-#<species><SNP_call_file_path>
+#<species><SNP_call_file_path>
#
# So, for example, if you had a SNP call file located at
# /galaxy/data/location/gd/snps/bighorn_snps.txt for a collection of
# Ovis canadensis SNPs, then the gd.snps.loc entry would look like this:
#
-#bighorn /galaxy/data/location/gd/snps/bighorn_snps.txt
+#bighorn /galaxy/data/location/gd/snps/bighorn_snps.txt
#
# Your gd.snps.loc file should include an entry for each pair of species
# SNPs and SNP call file. For example:
#
-#bighorn /galaxy/data/location/gd/snps/bighorn_snps.txt
-#tasmanian_devil /galaxy/data/location/gd/snps/tasmanian_devil_snps.txt
+#bighorn /galaxy/data/location/gd/snps/bighorn_snps.txt
+#tasmanian_devil /galaxy/data/location/gd/snps/tasmanian_devil_snps.txt
#...etc...
diff -r 732c10115fdf807ada88bf83cfe8a03f0c1c599e -r 463fc935b97cf697f0fb0a48aae052a35c8e95c7 tool-data/lastz_seqs.loc.sample
--- a/tool-data/lastz_seqs.loc.sample
+++ b/tool-data/lastz_seqs.loc.sample
@@ -5,13 +5,13 @@
#the directories in which those files are stored. The lastz_seqs.loc
#file has this format (white space characters are TAB characters):
#
-#<unique_build_id><display_name><file_path>
+#<unique_build_id><display_name><file_path>
#
#So, for example, if your lastz_seqs.loc began like this:
#
-#hg18 Human (Homo sapiens): hg18 /depot/data2/galaxy/twobit/hg18.2bit
-#hg19 Human (Homo sapiens): hg19 /depot/data2/galaxy/twobit/hg19.2bit
-#mm9 Mouse (Mus musculus): mm9 /depot/data2/galaxy/twobit/mm9.2bit
+#hg18 Human (Homo sapiens): hg18 /depot/data2/galaxy/twobit/hg18.2bit
+#hg19 Human (Homo sapiens): hg19 /depot/data2/galaxy/twobit/hg19.2bit
+#mm9 Mouse (Mus musculus): mm9 /depot/data2/galaxy/twobit/mm9.2bit
#
#then your /depot/data2/galaxy/twobit/ directory
#would need to contain the following 2bit files:
diff -r 732c10115fdf807ada88bf83cfe8a03f0c1c599e -r 463fc935b97cf697f0fb0a48aae052a35c8e95c7 tool-data/liftOver.loc.sample
--- a/tool-data/liftOver.loc.sample
+++ b/tool-data/liftOver.loc.sample
@@ -8,7 +8,7 @@
#located at /depot/data2/galaxy/anoCar1/liftOver/anoCar1ToGalGal3.over.chain,
#then the liftOver.loc entry would look like this:
#
-#anoCar1 galGal3 /depot/data2/galaxy/anoCar1/liftOver/anoCar1ToGalGal3.over.chain
+#anoCar1 galGal3 /depot/data2/galaxy/anoCar1/liftOver/anoCar1ToGalGal3.over.chain
#
#and your /depot/data2/galaxy/anoCar1/liftOver directory would
#contain all of your "chain" files (e.g.):
diff -r 732c10115fdf807ada88bf83cfe8a03f0c1c599e -r 463fc935b97cf697f0fb0a48aae052a35c8e95c7 tool-data/mosaik_index.loc.sample
--- a/tool-data/mosaik_index.loc.sample
+++ b/tool-data/mosaik_index.loc.sample
@@ -5,13 +5,13 @@
#the directories in which those files are stored. The mosaik_index.loc
#file has this format (longer white space is the TAB character):
#
-#<unique_build_id><dbkey><display_name><fasta_file_path>
+#<unique_build_id><dbkey><display_name><fasta_file_path>
#
#So, for example, if you had hg18 indexed and stored in
#/depot/data2/galaxy/mosaik/hg18/
#then the mosaik_index.loc entry would look like this:
#
-#hg18 hg18 hg18 Pretty /depot/data2/galaxy/mosaik/hg18/hg18.fa
+#hg18 hg18 hg18 Pretty /depot/data2/galaxy/mosaik/hg18/hg18.fa
#
#and your /depot/data2/galaxy/mosaik/hg18/ directory
#would contain the following files:
diff -r 732c10115fdf807ada88bf83cfe8a03f0c1c599e -r 463fc935b97cf697f0fb0a48aae052a35c8e95c7 tool-data/ngs_sim_fasta.loc.sample
--- a/tool-data/ngs_sim_fasta.loc.sample
+++ b/tool-data/ngs_sim_fasta.loc.sample
@@ -4,17 +4,17 @@
#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>
+#<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
+#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
+#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
diff -r 732c10115fdf807ada88bf83cfe8a03f0c1c599e -r 463fc935b97cf697f0fb0a48aae052a35c8e95c7 tool-data/perm_base_index.loc.sample
--- a/tool-data/perm_base_index.loc.sample
+++ b/tool-data/perm_base_index.loc.sample
@@ -5,7 +5,7 @@
#the directories in which those files are stored. The perm_base_index.loc
#file has this format (longer white space characters are TAB characters):
#
-#<build_seed_readlength><display_name><file_base>
+#<build_seed_readlength><display_name><file_base>
#
#Because each PerM index is built with a specific seed and a specific read
#length, this needs to be specified so the user can choose the appropriate
@@ -13,7 +13,7 @@
#50, and stored in /depot/data/galaxy/phiX/perm_index/,
#then the perm_base_index.loc entry would look something like this:
#
-#phiX_F3_50 phiX: seed=F3, read length=50 /depot/data/galaxy/phiX/perm_index/phiX_base_F3_50.index
+#phiX_F3_50 phiX: seed=F3, read length=50 /depot/data/galaxy/phiX/perm_index/phiX_base_F3_50.index
#
#and your /depot/data/galaxy/phiX/perm_index/ directory
#would contain the file phiX_base_F3_50.index:
@@ -21,7 +21,7 @@
#Your perm_base_index.loc file should include an entry per line for each
#index set you have stored. For example:
#
-#phiX_F3_50 phiX: seed=F3, read length=50 /data/galaxy/phiX/perm_index/phiX_base_F3_50.index
-#phiX_F4_50 phiX: seed=F4, read length=50 /data/galaxy/phiX/perm_index/phiX_base_F3_50.index
-#hg19_F3_50 hg19: seed=F3, read length=50 /data/galaxy/hg19/perm_index/hg19_base_F3_50.index
-#hg19_F4_50 hg19: seed=F4, read length=50 /data/galaxy/hg19/perm_index/hg19_base_F3_50.index
+#phiX_F3_50 phiX: seed=F3, read length=50 /data/galaxy/phiX/perm_index/phiX_base_F3_50.index
+#phiX_F4_50 phiX: seed=F4, read length=50 /data/galaxy/phiX/perm_index/phiX_base_F3_50.index
+#hg19_F3_50 hg19: seed=F3, read length=50 /data/galaxy/hg19/perm_index/hg19_base_F3_50.index
+#hg19_F4_50 hg19: seed=F4, read length=50 /data/galaxy/hg19/perm_index/hg19_base_F3_50.index
diff -r 732c10115fdf807ada88bf83cfe8a03f0c1c599e -r 463fc935b97cf697f0fb0a48aae052a35c8e95c7 tool-data/perm_color_index.loc.sample
--- a/tool-data/perm_color_index.loc.sample
+++ b/tool-data/perm_color_index.loc.sample
@@ -5,7 +5,7 @@
#the directories in which those files are stored. The perm_color_index.loc
#file has this format (white space characters are TAB characters):
#
-#<build_seed_readlength><display_name><file_base>
+#<build_seed_readlength><display_name><file_base>
#
#Because each PerM index is built with a specific seed and a specific read
#length, this needs to be specified so the user can choose the appropriate
@@ -13,7 +13,7 @@
#50, and stored in /depot/data/galaxy/phiX/perm_index/,
#then the perm_color_index.loc entry would look something like this:
#
-#phiX_F3_50 phiX: seed=F3, read length=50 /data/galaxy/phiX/perm_index/phiX_color_F3_50.index
+#phiX_F3_50 phiX: seed=F3, read length=50 /data/galaxy/phiX/perm_index/phiX_color_F3_50.index
#
#and your /depot/data/galaxy/phiX/perm_index/ directory
#would contain the file phiX_color_F3_50.index:
@@ -21,8 +21,8 @@
#Your perm_color_index.loc file should include an entry per line for each
#index set you have stored. For example:
#
-#phiX_F3_50 phiX: seed=F3, read length=50 /data/galaxy/phiX/perm_index/phiX_color_F3_50.index
-#phiX_F4_50 phiX: seed=F4, read length=50 /data/galaxy/phiX/perm_index/phiX_color_F3_50.index
-#hg19_F3_50 hg19: seed=F3, read length=50 /data/galaxy/hg19/perm_index/hg19_color_F3_50.index
-#hg19_F4_50 hg19: seed=F4, read length=50 /data/galaxy/hg19/perm_index/hg19_color_F3_50.index
+#phiX_F3_50 phiX: seed=F3, read length=50 /data/galaxy/phiX/perm_index/phiX_color_F3_50.index
+#phiX_F4_50 phiX: seed=F4, read length=50 /data/galaxy/phiX/perm_index/phiX_color_F3_50.index
+#hg19_F3_50 hg19: seed=F3, read length=50 /data/galaxy/hg19/perm_index/hg19_color_F3_50.index
+#hg19_F4_50 hg19: seed=F4, read length=50 /data/galaxy/hg19/perm_index/hg19_color_F3_50.index
#
diff -r 732c10115fdf807ada88bf83cfe8a03f0c1c599e -r 463fc935b97cf697f0fb0a48aae052a35c8e95c7 tool-data/picard_index.loc.sample
--- a/tool-data/picard_index.loc.sample
+++ b/tool-data/picard_index.loc.sample
@@ -5,13 +5,13 @@
#the directories in which those files are stored. The picard_index.loc
#file has this format (longer white space is the TAB character):
#
-#<unique_build_id><dbkey><display_name><fasta_file_path>
+#<unique_build_id><dbkey><display_name><fasta_file_path>
#
#So, for example, if you had hg18 indexed and stored in
#/depot/data2/galaxy/srma/hg18/,
#then the srma_index.loc entry would look like this:
#
-#hg18 hg18 hg18 Pretty /depot/data2/galaxy/picard/hg18/hg18.fa
+#hg18 hg18 hg18 Pretty /depot/data2/galaxy/picard/hg18/hg18.fa
#
#and your /depot/data2/galaxy/srma/hg18/ directory
#would contain the following three files:
diff -r 732c10115fdf807ada88bf83cfe8a03f0c1c599e -r 463fc935b97cf697f0fb0a48aae052a35c8e95c7 tool-data/quality_scores.loc.sample
--- a/tool-data/quality_scores.loc.sample
+++ b/tool-data/quality_scores.loc.sample
@@ -8,7 +8,7 @@
#/depot/data2/galaxy/panTro2/quality_scores, then the quality_scores.loc entry
#would look like this:
#
-#panTro2 /depot/data2/galaxy/panTro2/quality_scores
+#panTro2 /depot/data2/galaxy/panTro2/quality_scores
#
#and your /depot/data2/galaxy/panTro2/quality_scores directory would
#contain all of your quality score files (e.g.):
diff -r 732c10115fdf807ada88bf83cfe8a03f0c1c599e -r 463fc935b97cf697f0fb0a48aae052a35c8e95c7 tool-data/regions.loc.sample
--- a/tool-data/regions.loc.sample
+++ b/tool-data/regions.loc.sample
@@ -8,7 +8,7 @@
#/depot/data2/galaxy/regions/encode_regions_coords_hg16.bed, then the
#regions.loc entry would look like this:
#
-#hg16 encode_hg16 ENCODE Regions /depot/data2/galaxy/regions/encode_regions_coords_hg16.bed
+#hg16 encode_hg16 ENCODE Regions /depot/data2/galaxy/regions/encode_regions_coords_hg16.bed
#
#and your /depot/data2/galaxy/regions/ directory would
#contain all of your regions files (e.g.):
diff -r 732c10115fdf807ada88bf83cfe8a03f0c1c599e -r 463fc935b97cf697f0fb0a48aae052a35c8e95c7 tool-data/srma_index.loc.sample
--- a/tool-data/srma_index.loc.sample
+++ b/tool-data/srma_index.loc.sample
@@ -8,13 +8,13 @@
#the directories in which those files are stored. The srma_index.loc
#file has this format (longer white space is the TAB character):
#
-#<unique_build_id><dbkey><display_name><fasta_file_path>
+#<unique_build_id><dbkey><display_name><fasta_file_path>
#
#So, for example, if you had hg18 indexed and stored in
#/depot/data2/galaxy/srma/hg18/,
#then the srma_index.loc entry would look like this:
#
-#hg18 hg18 hg18 Pretty /depot/data2/galaxy/srma/hg18/hg18.fa
+#hg18 hg18 hg18 Pretty /depot/data2/galaxy/srma/hg18/hg18.fa
#
#and your /depot/data2/galaxy/srma/hg18/ directory
#would contain the following three files:
diff -r 732c10115fdf807ada88bf83cfe8a03f0c1c599e -r 463fc935b97cf697f0fb0a48aae052a35c8e95c7 tool-data/twobit.loc.sample
--- a/tool-data/twobit.loc.sample
+++ b/tool-data/twobit.loc.sample
@@ -8,7 +8,7 @@
#/depot/data2/galaxy/droPer1/, then the twobit.loc entry
#would look like this:
#
-#droPer1 /depot/data2/galaxy/droPer1/droPer1.2bit
+#droPer1 /depot/data2/galaxy/droPer1/droPer1.2bit
#
#and your /depot/data2/galaxy/droPer1/ directory would
#contain all of your twobit files (e.g.):
@@ -19,8 +19,8 @@
#Your twobit.loc file should include an entry per line for each twobit
#file you have stored. For example:
#
-#droPer1 /depot/data2/galaxy/droPer1/droPer1.2bit
-#apiMel2 /depot/data2/galaxy/apiMel2/apiMel2.2bit
-#droAna1 /depot/data2/galaxy/droAna1/droAna1.2bit
-#droAna2 /depot/data2/galaxy/droAna2/droAna2.2bit
+#droPer1 /depot/data2/galaxy/droPer1/droPer1.2bit
+#apiMel2 /depot/data2/galaxy/apiMel2/apiMel2.2bit
+#droAna1 /depot/data2/galaxy/droAna1/droAna1.2bit
+#droAna2 /depot/data2/galaxy/droAna2/droAna2.2bit
#...etc...
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0