├── test ├── data │ ├── tracks.conf │ ├── tracks │ │ ├── genes │ │ │ └── Chr5 │ │ │ │ ├── hist-20000-0.json │ │ │ │ ├── names.txt │ │ │ │ └── trackData.json │ │ └── tes │ │ │ └── Chr5 │ │ │ ├── hist-5000-0.json │ │ │ ├── names.txt │ │ │ └── trackData.json │ ├── test_smrna_short.bw │ ├── names │ │ ├── meta.json │ │ ├── d.json │ │ ├── 2.json │ │ ├── 0.json │ │ ├── 8.json │ │ ├── 7.json │ │ ├── 1.json │ │ ├── e.json │ │ ├── 9.json │ │ ├── 6.json │ │ ├── 4.json │ │ ├── f.json │ │ ├── a.json │ │ ├── 3.json │ │ ├── b.json │ │ ├── 5.json │ │ └── c.json │ ├── test_smrna_short_adjusted.bam │ ├── seq │ │ ├── refSeqs.json │ │ └── a59 │ │ │ └── b6d │ │ │ └── 00 │ │ │ ├── Chr5-2.txt │ │ │ ├── Chr5-0.txt │ │ │ └── Chr5-1.txt │ ├── test_smrna_short_adjusted.bam.bai │ ├── .htaccess │ └── trackList.json ├── index.html ├── run-jasmine.js └── spec │ └── SmallRNAPlugin.spec.js ├── .gitignore ├── img ├── demo_image.png ├── checkmark-red.png ├── smrna-filter.png ├── checkmark-blue.png ├── checkmark-gray.png ├── checkmark-green.png ├── demo_image_old.png ├── checkmark-orange.png ├── checkmark-purple.png ├── checkmark-yellow.png └── smrna-filter-blank.png ├── .jsbeautifyrc ├── .travis.yml ├── LICENSE ├── package.json ├── js ├── SmallRNAPlugin.profile.js ├── View │ ├── Dialog │ │ ├── QualityFilterDialog.js │ │ └── ReadFilterDialogCheck.js │ ├── Track │ │ ├── _NamedFeatureFiltersMixin.js │ │ ├── _AlignmentsMixin.js │ │ ├── smAlignments.js │ │ └── smHTMLAlignments.js │ ├── FeatureGlyph │ │ └── smAlignment.js │ └── StrandedBitmapRectLayout.js └── main.js ├── CHANGELOG.md ├── css └── main.css ├── yarn.lock └── README.md /test/data/tracks.conf: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/data/tracks/genes/Chr5/hist-20000-0.json: -------------------------------------------------------------------------------- 1 | [1,2,5] 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | npm-debug.log 3 | node_modules 4 | built -------------------------------------------------------------------------------- /test/data/tracks/tes/Chr5/hist-5000-0.json: -------------------------------------------------------------------------------- 1 | [3,6,1,5,5,2,3,4,5,2] 2 | -------------------------------------------------------------------------------- /img/demo_image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bhofmei/jbplugin-smallrna/HEAD/img/demo_image.png -------------------------------------------------------------------------------- /img/checkmark-red.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bhofmei/jbplugin-smallrna/HEAD/img/checkmark-red.png -------------------------------------------------------------------------------- /img/smrna-filter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bhofmei/jbplugin-smallrna/HEAD/img/smrna-filter.png -------------------------------------------------------------------------------- /img/checkmark-blue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bhofmei/jbplugin-smallrna/HEAD/img/checkmark-blue.png -------------------------------------------------------------------------------- /img/checkmark-gray.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bhofmei/jbplugin-smallrna/HEAD/img/checkmark-gray.png -------------------------------------------------------------------------------- /img/checkmark-green.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bhofmei/jbplugin-smallrna/HEAD/img/checkmark-green.png -------------------------------------------------------------------------------- /img/demo_image_old.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bhofmei/jbplugin-smallrna/HEAD/img/demo_image_old.png -------------------------------------------------------------------------------- /img/checkmark-orange.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bhofmei/jbplugin-smallrna/HEAD/img/checkmark-orange.png -------------------------------------------------------------------------------- /img/checkmark-purple.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bhofmei/jbplugin-smallrna/HEAD/img/checkmark-purple.png -------------------------------------------------------------------------------- /img/checkmark-yellow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bhofmei/jbplugin-smallrna/HEAD/img/checkmark-yellow.png -------------------------------------------------------------------------------- /img/smrna-filter-blank.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bhofmei/jbplugin-smallrna/HEAD/img/smrna-filter-blank.png -------------------------------------------------------------------------------- /test/data/test_smrna_short.bw: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bhofmei/jbplugin-smallrna/HEAD/test/data/test_smrna_short.bw -------------------------------------------------------------------------------- /.jsbeautifyrc: -------------------------------------------------------------------------------- 1 | { 2 | "js": { 3 | "keep_array_indentation": false, 4 | "break_chained_methods": true, 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /test/data/names/meta.json: -------------------------------------------------------------------------------- 1 | {"hash_bits":"4","lowercase_keys":1,"track_names":["genes","tes"],"format":"json","compress":0} 2 | -------------------------------------------------------------------------------- /test/data/test_smrna_short_adjusted.bam: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bhofmei/jbplugin-smallrna/HEAD/test/data/test_smrna_short_adjusted.bam -------------------------------------------------------------------------------- /test/data/seq/refSeqs.json: -------------------------------------------------------------------------------- 1 | [{"length":50001,"seqChunkSize":20000,"end":50001,"name":"Chr5","description":"Chr5:12550003..12600003","start":0}] 2 | -------------------------------------------------------------------------------- /test/data/test_smrna_short_adjusted.bam.bai: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bhofmei/jbplugin-smallrna/HEAD/test/data/test_smrna_short_adjusted.bam.bai -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - 7 4 | sudo: false 5 | cache: 6 | - pip 7 | - yarn 8 | before_install: 9 | - pip install --user RangeHTTPServer 10 | install: 11 | - TRAVIS_CI=1 yarn install 12 | before_script: 13 | - python -m RangeHTTPServer & 14 | script: 15 | - phantomjs test/run-jasmine.js http://localhost:8000/test/ 16 | -------------------------------------------------------------------------------- /test/data/names/d.json: -------------------------------------------------------------------------------- 1 | {"at5g332":{"exact":[],"prefix":["AT5G33285"]},"at5g3330":{"exact":[],"prefix":["AT5G33300","AT5G33306"]},"at5te44485":{"exact":[["AT5TE44485",1,"AT5TE44485","Chr5",9661,9965]],"prefix":[]},"tat":{"exact":[],"prefix":["TAT1_ATH"]},"atlantys":{"prefix":["ATLANTYS1"],"exact":[]},"at5te44470":{"prefix":[],"exact":[["AT5TE44470",1,"AT5TE44470","Chr5",4220,5365]]}} 2 | -------------------------------------------------------------------------------- /test/data/names/2.json: -------------------------------------------------------------------------------- 1 | {"brodyag":{"prefix":["BRODYAGA1A"],"exact":[]},"at5te44480":{"prefix":[],"exact":[["AT5TE44480",1,"AT5TE44480","Chr5",9380,9661]]},"atm":{"exact":[],"prefix":["ATMUNX1"]},"helitron2":{"prefix":[],"exact":[["HELITRON2",1,"AT5TE44615","Chr5",44043,44283]]},"me":{"exact":[],"prefix":["META1"]},"at5g3335":{"exact":[],"prefix":["AT5G33350","AT5G33355"]},"at5te44475":{"exact":[["AT5TE44475",1,"AT5TE44475","Chr5",7462,8196]],"prefix":[]},"atlanty":{"prefix":["ATLANTYS1"],"exact":[]}} 2 | -------------------------------------------------------------------------------- /test/data/tracks/genes/Chr5/names.txt: -------------------------------------------------------------------------------- 1 | [["AT5G33300","AT5G33300"],"genes","AT5G33300","Chr5",12426,15754] 2 | [["AT5G33310","AT5G33310"],"genes","AT5G33310","Chr5",27317,32196] 3 | [["AT5G33320","AT5G33320"],"genes","AT5G33320","Chr5",38834,41745] 4 | [["AT5G33330","AT5G33330"],"genes","AT5G33330","Chr5",41679,42893] 5 | [["AT5G33340","AT5G33340"],"genes","AT5G33340","Chr5",44463,45949] 6 | [["AT5G33350","AT5G33350"],"genes","AT5G33350","Chr5",46781,48095] 7 | [["AT5G33355","AT5G33355"],"genes","AT5G33355","Chr5",49249,49668] 8 | -------------------------------------------------------------------------------- /test/data/names/0.json: -------------------------------------------------------------------------------- 1 | {"at5te4452":{"prefix":["AT5TE44520","AT5TE44525"],"exact":[]},"tat1_a":{"prefix":["TAT1_ATH"],"exact":[]},"meta1":{"prefix":[],"exact":[["META1",1,"AT5TE44535","Chr5",19135,19601]]},"brodyaga":{"exact":[],"prefix":["BRODYAGA1A"]},"brodyaga1":{"exact":[],"prefix":["BRODYAGA1A"]},"atdna":{"prefix":["ATDNA1T9A","ATDNA2T9C"],"exact":[]},"at5te44525":{"prefix":[],"exact":[["AT5TE44525",1,"AT5TE44525","Chr5",16839,18018]]},"arnoldy2":{"prefix":[],"exact":[["ARNOLDY2",1,"AT5TE44580","Chr5",35230,35856]]},"atcopia":{"prefix":["ATCOPIA30","ATCOPIA28"],"exact":[]}} 2 | -------------------------------------------------------------------------------- /test/data/.htaccess: -------------------------------------------------------------------------------- 1 | # This Apache .htaccess file is generated by JBrowse (GenomeDB) for 2 | # allowing cross-origin requests as defined by the Cross-Origin 3 | # Resource Sharing working draft from the W3C 4 | # (http://www.w3.org/TR/cors/). In order for Apache to pay attention 5 | # to this, it must have mod_headers enabled, and its AllowOverride 6 | # configuration directive must allow FileInfo overrides. 7 | 8 | Header onsuccess set Access-Control-Allow-Origin * 9 | Header onsuccess set Access-Control-Allow-Headers X-Requested-With,Range 10 | 11 | -------------------------------------------------------------------------------- /test/data/names/8.json: -------------------------------------------------------------------------------- 1 | {"atrep10":{"exact":[],"prefix":["ATREP10B","ATREP10D"]},"at5te44550":{"prefix":[],"exact":[["AT5TE44550",1,"AT5TE44550","Chr5",21977,22589]]},"tat1_ath":{"prefix":[],"exact":[["TAT1_ATH",1,"AT5TE44550","Chr5",21977,22589],["TAT1_ATH",1,"AT5TE44565","Chr5",32312,32399]]},"t":{"prefix":["TAT1_ATH"],"exact":[]},"at5te4459":{"prefix":["AT5TE44590","AT5TE44595"],"exact":[]},"at5g33330":{"exact":[["AT5G33330",0,"AT5G33330","Chr5",41679,42893]],"prefix":[]},"at5te4446":{"exact":[],"prefix":["AT5TE44460","AT5TE44465"]},"tat1":{"prefix":["TAT1_ATH"],"exact":[]},"m":{"prefix":["META1"],"exact":[]}} 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2017 Brigitte Hofmeister 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. 5 | You may obtain a copy of the License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software 10 | distributed under the License is distributed on an "AS IS" BASIS, 11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | See the License for the specific language governing permissions and 13 | limitations under the License. -------------------------------------------------------------------------------- /test/data/names/7.json: -------------------------------------------------------------------------------- 1 | {"at5g3333":{"exact":[],"prefix":["AT5G33330"]},"atr":{"exact":[],"prefix":["ATREP11","ATREP15","ATREP10B","ATREP10D","ATREP3","ATREP9"]},"atrep15":{"prefix":[],"exact":[["ATREP15",1,"AT5TE44475","Chr5",7462,8196],["ATREP15",1,"AT5TE44525","Chr5",16839,18018]]},"at5te44555":{"exact":[["AT5TE44555",1,"AT5TE44555","Chr5",23003,27141]],"prefix":[]},"he":{"exact":[],"prefix":["HELITRONY1E","HELITRONY3","HELITRONY1D","HELITRON2"]},"h":{"exact":[],"prefix":["HELITRONY1E","HELITRONY3","HELITRONY1D","HELITRON2"]},"helitrony1d":{"prefix":[],"exact":[["HELITRONY1D",1,"AT5TE44575","Chr5",33705,34145],["HELITRONY1D",1,"AT5TE44620","Chr5",45912,46508]]}} 2 | -------------------------------------------------------------------------------- /test/data/names/1.json: -------------------------------------------------------------------------------- 1 | {"atrep9":{"prefix":[],"exact":[["ATREP9",1,"AT5TE44605","Chr5",43348,43955]]},"helitro":{"exact":[],"prefix":["HELITRONY1E","HELITRONY3","HELITRONY1D","HELITRON2"]},"bro":{"prefix":["BRODYAGA1A"],"exact":[]},"atdna1":{"prefix":["ATDNA1T9A"],"exact":[]},"at5g33355":{"exact":[["AT5G33355",0,"AT5G33355","Chr5",49249,49668]],"prefix":[]},"atli":{"exact":[],"prefix":["ATLINE1A"]},"ch":{"prefix":["Chr5"],"exact":[]},"atmunx":{"prefix":["ATMUNX1"],"exact":[]},"brody":{"prefix":["BRODYAGA1A"],"exact":[]},"at5g3332":{"exact":[],"prefix":["AT5G33320"]},"helitrony1e":{"exact":[["HELITRONY1E",1,"AT5TE44460","Chr5",3821,4012]],"prefix":[]},"at5te44535":{"prefix":[],"exact":[["AT5TE44535",1,"AT5TE44535","Chr5",19135,19601]]}} 2 | -------------------------------------------------------------------------------- /test/data/names/e.json: -------------------------------------------------------------------------------- 1 | {"at5te44530":{"prefix":[],"exact":[["AT5TE44530",1,"AT5TE44530","Chr5",18308,19135]]},"atline1a":{"exact":[["ATLINE1A",1,"AT5TE44600","Chr5",43008,43348]],"prefix":[]},"arn":{"exact":[],"prefix":["ARNOLDY2"]},"chr5":{"exact":[["Chr5",50001,"Chr5",null,0,50001,20000]],"prefix":[]},"at5g33306":{"prefix":[],"exact":[["AT5G33306",1,"AT5G33306","Chr5",21674,27068]]},"at5g33350":{"exact":[["AT5G33350",0,"AT5G33350","Chr5",46781,48095]],"prefix":[]},"at5g3328":{"prefix":["AT5G33285"],"exact":[]},"at5te4458":{"exact":[],"prefix":["AT5TE44580","AT5TE44585"]},"atlin":{"exact":[],"prefix":["ATLINE1A"]},"atdna1t9a":{"prefix":[],"exact":[["ATDNA1T9A",1,"AT5TE44595","Chr5",38886,40623]]},"at5te4447":{"exact":[],"prefix":["AT5TE44470","AT5TE44475"]},"atrep11":{"prefix":[],"exact":[["ATREP11",1,"AT5TE44470","Chr5",4220,5365]]}} 2 | -------------------------------------------------------------------------------- /test/data/names/9.json: -------------------------------------------------------------------------------- 1 | {"atcopia2":{"prefix":["ATCOPIA28"],"exact":[]},"atcopia30":{"prefix":[],"exact":[["ATCOPIA30",1,"AT5TE44540","Chr5",19601,20938]]},"dt":{"exact":[],"prefix":["DT1"]},"at5te44540":{"prefix":[],"exact":[["AT5TE44540",1,"AT5TE44540","Chr5",19601,20938]]},"atline":{"prefix":["ATLINE1A"],"exact":[]},"ar":{"exact":[],"prefix":["ARNOLDY2"]},"at5te44625":{"exact":[["AT5TE44625",1,"AT5TE44625","Chr5",46022,46438]],"prefix":[]},"at5g33320":{"exact":[["AT5G33320",0,"AT5G33320","Chr5",38834,41745]],"prefix":[]},"at5te4449":{"prefix":["AT5TE44490"],"exact":[]},"helitrony1":{"prefix":["HELITRONY1E","HELITRONY1D"],"exact":[]},"at5te4461":{"exact":[],"prefix":["AT5TE44610","AT5TE44615"]},"b":{"prefix":["BRODYAGA1A"],"exact":[]},"atcopi":{"exact":[],"prefix":["ATCOPIA30","ATCOPIA28"]},"at5te4456":{"prefix":["AT5TE44565"],"exact":[]}} 2 | -------------------------------------------------------------------------------- /test/data/names/6.json: -------------------------------------------------------------------------------- 1 | {"met":{"exact":[],"prefix":["META1"]},"atcop":{"prefix":["ATCOPIA30","ATCOPIA28"],"exact":[]},"at5te44620":{"exact":[["AT5TE44620",1,"AT5TE44620","Chr5",45912,46508]],"prefix":[]},"at5te446":{"prefix":["AT5TE44600","AT5TE44605","AT5TE44610","AT5TE44615","AT5TE44620","AT5TE44625"],"exact":[]},"at5te44545":{"prefix":[],"exact":[["AT5TE44545",1,"AT5TE44545","Chr5",20938,21014]]},"atdna2t":{"exact":[],"prefix":["ATDNA2T9C"]},"at5te4453":{"prefix":["AT5TE44530","AT5TE44535"],"exact":[]},"atdna2t9":{"prefix":["ATDNA2T9C"],"exact":[]},"dt1":{"exact":[["DT1",1,"AT5TE44485","Chr5",9661,9965]],"prefix":[]},"atlan":{"prefix":["ATLANTYS1"],"exact":[]},"at5g3":{"exact":[],"prefix":["AT5G33300","AT5G33310","AT5G33320","AT5G33330","AT5G33340","AT5G33350","AT5G33355","AT5G33285","AT5G33306"]},"atd":{"exact":[],"prefix":["ATDNA1T9A","ATDNA2T9C"]},"arnol":{"prefix":["ARNOLDY2"],"exact":[]}} 2 | -------------------------------------------------------------------------------- /test/data/names/4.json: -------------------------------------------------------------------------------- 1 | {"at5g3334":{"exact":[],"prefix":["AT5G33340"]},"arnold":{"prefix":["ARNOLDY2"],"exact":[]},"atmun":{"prefix":["ATMUNX1"],"exact":[]},"atmunx1":{"exact":[["ATMUNX1",1,"AT5TE44590","Chr5",37871,38243]],"prefix":[]},"at5te44600":{"prefix":[],"exact":[["AT5TE44600",1,"AT5TE44600","Chr5",43008,43348]]},"chr":{"prefix":["Chr5"],"exact":[]},"at5te44565":{"exact":[["AT5TE44565",1,"AT5TE44565","Chr5",32312,32399]],"prefix":[]},"at5":{"prefix":["AT5G33300","AT5G33310","AT5G33320","AT5G33330","AT5G33340","AT5G33350","AT5G33355","AT5TE44460","AT5TE44465","AT5TE44470","AT5G33285","AT5TE44475","AT5TE44480","AT5TE44485","AT5TE44490","AT5TE44520","AT5TE44525","AT5TE44530","AT5TE44535","AT5TE44540",{"name":"too many matches","hitLimit":1}],"exact":[]},"at5te44590":{"exact":[["AT5TE44590",1,"AT5TE44590","Chr5",37871,38243]],"prefix":[]},"atl":{"prefix":["ATLANTYS1","ATLINE1A"],"exact":[]},"arno":{"exact":[],"prefix":["ARNOLDY2"]}} 2 | -------------------------------------------------------------------------------- /test/data/names/f.json: -------------------------------------------------------------------------------- 1 | {"atdna1t9":{"prefix":["ATDNA1T9A"],"exact":[]},"atmu":{"exact":[],"prefix":["ATMUNX1"]},"at5te44520":{"exact":[["AT5TE44520",1,"AT5TE44520","Chr5",16802,16839]],"prefix":[]},"at5te4460":{"exact":[],"prefix":["AT5TE44600","AT5TE44605"]},"atcopia3":{"exact":[],"prefix":["ATCOPIA30"]},"helit":{"exact":[],"prefix":["HELITRONY1E","HELITRONY3","HELITRONY1D","HELITRON2"]},"c":{"prefix":["Chr5"],"exact":[]},"helitr":{"exact":[],"prefix":["HELITRONY1E","HELITRONY3","HELITRONY1D","HELITRON2"]},"atrep3":{"exact":[["ATREP3",1,"AT5TE44585","Chr5",36008,36620]],"prefix":[]},"tat1_":{"prefix":["TAT1_ATH"],"exact":[]},"atrep10b":{"exact":[["ATREP10B",1,"AT5TE44490","Chr5",9965,10060],["ATREP10B",1,"AT5TE44520","Chr5",16802,16839]],"prefix":[]},"atline1":{"prefix":["ATLINE1A"],"exact":[]},"at5g33340":{"prefix":[],"exact":[["AT5G33340",0,"AT5G33340","Chr5",44463,45949]]},"at5te4457":{"exact":[],"prefix":["AT5TE44570","AT5TE44575"]},"at5te4448":{"exact":[],"prefix":["AT5TE44480","AT5TE44485"]}} 2 | -------------------------------------------------------------------------------- /test/data/names/a.json: -------------------------------------------------------------------------------- 1 | {"atrep10d":{"exact":[["ATREP10D",1,"AT5TE44530","Chr5",18308,19135]],"prefix":[]},"at5te44570":{"exact":[["AT5TE44570",1,"AT5TE44570","Chr5",32820,33705]],"prefix":[]},"helitron":{"exact":[],"prefix":["HELITRONY1E","HELITRONY3","HELITRONY1D","HELITRON2"]},"at5te444":{"exact":[],"prefix":["AT5TE44460","AT5TE44465","AT5TE44470","AT5TE44475","AT5TE44480","AT5TE44485","AT5TE44490"]},"helitrony":{"prefix":["HELITRONY1E","HELITRONY3","HELITRONY1D"],"exact":[]},"atcopia28":{"exact":[["ATCOPIA28",1,"AT5TE44545","Chr5",20938,21014],["ATCOPIA28",1,"AT5TE44570","Chr5",32820,33705]],"prefix":[]},"at5te44615":{"prefix":[],"exact":[["AT5TE44615",1,"AT5TE44615","Chr5",44043,44283]]},"at5g33310":{"prefix":[],"exact":[["AT5G33310",0,"AT5G33310","Chr5",27317,32196]]},"atlantys1":{"exact":[["ATLANTYS1",1,"AT5TE44555","Chr5",23003,27141]],"prefix":[]},"br":{"prefix":["BRODYAGA1A"],"exact":[]},"at5te44585":{"exact":[["AT5TE44585",1,"AT5TE44585","Chr5",36008,36620]],"prefix":[]},"atdn":{"prefix":["ATDNA1T9A","ATDNA2T9C"],"exact":[]}} 2 | -------------------------------------------------------------------------------- /test/data/names/3.json: -------------------------------------------------------------------------------- 1 | {"brod":{"prefix":["BRODYAGA1A"],"exact":[]},"at5te4462":{"prefix":["AT5TE44620","AT5TE44625"],"exact":[]},"atla":{"prefix":["ATLANTYS1"],"exact":[]},"ta":{"prefix":["TAT1_ATH"],"exact":[]},"at5te44465":{"prefix":[],"exact":[["AT5TE44465",1,"AT5TE44465","Chr5",4012,4220]]},"atrep1":{"prefix":["ATREP11","ATREP15","ATREP10B","ATREP10D"],"exact":[]},"at5te4455":{"prefix":["AT5TE44550","AT5TE44555"],"exact":[]},"atlant":{"prefix":["ATLANTYS1"],"exact":[]},"at5g33":{"exact":[],"prefix":["AT5G33300","AT5G33310","AT5G33320","AT5G33330","AT5G33340","AT5G33350","AT5G33355","AT5G33285","AT5G33306"]},"arnoldy":{"exact":[],"prefix":["ARNOLDY2"]},"a":{"prefix":["AT5G33300","AT5G33310","AT5G33320","AT5G33330","AT5G33340","AT5G33350","AT5G33355","AT5TE44460","AT5TE44465","AT5TE44470","ATREP11","AT5G33285","AT5TE44475","ATREP15","AT5TE44480","AT5TE44485","AT5TE44490","ATREP10B","AT5TE44520","AT5TE44525",{"hitLimit":1,"name":"too many matches"}],"exact":[]},"at5te44490":{"exact":[["AT5TE44490",1,"AT5TE44490","Chr5",9965,10060]],"prefix":[]}} 2 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jbplugin-smallrna", 3 | "version": "1.4.6", 4 | "description": "JBrowse plugin for viewing small RNA alignments", 5 | "main": "js/main.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "git+https://github.com/bhofmei/jbplugin-smallrna.git" 12 | }, 13 | "keywords": [ 14 | "JBrowse", 15 | "JBrowse plugin", 16 | "small rna" 17 | ], 18 | "author": "Brigitte Hofmeister", 19 | "license": "Apache-2.0", 20 | "bugs": { 21 | "url": "https://github.com/bhofmei/jbplugin-smallrna/issues" 22 | }, 23 | "ignore": [ 24 | "node_modules", 25 | "test" 26 | ], 27 | "directories": { 28 | "test": "test" 29 | }, 30 | "homepage": "https://github.com/bhofmei/jbplugin-smallrna#readme", 31 | "devDependencies": { 32 | "jasmine": "^2.7.0", 33 | "jbrowse": "git+https://github.com/bhofmei/jbrowse" 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /test/data/names/b.json: -------------------------------------------------------------------------------- 1 | {"at5g33285":{"exact":[["AT5G33285",1,"AT5G33285","Chr5",5186,6425]],"prefix":[]},"at5g3331":{"exact":[],"prefix":["AT5G33310"]},"atrep":{"prefix":["ATREP11","ATREP15","ATREP10B","ATREP10D","ATREP3","ATREP9"],"exact":[]},"atdna2":{"exact":[],"prefix":["ATDNA2T9C"]},"hel":{"prefix":["HELITRONY1E","HELITRONY3","HELITRONY1D","HELITRON2"],"exact":[]},"atco":{"prefix":["ATCOPIA30","ATCOPIA28"],"exact":[]},"at5te4":{"exact":[],"prefix":["AT5TE44460","AT5TE44465","AT5TE44470","AT5TE44475","AT5TE44480","AT5TE44485","AT5TE44490","AT5TE44520","AT5TE44525","AT5TE44530","AT5TE44535","AT5TE44540","AT5TE44545","AT5TE44550","AT5TE44555","AT5TE44565","AT5TE44570","AT5TE44575","AT5TE44580","AT5TE44585",{"hitLimit":1,"name":"too many matches"}]},"at5te44605":{"prefix":[],"exact":[["AT5TE44605",1,"AT5TE44605","Chr5",43348,43955]]},"at5g":{"exact":[],"prefix":["AT5G33300","AT5G33310","AT5G33320","AT5G33330","AT5G33340","AT5G33350","AT5G33355","AT5G33285","AT5G33306"]},"at5te44595":{"prefix":[],"exact":[["AT5TE44595",1,"AT5TE44595","Chr5",38886,40623]]},"at5g33300":{"prefix":[],"exact":[["AT5G33300",0,"AT5G33300","Chr5",12426,15754]]},"at5g333":{"prefix":["AT5G33300","AT5G33310","AT5G33320","AT5G33330","AT5G33340","AT5G33350","AT5G33355","AT5G33306"],"exact":[]}} 2 | -------------------------------------------------------------------------------- /test/data/names/5.json: -------------------------------------------------------------------------------- 1 | {"at5t":{"exact":[],"prefix":["AT5TE44460","AT5TE44465","AT5TE44470","AT5TE44475","AT5TE44480","AT5TE44485","AT5TE44490","AT5TE44520","AT5TE44525","AT5TE44530","AT5TE44535","AT5TE44540","AT5TE44545","AT5TE44550","AT5TE44555","AT5TE44565","AT5TE44570","AT5TE44575","AT5TE44580","AT5TE44585",{"name":"too many matches","hitLimit":1}]},"brodya":{"prefix":["BRODYAGA1A"],"exact":[]},"atdna1t":{"prefix":["ATDNA1T9A"],"exact":[]},"atc":{"exact":[],"prefix":["ATCOPIA30","ATCOPIA28"]},"at5te44580":{"prefix":[],"exact":[["AT5TE44580",1,"AT5TE44580","Chr5",35230,35856]]},"at5te44610":{"exact":[["AT5TE44610",1,"AT5TE44610","Chr5",43955,44043]],"prefix":[]},"at5te4454":{"exact":[],"prefix":["AT5TE44540","AT5TE44545"]},"helitrony3":{"exact":[["HELITRONY3",1,"AT5TE44480","Chr5",9380,9661]],"prefix":[]},"atre":{"prefix":["ATREP11","ATREP15","ATREP10B","ATREP10D","ATREP3","ATREP9"],"exact":[]},"at5te44575":{"exact":[["AT5TE44575",1,"AT5TE44575","Chr5",33705,34145]],"prefix":[]},"meta":{"prefix":["META1"],"exact":[]},"at5te":{"exact":[],"prefix":["AT5TE44460","AT5TE44465","AT5TE44470","AT5TE44475","AT5TE44480","AT5TE44485","AT5TE44490","AT5TE44520","AT5TE44525","AT5TE44530","AT5TE44535","AT5TE44540","AT5TE44545","AT5TE44550","AT5TE44555","AT5TE44565","AT5TE44570","AT5TE44575","AT5TE44580","AT5TE44585",{"hitLimit":1,"name":"too many matches"}]}} 2 | -------------------------------------------------------------------------------- /test/data/names/c.json: -------------------------------------------------------------------------------- 1 | {"heli":{"exact":[],"prefix":["HELITRONY1E","HELITRONY3","HELITRONY1D","HELITRON2"]},"atdna2t9c":{"exact":[["ATDNA2T9C",1,"AT5TE44625","Chr5",46022,46438]],"prefix":[]},"at5te44460":{"prefix":[],"exact":[["AT5TE44460",1,"AT5TE44460","Chr5",3821,4012]]},"d":{"prefix":["DT1"],"exact":[]},"brodyaga1a":{"exact":[["BRODYAGA1A",1,"AT5TE44465","Chr5",4012,4220],["BRODYAGA1A",1,"AT5TE44610","Chr5",43955,44043]],"prefix":[]},"at5te445":{"exact":[],"prefix":["AT5TE44520","AT5TE44525","AT5TE44530","AT5TE44535","AT5TE44540","AT5TE44545","AT5TE44550","AT5TE44555","AT5TE44565","AT5TE44570","AT5TE44575","AT5TE44580","AT5TE44585","AT5TE44590","AT5TE44595"]},"at":{"exact":[],"prefix":["AT5G33300","AT5G33310","AT5G33320","AT5G33330","AT5G33340","AT5G33350","AT5G33355","AT5TE44460","AT5TE44465","AT5TE44470","ATREP11","AT5G33285","AT5TE44475","ATREP15","AT5TE44480","AT5TE44485","AT5TE44490","ATREP10B","AT5TE44520","AT5TE44525",{"hitLimit":1,"name":"too many matches"}]},"tat1_at":{"exact":[],"prefix":["TAT1_ATH"]},"at5te44":{"exact":[],"prefix":["AT5TE44460","AT5TE44465","AT5TE44470","AT5TE44475","AT5TE44480","AT5TE44485","AT5TE44490","AT5TE44520","AT5TE44525","AT5TE44530","AT5TE44535","AT5TE44540","AT5TE44545","AT5TE44550","AT5TE44555","AT5TE44565","AT5TE44570","AT5TE44575","AT5TE44580","AT5TE44585",{"name":"too many matches","hitLimit":1}]}} 2 | -------------------------------------------------------------------------------- /js/SmallRNAPlugin.profile.js: -------------------------------------------------------------------------------- 1 | function copyOnly(mid) { 2 | return mid in { 3 | // There are no modules right now that are copy-only. If you have some, though, just add 4 | // them here like this: 5 | // 'app/module': 1 6 | }; 7 | } 8 | 9 | var profile = { 10 | action: 'release', 11 | cssOptimize: 'comments', 12 | mini: true, 13 | 14 | basePath: '../../../src', 15 | packages: [ 16 | {name: 'SmallRNAPlugin', location: '../plugins/SmallRNAPlugin/js' } 17 | ], 18 | 19 | layerOptimize: 'closure', 20 | stripConsole: 'normal', 21 | selectorEngine: 'acme', 22 | 23 | layers: { 24 | 'SmallRNAPlugin/main': { 25 | include: [ 26 | 'SmallRNAPlugin', 27 | ], 28 | exclude: [ 'JBrowse' ] 29 | } 30 | }, 31 | 32 | staticHasFeatures: { 33 | 'dojo-trace-api':0, 34 | 'dojo-log-api':0, 35 | 'dojo-publish-privates':0, 36 | 'dojo-sync-loader':0, 37 | 'dojo-xhr-factory':0, 38 | 'dojo-test-sniff':0 39 | }, 40 | 41 | resourceTags: { 42 | // Files that contain test code. 43 | test: function (filename, mid) { 44 | return false; 45 | }, 46 | 47 | // Files that should be copied as-is without being modified by the build system. 48 | copyOnly: function (filename, mid) { 49 | return copyOnly(mid); 50 | }, 51 | 52 | // Files that are AMD modules. 53 | amd: function (filename, mid) { 54 | return !copyOnly(mid) && /.js$/.test(filename); 55 | }, 56 | 57 | // Files that should not be copied when the “mini” compiler flag is set to true. 58 | miniExclude: function (filename, mid) { 59 | return ! ( /^SmallRNAPlugin/.test(mid) ); 60 | } 61 | } 62 | }; 63 | -------------------------------------------------------------------------------- /test/index.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | Jasmine Spec Runner 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 59 | 60 | 61 | 62 | 63 | 64 |
65 | 66 | 67 | 68 | -------------------------------------------------------------------------------- /test/data/trackList.json: -------------------------------------------------------------------------------- 1 | { 2 | "formatVersion" : 1, 3 | "names" : { 4 | "type" : "Hash", 5 | "url" : "names/" 6 | }, 7 | "tracks" : [ 8 | { 9 | "key" : "Reference sequence", 10 | "seqType" : "dna", 11 | "urlTemplate" : "seq/{refseq_dirpath}/{refseq}-", 12 | "category" : "Test data", 13 | "chunkSize" : 20000, 14 | "storeClass" : "JBrowse/Store/Sequence/StaticChunked", 15 | "type" : "SequenceTrack", 16 | "label" : "DNA" 17 | }, 18 | { 19 | "key" : "Genes", 20 | "compress" : 0, 21 | "category" : "Test data", 22 | "urlTemplate" : "tracks/genes/{refseq}/trackData.json", 23 | "type" : "JBrowse/View/Track/CanvasFeatures", 24 | "storeClass" : "JBrowse/Store/SeqFeature/NCList", 25 | "style" : { 26 | "className" : "feature", 27 | "color" : "#daa520" 28 | }, 29 | "label" : "genes" 30 | }, 31 | { 32 | "label" : "tes", 33 | "key" : "Transposable Elements", 34 | "compress" : 0, 35 | "category" : "Test data", 36 | "urlTemplate" : "tracks/tes/{refseq}/trackData.json", 37 | "storeClass" : "JBrowse/Store/SeqFeature/NCList", 38 | "style" : { 39 | "className" : "feature", 40 | "color" : "#77158D" 41 | }, 42 | "type" : "JBrowse/View/Track/CanvasFeatures" 43 | }, 44 | { 45 | "histograms" : { 46 | "storeClass" : "JBrowse/Store/SeqFeature/BigWig", 47 | "urlTemplate" : "test_smrna_short.bw" 48 | }, 49 | "category" : "Test data", 50 | "key" : "Wild Type Small RNA", 51 | "type" : "SmallRNAPlugin/View/Track/smAlignments", 52 | "storeClass" : "JBrowse/Store/SeqFeature/BAM", 53 | "label" : "track_wild_type_smrna", 54 | "urlTemplate" : "test_smrna_short_adjusted.bam" 55 | }, 56 | { 57 | "category" : "Test data", 58 | "key" : "Wild Type Small RNA HTML", 59 | "type" : "SmallRNAPlugin/View/Track/smHTMLAlignments", 60 | "storeClass" : "JBrowse/Store/SeqFeature/BAM", 61 | "label" : "track_wild_type_smrna_html", 62 | "urlTemplate" : "test_smrna_short_adjusted.bam" 63 | } 64 | ] 65 | } 66 | -------------------------------------------------------------------------------- /test/data/tracks/tes/Chr5/names.txt: -------------------------------------------------------------------------------- 1 | [["AT5TE44460","HELITRONY1E","AT5TE44460"],"tes","AT5TE44460","Chr5",3821,4012] 2 | [["AT5TE44465","BRODYAGA1A","AT5TE44465"],"tes","AT5TE44465","Chr5",4012,4220] 3 | [["AT5TE44470","ATREP11","AT5TE44470"],"tes","AT5TE44470","Chr5",4220,5365] 4 | [["AT5G33285","AT5G33285"],"tes","AT5G33285","Chr5",5186,6425] 5 | [["AT5TE44475","ATREP15","AT5TE44475"],"tes","AT5TE44475","Chr5",7462,8196] 6 | [["AT5TE44480","HELITRONY3","AT5TE44480"],"tes","AT5TE44480","Chr5",9380,9661] 7 | [["AT5TE44485","DT1","AT5TE44485"],"tes","AT5TE44485","Chr5",9661,9965] 8 | [["AT5TE44490","ATREP10B","AT5TE44490"],"tes","AT5TE44490","Chr5",9965,10060] 9 | [["AT5TE44520","ATREP10B","AT5TE44520"],"tes","AT5TE44520","Chr5",16802,16839] 10 | [["AT5TE44525","ATREP15","AT5TE44525"],"tes","AT5TE44525","Chr5",16839,18018] 11 | [["AT5TE44530","ATREP10D","AT5TE44530"],"tes","AT5TE44530","Chr5",18308,19135] 12 | [["AT5TE44535","META1","AT5TE44535"],"tes","AT5TE44535","Chr5",19135,19601] 13 | [["AT5TE44540","ATCOPIA30","AT5TE44540"],"tes","AT5TE44540","Chr5",19601,20938] 14 | [["AT5TE44545","ATCOPIA28","AT5TE44545"],"tes","AT5TE44545","Chr5",20938,21014] 15 | [["AT5G33306","AT5G33306"],"tes","AT5G33306","Chr5",21674,27068] 16 | [["AT5TE44550","TAT1_ATH","AT5TE44550"],"tes","AT5TE44550","Chr5",21977,22589] 17 | [["AT5TE44555","ATLANTYS1","AT5TE44555"],"tes","AT5TE44555","Chr5",23003,27141] 18 | [["AT5TE44565","TAT1_ATH","AT5TE44565"],"tes","AT5TE44565","Chr5",32312,32399] 19 | [["AT5TE44570","ATCOPIA28","AT5TE44570"],"tes","AT5TE44570","Chr5",32820,33705] 20 | [["AT5TE44575","HELITRONY1D","AT5TE44575"],"tes","AT5TE44575","Chr5",33705,34145] 21 | [["AT5TE44580","ARNOLDY2","AT5TE44580"],"tes","AT5TE44580","Chr5",35230,35856] 22 | [["AT5TE44585","ATREP3","AT5TE44585"],"tes","AT5TE44585","Chr5",36008,36620] 23 | [["AT5TE44590","ATMUNX1","AT5TE44590"],"tes","AT5TE44590","Chr5",37871,38243] 24 | [["AT5TE44595","ATDNA1T9A","AT5TE44595"],"tes","AT5TE44595","Chr5",38886,40623] 25 | [["AT5TE44600","ATLINE1A","AT5TE44600"],"tes","AT5TE44600","Chr5",43008,43348] 26 | [["AT5TE44605","ATREP9","AT5TE44605"],"tes","AT5TE44605","Chr5",43348,43955] 27 | [["AT5TE44610","BRODYAGA1A","AT5TE44610"],"tes","AT5TE44610","Chr5",43955,44043] 28 | [["AT5TE44615","HELITRON2","AT5TE44615"],"tes","AT5TE44615","Chr5",44043,44283] 29 | [["AT5TE44620","HELITRONY1D","AT5TE44620"],"tes","AT5TE44620","Chr5",45912,46508] 30 | [["AT5TE44625","ATDNA2T9C","AT5TE44625"],"tes","AT5TE44625","Chr5",46022,46438] 31 | -------------------------------------------------------------------------------- /js/View/Dialog/QualityFilterDialog.js: -------------------------------------------------------------------------------- 1 | define( "SmallRNAPlugin/View/Dialog/QualityFilterDialog", [ 2 | 'dojo/_base/declare', 3 | 'dojo/_base/lang', 4 | 'dojo/dom-construct', 5 | 'dijit/focus', 6 | 'dijit/form/NumberSpinner', 7 | 'JBrowse/View/Dialog/WithActionBar', 8 | 'dojo/on', 9 | 'dijit/form/Button' 10 | ], 11 | function( 12 | declare, 13 | lang, 14 | domConstruct, 15 | focus, 16 | dijitNumberSpinner, 17 | ActionBarDialog, 18 | on, 19 | Button 20 | ) { 21 | 22 | return declare ( ActionBarDialog,{ 23 | /** 24 | * Dijit Dialog subclass to change the min 25 | * and max score of XYPlots 26 | */ 27 | 28 | title: 'Set minimum mapping quality', 29 | //autofocus: false, 30 | 31 | constructor: function( args ){ 32 | this.browser = args.browser; 33 | this.min_quality = args.minQuality || 0; 34 | this.setCallback = args.setCallback || function() {}; 35 | this.cancelCallback = args.cancelCallback || function() {}; 36 | this.scoreConstraints = {min: 0, max: 100}; 37 | }, 38 | 39 | _fillActionBar: function( actionBar ){ 40 | var ok_button = new Button({ 41 | label: "OK", 42 | onClick: lang.hitch(this, function() { 43 | var min_quality = this.minQualityText.value; 44 | this.setCallback && this.setCallback( min_quality ); 45 | this.hide(); 46 | }) 47 | }).placeAt(actionBar); 48 | 49 | var cancel_button = new Button({ 50 | label: "Cancel", 51 | onClick: lang.hitch(this, function() { 52 | this.cancelCallback && this.cancelCallback(); 53 | this.hide(); 54 | }) 55 | }).placeAt(actionBar); 56 | }, 57 | 58 | show: function( callback ) { 59 | dojo.addClass( this.domNode, 'smrna-track-quality-dialog' ); 60 | 61 | this.minQualityText = new dijitNumberSpinner({ 62 | id: 'smrna-track-min-quality', 63 | value: this.min_quality, 64 | constraints: this.scoreConstraints, 65 | smallDelta: 5, 66 | intermediateChanges: true, 67 | style:"width:75px;margin-left:5px;" 68 | }); 69 | this.set('content', [ 70 | domConstruct.create('label', { "for": 'smrna-track-min-quality', innerHTML: 'Min Mapping Quality' } ), 71 | this.minQualityText.domNode 72 | ] ); 73 | 74 | this.inherited( arguments ); 75 | }, 76 | 77 | hide: function() { 78 | this.inherited(arguments); 79 | window.setTimeout( lang.hitch( this, 'destroyRecursive' ), 500 ); 80 | } 81 | }); 82 | }); 83 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Release Notes 2 | 3 | ## [v1.4.6] - 2019-04-08 4 | - FIXED error where base and quality didn't show up properly in the alignment 5 | dialog in the newer versions of JBrowse; caused by change in function parameters 6 | in DetailsMixin function 7 | 8 | ##[v1.4.5] - 2019-03-25 9 | - FIXED error with strand undefined in newer JBrowse versions; this was caused by a change in how JBrowse stores BAM data 10 | 11 | ## [v1.4.4] - 2018-04-27 12 | - FIXED minor bug where it wouldn't work when using the NeatCanvasFeature plugin and there were multimapped reads 13 | 14 | ## [v1.4.3] - 2017-11-02 15 | - UPDATED small rna colors 16 | - 21: blue 17 | - 22: green 18 | - 23: purple 19 | - 24: orange 20 | - piRNAs: red 21 | - other: gray 22 | - FIXED minor bug with opacity in details dialog 23 | 24 | ## [v1.4.2] - 2017-10-02 25 | - ADDED dialog mode to take screenshots of filtering dialog 26 | 27 | ## [v1.4.1] - 2017-08-17 28 | - minor bug fixes 29 | 30 | ## [v1.4.0] - 2017-08-08 31 | - ADDED an HTMLFeature style track to compliment the default canvas style track 32 | - this is mainly useful for screenshots so reads are div objects not painted on the canvas 33 | 34 | ## [v1.3.1] - 2016-10-04 35 | - FIXED issue with filtering when changing between multiple non-zero values 36 | - FIXED some labels to be "mapping quality" not "quality score" to minimize possible confusion 37 | 38 | ## [v1.3.0] - 2016-09-26 39 | - ADDED filtering option to filter by minimum quality score of reads 40 | - Able to filter per track or across all tracks 41 | 42 | ## [v1.2.3] - 2016-09-24 43 | - UPDATED Handle isAnimal better to match MethylationPlugin 44 | 45 | ## [v1.2.2] - 2016-09-23 46 | - ADDED Option to solid-fill multimappers which will be useful for screenshots if user does not want multimappers to appear different 47 | 48 | ## [v1.2.1] - 2016-09-19 49 | - FIXED issue with track check boxes IDs that prevented filtering on multiple tracks 50 | 51 | ## [v1.2.0] - 2016-06-10 52 | - Reads are organized on the y-axis by strand; positive reads on positive-strand y-axis and negative-strand reads on negative y-axis 53 | - Also includes "max height exceeded" warning independently for the positive and negative y-axis 54 | - In order to accommodate more data, the individual reads are smaller than the default heights for RNA-seq reads 55 | 56 | ## [v1.1.0] - 2016-06-02 57 | - ADDED Filtering dialog for all visible tracks 58 | - Only works on visible tracks and only changes features in which the check box was clicked 59 | - Colored checkboxes 60 | 61 | ## [v1.0.4] - 2016-04-03 62 | - FIXED issue with coloring of multi mapped reads; now show transparency when multimapped 63 | 64 | ## [v1.0.3] - 2016-03-25 65 | - FIXED Correctly display multimapping status in the read detail pop-up 66 | 67 | ## [v1.0.2] - 2016-03-18 68 | - ADDED Use XM attribute (with sam flag and/or NH attribute) to determine if a read is multi mapped 69 | 70 | ## [v1.0.1] - 2016-03-14 71 | - UPDATED coloring 72 | 73 | ## [v1.0.0] - 2016-03-09 74 | - First production ready version 75 | - Supports coloring and filtering of reads by size 76 | - Supports animal vs non-animal smRNA scheme (animal includes piRNAs which are 26-31 bp) 77 | - Supports coloring and filtering based on multimapped status 78 | -------------------------------------------------------------------------------- /js/main.js: -------------------------------------------------------------------------------- 1 | define([ 2 | 'dojo/_base/declare', 3 | 'dojo/_base/array', 4 | 'dojo/_base/lang', 5 | 'dojo/Deferred', 6 | 'dojo/dom-construct', 7 | 'dijit/form/Button', 8 | 'dijit/registry', 9 | 'dojo/fx', 10 | 'dojo/dom', 11 | 'dojo/dom-style', 12 | 'dojo/on', 13 | 'dojo/query', 14 | 'dojo/dom-geometry', 15 | 'JBrowse/Plugin', 16 | 'JBrowse/Util', 17 | 'dijit/MenuItem', 18 | "JBrowse/Browser", 19 | './View/Track/smAlignments', 20 | './View/Track/smHTMLAlignments', 21 | './View/Dialog/ReadFilterDialogCheck' 22 | ], 23 | function ( 24 | declare, 25 | array, 26 | lang, 27 | Deferred, 28 | domConstruct, 29 | dijitButton, 30 | dijitRegistry, 31 | coreFx, 32 | dom, 33 | style, 34 | on, 35 | query, 36 | domGeom, 37 | JBrowsePlugin, 38 | Util, 39 | dijitMenuItem, 40 | Browser, 41 | Alignments, 42 | HTMLAlignments, 43 | smReadFilterDialog 44 | ) { 45 | 46 | return declare(JBrowsePlugin, { 47 | constructor: function (args) { 48 | this.config.version = '1.4.6'; 49 | console.log('SmallRNAPlugin starting - v' + this.config.version); 50 | var baseUrl = this._defaultConfig().baseUrl; 51 | var thisB = this; 52 | var browser = this.browser; 53 | 54 | // isAnimal is off by default 55 | this.config.isAnimal = false; 56 | if (browser.config.isAnimal === true || args.isAnimal === true) { 57 | this.config.isAnimal = true; 58 | } 59 | this.config.dialog = false; 60 | if (args.dialogMode === true) { 61 | this.config.dialog = true; 62 | } 63 | if (this.config.isAnimal) { 64 | lang.extend(Alignments, { 65 | _isAnimal: thisB._isAnimal 66 | }); 67 | lang.extend(HTMLAlignments, { 68 | _isAnimal: thisB._isAnimal 69 | }); 70 | } 71 | // toolbar button 72 | browser.afterMilestone('initView', function () { 73 | var navBox = dom.byId("navbox"); 74 | browser.smRNAButton = new dijitButton({ 75 | title: "Filter small RNA reads", 76 | id: 'smrna-filter-btn', 77 | width: '22px', 78 | onClick: function () { 79 | new smReadFilterDialog({ 80 | browser: browser, 81 | config: thisB.config, 82 | setCallback: function (options) { 83 | //thisB.config = options; 84 | lang.mixin(thisB.config, options); 85 | } 86 | }).show(); 87 | } 88 | }, domConstruct.create('button', {}, navBox)) 89 | }); 90 | 91 | // handle dialog mode 92 | console.log(JSON.stringify(this.config.dialog)); 93 | if (this.config.dialog) { 94 | browser.afterMilestone('completely initialized', function () { 95 | if (browser.view.tracks.length < 1) { 96 | setTimeout(function () { 97 | var button = dijitRegistry.byId('smrna-filter-btn'); 98 | button.onClick(); 99 | }, 700) 100 | } 101 | }); // end milestone completely initialized 102 | } 103 | }, // end constructor 104 | 105 | _isAnimal: function () { 106 | return true; 107 | } 108 | 109 | }); 110 | }); 111 | -------------------------------------------------------------------------------- /test/run-jasmine.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var system = require('system'); 3 | 4 | /** 5 | * Wait until the test condition is true or a timeout occurs. Useful for waiting 6 | * on a server response or for a ui change (fadeIn, etc.) to occur. 7 | * 8 | * @param testFx javascript condition that evaluates to a boolean, 9 | * it can be passed in as a string (e.g.: "1 == 1" or "$('#bar').is(':visible')" or 10 | * as a callback function. 11 | * @param onReady what to do when testFx condition is fulfilled, 12 | * it can be passed in as a string (e.g.: "1 == 1" or "$('#bar').is(':visible')" or 13 | * as a callback function. 14 | * @param timeOutMillis the max amount of time to wait. If not specified, 3 sec is used. 15 | */ 16 | function waitFor(testFx, onReady, timeOutMillis) { 17 | var maxtimeOutMillis = timeOutMillis ? timeOutMillis : 3001, //< Default Max Timeout is 3s 18 | start = new Date().getTime(), 19 | condition = false, 20 | interval = setInterval(function() { 21 | if ( (new Date().getTime() - start < maxtimeOutMillis) && !condition ) { 22 | // If not time-out yet and condition not yet fulfilled 23 | condition = (typeof(testFx) === "string" ? eval(testFx) : testFx()); //< defensive code 24 | } else { 25 | if(!condition) { 26 | // If condition still not fulfilled (timeout but condition is 'false') 27 | console.log("'waitFor()' timeout"); 28 | phantom.exit(1); 29 | } else { 30 | typeof(onReady) === "string" ? eval(onReady) : onReady(); //< Do what it's supposed to do once the condition is fulfilled 31 | clearInterval(interval); //< Stop this interval 32 | } 33 | } 34 | }, 100); //< repeat check every 100ms 35 | }; 36 | 37 | 38 | if (system.args.length !== 2) { 39 | console.log('Usage: run-jasmine2.js URL'); 40 | phantom.exit(1); 41 | } 42 | 43 | var page = require('webpage').create(); 44 | 45 | // Route "console.log()" calls from within the Page context to the main Phantom context (i.e. current "this") 46 | page.onConsoleMessage = function(msg) { 47 | console.log(msg); 48 | }; 49 | 50 | page.open(system.args[1], function(status){ 51 | if (status !== "success") { 52 | console.log("Unable to access network"); 53 | phantom.exit(); 54 | } else { 55 | waitFor(function(){ 56 | return page.evaluate(function(){ 57 | return (document.body.querySelector('.symbolSummary .pending') === null && 58 | document.body.querySelector('.jasmine-duration') !== null); 59 | }); 60 | }, function(){ 61 | var exitCode = page.evaluate(function(){ 62 | console.log(''); 63 | 64 | var title = 'Jasmine'; 65 | var version = document.body.querySelector('.jasmine-version').innerText; 66 | var duration = document.body.querySelector('.jasmine-duration').innerText; 67 | var banner = title + ' ' + version + ' ' + duration; 68 | console.log(banner); 69 | 70 | var list = document.body.querySelectorAll('.jasmine-results > .jasmine-failures > .jasmine-spec-detail.jasmine-failed'); 71 | if (list && list.length > 0) { 72 | console.log(''); 73 | console.log(list.length + ' test(s) FAILED:'); 74 | for (i = 0; i < list.length; ++i) { 75 | var el = list[i], 76 | desc = el.querySelector('.jasmine-description'), 77 | msg = el.querySelector('.jasmine-messages > .jasmine-result-message'); 78 | console.log(''); 79 | console.log(desc.innerText); 80 | console.log(msg.innerText); 81 | console.log(''); 82 | } 83 | return 1; 84 | } else { 85 | console.log(document.body.querySelector('.jasmine-alert > .jasmine-bar,.jasmine-passed > .bar.skipped').innerText); 86 | return 0; 87 | } 88 | }); 89 | phantom.exit(exitCode); 90 | }); 91 | } 92 | }); 93 | -------------------------------------------------------------------------------- /css/main.css: -------------------------------------------------------------------------------- 1 | /* 2 | * Styles for small RNA plugin 3 | */ 4 | 5 | /* CHECKBOXES */ 6 | div#smrna-filter-dialog-sizes div.dijit.dijitReset.dijitInline.dijitCheckBox{ 7 | margin-top: 1px; 8 | } 9 | 10 | tr.smrna-select-blue span.dijitInline.dijitIcon.dijitMenuItemIcon.dijitCheckedMenuItemIcon, 11 | tr.smrna-select-blue img.dijitCheckedMenuItemIcon, 12 | div.dijit.dijitReset.dijitInline.smrna-select-blue.dijitCheckBox { 13 | background-image: url("../img/checkmark-blue.png"); 14 | } 15 | 16 | tr.smrna-select-green span.dijitInline.dijitIcon.dijitMenuItemIcon.dijitCheckedMenuItemIcon, 17 | tr.smrna-select-green img.dijitCheckedMenuItemIcon, 18 | div.dijit.dijitReset.dijitInline.smrna-select-green.dijitCheckBox{ 19 | background-image: url("../img/checkmark-green.png"); 20 | } 21 | 22 | tr.smrna-select-orange span.dijitInline.dijitIcon.dijitMenuItemIcon.dijitCheckedMenuItemIcon, 23 | tr.smrna-select-orange img.dijitCheckedMenuItemIcon, 24 | div.dijit.dijitReset.dijitInline.smrna-select-orange.dijitCheckBox{ 25 | background-image: url("../img/checkmark-orange.png"); 26 | } 27 | 28 | tr.smrna-select-red span.dijitInline.dijitIcon.dijitMenuItemIcon.dijitCheckedMenuItemIcon, 29 | tr.smrna-select-red img.dijitCheckedMenuItemIcon, 30 | div.dijit.dijitReset.dijitInline.smrna-select-red.dijitCheckBox{ 31 | background-image: url("../img/checkmark-red.png"); 32 | } 33 | 34 | tr.smrna-select-purple span.dijitInline.dijitIcon.dijitMenuItemIcon.dijitCheckedMenuItemIcon, 35 | tr.smrna-select-purple img.dijitCheckedMenuItemIcon, 36 | div.dijit.dijitReset.dijitInline.smrna-select-purple.dijitCheckBox{ 37 | background-image: url("../img/checkmark-purple.png"); 38 | } 39 | 40 | tr.smrna-select-yellow span.dijitInline.dijitIcon.dijitMenuItemIcon.dijitCheckedMenuItemIcon, 41 | tr.smrna-select-yellow img.dijitCheckedMenuItemIcon, 42 | div.dijit.dijitReset.dijitInline.smrna-select-yellow.dijitCheckBox{ 43 | background-image: url("../img/checkmark-yellow.png"); 44 | } 45 | 46 | tr.smrna-select-gray span.dijitInline.dijitIcon.dijitMenuItemIcon.dijitCheckedMenuItemIcon, 47 | tr.smrna-select-gray img.dijitCheckedMenuItemIcon, 48 | div.dijit.dijitReset.dijitInline.smrna-select-gray.dijitCheckBox{ 49 | background-image: url("../img/checkmark-gray.png"); 50 | } 51 | 52 | /* TOOLBAR BUTTON AND DIALOG */ 53 | #smrna-filter-btn{ 54 | height:17px; 55 | width: 17px; 56 | background-image: url("../img/smrna-filter.png"); 57 | background-repeat: no-repeat; 58 | background-position: center center; 59 | } 60 | 61 | #smrna-filter-dialog-sizes{ 62 | float:left; 63 | padding-right:10px; 64 | } 65 | #smrna-filter-dialog-others{ 66 | float:right; 67 | padding-left:5px; 68 | } 69 | 70 | .smrna-filter-dialog-column h3{ 71 | margin: 2px 0px; 72 | } 73 | #smrna-filter-dialog-img{ 74 | padding-right:2px; 75 | vertical-align: middle; 76 | } 77 | 78 | /* HEIGHT EXCEEDED */ 79 | div.block.height_overflow .smrna_height_overflow_message_top, 80 | div.block.height_overflow .smrna_height_overflow_message_bottom 81 | { 82 | position: absolute; 83 | color: rgb(77,77,77); 84 | text-shadow: white 0px 0px 1px; 85 | white-space: nowrap; 86 | width: 100%; 87 | font-weight: bold; 88 | text-align: center; 89 | z-index: 2000; 90 | } 91 | div.block.height_overflow .smrna_height_overflow_message_bottom{ 92 | border-bottom: 1.5px solid rgb(77,77,77); 93 | } 94 | div.block.height_overflow .smrna_height_overflow_message_top{ 95 | border-top: 1.5px solid rgb(77,77,77); 96 | } 97 | 98 | /* STYLES FOR HTML TYPE FEATURES */ 99 | .smrna-alignment{ 100 | /* shouldn't need anything at the moment */ 101 | } 102 | 103 | .smrna-21{ 104 | /* blue */ 105 | background: #3E98AF; 106 | border: solid 0px #3E98AF; 107 | } 108 | .smrna-22{ 109 | /* green */ 110 | background: #8BC240; 111 | border: solid 0px #8BC240; 112 | } 113 | .smrna-23{ 114 | /* purple */ 115 | background: #A55EA4; 116 | border: solid 0px #A55EA4; 117 | } 118 | .smrna-24{ 119 | /* orange */ 120 | background: #F37A22; 121 | border: solid 0px #F37A22; 122 | } 123 | .smrna-pi{ 124 | /* red */ 125 | background: #A94544; 126 | border: solid 0px #A94544; 127 | } 128 | .smrna-other{ 129 | /* gray */ 130 | background: #646464; 131 | border: solid 0px #646464; 132 | } 133 | .multimapped-read{ 134 | background: transparent; 135 | border-width: 1px; 136 | } 137 | -------------------------------------------------------------------------------- /js/View/Track/_NamedFeatureFiltersMixin.js: -------------------------------------------------------------------------------- 1 | define("SmallRNAPlugin/View/Track/_NamedFeatureFiltersMixin", [ 2 | 'dojo/_base/declare', 3 | 'dojo/_base/array', 4 | 'dojo/when', 5 | 'SmallRNAPlugin/View/Dialog/QualityFilterDialog' 6 | ], 7 | function( 8 | declare, 9 | array, 10 | when, 11 | QualityFilterDialog 12 | ) { 13 | return declare( null, { 14 | constructor: function() { 15 | this._initializeConfiguredFeatureFilters(); 16 | this.alwaysfilter = ['filterQuality']; 17 | }, 18 | 19 | _initializeConfiguredFeatureFilters: function() { 20 | // initialize toggling feature filters 21 | var thisB = this; 22 | return when( this._getNamedFeatureFilters() ) 23 | .then( function( filters ) { 24 | for( var filtername in filters ) { 25 | if( thisB.config[filtername] ) 26 | thisB.addFeatureFilter( filters[filtername].func, filtername ); 27 | else 28 | thisB.removeFeatureFilter( filtername ); 29 | } 30 | }); 31 | }, 32 | 33 | _toggleFeatureFilter: function( filtername, setActive ) { 34 | var thisB = this; 35 | var isAlwaysFilter = thisB.alwaysfilter.indexOf(filtername); 36 | // if no setActive, we will toggle it 37 | if( setActive === undefined ) 38 | setActive = ! this.config[filtername]; 39 | 40 | // nothing to do if not changed 41 | if( !!setActive === !!this.config[filtername] && isAlwaysFilter === -1) 42 | return; 43 | 44 | this.config[filtername] = setActive; 45 | 46 | var thisB = this; 47 | when( this._getNamedFeatureFilters(), 48 | function( filters ) { 49 | if( setActive ) 50 | thisB.addFeatureFilter( filters[filtername].func, filtername ); 51 | else 52 | thisB.removeFeatureFilter( filtername ); 53 | 54 | thisB.changed(); 55 | }); 56 | }, 57 | 58 | _getNamedFeatureFilters: function() { 59 | return {}; 60 | // return lang.mixin( 61 | // {}, 62 | // this.inherited(arguments), 63 | // { 64 | 65 | // }); 66 | }, 67 | 68 | _makeFeatureFilterTrackMenuItems: function( names, sizes, filters ) { 69 | var thisB = this; 70 | return when( filters || this._getNamedFeatureFilters() ) 71 | .then( function( filters ) { 72 | var out = []; 73 | out.push({ 74 | label: 'Filter by Size', 75 | iconClass: "dijitIconPackage", 76 | title: 'filter reads by size', 77 | children: array.map( 78 | sizes, 79 | function( name ) { 80 | return thisB._makeFeatureFilterTrackMenuItemSizes( name, filters[name] ); 81 | }) 82 | }); 83 | out = out.concat(array.map( 84 | names, 85 | function( name ) { 86 | return thisB._makeFeatureFilterTrackMenuItem( name, filters[name] ); 87 | }) 88 | ); 89 | return out; 90 | }); 91 | }, 92 | 93 | _makeFeatureFilterTrackMenuItem: function( filtername, filterspec ) { 94 | var thisB = this; 95 | if( filtername == 'SEPARATOR' ) 96 | return { type: 'dijit/MenuSeparator' }; 97 | // quality filter requires dialog box 98 | else if(filtername == 'filterQuality'){ 99 | return { 100 | label: filterspec.desc, 101 | title: filterspec.title, 102 | iconClass: 'dijitIconFilter', 103 | action: function(){ 104 | new QualityFilterDialog({ 105 | min_quality: thisB.config.filterQuality, 106 | setCallback: function(min_quality){ 107 | thisB._toggleFeatureFilter( filtername, min_quality ); 108 | } 109 | }).show(); 110 | } 111 | } 112 | } 113 | // all other filters 114 | return { label: filterspec.desc, 115 | title: filterspec.title, 116 | type: 'dijit/CheckedMenuItem', 117 | checked: !! thisB.config[filtername], 118 | onClick: function(event) { 119 | thisB._toggleFeatureFilter( filtername, this.checked ); 120 | } 121 | }; 122 | }, 123 | _makeFeatureFilterTrackMenuItemSizes: function( filtername, filterspec ) { 124 | var thisB = this; 125 | if( filtername == 'SEPARATOR' ) 126 | return { type: 'dijit/MenuSeparator' }; 127 | return { label: filterspec.desc, 128 | title: filterspec.title, 129 | type: 'dijit/CheckedMenuItem', 130 | className:filterspec.id, 131 | checked: !! thisB.config[filtername], 132 | onClick: function(event) { 133 | thisB._toggleFeatureFilter( filtername, this.checked ); 134 | } 135 | }; 136 | } 137 | 138 | }); 139 | }); 140 | -------------------------------------------------------------------------------- /test/spec/SmallRNAPlugin.spec.js: -------------------------------------------------------------------------------- 1 | require([ 2 | 'dojo/_base/declare', 3 | 'dojo/_base/array', 4 | 'JBrowse/Browser', 5 | 'JBrowse/Store/SeqFeature/BAM', 6 | 'JBrowse/Model/SimpleFeature', 7 | 'SmallRNAPlugin/View/FeatureGlyph/smAlignment', 8 | 'SmallRNAPlugin/View/Track/smAlignments', 9 | 'SmallRNAPlugin/View/Track/smHTMLAlignments', 10 | 'JBrowse/View/FeatureGlyph/Box' 11 | ], function ( 12 | declare, 13 | array, 14 | Browser, 15 | bamStore, 16 | bamFeature, 17 | smAlignment, 18 | smAlignments, 19 | smHTMLAlignments, 20 | BoxGlyph 21 | ) { 22 | 23 | describe('Initial test', function () { 24 | var test = true; 25 | it('jasmine is working', function () { 26 | expect(test).toBe(true); 27 | }); 28 | }); // end initial test 29 | 30 | describe('Track', function () { 31 | var track = new smAlignments({ 32 | browser: new Browser({ 33 | unitTestMode: true 34 | }), 35 | config: { 36 | urlTemplate: "../data/test_smrna_short_adjusted.bam", 37 | label: "testtrack" 38 | } 39 | }); 40 | it('constructed', function () { 41 | expect(track).toBeTruthy(); 42 | }); 43 | it('isAnimal is false', function () { 44 | expect(track.config.isAnimal).toBe(false); 45 | }); 46 | }); // end track 47 | 48 | describe('HTML Track', function () { 49 | var track = new smHTMLAlignments({ 50 | browser: new Browser({ 51 | unitTestMode: true 52 | }), 53 | config: { 54 | urlTemplate: "../data/test_smrna_short_adjusted.bam", 55 | label: "testtrack-html" 56 | } 57 | }); 58 | it('constructed', function () { 59 | expect(track).toBeTruthy(); 60 | }); 61 | }); // end html track 62 | 63 | describe('Track with histograms', function () { 64 | var track = new smAlignments({ 65 | browser: new Browser({ 66 | unitTestMode: true 67 | }), 68 | config: { 69 | urlTemplate: "../data/test_smrna_short_adjusted.bam", 70 | label: "testtrack", 71 | histograms: { 72 | urlTemplate: "../data/test_smrna_short.bw" 73 | } 74 | } 75 | }); 76 | it('constructed', function () { 77 | expect(track).toBeTruthy(); 78 | }); 79 | }); // end describe track with histograms 80 | 81 | describe('Test features and filters', function () { 82 | var store = new bamStore({ 83 | browser: new Browser({ 84 | unitTestMode: true 85 | }), 86 | urlTemplate: '../data/test_smrna_short_adjusted.bam', 87 | refSeq: { 88 | name: 'Chr5', 89 | start: 0, 90 | end: 50001 91 | } 92 | }); 93 | it('constructed', function () { 94 | expect(store).toBeTruthy(); 95 | }); 96 | var features = []; 97 | beforeEach(function (done) { 98 | store.getFeatures({ 99 | start: 2500, 100 | end: 5000 101 | }, function (feature) { 102 | features.push(feature); 103 | }, function () { 104 | done(); 105 | }, function (error) { 106 | console.error(error); 107 | done(); 108 | }); 109 | }); 110 | afterEach(function () { 111 | features = []; 112 | }); 113 | it('all features', function () { 114 | expect(features.length).toEqual(169); 115 | }); 116 | describe('test filters', function () { 117 | it('len 24 filter', function () { 118 | var len24 = array.filter(features, function (f) { 119 | return f.get('seq_length') === 24; 120 | }); 121 | expect(len24.length).toBe(105); 122 | }); 123 | 124 | it('len 22 filter', function () { 125 | var len22 = array.filter(features, function (f) { 126 | return f.get('seq_length') === 22; 127 | }); 128 | expect(len22.length).toBe(3); 129 | }); 130 | 131 | it('plus strand filter', function () { 132 | var plusStrand = array.filter(features, function (f) { 133 | return (f.get('strand') === "+" || f.get('strand') === 1); 134 | }); 135 | expect(plusStrand.length).toBe(36); 136 | }); 137 | 138 | it('sequence filter', function () { 139 | var seqTest = array.filter(features, function (f) { 140 | return f.get('seq') === "TTGTGGTTGTTCTTAGGCTTCAGT"; 141 | }); 142 | expect(seqTest.length).toBe(5); 143 | }); 144 | 145 | it('multimapped filter', function () { 146 | var multitest = array.filter(features, function (f) { 147 | return f.get('nh') > 1; 148 | }); 149 | expect(multitest.length).toBe(51); 150 | }); 151 | 152 | it('quality filter', function () { 153 | 154 | 155 | var qualtest = array.filter(features, function (f) { 156 | return (f.get('score') > 10 && f.get('score') <= 30); 157 | }); 158 | expect(qualtest.length).toBe(71); 159 | }); 160 | }); 161 | }); 162 | 163 | }); 164 | -------------------------------------------------------------------------------- /yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | balanced-match@^1.0.0: 6 | version "1.0.0" 7 | resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" 8 | 9 | brace-expansion@^1.1.7: 10 | version "1.1.8" 11 | resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.8.tgz#c07b211c7c952ec1f8efd51a77ef0d1d3990a292" 12 | dependencies: 13 | balanced-match "^1.0.0" 14 | concat-map "0.0.1" 15 | 16 | concat-map@0.0.1: 17 | version "0.0.1" 18 | resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" 19 | 20 | dgrid@^1.1.0: 21 | version "1.2.1" 22 | resolved "https://registry.yarnpkg.com/dgrid/-/dgrid-1.2.1.tgz#d75579908777b1cccf996090c87b3575e3c73724" 23 | 24 | dijit@1.12.2, dijit@^1.12.2: 25 | version "1.12.2" 26 | resolved "https://registry.yarnpkg.com/dijit/-/dijit-1.12.2.tgz#4891b0d045051773216d3f0b7175699f173456a6" 27 | dependencies: 28 | dojo "1.12.2" 29 | 30 | dojo-dstore@^1.1.1: 31 | version "1.1.2" 32 | resolved "https://registry.yarnpkg.com/dojo-dstore/-/dojo-dstore-1.1.2.tgz#cee36999f3f807d1cffcfdf6157db0f2b237cde4" 33 | dependencies: 34 | dojo "^1.9.0" 35 | 36 | dojo-util@^1.12.2: 37 | version "1.12.2" 38 | resolved "https://registry.yarnpkg.com/dojo-util/-/dojo-util-1.12.2.tgz#48ab67b5c39600eca03dda4a62ae240f401d25e0" 39 | 40 | dojo@1.12.2, dojo@^1.12.2, dojo@^1.9.0: 41 | version "1.12.2" 42 | resolved "https://registry.yarnpkg.com/dojo/-/dojo-1.12.2.tgz#64a863d0c28b6318656cfd8a8fd5748b07aa4fda" 43 | 44 | dojox@^1.12.2: 45 | version "1.12.2" 46 | resolved "https://registry.yarnpkg.com/dojox/-/dojox-1.12.2.tgz#1ab7723c18c66fd8b016db7dc81e6260d1532c2c" 47 | dependencies: 48 | dijit "1.12.2" 49 | dojo "1.12.2" 50 | 51 | electron-screenshot@^1.0.2: 52 | version "1.0.5" 53 | resolved "https://registry.yarnpkg.com/electron-screenshot/-/electron-screenshot-1.0.5.tgz#8cd46c4eb3d86b0401b0408228bdce033c535369" 54 | 55 | exit@^0.1.2: 56 | version "0.1.2" 57 | resolved "https://registry.yarnpkg.com/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c" 58 | 59 | filesaver.js@^0.2.0: 60 | version "0.2.0" 61 | resolved "https://registry.yarnpkg.com/filesaver.js/-/filesaver.js-0.2.0.tgz#2657dc471ec78f2d405d9da066cf039a5be69802" 62 | 63 | fs.realpath@^1.0.0: 64 | version "1.0.0" 65 | resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" 66 | 67 | glob@^7.0.6: 68 | version "7.1.2" 69 | resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15" 70 | dependencies: 71 | fs.realpath "^1.0.0" 72 | inflight "^1.0.4" 73 | inherits "2" 74 | minimatch "^3.0.4" 75 | once "^1.3.0" 76 | path-is-absolute "^1.0.0" 77 | 78 | inflight@^1.0.4: 79 | version "1.0.6" 80 | resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" 81 | dependencies: 82 | once "^1.3.0" 83 | wrappy "1" 84 | 85 | inherits@2: 86 | version "2.0.3" 87 | resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" 88 | 89 | "jDataView@git+https://github.com/rbuels/jdataview.git": 90 | version "1.1.0" 91 | resolved "git+https://github.com/rbuels/jdataview.git#db0893d468ba034fadbbb5700d4ed79ab0dc236e" 92 | 93 | jasmine-core@~2.7.0: 94 | version "2.7.0" 95 | resolved "https://registry.yarnpkg.com/jasmine-core/-/jasmine-core-2.7.0.tgz#50ff8c4f92d8ef5c0b2c1b846dd263ed85152091" 96 | 97 | jasmine@^2.7.0: 98 | version "2.7.0" 99 | resolved "https://registry.yarnpkg.com/jasmine/-/jasmine-2.7.0.tgz#5cf0bb4e594b4600bb4235560366212ac5aea1b2" 100 | dependencies: 101 | exit "^0.1.2" 102 | glob "^7.0.6" 103 | jasmine-core "~2.7.0" 104 | 105 | "jbrowse@git+https://github.com/bhofmei/jbrowse": 106 | version "0.0.1" 107 | resolved "git+https://github.com/bhofmei/jbrowse#81582b54ef4198219911a126b951509172356168" 108 | dependencies: 109 | dgrid "^1.1.0" 110 | dijit "^1.12.2" 111 | dojo "^1.12.2" 112 | dojo-dstore "^1.1.1" 113 | dojo-util "^1.12.2" 114 | dojox "^1.12.2" 115 | electron-screenshot "^1.0.2" 116 | filesaver.js "^0.2.0" 117 | jDataView "git+https://github.com/rbuels/jdataview.git" 118 | json-schema "git+https://github.com/kriszyp/json-schema.git" 119 | jszlib "git+https://github.com/cmdcolin/jszlib.git" 120 | lazyload "git+https://github.com/cmdcolin/lazyload.git#amd" 121 | 122 | "json-schema@git+https://github.com/kriszyp/json-schema.git": 123 | version "0.2.3" 124 | resolved "git+https://github.com/kriszyp/json-schema.git#24c4ed1b2359ab457a00e90606a777c2962ecd3b" 125 | 126 | "jszlib@git+https://github.com/cmdcolin/jszlib.git": 127 | version "0.0.1" 128 | resolved "git+https://github.com/cmdcolin/jszlib.git#c966ceac3b283d2248764c09e07a4b268edd5032" 129 | 130 | "lazyload@git+https://github.com/cmdcolin/lazyload.git#amd": 131 | version "1.0.0" 132 | resolved "git+https://github.com/cmdcolin/lazyload.git#042bdb8e5f9d84932c192ee1c295579b5e0c8100" 133 | 134 | minimatch@^3.0.4: 135 | version "3.0.4" 136 | resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" 137 | dependencies: 138 | brace-expansion "^1.1.7" 139 | 140 | once@^1.3.0: 141 | version "1.4.0" 142 | resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" 143 | dependencies: 144 | wrappy "1" 145 | 146 | path-is-absolute@^1.0.0: 147 | version "1.0.1" 148 | resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" 149 | 150 | wrappy@1: 151 | version "1.0.2" 152 | resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" 153 | -------------------------------------------------------------------------------- /js/View/FeatureGlyph/smAlignment.js: -------------------------------------------------------------------------------- 1 | define("SmallRNAPlugin/View/FeatureGlyph/smAlignment", [ 2 | 'dojo/_base/declare', 3 | 'dojo/_base/lang', 4 | 'dojo/_base/array', 5 | 'JBrowse/View/FeatureGlyph/Box', 6 | 'JBrowse/View/FeatureGlyph/Alignment' 7 | ], 8 | function ( 9 | declare, 10 | lang, 11 | array, 12 | BoxGlyph, 13 | Alignment 14 | ) { 15 | 16 | return declare([Alignment], { 17 | 18 | constructor: function () { 19 | this._drawMismatches = function () {}; 20 | 21 | }, 22 | 23 | _defaultConfig: function () { 24 | return this._mergeConfigs( 25 | lang.clone(this.inherited(arguments)), { 26 | style: { 27 | color: function (feature, path, glyph, track) { 28 | var strand = feature.get('strand'); 29 | var multimapping = (feature.get('supplementary_alignment') || (typeof feature.get('xm') != 'undefined' && feature.get('xm') > 1) || (typeof feature.get('nh') != 'undefined' && feature.get('nh') > 1)) 30 | // check if multimapping reads should be solid fill 31 | if (multimapping && !track.config.style.solidFill) { 32 | //return null; 33 | return '#FFFFFF'; 34 | } 35 | var seqLen = feature.get('seq_length'); 36 | if (Math.abs(strand) != 1 && strand != '+' && strand != '-') 37 | return glyph.getStyle(feature, '_color_gray'); 38 | else if (seqLen == 21) 39 | return glyph.getStyle(feature, '_color_blue'); 40 | else if (seqLen == 22) 41 | return glyph.getStyle(feature, '_color_green'); 42 | else if (seqLen == 23) 43 | return glyph.getStyle(feature, '_color_purple'); 44 | else if (seqLen == 24) 45 | return glyph.getStyle(feature, '_color_orange'); 46 | else if (seqLen > 25 && seqLen < 32 && track.config.isAnimal) 47 | return glyph.getStyle(feature, '_color_red'); 48 | else 49 | return glyph.getStyle(feature, '_color_gray'); 50 | }, 51 | borderColor: function (feature, path, glyph, track) { 52 | var strand = feature.get('strand'); 53 | var seqLen = feature.get('seq_length'); 54 | if (Math.abs(strand) != 1 && strand != '+' && strand != '-') 55 | return glyph.getStyle(feature, '_color_gray'); 56 | else if (seqLen == 21) 57 | return glyph.getStyle(feature, '_color_blue'); 58 | else if (seqLen == 22) 59 | return glyph.getStyle(feature, '_color_green'); 60 | else if (seqLen == 23) 61 | return glyph.getStyle(feature, '_color_purple'); 62 | else if (seqLen == 24) 63 | return glyph.getStyle(feature, '_color_orange'); 64 | else if (seqLen > 25 && seqLen < 32 && track.config.isAnimal) 65 | return glyph.getStyle(feature, '_color_red'); 66 | else 67 | return glyph.getStyle(feature, '_color_gray'); 68 | }, 69 | image: 'blue', 70 | /* choose colors based on length */ 71 | _color_orange: '#F37A22', // orange - 24 72 | _color_blue: '#3E98AF', // blue - 21 73 | _color_purple: '#A55EA4', // purple - 23 74 | _color_red: '#A94544', // red - pi 75 | _color_green: '#8BC240', // green - 22 76 | _color_gray: '#646464', // gray - other 77 | strandArrow: false, 78 | height: 4, 79 | marginBottom: 0.5, 80 | showMismatches: false 81 | } 82 | } 83 | ); 84 | }, 85 | 86 | makeFeatureLabel: function (feature, fRect) { 87 | var text = this.getFeatureLabel(feature); 88 | if (!text) 89 | return null; 90 | else if (!isNaN(text)) 91 | text = text + ' bp'; 92 | var font = this.getStyle(feature, 'textFont'); 93 | var l = fRect ? this.makeBottomOrTopLabel(text, font, fRect) : this.makePopupLabel(text, font); 94 | l.fill = this.getStyle(feature, 'textColor'); 95 | return l; 96 | }, 97 | 98 | layoutFeature: function (viewArgs, layout, feature) { 99 | var fRect = this._getFeatureRectangle(viewArgs, feature); 100 | 101 | var scale = viewArgs.scale; 102 | var leftBase = viewArgs.leftBase; 103 | var startbp = fRect.l / scale + leftBase; 104 | var endbp = (fRect.l + fRect.w) / scale + leftBase; 105 | // need to get the strand so we know about it but don't actually need to use it 106 | var featStrand = feature.get('strand'); 107 | 108 | fRect.t = layout.addRect( 109 | feature.id(), 110 | startbp, 111 | endbp, 112 | fRect.h, 113 | feature 114 | ); 115 | if (fRect.t === null || fRect.t === undefined) 116 | return fRect.t; 117 | 118 | fRect.f = feature; 119 | 120 | return fRect; 121 | }, 122 | 123 | _getFeatureRectangle: function (viewArgs, feature) { 124 | var block = viewArgs.block; 125 | var fRect = { 126 | l: block.bpToX(feature.get('start')), 127 | h: this._getFeatureHeight(viewArgs, feature), 128 | viewInfo: viewArgs, 129 | f: feature, 130 | glyph: this 131 | }; 132 | 133 | fRect.w = block.bpToX(feature.get('end')) - fRect.l; 134 | 135 | // save the original rect in `rect` as the dimensions 136 | // we'll use for the rectangle itself 137 | fRect.rect = { 138 | l: fRect.l, 139 | h: fRect.h, 140 | w: Math.max(fRect.w, 2), 141 | t: 0 142 | }; 143 | fRect.w = fRect.rect.w; // in case it was increased 144 | // only add margin for collapased view 145 | if (viewArgs.displayMode === 'collapsed') 146 | fRect.h += this.getStyle(feature, 'marginBottom') || 0; 147 | 148 | //var strand = fRect.strandArrow = feature.get('strand') 149 | // if we are showing strand arrowheads, expand the frect a little 150 | if (this.getStyle(feature, 'strandArrow')) { 151 | var strand = fRect.strandArrow = feature.get('strand'); 152 | var i; 153 | if (strand == -1) { 154 | i = this._embeddedImages.minusArrow; 155 | fRect.w += i.width; 156 | fRect.l -= i.width; 157 | } else { 158 | i = this._embeddedImages.plusArrow; 159 | fRect.w += i.width; 160 | } 161 | } 162 | 163 | // no labels or descriptions if displayMode is collapsed, so stop here 164 | if (viewArgs.displayMode == "collapsed") 165 | return fRect; 166 | 167 | this._expandRectangleWithLabels(viewArgs, feature, fRect); 168 | this._addMasksToRect(viewArgs, feature, fRect); 169 | 170 | return fRect; 171 | } 172 | 173 | }); 174 | }); 175 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Build Status](https://travis-ci.org/bhofmei/jbplugin-smallrna.svg?branch=master)](https://travis-ci.org/bhofmei/jbplugin-smallrna) 2 | 3 | # Small RNA Plugin 4 | 5 | JBrowse plugin to support small RNA visualization 6 | 7 | Based on the JBrowse tack type "Alignments2", the small RNA alignments track shows individual reads. The differences are: 8 | 9 | 1. Reads are colored by size not strand 10 | 2. Reads can be filtered by size and/or multimapping 11 | 3. There is animal and plant specific coloring because plant's don't have piRNAs. Plant coloring is the default. 12 | 4. Reads are organized on a y-axis by strand with positive-strand reads above the y-axis origin and negative-strand reads below it. 13 | 14 | 15 | ## Install 16 | 17 | For JBrowse 1.11.6+ in the _JBrowse/plugins_ folder, type: 18 | ``git clone https://github.com/bhofmei/jbplugin-smallrna.git SmallRNAPlugin`` 19 | 20 | **or** 21 | 22 | downloaded the latest release version at [releases](https://github.com/bhofmei/jbplugin-smallrna/releases). 23 | Unzip the downloaded folder, place in _JBrowse/plugins_, and rename the folder _SmallRNAPlugin_ 24 | 25 | ## Activate 26 | Add this to _jbrowse.conf_ under `[GENERAL]`: 27 | 28 | [ plugins.SmallRNAPlugin ] 29 | location = plugins/SmallRNAPlugin 30 | 31 | If that doesn't work, add this to _jbrowse_conf_.json: 32 | 33 | "plugins" : { 34 | "SmallRNAPlugin" : { "location" : "plugins/SmallRNAPlugin" } 35 | } 36 | 37 | ## Test 38 | 39 | Sample data is included in the plugin to test that the plugin is working properly. With `URL` as the URL path to the JBrowse instance, navigate a web browser to `URL/index.html?data=plugins/SmallRNAPlugin/test/data`. 40 | 41 | ![Demo Image](img/demo_image.png) 42 | 43 | ## The Basics 44 | - Each read is colored based on length 45 | - Blue: 21 nt 46 | - Green: 22 nt 47 | - Purple: 23 nt 48 | - Orange: 24 nt 49 | - Red: piRNAs (26-31 nt) 50 | - Gray: all other sizes 51 | - *Colors were inspired by [this color scheme](https://mpss.danforthcenter.org/web/php/pages/legend.php?SITE=AT_sRNA)* 52 | - Reads are positions positions based on strand 53 | - Above y-axis origin: positive strand 54 | - Below y-axis origin: negative strand 55 | - Unfilled reads indicate read maps to multiple locations 56 | - Filtering options 57 | - Filter an individual track using the track drop-down menu 58 | - Filter all visible smRNA tracks using the toolbar button 59 | - Filter for size, strand, read quality, multimapping 60 | 61 | ## Plants vs Animals 62 | The plant-specific smRNA color scheme is the default. However, if you want to use the animal-specific color scheme, it is very easy and flexible to change. This is compatible with the [DNA Methylation plugin](https://github.com/bhofmei/jbplugin-methylation). 63 | 64 | Using the animal coloring scheme is enforced hierarchically. Configurations specified at a higher level overpower lower-level specification. If not specified at a specific level, inherits the setting of the level below. 65 | 66 | | level| location | syntax| 67 | |--|--|--| 68 | |*highest* | individual track config | `isAnimal=true` | 69 | | | `tracks.conf` | `[general]`
`isAnimal=true` | 70 | | | `jbrowse.conf` | `[general]`
`isAnimal=true` | 71 | |*lowest*| **default** | `isAnimal=false`| 72 | 73 | Note that toolbar buttons are defined by `tracks.conf` and `jbrowse.conf`. 74 | 75 | ## Using small RNA Tracks 76 | ### File Formats 77 | Reads are read directly from a BAM file. Follow the instructions for the Alignments2 track to specify the file location. 78 | Also, make sure the indexed BAM file (`.bam.bai`) is in the same directory as the BAM file. 79 | Optionally, you can also supply a BigWig file for coverage view when zoomed out. I recommend this. Otherwise the track says "Too much data to show; zoom in to see detail" 80 | 81 | ### JSON Track Specifications 82 | Track specifications are similar to the Alignments2 specifications. The _label_, _type_, and _urlTemplate_ must be specified. Take note of _type_; this is the difference from Alignments2. 83 | 84 | To change the plant or animal coloring scheme, for the specific track, include the _isAnimal_ setting. Otherwise it assumes the setting based on the priority list above. 85 | 86 | In trackList.json, 87 | 88 | ``` 89 | { 90 | "key" : "Small RNA", 91 | "label" : "smrna", 92 | "storeClass" : "JBrowse/Store/SeqFeature/BAM", 93 | "urlTemplate" : "path/to/smallrna.bam", 94 | "type" : "SmallRNAPlugin/View/Track/smAlignments", 95 | "isAnimal" : true 96 | } 97 | ``` 98 | 99 | In tracks.conf, 100 | 101 | [tracks.smrna] 102 | key = Small RNA 103 | storeClass = JBrowse/Store/SeqFeature/BAM 104 | urlTemplate = path/to/smallrna.bam 105 | type = SmallRNAPlugin/View/Track/smAlignments 106 | isAnimal = true 107 | 108 | Similar to other alignments, you can specify a BigWig file to use for the histogram view. 109 | 110 | In trackList.json, 111 | 112 | ``` 113 | { 114 | "key" : "Small RNA", 115 | "label" : "smrna", 116 | "storeClass" : "JBrowse/Store/SeqFeature/BAM", 117 | "urlTemplate" : "path/to/smallrna.bam", 118 | "type" : "SmallRNAPlugin/View/Track/smAlignments", 119 | "isAnimal" : true, 120 | "histograms" : { 121 | "storeClass" : "JBrowse/Store/SeqFeature/BigWig", 122 | "urlTemplate" : "path/to/smallrna.bw" 123 | } 124 | } 125 | ``` 126 | 127 | ### HTML Features-style Track 128 | The track type `smAlignments` is preferred for its speed, but HTMLFeature alignments track is available. 129 | It is comparable to JBrowse's Alignments track. 130 | 131 | This track type is beneficial when taking PDF/SVG screenshots so each read is an HTML element (compared to being painted on the canvas for smAlignments/Alignments2). 132 | 133 | Track configurations are the same except the track type and it does not accept a BigWig file for histograms. 134 | 135 | In _tracks.conf_, 136 | ``` 137 | [tracks.smrna-html] 138 | key = Small RNA - HTML 139 | storeClass = JBrowse/Store/SeqFeature/BAM 140 | urlTemplate = path/to/smallrna.bam 141 | type = SmallRNAPlugin/View/Track/smHTMLAlignments 142 | ``` 143 | 144 | In _trackList.json_, 145 | ``` 146 | { 147 | "key" : "Small RNA - HTML", 148 | "label" : "smrna-html", 149 | "storeClass" : "JBrowse/Store/SeqFeature/BAM", 150 | "urlTemplate" : "path/to/smallrna.bam", 151 | "type" : "SmallRNAPlugin/View/Track/smHTMLAlignments", 152 | "isAnimal" : true 153 | } 154 | ``` 155 | 156 | ### Additional configurations 157 | By default, mutlimapped reads are lighter/less opaque. To disable this, use `style.solidFill = true` in _tracks.conf_ and `"style":{ "solidFill" : true }` in _trackList.json_. 158 | 159 | ## Multimapping 160 | Traditionally, for small RNA analysis is important to know if a read maps uniquely or multiple times within the genome. In this plugin, multi-mapped reads are shown in the appropriate color for the length, but are more transparent. 161 | Reads are determined to be multi mapped based on the SAM flag (read is supplementary) or the SAM attribute `NH`. Even when multiple alignments for the same read are output in the BAM file, the mapping program may not set the flag or `NH` attribute. For example, bowtie does not set these even when `-k 2+`. 162 | 163 | ## Quality Filtering 164 | Mapping programs vary greatly in how they assign quality scores for reads, the `MQ` or `MAPQ` score. 165 | From the [SAM format specification](http://samtools.github.io/hts-specs/SAMv1.pdf), 166 | > MAPQ: MAPping Quality. It equals −10 log10 Pr{mapping position is wrong}, rounded to the nearest 167 | integer. A value 255 indicates that the mapping quality is not available. 168 | 169 | To accommodate as many scoring schemes as possible, users can filter by minimum quality score. 170 | 171 | Reads with value 255 are always shown. 172 | 173 | ## Future Plans 174 | The following features plan to be supported in the future. 175 | - Testing for smHTMLAlignments -------------------------------------------------------------------------------- /test/data/tracks/genes/Chr5/trackData.json: -------------------------------------------------------------------------------- 1 | {"histograms":{"stats":[{"max":5,"basesPerBin":"20000","mean":2.66666666666667}],"meta":[{"arrayParams":{"chunkSize":10000,"urlTemplate":"hist-20000-{Chunk}.json","length":3},"basesPerBin":"20000"}]},"formatVersion":1,"intervals":{"nclist":[[0,12426,15754,-1,"AT5G33300","protein_coding_gene","Chr5","AT5G33300","gene","Thhalv10004098m.g","chromosome-associated_kinesin-related",[[1,12426,15754,-1,[[2,15672,15754,-1,"five_prime_UTR","TAIR10","Chr5"],[3,15561,15672,-1,0,"TAIR10","CDS","Chr5"],[4,15165,15279,-1,"Chr5",0,"CDS","TAIR10"],[5,14970,15075,-1,"Chr5",0,"TAIR10","CDS"],[6,14794,14875,-1,0,"TAIR10","CDS","Chr5"],[7,14271,14343,-1,"Chr5","TAIR10","CDS",0],[8,14075,14169,-1,"Chr5","CDS","TAIR10",0],[9,13956,13988,-1,2,"TAIR10","CDS","Chr5"],[5,13641,13715,-1,"Chr5",0,"TAIR10","CDS"],[10,13454,13532,-1,"Chr5",1,"CDS","TAIR10"],[11,13224,13369,-1,"TAIR10",1,"CDS","Chr5"],[12,12785,13142,-1,"CDS","TAIR10",0,"Chr5"],[13,12645,12702,-1,"Chr5",0,"CDS","TAIR10"],[14,12426,12645,-1,"Chr5","three_prime_UTR","TAIR10"]],"TAIR10","1","AT5G33300.1","Chr5","AT5G33300.1","mRNA"]],"TAIR10"],[15,27317,32196,-1,"TAIR10",[[16,27317,32196,-1,[[17,27317,32196,-1,"TAIR10","pseudogenic_exon","Chr5"]],"TAIR10","AT5G33310.1","1","pseudogenic_transcript","AT5G33310.1","Chr5"]],"Chr5","AT5G33310","pseudogene","AT5G33310","pseudogene"],[18,38834,41745,1,"Glucose-6-phosphate/phosphate_translocator-related","Potri.015G077900",[[19,38834,41745,1,"TAIR10",[[20,38834,38946,1,"TAIR10","five_prime_UTR","Chr5"],[21,38946,39330,1,"TAIR10",0,"CDS","Chr5"],[22,39832,39955,1,"CDS","TAIR10",0,"Chr5"],[23,40047,40200,1,"TAIR10","CDS",0,"Chr5"],[24,40395,40481,1,"Chr5",0,"TAIR10","CDS"],[25,40578,40663,1,"Chr5",1,"CDS","TAIR10"],[24,40746,40866,1,"Chr5",0,"TAIR10","CDS"],[26,40952,41021,1,"TAIR10",0,"CDS","Chr5"],[27,41111,41241,1,"TAIR10","CDS",0,"Chr5"],[28,41328,41405,1,"Chr5","CDS",2,"TAIR10"],[29,41405,41745,1,"three_prime_UTR","TAIR10","Chr5"]],"AT5G33320.1","Chr5","mRNA","1","AT5G33320.1"]],"TAIR10","Bradi4g27550","AT5G33320","protein_coding_gene","Chr5","AT5G33320","gene"],[30,41679,42893,-1,"gene","Chr5","AT5G33330","AT5G33330","protein_coding_gene","TAIR10",[[31,41679,42893,-1,"1","AT5G33330.1","Chr5","AT5G33330.1","mRNA","TAIR10",[[32,42413,42893,-1,0,"TAIR10","CDS","Chr5"],[33,41750,41822,-1,"Chr5","TAIR10","CDS",0],[34,41679,41750,-1,"Chr5","TAIR10","three_prime_UTR"]]]],"_ribonuclease_H-like_superfamily_protein","Polynucleotidyl_transferase"],[35,44463,45949,1,"Thhalv10003479m.g","Eukaryotic_aspartyl_protease_family_protein","Potri.003G087900",[[36,44463,45949,1,[[37,44463,44470,1,"Chr5","five_prime_UTR","TAIR10"],[38,44470,45784,1,0,"CDS","TAIR10","Chr5"],[39,45784,45949,1,"Chr5","TAIR10","three_prime_UTR"]],"TAIR10","1","AT5G33340.1","AT5G33340.1","Chr5","mRNA"]],"TAIR10","Bradi2g04935","AT5G33340","protein_coding_gene","Chr5","AT5G33340","gene"],[40,46781,48095,1,"AT5G33350","pseudogene","Chr5","AT5G33350","pseudogene","TAIR10",[[41,46781,48095,1,"AT5G33350.1","1","pseudogenic_transcript","AT5G33350.1","Chr5",[[42,46781,48095,1,"Chr5","TAIR10","pseudogenic_exon"]],"TAIR10"]]],[43,49249,49668,1,"Defensin-like_(DEFL)_family_protein","TAIR10",[[36,49249,49668,1,[[44,49249,49315,1,"five_prime_UTR","TAIR10","Chr5"],[28,49315,49382,1,"Chr5","CDS",0,"TAIR10"],[9,49492,49668,1,2,"TAIR10","CDS","Chr5"]],"TAIR10","1","AT5G33355.1","AT5G33355.1","Chr5","mRNA"]],"protein_coding_gene","AT5G33355","gene","AT5G33355","Chr5"]],"classes":[{"attributes":["Start","End","Strand","Name","Note","Seq_id","Id","Type","_esalsugineum-ortholog","_description","Subfeatures","Source"],"isArrayAttr":{"Subfeatures":1}},{"attributes":["Start","End","Strand","Subfeatures","Source","_index","Name","Seq_id","Id","Type"],"isArrayAttr":{"Subfeatures":1}},{"isArrayAttr":{},"attributes":["Start","End","Strand","Type","Source","Seq_id"]},{"isArrayAttr":{},"attributes":["Start","End","Strand","Phase","Source","Type","Seq_id"]},{"isArrayAttr":{},"attributes":["Start","End","Strand","Seq_id","Phase","Type","Source"]},{"isArrayAttr":{},"attributes":["Start","End","Strand","Seq_id","Phase","Source","Type"]},{"isArrayAttr":{},"attributes":["Start","End","Strand","Phase","Source","Type","Seq_id"]},{"attributes":["Start","End","Strand","Seq_id","Source","Type","Phase"],"isArrayAttr":{}},{"attributes":["Start","End","Strand","Seq_id","Type","Source","Phase"],"isArrayAttr":{}},{"isArrayAttr":{},"attributes":["Start","End","Strand","Phase","Source","Type","Seq_id"]},{"attributes":["Start","End","Strand","Seq_id","Phase","Type","Source"],"isArrayAttr":{}},{"attributes":["Start","End","Strand","Source","Phase","Type","Seq_id"],"isArrayAttr":{}},{"attributes":["Start","End","Strand","Type","Source","Phase","Seq_id"],"isArrayAttr":{}},{"attributes":["Start","End","Strand","Seq_id","Phase","Type","Source"],"isArrayAttr":{}},{"attributes":["Start","End","Strand","Seq_id","Type","Source"],"isArrayAttr":{}},{"attributes":["Start","End","Strand","Source","Subfeatures","Seq_id","Id","Type","Name","Note"],"isArrayAttr":{"Subfeatures":1}},{"isArrayAttr":{"Subfeatures":1},"attributes":["Start","End","Strand","Subfeatures","Source","Name","_index","Type","Id","Seq_id"]},{"attributes":["Start","End","Strand","Source","Type","Seq_id"],"isArrayAttr":{}},{"isArrayAttr":{"Subfeatures":1},"attributes":["Start","End","Strand","_description","_ptrichocarpa-ortholog","Subfeatures","Source","_bdistachyon-ortholog","Name","Note","Seq_id","Id","Type"]},{"isArrayAttr":{"Subfeatures":1},"attributes":["Start","End","Strand","Source","Subfeatures","Id","Seq_id","Type","_index","Name"]},{"isArrayAttr":{},"attributes":["Start","End","Strand","Source","Type","Seq_id"]},{"isArrayAttr":{},"attributes":["Start","End","Strand","Source","Phase","Type","Seq_id"]},{"attributes":["Start","End","Strand","Type","Source","Phase","Seq_id"],"isArrayAttr":{}},{"isArrayAttr":{},"attributes":["Start","End","Strand","Source","Type","Phase","Seq_id"]},{"attributes":["Start","End","Strand","Seq_id","Phase","Source","Type"],"isArrayAttr":{}},{"isArrayAttr":{},"attributes":["Start","End","Strand","Seq_id","Phase","Type","Source"]},{"isArrayAttr":{},"attributes":["Start","End","Strand","Source","Phase","Type","Seq_id"]},{"attributes":["Start","End","Strand","Source","Type","Phase","Seq_id"],"isArrayAttr":{}},{"isArrayAttr":{},"attributes":["Start","End","Strand","Seq_id","Type","Phase","Source"]},{"isArrayAttr":{},"attributes":["Start","End","Strand","Type","Source","Seq_id"]},{"isArrayAttr":{"Subfeatures":1},"attributes":["Start","End","Strand","Type","Seq_id","Id","Name","Note","Source","Subfeatures","_description2","_description"]},{"isArrayAttr":{"Subfeatures":1},"attributes":["Start","End","Strand","_index","Name","Seq_id","Id","Type","Source","Subfeatures"]},{"attributes":["Start","End","Strand","Phase","Source","Type","Seq_id"],"isArrayAttr":{}},{"attributes":["Start","End","Strand","Seq_id","Source","Type","Phase"],"isArrayAttr":{}},{"isArrayAttr":{},"attributes":["Start","End","Strand","Seq_id","Source","Type"]},{"isArrayAttr":{"Subfeatures":1},"attributes":["Start","End","Strand","_esalsugineum-ortholog","_description","_ptrichocarpa-ortholog","Subfeatures","Source","_bdistachyon-ortholog","Name","Note","Seq_id","Id","Type"]},{"attributes":["Start","End","Strand","Subfeatures","Source","_index","Name","Id","Seq_id","Type"],"isArrayAttr":{"Subfeatures":1}},{"attributes":["Start","End","Strand","Seq_id","Type","Source"],"isArrayAttr":{}},{"isArrayAttr":{},"attributes":["Start","End","Strand","Phase","Type","Source","Seq_id"]},{"isArrayAttr":{},"attributes":["Start","End","Strand","Seq_id","Source","Type"]},{"isArrayAttr":{"Subfeatures":1},"attributes":["Start","End","Strand","Name","Note","Seq_id","Id","Type","Source","Subfeatures"]},{"isArrayAttr":{"Subfeatures":1},"attributes":["Start","End","Strand","Name","_index","Type","Id","Seq_id","Subfeatures","Source"]},{"attributes":["Start","End","Strand","Seq_id","Source","Type"],"isArrayAttr":{}},{"attributes":["Start","End","Strand","_description","Source","Subfeatures","Note","Name","Type","Id","Seq_id"],"isArrayAttr":{"Subfeatures":1}},{"isArrayAttr":{},"attributes":["Start","End","Strand","Type","Source","Seq_id"]},{"attributes":["Start","End","Chunk"],"isArrayAttr":{"Sublist":1}}],"minStart":12426,"count":7,"urlTemplate":"lf-{Chunk}.json","maxEnd":49668,"lazyClass":45},"featureCount":7} 2 | -------------------------------------------------------------------------------- /js/View/StrandedBitmapRectLayout.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Adapted from GranularRectLayout.js 3 | * Handles having rectangles on a "postive" axis and "negative" axis 4 | * for stranded smRNA reads 5 | * Will maintain two separate lists of negative and positve 6 | * note: negative strand acts like the original data. postive strand 7 | * acts differently since height increases negatively 8 | * 9 | * 'pitchX' and 'pitchY' are ratios of input scale resolution to 10 | * internal bitmap resolution 11 | */ 12 | define( 13 | "SmallRNAPlugin/View/StrandedBitmapRectLayout", ['dojo/_base/declare'], 14 | function( declare ) { 15 | return declare( null,{ 16 | /** 17 | * @param args.pitchX layout grid pitch in the X direction 18 | * @param args.pitchY layout grid pitch in the Y direction 19 | * @param args.maxHeight maximum layout height, default Infinity (no max) 20 | */ 21 | constructor: function( args ) { 22 | //console.log(JSON.stringify(args)); 23 | this.pitchX = args.pitchX || 10; 24 | this.pitchY = args.pitchY || 10; 25 | 26 | this.displayMode = args.displayMode; 27 | 28 | // reduce the pitchY to try and pack the features tighter 29 | if( this.displayMode == 'compact' ) { 30 | this.pitchY = Math.round( this.pitchY/4 ) || 1; 31 | this.pitchX = Math.round( this.pitchX/4 ) || 1; 32 | } // increase pitchY for collapsed view 33 | if(this.displayMode == 'collapsed') 34 | this.pitchY = Math.round(this.pitchY*2); 35 | 36 | this.bitmap = []; 37 | this.rectangles = {}; 38 | this.maxHeight = Math.ceil( ( args.maxHeight || Infinity ) / this.pitchY ); 39 | this.originY = (args.originY || (this.maxHeight == Infinity ? 600 : Math.floor(this.maxHeight/2.0))); 40 | this.pTotalHeight = 0; // total height, in units of bitmap squares (px/pitchY) 41 | }, 42 | 43 | /** 44 | * @returns {Number} top position for the rect, or Null if laying out the rect would exceed maxHeight 45 | */ 46 | addRect: function( id, left, right, height, data ) { 47 | //console.log(this.bitmap); 48 | // if we have already laid it out, return its layout 49 | if( id in this.rectangles ) { 50 | var storedRec = this.rectangles[id]; 51 | if( storedRec.top === null ) 52 | return null; 53 | 54 | // add it to the bitmap again, since that bitmap range may have been discarded 55 | this._addRectToBitmap( storedRec, data ); 56 | return storedRec.top * this.pitchY; 57 | } 58 | 59 | var pLeft = Math.floor( left / this.pitchX ); 60 | var pRight = Math.floor( right / this.pitchX ); 61 | var pHeight = Math.ceil( height / this.pitchY ); 62 | 63 | var midX = Math.floor((pLeft+pRight)/2); 64 | var rectangle = { id: id, l: pLeft, r: pRight, mX: midX, h: pHeight }; 65 | var strand = 0; 66 | if( data ) 67 | rectangle.data = data; 68 | strand = data.get('strand'); 69 | //console.log(JSON.stringify(rectangle.data.data)); 70 | var top = this.originY-1; 71 | var topStart; 72 | // negative strand 73 | if(strand == -1 ){ 74 | var maxTopNeg = this.maxHeight - pHeight; 75 | topStart = this.originY + (this.displayMode == 'compact' ? 2 : 1); 76 | for(top = topStart; top <= maxTopNeg; top ++){ 77 | if( !(this._collides(rectangle, top))) 78 | break; 79 | }} else if (strand == 1){ 80 | // positive strand 81 | var maxTopPos = 0; 82 | topStart = this.originY - pHeight - (this.displayMode == 'compact' ? 2 : 1); 83 | for(top = topStart; top >= maxTopPos; top =top - pHeight ){ 84 | if( ! this._collides( rectangle, top ) ) 85 | break; 86 | }} 87 | // this must change 88 | /*var maxTop = this.maxHeight - pHeight; 89 | for(var top = 0; top <= maxTop; top++ ){ 90 | if( ! this._collides( rectangle, top ) ) 91 | break; 92 | }*/ 93 | if( (strand == -1 && top > maxTopNeg ) || (strand == 1 && top < maxTopPos) ) { 94 | rectangle.top = top = (strand === -1 ? null : undefined ); 95 | this.rectangles[id] = rectangle; 96 | this.pTotalHeight = Math.max( this.pTotalHeight||0, top+pHeight ); 97 | return (strand === -1 ? null : undefined ); 98 | } 99 | else { 100 | rectangle.top = top; 101 | this._addRectToBitmap( rectangle, data ); 102 | this.rectangles[id] = rectangle; 103 | this.pTotalHeight = Math.max( this.pTotalHeight||0, top+pHeight ); 104 | return top * this.pitchY; 105 | } 106 | }, 107 | 108 | _collides: function( rect, top ) { 109 | // must change to include strand 110 | if( this.displayMode == "collapsed" ) 111 | return false; 112 | 113 | var bitmap = this.bitmap; 114 | //var mY = top + rect.h/2; // Y midpoint: ( top+height + top ) / 2 115 | 116 | // test the left first, then right, then middle 117 | var mRow = bitmap[top]; 118 | if( mRow && ( mRow[rect.l] || mRow[rect.r] || mRow[rect.mX]) ) 119 | return true; 120 | 121 | // finally, test exhaustively 122 | var maxY = top+rect.h; 123 | for( var y = top; y < maxY; y++ ) { 124 | var row = bitmap[y]; 125 | if( row ) { 126 | if( row.allFilled ) 127 | return true; 128 | if( row.length > rect.l ) 129 | for( var x = rect.l; x <= rect.r; x++ ) 130 | if( row[x] ) 131 | return true; 132 | } 133 | } 134 | 135 | return false; 136 | }, 137 | 138 | /** 139 | * make a subarray if it does not exist 140 | * @private 141 | */ 142 | _autovivify: function( array, subscript ) { 143 | return array[subscript] || 144 | (function() { var a = []; array[subscript] = a; return a; })(); 145 | }, 146 | 147 | _addRectToBitmap: function( rect, data ) { 148 | if( rect.top === null ) 149 | return; 150 | 151 | data = data || true; 152 | //console.log(rect.top); 153 | var bitmap = this.bitmap; 154 | var av = this._autovivify; 155 | var yEnd = rect.top+rect.h; 156 | if( rect.r-rect.l > 20000 ) { 157 | // the rect is very big in relation to the view size, just 158 | // pretend, for the purposes of layout, that it extends 159 | // infinitely. this will cause weird layout if a user 160 | // scrolls manually for a very, very long time along the 161 | // genome at the same zoom level. but most users will not 162 | // do that. hopefully. 163 | for( var y = rect.top; y < yEnd; y++ ) { 164 | av(bitmap,y).allFilled = data; 165 | } 166 | } 167 | else { 168 | // this might need to change 169 | for( var y = rect.top; y < yEnd; y++ ) { 170 | // console.log(y); 171 | var row = av(bitmap,y); 172 | for( var x = rect.l; x <= rect.r; x++ ) 173 | row[x] = data; 174 | } 175 | } 176 | }, 177 | 178 | /** 179 | * Given a range of X coordinates, deletes all data dealing with 180 | * the features. 181 | */ 182 | discardRange: function( left, right ) { 183 | //console.log( 'discard', left, right ); 184 | var pLeft = Math.floor( left / this.pitchX ); 185 | var pRight = Math.floor( right / this.pitchX ); 186 | var bitmap = this.bitmap; 187 | for( var y = 0; y < bitmap.length; ++y ) { 188 | var row = bitmap[y]; 189 | if( row ) 190 | for( var x = pLeft; x <= pRight; ++x ) { 191 | delete row[x]; 192 | } 193 | } 194 | }, 195 | 196 | hasSeen: function( id ) { 197 | return !! this.rectangles[id]; 198 | }, 199 | 200 | getByCoord: function( x, y ) { 201 | var pY = Math.floor( y / this.pitchY ); 202 | //console.log('coord', y); 203 | var r = this.bitmap[pY]; 204 | if( ! r ) return undefined; 205 | return r.allFilled || function() { 206 | var pX = Math.floor( x / this.pitchX ); 207 | return r[pX]; 208 | }.call(this); 209 | }, 210 | 211 | getByID: function( id ) { 212 | var r = this.rectangles[id]; 213 | if( r ) { 214 | return r.data || true; 215 | } 216 | return undefined; 217 | }, 218 | 219 | cleanup: function() { 220 | }, 221 | 222 | getTotalHeight: function() { 223 | //return this.pTotalHeight * this.pitchY; 224 | return this.maxHeight*this.pitchY; 225 | }, 226 | getOriginY: function(){ 227 | return this.originY * this.pitchY; 228 | } 229 | } 230 | ); 231 | }); 232 | -------------------------------------------------------------------------------- /test/data/tracks/tes/Chr5/trackData.json: -------------------------------------------------------------------------------- 1 | {"formatVersion":1,"histograms":{"meta":[{"arrayParams":{"urlTemplate":"hist-5000-{Chunk}.json","length":10,"chunkSize":10000},"basesPerBin":"5000"}],"stats":[{"mean":3.6,"basesPerBin":"5000","max":6}]},"intervals":{"classes":[{"attributes":["Start","End","Strand","Subfeatures","Seq_id","Id","Source","Name","Type","Alias"],"isArrayAttr":{"Subfeatures":1}},{"attributes":["Start","End","Strand","Seq_id","Source","Type"],"isArrayAttr":{}},{"attributes":["Start","End","Strand","Type","Alias","Id","Source","Name","Seq_id","Subfeatures"],"isArrayAttr":{"Subfeatures":1}},{"isArrayAttr":{},"attributes":["Start","End","Strand","Type","Source","Seq_id"]},{"isArrayAttr":{"Subfeatures":1},"attributes":["Start","End","Strand","Name","Id","Source","Seq_id","Subfeatures","Alias","Type"]},{"attributes":["Start","End","Strand","Seq_id","Type","Source"],"isArrayAttr":{}},{"attributes":["Start","End","Strand","Type","Id","Source","Note","Name","Seq_id"],"isArrayAttr":{}},{"attributes":["Start","End","Strand","Id","Source","Name","Subfeatures","Seq_id","Type","Alias"],"isArrayAttr":{"Subfeatures":1}},{"attributes":["Start","End","Strand","Source","Type","Seq_id"],"isArrayAttr":{}},{"attributes":["Start","End","Strand","Alias","Type","Seq_id","Subfeatures","Source","Id","Name"],"isArrayAttr":{"Subfeatures":1}},{"isArrayAttr":{},"attributes":["Start","End","Strand","Seq_id","Type","Source"]},{"isArrayAttr":{"Subfeatures":1},"attributes":["Start","End","Strand","Name","Id","Source","Seq_id","Subfeatures","Type","Alias"]},{"isArrayAttr":{},"attributes":["Start","End","Strand","Seq_id","Source","Type"]},{"attributes":["Start","End","Strand","Alias","Type","Id","Source","Name","Seq_id","Subfeatures"],"isArrayAttr":{"Subfeatures":1}},{"attributes":["Start","End","Strand","Seq_id","Source","Type"],"isArrayAttr":{}},{"attributes":["Start","End","Strand","Name","Id","Source","Subfeatures","Seq_id","Alias","Type"],"isArrayAttr":{"Subfeatures":1}},{"attributes":["Start","End","Strand","Seq_id","Subfeatures","Id","Source","Name","Type","Alias"],"isArrayAttr":{"Subfeatures":1}},{"attributes":["Start","End","Strand","Type","Alias","Name","Source","Id","Seq_id","Subfeatures"],"isArrayAttr":{"Subfeatures":1}},{"attributes":["Start","End","Strand","Type","Source","Seq_id"],"isArrayAttr":{}},{"isArrayAttr":{"Subfeatures":1},"attributes":["Start","End","Strand","Type","Alias","Subfeatures","Seq_id","_derived_features","Name","Id","Source"]},{"isArrayAttr":{},"attributes":["Start","End","Strand","Seq_id","Type","Source"]},{"attributes":["Start","End","Strand","Type","Alias","Seq_id","Subfeatures","Source","Id","Name"],"isArrayAttr":{"Subfeatures":1}},{"attributes":["Start","End","Strand","Name","Note","Source","Id","Seq_id","Type"],"isArrayAttr":{}},{"isArrayAttr":{"Subfeatures":1},"attributes":["Start","End","Strand","Source","Id","Name","Subfeatures","Seq_id","Alias","Type"]},{"attributes":["Start","End","Strand","Source","Type","Seq_id"],"isArrayAttr":{}},{"isArrayAttr":{"Subfeatures":1},"attributes":["Start","End","Strand","Source","Id","Name","Seq_id","Subfeatures","Type","Alias"]},{"isArrayAttr":{"Subfeatures":1},"attributes":["Start","End","Strand","Name","_derived_features","Source","Id","Seq_id","Subfeatures","Type","Alias"]},{"isArrayAttr":{"Subfeatures":1},"attributes":["Start","End","Strand","Alias","Type","Name","Id","Source","Subfeatures","Seq_id"]},{"isArrayAttr":{"Subfeatures":1},"attributes":["Start","End","Strand","Type","Alias","Name","Id","Source","Seq_id","Subfeatures"]},{"isArrayAttr":{},"attributes":["Start","End","Strand","Type","Source","Seq_id"]},{"isArrayAttr":{"Subfeatures":1},"attributes":["Start","End","Strand","Id","Source","Name","Seq_id","Subfeatures","Alias","Type"]},{"attributes":["Start","End","Strand","Type","Alias","Source","Id","Name","Seq_id","Subfeatures"],"isArrayAttr":{"Subfeatures":1}},{"isArrayAttr":{},"attributes":["Start","End","Strand","Seq_id","Source","Type"]},{"isArrayAttr":{"Subfeatures":1},"attributes":["Start","End","Strand","Subfeatures","Seq_id","Name","Source","Id","Type","Alias"]},{"isArrayAttr":{"Subfeatures":1},"attributes":["Start","End","Strand","Id","Source","Name","Seq_id","Subfeatures","Type","Alias"]},{"isArrayAttr":{"Subfeatures":1},"attributes":["Start","End","Strand","Seq_id","Subfeatures","Source","Id","Name","Alias","Type"]},{"attributes":["Start","End","Strand","Source","Type","Seq_id"],"isArrayAttr":{}},{"attributes":["Start","End","Strand","Type","Alias","Name","Source","Id","Subfeatures","Seq_id"],"isArrayAttr":{"Subfeatures":1}},{"attributes":["Start","End","Strand","Source","Type","Seq_id"],"isArrayAttr":{}},{"attributes":["Start","End","Chunk"],"isArrayAttr":{"Sublist":1}}],"nclist":[[0,3821,4012,-1,[[1,3821,4012,-1,"Chr5","TAIR10","transposon_fragment"]],"Chr5","AT5TE44460","TAIR10","AT5TE44460","transposable_element","HELITRONY1E"],[2,4012,4220,-1,"transposable_element","BRODYAGA1A","AT5TE44465","TAIR10","AT5TE44465","Chr5",[[3,4012,4220,-1,"transposon_fragment","TAIR10","Chr5"]]],[4,4220,5365,1,"AT5TE44470","AT5TE44470","TAIR10","Chr5",[[5,4220,5365,1,"Chr5","transposon_fragment","TAIR10"]],"ATREP11","transposable_element"],[6,5186,6425,-1,"transposable_element_gene","AT5G33285","TAIR10","transposable_element_gene","AT5G33285","Chr5"],[7,7462,8196,1,"AT5TE44475","TAIR10","AT5TE44475",[[8,7462,8196,1,"TAIR10","transposon_fragment","Chr5"]],"Chr5","transposable_element","ATREP15"],[9,9380,9661,1,"HELITRONY3","transposable_element","Chr5",[[10,9380,9661,1,"Chr5","transposon_fragment","TAIR10"]],"TAIR10","AT5TE44480","AT5TE44480"],[11,9661,9965,-1,"AT5TE44485","AT5TE44485","TAIR10","Chr5",[[12,9661,9965,-1,"Chr5","TAIR10","transposon_fragment"]],"transposable_element","DT1"],[13,9965,10060,1,"ATREP10B","transposable_element","AT5TE44490","TAIR10","AT5TE44490","Chr5",[[14,9965,10060,1,"Chr5","TAIR10","transposon_fragment"]]],[15,16802,16839,-1,"AT5TE44520","AT5TE44520","TAIR10",[[1,16802,16839,-1,"Chr5","TAIR10","transposon_fragment"]],"Chr5","ATREP10B","transposable_element"],[16,16839,18018,1,"Chr5",[[12,16839,18018,1,"Chr5","TAIR10","transposon_fragment"]],"AT5TE44525","TAIR10","AT5TE44525","transposable_element","ATREP15"],[11,18308,19135,-1,"AT5TE44530","AT5TE44530","TAIR10","Chr5",[[12,18308,19135,-1,"Chr5","TAIR10","transposon_fragment"]],"transposable_element","ATREP10D"],[17,19135,19601,1,"transposable_element","META1","AT5TE44535","TAIR10","AT5TE44535","Chr5",[[18,19135,19601,1,"transposon_fragment","TAIR10","Chr5"]]],[19,19601,20938,1,"transposable_element","ATCOPIA30",[[20,19601,20938,1,"Chr5","transposon_fragment","TAIR10"]],"Chr5","7,12570175,12571226,1,TAIR10,AT5TE44540,Chr5,AT5G33303,transposable_element_gene,transposable_element_gene,AT5G33303","AT5TE44540","AT5TE44540","TAIR10"],[21,20938,21014,1,"transposable_element","ATCOPIA28","Chr5",[[1,20938,21014,1,"Chr5","TAIR10","transposon_fragment"]],"TAIR10","AT5TE44545","AT5TE44545"],[22,21674,27068,1,"AT5G33306","transposable_element_gene","TAIR10","AT5G33306","Chr5","transposable_element_gene",{"Sublist":[[11,21977,22589,1,"AT5TE44550","AT5TE44550","TAIR10","Chr5",[[12,21977,22589,1,"Chr5","TAIR10","transposon_fragment"]],"transposable_element","TAT1_ATH"]]}],[23,23003,27141,1,"TAIR10","AT5TE44555","AT5TE44555",[[24,25835,27141,1,"TAIR10","transposon_fragment","Chr5"],[10,24582,25512,1,"Chr5","transposon_fragment","TAIR10"],[1,23003,24586,1,"Chr5","TAIR10","transposon_fragment"]],"Chr5","ATLANTYS1","transposable_element"],[25,32312,32399,1,"TAIR10","AT5TE44565","AT5TE44565","Chr5",[[24,32312,32399,1,"TAIR10","transposon_fragment","Chr5"]],"transposable_element","TAT1_ATH"],[26,32820,33705,1,"AT5TE44570","7,12582856,12583555,1,TAIR10,AT5TE44570,Chr5,AT5G33315,transposable_element_gene,transposable_element_gene,AT5G33315","TAIR10","AT5TE44570","Chr5",[[3,32820,33705,1,"transposon_fragment","TAIR10","Chr5"]],"transposable_element","ATCOPIA28"],[27,33705,34145,1,"HELITRONY1D","transposable_element","AT5TE44575","AT5TE44575","TAIR10",[[12,33705,34145,1,"Chr5","TAIR10","transposon_fragment"]],"Chr5"],[28,35230,35856,-1,"transposable_element","ARNOLDY2","AT5TE44580","AT5TE44580","TAIR10","Chr5",[[29,35230,35856,-1,"transposon_fragment","TAIR10","Chr5"]]],[30,36008,36620,-1,"AT5TE44585","TAIR10","AT5TE44585","Chr5",[[12,36008,36620,-1,"Chr5","TAIR10","transposon_fragment"]],"ATREP3","transposable_element"],[31,37871,38243,1,"transposable_element","ATMUNX1","TAIR10","AT5TE44590","AT5TE44590","Chr5",[[32,37871,38243,1,"Chr5","TAIR10","transposon_fragment"]]],[33,38886,40623,-1,[[3,38886,39079,-1,"transposon_fragment","TAIR10","Chr5"],[29,40262,40623,-1,"transposon_fragment","TAIR10","Chr5"]],"Chr5","AT5TE44595","TAIR10","AT5TE44595","transposable_element","ATDNA1T9A"],[17,43008,43348,-1,"transposable_element","ATLINE1A","AT5TE44600","TAIR10","AT5TE44600","Chr5",[[8,43008,43348,-1,"TAIR10","transposon_fragment","Chr5"]]],[15,43348,43955,-1,"AT5TE44605","AT5TE44605","TAIR10",[[24,43348,43955,-1,"TAIR10","transposon_fragment","Chr5"]],"Chr5","ATREP9","transposable_element"],[34,43955,44043,1,"AT5TE44610","TAIR10","AT5TE44610","Chr5",[[3,43955,44043,1,"transposon_fragment","TAIR10","Chr5"]],"transposable_element","BRODYAGA1A"],[35,44043,44283,-1,"Chr5",[[36,44043,44283,-1,"TAIR10","transposon_fragment","Chr5"]],"TAIR10","AT5TE44615","AT5TE44615","HELITRON2","transposable_element"],[37,45912,46508,-1,"transposable_element","HELITRONY1D","AT5TE44620","TAIR10","AT5TE44620",[[5,45912,46022,-1,"Chr5","transposon_fragment","TAIR10"],[24,46438,46508,-1,"TAIR10","transposon_fragment","Chr5"]],"Chr5",{"Sublist":[[13,46022,46438,1,"ATDNA2T9C","transposable_element","AT5TE44625","TAIR10","AT5TE44625","Chr5",[[38,46022,46438,1,"TAIR10","transposon_fragment","Chr5"]]]]}]],"count":30,"minStart":3821,"maxEnd":46508,"lazyClass":39,"urlTemplate":"lf-{Chunk}.json"},"featureCount":30} 2 | -------------------------------------------------------------------------------- /js/View/Track/_AlignmentsMixin.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Based on JBrowse _AlignmentsMixin 3 | * customized for smallRNA data 4 | * specifically, fewer track menu options, different colors, less details 5 | */ 6 | define("SmallRNAPlugin/View/Track/_AlignmentsMixin", [ 7 | 'dojo/_base/declare', 8 | 'dojo/_base/array', 9 | 'dojo/_base/lang', 10 | 'dojo/when', 11 | 'JBrowse/Util', 12 | 'JBrowse/Store/SeqFeature/_MismatchesMixin', 13 | 'SmallRNAPlugin/View/Track/_NamedFeatureFiltersMixin' 14 | ], 15 | function( 16 | declare, 17 | array, 18 | lang, 19 | when, 20 | Util, 21 | MismatchesMixin, 22 | NamedFeatureFiltersMixin 23 | ) { 24 | 25 | return declare([ MismatchesMixin, NamedFeatureFiltersMixin ], { 26 | 27 | /** 28 | * Make a default feature detail page for the given feature. 29 | * @returns {HTMLElement} feature detail page HTML 30 | */ 31 | defaultFeatureDetail: function( /** JBrowse.Track */ track, /** Object */ f, /** HTMLElement */ div ) { 32 | var container = dojo.create('div', { 33 | className: 'detail feature-detail feature-detail-'+track.name.replace(/\s+/g,'_').toLowerCase(), 34 | innerHTML: '' 35 | }); 36 | var fmt = lang.hitch( this, function( name, value, feature, unsafe ) { 37 | if(unsafe===undefined) unsafe=false; 38 | name = Util.ucFirst( name.replace(/_/g,' ') ); 39 | return this.renderDetailField(container, name, value, feature, null, {}, unsafe); 40 | }); 41 | fmt( 'Name', f.get('name'), f ); 42 | fmt( 'Type', f.get('type'), f ); 43 | // if score is undefined, that means it was originally 255 44 | var score = (f.get('score')); 45 | fmt( 'Score', (score === undefined ? 255 : score), f ); 46 | fmt( 'Description', f.get('note'), f ); 47 | fmt( 48 | 'Position', 49 | Util.assembleLocString({ start: f.get('start'), 50 | end: f.get('end'), 51 | ref: this.refSeq.name }) 52 | + ({'1':' (+)', '-1': ' (-)', 0: ' (no strand)' }[f.get('strand')] || ''), 53 | f 54 | ); 55 | 56 | 57 | if( f.get('seq') ) { 58 | fmt('Sequence and Quality', this._renderSeqQual( f ), f, true ); 59 | } 60 | /* multimapping */ 61 | var mm = (f.get('supplementary_alignment') || (typeof f.get('xm')!='undefined'&&f.get('xm')>1) || (typeof f.get('nh') != 'undefined' && f.get('nh') > 1 )); 62 | fmt("Multimapped",mm,f); 63 | 64 | /* change filtering options to only capture the options we are interested in 65 | seq, qual, supplementary_alignment, source, seq_length, NH, CIGAR, seq_reverse_complemented(?)*/ 66 | var additionalTags = array.filter( 67 | f.tags(), function(t) { 68 | return {source:1,seq_length:1,NH:1,CIGAR:1,seq_reverse_complemented:1}[t.toLowerCase()]; 69 | } 70 | ); 71 | array.forEach( additionalTags, function(t) { 72 | if(t=="NH") 73 | fmt("Number mapped locations",f.get(t),f); 74 | else 75 | fmt( t, f.get(t), f ); 76 | }); 77 | 78 | return container; 79 | }, 80 | 81 | // takes a feature, returns an HTML representation of its 'seq' 82 | // and 'qual', if it has at least a seq. empty string otherwise. 83 | _renderSeqQual: function( feature ) { 84 | 85 | var seq = feature.get('seq'), 86 | qual = feature.get('qual') || ''; 87 | if( !seq ) 88 | return ''; 89 | 90 | qual = qual.split(/\s+/); 91 | 92 | var html = ''; 93 | for( var i = 0; i < seq.length; i++ ) { 94 | html += '
' 95 | + seq[i]+''; 96 | if( qual[i] ) 97 | html += ''+qual[i]+''; 98 | html += '
'; 99 | } 100 | return '
'+html+'
'; 101 | }, 102 | 103 | // recursively find all the stylesheets that are loaded in the 104 | // current browsing session, traversing imports and such 105 | _getStyleSheets: function( inSheets ) { 106 | var outSheets = []; 107 | array.forEach( inSheets, function( sheet ) { 108 | outSheets.push( sheet ); 109 | array.forEach( sheet.cssRules || sheet.rules, function( rule ) { 110 | if( rule.styleSheet ) 111 | outSheets.push.apply( outSheets, this._getStyleSheets( [rule.styleSheet] ) ); 112 | },this); 113 | },this); 114 | return outSheets; 115 | }, 116 | 117 | // filters for BAM alignments according to some flags 118 | /* this function needs updated */ 119 | _getNamedFeatureFilters: function() { 120 | return lang.mixin( {}, this.inherited( arguments ), 121 | { 122 | hideMultiMappers: { 123 | desc: 'Hide multi-mapped alignments', 124 | title: 'Show only uniquely aligned reads', 125 | func: function( f ) { 126 | return ! (f.get('supplementary_alignment') || (typeof f.get('nh') != 'undefined' && f.get('nh') > 1 ) || (typeof f.get('xm')!='undefined'&&f.get('xm')>1)); 127 | } 128 | }, 129 | filterQuality: { 130 | desc: 'Filter by mapping quality', 131 | title: 'Set minimum mapping quality for visible reads', 132 | alwaysfilter: true, 133 | func: function( f ){ 134 | return ( (this.config.filterQuality === 0) || ((f.get('score') === undefined) || f.get('score') === 255 || f.get('score') >= this.config.filterQuality )) 135 | } 136 | }, 137 | hideForwardStrand: { 138 | desc: 'Hide reads aligned to the forward strand', 139 | title:'Show/hide forward strand reads', 140 | func: function( f ) { 141 | return f.get('strand') != 1; 142 | } 143 | }, 144 | hideReverseStrand: { 145 | desc: 'Hide reads aligned to the reverse strand', 146 | title:'Show/hide reverse strand reads', 147 | func: function( f ) { 148 | return f.get('strand') != -1; 149 | } 150 | }, 151 | hide21:{ 152 | desc: 'Hide 21-mers', 153 | title: 'Show/hide 21 bp-long reads', 154 | id: 'smrna-select-blue', 155 | func: function(f){ 156 | return f.get('seq_length') != 21; 157 | } 158 | }, 159 | hide22:{ 160 | desc: 'Hide 22-mers', 161 | title: 'Show/hide 22 bp-long reads', 162 | id: 'smrna-select-green', 163 | func: function(f){ 164 | return f.get('seq_length') != 22; 165 | } 166 | }, 167 | hide23:{ 168 | desc: 'Hide 23-mers', 169 | title: 'Show/hide 23 bp-long reads', 170 | id: 'smrna-select-purple', 171 | func: function(f){ 172 | return f.get('seq_length') != 23; 173 | } 174 | }, 175 | hide24:{ 176 | desc: 'Hide 24-mers', 177 | title: 'Show/hide 24 bp-long reads', 178 | id: 'smrna-select-orange', 179 | func: function(f){ 180 | return f.get('seq_length') != 24; 181 | } 182 | }, 183 | hidepi:{ 184 | desc: 'Hide piRNAs', 185 | title: 'Show/hide piRNAs (26-31 bp)', 186 | id: 'smrna-select-red', 187 | func: function(f){ 188 | return !(f.get('seq_length') > 25 && f.get('seq_length') < 32); 189 | } 190 | }, 191 | hideOthers:{ 192 | desc: 'Hide others', 193 | title: 'Show/hide all other sized reads', 194 | id: 'smrna-select-gray', 195 | func: function(f){ 196 | return this.config.isAnimal ? !(f.get('seq_length') < 21 || f.get('seq_length') > 31 || f.get('seq_length')==25) : !(f.get('seq_length') < 21 || f.get('seq_length') > 24); 197 | } 198 | } 199 | }); 200 | }, 201 | 202 | _alignmentsFilterTrackMenuOptions: function() { 203 | // add toggles for feature filters 204 | var track = this; 205 | return when( this._getNamedFeatureFilters() ) 206 | .then( function( filters ) { 207 | var sizesAr = ['hide21','hide22','hide23','hide24']; 208 | if (track.config.isAnimal) 209 | sizesAr.push('hidepi'); 210 | sizesAr.push('hideOthers'); 211 | return track._makeFeatureFilterTrackMenuItems( 212 | [ 213 | 'filterQuality', 214 | 'hideForwardStrand', 215 | 'hideReverseStrand', 216 | 'hideMultiMappers' 217 | ], 218 | sizesAr, 219 | filters ); 220 | }); 221 | } 222 | 223 | }); 224 | }); 225 | -------------------------------------------------------------------------------- /js/View/Dialog/ReadFilterDialogCheck.js: -------------------------------------------------------------------------------- 1 | define("SmallRNAPlugin/View/Dialog/ReadFilterDialogCheck", [ 2 | 'dojo/_base/declare', 3 | 'dojo/_base/lang', 4 | 'dojo/dom-construct', 5 | 'dijit/focus', 6 | 'dojo/_base/array', 7 | 'dijit/form/NumberSpinner', 8 | 'dijit/form/CheckBox', 9 | 'JBrowse/View/Dialog/WithActionBar', 10 | 'dojo/on', 11 | 'dijit/form/Button', 12 | 'SmallRNAPlugin/View/Track/_NamedFeatureFiltersMixin' 13 | ], 14 | function ( 15 | declare, 16 | lang, 17 | dom, 18 | focus, 19 | array, 20 | dijitNumberSpinner, 21 | dijitCheckedMenuItem, 22 | ActionBarDialog, 23 | on, 24 | Button, 25 | NamedFeatureFiltersMixin 26 | ) { 27 | 28 | return declare(ActionBarDialog, { 29 | /** 30 | * Dijit Dialog subclass to change the min 31 | * and max score of XYPlots 32 | */ 33 | 34 | //title: 'Filter all visible smRNA tracks', 35 | title: 'Filter all visible smRNA tracks', 36 | //autofocus: false, 37 | 38 | constructor: function (args) { 39 | this.browser = args.browser; 40 | this.sizeProps = this._initializeSizeProperties(args); 41 | this.otherProps = this._initializeOtherProperties(args); 42 | 43 | this.isAnimal = args.config.isAnimal; 44 | 45 | this.setCallback = args.setCallback || function () {}; 46 | this.cancelCallback = args.cancelCallback || function () {}; 47 | }, 48 | 49 | _initializeSizeProperties: function (args) { 50 | return { 51 | hide21: { 52 | id: 'hide21', 53 | hide: (args.config.hide21 === true ? true : undefined), 54 | 'class': 'smrna-select-blue', 55 | label: 'Hide 21-mers' 56 | }, 57 | hide22: { 58 | id: 'hide22', 59 | hide: (args.config.hide22 === true ? true : undefined), 60 | 'class': 'smrna-select-green', 61 | label: 'Hide 22-mers' 62 | }, 63 | hide23: { 64 | id: 'hide23', 65 | hide: (args.config.hide23 === true ? true : undefined), 66 | 'class': 'smrna-select-purple', 67 | label: 'Hide 23-mers' 68 | }, 69 | hide24: { 70 | id: 'hide24', 71 | hide: (args.config.hide24 === true ? true : undefined), 72 | 'class': 'smrna-select-orange', 73 | label: 'Hide 24-mers' 74 | }, 75 | hidepi: { 76 | id: 'hidepi', 77 | hide: (args.config.hidepi === true ? true : undefined), 78 | 'class': 'smrna-select-red', 79 | label: 'Hide piRNAs' 80 | }, 81 | hideOthers: { 82 | id: 'hideOthers', 83 | hide: (args.config.hideOthers === true ? true : undefined), 84 | 'class': 'smrna-select-gray', 85 | label: 'Hide other sizes' 86 | } 87 | } 88 | }, 89 | _initializeOtherProperties: function (args) { 90 | return { 91 | hideReverseStrand: { 92 | id: 'hidereverse', 93 | hide: (args.config.hideReverseStrand === true ? true : undefined), 94 | label: 'Hide reverse strand reads' 95 | }, 96 | hideForwardStrand: { 97 | id: 'hideforward', 98 | hide: (args.config.hideForwardStrand === true ? true : undefined), 99 | label: 'Hide forward strand reads' 100 | }, 101 | hideMultiMappers: { 102 | id: 'hidemulti', 103 | hide: (args.config.hideMultiMappers === true ? true : undefined), 104 | label: 'Hide multi-mapped alignments' 105 | }, 106 | filterQuality: { 107 | id: 'filterquality', 108 | hide: (args.config.filterQuality === undefined ? 0 : args.config.filterQuality), 109 | label: 'Minimum mapping quality' 110 | } 111 | } 112 | }, 113 | 114 | _fillActionBar: function (actionBar) { 115 | var ok_button = new Button({ 116 | label: "OK", 117 | onClick: lang.hitch(this, function () { 118 | this.filterCallback(); 119 | var out = { 120 | isAnimal: this.isAnimal 121 | }; 122 | for (var size in this.sizeProps) { 123 | out[size] = this.sizeProps[size].hide; 124 | } 125 | for (var opt in this.otherProps) { 126 | out[opt] = this.otherProps[opt].hide; 127 | } 128 | this.setCallback && this.setCallback(out); 129 | this.hide(); 130 | }) 131 | }).placeAt(actionBar); 132 | 133 | var cancel_button = new Button({ 134 | label: "Cancel", 135 | onClick: lang.hitch(this, function () { 136 | this.cancelCallback && this.cancelCallback(); 137 | this.hide(); 138 | }) 139 | }).placeAt(actionBar); 140 | }, 141 | 142 | filterCallback: function () { 143 | var dialog = this; 144 | var hide = lang.mixin(dialog.sizeProps, dialog.otherProps); 145 | var tracks = dialog.browser.view.visibleTracks(); 146 | array.forEach(tracks, function (track) { 147 | // operate only on smAlignments tracks 148 | if (!/\b(smAlignments)/.test(track.config.type)) 149 | return; 150 | for (var o in hide) { 151 | // handle quality filter info 152 | var h = hide[o].hide; 153 | if (h !== undefined) 154 | track._toggleFeatureFilter(o, h); 155 | } 156 | }); 157 | }, 158 | 159 | show: function (callback) { 160 | var dialog = this; 161 | dojo.addClass(this.domNode, 'smrna-filter-dialog'); 162 | 163 | // left pane for filtering by size 164 | var leftPane = dom.create('div', { 165 | id: 'smrna-filter-dialog-sizes', 166 | 'class': 'smrna-filter-dialog-column' 167 | }); 168 | dom.create('h3', { 169 | innerHTML: 'Filter by size' 170 | }, leftPane); 171 | var size; 172 | for (size in this.sizeProps) { 173 | if (size == 'hidepi' & dialog.isAnimal !== true) { 174 | continue 175 | } 176 | var obj = dialog.sizeProps[size]; 177 | var box = new dijitCheckedMenuItem({ 178 | id: 'smrna-dialog-' + obj.id + '-box', 179 | title: obj.label, 180 | _prop: size, 181 | 'class': obj.class, 182 | checked: (obj.hide === true ? true : false) 183 | }); 184 | box.onClick = lang.hitch(this, '_setSizeProp', box); 185 | leftPane.appendChild(box.domNode); 186 | dom.create('label', { 187 | "for": 'smrna-dialog-' + obj.id + '-box', 188 | innerHTML: obj.label 189 | }, leftPane); 190 | leftPane.appendChild(dom.create('br')); 191 | } 192 | 193 | //Right pane - other filter types 194 | var rightPane = dom.create('div', { 195 | id: 'smrna-filter-dialog-others', 196 | 'class': 'smrna-filter-dialog-column' 197 | }); 198 | dom.create('h3', { 199 | innerHTML: 'Filter by other properties' 200 | }, rightPane); 201 | for (var opt in dialog.otherProps) { 202 | var obj = dialog.otherProps[opt]; 203 | var box; 204 | if (opt === 'filterQuality') { 205 | box = new dijitNumberSpinner({ 206 | id: 'smrna-dialog-' + obj.id + '-box', 207 | title: obj.label, 208 | _prop: opt, 209 | value: obj.hide, 210 | constraints: { 211 | min: 0, 212 | max: 255 213 | }, 214 | smallDelta: 5, 215 | intermediateChanges: true, 216 | style: "width:50px;margin-right:5px;" 217 | }); 218 | box.onChange = lang.hitch(this, '_setOtherProp', box); 219 | } else { 220 | box = new dijitCheckedMenuItem({ 221 | id: 'smrna-dialog-' + obj.id + '-box', 222 | title: obj.label, 223 | _prop: opt, 224 | checked: (obj.hide === true ? true : false) 225 | }); 226 | box.onClick = lang.hitch(this, '_setOtherProp', box); 227 | } 228 | rightPane.appendChild(box.domNode); 229 | dom.create('label', { 230 | "for": 'smrna-dialog-' + obj.id + '-box', 231 | innerHTML: obj.label 232 | }, rightPane); 233 | rightPane.appendChild(dom.create('br')); 234 | } 235 | 236 | this.set('content', [ 237 | leftPane, 238 | rightPane 239 | ]); 240 | 241 | this.inherited(arguments); 242 | this.domNode.style.width = 'auto'; 243 | }, 244 | 245 | _setSizeProp: function (box) { 246 | if (this.sizeProps.hasOwnProperty(box._prop)) { 247 | this.sizeProps[box._prop]['hide'] = box.checked; 248 | } 249 | }, 250 | _setOtherProp: function (box) { 251 | if (this.otherProps.hasOwnProperty(box._prop)) { 252 | this.otherProps[box._prop]['hide'] = (box.checked === undefined ? box.value : box.checked); 253 | } 254 | }, 255 | 256 | hide: function () { 257 | this.inherited(arguments); 258 | window.setTimeout(lang.hitch(this, 'destroyRecursive'), 500); 259 | } 260 | }); 261 | }); 262 | -------------------------------------------------------------------------------- /test/data/seq/a59/b6d/00/Chr5-2.txt: -------------------------------------------------------------------------------- 1 | GCTTGTTCTTGAGATTTGTCACTCACTCTGATATGTTTACCTTGATAGCTAGCTGCCATCTTGCCGCTTGCTGTTGTGCACACACTTGGTAATCTGTTTACGAACATGAGTCTTGGGAAAGTTTCTGTTTCCTTTACTCACACCATTAAAGCCATGGAGCCTTTCTTCTCTGTTTTATTGTCTGCTATGTTTCTCGGGGAGGTGAGCTCTTTTTTTTATTTGGGTTTTTCTTTGACGTCTCGGAGTTGATTAATGCACTCGTACCTATTGTCCTCCTGTCTGGACTAAGTTGCTATGTGATTCTTGTTTCTAATGGCTTGTTAATGATAGTCTATATTACTCATCGCTTTTGTTTGATTTGTGTAAAGCATAATTCGTTTACTAACTCTTTCTTAGAAACCTACTCCATGGGTACTCGGTGCCATTGTACCAATTGTTGGTGGAGTTGCACTTGCTTCAATTTCGGAGGTCTCATTCAACTGGTTAGTTTGTCGACGAGTATTGTGACATTTAAGTCGGTGGTTATCTATTCTTCTGATAACTCTCAGATATTTACTACGGTTACTTGTTTTGTGGTAGGGCTGGATTTTCGAGTGCAATGGCATCAAACTTGACTAACCAATCCCGTAATGTGCTGAGTAAGAAAGTCATGGTTAAGAAAGATGTAAGTTTCCTATGTGTGGATCAAACTTTCAATCTTCGTGTTTTGGAATAAATTAACTAAAACTTGATTTTGTGTCTCGGCAGGATTCTCTTGACAACATCACTCTCTTCTCAATTATAACATTGATGTCTCTCGTTCTGATGGCTCCTGTGACTTTCTTTACGGAAGGCATCAAGTTCACTCCTTCATACATTCAATCAGCTGTGAGTTTAGTATATATTACGATTCTATTTTTTCTATATCCTTCTCAAATGTTTGCAGTTCCTAACAACCAATCTCGGTTTTGCAGGGTGTGAATGTTAAACAAATATATACAAAGTCTCTTATCGCTGCACTCTGCTTCCACGCATACCAGCAGGTTAGGCTTTTTTTTCTCTTAATGATTTGGTTGCTTTACTTGAGTATATAACGAATTTGAATTGACATTTCTGAAATGTGGATAATACAGGTGTCGTACATGATATTGGCGAGAGTATCACCGGTTACACATTCTGTCGGAAACTGTGTGAAACGTGTTGTGGTTATTGTGAGCTCTGTCATCTTCTTCAAGACACCCGTCTCGCCTGTTAATGCTTTCGGTAACATCCAGTCTTATTCTCTTCTCGGCTTCAGTGAATACGCAATACTTTGGAACTCATTGTCGTTTATTTTTGTCTCTGCGGCAGGAACTGGAATCGCCCTTGCGGGTGTCTTCTTATACTCCAGAGTGAAGGGTATTAAGCCAAAGCCAAAGACTGCTTAAGCAAATATCGGCTAATACCTAATGTCATATCACTCCCGCGCTTTGGATTTGTATACAATTTCTCGAGCTAAAGTTTTCAGATAGATGGTTTTATTCTTTTGCGGGTTTTTTCACGAAGTTTCATCATCCCTTTCTAAGCTTTTCGCTGCAGCCATCGGTTCTCTTAGAGTTTGTTATAAGTTCTCTTCTGTGTCTAGACAAATGCTAAACTCTTAAATTTCTTACAGTTTTTCCAAGAATAACTTGTCAACACATTCTCATTACTGCTTTTAGTTTACACGTTTAAGGTTTATTAGGAGGAGCACGTGAATTGTTCCTTTTGCTATGGTGATAAAAAGCACAATATTAAGCATTTGAGGATACCTCTTGACTTGCATTTGCACCCGATTCAGTAGTCTGCACGAGTTGTTTGAACTCCTTATCCACAGTTCAATACCTCTAAGTGATATGGATTCGACATATTTTAAAGTGATATTATACTTCAAAACTTTAGTTTATTTCCGTTAAGGACATTCATCGTGAACAACCATAATTTGAATCGCACAGAAATTTTTAAAAATGCTTTAAACTATTAGATCTCAGTAATTATTTAACATAATTTCTTGTATGCCATAAATTTTGTATATAAAATCATTCTTCCATTTATGCTATGCCCAAAAGTCATAATCTTAGCATTATACAGCTACATATTTACTGATCATAAAATTACGTATTGATCACATAATTTGTATCTATTTTTTAAAAGGTTAATACTCTTATATATCGTTGAATTAAAAAAAAAAAAAAACATTCGAAGACAATAAAATACTCGTTTCTATTGATTCGCTAGGTGAATTTACGAAGGAAAATTTTGATTTTTGGTCATAAAAAGAGTAATCTCGTTTGAAATAATATATTTGTTTTGAGAAATAATCTATTTTGATAGTTGTAAAGTGGGTAAACTGAATCGAACCATGTTTACTTTTTTTTTTTTTTGTCGTCATTTTCATTACTTCACAACTAACTTACATGAGTCCATGATATTACATATTGCATCTTTTTGGATCTTGCTACTTTTGCGAGATGATCAGCTACATCATTGATTGTACTATTCACTTTACTTACAACAAAAGAAGCTGAAATTGTAGCAAGTTTTTGTATGTCCTGGATATAAGCGGCCAAAGGGGAGTTAGTTGTGGGGCATGCCTTCTTGTCCTTTTGCAGATATGGCGCTACATTCTGATACAGGATTGAAGCATCGACACAAAATTTAACCTCTTCGTAACCCAGTCTCCGTACTTGCATCATTGCCGACCTAAGGGCTTCCGCTTCCGCTTCAATCGAAGAGTTAGTTGGAGGTATAGAGGCCATACCTTTGAGAACCATTTGAGCTTTGTCATTGTAAAGGACCCACCCAATTCCTGCACATTCAGTTGGGGAAACCCAAGATGCATCCACAAAGCAGCAGTATGCTTTGGCTTCTTTCATGATATCTTGTACATTCCCCATTAATGCCCCGGTCTTCTGTTGGTCTTGTTGAGAATTTGGTTGGGGCTGAGTCAAATCGATGAGCGCTTTGTTGATAATATCTGGTATAGACCATTTTCAGTTGTTGAAGATAAGGTCATTGCTCATTTTCCAGATACGCCAACCAATGAAAGGGAATAGACTTACATCCTTTCTGTGGTTTTTTGTCAGACTCATCAATTTCTCAATATTCTCCATATAAGAGTTTAAGTTCCAAGATGCACCTGGTATAGAAAGGTTCGGTGCCTGCTCCCAGATTTCTCTGCTGATTCGGCATTGAAAGAGCAAATGGTTTATGTTTTCCGGAGCTTCACCACATCTGAAACAAATGTCATCTGAAGTCAACTTTCTCCTCTTGAGGTTATCTGCAGTCGGTAAAGCATTATGGAGTACTTTCCACCAAAAGTGTTTAATCTTTGGTGGAGTATTAAGGTTCCATAATGTTGACTTTTAAATTTTATGATAAATGTCTTAAATTATATAAATACGATCTAAAAGTAACTTTAAATTTAAAGTTTACATTTAGATATTTGATAAACTTCATTTAATAATCTTTGTCAATGTGTCTATATAACCTAATGTTTTGTTCTTGTTTTGTTCTTGTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTATGAAAAGTATTATTACCTGATGTATATTAATTGTTATGTTGTGATTGGTTTCTGTTGGAGCTTCTCTGCTTATGTGTATGAGTTGTTTTGTTTTGATTGGTTAATCTTTTTAATGATGTGTCTAGCGAGAGTTATTTTATTTTAATTGTACTATATTTATATTGTGATGTTTCTCTTAAATTAAAAATTTATGACTATATATATGACAATATATATATATATATATATATATATATACATTATTGAGATAGATAATGAATACATTAGTTTATCATTAAATTTAATAGGTACTGATCTTCAAATTATTTTCAAACGATTCTCTGTCAATTTCTTGATATTTTTAAACTAAAATCCATTTTTTAAAAAATAGACTGATTTAACAAACATTAAAAGTTAATTGTTTCTGTACATGCCACGGATCGAAAATGAGTCAGTAAATGAATATTTTTTACCTAAAGTCACACATTGTATATACCTAAGTAAATGATACATGACCAAAATTAGAAGATCAAGAATCCTTATATTACGAAAATATCCGGTTACATTCGTTGAATACTTTAATGAAGAATCTAGGATATAATTAAAGAAGAAGAAAATATGTAAGCATTTAGAAATAAAATAACTTGGAGATATAAGCAAACCATAAACACGTCCATATGAATGAATGGTACACTCCTCGTAAATAAATAAATATATGCATCAAAATGAGAAAATCTTCACTTTTATTTATTCTTAATACGTCAGATTCTCTGAACACAAAATGATATAATTTGTAGATAACTTACTCAAAACGTAAGAACTCACTATCTATTATCATTTATTAACCACCATCTCATTAATCTTATAAATATGTACTCATTAGATTGTCAAAAGTAAAACCTCACAATACACTTTAAACTACAAATCAAAACAATGGCCTCTCTATTCTCTTCAGTTCTCTTGTCTCTTTGTTTACTCTCTTCACTTTTTCTCTCAAATGCAAACGCTAAGCCAAAACTAGGCTTCACCGCGGATCTAATCCACCGTGATTCTCCTAAATCGCCGTTCTATAACCCGATGGAAACCTCTTCCCAGCGTCTACGAAACGCGATCCACCGATCCGTTAACCGTGTTTTCCATTTCACTGAAAAGGATAACACACCACAACCACAGATTGACCTCACCTCAAATAGCGGTGAATATCTCATGAACGTATCCATTGGAACACCTCCTTTCCCGATCATGGCCATCGCCGACACCGGAAGTGATCTCCTCTGGACGCAGTGCGCACCATGCGATGATTGTTACACTCAAGTTGATCCTCTCTTTGACCCTAAAACGTCTTCCACATACAAAGACGTTTCTTGCTCCTCAAGTCAATGTACTGCCCTAGAAAATCAAGCCTCTTGTTCCACAAATGACAACACTTGTTCTTACTCATTGTCTTACGGGGATAACTCATACACAAAGGGTAACATCGCCGTGGATACCTTAACGCTCGGCTCCAGCGATACCCGCCCTATGCAGCTTAAGAATATTATTATCGGTTGTGGTCACAACAACGCTGGAACGTTTAACAAGAAAGGCTCTGGAATCGTCGGACTAGGTGGTGGTCCGGTTTCGCTTATCAAGCAACTTGGCGACTCCATCGACGGTAAATTCTCATACTGCTTGGTTCCTCTAACTTCCAAAAAGGATCAAACGAGTAAAATCAACTTCGGAACCAATGCCATCGTGTCGGGATCAGGAGTTGTCTCAACTCCTCTGATCGCAAAGGCGTCTCAAGAGACCTTCTATTACCTAACCCTAAAATCCATTAGCGTGGGAAGCAAGCAAATCCAATACTCAGGCTCAGATTCTGAAAGCAGCGAGGGAAACATCATCATCGATTCAGGCACAACTTTAACGTTATTACCGACTGAATTTTACTCCGAGCTCGAGGATGCGGTTGCATCCTCTATCGATGCTGAGAAGAAGCAAGATCCACAAAGCGGTTTGAGTCTATGTTACAGTGCAACCGGAGATCTAAAAGTTCCAGTCATTACTATGCATTTTGATGGAGCCGATGTGAAGCTTGACTCCTCCAATGCCTTTGTACAAGTCTCGGAGGATTTGGTTTGCTTTGCCTTCCGCGGAAGCCCGAGTTTCTCCATATACGGTAATGTGGCGCAGATGAACTTTCTTGTTGGATACGACACTGTTTCCAAAACGGTGTCATTTAAGCCAACAGATTGTGCAAAGATGTAGTTGTTTCATCTCAACATGTTTTTCAAAATTGTGTTTTCAATTACAATAATGGCTGATTTAGTTTCAGCCTTAGTTCTTTTGAATTTTTCTAATTCACATGTAGTAGTCTATCTTTTCAAGGGAGAGTTAAATTCTCGACCTTTTGTTCTTTTGGTGATGCTTTGTATTTCCTTGAATTTTCAATCACAATTAAAATCATGAAAACCTTATCTCCGGTAACTATTTTCTTGTCCATCTCTATACTCTGTTTTAGTTTATAATCATCTCTATGATGTAAACCAAATATGACAAGACAATTCTATAATTTTGTTCAAAATTTAGTTTTTTTTTTCATTTTACTAATAAAATCTAGAAATACTACTTTTGTGTCTATTATATTATTGTGATGAAATACTTATAAGAAACAGATGAATGTGATTCTAATTCAATATTGCTTTTAAGGAATTATATTGGTCCTACTATTCTATTTTGATGTGTTCTATATTTTACTATATTCAATGGGATTATGGATTATAGAAATATTTTGAAAATATTATACTATTATTTATAAATAATTCAATTAGTTTTTCTTCTTAAGTTTCTTATAAAAAATAAATATATCTTATAAGAAATAAATATATTTTATATTTCATAAAAATCATACATTGTACATATCTAGGTGGATGATACATGGCCTAAATTAGATCATGAATCATAAAAATCCAGCTGTAGATAAACATAACAAGGATGAATGGTACAATCCTGGTCAAAAAAAATAAAAGGAAAAGTTATATGCATTAAAATGAGAAAATCTTCGCTTTTATTGTTTCTTATTTATCAGATTCTCTAAATGTAAATGACACAATTTGTAGATAATTTACTAAAAATGTAAGAATCTCATCATGTACTACCATTTATGAATCCTTATCCAATTGACCTTATAAATATTACTCATCAGATTGTCAAAAGTAAAAACTGACCATTCAGGCAATCACTTAAACTACAATCTAAGAAAATGGCCTCTCTATTCACTTCACTTCTCTTGTCTCTATGTTTATTCTCTTCTCCTATTTTCTCAAACGCAAACGCCAAACCAAAACTAGGCTTCACCGCGGATCTGATCCACCGCGATTCTCCTAAATCGCCATTCTATAACCCGGCGGAAACCCCTTCCCAACGTATGAGAAACGCTATCCACCGATCCTTTAACCGTGCTTCCCATTTCAGTAATCTTTTTGAAAAGGATGCATCACTTAACGCACCACAAACTGATATCACCAAATATTTCGGTATATATCTTATGAACGTATCCCTTGGGAGTTGGGACACCTCCCGTCCCAATCATGGCGGCCGCTGACACCGGAAGTGATCTCATCTGGACGCAGTGCAAACCATGCGATGATTGTTACACTCAAGTTGATCCTCTCTTTGACCCTAAAGCGTCTTCCACATACAAAGACGTTTCTTGCCCCTCAAGCCAATGTAGGGCTCTAAAAGATGATGCTTCTTGTTCCAAAAAAGACAACACTTGCTCTTACTCAATGAATTACGGGGATAACTCATACTCACGGGGTAATGTCGCTGTGGATACCTTAACGCTCGGCTCCACCGATAACCGTCCGGTGCAGGTTAAGAATATTATCATCGGTTGTGGTCACGAAAACGCTGTAACATTTAGAAACAAGAGCTCTGGAATCGTTGGACTTGGTGGTGGTGCGGTTTCGCTCGTTAAACAACTCGGAGACTCCATCGAAGGTAAATTCTCATACTGCTTGGTACCTGAAAATGATCAAACGAGCAAGATTAGTTTCGGAACCAATGCGGTTGTGTCGGGACCGGGAACTGTCTCAACTCCTTTGGTCGTGAAGTCTCCAGAGACCTTCTATTTTCTAACCCTAAAATCTATTACCGTGGGAAGCAAGAATATGCCAACCCCAGGCTCTGATATCAAGGGAAACATGGTCATCGATTCGGGCACAACTCTAACTCTGTTACCTGGGAAATATTATTTCCAGATTGAGAGTGCTGTTGCGTCTTTAATCGATGCAGAGAGGTCGAAAGATGAAAGAATCGGTTCGAGTCTTTGATACAATGCAACCGCAGATCTGAAAGTCCCAGTCATTACTATGCATTTCGATGGAGCAGATGTGAAGCTTGATTCCTATAATTCATTTTTTAAAGTCTCAGATGATTTGGTTTGCTTTGCCTTTGGCTTGAACTTGATTACGAGGGATGGGATATACGGGAATGTGGCGCAGAAGAACTTTCTTGTTGGATACGACACTGTTTCCAAATCGTTGTCATTTAAAAAAACAGATTGTGCAAAGATGTAGATGGTTCAGCTTAGCATGTGGCTAATTTCCTTTTTTCAAAAGTATGTTTTCAGTTATCATTATGGCTGATTTGATTTTAGCCTTAAAATAGTTATTTGAATTCATTCAGCAGGACCATAGCACTGCAAGAGAACAAAGCCTTTTTCGACAGACTTTCCAACGATACATAAACGGTCGGAAATTCTCGACAGTTTTGTAATGATATTCCGACGGATTTCGCACGACATGTTTCCCGTTCTCGCACTGCAACCGGTTTCGCAACCATAGTTATCGTCAGAATAGCGTAGAGAAATTGTCAGAAAATACCTCATCGAAAACCCGTCGGTAATTTGTAACACGTTTGCAACGACATTCAGATTTCCAACGAGATAAAATCGACCAATTTATGTCATTGAAAATTCGTCGAATACGGCTGTTTCCGACGTTATTCCGACGATTTCATCCGTTGGAAATATCCTATCGAACGTTATAGCATGTAATAAAATCGCCTTTAAAAGCGACTAAGCTTGCACCTTTGTGTCCAAAAAACTTTTTATCAACTAGAGATAAAATAGGTTATTAGTTTACCTTGCCAGAAAAATAAATAAAAACAATGTGAAACTTAAGATAAAAGGCAGACGAGATTTTTTAGGTTCTGTAAGACAATCCTTTGCTATTTTGTTTTGACATGCATAGAAGTTAACACATACTACGGAAATGTTAAAAAAAAAACGAGATAGTGTCGCCATGATAACTGCAATGCTGCTGAAACCCTAAACTTTATTAATGAACTAATGAAGCCAAATCATTTTTCTTTTATGATTAAAAAGTTGCCAAGATTCGTGCTCACTCTGTCAAAGACAACAACATTATCATTTTTCAAACAGTAGTTGATTAAACTAAATTAAAAATGGGTATATAAAATGAGTTATAACGATAAAGACAACAACGACTTTCCCTTTGCTTGATTATTTAAAACAAGTCCCTGATAAGAAGAAGACGTCTAGTGGAAAATAAAATGTTACAGAAAAGGCGCCAATACACAATTGTGGCGACATTATGAACTTGCTCAATAAGAGAAAACTTTAAAGAAAAGAGGGGGATATTAAACAATTATAACAAATCTACCAAAATTTTGACTATAAATAGATCACTACACATATGGATTTGTCTCATCGAAGTAAATATTAAATTGAAAGAGCAAAAAAATAAGTCTTAATAAACGCAAAGCATTAAAGAGATGGCAAAGAACCTCAACTCCGTTAGCTTCATCGTTCTCTTGCTGGTTCTTTTGGTGGCTTCCACCGGTATGAATTTATTCTCTAATCTCTATTATACTTTGTGTGTATATGTATATGCAAAAAACATTTACATAATAATCTTTTGCTGATGAATTTACTGAAATGTCAAAATGTAGAAATCCTGAAGAGCGATGCTGCATGCTTCACGTTCTTAGGCGAGTGCGGGCCGGAGCCGTTTACAGGTTCAAATGCTGATTGCTTAGCGTGTTGTGTAGCTCTCTACAAGAGTCCACCAGTTTGTGCTGGACGTGTTGAGGGAGTCCCGGCTCACTGCCATTGCTACAAATCGTAAAGAGGTTCAAAATAAACCTCATATATATAATTACCAAGTGTAACTTTTCTTTTCATTCGGTGTGATAAGGACATTACATGTGTGTGTGTGTGTGTCTGTGTGTGGTAAACTGGTGTCTGGTAAGTTTCTTTTGAATCCAAATAAAACATCAAGGGCAAAGCTTCACTGCTTCCCCTTAATAAATGTAAGCTCATGTTGTCTTCACTTTTGATTCGTTTTGAATAATAAACTCGTTTTTTGTTCCCCATTTCATTCGAAACTATATTCAAATTTCTGTCACTCCAAATTATCTAACAAATATTGACCATTTATTGGATAGTAAAATCTGATTT -------------------------------------------------------------------------------- /js/View/Track/smAlignments.js: -------------------------------------------------------------------------------- 1 | define("SmallRNAPlugin/View/Track/smAlignments", [ 2 | 'dojo/_base/declare', 3 | 'dojo/_base/lang', 4 | 'dojo/_base/array', 5 | 'dojo/promise/all', 6 | 'dojo/dom-construct', 7 | 'dojo/dom-class', 8 | 'dojo/Deferred', 9 | 'JBrowse/Util', 10 | 'SmallRNAPlugin/View/StrandedBitmapRectLayout', 11 | 'JBrowse/View/Track/CanvasFeatures', 12 | 'SmallRNAPlugin/View/Track/_AlignmentsMixin' 13 | ], 14 | function ( 15 | declare, 16 | lang, 17 | array, 18 | all, 19 | domConstruct, 20 | domClass, 21 | Deferred, 22 | Util, 23 | Layout, 24 | CanvasFeatureTrack, 25 | AlignmentsMixin 26 | ) { 27 | 28 | return declare([CanvasFeatureTrack, AlignmentsMixin], { 29 | 30 | constructor: function (args) {}, 31 | 32 | _defaultConfig: function () { 33 | var thisB = this; 34 | var c = Util.deepUpdate( 35 | lang.clone(this.inherited(arguments)), { 36 | glyph: 'SmallRNAPlugin/View/FeatureGlyph/smAlignment', 37 | maxFeatureGlyphExpansion: 0, 38 | maxFeatureScreenDensity: 6, 39 | hideMultiMappers: false, 40 | hideForwardStrand: false, 41 | hideReverseStrand: false, 42 | hide21: false, 43 | hide22: false, 44 | hide23: false, 45 | hide24: false, 46 | hidepi: false, 47 | hideOthers: false, 48 | maxHeight: 400, 49 | filterQuality: 0, 50 | isAnimal: thisB._isAnimal(), 51 | 52 | histograms: { 53 | description: 'coverage depth', 54 | binsPerBlock: 200 55 | }, 56 | 57 | style: { 58 | showLabels: false, 59 | label: "seq_length", 60 | description: false, 61 | origin_color: 'black', 62 | clip_marker: true, 63 | solidFill: false 64 | } 65 | } 66 | ); 67 | return c; 68 | }, 69 | 70 | _isAnimal: function () { 71 | return false; 72 | }, 73 | 74 | /* Functions from Canvas tracks that need to be changed for small-rna specific purposes */ 75 | _getLayout: function (scale) { 76 | if (!this.layout || this._layoutpitchX != 4 / scale) { 77 | // if no layoutPitchY configured, calculate it from the 78 | // height and marginBottom (parseInt in case one or both are functions), or default to 3 if the 79 | // calculation didn't result in anything sensible. 80 | var pitchY = this.getConf('layoutPitchY') || 4; 81 | this.layout = new Layout({ 82 | pitchX: 4 / scale, 83 | pitchY: pitchY, 84 | maxHeight: this.getConf('maxHeight'), 85 | displayMode: this.displayMode 86 | }); 87 | this._layoutpitchX = 4 / scale; 88 | } 89 | 90 | return this.layout; 91 | }, 92 | 93 | fillFeatures: function (args) { 94 | var thisB = this; 95 | 96 | var blockIndex = args.blockIndex; 97 | var block = args.block; 98 | var blockWidthPx = block.domNode.offsetWidth; 99 | var scale = args.scale; 100 | var leftBase = args.leftBase; 101 | var rightBase = args.rightBase; 102 | var finishCallback = args.finishCallback; 103 | 104 | var fRects = []; 105 | 106 | // count of how many features are queued up to be laid out 107 | var featuresInProgress = 0; 108 | // promise that resolved when all the features have gotten laid out by their glyphs 109 | var featuresLaidOut = new Deferred(); 110 | // flag that tells when all features have been read from the 111 | // store (not necessarily laid out yet) 112 | var allFeaturesRead = false; 113 | 114 | var errorCallback = lang.hitch(thisB, function (e) { 115 | this._handleError(e, args); 116 | finishCallback(e); 117 | }); 118 | 119 | var layout = this._getLayout(scale); 120 | 121 | // query for a slightly larger region than the block, so that 122 | // we can draw any pieces of glyphs that overlap this block, 123 | // but the feature of which does not actually lie in the block 124 | // (long labels that extend outside the feature's bounds, for 125 | // example) 126 | var bpExpansion = Math.round(this.config.maxFeatureGlyphExpansion / scale); 127 | 128 | var region = { 129 | ref: this.refSeq.name, 130 | start: Math.max(0, leftBase - bpExpansion), 131 | end: rightBase + bpExpansion 132 | }; 133 | this.store.getFeatures(region, 134 | function (feature) { 135 | if (thisB.destroyed || !thisB.filterFeature(feature)) 136 | return; 137 | fRects.push(null); // put a placeholder in the fRects array 138 | featuresInProgress++; 139 | var rectNumber = fRects.length - 1; 140 | 141 | // get the appropriate glyph object to render this feature 142 | thisB.getGlyph( 143 | args, 144 | feature, 145 | function (glyph) { 146 | // have the glyph attempt 147 | // to add a rendering of 148 | // this feature to the 149 | // layout 150 | //console.log('feature', JSON.stringify(feature.data)); 151 | var fRect = glyph.layoutFeature( 152 | args, 153 | layout, 154 | feature 155 | ); 156 | if (fRect === null) { 157 | // could not lay out, would exceed our configured maxHeight for negative strand 158 | // mark the block as exceeding the max height 159 | block.maxHeightExceededBottom = true; 160 | } else if (fRect === undefined) { 161 | // could not layout because would exceed for postive strand 162 | // mark as exceeding top max height 163 | block.maxHeightExceededTop = true; 164 | } else { 165 | // laid out successfully 166 | if (!(fRect.l >= blockWidthPx || fRect.l + fRect.w < 0)) 167 | fRects[rectNumber] = fRect; 168 | } 169 | 170 | // this might happen after all the features have been sent from the store 171 | if (!--featuresInProgress && allFeaturesRead) { 172 | featuresLaidOut.resolve(); 173 | } 174 | }, 175 | errorCallback 176 | ); 177 | }, 178 | 179 | // callback when all features sent 180 | function () { 181 | if (thisB.destroyed) 182 | return; 183 | 184 | allFeaturesRead = true; 185 | if (!featuresInProgress && !featuresLaidOut.isFulfilled()) { 186 | featuresLaidOut.resolve(); 187 | } 188 | 189 | featuresLaidOut.then(function () { 190 | 191 | var totalHeight = layout.getTotalHeight(); 192 | var c = block.featureCanvas = 193 | domConstruct.create( 194 | 'canvas', { 195 | height: totalHeight, 196 | width: block.domNode.offsetWidth + 1, 197 | style: { 198 | cursor: 'default', 199 | height: totalHeight + 'px', 200 | position: 'absolute' 201 | }, 202 | innerHTML: 'Your web browser cannot display this type of track.', 203 | className: 'canvas-track' 204 | }, 205 | block.domNode 206 | ); 207 | var ctx = c.getContext('2d'); 208 | 209 | // finally query the various pixel ratios 210 | var ratio = Util.getResolution(ctx, thisB.browser.config.highResolutionMode); 211 | // upscale canvas if the two ratios don't match 212 | if (thisB.browser.config.highResolutionMode != 'disabled' && ratio >= 1) { 213 | 214 | var oldWidth = c.width; 215 | var oldHeight = c.height; 216 | 217 | c.width = oldWidth * ratio; 218 | c.height = oldHeight * ratio; 219 | 220 | c.style.width = oldWidth + 'px'; 221 | c.style.height = oldHeight + 'px'; 222 | 223 | // now scale the context to counter 224 | // the fact that we've manually scaled 225 | // our canvas element 226 | ctx.scale(ratio, ratio); 227 | } 228 | 229 | //console.log(block.maxHeightExceededBottom,block.maxHeightExceededTop); 230 | // bottom overflow, aka negative strand 231 | if (block.maxHeightExceededBottom) 232 | thisB.markBlockHeightOverflow(block, false); 233 | if (block.maxHeightExceededTop) 234 | thisB.markBlockHeightOverflow(block, true); 235 | 236 | thisB.heightUpdate(totalHeight, 237 | blockIndex); 238 | 239 | thisB.renderFeatures(args, fRects); 240 | 241 | thisB.renderClickMap(args, fRects); 242 | // add origin 243 | thisB.renderOrigin(args, layout.getOriginY()); 244 | 245 | finishCallback(); 246 | }); 247 | }, 248 | errorCallback 249 | ); 250 | }, 251 | 252 | markBlockHeightOverflow: function (block, top) { 253 | if (block.heightOverflowedBottom && !(top)) 254 | return; 255 | else if (block.heightOverflowedTop && top) 256 | return; 257 | // don't draw if we turned off clip markers 258 | if (!this.config.style.clip_marker) 259 | return; 260 | if (top) 261 | block.heightOverflowedTop = true; 262 | else 263 | block.heightOverflowedBottom = true; 264 | 265 | var topHeight = (top ? 0 : this.height - 16); 266 | block.heightOverflowed = true; 267 | domClass.add(block.domNode, 'height_overflow'); 268 | domConstruct.create('div', { 269 | className: 'smrna_height_overflow_message' + (top ? '_top' : '_bottom'), 270 | innerHTML: 'Max height reached', 271 | style: { 272 | top: (topHeight) + 'px', 273 | height: '16px' 274 | } 275 | }, block.domNode); 276 | }, 277 | 278 | renderOrigin: function (args, originY) { 279 | var canvas = args.block.featureCanvas; 280 | var ctx = this.getRenderingContext(args); 281 | if (ctx) { 282 | var originColor = this.config.style.origin_color; 283 | if (typeof originColor == 'string' && !{ 284 | 'none': 1, 285 | 'off': 1, 286 | 'no': 1, 287 | 'zero': 1 288 | }[originColor]) { 289 | ctx.fillStyle = originColor; 290 | ctx.fillRect(0, originY, canvas.width, 1); 291 | } 292 | } 293 | }, 294 | 295 | _trackMenuOptions: function () { 296 | var track = this; 297 | var displayOptions = []; 298 | return all([this.inherited(arguments), this._alignmentsFilterTrackMenuOptions(), displayOptions]) 299 | .then(function (options) { 300 | var o = options.shift(); 301 | options.unshift({ 302 | type: 'dijit/MenuSeparator' 303 | }); 304 | return o.concat.apply(o, options); 305 | }); 306 | } 307 | }); 308 | }); 309 | -------------------------------------------------------------------------------- /js/View/Track/smHTMLAlignments.js: -------------------------------------------------------------------------------- 1 | define("SmallRNAPlugin/View/Track/smHTMLAlignments", [ 2 | 'dojo/_base/declare', 3 | 'dojo/_base/array', 4 | 'dojo/_base/lang', 5 | 'dojo/promise/all', 6 | 'dojo/dom-construct', 7 | 'dojo/dom-class', 8 | 'dojo/Deferred', 9 | 'JBrowse/Util', 10 | 'SmallRNAPlugin/View/StrandedBitmapRectLayout', 11 | 'JBrowse/View/Track/HTMLFeatures', 12 | 'SmallRNAPlugin/View/Track/_AlignmentsMixin' 13 | ], 14 | function ( 15 | declare, 16 | array, 17 | lang, 18 | all, 19 | domConstruct, 20 | domClass, 21 | Deferred, 22 | Util, 23 | Layout, 24 | HTMLFeatures, 25 | AlignmentsMixin 26 | ) { 27 | 28 | return declare([HTMLFeatures, AlignmentsMixin], { 29 | 30 | constructor: function (args) { 31 | this.glyphHeight = 4; 32 | }, 33 | 34 | _defaultConfig: function () { 35 | var thisB = this; 36 | var c = Util.deepUpdate( 37 | lang.clone(this.inherited(arguments)), { 38 | maxFeatureScreenDensity: 6, 39 | 40 | hideMultiMappers: false, 41 | hideForwardStrand: false, 42 | hideReverseStrand: false, 43 | hide21: false, 44 | hide22: false, 45 | hide23: false, 46 | hide24: false, 47 | hidepi: false, 48 | hideOthers: false, 49 | maxHeight: 400, 50 | filterQuality: 0, 51 | isAnimal: thisB._isAnimal(), 52 | 53 | style: { 54 | _defaultLabelScale: 50, 55 | className: 'smrna-alignment', 56 | arrowheadClass: 'arrowhead', 57 | origin_color: 'black', 58 | centerChildrenVertically: true, 59 | showSubfeatures: false, 60 | showLabels: false, 61 | clip_marker: 'black' 62 | } 63 | } 64 | ); 65 | return c; 66 | }, 67 | 68 | _isAnimal: function () { 69 | return false; 70 | }, 71 | 72 | 73 | /* Functions from html tracks that need to be changed for small-rna specific purposes */ 74 | _getLayout: function (scale) { 75 | if (!this.layout || this._layoutpitchX != 4 / scale) { 76 | // if no layoutPitchY configured, calculate it from the 77 | // height and marginBottom (parseInt in case one or both are functions), or default to 3 if the 78 | // calculation didn't result in anything sensible. 79 | var pitchY = this.getConf('layoutPitchY') || 4; 80 | this.layout = new Layout({ 81 | pitchX: 4 / scale, 82 | pitchY: pitchY, 83 | maxHeight: this.getConf('maxHeight'), 84 | displayMode: 'normal' 85 | }); 86 | this._layoutpitchX = 4 / scale; 87 | } 88 | 89 | return this.layout; 90 | }, 91 | 92 | fillFeatures: function (args) { 93 | var blockIndex = args.blockIndex; 94 | var block = args.block; 95 | var leftBase = args.leftBase; 96 | var rightBase = args.rightBase; 97 | var scale = args.scale; 98 | var stats = args.stats; 99 | var containerStart = args.containerStart; 100 | var containerEnd = args.containerEnd; 101 | var finishCallback = args.finishCallback; 102 | var browser = this.browser; 103 | 104 | 105 | this.scale = scale; 106 | 107 | block.featureNodes = {}; 108 | 109 | //determine the glyph height, arrowhead width, label text dimensions, etc. 110 | if (!this.haveMeasurements) { 111 | this.measureStyles(); 112 | this.haveMeasurements = true; 113 | } 114 | 115 | var curTrack = this; 116 | 117 | var featCallback = lang.hitch(this, function (feature) { 118 | var uniqueId = feature.id(); 119 | if (!this._featureIsRendered(uniqueId)) { 120 | if (this.filterFeature(feature)) { 121 | 122 | // hook point 123 | var render = 1; 124 | if (typeof this.renderFilter === 'function') 125 | render = this.renderFilter(feature); 126 | 127 | if (render === 1) { 128 | this.addFeatureToBlock(feature, uniqueId, block, scale, containerStart, containerEnd); 129 | } 130 | } 131 | } 132 | }); 133 | 134 | this.store.getFeatures({ 135 | ref: this.refSeq.name, 136 | start: leftBase, 137 | end: rightBase 138 | }, 139 | featCallback, 140 | function (args) { 141 | curTrack.heightUpdate(curTrack._getLayout(scale).getTotalHeight(), 142 | blockIndex); 143 | if (args && args.maskingSpans) { 144 | //note: spans have to be inverted 145 | var invSpan = []; 146 | invSpan[0] = { 147 | start: leftBase 148 | }; 149 | var i = 0; 150 | for (var span in args.maskingSpans) { 151 | if (args.maskingSpans.hasOwnProperty(span)) { 152 | span = args.maskingSpans[span]; 153 | invSpan[i].end = span.start; 154 | i++; 155 | invSpan[i] = { 156 | start: span.end 157 | }; 158 | } 159 | } 160 | invSpan[i].end = rightBase; 161 | if (invSpan[i].end <= invSpan[i].start) { 162 | invSpan.splice(i, 1); 163 | } 164 | if (invSpan[0].end <= invSpan[0].start) { 165 | invSpan.splice(0, 1); 166 | } 167 | curTrack.maskBySpans(invSpan, args.maskingSpans); 168 | } 169 | if (block.maxHeightExceededBottom) 170 | curTrack.markBlockHeightOverflow(block, false) 171 | if (block.maxHeightExceededTop) 172 | curTrack.markBlockHeightOverflow(block, true); 173 | curTrack.renderOrigin(block, curTrack.layout.getOriginY()); 174 | finishCallback(); 175 | }, 176 | function (error) { 177 | console.error(error, error.stack); 178 | curTrack.fillBlockError(blockIndex, block, error); 179 | finishCallback(); 180 | } 181 | ); 182 | }, 183 | renderFeature: function (feature, uniqueId, block, scale, containerStart, containerEnd) { 184 | //featureStart and featureEnd indicate how far left or right 185 | //the feature extends in bp space, including labels 186 | //and arrowheads if applicable 187 | 188 | var featureEnd = feature.get('end'); 189 | var featureStart = feature.get('start'); 190 | if (typeof featureEnd == 'string') 191 | featureEnd = parseInt(featureEnd); 192 | if (typeof featureStart == 'string') 193 | featureStart = parseInt(featureStart); 194 | // layoutStart: start genome coord (at current scale) of horizontal space need to render feature, 195 | // including decorations (arrowhead, label, etc) and padding 196 | var layoutStart = featureStart; 197 | // layoutEnd: end genome coord (at current scale) of horizontal space need to render feature, 198 | // including decorations (arrowhead, label, etc) and padding 199 | var layoutEnd = featureEnd; 200 | 201 | var strand = feature.get('strand'); 202 | 203 | var levelHeight = this.glyphHeight + this.glyphHeightPad; 204 | 205 | layoutEnd += Math.max(1, this.padding / scale); 206 | 207 | var top = this._getLayout(scale) 208 | .addRect(uniqueId, 209 | layoutStart, 210 | layoutEnd, 211 | levelHeight, 212 | feature); 213 | 214 | if (top === null || top === undefined) { 215 | // could not lay out, would exceed our configured maxHeight 216 | // mark the block as exceeding the max height 217 | //if (top === null && block.maxHeightExceededBottom !== true) 218 | if (top === null) 219 | block.maxHeightExceededBottom = true; 220 | //else if(block.maxHeightExceededTop !== true) 221 | else 222 | block.maxHeightExceededTop = true; 223 | return null; 224 | } 225 | 226 | var featDiv = this.config.hooks.create(this, feature); 227 | this._connectFeatDivHandlers(featDiv); 228 | // NOTE ANY DATA SET ON THE FEATDIV DOM NODE NEEDS TO BE 229 | // MANUALLY DELETED IN THE cleanupBlock METHOD BELOW 230 | featDiv.track = this; 231 | featDiv.feature = feature; 232 | featDiv.layoutEnd = layoutEnd; 233 | 234 | // border values used in positioning boolean subfeatures, if any. 235 | featDiv.featureEdges = { 236 | s: Math.max(featDiv.feature.get('start'), containerStart), 237 | e: Math.min(featDiv.feature.get('end'), containerEnd) 238 | }; 239 | 240 | // (callbackArgs are the args that will be passed to callbacks 241 | // in this feature's context menu or left-click handlers) 242 | featDiv.callbackArgs = [this, featDiv.feature, featDiv]; 243 | 244 | 245 | block.featureNodes[uniqueId] = featDiv; 246 | 247 | // hook point 248 | if (typeof this.featureHook1 === 'function') 249 | this.featureHook1(feature, featDiv); 250 | 251 | // record whether this feature protrudes beyond the left and/or right side of the block 252 | if (layoutStart < block.startBase) { 253 | if (!block.leftOverlaps) block.leftOverlaps = []; 254 | block.leftOverlaps.push(uniqueId); 255 | } 256 | if (layoutEnd > block.endBase) { 257 | if (!block.rightOverlaps) block.rightOverlaps = []; 258 | block.rightOverlaps.push(uniqueId); 259 | } 260 | // update 261 | domClass.add(featDiv, "feature"); 262 | var className = this.config.style.className; 263 | domClass.add(featDiv, className); 264 | var seqLen = feature.get('seq_length'); 265 | // pi rnas 266 | if (seqLen > 25 && seqLen < 32 && this.config.isAnimal) 267 | domClass.add(featDiv, 'smrna-' + 'pi'); 268 | // other 269 | else if (seqLen < 21 || seqLen >= 25) 270 | domClass.add(featDiv, 'smrna-' + 'other'); 271 | // otherwise it's fine 272 | else 273 | domClass.add(featDiv, 'smrna-' + seqLen); 274 | 275 | 276 | // check multimapping 277 | if (feature.get('supplementary_alignment') || (typeof feature.get('xm') != 'undefined' && feature.get('xm') > 1) || (typeof feature.get('nh') != 'undefined' && feature.get('nh') > 1)) { 278 | if (!this.config.style.solidFill) 279 | domClass.add(featDiv, 'multimapped-read'); 280 | } 281 | 282 | // Since some browsers don't deal well with the situation where 283 | // the feature goes way, way offscreen, we truncate the feature 284 | // to exist betwen containerStart and containerEnd. 285 | // To make sure the truncated end of the feature never gets shown, 286 | // we'll destroy and re-create the feature (with updated truncated 287 | // boundaries) in the transfer method. 288 | var displayStart = Math.max(featureStart, containerStart); 289 | var displayEnd = Math.min(featureEnd, containerEnd); 290 | var blockWidth = block.endBase - block.startBase; 291 | var featwidth = Math.max(this.minFeatWidth, (100 * ((displayEnd - displayStart) / blockWidth))); 292 | featDiv.style.cssText = 293 | "left:" + (100 * (displayStart - block.startBase) / blockWidth) + "%;" + 294 | "top:" + top + "px;" + 295 | " width:" + featwidth + "%;" + 296 | (this.config.style.featureCss ? this.config.style.featureCss : ""); 297 | 298 | // Store the containerStart/End so we can resolve the truncation 299 | // when we are updating static elements 300 | featDiv._containerStart = containerStart; 301 | featDiv._containerEnd = containerEnd; 302 | 303 | // fill in the template parameters in the featDiv and also for the labelDiv (see below) 304 | var context = lang.mixin({ 305 | track: this, 306 | feature: feature, 307 | callbackArgs: [this, feature] 308 | }); 309 | if (featDiv.title) { 310 | featDiv.title = this.template(feature, this._evalConf(context, featDiv.title, "label")); 311 | } 312 | 313 | // render the popup menu if configured 314 | if (this.config.menuTemplate) { 315 | window.setTimeout(lang.hitch(this, '_connectMenus', featDiv), 50 + Math.random() * 150); 316 | } 317 | 318 | if (typeof this.config.hooks.modify == 'function') { 319 | this.config.hooks.modify(this, feature, featDiv); 320 | } 321 | 322 | return featDiv; 323 | }, 324 | 325 | addFeatureToBlock: function (feature, uniqueId, block, scale, 326 | containerStart, containerEnd) { 327 | var featDiv = this.renderFeature(feature, uniqueId, block, scale, 328 | containerStart, containerEnd); 329 | if (!featDiv) 330 | return null; 331 | 332 | block.domNode.appendChild(featDiv); 333 | if (this.config.style.centerChildrenVertically) 334 | this._centerChildrenVertically(featDiv); 335 | return featDiv; 336 | }, 337 | 338 | markBlockHeightOverflow: function (block, top) { 339 | if (block.heightOverflowedBottom && !(top)) 340 | return; 341 | else if (block.heightOverflowedTop && top) 342 | return; 343 | // don't draw if we turned off clip markers 344 | if (!this.config.style.clip_marker) 345 | return; 346 | if (top) 347 | block.heightOverflowedTop = true; 348 | else 349 | block.heightOverflowedBottom = true; 350 | 351 | var topHeight = (top ? 0 : this.height - 16); 352 | block.heightOverflowed = true; 353 | domClass.add(block.domNode, 'height_overflow'); 354 | domConstruct.create('div', { 355 | className: 'smrna_height_overflow_message' + (top ? '_top' : '_bottom'), 356 | innerHTML: 'Max height reached', 357 | style: { 358 | top: (topHeight) + 'px', 359 | height: '16px' 360 | } 361 | }, block.domNode); 362 | }, 363 | 364 | renderOrigin: function (block, originY) { 365 | var originColor = this.config.style.origin_color; 366 | if (typeof originColor == 'string' && !{ 367 | 'none': 1, 368 | 'off': 1, 369 | 'no': 1, 370 | 'zero': 1 371 | }[originColor]) { 372 | var origin = domConstruct.create('div', { 373 | style: { 374 | background: originColor, 375 | height: '1px', 376 | width: '100%', 377 | top: originY + 'px' 378 | }, 379 | className: 'feature' 380 | }, block.domNode); 381 | //block.domNode.addChild(origin); 382 | } 383 | }, 384 | 385 | _trackMenuOptions: function () { 386 | var track = this; 387 | var displayOptions = []; 388 | return all([this.inherited(arguments), this._alignmentsFilterTrackMenuOptions(), displayOptions]) 389 | .then(function (options) { 390 | var o = options.shift(); 391 | options.unshift({ 392 | type: 'dijit/MenuSeparator' 393 | }); 394 | return o.concat.apply(o, options); 395 | }); 396 | } 397 | }); 398 | }); 399 | -------------------------------------------------------------------------------- /test/data/seq/a59/b6d/00/Chr5-0.txt: -------------------------------------------------------------------------------- 1 | GCAAGTTTATGTTACAAATTTGTATTTGATTTCTCTTTGATTGGGGTACAGATCATTGGGAACATATCTGCAGTATCAGCGTCTCTTCTCATTGGAAAGGCAGGGCCTATGGTGCATACTGGTGCTTGTGTTGCATCTATACTTGGTCAGGGTGGCTCCAAAAGATATAGATTGACCTGGAGATGGCTCAGATTTTTCAAAAATGATAGAGACAGAAGAGATCTTGTAACTTGTGGGGCAGCTGCTGGTATCGCTGCTTCGTTTCGTGCTCCGGTTGGTGGTGTCCTGTTTGCGCTTGAGGAAATGTCATCTTGGTATGTTAAGTTATTCTCTTCAACTCAAAAGATATCTTTTTTAGTTCATTAGTTACCGGTCACTATATCTGTTCTTATTTAGTTCATTGTGAATGATTCATTGAAGCTAGAATGGGGTTCCGTTGTAGGTGGAGGAGTGCACTTTTATGGAGAATCTTCTTTTCGACAGCTGTTGTGGCAATAGTTCTCAGAGCTCTAATCGATGTGTGTTTAAGTGGAAAGTGTGGGTTATTTGGTAAAGGAGGCTTAATAATGTTTGATGTCTACTCAGAAAATGCGTCATATCATTTAGGGGATGTACTTCCTGTTCTTCTTCTTGGGGTTGTTGGTGGTATTTTAGGAAGCTTATACAACTTCTTACTGGATAAGGTTCTGCGAGCTTACAACTACATATATGAGTAAGCTTACAACTACAGACACATACACACAAGTAAATGTTTTCTTGATTTCTAACAGTTTTTTCTGTCCAGGAAAGGGGTTACTTGGAAAATCCTCCTCGCTTGTGCGATATCGATTTTCACGTCCTGCCTTCTTTTCGGATTACCATTTCTTGCATCATGCCAACCTTGTCCTGTCGATGCCTTAGAGGAGTGCCCTACAATTGGACGGTCTGGAAACTTTAAGAAATACCAATGCCCTCCTGGTCACTACAATGATCTAGCTAGCCTTATTTTCAACACAAATGATGATGCCATCAAAAACCTTTTCAGCAAAAACACTGACTTCGAGTTTCATTATTTTTCGGTTCTCGTATTTTTTGTCACCTGCTTCTTCCTCAGTATCTTTAGCTATGGCATTGTTGCTCCAGCAGGGCTCTTTGTGCCAGTTATTGTAACAGGAGCATCGTATGGACGGTTTGTAGGGATGCTGCTTGGTTCAAACTCAAATCTTAATCATGGTCTGTTTGCTGTGCTCGGTGCTGCATCCTTTCTTGGCGGAACAATGAGGATGACAGTTTCCACTTGTGTTATTCTCCTTGAGCTGACCAACAATCTGCTGCTACTACCTATGATGATGGTGGTCCTTCTGATTTCAAAAACAGTTGCTGATGGTTTCAATGCTAACATCTACAACCTCATCATGAAGTTAAAAGGATTTCCCTACCTCTACAGCCATGCAGAGCCTTACATGAGGCAGCTTCTAGTTGGTGATGTAGTCACCGGCCCACTTCAAGTCTTCAATGGCATTGAGAAAGTCGAGACTATTGTACACGTTCTCAAAACGACCAATCACAATGGCTTCCCCGTGGTTGATGGGCCACCACTAGCTGCAGCTCCTGTTCTACACGGTCTAATCCTCCGGGCTCATATTCTGACTCTGTTAAAGAAACGAGTATTCATGCCTAGTCCAGTAGCTTGTGACTCCAATACCCTTTCCCAATTCAAGGCAGAGGAGTTTGCTAAGAAGGGTTCTGGGAGGAGTGATAAGATAGAAGATGTGGAATTAAGCGAGGAAGAATTGAATATGTATTTGGATTTGCACCCATTCTCTAATGCCTCTCCGTACACTGTTGTGGAGACAATGTCACTTGCAAAGGCCCTTATTCTCTTCCGTGAGGTTGGCATAAGGCACTTACTGGTTATACCAAAAACCTCCAATGTAAGTGATTTTGGTTTCTTCTTTCTCCCTGGTCCTTATTAGATTATGGTAGGCACTAGTACGTGTGATACTTGATACCTATAGATGAATAATAAGTAAAATGGTGAACACAGTAGAGTCTCTTGAGTTTTGTATGTTTGTTAAGGGAATCAATAACAAAACTCGAAATCTCGAACCACCAATTAGTTCTCTATATATCTGGTAGCTCTTTGGTTTCTTGGTTCATCAGTTATCGAATATTAAATTCGTTGATTTGCATTGCAGAGACCTCCAGTGGTAGGTATATTGACACGGCATGACTTCATGCCGGAACATATACTAGGCCTGCATCCCTCCGTTTCTCGGAGCAAGTGGAAAAGGCTTCGGATTCGGCTGCCTTTCTTCTCATGAAGTATTAAGCTGCCTACCAAGTTTCAGGTATGACAGTTCAGATAAACTCTGTACAGTATATTAAAAGCAGCCTTGTGGTGCTATGTCGAACTCTTAGATACAGAAAGATGTAGAGAGATTTATAAATGTTGTATTGCTCTTATTGCATCCGCTACAGCTTTTGTTGGTTCTTTTTTATTTGTTGTATATAGGTTCTTCTATCTTTCGACCTTCTTCAATTTCTCGGTCCGAGGACTAAATACAAATTTAGACTCCCTTAATACAATTTGCGTAACGCGTAGGGCCACAAACATACTTTTAGGAAAACCTGCAAGATCTCAACGAACATGAATTAGCTCCTACCATACAAAACTGAAACAGAATCATAGAACATTTTAGGACAGCATACACGAATATAACTGGTGTATAATATAGGCATAAGATGATAAAACTAAATGAATAGTATTAGTTCTCTACATTTTTACGCCATTCTCTATATACACACTGATTATAAGAAGTGAGTTGGCTGCTTTAATGCTTTTAAACACTAAAAGTTAGATTTACTTTTTTTTGCTCTTTGTTTTTGATAGAAATATATAATGAGAAGTTAGATTTACTTTATTTTATTATAATCTACTCATATTCTACCAATTTTACTGAAACAAAATATTTTCCAACCAAAAAAAGTTGAAAATAACATCTGAGCTGCTTTCTCAATAAACAACCAAGATTTACAGAAGAATCAATTATGGATTTGCTATTTTTTGGAATGACATTTGTGGATTTTGTCCTTTTATGAATAGTTTGTGGATTTGCCCTTTTTCAGGCTACAAAAATATGATTTAACATGCGTTTTATTCGTTATGTTTGGGTTTAGTCGGTTGTGGTTGTTCTTAGGCTTCAGTATTTTGTATAAATTACGTATTTTTATCAAAAGAAATCATAAATACGTATATTTTTAAATATTAGAAAATAGTATATCCGTAAGATTTTAGTAAAAATGGTAATTTTAAAAGATTTATTTGAAAAATAGCAAAATCAACAATAATCCCTTTACAGAATGGAAAAAGTTTAATTCCCTGCCAGTATGTGTTTCCAAAACTTTATTTACAACCTCAAACATTCCTTAAAAAGATACGCCAATAGTAATTTTTCTGATTGGAACAATAGATAATACATAGATATTTCTTACCTAACACTAGTATACAATGAATTCTCTTCAGTATTACTCGTGGGGTTTAAATTTTCCAAATGAAGAAATCTTCACGTGAATCTATTCGGTCTTTTGGTCCCCATCATTTCGTTTTCTCATGTCAGTATAATGTATTTTTAAATGTTTGTGAAATAGTCAAGAATGATGTTGTAATTGATATATATACTAGTAGGTGAATATCTACAAAACACACGGATTTTTATTCTTATACTAGTTTCTTTTGCGACTAAGCCAATTTCCTTGTACCGTTATATTTTCTTGTTAAAGCTACATCTTTGAAATAGGGCTGATTATGCTTGCTATGTTTTATATGAAAAAAAACTCGTAATTATTTTTTGGGATGTTAAATATTGAGGAGGTGCATGCATTTGAGGAAAAGATCCAGCACAATTTAAACATCAACCTCTTTTGTTCAAAATGGTTTCTTGTATTATAACTACCCATAAAGATTTAACAAAATAACTCATTAGAATTTTGTTTTTTTATTCGCAGTTTAAAGTTGAGTTTTTTTTGTATGCAAAATCCTAATATGTTACTTTTTCCACGTTGTTCGATTTTGCAACCGTGTTTCGGATGCACGCTTTCTGTTTTGATGTCATCACATTTACTTTTTAAGTCTTAAAATCAATACTTTTAAACATACAAAAATGATCAAATTTAGTGTTCTCTTACATATGTAACCAAAAATGTGTCATCATTTATATGAGTGTGGAAGCAGAGCCGTACCAACGTTAACTCTTCAAATTTAATATTAAAATTAAAAATAAAATGCTCTAATTAAAAAAGAAATAACGTCAACAAAAATAAACATATCTTCATATAATTTTTTCTAAATAAACTATAAAAAAAAAAGTAAAAAAAAAATAAAAACAAACTAGCCAACAAAATATCTATATATACATTTTCACAACACTTTTATGAAATAAATCCTCAAATTATAACTTATTTACAAAGAATGTCATTAATATTAATTATTATCAATTAATTAAATCTCTAATTACTATTATTTCTTTATCTAATATATGTCTATCAATTCTAATTACTTAAAAAAAAAGAAAAATCTTAGGATATTATTAATAGTATACTTTATTAAAAGTAAATATTGTAGTTATTAAACGTTTACAATATTTATAATATGTGAAATTTATAAAAGTTAAATAACCATTTCAAAGAAAACTTTTAAATTGATTTGAATTATAATTTTTTTAATAAAAGTATTATTAAAACAAAAACAAATAAAAAAAATTTAATTTCACCGAACAGGATTAGATGATAGGACGAGTTTAAAAATATTATAATATATAAAATTTATAACAATTAAATAACCATTTGAAAGAAAACTTTTACATTGATTTGAATTATATATCTTTTAAATTAAAATATTATTAAAAAAAATAACAAAATAATGTTTAATTTCACTTAACGAGATTAGATGGTCGGACATGTTTGGATCGACAGTATTACAAGACGGTATACCACGGGCAAAATCCTAAATATAACAATCAAAATACAATTATATTATCTTAAACAATAAACAAAACAAACAATATGAACAAAACAAATGTAATTTAAATTTAAATTATTTAGTTATAATCTAAATTTTAATTTAATGAACTGTATGTTATTGCTCCTATATTTTTAAACAGTAAATATCTAACATAGTAATTGTATGTTATTGCTCCTATGACTTAATGAACTGTATGTTATTTCTAATTTCTTTTGGAATAGCTTCTCTTAGAACTTTATGTTCAAAAAAATATCATTACCAACAACATGTGAATGCTTTCCATGGTTAGAAAATCTTCAAGATTGGCATAAAAAGCCATCAAACTATCATCACTTGTTGATTGCAATTTTCTCAACAAAAAAAAAAAACTTGTTTGTATCTTTGAAATTGCTCAAATCTTAATTTAGTAGAAAGCTTGATCCATGATTTGAATAAAGTCGTCAATCCTGAAGCTGTCCTCGTATGATAATGTCACACTTCTCTCAACATTCTCTGATTTTCACCATAATGTAGTTTAGTTTTTTTTTAGGAAATAGATGATCGATCTCCAAAAATTCTGCAGTTTTTTAGCTTATGCTTTTGCTCTCTTAAAATCTTACTCTATATTTTTAAAAATAAGAAACCAACCTCGTGAGTTGAGAAATAGCTACATCAATGCTCATATCTTCTAAATGCAAATTTTTACTCACGATGTTAAAGTATATAAGATTATACCAAATAATCATTGAAACTAGAAACTCAAAACTTCCAATTCCATGTATTTTACTTGTTGCAAGACATTAAGTATCGCTCGACTCTTTCGGATCATCACAATTTTCAGCAATATATACTAACACATTCATGATTTTAAGAACTTGAAATCGTATTGTTTTAACACTTTCGACATATCCCTACTTCCAATATACATTTCAAAATCATATTGCCTTAAAAGCTTAAGTGGTATGTCATCCACGTAATATGTAAATATTTTTCACCGTTTATTTGAAGATGAAAAAAGGTAATAAGTATGTTGAATAATCTCCAAAAATAAGATTGCTTTTGAAGAAGTTGTTATATGTGACAACAACATGGTGTATATAAAAAAAAACACCCTAAATTTATCTCAAGAAACTGTTTTTGTACTCCCTTATGTTTTTTTTTTCATTATAAAACCATTATCATAACCTTTGTTCCCTCACATCCTTAATTTTTAAGTTAAAAACAGTCAAAACATCATGAAAGTCAGGGTAAAAAATTATCATCGGATATATCAACTTTCAAGAACATTAAAAAAAATATTTGATTGTTGAAGTTGAGTTAAACATCTACACACTAAGTGATGATAGTGATGTGTCCATGATAGCTGATATTTGGAATACAGTAGAAAATGACGGAGAAGTTCTTTGTACCTTGAGTTTTCTGAACACTAATAACTTTTACCTCATCCGCTTACCAAAAACAGTTAACTTGTTCTGAGTTCCTTATTAGTAAATTTATCCTATTTTTTATTTCTTTCTAATAACATAGAGTTAGCAAAACTTTTAAGCAAATATTAATTTTGTTCTGAATTCTTTATTAGTAAATTTATCATATTTTTTATTTCTTTCTAATAACATAGAGTTAGCAAATGTTTTAAGCAAATATTAATTTATTTCATCGGATGACACATCACTGCATAATATTGAATTTATTTTTCTAATTTTGCCTTTACAGCCATATTTGTTACAAGTTTTGGTTCACTATATTATTATACTTATATAATCTAGCAGAAAATATTTAAAACTAATCAATTTTGTTGCGATGTCACATTGATAACAGACTAGCAGTAAACGGAGATGACTCATGTCAATTTATATTTTAAATACCAAACAGCAATTATCAATTTAAACGCATTTATTGTAGTATTATAAATCTTTGTGTCTAAATGACGTCAAAAGATAAACCAAATTTGTATCAAACTTCTTTGTCCCACCTCACCAAAAAAAGAACACTTCTTTGTCCCGCAGTATACTGAAGCAAGTTTACTGCTATTTTCTAAAATAATTTAAATGGTTAGTGTTATAGGACTATTTAAATTAGCAAATATTAAAGAGAAAATTGTGTGGGGAGTCAAAAATATATATGAATTAAAATAACGTGTTTTTGATAAAAATCAATATGGTCCATATATTTAGGTCAATGAATATATTTCAAAACCAAAATCAGTCAATTAAATAACGTGTCATTCAAGAAAAAAATTGATACCTTTTTATTTTTAATTTACAGTTTAGAACATTCTAAATTATCATTCAGAAACTGTAGTTTTAGTAAAACTGTATCATGTTCTAGTATCAAGGAAGAGACGAGATTCAAATTCTGAGGGGAATGTCTGCGAAATAGAACTAGTCAATTTGCTATCATTTTTTATCTGTAGATATTATGTATATGATGAACTAGAACACATGATTAGACGTAAAAAAAAAAAAAGTACGTATCTAATCCCAAAAAATTTACATATCAAAAAATAATAATCCAATCGTCCCTTAGTAATTTAATTTATTACTTTTACCATTTAGCAAAAGAACTTTTCAATTTTTTTAATACGTTAAAAAAAGTATTATTTAAATTATCAGTTTATTATTTTTGTTGGTTTAAAGCATGCATAAACTTGAGATTTGCTAATTTAAATCCTTAATTGTATGTTGACTTTCAATTTAATCATAAATTTTCGTTGACTAAGCCAATTGAGGTACTAATTTTTTTTTCGACGTCATTAATTAACTTAAAAACGAGAGATTACTTCGAATTCTAAAAAGAATAGAAAATCCGAAAAAGAGGAGATAATCCAAAGAAAAATTGAAAAAAAATCTAAAATCAATTTTGGAGATCTAAAGTTTGTTCGTGGTTAGGAGAATTTTTAACGATGTGTTTTAATTAGCTTAGTAAACGAGAATTCGTAATTAAATTAAAAATTAACATAAAATTAAGGATTTCAATCACCAAATTAAAAGTTAAACCAATAAAAATGATAATTTGGTGATTTAAATACTATATTTCCCAAAAAATAACCCCAATACTAGTTAGAAAATATATAGCAGTGATGCAAACGTACGGCATGTAAAGCTTTCTACTAAAAATAATGTATAAAAATATCTAAATTTTAGTAAACGTGTCGAAAAAGAAAAAGGGTTCTCAAATTAAACGCATTATTTGTTAAGATTATAAATGCATACTATAAACGAATACAAGGAAGAAAAAAAATACAACAAGTCTTTGACAAAAAAATAATAATACAACAAGTTGCTTGGTGATGCAAAACTCATTTCTCCTCCCACTAATGATCGATGATAGAGACATAACAAAGAATCTTTCATGACTTTTCTTCTTTTTCTCCTCACTTCCAAAAATTCTCTCTTGTCTTCCTCTTAAGATGAAAGAATCATAAAAGGAACCCAAAGAAAAGCAAAAACATAACCATGGCTGCTCCAAGATCAAGAAGATGCTCTCTTTCTCTCTTAACTCTTTTCTCCATCACTCTTATTCTTATTTCTGTTTCACTCTTTGTCTCCACAAAACCAGCTAATAAGCCTTTCCTCGATTACAGAAACCAGTTTTCTATTTCCATCTCTATCTCTTCTCCTCTTGAACAAAACACAACAAACACTAGTTTTGTCTCAGCCTCTCCTCCTTTGTCCCCTCTTGGTCAGAGCAACACAACAAACACTATTCTTGCTTCTTCTTCTTCTTCTTCCTCTTTTTCTGATCACCAAAACCAAAATAAGTCTCCAAGTCCTACAAGTAAAAAAATTGTTATCAGGGTATGTAATCATTCTTTCTCTCTTTGTTTTTTTCTTTTTCAAGTCTCACAAATAAATAATTTTGTATTGATCAAACTCTTTTTCTTTCTAATACTTTTCTTTGTCAAAGTAAATAATAATCTTTACTTTTATTTTTACTATGATCAGAAAAGAAGTGGGTTAGACAAAATAGAATCAGATTTAGCAAAAGCAAGAGCAGCAATTAAGAAGGCAGCTTCTACACAAAATTATGTCAGCTCTCTCTATAAAAATCCAGCCGCCTTTCATCAGTTGAGTTTTGCAATTCTTCTTCTTCTTCTTTTTTTAACCATTTGAGGTAAAAAAAAAGATTTCTTCTTTTATTAAACAGTAATTTAATACTAGTACAGTATTTGACAGTTCCTAGATTTTTAGTCAAATATGATAGCGCTGACAATTTTTCACATGGATTTTGCTGTTTTTTCAAACTATTTGACATCGATTTCATCAAAGAATTCAGCATTTAATTACGGTTACAATAAAGACAAATTAAACAAATACGCAACGTACACATAGAGTTTTAACGGCTCCTGTGAGATGCCTCTTTCTAAGCAAAAGTTTACTCTTCTTTTTGTTTGTTTATTTTCATATCCGAGATTTTGCAGTACATAATATTGGAATTGAGCTTTTGAGGTTTCAATTGAACTAAAAAGAAGTTTTAATGTATTCAACTACTTTTCTACTAAAAGAGTTTGTTTATTCTCATGGCTTCTTTTTTATAACATAATTAGTTTAAAAGCTAAGATTAAAAAAGGTTTTAATCATTAACTATGTGTTGGAAAACAAAATTAAAGAAAGCTTTTGAACTTTTTGCTAATCATATTTAATTTATTTTTTTAATCAAAATTATCAAATTAGGATTTTTTTTAATAGTCCTTCTTCTCCTTTTTAATTGATTTTTTAGAAAACAAAACACACAGATTAAGAAAACATATTAAAACTGATTATAAATGTATTAATTTTTAGGATTTACATTTTACTATAATTTTAAATTAATGATATTTAATTATTTGTTTTGAAGTTTAAAATTTATCAATAAATAACTAATAAATAGTAAATAGTAAATCTAAAAAATCAATTGTTTGAAACAAATTGTTTTCTAAAAAATTAATTAATAAGGAACAGAGAGAATATACAAATAAAATATTGAGATGTTTCTTTTTTGTTTAAAGTATTGAGATGTTTGTTCATTAGAATAGAAGACTATTCGATTCTTTCAAAACAAGTAAACAAGTAGGAGATAGAATGAATATTTAAACTCCAATACGAACGTGGCGTAGCTCACCTCAGTGATATTATTACTTGCTTTGTAATAAATAAAACATTGATGTCATACTCGTGTATGCACAAAATATCAGGAGTCACACGGAGATGATGAATCGTTTTAAGGTGTGGACATACACAGAGGGAGAGGTCCCATTGTTCCATGACGGCCCTGTGAATGACATTTACGGCATAGAAGGACAATTCATGGACGAAATGTGCGTGGACGGACCGAAGAGTAGAAGCCGTTTTCGGGCAGATCGACCCGAGAATGCTCATGTTTTCTTCATACCATTTAGCGTCGCCAAGGTCATCCACTTCGTCTACAAGCCCATCACCTCTGTCGAAGGGTTTTCGCGGGCTCGCCTACACCGCCTTATAGAGGATTATGTTGATGTAGTTGCTACTAAGCATCCATATTGGAACCGAAGCCAAGGAGGCGACCATTTCATGGTATCATGCCATGACTGGGTACGTATACTAATTTTCTTTTTTTAATTGATGGCTAAGAGTTTGAATATTAAACATCTTTAATTAATATCGTAGTTATTTTTGGTTAATTTTTTATTTAATTTTTTGTCGACAATTTTATCAGATTAGCTTATATAAGCCAATGTCGGGAAATATTGTTTACATAAGTAAAAATATGCGGTTAATTATTTTTGGTTAGTAAACAAATTTGGCTTGAATTTTAAACCAAATTTTGTTTGGCTTGAATTTTAAATAAGCAAAGACCTCCTTGATATTACAAATTGCTAAAAACAAAAGAGATGTAGTGAGTTGATGAGGCTAACACTAAAATAGACTATAGTCTCTACGGGAGTGTAGTATATTAGTATATCACTTGATTTATCTTATTAAGAAAAAAGTATTATGTATTATATCGAATAATCTTGTTAGAAACATAACAAAACAAGAAACGATTTTTGAGATTTGAATTAGAGAAATAATTTACGTATTGAAATTGGCTTAAACCTATACAAGTTTTATATTATTGTTGTTGATTTTACGTAGTTGCTTGATTCTATTAATTTGATTAATATTATATCAAGAAAATTATCATCTAAATTCCTGATTTTTTTTTAATGAATATGATTTACATTTGTGTGTGTATAGGCACCAGACGTGATTGATGGGAATCCAAAGTTGTTTGAAAAATTCATTAGGGGACTTTGCAATGCTAACACCTCGGAAGGTTTCCGACCTAACGTGGACGTATCCATTCCGGAGATCTACCTTCCTAAAGGTAAATTGGGTCCGTCTTTTCTCGGGAAATCACCGCGAGTTCGATCTATACTCGCATTTTTCGCTGGAAGAAGTCACGGTGAAATCCGAAAAATCTTATTTCAACATTGGAAAGAAATGGACAATGAAGTCCAAGTCTATGATCGTCTTCCGCCAGGAAAAGACTATACAAAAACTATGGGAATGAGTAAGTTTTGTCTGTGTCCGAGTGGTTGGGAGGTCGCTAGCCCGAGGGAGGTCGAGGCGATATATGCTGGTTGTGTACCAGTGATCATATCGGATAATTATTCATTACCATTCAGTGATGTGCTGAATTGGGATTCCTTCTCCATACAAATCCCTGTTTCTAGGATAAAAGAGATCAAAACCATTCTACAAAGTGTCTCTCTCGTAAGATACTTGAAGATGTATAAGAGAGTTTTAGAAGTGAAGCAGCATTTCGTGTTGAATCGTCCAGCTAAACCCTACGATGTGATGCATATGATGCTTCATTCGATCTGGTTAAGACGACTTAATCTTAGGCTTGGTACATAGTATACAATTTTTTGTTATGTTGCAAATAAATATTAAGTGTCTAAGTTCATATGAGTTACTAGCTTTGTATTCTTTCCATAAATTTGCATAGTTCTCTCTTGTAAAAAAATATACAACAACAAACACAATATCAAAGATTTCCTTATTAATAAGAGAAACAAAGCATTTGTTATTTTTGTTAATTAGCATTTGTTATTACTGTTAATTAATACTTGTTGTTTCTTTTTTTCTTCTTAGTTATTGTAACTCCGACTCATTCGTCTTGATCTAGACATTTTTGTAGCTCTTTTGAAAGATTGATGATCATTCTTTACGTAAAGATATTCATAACATTTTCTTCCTACTGTAAGAAACCTACCATGTCTCTCTTATTTCTATTAGCATTTATGTGTGAGTAGTGATCATATATTTGGGTCTATGTGGTTGAATGTTGTTCTATTTTTGAGATTCTTCGTTAGTTCGTTCATAAATTCCATGATTAATCCTTTAATATTTAGTTAAATAGACACTAACATAGCTTGGGAGATACTTTAGCCATATGTTACTATGTTTAGTGTCTTGCCTACATATGAACAGTTTTTTTTTTTTTGAACTTCAAAAAACAAACCAAGTCTCTTATCATCTTCAGACCTCAAGTTGCAAAATAGCTCTAAAATCAAACGATTCATAGCCAAATGTCTGAGACACCTTTTCTTTTACAACGTTTAGATAATGATTGCAGCGGTTTTGGTATATAAACCAAAAGAAAAACGTTTAAGCTTCTTAAAGTGTTTCTCTGTTTACTTTCATATCCTTTTATCAATTTTCATTATTTCTTAGCAACCCGTTTCTGCACTTTCCTCAACTTACCAACTTTTACAGCTTCCTGTAAAATCCAAAATTAAAGTTATAACCAAATATGTGAAAATGGCTGGTCATAAATTAGAGGTTGCAGAAGAAGAAGTTTACTTGTATATTCCCTATGTCACGTAATGGTTGTTTATTTGCGCCTTTGTCGTCATGGCTAATTCCAGCAGGCTTCTTAACATCTATTGGTTCCATTGGTTTGTCGGGTTTCGCACTTTCGTCTCTGTTGCTACATTTGGAAGCTAAGCAGCCACAAGAGTCCCCACATCCACTTCCATTTGCCTTGCATTTGCAACTTTTGGTCTTGCACAAAGATTTTTTAGTGCAAGAGCAACACACTTCTGCTTTGCTCTGTTCCTTTTTGCAAAGTGTTTCCTCAGAAGTTTCCGGTTGAAATGGCTCCGAGTTTGATTCATCGTCGATATTCTTGCTGGTGATAGAGCGTTCCACTGGTTCGCTCTGATCACAACAATTGGAATCGAAAAATCAGACAACAAACCAGGAGAAAAATTGGCATTTGTTATTAAGGTATAAAATTAACCTGAACTTTATCAGTTTCACTGAATTGTGATTTGGTCATTTCCATCTGGCTGACAAGAGTACTCAGTTTGTTAAATTCCTCTTTGAGTTCCTTTAGTTCTGAGTCCATTGGAGTGTGGTTGATTTGGTTGTCACAAGACGCAGAACTAAATAAGAGAAGCAAAGATAACCAATCACCAAAGAGAACACAACTTGAGGCTACAACAAAAGTTTAGCTACGATCAAACTTACCATGAGCTTTGCTCTCCCTCAAATTCTGCCTTCAACAAACCTGCCTCTAAGCTGAACCTTTTGATCTCTTCAGCCATTCTGATAAAAATAGTAAAGAATACATAATTTCATGCTACTGAAGTAATAGAGTAGCAATAGCAAAAAGAAAGGGATATAAAATCCCACAGCTTTTCTTTTGAAAGCTTACTCTTTCATTTGGCGTTCGTAATCAGAATGAATTTTATTCAGTTTCATTAGTAGGCCTGATTCATTGCTAGACTCCTGCACAACCAGAATAAGAAACCATTTGGAGTTCCAAAATGTAGAAATCAATACAACACCACGTATATCATCCAATAACAAAAATCTGAATCTTTGTCACGAGTGTAACATATACTAAAGATCCTAAATAGAGGTTCCAAAAAATTAGTGCTGTTGAGAGCTTATGTAACACTTAACCAATTGCTTAAACTCTCGTTGAAAATAAGATGTTACATTGATGCTTAGGCTCAGGTATCCATACCTGAATCTCGGAGCTTGTTCCTTTTGATGGGCCTGGAAAATACAAAGAAGACACTTACACAATTTAGCAAAAGAAACAAGGAAAAGAAAGGAACGGATACCAGCTATCTGTTATGTTACCTTTCTTTTTGTTGGAAGAAATCTTTTTAGATTGAAGCAGCATTTTTAGACGCTTCAGGGCTGTCAAAGCTTGTGTATTCTTCAGCTGCAAAATCTGAGTAAAAGAATATAGACATTAACAAGTCACATGGAGTCAGTAGTAAACCACGGTTGCTGAAATATACATATAGCATAGTACAATCAGCAGAAAATATACCAGCTTCTGGCGATTGTTCAGAGCTGACAGGACATGTTTCTCAAACTCACTTTTCCTTAGCTCTTTTTTGAGCTGTTACAATAGAAGCACTATATAATTAAAAGCCTGAGGTATCATATATGAGGGAAAACATGATCAAACTAAGAGAGCACTGAACAAGGCAAGCACAATTGGCTAACAATCTCATCAAGAAAGAATGTATCCAAACTGATCTTGGAATACAATTCTCAAAATCAAACTACCATAACTAGAACCCCTGTTGTGTACTGTATATATATGGAAAACCATATGTGCAACAAACAATTTGAACAAAAAACATGGGGATTTTGAGAACGTTTATCAATCATACATAAGTATAAATCAAGTATGGCATGTAACCAGATTATCAACTATCATCTATGTCCATCAGAACTTGACTGCATTATGATGTAACCCGAAGTGGGAATCTACAACTTGATGATTTGACATTCACTCATAAACCAAAGAAAAAATGTATAGATACTAGACCTGCTACTCTCGTTACCTGAAGAACTTCCTTTTCTAGTGAAGCTTTCAATAGTCTGAACTGCATAGAGTCTAGCTTGATCTTGCAATGCAACTTAACCTGAAGAATATACACAACTCACAAAACTAAAAACCCAAAACAAACTGCTGCATTTTCCATTGATCATAAACATTATTTACAACAATATACTTCACCTTTTGCGCCTTCAATTTCTGAACTTCACCATCAAATTGCTTAACAGAACTCTCAGTTTTATACTTCTTTGTGGAGCACATAGACTTACTCCTTGAACTCATACCCTATACAAGTATCAAGGTCAAAAAAATATGCGTAGTATAGCATAAATGTCTCTTTTTAAAAATTGAAACCTGAGAAACAAAATAATCCACCTCCTCTTTGTTAGCAATAGACTTTTGAGAAAACTTTCTGCTTGACTGTAACGTACCAACCGATGAGCTTATCGAAACATCAGCCAATTTTGACCTTAGCTCTTCCACATCACTCTGCCGAAATCCGAAACAATCATTTCAACATTACACAATACACAATAAGTTCTATAGAATGATTCTATACATTTATATTAATGCGAATTGATCAATTTCACAGTTCTCTAAGATATTTTTCTGCAAATTGGAAACTGAAGCGACGAATATCATTCATAAATTGAGATCTTAAGCGAGATATTTTCGAGAGATTATCTTCCACAAGTACGAAATCGAAGCAAAAGAAGCGATTCTAAATTTGATAATCGGAGAAAAAATTCAAAATGAAAAATGGGGGGAAACCTTGAGAGCTTCGTTCACGGACTCCAGATCCAGAATCTTCTTCTCGTAGAGTTTCTCAGCATCGTCTCCGAGAGATGAATCCTTTGATCGGAGATTTGGCTTCTTCGTCATCTTCGGCGAAGAGTTTGTACTTTCTCGATGCGAGTGTGAGAGACAACAACGCTCCTTCTTCTCTCTCTCTTTCCTAATTGATGAAAAGGTGCGGAGAGAAGTATTTGAATTTACAATTAGTTTTAGTTTCATTATGGGCCTAAAATAACGAAAGCCCATCTTATTTTTTCAACCTAAGGCCCACAACCAAAATAATTTTATCATTTTTAAACAAAGACCCAACAGGAAAGAAGGTTTAAGGTGTTGTTCCTTTATGGACATGTCCTAGGGTTCCACACTTTTGGGAGGGTATTCAATGATTGAATTAAAAGAATTTAGTTTAACAGAATTTAGTTGGATTCTAAAAACACGTCGAGATAAGTATGAGAATTTGTTTTTTTTTGTTTGTTTGTATTGGTTTTGTTAAAAAGGCATAAAAAATAAGAATATGTTTTGGATAAGACTAATAAAATAATACTGTTGATTTTTTTTTTTTTTTTTTTAAATTATATTAAGACTCCTGTGACATTTTGGAGATGAGACTTGCTTGTAACGCCATTGTTTTCATCGTAAGTGTTGTTCTCTTCGGATGTCACGTAGAATCTCCATGAGATACACAGTTTTCATCAGCTATGTGAGCAAAAAGAGAAAAGGAAATATTTGTTTTGTGTCTTGATGGGAGAAGAACTAATTAGAGTTTTAGAGTAATATTGAACTCTGTCATCCAAAGGTGTAACAACAAAACATCTTTCGCCCGGCAAGCATCATCTGAACAGGGTTTTTTATGAGTCCGGCTTCACCCGATGATGTCTTTGAGGTACCATAAGTTCTTGATTATGTTTTTAAGTCCCTCCTTCTTCTCTGGTCATTGACTGTCTGACTATAATTAGTTAGAGAAGTCATATCTGCAATATAAAATGTCATGTTTATGATTGAGTATAAGAACTGGAATCGCACCATCAATGTCTCAAACATACTGGCATCAAATTTTAATCTTTAAGTACTTTTTCGGGCCTTTCCGTGATCTGTGCTATATTACGGACCCAAAATTACTTGTTCAAACATTATTTTCAAATAATTTTCATGTATCAAAGCTCGTTAAGACTAGATGGGGTATCTCTACATAGCGGGTGGGACCCATGGCGAATGGGTGATAAAGTCAAAATACGATAGCAGAATTGTTTCTTCACATTTTTTAGTGTACTTGTTATTGACTAATTTACATATTTACATTTACATTATTTAAAAAATCAGTAACTAAATAACACTATAATTTAAACTACTCTTTGAAATATATAAGGGAATAACGTAAGAAGTATATGGAATGTCAAACAAAATTATTTCTAATTTACTACTAATAAAAAAAACATTCGAAACTTCTCAAGCTATACTCATCATCACTCCAAAAATCATTTTAGAGGATGCCACATCAGATCTGTTTTAATACTTTCTCCAAATGTCATGTCAGCAAGTTATTTTTGTTTTAGAAAATAAAAGAAAAAATATTTTAATAAATATTGTCAGAAAATCAGTGTTAATATTTTTTACTCCAAAAACAAAAAACAAAACAATACTTAAAATAAAATATTGATCTTTCTTGGATTCCAATTAAAATGGTTTAAACTAACAAAAAAATAGTTGAAAAGAAACTTAATATTTTATAATTTATTTCTGAGATGACAAACTCCAATTTTTTAATGACAGTTTTTATAAATTTTAGGTAATATAATTCATTAGTTGACAAAAAGGTAATATAATTCATTATTTTAATTAAAAATTAAATTTAGGTAAATTACAATTAACTAATTTTGAGAACATTAAGAATCTTTACACATAATAAGCACTATAAACTCTTTTAATTATATAAAGGATTAACATATATGCATAATTGAACAATATGCTAGCAATCTAATAATAAAATTAGCTTCTACAAATTAATTTTACAGATTATCCACCCATTAAGTTTAATTCGTTTACTATACATAATTCCAACTAATGAACCAAACTCAACAAAAACCAAAATCCAATAATTATTCAAAACAAAACCTCAATGAAAATGAATGAATAAATAAAAAAATAATGAAAACAAACCCAAAGTTTGTTTTGGGTTAAGAAAAACTATTTCTATTACAATCATCTTTAATAAAATAAAAATAAAACAAAGAAAAGGTACTTCAATTTGATTTTAAATATCATAAATAGATAGAATGTAAAAATATAAGCAATATAAACTAATTTTATATTTATAGTTAGGAAATTCTAAAAAATAATAAGAACTAAAAAACAATAAAAACATAAATTAAAATTTAATATAAACCGGGTGTATCCCGGTATTAACTCTAGTCATTAGAAAAATCATCATTAAGCAATCCCAAATGCGTTTGATCCACCATCAATGTCGCTTGGATCAAATCAAAACTGTGATGATTGACATATATAGTTAATACTTTTGAAACAATTTTCTCTGCCACACAATAAGAAAGGCGCATATGTATATAAAAAAGGGAAAATTTCTGAAAAAAATCCAATGCCAAAAAACTACCTAAACTTTTTTTGTTGTCAGAAAATACACAAATTAATCTGGGTTGGAAATAAAAAAACACGACCTATTATTTTTTCCGACTACCTCCTTTCGCTGTAACGGGCTGTTAACAACGTTAACCTAATTGTCAAACGCTGTTAATTTTACTTACAGAAAATTCCTGAAAAACACGATTTATTTAATATTTGCCAAAACAATACTAGAACTTTTTTTCGTTGCTAGAAATATATACATATTAGTTTAAAATTGAAATAAAAGCATGACTTAGTTTTTTTGTTCCAATTTCTCCCACTTTGTTGTAATGGTTATCAATAGGGTCAACCAAATAAAAATATAATTATTTTCTCATTTTCTTTGCACGTGATAAATAAGAATAGCTATAAAATCGATATTATCCCCTAATAAACCCATAATCGATTGTGGACATATCTTGAACCCTAGTTTTAACATACCACATCTATCTATTTAAGAAGCTAACCACAATAAATTGAAGAAATTAATAAGAAGAACCTTTAGTAACAACGGAGGTATTTTTTAATTTATTGTTGTTTAATTTATATGAAAGATGTTGAAAAAAACATTAGCAATTTAGGAAAAAACTTACCCATCAATAACATGATTTAGGTTGAAATTATTCAAGAACTTAAGGTTTCAAAGGATTTTTTTAATAGTCAAGTTTTTTAAGAATATTTTGTAAATAAAATTAACAACATTTGACTATTTGGTTAGGGAAATCGAAAAAATAAAAATAGATCGTGTTTTCTATTTCCAAGTTAAGTTAGTTTGGGTATTTTTCTGACAACAAAAATCTTCATGTATTGTTTTTGGCAAATATTAATTGTGTGATTGCTTCGTCTGTAACTATAGTTTTTTTGTTGTAGAATTTTTGCTGTATAAATGATGACTGTAGCTGTAGATTTTATTGCTGTATAAATTAGGTCGTGTTATGAATAAAGATGGATGCCCATTATAAGGCTAATCATCTAAGCCCATCATCTAGATGTTTCTAGGGTTTTACCCTTTCCTTGTACTCCTATATAAAGAACCTTTTTCTCAATGGAATACTACACTCATTTTCTTTTATATCTTTCTCTAGTTACAACACGTTATCAGCACGCTCTAAAAGGTAGATATAGAGATTCTTACATTTTTTTAAGAACAATGTTTACTTATCGACTCATGGTTCATAGTACTTATTTTATATTATTGAAACAAAACAATATGAGCCGATCGATGATTATAGTATAGATCGGTAAAAGCATGTTTTCAATGATTCAATAAAGAAGAAAATCATGCTTATCATTTGTTTCTCTAATTACTATTGCATGATTCAATGATTCTACAAAGAAAATCGTTAAAGAAGAGAATCATGCTTGTTAGTTGTTAATTTTTGTGATTTACTATTATAATATTGAATATATAAATTACCAATTTTATAATTATATAACTAATTTTGTAACTATTCACAGCCTGGTGGTGGGTGATGCAAGCATGTATTAATGTTTTAGCATTCCAGTTTCGAATAGTTGCATCTATATTCAATATCGTTTTGTAAATATTATATTGTCTAAAATCCATTTATGATTGATACGATATCCCTTATTTAACTCCTTTGATTAAAATGTTATACATATCTTATCACCTTTAGATATTGACTTTTCCATATTAAATATTTGATTTCCATATATTTGATTGTGTTATTATTATTTTTACTAAAAGTGTTGCAAGATAATTTTCTTTTTATAAGATACTTGTAATATTTTATTTTTCTAAATCTTTGTGGCATCTAAAAAAAACGAAAAAAAA -------------------------------------------------------------------------------- /test/data/seq/a59/b6d/00/Chr5-1.txt: -------------------------------------------------------------------------------- 1 | AACGATAGATAATCTTATTTTGTGAATTTTCGTTACAAATAATATCTTATTGTTATAAAATATCTGTAATATTTTATTTGTTAATATATTTTGAAAATTAACATATATTCTTGAAATTTATATGATATGTAATCATTTATTTTTAATATTTCAGTGAATCATGTCAAAAACTCATGAGCTTTGAATTTGGAGCTCTTGATATCACGGGAGATAACTACTTGGCATGGGCACTAGATGCTAAAATTCATCTAGATTCAAAGGATCTCCTTGATACTATTAAAGATGGTAATCAAACTCCAAGCAAAGATAAATCAAAAGCTATGATTTTTTTGCGACACCATCTCCACGAGGATCTCAAGAATGAGTACCTCAATGTGAAAGATCCACAGATCCTTTGGAACGATCTAAAGGATAGGTATGATCATCAAAAGACAGTGATCTTACCTAAGGCCCGATATGATTGGACTCATCTGAGACTCCAGGACTATAAGTCTGTAAGTGAGTACAACTCAGCTTTGTTCAAAATAACATCCAAATTGGAGTTATGTGGAGAGAAAATCACGGATGCAGATAAGTTGGAGAAAACATTCTCTACTTTTCATGCTAAAAATATTGTCCTCCAGACACAGTACCGTGAAAAGAGATTCGTAAAGTATTCCCAACTTATTTCTTGTCTCTTTGTAGGTGAGAAAAACAATGAGTTGCTTTTGAAAAACCATGGACTACGCCCATCAGGTTCTGCTCCATTCCCTGAAGCGAATGTGACATCCTATGGTCAAGAAAGTGGTTACAACCATGGTTGTGGCCGTGGTCATGGTCGTGGTCGTGGTCGCGGTCGTGGTCGTGGGCGTGGATACACTGGAGGACGAGGCAATGGAGTTCACTTTAAGAACTCAAACTCTCACAAGAAGTGGGAAAACAAAGATGGTAACAAACAAGTGAAAATACCGTATGCGAATATCTGTTACCGTTGTGGAGCGAAAGATCACTGGTGTTGGTGTCGGATCCCGCACCATGGACTTGGGACCGGTCAAAGATTGCCACATAAGCAGGAGAGGCCCAAAAGAAGAGAAGCCCATAGGATACCCCGAGTTGATAGCACAAGCGAGGTTTGACCTGCGAAGTGGATACGGAATCAAGGTCAAAGTTACCCGGAGTGAAGTGTCGAATGGGCCGACAGTTGAAGCCCAAGAAGTTCGGAGTCAATTCAAATTCGACGTTTGAATAGATAATTCAAAGACTGAAACGGATATATTTAAGATAGAATAATTTTGTGTAAATGGGAATTTAATGTATTCTTTGGGTATAAATTATGGGTCAAAGACCATGTAAAGGGACACGCATTTTTGGGCAAACACACTATAGGCATTTTCCTACAAAGCTCATAGTTTTCTCGATAGTCATCAATCTATTTTCTAGTACATTTGTCCTCAAGAATAATCCTTCTCACTAAATAAATAAATACTTGAGTGTGTGAATCCGACATCCATATTTTGGCGCCGTCTGTGGGGACGGAGGATTCTTGAGTCGTCAGATTTTTTCTATATATTACATTTCCGAAGTGAGCCGTAATGTCTGGAGAATATGCTACCAAGGCTTCATTAGCCGAAACCCTCAAGACCATGCAACAAACTATGGCCGATATGGCGCAGAAGTTTTCGAATGTGAAAAAAACCGTCGAAACACTGCAAACAACCCATGTATCACTCAGCCAAAATGTTAGTACTATTCAGTCTCGTGTCCGTTCTTTGAATGCAGGCAATTCTACTAGAGTTCGGAGAACTATCTTCGGATCACCAAACTCCCTTCTGCGAAATGCAACGAGTGATCAAACGACCCCAGATGGTACAAACGCGGATAACCAACCGGAAGATGGAGAAACGCACCTCGAAGACGACAACCAGTTCGTCGATCAACACGAGCAATAAAACTTCGACCAGTTCGAAACCATGAAAGAAGTAAGCCGGGAATTGAAAGAAATGAGGTCAAAATTCTATCAAGCAACATGCTCGGAGCCGGATATCAACCGGGTCATCTAAGAAGCTAGGCGAACACCTTTCACCCCGCAAATTGCAAGCTTGAGAATCAGGGATTCTCGAAGACTCAACTTAGAACCGTACAACGGTTTGGAAGACCCGAAAGGCTATCTCGCCGCTTTTCTAATAGCCGCTGGGCGAGTTGATTTGAACGAAGCCGATGAAGACGCAGGATACTGCAAGCTTTTCTGTGAAAATCTGTGTGGACAAGCCCTGATGTGGTTCACTCAGTTGGAACCAGGATCGATCTACAACTTCAACGAACTATCGACAGTATTTTAAAACAATACTCAATTCTTCTGGATAAGAGCATTTTGGATACCGATCTCTGGAATTTATCTCAAGGGCCGAATGAGACACTTCGGGCTTTCATCGCTAAATTTAAGAACGTACTTTCAACGCTCCCGAGGATCTCACAACAGTCGGCTCTAGCGGCTTTGCGAAAAGGATTATGGCATGATTCGAGATTCAAAGAAGATTTGATACTTCACAAACCTGATACTATTCAAGATGCATTATTCTGAGCGAATAATTGGATGGAAGTCGAAGATGAAAAAGAAAGTTTCGCAAAGAGAAATAAGCAAGCGAAACCAGCAGCTACTTTTTCACCCAAGAAGTTCGAACCTCGGGAGAATCAAGGACCAAGGAAGTTTGGTTCACAACCATTCAATAATAACGTTGAAAAGTAATTTCAGGGGAAAGGAAGGTCAAATACCTGGGTTCGGGATGAGAGCTTGTATTGTGATATACAAAAAGTCACCGGGCATCTGACCAAAGACTGCAGTGTTTTTAAAAGGCATCTCGCAGAATTATGGGCAAGCGGAGATCTTTCAAAATTAAATATGGAGAACTTCGTCAAGCAATATCATGAGTCGAGAGATAACTCAGAAGCTCAAAACTCTAAGAGACCAAGACCGGCTGGCGAAGAAGAACCAAGAAGTTCAAAAGATAAAATCAACGTAATTCTTGGAGGATCTAAACTTTGCCGTGATTCCATCAGCGCAATCAAAAAGCATAGACGGAATGTTCTTCTAAAGTCAAGTTTAAGTGAAGAAGTAGATTTTCAAGGCGCTTCAATATCATTCAAGGAAAAGGAGACACAGCACCTCGAAAGACCTCACGATGACGCTCTAGTAATTACGTTGGATGTGGCTAACTTCGAGGTTTCAAGAATCCTCGTCGATACCGGCAGCTCGGTAGATCTAATTTTTCTTAGCACTTTGGAAAGGATGGGGATAAGCAGGGCCGATGTGGTAGGACCGCCATCTCCCTTAGTAGCTTTTACAAGTGAGTCAGCAATGTCTCTCGGAACAATCAAACTACCAGTTTTGGCGGGAAAGATGTCGAAGATTGTAGATTTTGTCGTTTTTGATAAACCAGCAGCTTATAACATCATCCTCAGAACTTCGTGGATCTACCTAATGAAAGCTGTCCCCTCTACGGATCATCAATGCCTCAAATTCCCAACTCCAAACGGAGTGGAAACAATTCGGGGAGACCAAGAAGCTTCGAGAACTTGTTATTTAGCTAGCCACCGATTGAAAATCCAATAGCAATTAACGAAGCCCGCAAAGAAAGAAGTAGTCCCGAGCTTTCCTAGCGGGCAAAAGGTGGACGATGTCGTGGTCTGAGTAATTCTAGAAGCAGACAAACCGGATCAGAAAGTTTGGATTGGAGCTACTTTGTCAGGCGAAATAAAGGGAGCTTTAATCGAGCTGTTAAAAAGAAACAAGAAATCATTTGCTTGGTCAGCAGCAGATATGCCCGGCATAGATTCGAATATAATTTGTCACGAGTTGAATGTGGACCCGAGCTTCAAACCAATAAAGCAGAAAAGAAGAAAATTCGGAGTGGAGGGAGCAAAAGCAGTAAACGACAAAGTGGTTAAACTCTTAAAAATAGGATCTATAAGGGAGGTGCAAAACCCGGATTGGGTGGCAAACACCGTTGTGGTCAAAAAGAAGAATGGAAAGGATAGGGTGTGCATCGACTTCACAGATCTCAACAAAGCTTGTCTAAAAGATAGTTTCTCACTCCCATATATAGATCGTCTCGTGGAATCAACTTGCCGGAAACGAATTGCTATCCTTTATGGATGCCTTTTCGGGATACAACCAAATCATGATGAATCCAGAAGATCAAGAGAAAACTTTATTTATCACGGATAGGGGCATCTATTGTTACAAAGTTATGCCATTCTGGTTGAAGAACGCGGGAGCGACCTATCAACGGCTGTTTAACAAGATGTTCAACGAGCATCTCGGGAAAACAATGGAAGTCTACATCGATGATATGCTAGTCAAATCATTGAAAAAGGAAGACCATGTTAAGCATCTAGAAGAGTGTTTCGCAATCCTTAACCAATATCAAATGAAGCTGAACCCAGCAAAATGTACATTTGGAGTCCCGTCCGGGGAATTTCTCGGTTATATTGTCACAAAGAGAGGAATTGAGGCAAATCCAAACCAAATTAACGCTTTTCTCAACATGCCATCTCCAAGAAATTTCAAGGAAGTATAACGGTTAACCAGTCGGATTGCAGCATTCGACAAAGAGTTTCTTTAGGATGAGAAGTGTGAAGAAGCATTCGGACAGCTTAAAGCGTATCTGTCCACTCCACCTGTATTATCCAAACCTGAGGCGGATGAGAAGCTCTATCTATACGTTTCGGTCTCAGGCCATGCGGTTAGTGGAGTCTTAATCTGGGAAGATTGGGGAGAGCAAAAACCAATTTACTACATAAGCAAATCCATGACAGATCCGGAGACCAGGTATACGATGATGGAAAAGCTTGCACTTGCAGTGGTAACCTCAGCTCGGAAGCTTCGTCCGTATTTTCAATCCCACCCAATCGAAGTGTTATCAAATTAACCGCTTCGAACAATTCTCCATAGCCCAAACCAATCCGGAAGATTGGCGAAGTGGGCAGTGGAGTTAAGTGAGTATGATATAGAGTACAAGAGCCGAGTCGCGATGAAGGCTCAAGTTCTTGCTGATTTTTTAAAAGAATTACCGGTACTTGGAGGACAGGAGCAGCCGGAAAATCAGTCTTGGAAGTTACATGTTGCTGGATCATCATCAAAAAATGGATCCGGGGTGGGAATCAAGTTAGAATCTCCCACTTCGGAAATCCTTGAGCAGTCATTCCGATTATTATTCACCGCATCTAACAATGAAGCAGAGTATGAAGCGTTAATTGCCGGACTCAGGTTGGCACAAGGAGTTGGAGGCGATGAAGTGGTCGCATATTGTGATTCGCAGCTGGTTGTTAACCAGTTCAATGGTGACTATGAAGCCAAAGATTCACGAATGAAGGCATATCTTGAGGTGGTCAAAGACTTGGCTAAAAATTTTAAGAAGTTCGAACTCATTCGCATACCACGAGGAGAAAACATAACTGCGGACGCACTTGCGGCTCTAGCGTCAACATCAGATCCCGAAGTCAAGAGAATCATTCCGGTATAATGTATTTCAGAAAGGACCATTAAGGAAGAAAAGGAAACACTCGTCGTTACAAGGTCTCGAGCCGCAGCCCAAGATCGCGGTGAACCTGCGATCGAAGTACCACCTGTCAAAAGACGAAAGTCAAAAGGAGCAACCGTACCTAAGCCTGTTGTGCAAGAAGATAATAGGCTCGAAGAAAATGTTGAACCAGTAACAGAACTCGCCCCGAAAAACACTATCGAAGCAGAGGCTGAACCATGGGTTGACGAAGACATCCTTCGAGCCGAATGAACATCCCGAACAGGAAGCTCAAATATTTCACGAAATCGACCAAATTCCGGCTAAAGATTGGGGGCTGATTGGAGGGAGCCAATAAAACATTACATTGTTACAGAGAGCTCCCAAAGAATAGATGGCAGGCTAGGAAAATGAGAATCGTTAGCGCGAAATTTTATCTATCGAAGGATTCTTTGTATAGACGAGGTGTAAGCGATCCCTATTTACTTTACATCTTTGGGCCCGAAGTTGAGATCGTTATGAGCGAAGTGCACGAAGGTTTGTGTGGAAGTCATTCCTCGGGTAGGGCTATGGCTTTCAAGATTAAGAGGATGGGATACTATTGGCCTACTATGATCACGGACTGTGTTAAGTATGCTCAGCGATGCAAACGTTGCCAACTCCACGCACCTCTCATCCATCAACCTTTAGAGTTATTTTCTTCGATCTCTGCCCCATACCCGTTCATGTGATGGTCGATGGATATCATTGGACCATTGCACAGGTCAACTCGAGGTGTACAGTATCTCTTGGTCCTAAATGATTACTTTTCGAAGTGGATTGAAGCTGAAGCATATGTAAACATCGAAGATTCGGCGGTAAAAACTTTCATTTGGAAGAATATCATATGTAGGCACGGCGTCCCATACGAGATAGTTACGGACAACAGACCACAATTTATCTCACATGAATTCGAAGCTTTTTGCTCGGATTGGGGGATTAAAGTTAGTTATTCCACAACGCGATATCCACAAGGGAACGGTCAGGTCGAGGGTGCGAACAAGACAATTCTAAGCAATCTTAAGAAACGATTGAGTCATTTGAAAGGAGGCTCGTATGACGAACTTCAGCCGGTTCTATGGGCATATCGCACAACTCCTAGGCGCTCGACCGGAGAAACCCCGTTCTCATTGGTGTACGGAATGGAGGCAGTTGTCCCAACTGAGCTTAATGTACCAGGACTTCGTCGAACAGAAGCTCCTTTAAACGAAGAAGAGAATTCTGCGATGCTGGACGATTCGCTAGATACCATCAACAAGAGGCAAGATTGATCCAAATTCAAAATTATCAATAAGCAGCAGCTCGGTATTACAATTCAAAAATCAAAAGCAGACCTTTCTTTGTGGGTGATTATGTTTTGAAACGTGTGTTCGATAACAAGAAAGAAGAAGGAGCAGGCAAACTTGGCATTAATTGGGAAGGTCCTTACATTGTTACCGAGGTGGTCCGGAATGGTGTTTATAGATTGAAAGACTTGGAAGACAGACCAGTCCAACGTCCTTGGAACGTGGTGAACTTGAAGAAATTTTATGTTTAAAAATGATACGCATTTTTGTACATGAACTACGGTGTGGCTTGATCCCGAAATGGGTACGTAGGCAGCTCGAAAACAAGTTCAGCTATTAATAAAATTTGTTTTATTCATTTTGAAGAATAGTTGATTATACGAACGAATCAAGGAAAGGAGTTCGACTATGCGAACGTACAAAGCAGGAAGCAAGGTTACATTTATTCAAAGGGAAAATGAGGAAAAGATGCCAAAATCTTGGACACACTTCAGGTTAGGAAATCCTTCTCGTCTTGCACAACACTTCGACCCCTTGGTTGGCGAGATCGAGAATGGGCATCATACAATCCGGGATACGTGCGAATTCAGCGATTCCGAGTTCGATCCAGTCTCTGTGGTGAGAGTTGAGGGTGTGTAACTCCCTTGATATCACGGTGATTCTCCGTAGCATCTGATTGATCTTCTTTCGAAGTTTCTTCTTTTCCGTTGAACGTTTTTGGTGTTGAGCCGCGAGAGCTTTGATGAAGGCCATCGCAATTTCTTGATCTATGCTTGAAAGATCTTTGATTAGTGCACACAGAACTTGGATCTGGGATCTAAAGTTGCGAAGTGGGGAGCGTCCCCTATCCGGCACATTCGGAATGTCCTCATCGATCATTCTGACCCTGGAAAAGTCTGGCATGGACTCCGAACATCGAAGGTTAAAAGCCATAACTGCACCAAAAAAGATATTATTATAAGAGGGACTCTTAACTTTCAAAGATGTGATTCCATTCAAGGCCGGAGTGATTCGCGGCAGCATTCACGTCGTCCTACTCGCCCTGCATTCAAAGAGTATCTCCGAGACGAATATTTAAAAATCAAGGAAATTTGGAAAGTCTCCTTAAATAAAAACGGGCCAAAGCCCAAAAGAAAAGTCCATACAAAAATAAAAAAAAAGGGTTTCAAGTTTCGGGGAACATTTAAGAAAGGGGTTTAGGAACAGGTTCCTTCATCGCCGGTTCGGGGTTCGAGATGGATGCCTCGTTCTTAACATCCACATCGGGCTCGTTCTTCACACGCTTCCAAGGGTTGCTGTCTTCTTCTTCATCGTCACCCTCTTCGCTGTCAGACGGGATCACTTGGATCAGAGCGTTTACGAGACCGGGGACTTGACCTCGAGCACGGAGGTACATCCGAAGCATGTGCGGGATCTTCGCCACACAGTCGAAGTTCCTCCACTCCCATTGAAAGGGATCGCTCTCCATAGCCCTTACCTTCCTCTCGATGCGGGCAATTCGGGCCTTGAGCGTTTGCCTCTTGAGGCCCAACCGTTGCCTCTCATCGCATAAGCGGCGGTGTTTGTTGACGACCTAGAACAAAGTTCTTTAGTTTGAGTGGGAGTCTTTCCGATAAGAAAGAGGGTAAAAGACTTACCTTGTCTATAAAATCGTACGCCTCTTTCTTGTCATTCGAAGGAAAGTGAAAGCAAGCATGAGGAAAGAGAACGCCGGCGGGCTCAAAGTCATCGCCGGACAGAAACAATGGACTTCTGGGGTCGAGATGGCATACGGTGGAGGCTCTTTCGTTTTCCATTCTTGAAGTGTTTACCAAATAAATTTCTGAGATCATATTTTGAGGCACTAATGACAGTTTATGCTCTTATTTATAGAGGGTTAGGGTTTTTACTCGAAACCACTAAATTAATAATTGTGGCGTGTCTGAATGGGTTAAACCGTTTTTGGGAATCGAGGAAAAGGCAATTATTGCCTTAGAGGCTTGAAGCTTTTCCTATTTTCCAAGGAAGAAAATGGCAACCATCGCATTTAAGACAAACGGTTCATTAAATAAAAGAAAAACAATTAAGGCTCAAGCACAGTAAATCGAACTGACCAAACCCGAGTTGGGGAGTTCGCGGAATTAAAACGAGTTCAAACTCACGTTTTCAGAGATAGGCCTGATCAACCTATAAATCTCGTAACTTGACCAAATGGTTAAACAAAGAAGCTATTTAAAAGATGGACTTTGCAAATCCATACTTAAATCTAGTAAAAACCCTCTTGGGATCATTGTCTTAAAAAAGGTTTAAAAGTCTCCTCAGGCAAAATACTTGTTAAGAAATTAAAGCCTACTTAGCCGATTAAAATAGTTCAGAAATAAACTTCGAGTTTGCTAACAAAAAGGGACAATCCCCATTAAGTGGACACAGCCACTACGGATCTTCAGCCACCTCGAGTTCAGGTTGAGTTGGCTCAGGATCGACCGGGTCCGCGGCAGCCGTTTCAGTTTCATCCGGTTCGTTGGCAGTGAGCTGTTCGGTAGGCATCCCAAATTCTGAACCATCGTCGTCCTCGATGACCACTGTTTCAGAGTTTGTGGATGGGGGAATTACTGGCGGGATGGCTGCCATTTCAGGAGTTTCAACCGGGATAACGGACACCTCGGGTTCCACGGGGTCACTGGGACCTGAAACAATTATCTCAAATCAAGAAAGACGCAAGAGTAACTTATTGTGGTTTTATTTCAAAATTTTGAGGCTTTTAAAACTTACCGGCCCAATCTAAACCAGACTCGCTCAAAGGAGGTGAGTCGGTAAAGAATTCCTCGAACTGTTGAGGGTTGAATGATGAAGAAGGAAGAGCGACCAAAAGACTTCGCTTCTCTGCTAAATCGGCTTCCAACTCGGACCTTTCTTGCTTCTCGGAAGAGTCTTTATCATGGGTTTGATCCAGAAGGAGGAGGTTGCTCTCGTATTCCTTGATGTCCGATTCCAGCTCCGTCCTTGCTTTCTCGGTTTGGATGAAAACGATCGCCCCTTGAATCAATTCCATCCCGTGACCTTTCACTTCCTTTCTGGCTTTCGATGCCGACCTCGCTAACTCAGCATCCAGTAGTTTGGCGATTGCCTTGTACTTGAGCTGCAATTCAGATAGCTGGTTGGACAAGTCGTAGGCACTGGATTCAGATTCCGAGAGTCTGTCCCGAGCGTTTGAGAGTTCCTCCTGGATCTTGTCATACCTCTGGTATTGATCCTGCAGCTCGTCGTTCGACTTCATGAGTTCAGAGGAAAGATTGTCCAATTGATCTTCTAGTTTTTGCCTTGCATCAGTTGAGGAGCGGAGCTCGGACTCGAGGGAAGAAAACATGTCTTTCCAGGCCAATACTCTTGTTCCCTGTCGAGCAACAACCTCTCATAGTATTCAATCATGTCGTTGAGTTCGCTGTTTGCCTGAACCAAGGGTTACAAAGGTAAGTTAGCATATGAGCGAAAAAATGGAGTTAAAAGATTACAAAAAAAACTAACCCGAGATGAGTGATAAGCGTGAAGAAGGAATCGCTCGCGAATTGCAGGGCGCCACCTGTCGAAGGTTGGCAGGATTGTGTCCTGCCGAGTCTTGAAGCATCGGAAGACGTTTCCTCTGTTTCCATCGCTGTCAAAGTAATAAAGAAGATTTGAAACTCATGTATGGGAAGTTAGGCCAGTGAATCGAACAATATAGTAAGTAAGAGAGTAAATGGTAATTACTAACGTGTGAGTGACTTGGTTTGAGGAACCAGTACGGCCTTAGGATTGACATCTCGGGGTTCAACTTCTTCTCGCCGAGGATTTTCACTCTGACCGGTCTTTTCGCTCCCAAATTTGGAAGAAGATGCGATGACTGGAGGAGGGGGACCAATTGAGCGAGGTGGGGGAGACAATCGAGGAGAACGGTCAGTTCGAGCTCTCGTCTTATCTCTTTTAGGAGAAGAACTGCTGCGGGTTGCTCTTTCCCTCTTTTTCCGATACAGGTCTGCTATCGGCTCGCTGCTTAACCTAGTCTGAGAAGCAGGTCGAGGCAAGTTGCGACGTGGTGATTGGTCTCTGCGAGGTGACCGGCTACCATGGCCTTCACGGTGAGGTGTAGGTCTGTATGCACCAGCAGATCTTGCACCTTCAGCGCTACCATCATCAACCAGGAGAGTTCTGCTATATTCCTTCTTGTCAACAGCGGACTGAAGGAACGACTTGTTTGCTTCACAAGCCTCTGTCATCGGCTTGGATAAAGTCTTGCGACGAGAAGCGATGGCCCTAGCAGAAGTTCCGTGAGGCAGAGGTGGAGGTGGTGGAAGTTGAAGTAGTTGTCCGGGAGGATTCGTCATGAGCTTGTGATTGGCTTCGACGAACCGGTCGAGAGTGAAAGAATTCCAAAGGGTCTCTCCTTCAATGACGATCTTGAAAAATTCGACGAACTCTACGGTCGGGAGGGTTAGAGTGATAAAAGCTGCGAGTTGAAAGCAATAAAATCGATTAAATCAGAAACAAGGATAAGCAAAAATCGTACGTGACCTAATTTCTACGAGGTTTCGCAGACCACTTCGATGGAAGCATATCGGAAAGGTTTCCAATCGAGGCAGGGGTTTTCTTGACCAGGAACCAAGGATGATGCCAATTCTCATCCTTGTTCAGGAGATTCGAAATGAGGTTCTGATTGGCGTTCGGGTACGCCGAGAAGTACCCAGTTTTCTTCGACGAACTCCTAACACTGAGAAGTTCATTCAATTCGGGAACCCTAATGACGAAACCGGCCTCCGCCGCAATGGTGATAATGCACAAGATGGTGCGGAGGAGATTGGGCGTCAACTGAGGTAGGGCGATTTCGAGAGCGGCCAAGTATCGAACCAAGGCTTCAGGAAGAGGGAAGGTCAGTCCGCAGCCTTTGAAGTAGATTTCATAGACGCAAAAGAACCCGGGACGGTGGTCCTCCGGCGATTCAGTGGGCTCCGACATCTGCGAATCTCTCATAATCTCAGCCGGAATCCGACAGAGCTCTCCCAATCGATTGAGGGATTGAAGAGTGCATGTGGATTGATAGTGAGGACCAGCGATATTGTTCGGCCGGGTGCAAAGGTCGTTACTAGAACCACATTTTCGAAAGATGGGGATTCGGGCCTTTCATTTTCAGAATTCATCGTGAGAGAATGAGTAAACTGAGGGTTCGAAGGATAGAAAATGTAGAGAGGAAGAAGAAAGGGACTTTGCTCTAAAAGAAAAATGAAGCGTGAAAAGTAATAAGGAGAGAGTAAAGCGAATTTACCTTACGCAAGCCAGTGACGATGATGGAACCGTCTTGGAAGTCGTGGGGGAAGTGGAAGAGTTTCCTCGCTTTAATAGTAAATAATTGATACGCAGTCATAATTGTGACAAATTTCACGAGAGTAATTATGGGTAATTCCGAAATCAAAGCAATAGCGTGGTTTTGGCGGGAAATCAGAAAGTCACTTGGCGCAATCTTCGCCCCTTAGAGCATTAAAGTCTTCCGAATTAGAGTTTCACTTCGAAAGACTTGGGGGGCTAATTGTTGGTGTCGGATCCCGCACCATGGGCTCGAGACCAGTCAAAGATTGCCACATAAGCAAGAGAGGCCCAAAAGAAGAGAAGCCCATAGGATACCCCGAGTTGATAGTACAAGCGAGGTGTTGACCTGGGAAGTGGATACAGAATCAAGGTCAAAGTTACCCGGAGTGAAGTGTCGAATGGGCCGACAGGTGAAGCCCAGGAAGTCTGGAGTCAATTCAAATTCGAACGTTTGAATAGATAATTCGAAAACTGAAACGAATACATTTAAGATAGAATAATTTTGTGTAAATGGGAATTTAATGTATTCTTTGGGTATAAATTATGGGTCAAAGGCCATGTAAAGGGACACGCATTTTTGGGCAAACACACTATACGCATTTTCCTACAAAGCTCATAGTTTTCTCAATAGTCATCAATCTATTTTCTAGTACATTTGTCCTCAAGAATAATCCTTCTCACTAAATAAATAAATACTTGAGTGTGTGAATCCGACATCCACAGACATGGGTTTGTTTTTTCCTAACCAATCCAAGGAAGATTTAATTGGTTTTGCAGATGCAGGATACTTATCTGATCCCCATAATGGTAGATCGCAAAGGATATGTCTTCACATGCGGGGGTACAGCTATTTCTTGGCGCTCTATGAAGCAAACTATTTCAGCCACATCTTCTAATCATGCAGAGATTTTAGCAATTCATGAAGCTAGCTGTGAGTGTGTATGGCTAAGATCCATAGTTCACCATATACAAGAAGACTGTGGTATGTATGCAGGGAAAAAGACTCCAACAATTATGTACGAAGACAATGCAGCATGCATCGCACAACTCAAAGACGGATACATCAAAGGCGATAGAACAAAGCACATCCTACCAAAATTCTTCTTCACACACGATCTACAAAAGAGCGGCGATGTACGAGTTCTACAGATCCGTTCGAATGATAATCTGGCTGACTTATTCACCAAGGCGCTACCTACTGCTATTTTCAAGAAGTTAGTCTATCGTATCGGATTACGCTGTCTCAAATATCTCGATGAATATACTCATAAGGGGGAGTAATTGTATGTTGCACTCTTTTTTTCTTAACCATGGTTTTTCTCATTGAGTTTTCCTGGTAAGGTTTTTAATGAGGCAGCATTTCAAATACTTTACCATTATGGTACTATAATGGTCATCAAGGGGGAGTGTTATGAATAAAGATGGATGCCCATTATAAGGCCCATCATCTAAGCCCATCATCTAGATGTTTCTAGGGTTTTACCCTTTCCTTGTACTCCTATATAAAGAACCTTTTTCTCAATGGAATACTACACTCATTTTCTTCTATATCTTTCTCTAGTTACAACAGGTTGTAGGTTTTATTAATTTAATATTATTACTTTGTAGAAATAAGATTATGGTTGTATGTATTTATAAACAAAAAAAATATTATTGGTAAATTGTACTTATGTGTTATATAATAGAATTCACAAATATCAAATTTAATATATATATATATATTGAAAATAATGTAAGTTATATATATGTCATAAAATAGATATTTACCTATTATTTATATCCATAAAACTAAATTTAATATATATATATATATATATATGAAAACTATAGTAATGTTTTTAAAGAAAATAAAGTGAAAAGAAAAAGAGAAAAAAGATACAAACCTTCTAAAGACCATAAAATTGTGCTTTAGAAAAACATGAACTTATCAGACAAAATAATTGAAAAAAAATACTATTTGGACTGTTAGAAAAAATAGGAAAGCTAAAGCATGATTATTTCAATTTTGGGGCTGTAAATTTTTTAGTGGCTTTAAAAATTTCCTACCGTCCAACCAATCATTTAAGTTAGGTTTTTTCGAGGAATTTTCTGTAAATAAAATTAACAGGGTTTGACGATTTGGTTAACATCGTTAACGGCCCGTTACGGTGAAGGGAGGTAGTCGGAAAAAAATAATAGGTCGTGTTTTTTTATCTCCAACCCAAATCAATTTGTGTATCTTTCTGACAACGAAAAAAATTTAGGTAGTTTTCTAGCAGATTTTAAATAGTTCGGATTTGTTTTGGGAATTTTCTCATACAGAAAATAAAATTGCACAAAAAATTATTTTGCTAAAAATATAGGTTCAGGACAACCAATACATATGGGTTTTTTCAGACAAAATATATCATAAAATTAACAACTTTAGGTGAAATTCAATATGATAAGGATTTGGTAAATTGAACTATAAACAATTGCAAATGAATAAGTGAAACAAAAAACAGCAAAGGAACTGCACCCGCCAATAAAAAAAAAAATCAAGCTAAGGAAGGCTGTATTTTGGAACATACAGTTTATATTAATGTTATACTGCTAAATTTAGTTATTTTCTAAAATTTGTTTAGTAAACATATTCAAGTAATTTTTTTCTTTGTAAATACTCTTAAAAATAGTATATGTTTTTTGGTTTTCTTTGTTTTTGTTAAACGATCTTGTAATAGCACTATTCGGGAAAACTAGATAATTCTCAGATCTCTTTCTTCTCTGCCTCTGTAAATCCGCCATGGCTCAATGAACTATTATGTAAAGACTTTTTAAATTAATATAAGTAATGTTCTATGGAAAAAAAATCAAGTAATAATAGTAGGAAAATTGTATTGTATAACCATCAAAAAACTTTATAATTAAACAACTAACCATTAAAAAAGAAGCAGTGATATTTTATGTAATATATACATATTTACCCTTGCTGATACATGTGCCTCAAAAGTCAATTCTCTACTTCTCCTTACCACCTTGAGTGCTTCATTTCTTTTATCTCGATTGGGTTTCCAAACCAGCTAAATAACGTGAATGTACTATACTGTTATCGTTATGGAATTAGCGATGTAATCAATAGGATTTTATTTGATTTGGAATTCTTACAAACAAATTTAACACTAAATACATATGTAACTAAGATTATCATGAACTATACTATTATTTTGATTAAAAACTAATTACAAGATTGCATGTTTTTTTCATAACTGTGAATATTCTATTTGATTATAGAAAATTAAAAATTATGTCAAGAATATTTAATTATATTTTAATTATCCGTAAACAAGTTTACAAAACAATTTCCTTGTATTTTTATGATATATAGTCCTTTTTTTGACGTGCATTTAACTCAATATTTTTAAATCTTATTTATTGTATCGTTTAGAATAAAACGTTACTTATTTGACTTCTGTTTAAATTTAACTTTTGGGTTTCCTATATAATATCTTTTAGGGTATAGTTTTTTCAGAAAATTTAACACATATATAAACAAGTCTTCAATCTTCCTCTTTATTGCTCCATGTTATTTCATAATCTACAAACATCTTCTGTTTAATCTCACCATTATTGATAATTTCATTAATTCCACAAATAAGAACCAAAAATTCATCATAAAACTTATAAATTTTGTTGCTTGGGTTTTTTATATACCATCTTAAGGTTTAGTTTTCTCTAATTAAAAACAATTAAAAATCTTATAGGAAAAAAGGAAGCAACCTTTGTTGAACAAAAAAGAGACATAGGCCTCACAACTAGCCTCCATCTCCTTGTCACTCTCACCACCACCACCGCCACCGCGGTGACCACCAACAACCATCACCATTATAACTAACACCACCACTACACCATCTCTATAATAAAATTAAAATTGATTTACGAATGATATATGAAAATAGTATAGTACACCATATTACTCCTATACATCCTAAATAGTACAACATATTTTTACTTACAAACACTATCTACTATTTTATAAATTTAAATCCTATTTTAAAAATTCAAACTATGTTTTATGTAGAAAAACATATATTTTTGTGTAATAAATTTCAGAATTGAAATCTATTTTTTGAAAAAGATATATAGCAAAAAAAATACAAATGAGTGAAAACTAAACTAAGTGTTACTAAATCATCTCACCAACAACTCTACACCAAAATTGTCTTTTCTCACCCTTTACATGCTATTTTCTTAATTTATATATATATGATGCTATATTCTTAATTAAGTATCAAAAATATCTAGTTTTGCAAATCACCCATAATAGTATTCATATATTAAAATAACAAAGCATGTAATTTTTATTAATCAAATAAATTATTCCAAAAAAATCTAACATTTTGAAACGAATGGGAATATTAATTATATTTGTCTATCGTATATGAAGACTCAACTACGTTTTCAAGACAAAAACAACGAATTTTTATTTTGTTTAGTAAACATAAATCTAAGAATTTGATTGATAATATACCAAATAAGGCCTTGATTCTGAAAATAGGTAGGACTATGGTCCCCCAACCTTGTCCAACGCATGTGTTTTGTACCATGCTTCCTCACCTACCCACTTCTCTCAATTCCATATTTATGTGTATTCAAAGAAATTTGGTGGAGGCTTTTTTTTGTATATATATATAAACTATGGCTACCAGAAAATTCTCAAAAAAACAGTTATCAGTTTGAGGATTTGGGAAAATTTTACAATTTCTATATGCTGGGTCAAAAGTCAAAAAATAAAATAAAGTATATATATATATATATATATATATATATATAATCAGAATTGTTTATCGTCCAAAATACTACGGAGTACGTAAACTCTTGTAAACGGATCACACAAGAGTACGGAAACCTTAGTTACCGACAACTAAAAGTATACAATGATCAAACGGACATAAGTGGATTTGATTGGCAACTAGTAAAGTCAAATAGATATATAAATTGAAATAATAAATAAAATGGATACAAATTAAAAGAAGTTTGACCCAAAAAAGAAGAAGAAATGGATACATAAGAGCTAATAAAAAGAAGGTTTAAACTTAAAAAACAACTGGATTCTCTTTAACACAAAAAACTTGAGATGCATTTTGTTGACGCTAATGTTTGATAACATTGCTCCTTAGGCGTGCTATACTAGGGGTGTGAGCCAAAGCACAATTAGCCTTACCTAAATGAATTATTGTGTTGCTTAGGCATGTTAAACTGAGAGTATGAGTGTAAACAAATATCAGCAAGTTCGTCCCAAAAATGATAAATTAAGCGATGAGGTAAAGAGATTCCTCTAATTTAAAAACCACGTAGCGCTAAACAATTAATCTAAGTTTTGAATTATGATGCAGATATTGCTGATCGAGAATTTTACAACTAGGCAACCAAAGTTAAGAAATAGATTGAGATTTTTGATTAGGTTGAGGCACAATAGGGTGTGGTTATGGTACATTGTTTTGTATAAGGATCATGTATGCGTGGGTGGTATGGGACTATGAGAGAATAATACGCGAACATGATCAATAAATATTGACAAGGTGGTTGAAGAAAAAAAAAGATGAAACTCGGGTTCATATAGAAAAAAATCCAAAGCTGTGAATGATGCATGCAAAATTCGGATTAACCCATTTATTTCTTATGTATAAAATGATTAGTGCGTGAGATAAAAAAATACTCATGATAGATAGACTAGATAAAAAAATACTCATGATAAATAGACTAAGATTTTTATTAGGATTTTGTAAAAAAAAACCTTCAAACTTGTTCATTTTTGCAATTTTATTTCCATTTCCAACAAATGTAAATTAATCCTATGAAGTATAAAATAATACGCATTATAACATTTTTGCCTATTTTTGCTATTATCAATTTTATAAAATATTGATATATAGTTTTTTAAACCGAACTCGAAAAGAAGAGTTTAACCTTACCTTCAAAATTTTAAAAATATAATCTAATGTGTGTGACCTTATAAACGTTTATAATATACGTATAAGGATCATATTGCGTATCATTTTAGACTTCAAATGATGAACCTGCATTTGTTGGAGATGAAGGATAAAATTCCAAAAATAGATTAGTTAAAGAATTTTTTTGCACAAAGCCTATTTTTTTCTTTGATGTATGTAAGCTTATCAACTGAGGTTGGTCAAAAATGGATTGAATAAGAACATGTCGACCATAAACCAAATAATTTAGGTTTTAGATGTTTTAACACTTTGCTAGAAGCCGAGTATATATAAAAGGATATATGACTCAAGTTTTAGGACCGAATTTTGTATAGTTGGTTTGGATCTCCATAATCTCAGAGCTTGGTGGTCAAGATTGTGCCTCGTAACCTCGTTATCCAAAAATGAAGTAGAATGTGAGTCGAATATCGTGAATTCGGTACCCTCTCGTTAGCTCATAGTGCGTTGAACCCTTTATCTCGAATTTGTCAAAACAAATTGATATTTTGTCGTGAAAAAAAAAAGTTCAGACGAAAAATAGTGGTCACAAGTCTTGTTCGAATTGATACCCGAAAAAACATCTTAACCAACTTAAAGTAAAAATTTAAAATCGGAAATTTAAATATTACCCTAAAGTTTTAAAAGGCGGACTTTTCAACGAAGGTTTATGCTAAGGTTAAAAAAAATACAGAAACGCTTTCTCACATTTCCATTTCAATAAATATATATCAGTCGCCACCCAAATTTCAGAATTGCTTCTCTTAGTATTTGCTTTCACCAACCCACTCGACGGAGTCTCCAACGCCTTCCTCCTCATTCTCCACTCTCACACCACCAACTTCTGATTCCAGATCTCAACGATGCAAAGCTCCGCCGTATTCTCCCTCTCTCCGTCGCTTCCTCTCCTAAAACCACGTCGGCTCTCTCTCCGCCACCATCCCATAACCACCGCCGCTTCTTCAAGCGATCTAAACGTTTCTCCAAATGTTGTCTCTATTCCTTCTTTATCTCGTCGATCTTGGCGTCTCGCTTCGTCTGATTCGCCTCTCCGTGCTTGGTCCGGTGTTCCTTCTCCGATCTCTCACTCCTTAGACACGAATCGTTTCAGAACCGCCGCTACTGCAGTTCCTGAAAGTGCTGAGGAAGGTGATAACAGTGGTAAATTGACGAAGGTTTTGGAACTTGGCTTGTTGTTCGCTATGTGGTACCTTTTCAATATCTACTTCAACATCTACAATAAACAGGTACTCCTTTGCTTCTCTACATGCTTAGTCTACTCCACTGTTTTGAATCAATGGAGAACTCAGAAATCTTATAGTCAATAGGATACTGGAGAGAGATTTTGTTCTGCTGATTCCGAAATTGGTACTGTTCATTGTGTTTTGGCTAATTGTTGTAAGTTCATAGTTTCAATAGATTGAACTAATCTTAACGATTGAGATTCATTTTTGTGTTTAATCGTGTTTTGATTAGGATGAAGTGTTCAGAAATTTGAGAGATATTTTGTTCTGCTGATTCAGAAAATTTCAGTGTTTATTGTGATTTGGCAAATTGTTAGAAGTCTAACTTTTGATTCTATCAAAAAATGTAAAGGTTTAGTTCAATCATGTTTTGATTAGGATGAAGAATTCAGAAATTTTATTATATCTTATACAGGAGAGAGATGTGTTTCACTGATTAGTTGATTTTATTGTTTGATTTTGAGGGAATCAATAGTTAGTTTCTTGTTTCTTCTTATTCTTGCAGGTTTTGAAAGCTCTACATGCTCCAATGACTGTGACTTTGGTTCAGTTTGCTGTTGGTAGTGTGCTCATTACTATCATGTGGGTTCTTAACCTGTACAAGAGACCAAAGATCAGTGGTGCTCAGGTGTGTGTGTGTGTGTGTGTTTTTAATGGAGGCTGGTAAAAGCT --------------------------------------------------------------------------------