├── img ├── new.png ├── fathmm.png ├── favicon.ico ├── pubmed.png ├── sort_asc.png ├── sort_both.png ├── sort_desc.png ├── sort_asc_disabled.png ├── sort_desc_disabled.png ├── glyphicons-halflings.png └── glyphicons-halflings-white.png ├── tmp └── .nothing ├── .gitignore ├── css ├── fathmm.css ├── Data-Table.css └── bootstrap-responsive.css ├── CHANGES.md ├── parseVCF.py ├── cgi-bin ├── submit.cgi ├── results.cgi └── fathmm.py ├── README.md ├── update.html ├── js ├── Data-Table.js ├── jquery.flot.crosshair.js └── bootstrap.min.js ├── index.html ├── about.html ├── disease.html ├── inherited.html └── cancer.html /img/new.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HAShihab/fathmm/HEAD/img/new.png -------------------------------------------------------------------------------- /img/fathmm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HAShihab/fathmm/HEAD/img/fathmm.png -------------------------------------------------------------------------------- /img/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HAShihab/fathmm/HEAD/img/favicon.ico -------------------------------------------------------------------------------- /img/pubmed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HAShihab/fathmm/HEAD/img/pubmed.png -------------------------------------------------------------------------------- /img/sort_asc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HAShihab/fathmm/HEAD/img/sort_asc.png -------------------------------------------------------------------------------- /img/sort_both.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HAShihab/fathmm/HEAD/img/sort_both.png -------------------------------------------------------------------------------- /img/sort_desc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HAShihab/fathmm/HEAD/img/sort_desc.png -------------------------------------------------------------------------------- /tmp/.nothing: -------------------------------------------------------------------------------- 1 | # 2 | # An Empty File To Force GitHub To Create The ./tmp Directory 3 | # 4 | -------------------------------------------------------------------------------- /img/sort_asc_disabled.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HAShihab/fathmm/HEAD/img/sort_asc_disabled.png -------------------------------------------------------------------------------- /img/sort_desc_disabled.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HAShihab/fathmm/HEAD/img/sort_desc_disabled.png -------------------------------------------------------------------------------- /img/glyphicons-halflings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HAShihab/fathmm/HEAD/img/glyphicons-halflings.png -------------------------------------------------------------------------------- /img/glyphicons-halflings-white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HAShihab/fathmm/HEAD/img/glyphicons-halflings-white.png -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Database Configuration 2 | config.ini 3 | 4 | # Server Submission(s) 5 | *.txt 6 | *.tab 7 | 8 | # Site Verification 9 | *1704* 10 | sitemap* 11 | -------------------------------------------------------------------------------- /css/fathmm.css: -------------------------------------------------------------------------------- 1 | 2 | body { 3 | padding-top: 105px; 4 | text-align: justify; 5 | } 6 | footer { 7 | font-size: 10px; 8 | text-align: center; 9 | } 10 | a:hover { 11 | text-decoration: none; 12 | } 13 | 14 | .navbar, 15 | .navbar .nav > li > a:focus, 16 | .navbar .nav > li > a:hover { 17 | background-color: transparent; 18 | border-color: transparent; 19 | } 20 | .navbar .nav > .active > a, 21 | .navbar .nav > .active > a:hover, 22 | .navbar .nav > .active > a:focus { 23 | background-color: transparent; 24 | border-color: transparent; 25 | outline: none; 26 | -webkit-box-shadow: none; 27 | -moz-box-shadow: none; 28 | box-shadow: none; 29 | } 30 | .nav-tabs > .active > a, .nav-tabs > .active > a:hover { 31 | outline: none; 32 | } 33 | .modal, .btn-large { 34 | outline: none; 35 | } 36 | 37 | .tab-content { 38 | overflow-x: hidden; 39 | } 40 | -------------------------------------------------------------------------------- /CHANGES.md: -------------------------------------------------------------------------------- 1 | fathmm 2 | ====== 3 | 4 | This page is a continuous listing of new features and bug fixes for the 5 | Functional Analysis through Hidden Markov Models software and server 6 | (http://fathmm.biocompute.org.uk). 7 | 8 | ## 5th July 2013 (v2.2) 9 | 10 | * A new method for ranking nsSNPs according to disease concepts, i.e. disease-specific predictions, has been added. 11 | * We now limit the number of web-based predictions shown; however, all predictions can be obtained in our tab-delimited report. 12 | * We have fixed a number of small bugs. 13 | 14 | * Human: updated pre-computed database to ENSEMBL 72, UniProt 2013_07, and RefSeq 59. 15 | 16 | ## 10th May 2013 (v2.2) 17 | 18 | * We now use the Representative Proteome (RP) database when searching for homologous sequences. 19 | * We now incorporate Pfam 27.0 into our domain-based predictions. 20 | * We have fixed a minor database bug. 21 | 22 | * Human: updated pre-computed database to ENSEMBL 71, UniProt 2013_05, and RefSeq 59. 23 | -------------------------------------------------------------------------------- /parseVCF.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python -u 2 | 3 | import os 4 | import argparse 5 | 6 | # 7 | if __name__ == '__main__': 8 | # 9 | 10 | parser = argparse.ArgumentParser( 11 | description = """ 12 | This program will parse the annotations provided by the Ensembl Variant Predictor (VEP) 13 | and create a list of protein consequences which can then be submitted to the 14 | Functional Analysis through Hidden Markov Models (FATHMM) software and server. 15 | """, 16 | epilog = """ 17 | Note: in order for this script to work, the VEP must be called using the additional --protein parameter. 18 | """, 19 | ) 20 | 21 | group = parser.add_argument_group('required arguments') 22 | group.add_argument( 23 | "-i", 24 | dest = "input", 25 | help = "a file containing the VEP annotations to parse", 26 | metavar = "", 27 | default = None, 28 | required = True 29 | ) 30 | group.add_argument( 31 | "-o", 32 | dest = "output", 33 | help = "where the protein consequences should be written to", 34 | metavar = "", 35 | default = None, 36 | required = True 37 | ) 38 | 39 | arguments = parser.parse_args() 40 | 41 | # 42 | 43 | try: 44 | Consequence = {} 45 | 46 | for record in open(arguments.input, "r"): 47 | if record.startswith("#") or not record.find("missense_variant") >= 0: 48 | continue 49 | record = record.strip().split("\t") 50 | 51 | x = record[10].split("/") 52 | Var = x[0] + record[9] + x[1] 53 | Info = dict([ x.split("=") for x in record[-1].split(";") ]) 54 | 55 | if not Info.has_key("ENSP"): 56 | continue 57 | 58 | if not Consequence.has_key(Info['ENSP']): 59 | Consequence[Info['ENSP']] = [] 60 | Consequence[Info['ENSP']].append(Var) 61 | 62 | Processed = open(arguments.output, "w") 63 | for id in Consequence: 64 | Processed.write(id + " " + ",".join(set(Consequence[id])) + "\n") 65 | # 66 | except: 67 | raise 68 | -------------------------------------------------------------------------------- /cgi-bin/submit.cgi: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python -u 2 | 3 | import os 4 | import sys 5 | import time 6 | import uuid 7 | import shlex 8 | import subprocess 9 | import traceback 10 | 11 | import cgi 12 | import cgitb; cgitb.enable() 13 | 14 | # 15 | if __name__ == '__main__': 16 | print "Content-Type: text/html" 17 | print 18 | 19 | try: 20 | HTMLForm = cgi.FieldStorage() 21 | HTMLTime = time.gmtime() 22 | HTMLSession = None 23 | 24 | while True: 25 | HTMLSession = str(uuid.uuid4()) 26 | if not os.path.exists("../tmp/" + HTMLSession + ".txt"): 27 | break 28 | 29 | Data = [] 30 | Data.append("# IP: " + str(os.environ['REMOTE_ADDR'])) 31 | Data.append("# Date: " + time.strftime("%d-%m-%Y", HTMLTime)) 32 | Data.append("# Time: " + time.strftime("%H:%M:%S", HTMLTime)) 33 | Data.append("# Weights: " + str(HTMLForm['weighted'].value)) 34 | 35 | if HTMLForm.has_key("threshold") and HTMLForm['threshold'].value: 36 | Data.append("# Threshold: " + str(HTMLForm['threshold'].value)) 37 | if HTMLForm.has_key("phenotypes") and HTMLForm['phenotypes'].value: 38 | Data.append("# Phenotypes: " + str(HTMLForm['phenotypes'].value)) 39 | 40 | Data.append(str(HTMLForm['batch'].value.strip())) 41 | 42 | open("../tmp/" + HTMLSession + ".txt", "w").write( 43 | "\n".join(Data) 44 | ) 45 | 46 | run = "python fathmm.py ../tmp/{0}.txt /tmp/{0}.tab -w {1} ".format(HTMLSession, str(HTMLForm['weighted'].value)) 47 | if HTMLForm.has_key("threshold") and HTMLForm['threshold'].value: 48 | run += "-t {0} ".format(str(HTMLForm['threshold'].value)) 49 | if HTMLForm.has_key("phenotypes") and HTMLForm['phenotypes'].value: 50 | run += "-p {0} ".format(str(HTMLForm['phenotypes'].value)) 51 | 52 | mv = "mv /tmp/{0}.tab ../tmp/{0}.tab".format(HTMLSession) 53 | 54 | #print str(HTMLForm) + "
" 55 | #print run + "
" 56 | #print mv 57 | 58 | pid = subprocess.Popen("{0}; {1}".format(run, mv), 59 | shell = True, 60 | stdin = subprocess.PIPE, 61 | stdout = subprocess.PIPE, 62 | stderr = subprocess.STDOUT, 63 | close_fds = True 64 | ) 65 | 66 | print """ 67 | 68 | 69 | 70 | fathmm - New Submission 71 | 76 | 77 | 78 |   79 | 80 | 81 | """ 82 | except Exception, e: 83 | raise 84 | 85 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | fathmm 2 | ====== 3 | 4 | This is the source code for the Functional Analysis through Hidden Markov Models 5 | software and server (http://fathmm.biocompute.org.uk). 6 | 7 | ## General Requirements 8 | 9 | You will need the following packages installed on your system: 10 | 11 | * MySQL 12 | * Python & Python MySQLdb (tested with Python 2.6/2.7) 13 | 14 | ## Setup: 15 | 16 | * Our pre-computed database can be found at http://fathmm.biocompute.org.uk/database/fathmm.v2.3.SQL.gz (instructions on how to create/upload the database can be found at http://fathmm.biocompute.org.uk/database/INSTALL) 17 | * Create a configuration file named "config.ini" and enter the following (substituting 18 | the required information with your MySQL credentials): 19 | 20 | ``` 21 | [DATABASE] 22 | HOST = [MySQL Host] 23 | PORT = [MySQL Port] 24 | USER = [MySQL Username] 25 | PASSWD = [MySQL Password] 26 | DB = fathmm 27 | ``` 28 | * Download "fathmm.py" from the ./cgi-bin folder and place it in the same directory as "config.ini" 29 | 30 | ## Running our Software 31 | 32 | In it's simplest form, our software parses dbSNP rs IDs and protein missense 33 | mutations from \ and returns a list of predictions weighted for 34 | inherited-disease mutations (Human) in \. Furthermore, we return predictions 35 | on disease-associations when a mutation falls within a SUPERFAMILY domain. 36 | 37 | ``` 38 | python fathmm.py -i -o 39 | ``` 40 | 41 | A combination of the below is accepted/valid input: 42 | 43 | * Human dbSNP rs IDs (dbSNP 137) - multiple SNPs should be entered on separate lines. 44 | * Human SwissProt/TrEMBL and/or Ensembl protein identifiers followed by the amino acid substitution in the conventional one letter format - multiple substitutions can be entered on a single line and should be separated by a comma. 45 | 46 | ``` 47 | rs137854462 48 | rs28936683 49 | rs121908258 50 | rs17132395 51 | rs121912297 52 | P43026 L441P 53 | P35555 N548I,E1073K,C2307S 54 | ``` 55 | 56 | ## Optional Parameters 57 | 58 | The --help parameter can be used to view additional program parameters. In brief, 59 | there are two optional parameters: 60 | 61 | * -w [?] 62 | 63 | An optional parameter which controls the prediction algorithm used in our software: 64 | 65 | ``` 66 | Inherited : return predictions weighted for human inherited-disease mutations [this is the default] 67 | Unweighted : return unweighted (species-independant) predictions 68 | Cancer : return predictions weighted specifically for Human cancer 69 | ``` 70 | 71 | * -p [?] 72 | 73 | An optional parameter which controls the phenotype ontology used in our software: 74 | 75 | ``` 76 | DO : Disease Ontology [this is the default] 77 | GO : Gene Ontology 78 | HP : Human Phenotype Ontology 79 | MP : Mouse Phenotype Ontology 80 | WP : Worm Phenotype Ontology 81 | YP : Yeast Phenotype Ontology 82 | FP : Fly Phenotype Ontology 83 | FA : Fly Anatomy Ontology 84 | ZA : Zebrafish Anatomy Ontology 85 | AP : Arabidopsis Plant Ontology 86 | KW : UniProtKB KeyWords 87 | ``` 88 | 89 | ## Contributing: 90 | 91 | We welcome any comments and/or suggestions that you may have regarding our software and server - please send an email directly to fathmm@biocompute.org.uk 92 | -------------------------------------------------------------------------------- /update.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | fathmm - Server Down 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 43 | 44 | 45 | 46 |
47 | 59 | 60 |
61 |

Server Unavailable

62 |
63 |

64 | Our server is temporarily unavailable for apporx. 1 hour due to scheduled maintenance - we apologise for any inconvenience this may cause. 65 |

66 |
67 | 68 |
69 | 79 | 80 |
81 | 82 | 83 | -------------------------------------------------------------------------------- /css/Data-Table.css: -------------------------------------------------------------------------------- 1 | 2 | div.dataTables_length label { 3 | float: left; 4 | text-align: left; 5 | } 6 | 7 | div.dataTables_length select { 8 | width: 75px; 9 | } 10 | 11 | div.dataTables_filter label { 12 | float: right; 13 | } 14 | 15 | div.dataTables_info { 16 | padding-top: 8px; 17 | } 18 | 19 | div.dataTables_paginate { 20 | float: right; 21 | margin: 0; 22 | } 23 | 24 | table.table { 25 | clear: both; 26 | margin-bottom: 6px !important; 27 | max-width: none !important; 28 | } 29 | 30 | table.table thead .sorting, 31 | table.table thead .sorting_asc, 32 | table.table thead .sorting_desc, 33 | table.table thead .sorting_asc_disabled, 34 | table.table thead .sorting_desc_disabled { 35 | cursor: pointer; 36 | *cursor: hand; 37 | } 38 | 39 | table.table thead .sorting { background: url('../img/sort_both.png') no-repeat center right; } 40 | table.table thead .sorting_asc { background: url('../img/sort_asc.png') no-repeat center right; } 41 | table.table thead .sorting_desc { background: url('../img/sort_desc.png') no-repeat center right; } 42 | 43 | table.table thead .sorting_asc_disabled { background: url('../img/sort_asc_disabled.png') no-repeat center right; } 44 | table.table thead .sorting_desc_disabled { background: url('../img/sort_desc_disabled.png') no-repeat center right; } 45 | 46 | table.dataTable th:active { 47 | outline: none; 48 | } 49 | 50 | /* Scrolling */ 51 | div.dataTables_scrollHead table { 52 | margin-bottom: 0 !important; 53 | border-bottom-left-radius: 0; 54 | border-bottom-right-radius: 0; 55 | } 56 | 57 | div.dataTables_scrollHead table thead tr:last-child th:first-child, 58 | div.dataTables_scrollHead table thead tr:last-child td:first-child { 59 | border-bottom-left-radius: 0 !important; 60 | border-bottom-right-radius: 0 !important; 61 | } 62 | 63 | div.dataTables_scrollBody table { 64 | border-top: none; 65 | margin-bottom: 0 !important; 66 | } 67 | 68 | div.dataTables_scrollBody tbody tr:first-child th, 69 | div.dataTables_scrollBody tbody tr:first-child td { 70 | border-top: none; 71 | } 72 | 73 | div.dataTables_scrollFoot table { 74 | border-top: none; 75 | } 76 | 77 | 78 | 79 | 80 | /* 81 | * TableTools styles 82 | */ 83 | .table tbody tr.active td, 84 | .table tbody tr.active th { 85 | background-color: #08C; 86 | color: white; 87 | } 88 | 89 | .table tbody tr.active:hover td, 90 | .table tbody tr.active:hover th { 91 | background-color: #0075b0 !important; 92 | } 93 | 94 | .table-striped tbody tr.active:nth-child(odd) td, 95 | .table-striped tbody tr.active:nth-child(odd) th { 96 | background-color: #017ebc; 97 | } 98 | 99 | table.DTTT_selectable tbody tr { 100 | cursor: pointer; 101 | *cursor: hand; 102 | } 103 | 104 | div.DTTT .btn { 105 | color: #333 !important; 106 | font-size: 12px; 107 | } 108 | 109 | div.DTTT .btn:hover { 110 | text-decoration: none !important; 111 | } 112 | 113 | 114 | ul.DTTT_dropdown.dropdown-menu a { 115 | color: #333 !important; /* needed only when demo_page.css is included */ 116 | } 117 | 118 | ul.DTTT_dropdown.dropdown-menu li:hover a { 119 | background-color: #0088cc; 120 | color: white !important; 121 | } 122 | 123 | /* TableTools information display */ 124 | div.DTTT_print_info.modal { 125 | height: 150px; 126 | margin-top: -75px; 127 | text-align: center; 128 | } 129 | 130 | div.DTTT_print_info h6 { 131 | font-weight: normal; 132 | font-size: 28px; 133 | line-height: 28px; 134 | margin: 1em; 135 | } 136 | 137 | div.DTTT_print_info p { 138 | font-size: 14px; 139 | line-height: 20px; 140 | } 141 | 142 | 143 | 144 | /* 145 | * FixedColumns styles 146 | */ 147 | div.DTFC_LeftHeadWrapper table, 148 | div.DTFC_LeftFootWrapper table, 149 | table.DTFC_Cloned tr.even { 150 | background-color: white; 151 | } 152 | 153 | div.DTFC_LeftHeadWrapper table { 154 | margin-bottom: 0 !important; 155 | border-top-right-radius: 0 !important; 156 | border-bottom-left-radius: 0 !important; 157 | border-bottom-right-radius: 0 !important; 158 | } 159 | 160 | div.DTFC_LeftHeadWrapper table thead tr:last-child th:first-child, 161 | div.DTFC_LeftHeadWrapper table thead tr:last-child td:first-child { 162 | border-bottom-left-radius: 0 !important; 163 | border-bottom-right-radius: 0 !important; 164 | } 165 | 166 | div.DTFC_LeftBodyWrapper table { 167 | border-top: none; 168 | margin-bottom: 0 !important; 169 | } 170 | 171 | div.DTFC_LeftBodyWrapper tbody tr:first-child th, 172 | div.DTFC_LeftBodyWrapper tbody tr:first-child td { 173 | border-top: none; 174 | } 175 | 176 | div.DTFC_LeftFootWrapper table { 177 | border-top: none; 178 | } 179 | -------------------------------------------------------------------------------- /js/Data-Table.js: -------------------------------------------------------------------------------- 1 | 2 | /* Set the defaults for DataTables initialisation */ 3 | $.extend( true, $.fn.dataTable.defaults, { 4 | "sDom": "<'row-fluid'<'span6'l><'span6'f>r>t<'row-fluid'<'span6'i><'span6'p>>", 5 | "sPaginationType": "bootstrap", 6 | "oLanguage": { 7 | "sLengthMenu": "_MENU_ records per page" 8 | } 9 | } ); 10 | 11 | 12 | /* Default class modification */ 13 | $.extend( $.fn.dataTableExt.oStdClasses, { 14 | "sWrapper": "dataTables_wrapper form-inline" 15 | } ); 16 | 17 | 18 | /* API method to get paging information */ 19 | $.fn.dataTableExt.oApi.fnPagingInfo = function ( oSettings ) 20 | { 21 | return { 22 | "iStart": oSettings._iDisplayStart, 23 | "iEnd": oSettings.fnDisplayEnd(), 24 | "iLength": oSettings._iDisplayLength, 25 | "iTotal": oSettings.fnRecordsTotal(), 26 | "iFilteredTotal": oSettings.fnRecordsDisplay(), 27 | "iPage": Math.ceil( oSettings._iDisplayStart / oSettings._iDisplayLength ), 28 | "iTotalPages": Math.ceil( oSettings.fnRecordsDisplay() / oSettings._iDisplayLength ) 29 | }; 30 | }; 31 | 32 | 33 | /* Bootstrap style pagination control */ 34 | $.extend( $.fn.dataTableExt.oPagination, { 35 | "bootstrap": { 36 | "fnInit": function( oSettings, nPaging, fnDraw ) { 37 | var oLang = oSettings.oLanguage.oPaginate; 38 | var fnClickHandler = function ( e ) { 39 | e.preventDefault(); 40 | if ( oSettings.oApi._fnPageChange(oSettings, e.data.action) ) { 41 | fnDraw( oSettings ); 42 | } 43 | }; 44 | 45 | $(nPaging).addClass('pagination').append( 46 | '' 50 | ); 51 | var els = $('a', nPaging); 52 | $(els[0]).bind( 'click.DT', { action: "previous" }, fnClickHandler ); 53 | $(els[1]).bind( 'click.DT', { action: "next" }, fnClickHandler ); 54 | }, 55 | 56 | "fnUpdate": function ( oSettings, fnDraw ) { 57 | var iListLength = 5; 58 | var oPaging = oSettings.oInstance.fnPagingInfo(); 59 | var an = oSettings.aanFeatures.p; 60 | var i, j, sClass, iStart, iEnd, iHalf=Math.floor(iListLength/2); 61 | 62 | if ( oPaging.iTotalPages < iListLength) { 63 | iStart = 1; 64 | iEnd = oPaging.iTotalPages; 65 | } 66 | else if ( oPaging.iPage <= iHalf ) { 67 | iStart = 1; 68 | iEnd = iListLength; 69 | } else if ( oPaging.iPage >= (oPaging.iTotalPages-iHalf) ) { 70 | iStart = oPaging.iTotalPages - iListLength + 1; 71 | iEnd = oPaging.iTotalPages; 72 | } else { 73 | iStart = oPaging.iPage - iHalf + 1; 74 | iEnd = iStart + iListLength - 1; 75 | } 76 | 77 | for ( i=0, iLen=an.length ; i'+j+'') 85 | .insertBefore( $('li:last', an[i])[0] ) 86 | .bind('click', function (e) { 87 | e.preventDefault(); 88 | oSettings._iDisplayStart = (parseInt($('a', this).text(),10)-1) * oPaging.iLength; 89 | fnDraw( oSettings ); 90 | } ); 91 | } 92 | 93 | // Add / remove disabled classes from the static elements 94 | if ( oPaging.iPage === 0 ) { 95 | $('li:first', an[i]).addClass('disabled'); 96 | } else { 97 | $('li:first', an[i]).removeClass('disabled'); 98 | } 99 | 100 | if ( oPaging.iPage === oPaging.iTotalPages-1 || oPaging.iTotalPages === 0 ) { 101 | $('li:last', an[i]).addClass('disabled'); 102 | } else { 103 | $('li:last', an[i]).removeClass('disabled'); 104 | } 105 | } 106 | } 107 | } 108 | } ); 109 | 110 | 111 | /* 112 | * TableTools Bootstrap compatibility 113 | * Required TableTools 2.1+ 114 | */ 115 | if ( $.fn.DataTable.TableTools ) { 116 | // Set the classes that TableTools uses to something suitable for Bootstrap 117 | $.extend( true, $.fn.DataTable.TableTools.classes, { 118 | "container": "DTTT btn-group", 119 | "buttons": { 120 | "normal": "btn", 121 | "disabled": "disabled" 122 | }, 123 | "collection": { 124 | "container": "DTTT_dropdown dropdown-menu", 125 | "buttons": { 126 | "normal": "", 127 | "disabled": "disabled" 128 | } 129 | }, 130 | "print": { 131 | "info": "DTTT_print_info modal" 132 | }, 133 | "select": { 134 | "row": "active" 135 | } 136 | } ); 137 | 138 | // Have the collection use a bootstrap compatible dropdown 139 | $.extend( true, $.fn.DataTable.TableTools.DEFAULTS.oTags, { 140 | "collection": { 141 | "container": "ul", 142 | "button": "li", 143 | "liner": "a" 144 | } 145 | } ); 146 | } 147 | 148 | 149 | /* Table initialisation */ 150 | $(document).ready(function() { 151 | $('#results').dataTable( { 152 | "sDom": "<'row'<'span6'l><'span6'f>r>t<'row'<'span6'i><'span6'p>>", 153 | "sPaginationType": "bootstrap", 154 | "oLanguage": { 155 | "sLengthMenu": "_MENU_ records per page" 156 | } 157 | } ); 158 | } ); 159 | -------------------------------------------------------------------------------- /js/jquery.flot.crosshair.js: -------------------------------------------------------------------------------- 1 | /* 2 | Flot plugin for showing crosshairs, thin lines, when the mouse hovers 3 | over the plot. 4 | 5 | crosshair: { 6 | mode: null or "x" or "y" or "xy" 7 | color: color 8 | lineWidth: number 9 | } 10 | 11 | Set the mode to one of "x", "y" or "xy". The "x" mode enables a 12 | vertical crosshair that lets you trace the values on the x axis, "y" 13 | enables a horizontal crosshair and "xy" enables them both. "color" is 14 | the color of the crosshair (default is "rgba(170, 0, 0, 0.80)"), 15 | "lineWidth" is the width of the drawn lines (default is 1). 16 | 17 | The plugin also adds four public methods: 18 | 19 | - setCrosshair(pos) 20 | 21 | Set the position of the crosshair. Note that this is cleared if 22 | the user moves the mouse. "pos" is in coordinates of the plot and 23 | should be on the form { x: xpos, y: ypos } (you can use x2/x3/... 24 | if you're using multiple axes), which is coincidentally the same 25 | format as what you get from a "plothover" event. If "pos" is null, 26 | the crosshair is cleared. 27 | 28 | - clearCrosshair() 29 | 30 | Clear the crosshair. 31 | 32 | - lockCrosshair(pos) 33 | 34 | Cause the crosshair to lock to the current location, no longer 35 | updating if the user moves the mouse. Optionally supply a position 36 | (passed on to setCrosshair()) to move it to. 37 | 38 | Example usage: 39 | var myFlot = $.plot( $("#graph"), ..., { crosshair: { mode: "x" } } }; 40 | $("#graph").bind("plothover", function (evt, position, item) { 41 | if (item) { 42 | // Lock the crosshair to the data point being hovered 43 | myFlot.lockCrosshair({ x: item.datapoint[0], y: item.datapoint[1] }); 44 | } 45 | else { 46 | // Return normal crosshair operation 47 | myFlot.unlockCrosshair(); 48 | } 49 | }); 50 | 51 | - unlockCrosshair() 52 | 53 | Free the crosshair to move again after locking it. 54 | */ 55 | 56 | (function ($) { 57 | var options = { 58 | crosshair: { 59 | mode: null, // one of null, "x", "y" or "xy", 60 | color: "rgba(170, 0, 0, 0.80)", 61 | lineWidth: 1 62 | } 63 | }; 64 | 65 | function init(plot) { 66 | // position of crosshair in pixels 67 | var crosshair = { x: -1, y: -1, locked: false }; 68 | 69 | plot.setCrosshair = function setCrosshair(pos) { 70 | if (!pos) 71 | crosshair.x = -1; 72 | else { 73 | var o = plot.p2c(pos); 74 | crosshair.x = Math.max(0, Math.min(o.left, plot.width())); 75 | crosshair.y = Math.max(0, Math.min(o.top, plot.height())); 76 | } 77 | 78 | plot.triggerRedrawOverlay(); 79 | }; 80 | 81 | plot.clearCrosshair = plot.setCrosshair; // passes null for pos 82 | 83 | plot.lockCrosshair = function lockCrosshair(pos) { 84 | if (pos) 85 | plot.setCrosshair(pos); 86 | crosshair.locked = true; 87 | } 88 | 89 | plot.unlockCrosshair = function unlockCrosshair() { 90 | crosshair.locked = false; 91 | } 92 | 93 | function onMouseOut(e) { 94 | if (crosshair.locked) 95 | return; 96 | 97 | if (crosshair.x != -1) { 98 | crosshair.x = -1; 99 | plot.triggerRedrawOverlay(); 100 | } 101 | } 102 | 103 | function onMouseMove(e) { 104 | if (crosshair.locked) 105 | return; 106 | 107 | if (plot.getSelection && plot.getSelection()) { 108 | crosshair.x = -1; // hide the crosshair while selecting 109 | return; 110 | } 111 | 112 | var offset = plot.offset(); 113 | crosshair.x = Math.max(0, Math.min(e.pageX - offset.left, plot.width())); 114 | crosshair.y = Math.max(0, Math.min(e.pageY - offset.top, plot.height())); 115 | plot.triggerRedrawOverlay(); 116 | } 117 | 118 | plot.hooks.bindEvents.push(function (plot, eventHolder) { 119 | if (!plot.getOptions().crosshair.mode) 120 | return; 121 | 122 | eventHolder.mouseout(onMouseOut); 123 | eventHolder.mousemove(onMouseMove); 124 | }); 125 | 126 | plot.hooks.drawOverlay.push(function (plot, ctx) { 127 | var c = plot.getOptions().crosshair; 128 | if (!c.mode) 129 | return; 130 | 131 | var plotOffset = plot.getPlotOffset(); 132 | 133 | ctx.save(); 134 | ctx.translate(plotOffset.left, plotOffset.top); 135 | 136 | if (crosshair.x != -1) { 137 | ctx.strokeStyle = c.color; 138 | ctx.lineWidth = c.lineWidth; 139 | ctx.lineJoin = "round"; 140 | 141 | ctx.beginPath(); 142 | if (c.mode.indexOf("x") != -1) { 143 | ctx.moveTo(crosshair.x, 0); 144 | ctx.lineTo(crosshair.x, plot.height()); 145 | } 146 | if (c.mode.indexOf("y") != -1) { 147 | ctx.moveTo(0, crosshair.y); 148 | ctx.lineTo(plot.width(), crosshair.y); 149 | } 150 | ctx.stroke(); 151 | } 152 | ctx.restore(); 153 | }); 154 | 155 | plot.hooks.shutdown.push(function (plot, eventHolder) { 156 | eventHolder.unbind("mouseout", onMouseOut); 157 | eventHolder.unbind("mousemove", onMouseMove); 158 | }); 159 | } 160 | 161 | $.plot.plugins.push({ 162 | init: init, 163 | options: options, 164 | name: 'crosshair', 165 | version: '1.0' 166 | }); 167 | })(jQuery); 168 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | fathmm - Home 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 47 | 48 | 49 | 50 |
51 | 74 | 75 | 76 | 77 |
78 |

Functional Analysis through Hidden Markov Models (v2.3)

79 |
80 |

81 | The Functional Analysis through Hidden Markov Models (fathmm) is a high-throughput web-server capable of predicting the functional, molecular and phenotypic consequences of 82 | protein missense variants using hidden Markov models (HMMs) representing the alignment of homologous sequences 83 | and conserved protein domains. 84 |

85 | 86 |
87 | 88 | 114 | 115 | 162 | 163 |
164 | 174 |
175 | 176 | 177 | 178 | 179 | 180 | -------------------------------------------------------------------------------- /about.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | fathmm - About Our Software and Server 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 47 | 48 | 49 | 50 | 51 | 52 |
53 | 76 | 77 |
78 |

About Our Software and Server

79 |
80 | 81 | 82 |
83 |
84 | 85 |
86 | 94 |
95 | 96 |
97 |

Overview:

98 |
99 |

100 | The Functional Analysis through Hidden Markov Models (fathmm) software and server is is capable of predicting the functional 101 | effects of protein missense mutations by combining sequence conservation within hidden Markov models (HMMs), representing the 102 | alignment of homologous (orthologous and/or paralogous) sequences and conserved protein domains, with "pathogenicity weights", representing the overall tolerance 103 | of the corresponding model to mutations. 104 |

105 | For more information, please refer to the following publications: 106 |

107 | Shihab HA, Gough J, Cooper DN, Stenson PD, Barker GLA, Edwards KJ, Day INM, Gaunt, TR. (2013). Predicting the Functional, Molecular and Phenotypic 108 | Consequences of Amino Acid Substitutions using Hidden Markov Models. Hum. Mutat., 34:57-65 109 | fathmm - Main Paper 110 |

111 | Shihab HA, Gough J, Cooper DN, Day INM, Gaunt, TR. (2013). Predicting the Functional Consequences of Cancer-Associated Amino Acid Substitutions. 112 | Bioinformatics 29:1504-1510. 113 | fathmm - Cancer Paper 114 |

115 |
116 | Back to Top ... 117 |
118 |
119 | 120 |
121 |

Input Format:

122 |
123 |

124 | Our software accepts one of the following formats (see here for annotating VCF files): 125 | 126 |

127 |

    128 |
  • 129 | <protein> <substitution> 130 |
  • 131 |
  • 132 | dbSNP rs identifiers 133 |
  • 134 |
135 |
136 | In the above, <protein> is the protein identifier and <substitution> is the amino acid substitution in the conventional one 137 | letter format. At present, our server accepts SwissProt/TrEMBL, RefSeq and Ensembl protein identifiers, e.g.: 138 |

139 |
140 | P43026 L441P
141 | 
142 | or: 143 |

144 |
145 | rs137854462
146 | 
147 |

148 |
149 | Back to Top ... 150 |
151 |
152 | 153 |
154 |

Batch Submission:

155 |
156 |

157 | 158 | It is possible to submit multiple amino acid substitutions as a 'Batch Submission' via our server. Here, all amino acid substitutions for a protein can be 159 | entered on a single line and should be separated by a comma, e.g: 160 |

161 |

162 | P43026 L441P
163 | ENSP00000325527 N548I,E1073K,C2307S 
164 | 
165 |
166 | Note: this option is not available when analysing dbSNP rs identifiers. 167 |

168 |
169 | Back to Top ... 170 |
171 |
172 | 173 |
174 |

VCF Annotation:

175 |
176 |

177 | Unfortunately, due to disk space constraints, we are unable to annotate Variant Call Format (VCF) files on your behalf. However, the consequences of all VCF variants 178 | can be derived using the Ensembl Variant Effect Predictor (VEP). 179 | Once annotated, the following script (available here) is capable of parsing these annotations and will provide you with a list of protein 180 | consequences which can then be used as input into our server/software. 181 |

182 | Additional help on using our script is available by typing the following command: 183 |

184 |

python parseVCF.py --help
185 |

186 |
187 | Back to Top ... 188 |
189 | 190 |
191 |
192 | 193 | 194 |
195 |
196 | 197 |
198 | 208 |
209 | 210 | 211 | 212 | 213 | 214 | 215 | -------------------------------------------------------------------------------- /cgi-bin/results.cgi: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python -u 2 | 3 | import os 4 | import sys 5 | import time 6 | import uuid 7 | import shlex 8 | import subprocess 9 | import traceback 10 | 11 | import cgi 12 | import cgitb; cgitb.enable() 13 | 14 | # 15 | if __name__ == '__main__': 16 | print "Content-Type: text/html" 17 | print 18 | 19 | HTML = "" 20 | try: 21 | HTMLForm = cgi.FieldStorage() 22 | HTMLSession = str(HTMLForm['session'].value).strip() 23 | 24 | HTML+= """ 25 | 26 | 27 | fathmm - fathmm Predictions 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 73 | 74 | 75 | 76 |
77 | 100 | """ 101 | 102 | 103 | if os.path.exists("../tmp/" + HTMLSession + ".txt"): 104 | # submission has been made ... 105 | if os.path.exists("../tmp/" + HTMLSession + ".tab"): 106 | # prediction have been made ... 107 | Predictions = [ x for x in open("../tmp/" + HTMLSession + ".tab", "r").readlines() if not x.startswith("#") ] 108 | 109 | HTML+= """ 110 |
111 |

fathmm Predictions

112 |
113 |

114 | Your request has now been processed and our predictions have been written onto your screen below - you can retrieve your results at 115 | any time during the next week using the following Job/Session Identifier: """ + HTMLSession + """. In addition, a 116 | "tab-delimited" report of our predictions has been made available via the "Download" button below. 117 |

118 |

119 | Download » 120 |

121 |
122 | """ 123 | 124 | if len(Predictions) > 1000: 125 | HTML+= """ 126 |
127 |
128 |
129 | 130 | 131 | It appears that your submission exceeded 1,000 records; therefore, in order to minimize the load on your browser, we have limited the 132 | below to the first 1,000 records. However, you can retrieve all your results in a tab-delimited report via the "Download" 133 | button above (right-click/save-as). 134 | 135 |
136 |
137 |
138 |
139 | """ 140 | HTML+= """ 141 |
142 |
143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | """ 157 | 158 | for record in Predictions[:1000]: 159 | if record and not record.startswith("#"): 160 | record = record.split("\t") 161 | 162 | if record[4] in [ "DAMAGING", "CANCER" ]: 163 | record[4] = "

%s

"% record[4] 164 | else: 165 | record[4] = "

%s

"% record[4] 166 | 167 | # warning/phenotypes formatting 168 | if record[7].strip(): 169 | record[6] = record[7] 170 | else: 171 | if record[6].strip(): 172 | record[6] = "
    " + "".join([ "
  • " + x + "
  • " for x in record[6].split("|") ]) + "
" 173 | 174 | HTML+= """ 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | """ 185 | 186 | HTML+= """ 187 | 188 |
#dbSNP IDProtein IDSubstitutionPredictionScoreFurther Information
""" + record[0] + """""" + record[1] + """""" + record[2] + """""" + record[3] + """""" + record[4] + """""" + record[5] + """""" + record[6] + """
189 |
190 |
191 | """ 192 | else: 193 | # request is being processed ... 194 | HTML+= """ 195 |
196 |

fathmm Predictions

197 |
198 |

199 | Your request is now being processed and our predictions will be written onto your screen once completed - if you submitted a large batch, 200 | please be patient as this may take a while. Note, you can retrieve your results at any time during the next week using the following 201 | Job/Session Identifier: """ + HTMLSession + """. 202 |

203 |

204 | Processing Request ... 205 |

206 |
207 | 208 | 213 | """ 214 | else: 215 | # no submission has been made/previous submission has been deleted ... 216 | HTML+= """ 217 |
218 |

fathmm Predictions

219 |
220 |

221 | You have entered an invalid or unknown Job/Session Identifier - please note, predictions are stored on our server for one week before being deleted. 222 |

223 |
224 | """ 225 | 226 | 227 | HTML+= """ 228 |
229 | 239 |
240 | 241 | 242 | 243 | 244 | """ 245 | except Exception, e: 246 | HTML = """ 247 | 248 | 249 | 250 | 251 | 252 | 253 | fathmm - fathmm Predictions 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 293 | 294 | 295 | 296 |
297 | 298 | 321 | 322 |
323 |

Server Error

324 |
325 |

326 | It appears there is a problem with our server - please try again and/or report the problem to the system administrator 327 | using the following address: fathmm.biocompute.org.uk 328 |

329 |
330 | 331 |
332 |
333 |
334 |

Stack Trace:

335 | 336 |
337 |
338 | 339 |
340 |
341 |
342 | """ 343 | HTML+= traceback.format_exc() 344 | HTML+= """ 345 |
346 |
347 |
348 |
349 |
350 |
351 |
352 |
353 | 354 |
355 | 365 |
366 | 367 | 368 | 369 | 370 | """ 371 | finally: 372 | print HTML 373 | -------------------------------------------------------------------------------- /cgi-bin/fathmm.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python -u 2 | 3 | import re 4 | import math 5 | import argparse 6 | import ConfigParser 7 | 8 | import MySQLdb 9 | import MySQLdb.cursors 10 | 11 | # 12 | def map_position(domain, substitution): 13 | """ 14 | """ 15 | 16 | if int(substitution[1:-1]) < int(domain['seq_begin']) or \ 17 | int(substitution[1:-1]) > int(domain['seq_end']): 18 | return None 19 | 20 | x = int(domain['seq_begin']) - 1 21 | y = int(domain['hmm_begin']) - 1 22 | 23 | for residue in list(domain['align']): 24 | if residue.isupper() or residue.islower(): 25 | # upper-case (match)/lower-case (insertion) characters correspond 26 | # to a sequence residue 27 | x += 1 28 | if residue.isupper() or residue == "-": 29 | # upper-case (match)/gap (deletion) characters correspond to 30 | # a HMM position 31 | y += 1 32 | if x == int(substitution[1:-1]): 33 | if residue.isupper(): 34 | return str(y) 35 | # unmapped residue (i.e. insertion) 36 | return None 37 | return None 38 | 39 | # 40 | def fetch_phenotype_prediction(Facade, Phenotype): 41 | """ 42 | """ 43 | 44 | Phenotypes = "" 45 | 46 | if not Arg.phenotypes: 47 | return Phenotypes 48 | 49 | for x in sorted(Facade, key=lambda x:x['information'], reverse=True): 50 | # use the most informative HMM 51 | if x['accession']: 52 | dbCursor.execute("select * from PHENOTYPES where accession='" + x['accession'] + "' and type='" + Phenotype + "' and origin=1 order by score") 53 | Phenotypes = "|".join([ x['description'] for x in dbCursor.fetchall() ]) 54 | 55 | if Phenotypes: 56 | break 57 | 58 | return Phenotypes 59 | 60 | # 61 | def Process(Protein, Substitution, Weights=None, Cutoff=None, Phenotype=None): 62 | """ 63 | """ 64 | 65 | Processed = { 66 | 'Prediction' : "", 67 | 'Score': "", 68 | 'Phenotype': "", 69 | 'HMM': "", 70 | 'Description': "", 71 | 'Position': "", 72 | 'W': "", 73 | 'M': "", 74 | 'D': "", 75 | 'O': "", 76 | 'Warning': "", 77 | } 78 | 79 | # fetch pre-computed sequence record 80 | dbCursor.execute("select a.* from SEQUENCE a, PROTEIN b where a.id=b.id and b.name='" + Protein + "'") 81 | Sequence = dbCursor.fetchone() 82 | 83 | if not Sequence: 84 | Processed['Warning'] = "No Sequence Record Found" 85 | 86 | return Processed 87 | 88 | # authenticate protein/substitution 89 | Warning = None 90 | if not Warning and not re.compile("^[ARNDCEQGHILKMFPSTWYV]\d+[ARNDCEQGHILKMFPSTWYV]$", re.IGNORECASE).match(Substitution): 91 | Warning = "Invalid Substitution Format" 92 | if not Warning and int(Substitution[1:-1]) > len(Sequence['sequence']): 93 | Warning = "Invalid Substitution Position" 94 | if not Warning and not Substitution[0] == Sequence['sequence'][int(Substitution[1:-1]) - 1]: 95 | Warning = "Inconsistent Wild-Type Residue (Expected '" + Sequence['sequence'][int(Substitution[1:-1]) - 1] + "')" 96 | if not Warning and Substitution[0] == Substitution[-1]: 97 | Warning = "Synonymous Mutation" 98 | 99 | if Warning: 100 | Processed['Warning'] = Warning 101 | 102 | return Processed 103 | 104 | # fetch pre-computed domain assignment(s) 105 | dbCursor.execute("select * from DOMAINS where id='" + str(Sequence['id']) + "' and " + Substitution[1:-1] + " between seq_begin and seq_end order by score") 106 | Domain = dbCursor.fetchall() 107 | 108 | Facade = [] 109 | 110 | for x in Domain: 111 | residue = map_position(x, Substitution) 112 | 113 | if residue: 114 | dbCursor.execute("select a.*, b.* from PROBABILITIES a, LIBRARY b where a.id=b.id and a.id='" + str(x['hmm']) + "' and a.position='" + residue + "'") 115 | Prob = dbCursor.fetchone() 116 | 117 | if Prob: 118 | Facade.append(Prob) 119 | 120 | # 121 | 122 | # fetch phenotype association(s) 123 | if Phenotype: 124 | Processed['Phenotype'] = fetch_phenotype_prediction(Facade, Phenotype) 125 | 126 | # derive/return a prediction ... 127 | if not Weights or Weights == "UNWEIGHTED": 128 | # append non-domain-based/sequence conservation to the Facade 129 | dbCursor.execute("select a.*, b.* from PROBABILITIES a, LIBRARY b where a.id=b.id and a.id='" + str(Sequence['id']) + "' and a.position='" + Substitution[1:-1] + "'") 130 | Prob = dbCursor.fetchone() 131 | 132 | if Prob: 133 | Facade.append(Prob) 134 | 135 | for x in sorted(Facade, key=lambda x:x['information'], reverse=True): 136 | try: 137 | Processed['HMM'] = x['id'] 138 | Processed['Description'] = x['description'] 139 | Processed['Position'] = x['position'] 140 | Processed['W'] = x[Substitution[0]] 141 | Processed['M'] = x[Substitution[-1]] 142 | Processed['D'] = "" 143 | Processed['O'] = "" 144 | 145 | Processed['Score'] = "%.2f" % math.log((Processed['M'] / (1.0 - Processed['M'])) / (Processed['W'] / (1.0 - Processed['W'])), 2) 146 | 147 | Processed['Prediction'] = "" 148 | if Cutoff: 149 | if float(Processed['Score']) <= Cutoff: Processed['Prediction'] = "DAMAGING" 150 | if float(Processed['Score']) > Cutoff: Processed['Prediction'] = "TOLERATED" 151 | 152 | return Processed 153 | except Exception, e: 154 | # skip the rare occasion(s) when probabilities are zero 155 | pass 156 | else: 157 | # prioritize domain-based predictions 158 | for x in sorted(Facade, key=lambda x:x['information'], reverse=True): 159 | try: 160 | dbCursor.execute("select * from WEIGHTS where id='" + x['id'] + "' and type='" + Weights + "'") 161 | w = \ 162 | dbCursor.fetchone() 163 | 164 | if w: 165 | Processed['HMM'] = x['id'] 166 | Processed['Description'] = x['description'] 167 | Processed['Position'] = x['position'] 168 | Processed['W'] = x[Substitution[0]] 169 | Processed['M'] = x[Substitution[-1]] 170 | Processed['D'] = w['disease'] + 1.0 171 | Processed['O'] = w['other'] + 1.0 172 | 173 | Processed['Score'] = "%.2f" % math.log(((1.0 - Processed['W']) * Processed['O']) / ((1.0 - Processed['M']) * Processed['D']), 2) 174 | 175 | Processed['Prediction'] = "" 176 | if Cutoff: 177 | if Weights == "INHERITED": 178 | if float(Processed['Score']) <= Cutoff: Processed['Prediction'] = "DAMAGING" 179 | if float(Processed['Score']) > Cutoff: Processed['Prediction'] = "TOLERATED" 180 | 181 | if Weights == "CANCER": 182 | if float(Processed['Score']) <= Cutoff: Processed['Prediction'] = "CANCER" 183 | if float(Processed['Score']) > Cutoff: Processed['Prediction'] = "PASSENGER/OTHER" 184 | 185 | return Processed 186 | except Exception, e: 187 | # skip the rare occasion(s) when probabilities are zero 188 | pass 189 | 190 | # no domain-based prediction, use a non-domain-based/sequence conservation prediction 191 | dbCursor.execute("select a.*, b.* from PROBABILITIES a, LIBRARY b where a.id=b.id and a.id='" + str(Sequence['id']) + "' and a.position='" + Substitution[1:-1] + "'") 192 | Facade = dbCursor.fetchone() 193 | 194 | if Facade: 195 | try: 196 | dbCursor.execute("select * from WEIGHTS where id='" + Facade['id'] + "' and type='" + Weights + "'") 197 | w = \ 198 | dbCursor.fetchone() 199 | 200 | if w: 201 | Processed['HMM'] = Facade['id'] 202 | Processed['Description'] = Facade['description'] 203 | Processed['Position'] = Facade['position'] 204 | Processed['W'] = Facade[Substitution[0]] 205 | Processed['M'] = Facade[Substitution[-1]] 206 | Processed['D'] = w['disease'] + 1.0 207 | Processed['O'] = w['other'] + 1.0 208 | 209 | Processed['Score'] = "%.2f" % math.log(((1.0 - Processed['W']) * Processed['O']) / ((1.0 - Processed['M']) * Processed['D']), 2) 210 | 211 | Processed['Prediction'] = "" 212 | if Cutoff: 213 | if Weights == "INHERITED": 214 | if float(Processed['Score']) <= Cutoff: Processed['Prediction'] = "DAMAGING" 215 | if float(Processed['Score']) > Cutoff: Processed['Prediction'] = "TOLERATED" 216 | 217 | if Weights == "CANCER": 218 | if float(Processed['Score']) <= Cutoff: Processed['Prediction'] = "CANCER" 219 | if float(Processed['Score']) > Cutoff: Processed['Prediction'] = "PASSENGER/OTHER" 220 | 221 | return Processed 222 | except Exception, e: 223 | # skip the rare occasion(s) when probabilities are zero 224 | raise 225 | 226 | return None 227 | 228 | 229 | 230 | # 231 | if __name__ == '__main__': 232 | # 233 | 234 | Config = ConfigParser.ConfigParser() 235 | Config.read("./config.ini") 236 | 237 | dbCursor = MySQLdb.connect( 238 | host = str(Config.get("DATABASE", "HOST")), 239 | port = int(Config.get("DATABASE", "PORT")), 240 | user = str(Config.get("DATABASE", "USER")), 241 | passwd = str(Config.get("DATABASE", "PASSWD")), 242 | db = str(Config.get("DATABASE", "DB")), 243 | compress = 1 244 | ).cursor(MySQLdb.cursors.DictCursor) 245 | 246 | # parse program argument(s) 247 | parser = argparse.ArgumentParser( 248 | description = 'Functional Analysis through Hidden Markov Models', 249 | add_help = False 250 | ) 251 | parser.add_argument( 252 | "-h", 253 | "--help", 254 | action = "help", 255 | help = argparse.SUPPRESS 256 | ) 257 | 258 | group = \ 259 | parser.add_argument_group("Required") 260 | group.add_argument( 261 | 'fi', 262 | metavar = '', 263 | type = argparse.FileType("r"), 264 | help = 'a file containing the mutation data to process' 265 | ) 266 | group.add_argument( 267 | 'fo', 268 | metavar = '', 269 | type = argparse.FileType("w"), 270 | help = 'where predictions/phenotype-associations will be written' 271 | ) 272 | 273 | group = \ 274 | parser.add_argument_group("Options") 275 | group.add_argument( 276 | '-w', 277 | dest = 'weights', 278 | metavar = "", 279 | default = "INHERITED", 280 | help = "use pathogenicity weights when returning predictions" 281 | ) 282 | group.add_argument( 283 | '-t', 284 | dest = 'threshold', 285 | metavar = "", 286 | default = None, 287 | type = float, 288 | help = "use prediction threshold when returning predictions" 289 | ) 290 | group.add_argument( 291 | '-p', 292 | dest = 'phenotypes', 293 | metavar = "", 294 | default = "", 295 | help = "use phenotype ontology when returning domain-phenotype associations" 296 | ); Arg = parser.parse_args() 297 | 298 | if Arg.weights: 299 | # authenticate prediction weights 300 | dbCursor.execute("select distinct type from WEIGHTS") 301 | 302 | if not Arg.weights.upper() in [ x['type'] for x in dbCursor.fetchall() ] + [ "UNWEIGHTED" ]: 303 | parser.error("argument -w: invalid option: '{0}'".format(Arg.weights)) 304 | 305 | if Arg.threshold == None: 306 | # initialize predcition threshold 307 | if Arg.weights.upper() == "UNWEIGHTED": Arg.threshold = -3.00 308 | if Arg.weights.upper() == "INHERITED": Arg.threshold = -1.50 309 | if Arg.weights.upper() == "CANCER": Arg.threshold = -0.75 310 | 311 | if Arg.phenotypes: 312 | # authenticate prediction phenotype 313 | dbCursor.execute("select distinct type from PHENOTYPES") 314 | 315 | if not Arg.phenotypes.upper() in [ x['type'] for x in dbCursor.fetchall() ]: 316 | parser.error("argument -p: invalid option: '{0}'".format(Arg.phenotypes)) 317 | 318 | 319 | ## 320 | 321 | 322 | Arg.fo.write("\t".join([ "#", 323 | "dbSNP ID", 324 | "Protein ID", 325 | "Substitution", 326 | "Prediction", 327 | "Score", 328 | "Domain-Phenotype Association", 329 | "Warning", 330 | "HMM ID", 331 | "HMM Description", 332 | "HMM Pos.", 333 | "HMM Prob. W.", 334 | "HMM Prob. M.", 335 | "HMM Weights D.", 336 | "HMM Weights O." 337 | ]) + "\n") 338 | 339 | idx = 1 340 | for record in Arg.fi: 341 | record = record.strip() 342 | 343 | if record and not record.startswith("#"): 344 | try: 345 | if re.compile("^rs\d+$", re.IGNORECASE).match(record): 346 | dbCursor.execute("select distinct * from VARIANTS where id='" + record + "'") 347 | dbRecords = dbCursor.fetchall() 348 | 349 | if not dbRecords: 350 | Arg.fo.write( 351 | "\t".join([ str(idx), 352 | record, 353 | "", 354 | "", 355 | "", 356 | "", 357 | "", 358 | "No dbSNP Mapping(s)", 359 | "", 360 | "", 361 | "", 362 | "", 363 | "", 364 | "", 365 | "" 366 | ]) + "\n" 367 | ); idx += 1; continue 368 | 369 | for x in dbRecords: 370 | dbSNP = x['id'] 371 | Protein = x['protein'] 372 | Substitution = x['substitution'] 373 | 374 | Prediction = \ 375 | Process(Protein, Substitution, Weights=Arg.weights.upper(), Cutoff=Arg.threshold, Phenotype=Arg.phenotypes.upper()) 376 | 377 | if not Prediction: 378 | Arg.fo.write( 379 | "\t".join([ str(idx), 380 | dbSNP, 381 | Protein, 382 | Substitution, 383 | "", 384 | "", 385 | "", 386 | "No Prediction Available", 387 | "", 388 | "", 389 | "", 390 | "", 391 | "", 392 | "", 393 | "" 394 | ]) + "\n" 395 | ); idx += 1; continue 396 | Arg.fo.write( 397 | "\t".join([ str(idx), 398 | dbSNP, 399 | Protein, 400 | Substitution, 401 | str(Prediction['Prediction']), 402 | str(Prediction['Score']), 403 | str(Prediction['Phenotype']), 404 | str(Prediction['Warning']), 405 | str(Prediction['HMM']), 406 | str(Prediction['Description']), 407 | str(Prediction['Position']), 408 | str(Prediction['W']), 409 | str(Prediction['M']), 410 | str(Prediction['D']), 411 | str(Prediction['O']) 412 | ]) + "\n" 413 | ); idx += 1; continue 414 | else: 415 | dbSNP = "" 416 | Protein = record.upper().split()[0] 417 | 418 | for Substitution in [ x.strip() for x in record.upper().split()[1].split(",") ]: 419 | Prediction = \ 420 | Process(Protein, Substitution, Weights=Arg.weights.upper(), Cutoff=Arg.threshold, Phenotype=Arg.phenotypes.upper()) 421 | 422 | if not Prediction: 423 | Arg.fo.write( 424 | "\t".join([ str(idx), 425 | dbSNP, 426 | Protein, 427 | Substitution, 428 | "", 429 | "", 430 | "", 431 | "No Prediction Available", 432 | "", 433 | "", 434 | "", 435 | "", 436 | "", 437 | "", 438 | "" 439 | ]) + "\n" 440 | ); idx += 1; continue 441 | Arg.fo.write( 442 | "\t".join([ str(idx), 443 | dbSNP, 444 | Protein, 445 | Substitution, 446 | str(Prediction['Prediction']), 447 | str(Prediction['Score']), 448 | str(Prediction['Phenotype']), 449 | str(Prediction['Warning']), 450 | str(Prediction['HMM']), 451 | str(Prediction['Description']), 452 | str(Prediction['Position']), 453 | str(Prediction['W']), 454 | str(Prediction['M']), 455 | str(Prediction['D']), 456 | str(Prediction['O']) 457 | ]) + "\n" 458 | ); idx += 1; continue 459 | except Exception, e: 460 | Arg.fo.write( 461 | "\t".join([ str(idx), 462 | "", 463 | "", 464 | "", 465 | "", 466 | "", 467 | "", 468 | "An Error Occured While Processing The Record: " + record, 469 | "", 470 | "", 471 | "", 472 | "", 473 | "", 474 | "" 475 | ]) + "\n" 476 | ); idx += 1 477 | 478 | -------------------------------------------------------------------------------- /disease.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | fathmm - Rank nsSNPs According to Specific Disease Concepts 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 47 | 48 | 49 | 50 | 51 | 52 |
53 | 76 | 77 |
78 |

Rank nsSNPs According to Specific Disease Concepts

79 |
80 | 81 | 92 | 93 |
94 |
95 |
96 |
97 |
98 |

Enter Your Mutations:

99 | 100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 | 109 |
110 | 111 | 112 |
113 |
114 |
115 |
116 | 117 |
118 |
119 |
120 |
121 |
122 | 123 |
124 | 143 | 144 |
145 |
146 |
147 |
148 |
149 |
150 | 179 | 180 |
181 |
182 |
183 |
184 |
185 |
186 | 187 | 188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 |
199 |
200 |
201 |
202 |
203 |
204 |
205 |
206 |
207 | 216 |
217 |
218 |

Overview:

219 |
220 |

221 | Our disease-specific algortihm is is capable of ranking protein missense mutations according to seventeen disease concepts by combining sequence 222 | conservation within hidden Markov models (HMMs), representing the alignment of homologous sequences and conserved protein domains, with "pathogenicity weights", 223 | representing the overall tolerance of the corresponding model to disease concepts, e.g. musculoskeletal and/or metabolic disease. 224 |

225 | For more information, please refer to the following publications: 226 |

227 | Shihab HA, Gough J, Mort M, Cooper DN, Day INM, Gaunt, TR. 228 | A Method for Ranking Non-Synonymous Single Nucleotide Polymorphisms based on Disease Concepts 229 | (submitted) 230 |

231 | Shihab HA, Gough J, Cooper DN, Stenson PD, Barker GLA, Edwards KJ, Day INM, Gaunt, TR. (2013). Predicting the Functional, Molecular and Phenotypic 232 | Consequences of Amino Acid Substitutions using Hidden Markov Models. Hum. Mutat., 34:57-65 233 | fathmm Paper 234 |

235 |
236 | Back to Top ... 237 |
238 |
239 | 240 |
241 |

Input Format:

242 |
243 |

244 | Our software accepts one of the following formats (see here for annotating VCF files): 245 | 246 |

247 |

    248 |
  • 249 | <protein> <substitution> 250 |
  • 251 |
  • 252 | dbSNP rs identifiers 253 |
  • 254 |
255 |
256 | In the above, <protein> is the protein identifier and <substitution> is the amino acid substitution in the conventional one 257 | letter format. At present, our server accepts SwissProt/TrEMBL, RefSeq and Ensembl protein identifiers, e.g.: 258 |

259 |
260 | P43026 L441P
261 | 
262 | or: 263 |

264 |
265 | rs137854462
266 | 
267 |

268 |
269 | Back to Top ... 270 |
271 |
272 | 273 |
274 |

Batch Submission:

275 |
276 |

277 | 278 | It is possible to submit multiple amino acid substitutions as a 'Batch Submission' via our server. Here, all amino acid substitutions for a protein can be 279 | entered on a single line and should be separated by a comma, e.g: 280 |

281 |

282 | P43026 L441P
283 | ENSP00000325527 N548I,E1073K,C2307S 
284 | 
285 |
286 | Note: this option is not available when analysing dbSNP rs identifiers. 287 |

288 |
289 | Back to Top ... 290 |
291 |
292 | 293 |
294 |

Prediction Score:

295 |
296 |

297 | Our disease-specific predictions are still experimental; therefore, we have not defined clear prediction thresholds for identifying whether a mutation 298 | is associated with your disease of interest or not. However, predictions scoring less than zero indicate there is a chance the mutation is associated 299 | with your disease of interest, with lower scores indicating increased confidence in the association. 300 |

301 |
302 | Back to Top ... 303 |
304 |
305 | 306 |
307 |

VCF Annotation:

308 |
309 |

310 | Unfortunately, due to disk space constraints, we are unable to annotate Variant Call Format (VCF) files on your behalf. However, the consequences of all VCF variants 311 | can be derived using the Ensembl Variant Effect Predictor (VEP). 312 | Once annotated, the following script (available here) is capable of parsing these annotations and will provide you with a list of protein 313 | consequences which can then be used as input into our server/software. 314 |

315 | Additional help on using our script is available by typing the following command: 316 |

317 |

python parseVCF.py --help
318 |

319 |
320 | Back to Top ... 321 |
322 | 323 |
324 |
325 |
326 |
327 | 328 |
329 | 339 |
340 | 341 | 342 | 343 | 344 | 353 | 354 | 355 | 356 | -------------------------------------------------------------------------------- /inherited.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | fathmm - Analyze dbSNP/Protein Missense Variants 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 47 | 48 | 49 | 50 | 51 | 52 |
53 | 76 | 77 |
78 |

Analyze Protein Missense Variants

79 |
80 | 81 | 92 | 93 |
94 |
95 |
96 |
97 |
98 |

Enter Your Mutations:

99 | 100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 | 109 |
110 | 111 | 112 |
113 |
114 |
115 |
116 | 117 |
118 |
119 |
120 |
121 |
122 | 123 |
124 | 128 | 129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 | 141 |
142 | 156 | 157 |
158 |
159 |
160 |
161 |
162 |
163 | 164 |
165 |
166 |
167 |
168 |
169 |
170 | 171 | 172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 | 201 |
202 |
203 |

Overview:

204 |
205 |

206 | The Functional Analysis through Hidden Markov Models (fathmm) software and server is is capable of predicting the functional 207 | effects of protein missense mutations by combining sequence conservation within hidden Markov models (HMMs), representing the 208 | alignment of homologous sequences and conserved protein domains, with "pathogenicity weights", representing the overall tolerance 209 | of the corresponding model to mutations. 210 |

211 | For more information, please refer to the following publication: 212 |

213 | Shihab HA, Gough J, Cooper DN, Stenson PD, Barker GLA, Edwards KJ, Day INM, Gaunt, TR. (2013). Predicting the Functional, Molecular and Phenotypic 214 | Consequences of Amino Acid Substitutions using Hidden Markov Models. Hum. Mutat., 34:57-65 215 | fathmm Paper 216 |

217 |
218 | Back to Top ... 219 |
220 |
221 | 222 |
223 |

Input Format:

224 |
225 |

226 | Our software accepts one of the following formats (see here for annotating VCF files): 227 | 228 |

229 |

    230 |
  • 231 | <protein> <substitution> 232 |
  • 233 |
  • 234 | dbSNP rs identifiers 235 |
  • 236 |
237 |
238 | In the above, <protein> is the protein identifier and <substitution> is the amino acid substitution in the conventional one 239 | letter format. At present, our server accepts SwissProt/TrEMBL, RefSeq and Ensembl protein identifiers, e.g.: 240 |

241 |
242 | P43026 L441P
243 | 
244 | or: 245 |

246 |
247 | rs137854462
248 | 
249 |

250 |
251 | Back to Top ... 252 |
253 |
254 | 255 |
256 |

Batch Submission:

257 |
258 |

259 | 260 | It is possible to submit multiple amino acid substitutions as a 'Batch Submission' via our server. Here, all amino acid substitutions for a protein can be 261 | entered on a single line and should be separated by a comma, e.g: 262 |

263 |

264 | P43026 L441P
265 | ENSP00000325527 N548I,E1073K,C2307S 
266 | 
267 |
268 | Note: this option is not available when analysing dbSNP rs identifiers. 269 |

270 |
271 | Back to Top ... 272 |
273 |
274 | 275 |
276 |

Prediction Algorithm:

277 |
278 |

279 | As described in our paper, our software is comprised of two algorithms: one sequence/conservation based (Unweighted) and the other 280 | combines our Unweighted algorithm with pathogenicity weights (Weighted). In short, our Weighted algorithm is capable of adjusting 281 | our conservation-based predictions to account for the tolerance of related sequences to mutations. For example, mutations falling within 282 | diverse regions of the Cellular Tumor Antigen P53 can be up-weighted according to the critical role the protein plays in cell regulation. 283 | In contrast, mutations falling within conserved regions of the MHC Antigen-Regognition Domain can be down-weighted according the 284 | hypervariable nature of the domain. 285 |

286 |
287 | Back to Top ... 288 |
289 |
290 | 291 |
292 |

Phenotype Associations:

293 |
294 |

295 | Our software not only predicts the potentially deleterious nature of protein variants but it is also capable of annotating 296 | the molecular and phenotypic consequences of these mutations via several domain-centric ontologies (dcGO). 297 | Here, the molecular consequences of mutations are statistically inferred by mapping SUPERFAMILY 298 | domains onto the Gene Ontology, the Human Phenotype Ontology and the Mammalian Phenotype Ontology (and more). 299 |

300 | For more information on these mappings, please refer to the following publications: 301 |

302 | Fang H, Gough J. (2012). dcGO: database of domain-centric ontologies on functions, phenotypes, diseases and more. Nucleic Acids Res., 41, D536-544. 303 |

304 | Gough J, Karplus K, Hughey R, Chothia C. (2001). Assignment of homology to genome sequences using a library of hidden Markov models that represent all proteins of known structure. J. Mol. Biol., 313, 903-919. 305 |

306 |
307 | Back to Top ... 308 |
309 |
310 | 311 |
312 |

VCF Annotation:

313 |
314 |

315 | Unfortunately, due to disk space constraints, we are unable to annotate Variant Call Format (VCF) files on your behalf. However, the consequences of all VCF variants 316 | can be derived using the Ensembl Variant Effect Predictor (VEP). 317 | Once annotated, the following script (available here) is capable of parsing these annotations and will provide you with a list of protein 318 | consequences which can then be used as input into our server/software. 319 |

320 | Additional help on using our script is available by typing the following command: 321 |

322 |

python parseVCF.py --help
323 |

324 |
325 | Back to Top ... 326 |
327 | 328 |
329 |
330 |
331 |
332 | 333 |
334 | 344 |
345 | 346 | 347 | 348 | 349 | 358 | 359 | 360 | 361 | -------------------------------------------------------------------------------- /cancer.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | fathmm - Analyze Cancer-Associated Variants 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 49 | 50 | 51 | 52 | 53 | 54 |
55 | 78 | 79 |
80 |

Analyze Cancer-Associated Variants

81 |
82 | 83 | 94 | 95 |
96 |
97 |
98 |
99 |
100 |

Enter Your Mutations:

101 | 102 | 103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 | 112 |
113 | 114 | 115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 | 125 |
126 | 127 | 128 |
129 |
130 |
131 |
132 |
133 |
134 | 135 |
136 |
137 |
138 |
139 |
140 |
141 | 142 | 143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 | 171 |
172 |
173 |

Overview:

174 |
175 |

176 | Our cancer-specific algorithm is capable of predicting the functional effects of cancer-associated protein missense mutations by combining 177 | sequence conservation within hidden Markov models (HMMs), representing the alignment of homologous sequences and conserved 178 | protein domains, with cancer-specific "pathogenicity weights", representing the overall tolerance of the corresponding model 179 | to cancer mutations. 180 |

181 | For more information, please refer to the following publications: 182 |

183 | Shihab HA, Gough J, Cooper DN, Day INM, Gaunt, TR. (2013). Predicting the Functional Consequences of Cancer-Associated Amino Acid Substitutions. 184 | Bioinformatics 29:1504-1510. 185 | Cancer-Specific Paper 186 |

187 | Shihab HA, Gough J, Cooper DN, Stenson PD, Barker GLA, Edwards KJ, Day INM, Gaunt, TR. (2013). Predicting the Functional, Molecular and Phenotypic 188 | Consequences of Amino Acid Substitutions using Hidden Markov Models. Hum. Mutat., 34:57-65 189 | fathmm Paper 190 |

191 |
192 | Back to Top ... 193 |
194 |
195 | 196 |
197 |

Input Format:

198 |
199 |

200 | Our software accepts one of the following formats (see here for annotating VCF files): 201 | 202 |

203 |

    204 |
  • 205 | <protein> <substitution> 206 |
  • 207 |
  • 208 | dbSNP rs identifiers 209 |
  • 210 |
211 |
212 | In the above, <protein> is the protein identifier and <substitution> is the amino acid substitution in the conventional one 213 | letter format. At present, our server accepts SwissProt/TrEMBL, RefSeq and Ensembl protein identifiers, e.g.: 214 |

215 |
216 | P43026 L441P
217 | 
218 | or: 219 |

220 |
221 | rs137854462
222 | 
223 |

224 |
225 | Back to Top ... 226 |
227 |
228 | 229 |
230 |

Batch Submission:

231 |
232 |

233 | 234 | It is possible to submit multiple amino acid substitutions as a 'Batch Submission' via our server. Here, all amino acid substitutions for a protein can be 235 | entered on a single line and should be separated by a comma, e.g: 236 |

237 |

238 | P43026 L441P
239 | ENSP00000325527 N548I,E1073K,C2307S 
240 | 
241 |
242 | Note: this option is not available when analysing dbSNP rs identifiers. 243 |

244 |
245 | Back to Top ... 246 |
247 |
248 | 249 |
250 |

Prediction Threshold:

251 |
252 |

253 | As described in our paper, our server uses a default prediction threshold of -0.75. Here, predictions with scores less than this indicate the 254 | mutation is potentially associated with cancer; however, our prediction threshold this can be adjusted and tuned to cater 255 | for your individual needs. For example, if you are interested in minimising the number of false positives in your analysis, then you should opt 256 | for a more conservative threshold, e.g. -3.0; however, if you are interested in capturing a large proportion of cancer-associated mutations (regardless of 257 | the number of false positives), then a less stringent threshold should be selected, e.g. 0.0 or higher. To inform you of this choice, the specificity and sensitivity 258 | of our software at various prediction thresholds can be seen using the below interactive graph: 259 |

260 | 261 |

262 |
263 |
Prediction Threshold
264 | 265 |

266 |
267 | Back to Top ... 268 |
269 |
270 | 271 |
272 |

VCF Annotation:

273 |
274 |

275 | Unfortunately, due to disk space constraints, we are unable to annotate Variant Call Format (VCF) files on your behalf. However, the consequences of all VCF variants 276 | can be derived using the Ensembl Variant Effect Predictor (VEP). 277 | Once annotated, the following script (available here) is capable of parsing these annotations and will provide you with a list of protein 278 | consequences which can then be used as input into our server/software. 279 |

280 | Additional help on using our script is available by typing the following command: 281 |

282 |

python parseVCF.py --help
283 |

284 |
285 | Back to Top ... 286 |
287 | 288 |
289 |
290 |
291 |
292 | 293 |
294 | 304 |
305 | 306 | 307 | 308 | 309 | 310 | 311 | 320 | 321 | 444 | 445 | 446 | -------------------------------------------------------------------------------- /css/bootstrap-responsive.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap Responsive v2.1.1 3 | * 4 | * Copyright 2012 Twitter, Inc 5 | * Licensed under the Apache License v2.0 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Designed and built with all the love in the world @twitter by @mdo and @fat. 9 | */ 10 | 11 | .clearfix { 12 | *zoom: 1; 13 | } 14 | 15 | .clearfix:before, 16 | .clearfix:after { 17 | display: table; 18 | line-height: 0; 19 | content: ""; 20 | } 21 | 22 | .clearfix:after { 23 | clear: both; 24 | } 25 | 26 | .hide-text { 27 | font: 0/0 a; 28 | color: transparent; 29 | text-shadow: none; 30 | background-color: transparent; 31 | border: 0; 32 | } 33 | 34 | .input-block-level { 35 | display: block; 36 | width: 100%; 37 | min-height: 30px; 38 | -webkit-box-sizing: border-box; 39 | -moz-box-sizing: border-box; 40 | box-sizing: border-box; 41 | } 42 | 43 | .hidden { 44 | display: none; 45 | visibility: hidden; 46 | } 47 | 48 | .visible-phone { 49 | display: none !important; 50 | } 51 | 52 | .visible-tablet { 53 | display: none !important; 54 | } 55 | 56 | .hidden-desktop { 57 | display: none !important; 58 | } 59 | 60 | .visible-desktop { 61 | display: inherit !important; 62 | } 63 | 64 | @media (min-width: 768px) and (max-width: 979px) { 65 | .hidden-desktop { 66 | display: inherit !important; 67 | } 68 | .visible-desktop { 69 | display: none !important ; 70 | } 71 | .visible-tablet { 72 | display: inherit !important; 73 | } 74 | .hidden-tablet { 75 | display: none !important; 76 | } 77 | } 78 | 79 | @media (max-width: 767px) { 80 | .hidden-desktop { 81 | display: inherit !important; 82 | } 83 | .visible-desktop { 84 | display: none !important; 85 | } 86 | .visible-phone { 87 | display: inherit !important; 88 | } 89 | .hidden-phone { 90 | display: none !important; 91 | } 92 | } 93 | 94 | @media (min-width: 1200px) { 95 | .row { 96 | margin-left: -30px; 97 | *zoom: 1; 98 | } 99 | .row:before, 100 | .row:after { 101 | display: table; 102 | line-height: 0; 103 | content: ""; 104 | } 105 | .row:after { 106 | clear: both; 107 | } 108 | [class*="span"] { 109 | float: left; 110 | min-height: 1px; 111 | margin-left: 30px; 112 | } 113 | .container, 114 | .navbar-static-top .container, 115 | .navbar-fixed-top .container, 116 | .navbar-fixed-bottom .container { 117 | width: 1170px; 118 | } 119 | .span12 { 120 | width: 1170px; 121 | } 122 | .span11 { 123 | width: 1070px; 124 | } 125 | .span10 { 126 | width: 970px; 127 | } 128 | .span9 { 129 | width: 870px; 130 | } 131 | .span8 { 132 | width: 770px; 133 | } 134 | .span7 { 135 | width: 670px; 136 | } 137 | .span6 { 138 | width: 570px; 139 | } 140 | .span5 { 141 | width: 470px; 142 | } 143 | .span4 { 144 | width: 370px; 145 | } 146 | .span3 { 147 | width: 270px; 148 | } 149 | .span2 { 150 | width: 170px; 151 | } 152 | .span1 { 153 | width: 70px; 154 | } 155 | .offset12 { 156 | margin-left: 1230px; 157 | } 158 | .offset11 { 159 | margin-left: 1130px; 160 | } 161 | .offset10 { 162 | margin-left: 1030px; 163 | } 164 | .offset9 { 165 | margin-left: 930px; 166 | } 167 | .offset8 { 168 | margin-left: 830px; 169 | } 170 | .offset7 { 171 | margin-left: 730px; 172 | } 173 | .offset6 { 174 | margin-left: 630px; 175 | } 176 | .offset5 { 177 | margin-left: 530px; 178 | } 179 | .offset4 { 180 | margin-left: 430px; 181 | } 182 | .offset3 { 183 | margin-left: 330px; 184 | } 185 | .offset2 { 186 | margin-left: 230px; 187 | } 188 | .offset1 { 189 | margin-left: 130px; 190 | } 191 | .row-fluid { 192 | width: 100%; 193 | *zoom: 1; 194 | } 195 | .row-fluid:before, 196 | .row-fluid:after { 197 | display: table; 198 | line-height: 0; 199 | content: ""; 200 | } 201 | .row-fluid:after { 202 | clear: both; 203 | } 204 | .row-fluid [class*="span"] { 205 | display: block; 206 | float: left; 207 | width: 100%; 208 | min-height: 30px; 209 | margin-left: 2.564102564102564%; 210 | *margin-left: 2.5109110747408616%; 211 | -webkit-box-sizing: border-box; 212 | -moz-box-sizing: border-box; 213 | box-sizing: border-box; 214 | } 215 | .row-fluid [class*="span"]:first-child { 216 | margin-left: 0; 217 | } 218 | .row-fluid .span12 { 219 | width: 100%; 220 | *width: 99.94680851063829%; 221 | } 222 | .row-fluid .span11 { 223 | width: 91.45299145299145%; 224 | *width: 91.39979996362975%; 225 | } 226 | .row-fluid .span10 { 227 | width: 82.90598290598291%; 228 | *width: 82.8527914166212%; 229 | } 230 | .row-fluid .span9 { 231 | width: 74.35897435897436%; 232 | *width: 74.30578286961266%; 233 | } 234 | .row-fluid .span8 { 235 | width: 65.81196581196582%; 236 | *width: 65.75877432260411%; 237 | } 238 | .row-fluid .span7 { 239 | width: 57.26495726495726%; 240 | *width: 57.21176577559556%; 241 | } 242 | .row-fluid .span6 { 243 | width: 48.717948717948715%; 244 | *width: 48.664757228587014%; 245 | } 246 | .row-fluid .span5 { 247 | width: 40.17094017094017%; 248 | *width: 40.11774868157847%; 249 | } 250 | .row-fluid .span4 { 251 | width: 31.623931623931625%; 252 | *width: 31.570740134569924%; 253 | } 254 | .row-fluid .span3 { 255 | width: 23.076923076923077%; 256 | *width: 23.023731587561375%; 257 | } 258 | .row-fluid .span2 { 259 | width: 14.52991452991453%; 260 | *width: 14.476723040552828%; 261 | } 262 | .row-fluid .span1 { 263 | width: 5.982905982905983%; 264 | *width: 5.929714493544281%; 265 | } 266 | .row-fluid .offset12 { 267 | margin-left: 105.12820512820512%; 268 | *margin-left: 105.02182214948171%; 269 | } 270 | .row-fluid .offset12:first-child { 271 | margin-left: 102.56410256410257%; 272 | *margin-left: 102.45771958537915%; 273 | } 274 | .row-fluid .offset11 { 275 | margin-left: 96.58119658119658%; 276 | *margin-left: 96.47481360247316%; 277 | } 278 | .row-fluid .offset11:first-child { 279 | margin-left: 94.01709401709402%; 280 | *margin-left: 93.91071103837061%; 281 | } 282 | .row-fluid .offset10 { 283 | margin-left: 88.03418803418803%; 284 | *margin-left: 87.92780505546462%; 285 | } 286 | .row-fluid .offset10:first-child { 287 | margin-left: 85.47008547008548%; 288 | *margin-left: 85.36370249136206%; 289 | } 290 | .row-fluid .offset9 { 291 | margin-left: 79.48717948717949%; 292 | *margin-left: 79.38079650845607%; 293 | } 294 | .row-fluid .offset9:first-child { 295 | margin-left: 76.92307692307693%; 296 | *margin-left: 76.81669394435352%; 297 | } 298 | .row-fluid .offset8 { 299 | margin-left: 70.94017094017094%; 300 | *margin-left: 70.83378796144753%; 301 | } 302 | .row-fluid .offset8:first-child { 303 | margin-left: 68.37606837606839%; 304 | *margin-left: 68.26968539734497%; 305 | } 306 | .row-fluid .offset7 { 307 | margin-left: 62.393162393162385%; 308 | *margin-left: 62.28677941443899%; 309 | } 310 | .row-fluid .offset7:first-child { 311 | margin-left: 59.82905982905982%; 312 | *margin-left: 59.72267685033642%; 313 | } 314 | .row-fluid .offset6 { 315 | margin-left: 53.84615384615384%; 316 | *margin-left: 53.739770867430444%; 317 | } 318 | .row-fluid .offset6:first-child { 319 | margin-left: 51.28205128205128%; 320 | *margin-left: 51.175668303327875%; 321 | } 322 | .row-fluid .offset5 { 323 | margin-left: 45.299145299145295%; 324 | *margin-left: 45.1927623204219%; 325 | } 326 | .row-fluid .offset5:first-child { 327 | margin-left: 42.73504273504273%; 328 | *margin-left: 42.62865975631933%; 329 | } 330 | .row-fluid .offset4 { 331 | margin-left: 36.75213675213675%; 332 | *margin-left: 36.645753773413354%; 333 | } 334 | .row-fluid .offset4:first-child { 335 | margin-left: 34.18803418803419%; 336 | *margin-left: 34.081651209310785%; 337 | } 338 | .row-fluid .offset3 { 339 | margin-left: 28.205128205128204%; 340 | *margin-left: 28.0987452264048%; 341 | } 342 | .row-fluid .offset3:first-child { 343 | margin-left: 25.641025641025642%; 344 | *margin-left: 25.53464266230224%; 345 | } 346 | .row-fluid .offset2 { 347 | margin-left: 19.65811965811966%; 348 | *margin-left: 19.551736679396257%; 349 | } 350 | .row-fluid .offset2:first-child { 351 | margin-left: 17.094017094017094%; 352 | *margin-left: 16.98763411529369%; 353 | } 354 | .row-fluid .offset1 { 355 | margin-left: 11.11111111111111%; 356 | *margin-left: 11.004728132387708%; 357 | } 358 | .row-fluid .offset1:first-child { 359 | margin-left: 8.547008547008547%; 360 | *margin-left: 8.440625568285142%; 361 | } 362 | input, 363 | textarea, 364 | .uneditable-input { 365 | margin-left: 0; 366 | } 367 | .controls-row [class*="span"] + [class*="span"] { 368 | margin-left: 30px; 369 | } 370 | input.span12, 371 | textarea.span12, 372 | .uneditable-input.span12 { 373 | width: 1156px; 374 | } 375 | input.span11, 376 | textarea.span11, 377 | .uneditable-input.span11 { 378 | width: 1056px; 379 | } 380 | input.span10, 381 | textarea.span10, 382 | .uneditable-input.span10 { 383 | width: 956px; 384 | } 385 | input.span9, 386 | textarea.span9, 387 | .uneditable-input.span9 { 388 | width: 856px; 389 | } 390 | input.span8, 391 | textarea.span8, 392 | .uneditable-input.span8 { 393 | width: 756px; 394 | } 395 | input.span7, 396 | textarea.span7, 397 | .uneditable-input.span7 { 398 | width: 656px; 399 | } 400 | input.span6, 401 | textarea.span6, 402 | .uneditable-input.span6 { 403 | width: 556px; 404 | } 405 | input.span5, 406 | textarea.span5, 407 | .uneditable-input.span5 { 408 | width: 456px; 409 | } 410 | input.span4, 411 | textarea.span4, 412 | .uneditable-input.span4 { 413 | width: 356px; 414 | } 415 | input.span3, 416 | textarea.span3, 417 | .uneditable-input.span3 { 418 | width: 256px; 419 | } 420 | input.span2, 421 | textarea.span2, 422 | .uneditable-input.span2 { 423 | width: 156px; 424 | } 425 | input.span1, 426 | textarea.span1, 427 | .uneditable-input.span1 { 428 | width: 56px; 429 | } 430 | .thumbnails { 431 | margin-left: -30px; 432 | } 433 | .thumbnails > li { 434 | margin-left: 30px; 435 | } 436 | .row-fluid .thumbnails { 437 | margin-left: 0; 438 | } 439 | } 440 | 441 | @media (min-width: 768px) and (max-width: 979px) { 442 | .row { 443 | margin-left: -20px; 444 | *zoom: 1; 445 | } 446 | .row:before, 447 | .row:after { 448 | display: table; 449 | line-height: 0; 450 | content: ""; 451 | } 452 | .row:after { 453 | clear: both; 454 | } 455 | [class*="span"] { 456 | float: left; 457 | min-height: 1px; 458 | margin-left: 20px; 459 | } 460 | .container, 461 | .navbar-static-top .container, 462 | .navbar-fixed-top .container, 463 | .navbar-fixed-bottom .container { 464 | width: 724px; 465 | } 466 | .span12 { 467 | width: 724px; 468 | } 469 | .span11 { 470 | width: 662px; 471 | } 472 | .span10 { 473 | width: 600px; 474 | } 475 | .span9 { 476 | width: 538px; 477 | } 478 | .span8 { 479 | width: 476px; 480 | } 481 | .span7 { 482 | width: 414px; 483 | } 484 | .span6 { 485 | width: 352px; 486 | } 487 | .span5 { 488 | width: 290px; 489 | } 490 | .span4 { 491 | width: 228px; 492 | } 493 | .span3 { 494 | width: 166px; 495 | } 496 | .span2 { 497 | width: 104px; 498 | } 499 | .span1 { 500 | width: 42px; 501 | } 502 | .offset12 { 503 | margin-left: 764px; 504 | } 505 | .offset11 { 506 | margin-left: 702px; 507 | } 508 | .offset10 { 509 | margin-left: 640px; 510 | } 511 | .offset9 { 512 | margin-left: 578px; 513 | } 514 | .offset8 { 515 | margin-left: 516px; 516 | } 517 | .offset7 { 518 | margin-left: 454px; 519 | } 520 | .offset6 { 521 | margin-left: 392px; 522 | } 523 | .offset5 { 524 | margin-left: 330px; 525 | } 526 | .offset4 { 527 | margin-left: 268px; 528 | } 529 | .offset3 { 530 | margin-left: 206px; 531 | } 532 | .offset2 { 533 | margin-left: 144px; 534 | } 535 | .offset1 { 536 | margin-left: 82px; 537 | } 538 | .row-fluid { 539 | width: 100%; 540 | *zoom: 1; 541 | } 542 | .row-fluid:before, 543 | .row-fluid:after { 544 | display: table; 545 | line-height: 0; 546 | content: ""; 547 | } 548 | .row-fluid:after { 549 | clear: both; 550 | } 551 | .row-fluid [class*="span"] { 552 | display: block; 553 | float: left; 554 | width: 100%; 555 | min-height: 30px; 556 | margin-left: 2.7624309392265194%; 557 | *margin-left: 2.709239449864817%; 558 | -webkit-box-sizing: border-box; 559 | -moz-box-sizing: border-box; 560 | box-sizing: border-box; 561 | } 562 | .row-fluid [class*="span"]:first-child { 563 | margin-left: 0; 564 | } 565 | .row-fluid .span12 { 566 | width: 100%; 567 | *width: 99.94680851063829%; 568 | } 569 | .row-fluid .span11 { 570 | width: 91.43646408839778%; 571 | *width: 91.38327259903608%; 572 | } 573 | .row-fluid .span10 { 574 | width: 82.87292817679558%; 575 | *width: 82.81973668743387%; 576 | } 577 | .row-fluid .span9 { 578 | width: 74.30939226519337%; 579 | *width: 74.25620077583166%; 580 | } 581 | .row-fluid .span8 { 582 | width: 65.74585635359117%; 583 | *width: 65.69266486422946%; 584 | } 585 | .row-fluid .span7 { 586 | width: 57.18232044198895%; 587 | *width: 57.12912895262725%; 588 | } 589 | .row-fluid .span6 { 590 | width: 48.61878453038674%; 591 | *width: 48.56559304102504%; 592 | } 593 | .row-fluid .span5 { 594 | width: 40.05524861878453%; 595 | *width: 40.00205712942283%; 596 | } 597 | .row-fluid .span4 { 598 | width: 31.491712707182323%; 599 | *width: 31.43852121782062%; 600 | } 601 | .row-fluid .span3 { 602 | width: 22.92817679558011%; 603 | *width: 22.87498530621841%; 604 | } 605 | .row-fluid .span2 { 606 | width: 14.3646408839779%; 607 | *width: 14.311449394616199%; 608 | } 609 | .row-fluid .span1 { 610 | width: 5.801104972375691%; 611 | *width: 5.747913483013988%; 612 | } 613 | .row-fluid .offset12 { 614 | margin-left: 105.52486187845304%; 615 | *margin-left: 105.41847889972962%; 616 | } 617 | .row-fluid .offset12:first-child { 618 | margin-left: 102.76243093922652%; 619 | *margin-left: 102.6560479605031%; 620 | } 621 | .row-fluid .offset11 { 622 | margin-left: 96.96132596685082%; 623 | *margin-left: 96.8549429881274%; 624 | } 625 | .row-fluid .offset11:first-child { 626 | margin-left: 94.1988950276243%; 627 | *margin-left: 94.09251204890089%; 628 | } 629 | .row-fluid .offset10 { 630 | margin-left: 88.39779005524862%; 631 | *margin-left: 88.2914070765252%; 632 | } 633 | .row-fluid .offset10:first-child { 634 | margin-left: 85.6353591160221%; 635 | *margin-left: 85.52897613729868%; 636 | } 637 | .row-fluid .offset9 { 638 | margin-left: 79.8342541436464%; 639 | *margin-left: 79.72787116492299%; 640 | } 641 | .row-fluid .offset9:first-child { 642 | margin-left: 77.07182320441989%; 643 | *margin-left: 76.96544022569647%; 644 | } 645 | .row-fluid .offset8 { 646 | margin-left: 71.2707182320442%; 647 | *margin-left: 71.16433525332079%; 648 | } 649 | .row-fluid .offset8:first-child { 650 | margin-left: 68.50828729281768%; 651 | *margin-left: 68.40190431409427%; 652 | } 653 | .row-fluid .offset7 { 654 | margin-left: 62.70718232044199%; 655 | *margin-left: 62.600799341718584%; 656 | } 657 | .row-fluid .offset7:first-child { 658 | margin-left: 59.94475138121547%; 659 | *margin-left: 59.838368402492065%; 660 | } 661 | .row-fluid .offset6 { 662 | margin-left: 54.14364640883978%; 663 | *margin-left: 54.037263430116376%; 664 | } 665 | .row-fluid .offset6:first-child { 666 | margin-left: 51.38121546961326%; 667 | *margin-left: 51.27483249088986%; 668 | } 669 | .row-fluid .offset5 { 670 | margin-left: 45.58011049723757%; 671 | *margin-left: 45.47372751851417%; 672 | } 673 | .row-fluid .offset5:first-child { 674 | margin-left: 42.81767955801105%; 675 | *margin-left: 42.71129657928765%; 676 | } 677 | .row-fluid .offset4 { 678 | margin-left: 37.01657458563536%; 679 | *margin-left: 36.91019160691196%; 680 | } 681 | .row-fluid .offset4:first-child { 682 | margin-left: 34.25414364640884%; 683 | *margin-left: 34.14776066768544%; 684 | } 685 | .row-fluid .offset3 { 686 | margin-left: 28.45303867403315%; 687 | *margin-left: 28.346655695309746%; 688 | } 689 | .row-fluid .offset3:first-child { 690 | margin-left: 25.69060773480663%; 691 | *margin-left: 25.584224756083227%; 692 | } 693 | .row-fluid .offset2 { 694 | margin-left: 19.88950276243094%; 695 | *margin-left: 19.783119783707537%; 696 | } 697 | .row-fluid .offset2:first-child { 698 | margin-left: 17.12707182320442%; 699 | *margin-left: 17.02068884448102%; 700 | } 701 | .row-fluid .offset1 { 702 | margin-left: 11.32596685082873%; 703 | *margin-left: 11.219583872105325%; 704 | } 705 | .row-fluid .offset1:first-child { 706 | margin-left: 8.56353591160221%; 707 | *margin-left: 8.457152932878806%; 708 | } 709 | input, 710 | textarea, 711 | .uneditable-input { 712 | margin-left: 0; 713 | } 714 | .controls-row [class*="span"] + [class*="span"] { 715 | margin-left: 20px; 716 | } 717 | input.span12, 718 | textarea.span12, 719 | .uneditable-input.span12 { 720 | width: 710px; 721 | } 722 | input.span11, 723 | textarea.span11, 724 | .uneditable-input.span11 { 725 | width: 648px; 726 | } 727 | input.span10, 728 | textarea.span10, 729 | .uneditable-input.span10 { 730 | width: 586px; 731 | } 732 | input.span9, 733 | textarea.span9, 734 | .uneditable-input.span9 { 735 | width: 524px; 736 | } 737 | input.span8, 738 | textarea.span8, 739 | .uneditable-input.span8 { 740 | width: 462px; 741 | } 742 | input.span7, 743 | textarea.span7, 744 | .uneditable-input.span7 { 745 | width: 400px; 746 | } 747 | input.span6, 748 | textarea.span6, 749 | .uneditable-input.span6 { 750 | width: 338px; 751 | } 752 | input.span5, 753 | textarea.span5, 754 | .uneditable-input.span5 { 755 | width: 276px; 756 | } 757 | input.span4, 758 | textarea.span4, 759 | .uneditable-input.span4 { 760 | width: 214px; 761 | } 762 | input.span3, 763 | textarea.span3, 764 | .uneditable-input.span3 { 765 | width: 152px; 766 | } 767 | input.span2, 768 | textarea.span2, 769 | .uneditable-input.span2 { 770 | width: 90px; 771 | } 772 | input.span1, 773 | textarea.span1, 774 | .uneditable-input.span1 { 775 | width: 28px; 776 | } 777 | } 778 | 779 | @media (max-width: 767px) { 780 | body { 781 | padding-right: 20px; 782 | padding-left: 20px; 783 | } 784 | .navbar-fixed-top, 785 | .navbar-fixed-bottom, 786 | .navbar-static-top { 787 | margin-right: -20px; 788 | margin-left: -20px; 789 | } 790 | .container-fluid { 791 | padding: 0; 792 | } 793 | .dl-horizontal dt { 794 | float: none; 795 | width: auto; 796 | clear: none; 797 | text-align: left; 798 | } 799 | .dl-horizontal dd { 800 | margin-left: 0; 801 | } 802 | .container { 803 | width: auto; 804 | } 805 | .row-fluid { 806 | width: 100%; 807 | } 808 | .row, 809 | .thumbnails { 810 | margin-left: 0; 811 | } 812 | .thumbnails > li { 813 | float: none; 814 | margin-left: 0; 815 | } 816 | [class*="span"], 817 | .row-fluid [class*="span"] { 818 | display: block; 819 | float: none; 820 | width: 100%; 821 | margin-left: 0; 822 | -webkit-box-sizing: border-box; 823 | -moz-box-sizing: border-box; 824 | box-sizing: border-box; 825 | } 826 | .span12, 827 | .row-fluid .span12 { 828 | width: 100%; 829 | -webkit-box-sizing: border-box; 830 | -moz-box-sizing: border-box; 831 | box-sizing: border-box; 832 | } 833 | .input-large, 834 | .input-xlarge, 835 | .input-xxlarge, 836 | input[class*="span"], 837 | select[class*="span"], 838 | textarea[class*="span"], 839 | .uneditable-input { 840 | display: block; 841 | width: 100%; 842 | min-height: 30px; 843 | -webkit-box-sizing: border-box; 844 | -moz-box-sizing: border-box; 845 | box-sizing: border-box; 846 | } 847 | .input-prepend input, 848 | .input-append input, 849 | .input-prepend input[class*="span"], 850 | .input-append input[class*="span"] { 851 | display: inline-block; 852 | width: auto; 853 | } 854 | .controls-row [class*="span"] + [class*="span"] { 855 | margin-left: 0; 856 | } 857 | .modal { 858 | position: fixed; 859 | top: 20px; 860 | right: 20px; 861 | left: 20px; 862 | width: auto; 863 | margin: 0; 864 | } 865 | .modal.fade.in { 866 | top: auto; 867 | } 868 | } 869 | 870 | @media (max-width: 480px) { 871 | .nav-collapse { 872 | -webkit-transform: translate3d(0, 0, 0); 873 | } 874 | .page-header h1 small { 875 | display: block; 876 | line-height: 20px; 877 | } 878 | input[type="checkbox"], 879 | input[type="radio"] { 880 | border: 1px solid #ccc; 881 | } 882 | .form-horizontal .control-label { 883 | float: none; 884 | width: auto; 885 | padding-top: 0; 886 | text-align: left; 887 | } 888 | .form-horizontal .controls { 889 | margin-left: 0; 890 | } 891 | .form-horizontal .control-list { 892 | padding-top: 0; 893 | } 894 | .form-horizontal .form-actions { 895 | padding-right: 10px; 896 | padding-left: 10px; 897 | } 898 | .modal { 899 | top: 10px; 900 | right: 10px; 901 | left: 10px; 902 | } 903 | .modal-header .close { 904 | padding: 10px; 905 | margin: -10px; 906 | } 907 | .carousel-caption { 908 | position: static; 909 | } 910 | } 911 | 912 | @media (max-width: 979px) { 913 | body { 914 | padding-top: 0; 915 | } 916 | .navbar-fixed-top, 917 | .navbar-fixed-bottom { 918 | position: static; 919 | } 920 | .navbar-fixed-top { 921 | margin-bottom: 20px; 922 | } 923 | .navbar-fixed-bottom { 924 | margin-top: 20px; 925 | } 926 | .navbar-fixed-top .navbar-inner, 927 | .navbar-fixed-bottom .navbar-inner { 928 | padding: 5px; 929 | } 930 | .navbar .container { 931 | width: auto; 932 | padding: 0; 933 | } 934 | .navbar .brand { 935 | padding-right: 10px; 936 | padding-left: 10px; 937 | margin: 0 0 0 -5px; 938 | } 939 | .nav-collapse { 940 | clear: both; 941 | } 942 | .nav-collapse .nav { 943 | float: none; 944 | margin: 0 0 10px; 945 | } 946 | .nav-collapse .nav > li { 947 | float: none; 948 | } 949 | .nav-collapse .nav > li > a { 950 | margin-bottom: 2px; 951 | } 952 | .nav-collapse .nav > .divider-vertical { 953 | display: none; 954 | } 955 | .nav-collapse .nav .nav-header { 956 | color: #777777; 957 | text-shadow: none; 958 | } 959 | .nav-collapse .nav > li > a, 960 | .nav-collapse .dropdown-menu a { 961 | padding: 9px 15px; 962 | font-weight: bold; 963 | color: #777777; 964 | -webkit-border-radius: 3px; 965 | -moz-border-radius: 3px; 966 | border-radius: 3px; 967 | } 968 | .nav-collapse .btn { 969 | padding: 4px 10px 4px; 970 | font-weight: normal; 971 | -webkit-border-radius: 4px; 972 | -moz-border-radius: 4px; 973 | border-radius: 4px; 974 | } 975 | .nav-collapse .dropdown-menu li + li a { 976 | margin-bottom: 2px; 977 | } 978 | .nav-collapse .nav > li > a:hover, 979 | .nav-collapse .dropdown-menu a:hover { 980 | background-color: #f2f2f2; 981 | } 982 | .navbar-inverse .nav-collapse .nav > li > a:hover, 983 | .navbar-inverse .nav-collapse .dropdown-menu a:hover { 984 | background-color: #111111; 985 | } 986 | .nav-collapse.in .btn-group { 987 | padding: 0; 988 | margin-top: 5px; 989 | } 990 | .nav-collapse .dropdown-menu { 991 | position: static; 992 | top: auto; 993 | left: auto; 994 | display: block; 995 | float: none; 996 | max-width: none; 997 | padding: 0; 998 | margin: 0 15px; 999 | background-color: transparent; 1000 | border: none; 1001 | -webkit-border-radius: 0; 1002 | -moz-border-radius: 0; 1003 | border-radius: 0; 1004 | -webkit-box-shadow: none; 1005 | -moz-box-shadow: none; 1006 | box-shadow: none; 1007 | } 1008 | .nav-collapse .dropdown-menu:before, 1009 | .nav-collapse .dropdown-menu:after { 1010 | display: none; 1011 | } 1012 | .nav-collapse .dropdown-menu .divider { 1013 | display: none; 1014 | } 1015 | .nav-collapse .nav > li > .dropdown-menu:before, 1016 | .nav-collapse .nav > li > .dropdown-menu:after { 1017 | display: none; 1018 | } 1019 | .nav-collapse .navbar-form, 1020 | .nav-collapse .navbar-search { 1021 | float: none; 1022 | padding: 10px 15px; 1023 | margin: 10px 0; 1024 | border-top: 1px solid #f2f2f2; 1025 | border-bottom: 1px solid #f2f2f2; 1026 | -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1); 1027 | -moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1); 1028 | box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1); 1029 | } 1030 | .navbar-inverse .nav-collapse .navbar-form, 1031 | .navbar-inverse .nav-collapse .navbar-search { 1032 | border-top-color: #111111; 1033 | border-bottom-color: #111111; 1034 | } 1035 | .navbar .nav-collapse .nav.pull-right { 1036 | float: none; 1037 | margin-left: 0; 1038 | } 1039 | .nav-collapse, 1040 | .nav-collapse.collapse { 1041 | height: 0; 1042 | overflow: hidden; 1043 | } 1044 | .navbar .btn-navbar { 1045 | display: block; 1046 | } 1047 | .navbar-static .navbar-inner { 1048 | padding-right: 10px; 1049 | padding-left: 10px; 1050 | } 1051 | } 1052 | 1053 | @media (min-width: 980px) { 1054 | .nav-collapse.collapse { 1055 | height: auto !important; 1056 | overflow: visible !important; 1057 | } 1058 | } 1059 | -------------------------------------------------------------------------------- /js/bootstrap.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap.js by @fat & @mdo 3 | * Copyright 2012 Twitter, Inc. 4 | * http://www.apache.org/licenses/LICENSE-2.0.txt 5 | */ 6 | !function(e){"use strict";e(function(){e.support.transition=function(){var e=function(){var e=document.createElement("bootstrap"),t={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd otransitionend",transition:"transitionend"},n;for(n in t)if(e.style[n]!==undefined)return t[n]}();return e&&{end:e}}()})}(window.jQuery),!function(e){"use strict";var t='[data-dismiss="alert"]',n=function(n){e(n).on("click",t,this.close)};n.prototype.close=function(t){function s(){i.trigger("closed").remove()}var n=e(this),r=n.attr("data-target"),i;r||(r=n.attr("href"),r=r&&r.replace(/.*(?=#[^\s]*$)/,"")),i=e(r),t&&t.preventDefault(),i.length||(i=n.hasClass("alert")?n:n.parent()),i.trigger(t=e.Event("close"));if(t.isDefaultPrevented())return;i.removeClass("in"),e.support.transition&&i.hasClass("fade")?i.on(e.support.transition.end,s):s()};var r=e.fn.alert;e.fn.alert=function(t){return this.each(function(){var r=e(this),i=r.data("alert");i||r.data("alert",i=new n(this)),typeof t=="string"&&i[t].call(r)})},e.fn.alert.Constructor=n,e.fn.alert.noConflict=function(){return e.fn.alert=r,this},e(document).on("click.alert.data-api",t,n.prototype.close)}(window.jQuery),!function(e){"use strict";var t=function(t,n){this.$element=e(t),this.options=e.extend({},e.fn.button.defaults,n)};t.prototype.setState=function(e){var t="disabled",n=this.$element,r=n.data(),i=n.is("input")?"val":"html";e+="Text",r.resetText||n.data("resetText",n[i]()),n[i](r[e]||this.options[e]),setTimeout(function(){e=="loadingText"?n.addClass(t).attr(t,t):n.removeClass(t).removeAttr(t)},0)},t.prototype.toggle=function(){var e=this.$element.closest('[data-toggle="buttons-radio"]');e&&e.find(".active").removeClass("active"),this.$element.toggleClass("active")};var n=e.fn.button;e.fn.button=function(n){return this.each(function(){var r=e(this),i=r.data("button"),s=typeof n=="object"&&n;i||r.data("button",i=new t(this,s)),n=="toggle"?i.toggle():n&&i.setState(n)})},e.fn.button.defaults={loadingText:"loading..."},e.fn.button.Constructor=t,e.fn.button.noConflict=function(){return e.fn.button=n,this},e(document).on("click.button.data-api","[data-toggle^=button]",function(t){var n=e(t.target);n.hasClass("btn")||(n=n.closest(".btn")),n.button("toggle")})}(window.jQuery),!function(e){"use strict";var t=function(t,n){this.$element=e(t),this.$indicators=this.$element.find(".carousel-indicators"),this.options=n,this.options.pause=="hover"&&this.$element.on("mouseenter",e.proxy(this.pause,this)).on("mouseleave",e.proxy(this.cycle,this))};t.prototype={cycle:function(t){return t||(this.paused=!1),this.interval&&clearInterval(this.interval),this.options.interval&&!this.paused&&(this.interval=setInterval(e.proxy(this.next,this),this.options.interval)),this},getActiveIndex:function(){return this.$active=this.$element.find(".item.active"),this.$items=this.$active.parent().children(),this.$items.index(this.$active)},to:function(t){var n=this.getActiveIndex(),r=this;if(t>this.$items.length-1||t<0)return;return this.sliding?this.$element.one("slid",function(){r.to(t)}):n==t?this.pause().cycle():this.slide(t>n?"next":"prev",e(this.$items[t]))},pause:function(t){return t||(this.paused=!0),this.$element.find(".next, .prev").length&&e.support.transition.end&&(this.$element.trigger(e.support.transition.end),this.cycle(!0)),clearInterval(this.interval),this.interval=null,this},next:function(){if(this.sliding)return;return this.slide("next")},prev:function(){if(this.sliding)return;return this.slide("prev")},slide:function(t,n){var r=this.$element.find(".item.active"),i=n||r[t](),s=this.interval,o=t=="next"?"left":"right",u=t=="next"?"first":"last",a=this,f;this.sliding=!0,s&&this.pause(),i=i.length?i:this.$element.find(".item")[u](),f=e.Event("slide",{relatedTarget:i[0],direction:o});if(i.hasClass("active"))return;this.$indicators.length&&(this.$indicators.find(".active").removeClass("active"),this.$element.one("slid",function(){var t=e(a.$indicators.children()[a.getActiveIndex()]);t&&t.addClass("active")}));if(e.support.transition&&this.$element.hasClass("slide")){this.$element.trigger(f);if(f.isDefaultPrevented())return;i.addClass(t),i[0].offsetWidth,r.addClass(o),i.addClass(o),this.$element.one(e.support.transition.end,function(){i.removeClass([t,o].join(" ")).addClass("active"),r.removeClass(["active",o].join(" ")),a.sliding=!1,setTimeout(function(){a.$element.trigger("slid")},0)})}else{this.$element.trigger(f);if(f.isDefaultPrevented())return;r.removeClass("active"),i.addClass("active"),this.sliding=!1,this.$element.trigger("slid")}return s&&this.cycle(),this}};var n=e.fn.carousel;e.fn.carousel=function(n){return this.each(function(){var r=e(this),i=r.data("carousel"),s=e.extend({},e.fn.carousel.defaults,typeof n=="object"&&n),o=typeof n=="string"?n:s.slide;i||r.data("carousel",i=new t(this,s)),typeof n=="number"?i.to(n):o?i[o]():s.interval&&i.pause().cycle()})},e.fn.carousel.defaults={interval:5e3,pause:"hover"},e.fn.carousel.Constructor=t,e.fn.carousel.noConflict=function(){return e.fn.carousel=n,this},e(document).on("click.carousel.data-api","[data-slide], [data-slide-to]",function(t){var n=e(this),r,i=e(n.attr("data-target")||(r=n.attr("href"))&&r.replace(/.*(?=#[^\s]+$)/,"")),s=e.extend({},i.data(),n.data()),o;i.carousel(s),(o=n.attr("data-slide-to"))&&i.data("carousel").pause().to(o).cycle(),t.preventDefault()})}(window.jQuery),!function(e){"use strict";var t=function(t,n){this.$element=e(t),this.options=e.extend({},e.fn.collapse.defaults,n),this.options.parent&&(this.$parent=e(this.options.parent)),this.options.toggle&&this.toggle()};t.prototype={constructor:t,dimension:function(){var e=this.$element.hasClass("width");return e?"width":"height"},show:function(){var t,n,r,i;if(this.transitioning||this.$element.hasClass("in"))return;t=this.dimension(),n=e.camelCase(["scroll",t].join("-")),r=this.$parent&&this.$parent.find("> .accordion-group > .in");if(r&&r.length){i=r.data("collapse");if(i&&i.transitioning)return;r.collapse("hide"),i||r.data("collapse",null)}this.$element[t](0),this.transition("addClass",e.Event("show"),"shown"),e.support.transition&&this.$element[t](this.$element[0][n])},hide:function(){var t;if(this.transitioning||!this.$element.hasClass("in"))return;t=this.dimension(),this.reset(this.$element[t]()),this.transition("removeClass",e.Event("hide"),"hidden"),this.$element[t](0)},reset:function(e){var t=this.dimension();return this.$element.removeClass("collapse")[t](e||"auto")[0].offsetWidth,this.$element[e!==null?"addClass":"removeClass"]("collapse"),this},transition:function(t,n,r){var i=this,s=function(){n.type=="show"&&i.reset(),i.transitioning=0,i.$element.trigger(r)};this.$element.trigger(n);if(n.isDefaultPrevented())return;this.transitioning=1,this.$element[t]("in"),e.support.transition&&this.$element.hasClass("collapse")?this.$element.one(e.support.transition.end,s):s()},toggle:function(){this[this.$element.hasClass("in")?"hide":"show"]()}};var n=e.fn.collapse;e.fn.collapse=function(n){return this.each(function(){var r=e(this),i=r.data("collapse"),s=e.extend({},e.fn.collapse.defaults,r.data(),typeof n=="object"&&n);i||r.data("collapse",i=new t(this,s)),typeof n=="string"&&i[n]()})},e.fn.collapse.defaults={toggle:!0},e.fn.collapse.Constructor=t,e.fn.collapse.noConflict=function(){return e.fn.collapse=n,this},e(document).on("click.collapse.data-api","[data-toggle=collapse]",function(t){var n=e(this),r,i=n.attr("data-target")||t.preventDefault()||(r=n.attr("href"))&&r.replace(/.*(?=#[^\s]+$)/,""),s=e(i).data("collapse")?"toggle":n.data();n[e(i).hasClass("in")?"addClass":"removeClass"]("collapsed"),e(i).collapse(s)})}(window.jQuery),!function(e){"use strict";function r(){e(t).each(function(){i(e(this)).removeClass("open")})}function i(t){var n=t.attr("data-target"),r;n||(n=t.attr("href"),n=n&&/#/.test(n)&&n.replace(/.*(?=#[^\s]*$)/,"")),r=n&&e(n);if(!r||!r.length)r=t.parent();return r}var t="[data-toggle=dropdown]",n=function(t){var n=e(t).on("click.dropdown.data-api",this.toggle);e("html").on("click.dropdown.data-api",function(){n.parent().removeClass("open")})};n.prototype={constructor:n,toggle:function(t){var n=e(this),s,o;if(n.is(".disabled, :disabled"))return;return s=i(n),o=s.hasClass("open"),r(),o||s.toggleClass("open"),n.focus(),!1},keydown:function(n){var r,s,o,u,a,f;if(!/(38|40|27)/.test(n.keyCode))return;r=e(this),n.preventDefault(),n.stopPropagation();if(r.is(".disabled, :disabled"))return;u=i(r),a=u.hasClass("open");if(!a||a&&n.keyCode==27)return n.which==27&&u.find(t).focus(),r.click();s=e("[role=menu] li:not(.divider):visible a",u);if(!s.length)return;f=s.index(s.filter(":focus")),n.keyCode==38&&f>0&&f--,n.keyCode==40&&f').appendTo(document.body),this.$backdrop.click(this.options.backdrop=="static"?e.proxy(this.$element[0].focus,this.$element[0]):e.proxy(this.hide,this)),i&&this.$backdrop[0].offsetWidth,this.$backdrop.addClass("in");if(!t)return;i?this.$backdrop.one(e.support.transition.end,t):t()}else!this.isShown&&this.$backdrop?(this.$backdrop.removeClass("in"),e.support.transition&&this.$element.hasClass("fade")?this.$backdrop.one(e.support.transition.end,t):t()):t&&t()}};var n=e.fn.modal;e.fn.modal=function(n){return this.each(function(){var r=e(this),i=r.data("modal"),s=e.extend({},e.fn.modal.defaults,r.data(),typeof n=="object"&&n);i||r.data("modal",i=new t(this,s)),typeof n=="string"?i[n]():s.show&&i.show()})},e.fn.modal.defaults={backdrop:!0,keyboard:!0,show:!0},e.fn.modal.Constructor=t,e.fn.modal.noConflict=function(){return e.fn.modal=n,this},e(document).on("click.modal.data-api",'[data-toggle="modal"]',function(t){var n=e(this),r=n.attr("href"),i=e(n.attr("data-target")||r&&r.replace(/.*(?=#[^\s]+$)/,"")),s=i.data("modal")?"toggle":e.extend({remote:!/#/.test(r)&&r},i.data(),n.data());t.preventDefault(),i.modal(s).one("hide",function(){n.focus()})})}(window.jQuery),!function(e){"use strict";var t=function(e,t){this.init("tooltip",e,t)};t.prototype={constructor:t,init:function(t,n,r){var i,s,o,u,a;this.type=t,this.$element=e(n),this.options=this.getOptions(r),this.enabled=!0,o=this.options.trigger.split(" ");for(a=o.length;a--;)u=o[a],u=="click"?this.$element.on("click."+this.type,this.options.selector,e.proxy(this.toggle,this)):u!="manual"&&(i=u=="hover"?"mouseenter":"focus",s=u=="hover"?"mouseleave":"blur",this.$element.on(i+"."+this.type,this.options.selector,e.proxy(this.enter,this)),this.$element.on(s+"."+this.type,this.options.selector,e.proxy(this.leave,this)));this.options.selector?this._options=e.extend({},this.options,{trigger:"manual",selector:""}):this.fixTitle()},getOptions:function(t){return t=e.extend({},e.fn[this.type].defaults,this.$element.data(),t),t.delay&&typeof t.delay=="number"&&(t.delay={show:t.delay,hide:t.delay}),t},enter:function(t){var n=e.fn[this.type].defaults,r={},i;this._options&&e.each(this._options,function(e,t){n[e]!=t&&(r[e]=t)},this),i=e(t.currentTarget)[this.type](r).data(this.type);if(!i.options.delay||!i.options.delay.show)return i.show();clearTimeout(this.timeout),i.hoverState="in",this.timeout=setTimeout(function(){i.hoverState=="in"&&i.show()},i.options.delay.show)},leave:function(t){var n=e(t.currentTarget)[this.type](this._options).data(this.type);this.timeout&&clearTimeout(this.timeout);if(!n.options.delay||!n.options.delay.hide)return n.hide();n.hoverState="out",this.timeout=setTimeout(function(){n.hoverState=="out"&&n.hide()},n.options.delay.hide)},show:function(){var t,n,r,i,s,o,u=e.Event("show");if(this.hasContent()&&this.enabled){this.$element.trigger(u);if(u.isDefaultPrevented())return;t=this.tip(),this.setContent(),this.options.animation&&t.addClass("fade"),s=typeof this.options.placement=="function"?this.options.placement.call(this,t[0],this.$element[0]):this.options.placement,t.detach().css({top:0,left:0,display:"block"}),this.options.container?t.appendTo(this.options.container):t.insertAfter(this.$element),n=this.getPosition(),r=t[0].offsetWidth,i=t[0].offsetHeight;switch(s){case"bottom":o={top:n.top+n.height,left:n.left+n.width/2-r/2};break;case"top":o={top:n.top-i,left:n.left+n.width/2-r/2};break;case"left":o={top:n.top+n.height/2-i/2,left:n.left-r};break;case"right":o={top:n.top+n.height/2-i/2,left:n.left+n.width}}this.applyPlacement(o,s),this.$element.trigger("shown")}},applyPlacement:function(e,t){var n=this.tip(),r=n[0].offsetWidth,i=n[0].offsetHeight,s,o,u,a;n.offset(e).addClass(t).addClass("in"),s=n[0].offsetWidth,o=n[0].offsetHeight,t=="top"&&o!=i&&(e.top=e.top+i-o,a=!0),t=="bottom"||t=="top"?(u=0,e.left<0&&(u=e.left*-2,e.left=0,n.offset(e),s=n[0].offsetWidth,o=n[0].offsetHeight),this.replaceArrow(u-r+s,s,"left")):this.replaceArrow(o-i,o,"top"),a&&n.offset(e)},replaceArrow:function(e,t,n){this.arrow().css(n,e?50*(1-e/t)+"%":"")},setContent:function(){var e=this.tip(),t=this.getTitle();e.find(".tooltip-inner")[this.options.html?"html":"text"](t),e.removeClass("fade in top bottom left right")},hide:function(){function i(){var t=setTimeout(function(){n.off(e.support.transition.end).detach()},500);n.one(e.support.transition.end,function(){clearTimeout(t),n.detach()})}var t=this,n=this.tip(),r=e.Event("hide");this.$element.trigger(r);if(r.isDefaultPrevented())return;return n.removeClass("in"),e.support.transition&&this.$tip.hasClass("fade")?i():n.detach(),this.$element.trigger("hidden"),this},fixTitle:function(){var e=this.$element;(e.attr("title")||typeof e.attr("data-original-title")!="string")&&e.attr("data-original-title",e.attr("title")||"").attr("title","")},hasContent:function(){return this.getTitle()},getPosition:function(){var t=this.$element[0];return e.extend({},typeof t.getBoundingClientRect=="function"?t.getBoundingClientRect():{width:t.offsetWidth,height:t.offsetHeight},this.$element.offset())},getTitle:function(){var e,t=this.$element,n=this.options;return e=t.attr("data-original-title")||(typeof n.title=="function"?n.title.call(t[0]):n.title),e},tip:function(){return this.$tip=this.$tip||e(this.options.template)},arrow:function(){return this.$arrow=this.$arrow||this.tip().find(".tooltip-arrow")},validate:function(){this.$element[0].parentNode||(this.hide(),this.$element=null,this.options=null)},enable:function(){this.enabled=!0},disable:function(){this.enabled=!1},toggleEnabled:function(){this.enabled=!this.enabled},toggle:function(t){var n=t?e(t.currentTarget)[this.type](this._options).data(this.type):this;n.tip().hasClass("in")?n.hide():n.show()},destroy:function(){this.hide().$element.off("."+this.type).removeData(this.type)}};var n=e.fn.tooltip;e.fn.tooltip=function(n){return this.each(function(){var r=e(this),i=r.data("tooltip"),s=typeof n=="object"&&n;i||r.data("tooltip",i=new t(this,s)),typeof n=="string"&&i[n]()})},e.fn.tooltip.Constructor=t,e.fn.tooltip.defaults={animation:!0,placement:"top",selector:!1,template:'
',trigger:"hover focus",title:"",delay:0,html:!1,container:!1},e.fn.tooltip.noConflict=function(){return e.fn.tooltip=n,this}}(window.jQuery),!function(e){"use strict";var t=function(e,t){this.init("popover",e,t)};t.prototype=e.extend({},e.fn.tooltip.Constructor.prototype,{constructor:t,setContent:function(){var e=this.tip(),t=this.getTitle(),n=this.getContent();e.find(".popover-title")[this.options.html?"html":"text"](t),e.find(".popover-content")[this.options.html?"html":"text"](n),e.removeClass("fade top bottom left right in")},hasContent:function(){return this.getTitle()||this.getContent()},getContent:function(){var e,t=this.$element,n=this.options;return e=(typeof n.content=="function"?n.content.call(t[0]):n.content)||t.attr("data-content"),e},tip:function(){return this.$tip||(this.$tip=e(this.options.template)),this.$tip},destroy:function(){this.hide().$element.off("."+this.type).removeData(this.type)}});var n=e.fn.popover;e.fn.popover=function(n){return this.each(function(){var r=e(this),i=r.data("popover"),s=typeof n=="object"&&n;i||r.data("popover",i=new t(this,s)),typeof n=="string"&&i[n]()})},e.fn.popover.Constructor=t,e.fn.popover.defaults=e.extend({},e.fn.tooltip.defaults,{placement:"right",trigger:"click",content:"",template:'

'}),e.fn.popover.noConflict=function(){return e.fn.popover=n,this}}(window.jQuery),!function(e){"use strict";function t(t,n){var r=e.proxy(this.process,this),i=e(t).is("body")?e(window):e(t),s;this.options=e.extend({},e.fn.scrollspy.defaults,n),this.$scrollElement=i.on("scroll.scroll-spy.data-api",r),this.selector=(this.options.target||(s=e(t).attr("href"))&&s.replace(/.*(?=#[^\s]+$)/,"")||"")+" .nav li > a",this.$body=e("body"),this.refresh(),this.process()}t.prototype={constructor:t,refresh:function(){var t=this,n;this.offsets=e([]),this.targets=e([]),n=this.$body.find(this.selector).map(function(){var n=e(this),r=n.data("target")||n.attr("href"),i=/^#\w/.test(r)&&e(r);return i&&i.length&&[[i.position().top+(!e.isWindow(t.$scrollElement.get(0))&&t.$scrollElement.scrollTop()),r]]||null}).sort(function(e,t){return e[0]-t[0]}).each(function(){t.offsets.push(this[0]),t.targets.push(this[1])})},process:function(){var e=this.$scrollElement.scrollTop()+this.options.offset,t=this.$scrollElement[0].scrollHeight||this.$body[0].scrollHeight,n=t-this.$scrollElement.height(),r=this.offsets,i=this.targets,s=this.activeTarget,o;if(e>=n)return s!=(o=i.last()[0])&&this.activate(o);for(o=r.length;o--;)s!=i[o]&&e>=r[o]&&(!r[o+1]||e<=r[o+1])&&this.activate(i[o])},activate:function(t){var n,r;this.activeTarget=t,e(this.selector).parent(".active").removeClass("active"),r=this.selector+'[data-target="'+t+'"],'+this.selector+'[href="'+t+'"]',n=e(r).parent("li").addClass("active"),n.parent(".dropdown-menu").length&&(n=n.closest("li.dropdown").addClass("active")),n.trigger("activate")}};var n=e.fn.scrollspy;e.fn.scrollspy=function(n){return this.each(function(){var r=e(this),i=r.data("scrollspy"),s=typeof n=="object"&&n;i||r.data("scrollspy",i=new t(this,s)),typeof n=="string"&&i[n]()})},e.fn.scrollspy.Constructor=t,e.fn.scrollspy.defaults={offset:10},e.fn.scrollspy.noConflict=function(){return e.fn.scrollspy=n,this},e(window).on("load",function(){e('[data-spy="scroll"]').each(function(){var t=e(this);t.scrollspy(t.data())})})}(window.jQuery),!function(e){"use strict";var t=function(t){this.element=e(t)};t.prototype={constructor:t,show:function(){var t=this.element,n=t.closest("ul:not(.dropdown-menu)"),r=t.attr("data-target"),i,s,o;r||(r=t.attr("href"),r=r&&r.replace(/.*(?=#[^\s]*$)/,""));if(t.parent("li").hasClass("active"))return;i=n.find(".active:last a")[0],o=e.Event("show",{relatedTarget:i}),t.trigger(o);if(o.isDefaultPrevented())return;s=e(r),this.activate(t.parent("li"),n),this.activate(s,s.parent(),function(){t.trigger({type:"shown",relatedTarget:i})})},activate:function(t,n,r){function o(){i.removeClass("active").find("> .dropdown-menu > .active").removeClass("active"),t.addClass("active"),s?(t[0].offsetWidth,t.addClass("in")):t.removeClass("fade"),t.parent(".dropdown-menu")&&t.closest("li.dropdown").addClass("active"),r&&r()}var i=n.find("> .active"),s=r&&e.support.transition&&i.hasClass("fade");s?i.one(e.support.transition.end,o):o(),i.removeClass("in")}};var n=e.fn.tab;e.fn.tab=function(n){return this.each(function(){var r=e(this),i=r.data("tab");i||r.data("tab",i=new t(this)),typeof n=="string"&&i[n]()})},e.fn.tab.Constructor=t,e.fn.tab.noConflict=function(){return e.fn.tab=n,this},e(document).on("click.tab.data-api",'[data-toggle="tab"], [data-toggle="pill"]',function(t){t.preventDefault(),e(this).tab("show")})}(window.jQuery),!function(e){"use strict";var t=function(t,n){this.$element=e(t),this.options=e.extend({},e.fn.typeahead.defaults,n),this.matcher=this.options.matcher||this.matcher,this.sorter=this.options.sorter||this.sorter,this.highlighter=this.options.highlighter||this.highlighter,this.updater=this.options.updater||this.updater,this.source=this.options.source,this.$menu=e(this.options.menu),this.shown=!1,this.listen()};t.prototype={constructor:t,select:function(){var e=this.$menu.find(".active").attr("data-value");return this.$element.val(this.updater(e)).change(),this.hide()},updater:function(e){return e},show:function(){var t=e.extend({},this.$element.position(),{height:this.$element[0].offsetHeight});return this.$menu.insertAfter(this.$element).css({top:t.top+t.height,left:t.left}).show(),this.shown=!0,this},hide:function(){return this.$menu.hide(),this.shown=!1,this},lookup:function(t){var n;return this.query=this.$element.val(),!this.query||this.query.length"+t+""})},render:function(t){var n=this;return t=e(t).map(function(t,r){return t=e(n.options.item).attr("data-value",r),t.find("a").html(n.highlighter(r)),t[0]}),t.first().addClass("active"),this.$menu.html(t),this},next:function(t){var n=this.$menu.find(".active").removeClass("active"),r=n.next();r.length||(r=e(this.$menu.find("li")[0])),r.addClass("active")},prev:function(e){var t=this.$menu.find(".active").removeClass("active"),n=t.prev();n.length||(n=this.$menu.find("li").last()),n.addClass("active")},listen:function(){this.$element.on("focus",e.proxy(this.focus,this)).on("blur",e.proxy(this.blur,this)).on("keypress",e.proxy(this.keypress,this)).on("keyup",e.proxy(this.keyup,this)),this.eventSupported("keydown")&&this.$element.on("keydown",e.proxy(this.keydown,this)),this.$menu.on("click",e.proxy(this.click,this)).on("mouseenter","li",e.proxy(this.mouseenter,this)).on("mouseleave","li",e.proxy(this.mouseleave,this))},eventSupported:function(e){var t=e in this.$element;return t||(this.$element.setAttribute(e,"return;"),t=typeof this.$element[e]=="function"),t},move:function(e){if(!this.shown)return;switch(e.keyCode){case 9:case 13:case 27:e.preventDefault();break;case 38:e.preventDefault(),this.prev();break;case 40:e.preventDefault(),this.next()}e.stopPropagation()},keydown:function(t){this.suppressKeyPressRepeat=~e.inArray(t.keyCode,[40,38,9,13,27]),this.move(t)},keypress:function(e){if(this.suppressKeyPressRepeat)return;this.move(e)},keyup:function(e){switch(e.keyCode){case 40:case 38:case 16:case 17:case 18:break;case 9:case 13:if(!this.shown)return;this.select();break;case 27:if(!this.shown)return;this.hide();break;default:this.lookup()}e.stopPropagation(),e.preventDefault()},focus:function(e){this.focused=!0},blur:function(e){this.focused=!1,!this.mousedover&&this.shown&&this.hide()},click:function(e){e.stopPropagation(),e.preventDefault(),this.select(),this.$element.focus()},mouseenter:function(t){this.mousedover=!0,this.$menu.find(".active").removeClass("active"),e(t.currentTarget).addClass("active")},mouseleave:function(e){this.mousedover=!1,!this.focused&&this.shown&&this.hide()}};var n=e.fn.typeahead;e.fn.typeahead=function(n){return this.each(function(){var r=e(this),i=r.data("typeahead"),s=typeof n=="object"&&n;i||r.data("typeahead",i=new t(this,s)),typeof n=="string"&&i[n]()})},e.fn.typeahead.defaults={source:[],items:8,menu:'',item:'
  • ',minLength:1},e.fn.typeahead.Constructor=t,e.fn.typeahead.noConflict=function(){return e.fn.typeahead=n,this},e(document).on("focus.typeahead.data-api",'[data-provide="typeahead"]',function(t){var n=e(this);if(n.data("typeahead"))return;n.typeahead(n.data())})}(window.jQuery),!function(e){"use strict";var t=function(t,n){this.options=e.extend({},e.fn.affix.defaults,n),this.$window=e(window).on("scroll.affix.data-api",e.proxy(this.checkPosition,this)).on("click.affix.data-api",e.proxy(function(){setTimeout(e.proxy(this.checkPosition,this),1)},this)),this.$element=e(t),this.checkPosition()};t.prototype.checkPosition=function(){if(!this.$element.is(":visible"))return;var t=e(document).height(),n=this.$window.scrollTop(),r=this.$element.offset(),i=this.options.offset,s=i.bottom,o=i.top,u="affix affix-top affix-bottom",a;typeof i!="object"&&(s=o=i),typeof o=="function"&&(o=i.top()),typeof s=="function"&&(s=i.bottom()),a=this.unpin!=null&&n+this.unpin<=r.top?!1:s!=null&&r.top+this.$element.height()>=t-s?"bottom":o!=null&&n<=o?"top":!1;if(this.affixed===a)return;this.affixed=a,this.unpin=a=="bottom"?r.top-n:null,this.$element.removeClass(u).addClass("affix"+(a?"-"+a:""))};var n=e.fn.affix;e.fn.affix=function(n){return this.each(function(){var r=e(this),i=r.data("affix"),s=typeof n=="object"&&n;i||r.data("affix",i=new t(this,s)),typeof n=="string"&&i[n]()})},e.fn.affix.Constructor=t,e.fn.affix.defaults={offset:0},e.fn.affix.noConflict=function(){return e.fn.affix=n,this},e(window).on("load",function(){e('[data-spy="affix"]').each(function(){var t=e(this),n=t.data();n.offset=n.offset||{},n.offsetBottom&&(n.offset.bottom=n.offsetBottom),n.offsetTop&&(n.offset.top=n.offsetTop),t.affix(n)})})}(window.jQuery); --------------------------------------------------------------------------------