From 9a25153bd2aa08e7377e53df5ceada56b14161ab Mon Sep 17 00:00:00 2001 From: Simon Brent Date: Mon, 30 Nov 2015 16:44:34 +0000 Subject: [PATCH 01/59] Make resize handle more visible --- css/resizer.css | 18 ++++- js/genoverse.combined.js | 118 +++++++++++++++--------------- js/genoverse.combined.nojquery.js | 118 +++++++++++++++--------------- js/plugins/resizer.js | 8 ++ 4 files changed, 140 insertions(+), 122 deletions(-) diff --git a/css/resizer.css b/css/resizer.css index 6fa9c672..9efbfbee 100644 --- a/css/resizer.css +++ b/css/resizer.css @@ -13,14 +13,24 @@ body.gv-dragging * { .gv-resizer-plugin .gv-canvas-container .gv-resizer .gv-handle { background-color: #5A5A5A; - border: 1px solid white; - border-width: 1px 0; - height: 1px; - margin: 1px 48%; + border: 1px solid #5A5A5A; + border-radius: 3px 3px 0 0; + height: 3px; + margin: 2px 48%; width: 4%; + box-sizing: border-box; } .gv-resizer-plugin .gv-canvas-container .gv-resizer:hover, .gv-resizer-plugin .gv-canvas-container .gv-resizer.ui-draggable-dragging { box-shadow: -1px -3px 6px -3px #000000 inset !important; } + +.gv-resizer-plugin .gv-canvas-container .gv-resizer:hover .gv-handle { + box-shadow: 0px -1px 3px #000000, 0px 0px 2px #FFFFFF inset !important; +} + +.gv-resizer-plugin .gv-canvas-container .gv-resizer-expander .gv-handle { + height: 5px; + margin-top: 0; +} diff --git a/js/genoverse.combined.js b/js/genoverse.combined.js index 3bcf6bdb..4be854fe 100644 --- a/js/genoverse.combined.js +++ b/js/genoverse.combined.js @@ -1554,32 +1554,20 @@ var Genoverse = Base.extend({ for (var i = 0; i < this.tracks.length; i++) { if (this.tracks[i].id && !(this.tracks[i] instanceof Genoverse.Track.Legend) && !(this.tracks[i] instanceof Genoverse.Track.HighlightRegion)) { + // when saving height, initialHeight is the height of the track once margins have been added, while defaultHeight is the DEFINED height of the track. + // Subtracting the difference between them gives you back the correct height to input back into the track when loading configuration conf = { - id : this.tracks[i].id, - namespace : this.tracks[i].namespace, - order : this.tracks[i].order + id : this.tracks[i].id, + namespace : this.tracks[i].namespace, + order : this.tracks[i].order, + autoHeight : this.tracks[i].autoHeight, + height : this.tracks[i].height - (this.tracks[i].initialHeight - this.tracks[i].defaultHeight) }; - // defaultAutoHeight is likely to be undefined, while autoHeight will be true or false - if (this.tracks[i].autoHeight !== !!this.tracks[i].defaultAutoHeight) { - conf.autoHeight = this.tracks[i].autoHeight; - } - - if (!this.tracks[i].autoHeight && ( - ( this.tracks[i].defaultAutoHeight && this.tracks[i].height !== this.tracks[i].prop('fullVisibleHeight')) || - (!this.tracks[i].defaultAutoHeight && this.tracks[i].height !== this.tracks[i].initialHeight) - )) { - // initialHeight is the height of the track once margins have been added, while defaultHeight is the DEFINED height of the track - // Subtracting the difference between them gives you back the correct height to input back into the track when loading configuration - conf.height = this.tracks[i].height - (this.tracks[i].initialHeight - this.tracks[i].defaultHeight); - } - if (this.tracks[i].config) { for (j in this.tracks[i].config) { - if (this.tracks[i].config[j] !== this.tracks[i].defaultConfig[j]) { - conf.config = conf.config || {}; - conf.config[j] = this.tracks[i].config[j]; - } + conf.config = conf.config || {}; + conf.config[j] = this.tracks[i].config[j]; } } @@ -2496,6 +2484,8 @@ var Genoverse = Base.extend({ } feature.menuEl = menu.appendTo(this.superContainer || this.container); + } else { + feature.menuEl.appendTo(this.superContainer || this.container); // Move the menu to the end of the container again, so that it will always be on top of other menus } this.menus = this.menus.add(feature.menuEl); @@ -2903,9 +2893,9 @@ Genoverse.Track = Base.extend({ }, setLengthMap: function () { - var extendArgs = [ true, {} ]; var featureFilters = []; - var settings, baseSetting, value, j, deepCopy; + var configSettings = []; + var settings, value, j, deepCopy; this.lengthMap = []; this.models = {}; @@ -2916,7 +2906,7 @@ Genoverse.Track = Base.extend({ settings = this.getConfig(i); if (settings) { - extendArgs.push(settings); + configSettings.push(settings); if (settings.featureFilter) { featureFilters.push(settings.featureFilter); @@ -2924,14 +2914,11 @@ Genoverse.Track = Base.extend({ } } - if (extendArgs.length > 2) { - baseSetting = $.extend.apply($, extendArgs.concat({ featureFilters: featureFilters })); + if (configSettings.length) { + configSettings = $.extend.apply($, [ true, {} ].concat(configSettings, { featureFilters: featureFilters })); - if (this[1]) { - $.extend(this[1], baseSetting); - } else { - this[1] = baseSetting; - } + // Force a lengthMap to exist. All entries in lengthMap get configSettings applied to them below + this[1] = this[1] || {}; } // Find all scale-map like keys @@ -2950,6 +2937,8 @@ Genoverse.Track = Base.extend({ } for (var i = 0; i < this.lengthMap.length; i++) { + $.extend(this.lengthMap[i][1], configSettings); + if (this.lengthMap[i][1].model && this.lengthMap[i][1].view) { continue; } @@ -3269,7 +3258,7 @@ Genoverse.Track.Controller = Base.extend({ var height = this.messageContainer.show().outerHeight(true); if (height > this.prop('height')) { - this.resize(height); + this.resize(height, undefined, false); } messages = null; @@ -3345,7 +3334,7 @@ Genoverse.Track.Controller = Base.extend({ if (autoHeight || this.prop('labels') === 'separate') { this.resize(autoHeight ? this.fullVisibleHeight : this.prop('height'), this.labelTop, false); } else { - this.toggleExpander(); + this.toggleExpander(false); } }, @@ -3364,7 +3353,7 @@ Genoverse.Track.Controller = Base.extend({ } }, - toggleExpander: function () { + toggleExpander: function (saveConfig) { if (this.prop('resizable') !== true) { return; } @@ -3384,7 +3373,7 @@ Genoverse.Track.Controller = Base.extend({ var h = this.messageContainer.outerHeight(true); if (h > height) { - this.resize(h); + this.resize(h, undefined, saveConfig); } this.expander = (this.expander || $('
').width(this.width).appendTo(this.container).on('click', function () { @@ -3675,6 +3664,8 @@ Genoverse.Track.Model = Base.extend({ this.urlParams = this.urlParams || {}; // hash of URL params this.xhrFields = this.xhrFields || {}; + this.dataBufferStart = this.dataBuffer.start; // Remember original dataBuffer.start, since dataBuffer.start is updated based on browser scale, in setLabelBuffer + if (!this._url) { this._url = this.url; // Remember original url } @@ -3707,7 +3698,7 @@ Genoverse.Track.Model = Base.extend({ }, setLabelBuffer: function (buffer) { - this.dataBuffer.start = Math.max(this.dataBuffer.start, buffer); + this.dataBuffer.start = Math.max(this.dataBufferStart, buffer); }, getData: function (start, end, done) { @@ -5531,7 +5522,7 @@ Genoverse.Track.File.BED = Genoverse.Track.File.extend({ model : Genoverse.Track.Model.File.BED, bump : true, featureHeight : 6, - + populateMenu: function (feature) { return { title : 'BED feature details', @@ -5555,7 +5546,7 @@ Genoverse.Track.File.VCF = Genoverse.Track.File.extend({ name : 'VCF', model : Genoverse.Track.Model.SequenceVariation.VCF, autoHeight : false, - + populateMenu: function (feature) { return { title : 'VCF feature details', @@ -5569,13 +5560,13 @@ Genoverse.Track.File.VCF = Genoverse.Track.File.extend({ INFO : feature.originalFeature[7].split(';').join('
') }; }, - - 1: { + + 1: { view: Genoverse.Track.View.Sequence.extend({ bump : true, labels : false, featureMargin : { top: 0, right: 0, bottom: 0, left: 0 }, - + draw: function (features, featureContext, labelContext, scale) { this.base.apply(this, arguments); this.highlightRef(features, featureContext, scale); @@ -5583,7 +5574,7 @@ Genoverse.Track.File.VCF = Genoverse.Track.File.extend({ highlightRef: function (features, context, scale) { context.strokeStyle = 'black'; - + for (var i = 0; i < features.length; i++) { if (features[i].allele === 'REF') { context.strokeRect(features[i].position[scale].X, features[i].position[scale].Y, features[i].position[scale].width, features[i].position[scale].height); @@ -5592,12 +5583,12 @@ Genoverse.Track.File.VCF = Genoverse.Track.File.extend({ } }) }, - + 1000: { view: Genoverse.Track.View.extend({ bump : false, labels : false, - + drawFeature: function (feature) { if (!feature.color) { var QUAL = feature.originalFeature[5]; @@ -5607,7 +5598,7 @@ Genoverse.Track.File.VCF = Genoverse.Track.File.extend({ feature.color = 'rgb(' + red + ',' + green + ',0)'; } - + this.base.apply(this, arguments); } }) @@ -6021,7 +6012,16 @@ Genoverse.Track.Legend = Genoverse.Track.Static.extend({ this.legends[i].controller.makeImage({}); } }, - afterUpdateTrackOrder: function () { + afterUpdateTrackOrder: function (e, ui) { + var track = ui.item.data('track'); + var legendTrack = this.legends[track.id] || track.legendTrack; + + // If a legend track, or a track with a sortable legend has been reordered, set a fixedOrder property to ensure that its lockToTrack status is ignored from now on. + // This allows a legend to initially be locked to a track, but then to be reordered once the browser has been initialized + if (legendTrack && legendTrack.lockToTrack && legendTrack.unsortable === false) { + legendTrack.fixedOrder = true; + } + for (var i in this.legends) { this.legends[i].updateOrder(); } @@ -6071,7 +6071,7 @@ Genoverse.Track.Legend = Genoverse.Track.Static.extend({ }, updateOrder: function () { - if (!this.tracks.length) { + if (!this.tracks.length || this.fixedOrder) { return; } @@ -6098,28 +6098,28 @@ Genoverse.Track.Scaleline = Genoverse.Track.Static.extend({ height : 12, labels : 'overlay', unsortable : true, - + resize: $.noop, - + makeFirstImage: function () { this.prop('scaleline', false); this.base.apply(this, arguments); }, - + render: function (f, img) { this.base(f, img); this.prop('drawnScale', img.data('scale')); }, - + positionFeatures: function (features, params) { var scaleline = this.prop('scaleline'); - + if (params.scale === this.drawnScale) { return false; } else if (scaleline) { return scaleline; } - + var strand = this.prop('strand'); var height = this.prop('height'); var text = this.formatLabel(this.browser.length); @@ -6128,7 +6128,7 @@ Genoverse.Track.Scaleline = Genoverse.Track.Static.extend({ var width2 = this.context.measureText(text2).width; var bg = this.prop('imgContainer').css('backgroundColor'); var x1, x2; - + if (strand === 1) { x1 = 0; x2 = this.width - width2 - 40; @@ -6136,23 +6136,23 @@ Genoverse.Track.Scaleline = Genoverse.Track.Static.extend({ x1 = 25; x2 = 30; } - + scaleline = [ { x: x1, y: height / 2, width: this.width - 25, height: 1, decorations: true }, { x: (this.width - width1 - 10) / 2, y: 0, width: width1 + 10, height: height, color: bg, labelColor: this.color, labelWidth: width1, label: text }, { x: x2, y: 0, width: width2 + 10, height: height, color: bg, labelColor: this.color, labelWidth: width2, label: text2 } ]; - + return this.base(this.prop('scaleline', scaleline), params); }, - + decorateFeature: function (feature, context) { var strand = this.prop('strand'); var height = this.prop('height'); var x = strand === 1 ? this.width - 25 : 25; - + context.strokeStyle = this.color; - + context.beginPath(); context.moveTo(x, height * 0.25); context.lineTo(x + (strand * 20), height * 0.5); diff --git a/js/genoverse.combined.nojquery.js b/js/genoverse.combined.nojquery.js index 2530258f..a622e15f 100644 --- a/js/genoverse.combined.nojquery.js +++ b/js/genoverse.combined.nojquery.js @@ -1549,32 +1549,20 @@ var Genoverse = Base.extend({ for (var i = 0; i < this.tracks.length; i++) { if (this.tracks[i].id && !(this.tracks[i] instanceof Genoverse.Track.Legend) && !(this.tracks[i] instanceof Genoverse.Track.HighlightRegion)) { + // when saving height, initialHeight is the height of the track once margins have been added, while defaultHeight is the DEFINED height of the track. + // Subtracting the difference between them gives you back the correct height to input back into the track when loading configuration conf = { - id : this.tracks[i].id, - namespace : this.tracks[i].namespace, - order : this.tracks[i].order + id : this.tracks[i].id, + namespace : this.tracks[i].namespace, + order : this.tracks[i].order, + autoHeight : this.tracks[i].autoHeight, + height : this.tracks[i].height - (this.tracks[i].initialHeight - this.tracks[i].defaultHeight) }; - // defaultAutoHeight is likely to be undefined, while autoHeight will be true or false - if (this.tracks[i].autoHeight !== !!this.tracks[i].defaultAutoHeight) { - conf.autoHeight = this.tracks[i].autoHeight; - } - - if (!this.tracks[i].autoHeight && ( - ( this.tracks[i].defaultAutoHeight && this.tracks[i].height !== this.tracks[i].prop('fullVisibleHeight')) || - (!this.tracks[i].defaultAutoHeight && this.tracks[i].height !== this.tracks[i].initialHeight) - )) { - // initialHeight is the height of the track once margins have been added, while defaultHeight is the DEFINED height of the track - // Subtracting the difference between them gives you back the correct height to input back into the track when loading configuration - conf.height = this.tracks[i].height - (this.tracks[i].initialHeight - this.tracks[i].defaultHeight); - } - if (this.tracks[i].config) { for (j in this.tracks[i].config) { - if (this.tracks[i].config[j] !== this.tracks[i].defaultConfig[j]) { - conf.config = conf.config || {}; - conf.config[j] = this.tracks[i].config[j]; - } + conf.config = conf.config || {}; + conf.config[j] = this.tracks[i].config[j]; } } @@ -2491,6 +2479,8 @@ var Genoverse = Base.extend({ } feature.menuEl = menu.appendTo(this.superContainer || this.container); + } else { + feature.menuEl.appendTo(this.superContainer || this.container); // Move the menu to the end of the container again, so that it will always be on top of other menus } this.menus = this.menus.add(feature.menuEl); @@ -2898,9 +2888,9 @@ Genoverse.Track = Base.extend({ }, setLengthMap: function () { - var extendArgs = [ true, {} ]; var featureFilters = []; - var settings, baseSetting, value, j, deepCopy; + var configSettings = []; + var settings, value, j, deepCopy; this.lengthMap = []; this.models = {}; @@ -2911,7 +2901,7 @@ Genoverse.Track = Base.extend({ settings = this.getConfig(i); if (settings) { - extendArgs.push(settings); + configSettings.push(settings); if (settings.featureFilter) { featureFilters.push(settings.featureFilter); @@ -2919,14 +2909,11 @@ Genoverse.Track = Base.extend({ } } - if (extendArgs.length > 2) { - baseSetting = $.extend.apply($, extendArgs.concat({ featureFilters: featureFilters })); + if (configSettings.length) { + configSettings = $.extend.apply($, [ true, {} ].concat(configSettings, { featureFilters: featureFilters })); - if (this[1]) { - $.extend(this[1], baseSetting); - } else { - this[1] = baseSetting; - } + // Force a lengthMap to exist. All entries in lengthMap get configSettings applied to them below + this[1] = this[1] || {}; } // Find all scale-map like keys @@ -2945,6 +2932,8 @@ Genoverse.Track = Base.extend({ } for (var i = 0; i < this.lengthMap.length; i++) { + $.extend(this.lengthMap[i][1], configSettings); + if (this.lengthMap[i][1].model && this.lengthMap[i][1].view) { continue; } @@ -3264,7 +3253,7 @@ Genoverse.Track.Controller = Base.extend({ var height = this.messageContainer.show().outerHeight(true); if (height > this.prop('height')) { - this.resize(height); + this.resize(height, undefined, false); } messages = null; @@ -3340,7 +3329,7 @@ Genoverse.Track.Controller = Base.extend({ if (autoHeight || this.prop('labels') === 'separate') { this.resize(autoHeight ? this.fullVisibleHeight : this.prop('height'), this.labelTop, false); } else { - this.toggleExpander(); + this.toggleExpander(false); } }, @@ -3359,7 +3348,7 @@ Genoverse.Track.Controller = Base.extend({ } }, - toggleExpander: function () { + toggleExpander: function (saveConfig) { if (this.prop('resizable') !== true) { return; } @@ -3379,7 +3368,7 @@ Genoverse.Track.Controller = Base.extend({ var h = this.messageContainer.outerHeight(true); if (h > height) { - this.resize(h); + this.resize(h, undefined, saveConfig); } this.expander = (this.expander || $('
').width(this.width).appendTo(this.container).on('click', function () { @@ -3670,6 +3659,8 @@ Genoverse.Track.Model = Base.extend({ this.urlParams = this.urlParams || {}; // hash of URL params this.xhrFields = this.xhrFields || {}; + this.dataBufferStart = this.dataBuffer.start; // Remember original dataBuffer.start, since dataBuffer.start is updated based on browser scale, in setLabelBuffer + if (!this._url) { this._url = this.url; // Remember original url } @@ -3702,7 +3693,7 @@ Genoverse.Track.Model = Base.extend({ }, setLabelBuffer: function (buffer) { - this.dataBuffer.start = Math.max(this.dataBuffer.start, buffer); + this.dataBuffer.start = Math.max(this.dataBufferStart, buffer); }, getData: function (start, end, done) { @@ -5526,7 +5517,7 @@ Genoverse.Track.File.BED = Genoverse.Track.File.extend({ model : Genoverse.Track.Model.File.BED, bump : true, featureHeight : 6, - + populateMenu: function (feature) { return { title : 'BED feature details', @@ -5550,7 +5541,7 @@ Genoverse.Track.File.VCF = Genoverse.Track.File.extend({ name : 'VCF', model : Genoverse.Track.Model.SequenceVariation.VCF, autoHeight : false, - + populateMenu: function (feature) { return { title : 'VCF feature details', @@ -5564,13 +5555,13 @@ Genoverse.Track.File.VCF = Genoverse.Track.File.extend({ INFO : feature.originalFeature[7].split(';').join('
') }; }, - - 1: { + + 1: { view: Genoverse.Track.View.Sequence.extend({ bump : true, labels : false, featureMargin : { top: 0, right: 0, bottom: 0, left: 0 }, - + draw: function (features, featureContext, labelContext, scale) { this.base.apply(this, arguments); this.highlightRef(features, featureContext, scale); @@ -5578,7 +5569,7 @@ Genoverse.Track.File.VCF = Genoverse.Track.File.extend({ highlightRef: function (features, context, scale) { context.strokeStyle = 'black'; - + for (var i = 0; i < features.length; i++) { if (features[i].allele === 'REF') { context.strokeRect(features[i].position[scale].X, features[i].position[scale].Y, features[i].position[scale].width, features[i].position[scale].height); @@ -5587,12 +5578,12 @@ Genoverse.Track.File.VCF = Genoverse.Track.File.extend({ } }) }, - + 1000: { view: Genoverse.Track.View.extend({ bump : false, labels : false, - + drawFeature: function (feature) { if (!feature.color) { var QUAL = feature.originalFeature[5]; @@ -5602,7 +5593,7 @@ Genoverse.Track.File.VCF = Genoverse.Track.File.extend({ feature.color = 'rgb(' + red + ',' + green + ',0)'; } - + this.base.apply(this, arguments); } }) @@ -6016,7 +6007,16 @@ Genoverse.Track.Legend = Genoverse.Track.Static.extend({ this.legends[i].controller.makeImage({}); } }, - afterUpdateTrackOrder: function () { + afterUpdateTrackOrder: function (e, ui) { + var track = ui.item.data('track'); + var legendTrack = this.legends[track.id] || track.legendTrack; + + // If a legend track, or a track with a sortable legend has been reordered, set a fixedOrder property to ensure that its lockToTrack status is ignored from now on. + // This allows a legend to initially be locked to a track, but then to be reordered once the browser has been initialized + if (legendTrack && legendTrack.lockToTrack && legendTrack.unsortable === false) { + legendTrack.fixedOrder = true; + } + for (var i in this.legends) { this.legends[i].updateOrder(); } @@ -6066,7 +6066,7 @@ Genoverse.Track.Legend = Genoverse.Track.Static.extend({ }, updateOrder: function () { - if (!this.tracks.length) { + if (!this.tracks.length || this.fixedOrder) { return; } @@ -6093,28 +6093,28 @@ Genoverse.Track.Scaleline = Genoverse.Track.Static.extend({ height : 12, labels : 'overlay', unsortable : true, - + resize: $.noop, - + makeFirstImage: function () { this.prop('scaleline', false); this.base.apply(this, arguments); }, - + render: function (f, img) { this.base(f, img); this.prop('drawnScale', img.data('scale')); }, - + positionFeatures: function (features, params) { var scaleline = this.prop('scaleline'); - + if (params.scale === this.drawnScale) { return false; } else if (scaleline) { return scaleline; } - + var strand = this.prop('strand'); var height = this.prop('height'); var text = this.formatLabel(this.browser.length); @@ -6123,7 +6123,7 @@ Genoverse.Track.Scaleline = Genoverse.Track.Static.extend({ var width2 = this.context.measureText(text2).width; var bg = this.prop('imgContainer').css('backgroundColor'); var x1, x2; - + if (strand === 1) { x1 = 0; x2 = this.width - width2 - 40; @@ -6131,23 +6131,23 @@ Genoverse.Track.Scaleline = Genoverse.Track.Static.extend({ x1 = 25; x2 = 30; } - + scaleline = [ { x: x1, y: height / 2, width: this.width - 25, height: 1, decorations: true }, { x: (this.width - width1 - 10) / 2, y: 0, width: width1 + 10, height: height, color: bg, labelColor: this.color, labelWidth: width1, label: text }, { x: x2, y: 0, width: width2 + 10, height: height, color: bg, labelColor: this.color, labelWidth: width2, label: text2 } ]; - + return this.base(this.prop('scaleline', scaleline), params); }, - + decorateFeature: function (feature, context) { var strand = this.prop('strand'); var height = this.prop('height'); var x = strand === 1 ? this.width - 25 : 25; - + context.strokeStyle = this.color; - + context.beginPath(); context.moveTo(x, height * 0.25); context.lineTo(x + (strand * 20), height * 0.5); diff --git a/js/plugins/resizer.js b/js/plugins/resizer.js index 2c168595..f260b0fc 100644 --- a/js/plugins/resizer.js +++ b/js/plugins/resizer.js @@ -34,4 +34,12 @@ Genoverse.Plugins.resizer = function () { this.prop('initialHeight', this.prop('height')); } }); + + this.on('afterToggleExpander', 'tracks', function () { + var resizer = this.prop('resizer'); + + if (resizer) { + resizer[this.expander && this.expander.is(':visible') ? 'addClass' : 'removeClass']('gv-resizer-expander'); + } + }); }; \ No newline at end of file From 0636b4007bfaa981717a95bdd9b4562ac014c9f8 Mon Sep 17 00:00:00 2001 From: Simon Brent Date: Mon, 30 Nov 2015 16:45:36 +0000 Subject: [PATCH 02/59] Whitespace tidying --- js/Track/library/File/BED.js | 2 +- js/Track/library/File/VCF.js | 16 +- js/Track/library/Scaleline.js | 24 +- js/genomes/grch37.js | 6141 +++++---------------------------- js/genomes/grch38.js | 6139 +++++--------------------------- js/genomes/node.js | 2 +- 6 files changed, 1849 insertions(+), 10475 deletions(-) diff --git a/js/Track/library/File/BED.js b/js/Track/library/File/BED.js index aa4edeb8..f5b7dc89 100644 --- a/js/Track/library/File/BED.js +++ b/js/Track/library/File/BED.js @@ -3,7 +3,7 @@ Genoverse.Track.File.BED = Genoverse.Track.File.extend({ model : Genoverse.Track.Model.File.BED, bump : true, featureHeight : 6, - + populateMenu: function (feature) { return { title : 'BED feature details', diff --git a/js/Track/library/File/VCF.js b/js/Track/library/File/VCF.js index 2c502ef3..6f440e68 100644 --- a/js/Track/library/File/VCF.js +++ b/js/Track/library/File/VCF.js @@ -2,7 +2,7 @@ Genoverse.Track.File.VCF = Genoverse.Track.File.extend({ name : 'VCF', model : Genoverse.Track.Model.SequenceVariation.VCF, autoHeight : false, - + populateMenu: function (feature) { return { title : 'VCF feature details', @@ -16,13 +16,13 @@ Genoverse.Track.File.VCF = Genoverse.Track.File.extend({ INFO : feature.originalFeature[7].split(';').join('
') }; }, - - 1: { + + 1: { view: Genoverse.Track.View.Sequence.extend({ bump : true, labels : false, featureMargin : { top: 0, right: 0, bottom: 0, left: 0 }, - + draw: function (features, featureContext, labelContext, scale) { this.base.apply(this, arguments); this.highlightRef(features, featureContext, scale); @@ -30,7 +30,7 @@ Genoverse.Track.File.VCF = Genoverse.Track.File.extend({ highlightRef: function (features, context, scale) { context.strokeStyle = 'black'; - + for (var i = 0; i < features.length; i++) { if (features[i].allele === 'REF') { context.strokeRect(features[i].position[scale].X, features[i].position[scale].Y, features[i].position[scale].width, features[i].position[scale].height); @@ -39,12 +39,12 @@ Genoverse.Track.File.VCF = Genoverse.Track.File.extend({ } }) }, - + 1000: { view: Genoverse.Track.View.extend({ bump : false, labels : false, - + drawFeature: function (feature) { if (!feature.color) { var QUAL = feature.originalFeature[5]; @@ -54,7 +54,7 @@ Genoverse.Track.File.VCF = Genoverse.Track.File.extend({ feature.color = 'rgb(' + red + ',' + green + ',0)'; } - + this.base.apply(this, arguments); } }) diff --git a/js/Track/library/Scaleline.js b/js/Track/library/Scaleline.js index 91b7e2bd..349ab501 100644 --- a/js/Track/library/Scaleline.js +++ b/js/Track/library/Scaleline.js @@ -4,28 +4,28 @@ Genoverse.Track.Scaleline = Genoverse.Track.Static.extend({ height : 12, labels : 'overlay', unsortable : true, - + resize: $.noop, - + makeFirstImage: function () { this.prop('scaleline', false); this.base.apply(this, arguments); }, - + render: function (f, img) { this.base(f, img); this.prop('drawnScale', img.data('scale')); }, - + positionFeatures: function (features, params) { var scaleline = this.prop('scaleline'); - + if (params.scale === this.drawnScale) { return false; } else if (scaleline) { return scaleline; } - + var strand = this.prop('strand'); var height = this.prop('height'); var text = this.formatLabel(this.browser.length); @@ -34,7 +34,7 @@ Genoverse.Track.Scaleline = Genoverse.Track.Static.extend({ var width2 = this.context.measureText(text2).width; var bg = this.prop('imgContainer').css('backgroundColor'); var x1, x2; - + if (strand === 1) { x1 = 0; x2 = this.width - width2 - 40; @@ -42,23 +42,23 @@ Genoverse.Track.Scaleline = Genoverse.Track.Static.extend({ x1 = 25; x2 = 30; } - + scaleline = [ { x: x1, y: height / 2, width: this.width - 25, height: 1, decorations: true }, { x: (this.width - width1 - 10) / 2, y: 0, width: width1 + 10, height: height, color: bg, labelColor: this.color, labelWidth: width1, label: text }, { x: x2, y: 0, width: width2 + 10, height: height, color: bg, labelColor: this.color, labelWidth: width2, label: text2 } ]; - + return this.base(this.prop('scaleline', scaleline), params); }, - + decorateFeature: function (feature, context) { var strand = this.prop('strand'); var height = this.prop('height'); var x = strand === 1 ? this.width - 25 : 25; - + context.strokeStyle = this.color; - + context.beginPath(); context.moveTo(x, height * 0.25); context.lineTo(x + (strand * 20), height * 0.5); diff --git a/js/genomes/grch37.js b/js/genomes/grch37.js index 047647d5..a0a79f78 100644 --- a/js/genomes/grch37.js +++ b/js/genomes/grch37.js @@ -1,5303 +1,990 @@ window.grch37 = { "1": { - "size": 249250621, - "bands": [ - { - "id": "p11.1", - "start": 121500001, - "end": 125000000, - "type": "acen" - }, - { - "id": "p11.2", - "start": 120600001, - "end": 121500000, - "type": "gneg" - }, - { - "id": "p12", - "start": 117800001, - "end": 120600000, - "type": "gpos50" - }, - { - "id": "p13.1", - "start": 116100001, - "end": 117800000, - "type": "gneg" - }, - { - "id": "p13.2", - "start": 111800001, - "end": 116100000, - "type": "gpos50" - }, - { - "id": "p13.3", - "start": 107200001, - "end": 111800000, - "type": "gneg" - }, - { - "id": "p21.1", - "start": 102200001, - "end": 107200000, - "type": "gpos100" - }, - { - "id": "p21.2", - "start": 99700001, - "end": 102200000, - "type": "gneg" - }, - { - "id": "p21.3", - "start": 94700001, - "end": 99700000, - "type": "gpos75" - }, - { - "id": "p22.1", - "start": 92000001, - "end": 94700000, - "type": "gneg" - }, - { - "id": "p22.2", - "start": 88400001, - "end": 92000000, - "type": "gpos75" - }, - { - "id": "p22.3", - "start": 84900001, - "end": 88400000, - "type": "gneg" - }, - { - "id": "p31.1", - "start": 69700001, - "end": 84900000, - "type": "gpos100" - }, - { - "id": "p31.2", - "start": 68900001, - "end": 69700000, - "type": "gneg" - }, - { - "id": "p31.3", - "start": 61300001, - "end": 68900000, - "type": "gpos50" - }, - { - "id": "p32.1", - "start": 59000001, - "end": 61300000, - "type": "gneg" - }, - { - "id": "p32.2", - "start": 56100001, - "end": 59000000, - "type": "gpos50" - }, - { - "id": "p32.3", - "start": 50700001, - "end": 56100000, - "type": "gneg" - }, - { - "id": "p33", - "start": 46800001, - "end": 50700000, - "type": "gpos75" - }, - { - "id": "p34.1", - "start": 44100001, - "end": 46800000, - "type": "gneg" - }, - { - "id": "p34.2", - "start": 40100001, - "end": 44100000, - "type": "gpos25" - }, - { - "id": "p34.3", - "start": 34600001, - "end": 40100000, - "type": "gneg" - }, - { - "id": "p35.1", - "start": 32400001, - "end": 34600000, - "type": "gpos25" - }, - { - "id": "p35.2", - "start": 30200001, - "end": 32400000, - "type": "gneg" - }, - { - "id": "p35.3", - "start": 28000001, - "end": 30200000, - "type": "gpos25" - }, - { - "id": "p36.11", - "start": 23900001, - "end": 28000000, - "type": "gneg" - }, - { - "id": "p36.12", - "start": 20400001, - "end": 23900000, - "type": "gpos25" - }, - { - "id": "p36.13", - "start": 16200001, - "end": 20400000, - "type": "gneg" - }, - { - "id": "p36.21", - "start": 12700001, - "end": 16200000, - "type": "gpos50" - }, - { - "id": "p36.22", - "start": 9200001, - "end": 12700000, - "type": "gneg" - }, - { - "id": "p36.23", - "start": 7200001, - "end": 9200000, - "type": "gpos25" - }, - { - "id": "p36.31", - "start": 5400001, - "end": 7200000, - "type": "gneg" - }, - { - "id": "p36.32", - "start": 2300001, - "end": 5400000, - "type": "gpos25" - }, - { - "id": "p36.33", - "start": 1, - "end": 2300000, - "type": "gneg" - }, - { - "id": "q11", - "start": 125000001, - "end": 128900000, - "type": "acen" - }, - { - "id": "q12", - "start": 128900001, - "end": 142600000, - "type": "gvar" - }, - { - "id": "q21.1", - "start": 142600001, - "end": 147000000, - "type": "gneg" - }, - { - "id": "q21.2", - "start": 147000001, - "end": 150300000, - "type": "gpos50" - }, - { - "id": "q21.3", - "start": 150300001, - "end": 155000000, - "type": "gneg" - }, - { - "id": "q22", - "start": 155000001, - "end": 156500000, - "type": "gpos50" - }, - { - "id": "q23.1", - "start": 156500001, - "end": 159100000, - "type": "gneg" - }, - { - "id": "q23.2", - "start": 159100001, - "end": 160500000, - "type": "gpos50" - }, - { - "id": "q23.3", - "start": 160500001, - "end": 165500000, - "type": "gneg" - }, - { - "id": "q24.1", - "start": 165500001, - "end": 167200000, - "type": "gpos50" - }, - { - "id": "q24.2", - "start": 167200001, - "end": 170900000, - "type": "gneg" - }, - { - "id": "q24.3", - "start": 170900001, - "end": 172900000, - "type": "gpos75" - }, - { - "id": "q25.1", - "start": 172900001, - "end": 176000000, - "type": "gneg" - }, - { - "id": "q25.2", - "start": 176000001, - "end": 180300000, - "type": "gpos50" - }, - { - "id": "q25.3", - "start": 180300001, - "end": 185800000, - "type": "gneg" - }, - { - "id": "q31.1", - "start": 185800001, - "end": 190800000, - "type": "gpos100" - }, - { - "id": "q31.2", - "start": 190800001, - "end": 193800000, - "type": "gneg" - }, - { - "id": "q31.3", - "start": 193800001, - "end": 198700000, - "type": "gpos100" - }, - { - "id": "q32.1", - "start": 198700001, - "end": 207200000, - "type": "gneg" - }, - { - "id": "q32.2", - "start": 207200001, - "end": 211500000, - "type": "gpos25" - }, - { - "id": "q32.3", - "start": 211500001, - "end": 214500000, - "type": "gneg" - }, - { - "id": "q41", - "start": 214500001, - "end": 224100000, - "type": "gpos100" - }, - { - "id": "q42.11", - "start": 224100001, - "end": 224600000, - "type": "gneg" - }, - { - "id": "q42.12", - "start": 224600001, - "end": 227000000, - "type": "gpos25" - }, - { - "id": "q42.13", - "start": 227000001, - "end": 230700000, - "type": "gneg" - }, - { - "id": "q42.2", - "start": 230700001, - "end": 234700000, - "type": "gpos50" - }, - { - "id": "q42.3", - "start": 234700001, - "end": 236600000, - "type": "gneg" - }, - { - "id": "q43", - "start": 236600001, - "end": 243700000, - "type": "gpos75" - }, - { - "id": "q44", - "start": 243700001, - "end": 249250621, - "type": "gneg" - } + "size" : 249250621, + "bands" : [ + { "id": "p11.1", "start": 121500001, "end": 125000000, "type": "acen" }, + { "id": "p11.2", "start": 120600001, "end": 121500000, "type": "gneg" }, + { "id": "p12", "start": 117800001, "end": 120600000, "type": "gpos50" }, + { "id": "p13.1", "start": 116100001, "end": 117800000, "type": "gneg" }, + { "id": "p13.2", "start": 111800001, "end": 116100000, "type": "gpos50" }, + { "id": "p13.3", "start": 107200001, "end": 111800000, "type": "gneg" }, + { "id": "p21.1", "start": 102200001, "end": 107200000, "type": "gpos100" }, + { "id": "p21.2", "start": 99700001, "end": 102200000, "type": "gneg" }, + { "id": "p21.3", "start": 94700001, "end": 99700000, "type": "gpos75" }, + { "id": "p22.1", "start": 92000001, "end": 94700000, "type": "gneg" }, + { "id": "p22.2", "start": 88400001, "end": 92000000, "type": "gpos75" }, + { "id": "p22.3", "start": 84900001, "end": 88400000, "type": "gneg" }, + { "id": "p31.1", "start": 69700001, "end": 84900000, "type": "gpos100" }, + { "id": "p31.2", "start": 68900001, "end": 69700000, "type": "gneg" }, + { "id": "p31.3", "start": 61300001, "end": 68900000, "type": "gpos50" }, + { "id": "p32.1", "start": 59000001, "end": 61300000, "type": "gneg" }, + { "id": "p32.2", "start": 56100001, "end": 59000000, "type": "gpos50" }, + { "id": "p32.3", "start": 50700001, "end": 56100000, "type": "gneg" }, + { "id": "p33", "start": 46800001, "end": 50700000, "type": "gpos75" }, + { "id": "p34.1", "start": 44100001, "end": 46800000, "type": "gneg" }, + { "id": "p34.2", "start": 40100001, "end": 44100000, "type": "gpos25" }, + { "id": "p34.3", "start": 34600001, "end": 40100000, "type": "gneg" }, + { "id": "p35.1", "start": 32400001, "end": 34600000, "type": "gpos25" }, + { "id": "p35.2", "start": 30200001, "end": 32400000, "type": "gneg" }, + { "id": "p35.3", "start": 28000001, "end": 30200000, "type": "gpos25" }, + { "id": "p36.11", "start": 23900001, "end": 28000000, "type": "gneg" }, + { "id": "p36.12", "start": 20400001, "end": 23900000, "type": "gpos25" }, + { "id": "p36.13", "start": 16200001, "end": 20400000, "type": "gneg" }, + { "id": "p36.21", "start": 12700001, "end": 16200000, "type": "gpos50" }, + { "id": "p36.22", "start": 9200001, "end": 12700000, "type": "gneg" }, + { "id": "p36.23", "start": 7200001, "end": 9200000, "type": "gpos25" }, + { "id": "p36.31", "start": 5400001, "end": 7200000, "type": "gneg" }, + { "id": "p36.32", "start": 2300001, "end": 5400000, "type": "gpos25" }, + { "id": "p36.33", "start": 1, "end": 2300000, "type": "gneg" }, + { "id": "q11", "start": 125000001, "end": 128900000, "type": "acen" }, + { "id": "q12", "start": 128900001, "end": 142600000, "type": "gvar" }, + { "id": "q21.1", "start": 142600001, "end": 147000000, "type": "gneg" }, + { "id": "q21.2", "start": 147000001, "end": 150300000, "type": "gpos50" }, + { "id": "q21.3", "start": 150300001, "end": 155000000, "type": "gneg" }, + { "id": "q22", "start": 155000001, "end": 156500000, "type": "gpos50" }, + { "id": "q23.1", "start": 156500001, "end": 159100000, "type": "gneg" }, + { "id": "q23.2", "start": 159100001, "end": 160500000, "type": "gpos50" }, + { "id": "q23.3", "start": 160500001, "end": 165500000, "type": "gneg" }, + { "id": "q24.1", "start": 165500001, "end": 167200000, "type": "gpos50" }, + { "id": "q24.2", "start": 167200001, "end": 170900000, "type": "gneg" }, + { "id": "q24.3", "start": 170900001, "end": 172900000, "type": "gpos75" }, + { "id": "q25.1", "start": 172900001, "end": 176000000, "type": "gneg" }, + { "id": "q25.2", "start": 176000001, "end": 180300000, "type": "gpos50" }, + { "id": "q25.3", "start": 180300001, "end": 185800000, "type": "gneg" }, + { "id": "q31.1", "start": 185800001, "end": 190800000, "type": "gpos100" }, + { "id": "q31.2", "start": 190800001, "end": 193800000, "type": "gneg" }, + { "id": "q31.3", "start": 193800001, "end": 198700000, "type": "gpos100" }, + { "id": "q32.1", "start": 198700001, "end": 207200000, "type": "gneg" }, + { "id": "q32.2", "start": 207200001, "end": 211500000, "type": "gpos25" }, + { "id": "q32.3", "start": 211500001, "end": 214500000, "type": "gneg" }, + { "id": "q41", "start": 214500001, "end": 224100000, "type": "gpos100" }, + { "id": "q42.11", "start": 224100001, "end": 224600000, "type": "gneg" }, + { "id": "q42.12", "start": 224600001, "end": 227000000, "type": "gpos25" }, + { "id": "q42.13", "start": 227000001, "end": 230700000, "type": "gneg" }, + { "id": "q42.2", "start": 230700001, "end": 234700000, "type": "gpos50" }, + { "id": "q42.3", "start": 234700001, "end": 236600000, "type": "gneg" }, + { "id": "q43", "start": 236600001, "end": 243700000, "type": "gpos75" }, + { "id": "q44", "start": 243700001, "end": 249250621, "type": "gneg" } ] }, "2": { - "size": 243199373, - "bands": [ - { - "id": "p11.1", - "start": 90500001, - "end": 93300000, - "type": "acen" - }, - { - "id": "p11.2", - "start": 83300001, - "end": 90500000, - "type": "gneg" - }, - { - "id": "p12", - "start": 75000001, - "end": 83300000, - "type": "gpos100" - }, - { - "id": "p13.1", - "start": 73500001, - "end": 75000000, - "type": "gneg" - }, - { - "id": "p13.2", - "start": 71500001, - "end": 73500000, - "type": "gpos50" - }, - { - "id": "p13.3", - "start": 68600001, - "end": 71500000, - "type": "gneg" - }, - { - "id": "p14", - "start": 64100001, - "end": 68600000, - "type": "gpos50" - }, - { - "id": "p15", - "start": 61300001, - "end": 64100000, - "type": "gneg" - }, - { - "id": "p16.1", - "start": 55000001, - "end": 61300000, - "type": "gpos100" - }, - { - "id": "p16.2", - "start": 52900001, - "end": 55000000, - "type": "gneg" - }, - { - "id": "p16.3", - "start": 47800001, - "end": 52900000, - "type": "gpos100" - }, - { - "id": "p21", - "start": 41800001, - "end": 47800000, - "type": "gneg" - }, - { - "id": "p22.1", - "start": 38600001, - "end": 41800000, - "type": "gpos50" - }, - { - "id": "p22.2", - "start": 36600001, - "end": 38600000, - "type": "gneg" - }, - { - "id": "p22.3", - "start": 32100001, - "end": 36600000, - "type": "gpos75" - }, - { - "id": "p23.1", - "start": 30000001, - "end": 32100000, - "type": "gneg" - }, - { - "id": "p23.2", - "start": 27900001, - "end": 30000000, - "type": "gpos25" - }, - { - "id": "p23.3", - "start": 24000001, - "end": 27900000, - "type": "gneg" - }, - { - "id": "p24.1", - "start": 19200001, - "end": 24000000, - "type": "gpos75" - }, - { - "id": "p24.2", - "start": 16700001, - "end": 19200000, - "type": "gneg" - }, - { - "id": "p24.3", - "start": 12200001, - "end": 16700000, - "type": "gpos75" - }, - { - "id": "p25.1", - "start": 7100001, - "end": 12200000, - "type": "gneg" - }, - { - "id": "p25.2", - "start": 4400001, - "end": 7100000, - "type": "gpos50" - }, - { - "id": "p25.3", - "start": 1, - "end": 4400000, - "type": "gneg" - }, - { - "id": "q11.1", - "start": 93300001, - "end": 96800000, - "type": "acen" - }, - { - "id": "q11.2", - "start": 96800001, - "end": 102700000, - "type": "gneg" - }, - { - "id": "q12.1", - "start": 102700001, - "end": 106000000, - "type": "gpos50" - }, - { - "id": "q12.2", - "start": 106000001, - "end": 107500000, - "type": "gneg" - }, - { - "id": "q12.3", - "start": 107500001, - "end": 110200000, - "type": "gpos25" - }, - { - "id": "q13", - "start": 110200001, - "end": 114400000, - "type": "gneg" - }, - { - "id": "q14.1", - "start": 114400001, - "end": 118800000, - "type": "gpos50" - }, - { - "id": "q14.2", - "start": 118800001, - "end": 122400000, - "type": "gneg" - }, - { - "id": "q14.3", - "start": 122400001, - "end": 129900000, - "type": "gpos50" - }, - { - "id": "q21.1", - "start": 129900001, - "end": 132500000, - "type": "gneg" - }, - { - "id": "q21.2", - "start": 132500001, - "end": 135100000, - "type": "gpos25" - }, - { - "id": "q21.3", - "start": 135100001, - "end": 136800000, - "type": "gneg" - }, - { - "id": "q22.1", - "start": 136800001, - "end": 142200000, - "type": "gpos100" - }, - { - "id": "q22.2", - "start": 142200001, - "end": 144100000, - "type": "gneg" - }, - { - "id": "q22.3", - "start": 144100001, - "end": 148700000, - "type": "gpos100" - }, - { - "id": "q23.1", - "start": 148700001, - "end": 149900000, - "type": "gneg" - }, - { - "id": "q23.2", - "start": 149900001, - "end": 150500000, - "type": "gpos25" - }, - { - "id": "q23.3", - "start": 150500001, - "end": 154900000, - "type": "gneg" - }, - { - "id": "q24.1", - "start": 154900001, - "end": 159800000, - "type": "gpos75" - }, - { - "id": "q24.2", - "start": 159800001, - "end": 163700000, - "type": "gneg" - }, - { - "id": "q24.3", - "start": 163700001, - "end": 169700000, - "type": "gpos75" - }, - { - "id": "q31.1", - "start": 169700001, - "end": 178000000, - "type": "gneg" - }, - { - "id": "q31.2", - "start": 178000001, - "end": 180600000, - "type": "gpos50" - }, - { - "id": "q31.3", - "start": 180600001, - "end": 183000000, - "type": "gneg" - }, - { - "id": "q32.1", - "start": 183000001, - "end": 189400000, - "type": "gpos75" - }, - { - "id": "q32.2", - "start": 189400001, - "end": 191900000, - "type": "gneg" - }, - { - "id": "q32.3", - "start": 191900001, - "end": 197400000, - "type": "gpos75" - }, - { - "id": "q33.1", - "start": 197400001, - "end": 203300000, - "type": "gneg" - }, - { - "id": "q33.2", - "start": 203300001, - "end": 204900000, - "type": "gpos50" - }, - { - "id": "q33.3", - "start": 204900001, - "end": 209000000, - "type": "gneg" - }, - { - "id": "q34", - "start": 209000001, - "end": 215300000, - "type": "gpos100" - }, - { - "id": "q35", - "start": 215300001, - "end": 221500000, - "type": "gneg" - }, - { - "id": "q36.1", - "start": 221500001, - "end": 225200000, - "type": "gpos75" - }, - { - "id": "q36.2", - "start": 225200001, - "end": 226100000, - "type": "gneg" - }, - { - "id": "q36.3", - "start": 226100001, - "end": 231000000, - "type": "gpos100" - }, - { - "id": "q37.1", - "start": 231000001, - "end": 235600000, - "type": "gneg" - }, - { - "id": "q37.2", - "start": 235600001, - "end": 237300000, - "type": "gpos50" - }, - { - "id": "q37.3", - "start": 237300001, - "end": 243199373, - "type": "gneg" - } + "size" : 243199373, + "bands" : [ + { "id": "p11.1", "start": 90500001, "end": 93300000, "type": "acen" }, + { "id": "p11.2", "start": 83300001, "end": 90500000, "type": "gneg" }, + { "id": "p12", "start": 75000001, "end": 83300000, "type": "gpos100" }, + { "id": "p13.1", "start": 73500001, "end": 75000000, "type": "gneg" }, + { "id": "p13.2", "start": 71500001, "end": 73500000, "type": "gpos50" }, + { "id": "p13.3", "start": 68600001, "end": 71500000, "type": "gneg" }, + { "id": "p14", "start": 64100001, "end": 68600000, "type": "gpos50" }, + { "id": "p15", "start": 61300001, "end": 64100000, "type": "gneg" }, + { "id": "p16.1", "start": 55000001, "end": 61300000, "type": "gpos100" }, + { "id": "p16.2", "start": 52900001, "end": 55000000, "type": "gneg" }, + { "id": "p16.3", "start": 47800001, "end": 52900000, "type": "gpos100" }, + { "id": "p21", "start": 41800001, "end": 47800000, "type": "gneg" }, + { "id": "p22.1", "start": 38600001, "end": 41800000, "type": "gpos50" }, + { "id": "p22.2", "start": 36600001, "end": 38600000, "type": "gneg" }, + { "id": "p22.3", "start": 32100001, "end": 36600000, "type": "gpos75" }, + { "id": "p23.1", "start": 30000001, "end": 32100000, "type": "gneg" }, + { "id": "p23.2", "start": 27900001, "end": 30000000, "type": "gpos25" }, + { "id": "p23.3", "start": 24000001, "end": 27900000, "type": "gneg" }, + { "id": "p24.1", "start": 19200001, "end": 24000000, "type": "gpos75" }, + { "id": "p24.2", "start": 16700001, "end": 19200000, "type": "gneg" }, + { "id": "p24.3", "start": 12200001, "end": 16700000, "type": "gpos75" }, + { "id": "p25.1", "start": 7100001, "end": 12200000, "type": "gneg" }, + { "id": "p25.2", "start": 4400001, "end": 7100000, "type": "gpos50" }, + { "id": "p25.3", "start": 1, "end": 4400000, "type": "gneg" }, + { "id": "q11.1", "start": 93300001, "end": 96800000, "type": "acen" }, + { "id": "q11.2", "start": 96800001, "end": 102700000, "type": "gneg" }, + { "id": "q12.1", "start": 102700001, "end": 106000000, "type": "gpos50" }, + { "id": "q12.2", "start": 106000001, "end": 107500000, "type": "gneg" }, + { "id": "q12.3", "start": 107500001, "end": 110200000, "type": "gpos25" }, + { "id": "q13", "start": 110200001, "end": 114400000, "type": "gneg" }, + { "id": "q14.1", "start": 114400001, "end": 118800000, "type": "gpos50" }, + { "id": "q14.2", "start": 118800001, "end": 122400000, "type": "gneg" }, + { "id": "q14.3", "start": 122400001, "end": 129900000, "type": "gpos50" }, + { "id": "q21.1", "start": 129900001, "end": 132500000, "type": "gneg" }, + { "id": "q21.2", "start": 132500001, "end": 135100000, "type": "gpos25" }, + { "id": "q21.3", "start": 135100001, "end": 136800000, "type": "gneg" }, + { "id": "q22.1", "start": 136800001, "end": 142200000, "type": "gpos100" }, + { "id": "q22.2", "start": 142200001, "end": 144100000, "type": "gneg" }, + { "id": "q22.3", "start": 144100001, "end": 148700000, "type": "gpos100" }, + { "id": "q23.1", "start": 148700001, "end": 149900000, "type": "gneg" }, + { "id": "q23.2", "start": 149900001, "end": 150500000, "type": "gpos25" }, + { "id": "q23.3", "start": 150500001, "end": 154900000, "type": "gneg" }, + { "id": "q24.1", "start": 154900001, "end": 159800000, "type": "gpos75" }, + { "id": "q24.2", "start": 159800001, "end": 163700000, "type": "gneg" }, + { "id": "q24.3", "start": 163700001, "end": 169700000, "type": "gpos75" }, + { "id": "q31.1", "start": 169700001, "end": 178000000, "type": "gneg" }, + { "id": "q31.2", "start": 178000001, "end": 180600000, "type": "gpos50" }, + { "id": "q31.3", "start": 180600001, "end": 183000000, "type": "gneg" }, + { "id": "q32.1", "start": 183000001, "end": 189400000, "type": "gpos75" }, + { "id": "q32.2", "start": 189400001, "end": 191900000, "type": "gneg" }, + { "id": "q32.3", "start": 191900001, "end": 197400000, "type": "gpos75" }, + { "id": "q33.1", "start": 197400001, "end": 203300000, "type": "gneg" }, + { "id": "q33.2", "start": 203300001, "end": 204900000, "type": "gpos50" }, + { "id": "q33.3", "start": 204900001, "end": 209000000, "type": "gneg" }, + { "id": "q34", "start": 209000001, "end": 215300000, "type": "gpos100" }, + { "id": "q35", "start": 215300001, "end": 221500000, "type": "gneg" }, + { "id": "q36.1", "start": 221500001, "end": 225200000, "type": "gpos75" }, + { "id": "q36.2", "start": 225200001, "end": 226100000, "type": "gneg" }, + { "id": "q36.3", "start": 226100001, "end": 231000000, "type": "gpos100" }, + { "id": "q37.1", "start": 231000001, "end": 235600000, "type": "gneg" }, + { "id": "q37.2", "start": 235600001, "end": 237300000, "type": "gpos50" }, + { "id": "q37.3", "start": 237300001, "end": 243199373, "type": "gneg" } ] }, "3": { - "size": 198022430, - "bands": [ - { - "id": "p11.1", - "start": 87900001, - "end": 91000000, - "type": "acen" - }, - { - "id": "p11.2", - "start": 87200001, - "end": 87900000, - "type": "gneg" - }, - { - "id": "p12.1", - "start": 83500001, - "end": 87200000, - "type": "gpos75" - }, - { - "id": "p12.2", - "start": 79800001, - "end": 83500000, - "type": "gneg" - }, - { - "id": "p12.3", - "start": 74200001, - "end": 79800000, - "type": "gpos75" - }, - { - "id": "p13", - "start": 69800001, - "end": 74200000, - "type": "gneg" - }, - { - "id": "p14.1", - "start": 63700001, - "end": 69800000, - "type": "gpos50" - }, - { - "id": "p14.2", - "start": 58600001, - "end": 63700000, - "type": "gneg" - }, - { - "id": "p14.3", - "start": 54400001, - "end": 58600000, - "type": "gpos50" - }, - { - "id": "p21.1", - "start": 52300001, - "end": 54400000, - "type": "gneg" - }, - { - "id": "p21.2", - "start": 50600001, - "end": 52300000, - "type": "gpos25" - }, - { - "id": "p21.31", - "start": 44200001, - "end": 50600000, - "type": "gneg" - }, - { - "id": "p21.32", - "start": 44100001, - "end": 44200000, - "type": "gpos50" - }, - { - "id": "p21.33", - "start": 43700001, - "end": 44100000, - "type": "gneg" - }, - { - "id": "p22.1", - "start": 39400001, - "end": 43700000, - "type": "gpos75" - }, - { - "id": "p22.2", - "start": 36500001, - "end": 39400000, - "type": "gneg" - }, - { - "id": "p22.3", - "start": 32100001, - "end": 36500000, - "type": "gpos50" - }, - { - "id": "p23", - "start": 30900001, - "end": 32100000, - "type": "gneg" - }, - { - "id": "p24.1", - "start": 26400001, - "end": 30900000, - "type": "gpos75" - }, - { - "id": "p24.2", - "start": 23900001, - "end": 26400000, - "type": "gneg" - }, - { - "id": "p24.3", - "start": 16400001, - "end": 23900000, - "type": "gpos100" - }, - { - "id": "p25.1", - "start": 13300001, - "end": 16400000, - "type": "gneg" - }, - { - "id": "p25.2", - "start": 11800001, - "end": 13300000, - "type": "gpos25" - }, - { - "id": "p25.3", - "start": 8700001, - "end": 11800000, - "type": "gneg" - }, - { - "id": "p26.1", - "start": 4000001, - "end": 8700000, - "type": "gpos50" - }, - { - "id": "p26.2", - "start": 2800001, - "end": 4000000, - "type": "gneg" - }, - { - "id": "p26.3", - "start": 1, - "end": 2800000, - "type": "gpos50" - }, - { - "id": "q11.1", - "start": 91000001, - "end": 93900000, - "type": "acen" - }, - { - "id": "q11.2", - "start": 93900001, - "end": 98300000, - "type": "gvar" - }, - { - "id": "q12.1", - "start": 98300001, - "end": 100000000, - "type": "gneg" - }, - { - "id": "q12.2", - "start": 100000001, - "end": 100900000, - "type": "gpos25" - }, - { - "id": "q12.3", - "start": 100900001, - "end": 102800000, - "type": "gneg" - }, - { - "id": "q13.11", - "start": 102800001, - "end": 106200000, - "type": "gpos75" - }, - { - "id": "q13.12", - "start": 106200001, - "end": 107900000, - "type": "gneg" - }, - { - "id": "q13.13", - "start": 107900001, - "end": 111300000, - "type": "gpos50" - }, - { - "id": "q13.2", - "start": 111300001, - "end": 113500000, - "type": "gneg" - }, - { - "id": "q13.31", - "start": 113500001, - "end": 117300000, - "type": "gpos75" - }, - { - "id": "q13.32", - "start": 117300001, - "end": 119000000, - "type": "gneg" - }, - { - "id": "q13.33", - "start": 119000001, - "end": 121900000, - "type": "gpos75" - }, - { - "id": "q21.1", - "start": 121900001, - "end": 123800000, - "type": "gneg" - }, - { - "id": "q21.2", - "start": 123800001, - "end": 125800000, - "type": "gpos25" - }, - { - "id": "q21.3", - "start": 125800001, - "end": 129200000, - "type": "gneg" - }, - { - "id": "q22.1", - "start": 129200001, - "end": 133700000, - "type": "gpos25" - }, - { - "id": "q22.2", - "start": 133700001, - "end": 135700000, - "type": "gneg" - }, - { - "id": "q22.3", - "start": 135700001, - "end": 138700000, - "type": "gpos25" - }, - { - "id": "q23", - "start": 138700001, - "end": 142800000, - "type": "gneg" - }, - { - "id": "q24", - "start": 142800001, - "end": 148900000, - "type": "gpos100" - }, - { - "id": "q25.1", - "start": 148900001, - "end": 152100000, - "type": "gneg" - }, - { - "id": "q25.2", - "start": 152100001, - "end": 155000000, - "type": "gpos50" - }, - { - "id": "q25.31", - "start": 155000001, - "end": 157000000, - "type": "gneg" - }, - { - "id": "q25.32", - "start": 157000001, - "end": 159000000, - "type": "gpos50" - }, - { - "id": "q25.33", - "start": 159000001, - "end": 160700000, - "type": "gneg" - }, - { - "id": "q26.1", - "start": 160700001, - "end": 167600000, - "type": "gpos100" - }, - { - "id": "q26.2", - "start": 167600001, - "end": 170900000, - "type": "gneg" - }, - { - "id": "q26.31", - "start": 170900001, - "end": 175700000, - "type": "gpos75" - }, - { - "id": "q26.32", - "start": 175700001, - "end": 179000000, - "type": "gneg" - }, - { - "id": "q26.33", - "start": 179000001, - "end": 182700000, - "type": "gpos75" - }, - { - "id": "q27.1", - "start": 182700001, - "end": 184500000, - "type": "gneg" - }, - { - "id": "q27.2", - "start": 184500001, - "end": 186000000, - "type": "gpos25" - }, - { - "id": "q27.3", - "start": 186000001, - "end": 187900000, - "type": "gneg" - }, - { - "id": "q28", - "start": 187900001, - "end": 192300000, - "type": "gpos75" - }, - { - "id": "q29", - "start": 192300001, - "end": 198022430, - "type": "gneg" - } + "size" : 198022430, + "bands" : [ + { "id": "p11.1", "start": 87900001, "end": 91000000, "type": "acen" }, + { "id": "p11.2", "start": 87200001, "end": 87900000, "type": "gneg" }, + { "id": "p12.1", "start": 83500001, "end": 87200000, "type": "gpos75" }, + { "id": "p12.2", "start": 79800001, "end": 83500000, "type": "gneg" }, + { "id": "p12.3", "start": 74200001, "end": 79800000, "type": "gpos75" }, + { "id": "p13", "start": 69800001, "end": 74200000, "type": "gneg" }, + { "id": "p14.1", "start": 63700001, "end": 69800000, "type": "gpos50" }, + { "id": "p14.2", "start": 58600001, "end": 63700000, "type": "gneg" }, + { "id": "p14.3", "start": 54400001, "end": 58600000, "type": "gpos50" }, + { "id": "p21.1", "start": 52300001, "end": 54400000, "type": "gneg" }, + { "id": "p21.2", "start": 50600001, "end": 52300000, "type": "gpos25" }, + { "id": "p21.31", "start": 44200001, "end": 50600000, "type": "gneg" }, + { "id": "p21.32", "start": 44100001, "end": 44200000, "type": "gpos50" }, + { "id": "p21.33", "start": 43700001, "end": 44100000, "type": "gneg" }, + { "id": "p22.1", "start": 39400001, "end": 43700000, "type": "gpos75" }, + { "id": "p22.2", "start": 36500001, "end": 39400000, "type": "gneg" }, + { "id": "p22.3", "start": 32100001, "end": 36500000, "type": "gpos50" }, + { "id": "p23", "start": 30900001, "end": 32100000, "type": "gneg" }, + { "id": "p24.1", "start": 26400001, "end": 30900000, "type": "gpos75" }, + { "id": "p24.2", "start": 23900001, "end": 26400000, "type": "gneg" }, + { "id": "p24.3", "start": 16400001, "end": 23900000, "type": "gpos100" }, + { "id": "p25.1", "start": 13300001, "end": 16400000, "type": "gneg" }, + { "id": "p25.2", "start": 11800001, "end": 13300000, "type": "gpos25" }, + { "id": "p25.3", "start": 8700001, "end": 11800000, "type": "gneg" }, + { "id": "p26.1", "start": 4000001, "end": 8700000, "type": "gpos50" }, + { "id": "p26.2", "start": 2800001, "end": 4000000, "type": "gneg" }, + { "id": "p26.3", "start": 1, "end": 2800000, "type": "gpos50" }, + { "id": "q11.1", "start": 91000001, "end": 93900000, "type": "acen" }, + { "id": "q11.2", "start": 93900001, "end": 98300000, "type": "gvar" }, + { "id": "q12.1", "start": 98300001, "end": 100000000, "type": "gneg" }, + { "id": "q12.2", "start": 100000001, "end": 100900000, "type": "gpos25" }, + { "id": "q12.3", "start": 100900001, "end": 102800000, "type": "gneg" }, + { "id": "q13.11", "start": 102800001, "end": 106200000, "type": "gpos75" }, + { "id": "q13.12", "start": 106200001, "end": 107900000, "type": "gneg" }, + { "id": "q13.13", "start": 107900001, "end": 111300000, "type": "gpos50" }, + { "id": "q13.2", "start": 111300001, "end": 113500000, "type": "gneg" }, + { "id": "q13.31", "start": 113500001, "end": 117300000, "type": "gpos75" }, + { "id": "q13.32", "start": 117300001, "end": 119000000, "type": "gneg" }, + { "id": "q13.33", "start": 119000001, "end": 121900000, "type": "gpos75" }, + { "id": "q21.1", "start": 121900001, "end": 123800000, "type": "gneg" }, + { "id": "q21.2", "start": 123800001, "end": 125800000, "type": "gpos25" }, + { "id": "q21.3", "start": 125800001, "end": 129200000, "type": "gneg" }, + { "id": "q22.1", "start": 129200001, "end": 133700000, "type": "gpos25" }, + { "id": "q22.2", "start": 133700001, "end": 135700000, "type": "gneg" }, + { "id": "q22.3", "start": 135700001, "end": 138700000, "type": "gpos25" }, + { "id": "q23", "start": 138700001, "end": 142800000, "type": "gneg" }, + { "id": "q24", "start": 142800001, "end": 148900000, "type": "gpos100" }, + { "id": "q25.1", "start": 148900001, "end": 152100000, "type": "gneg" }, + { "id": "q25.2", "start": 152100001, "end": 155000000, "type": "gpos50" }, + { "id": "q25.31", "start": 155000001, "end": 157000000, "type": "gneg" }, + { "id": "q25.32", "start": 157000001, "end": 159000000, "type": "gpos50" }, + { "id": "q25.33", "start": 159000001, "end": 160700000, "type": "gneg" }, + { "id": "q26.1", "start": 160700001, "end": 167600000, "type": "gpos100" }, + { "id": "q26.2", "start": 167600001, "end": 170900000, "type": "gneg" }, + { "id": "q26.31", "start": 170900001, "end": 175700000, "type": "gpos75" }, + { "id": "q26.32", "start": 175700001, "end": 179000000, "type": "gneg" }, + { "id": "q26.33", "start": 179000001, "end": 182700000, "type": "gpos75" }, + { "id": "q27.1", "start": 182700001, "end": 184500000, "type": "gneg" }, + { "id": "q27.2", "start": 184500001, "end": 186000000, "type": "gpos25" }, + { "id": "q27.3", "start": 186000001, "end": 187900000, "type": "gneg" }, + { "id": "q28", "start": 187900001, "end": 192300000, "type": "gpos75" }, + { "id": "q29", "start": 192300001, "end": 198022430, "type": "gneg" } ] }, "4": { - "size": 191154276, - "bands": [ - { - "id": "p11", - "start": 48200001, - "end": 50400000, - "type": "acen" - }, - { - "id": "p12", - "start": 44600001, - "end": 48200000, - "type": "gneg" - }, - { - "id": "p13", - "start": 41200001, - "end": 44600000, - "type": "gpos50" - }, - { - "id": "p14", - "start": 35800001, - "end": 41200000, - "type": "gneg" - }, - { - "id": "p15.1", - "start": 27700001, - "end": 35800000, - "type": "gpos100" - }, - { - "id": "p15.2", - "start": 21300001, - "end": 27700000, - "type": "gneg" - }, - { - "id": "p15.31", - "start": 17800001, - "end": 21300000, - "type": "gpos75" - }, - { - "id": "p15.32", - "start": 15200001, - "end": 17800000, - "type": "gneg" - }, - { - "id": "p15.33", - "start": 11300001, - "end": 15200000, - "type": "gpos50" - }, - { - "id": "p16.1", - "start": 6000001, - "end": 11300000, - "type": "gneg" - }, - { - "id": "p16.2", - "start": 4500001, - "end": 6000000, - "type": "gpos25" - }, - { - "id": "p16.3", - "start": 1, - "end": 4500000, - "type": "gneg" - }, - { - "id": "q11", - "start": 50400001, - "end": 52700000, - "type": "acen" - }, - { - "id": "q12", - "start": 52700001, - "end": 59500000, - "type": "gneg" - }, - { - "id": "q13.1", - "start": 59500001, - "end": 66600000, - "type": "gpos100" - }, - { - "id": "q13.2", - "start": 66600001, - "end": 70500000, - "type": "gneg" - }, - { - "id": "q13.3", - "start": 70500001, - "end": 76300000, - "type": "gpos75" - }, - { - "id": "q21.1", - "start": 76300001, - "end": 78900000, - "type": "gneg" - }, - { - "id": "q21.21", - "start": 78900001, - "end": 82400000, - "type": "gpos50" - }, - { - "id": "q21.22", - "start": 82400001, - "end": 84100000, - "type": "gneg" - }, - { - "id": "q21.23", - "start": 84100001, - "end": 86900000, - "type": "gpos25" - }, - { - "id": "q21.3", - "start": 86900001, - "end": 88000000, - "type": "gneg" - }, - { - "id": "q22.1", - "start": 88000001, - "end": 93700000, - "type": "gpos75" - }, - { - "id": "q22.2", - "start": 93700001, - "end": 95100000, - "type": "gneg" - }, - { - "id": "q22.3", - "start": 95100001, - "end": 98800000, - "type": "gpos75" - }, - { - "id": "q23", - "start": 98800001, - "end": 101100000, - "type": "gneg" - }, - { - "id": "q24", - "start": 101100001, - "end": 107700000, - "type": "gpos50" - }, - { - "id": "q25", - "start": 107700001, - "end": 114100000, - "type": "gneg" - }, - { - "id": "q26", - "start": 114100001, - "end": 120800000, - "type": "gpos75" - }, - { - "id": "q27", - "start": 120800001, - "end": 123800000, - "type": "gneg" - }, - { - "id": "q28.1", - "start": 123800001, - "end": 128800000, - "type": "gpos50" - }, - { - "id": "q28.2", - "start": 128800001, - "end": 131100000, - "type": "gneg" - }, - { - "id": "q28.3", - "start": 131100001, - "end": 139500000, - "type": "gpos100" - }, - { - "id": "q31.1", - "start": 139500001, - "end": 141500000, - "type": "gneg" - }, - { - "id": "q31.21", - "start": 141500001, - "end": 146800000, - "type": "gpos25" - }, - { - "id": "q31.22", - "start": 146800001, - "end": 148500000, - "type": "gneg" - }, - { - "id": "q31.23", - "start": 148500001, - "end": 151100000, - "type": "gpos25" - }, - { - "id": "q31.3", - "start": 151100001, - "end": 155600000, - "type": "gneg" - }, - { - "id": "q32.1", - "start": 155600001, - "end": 161800000, - "type": "gpos100" - }, - { - "id": "q32.2", - "start": 161800001, - "end": 164500000, - "type": "gneg" - }, - { - "id": "q32.3", - "start": 164500001, - "end": 170100000, - "type": "gpos100" - }, - { - "id": "q33", - "start": 170100001, - "end": 171900000, - "type": "gneg" - }, - { - "id": "q34.1", - "start": 171900001, - "end": 176300000, - "type": "gpos75" - }, - { - "id": "q34.2", - "start": 176300001, - "end": 177500000, - "type": "gneg" - }, - { - "id": "q34.3", - "start": 177500001, - "end": 183200000, - "type": "gpos100" - }, - { - "id": "q35.1", - "start": 183200001, - "end": 187100000, - "type": "gneg" - }, - { - "id": "q35.2", - "start": 187100001, - "end": 191154276, - "type": "gpos25" - } + "size" : 191154276, + "bands" : [ + { "id": "p11", "start": 48200001, "end": 50400000, "type": "acen" }, + { "id": "p12", "start": 44600001, "end": 48200000, "type": "gneg" }, + { "id": "p13", "start": 41200001, "end": 44600000, "type": "gpos50" }, + { "id": "p14", "start": 35800001, "end": 41200000, "type": "gneg" }, + { "id": "p15.1", "start": 27700001, "end": 35800000, "type": "gpos100" }, + { "id": "p15.2", "start": 21300001, "end": 27700000, "type": "gneg" }, + { "id": "p15.31", "start": 17800001, "end": 21300000, "type": "gpos75" }, + { "id": "p15.32", "start": 15200001, "end": 17800000, "type": "gneg" }, + { "id": "p15.33", "start": 11300001, "end": 15200000, "type": "gpos50" }, + { "id": "p16.1", "start": 6000001, "end": 11300000, "type": "gneg" }, + { "id": "p16.2", "start": 4500001, "end": 6000000, "type": "gpos25" }, + { "id": "p16.3", "start": 1, "end": 4500000, "type": "gneg" }, + { "id": "q11", "start": 50400001, "end": 52700000, "type": "acen" }, + { "id": "q12", "start": 52700001, "end": 59500000, "type": "gneg" }, + { "id": "q13.1", "start": 59500001, "end": 66600000, "type": "gpos100" }, + { "id": "q13.2", "start": 66600001, "end": 70500000, "type": "gneg" }, + { "id": "q13.3", "start": 70500001, "end": 76300000, "type": "gpos75" }, + { "id": "q21.1", "start": 76300001, "end": 78900000, "type": "gneg" }, + { "id": "q21.21", "start": 78900001, "end": 82400000, "type": "gpos50" }, + { "id": "q21.22", "start": 82400001, "end": 84100000, "type": "gneg" }, + { "id": "q21.23", "start": 84100001, "end": 86900000, "type": "gpos25" }, + { "id": "q21.3", "start": 86900001, "end": 88000000, "type": "gneg" }, + { "id": "q22.1", "start": 88000001, "end": 93700000, "type": "gpos75" }, + { "id": "q22.2", "start": 93700001, "end": 95100000, "type": "gneg" }, + { "id": "q22.3", "start": 95100001, "end": 98800000, "type": "gpos75" }, + { "id": "q23", "start": 98800001, "end": 101100000, "type": "gneg" }, + { "id": "q24", "start": 101100001, "end": 107700000, "type": "gpos50" }, + { "id": "q25", "start": 107700001, "end": 114100000, "type": "gneg" }, + { "id": "q26", "start": 114100001, "end": 120800000, "type": "gpos75" }, + { "id": "q27", "start": 120800001, "end": 123800000, "type": "gneg" }, + { "id": "q28.1", "start": 123800001, "end": 128800000, "type": "gpos50" }, + { "id": "q28.2", "start": 128800001, "end": 131100000, "type": "gneg" }, + { "id": "q28.3", "start": 131100001, "end": 139500000, "type": "gpos100" }, + { "id": "q31.1", "start": 139500001, "end": 141500000, "type": "gneg" }, + { "id": "q31.21", "start": 141500001, "end": 146800000, "type": "gpos25" }, + { "id": "q31.22", "start": 146800001, "end": 148500000, "type": "gneg" }, + { "id": "q31.23", "start": 148500001, "end": 151100000, "type": "gpos25" }, + { "id": "q31.3", "start": 151100001, "end": 155600000, "type": "gneg" }, + { "id": "q32.1", "start": 155600001, "end": 161800000, "type": "gpos100" }, + { "id": "q32.2", "start": 161800001, "end": 164500000, "type": "gneg" }, + { "id": "q32.3", "start": 164500001, "end": 170100000, "type": "gpos100" }, + { "id": "q33", "start": 170100001, "end": 171900000, "type": "gneg" }, + { "id": "q34.1", "start": 171900001, "end": 176300000, "type": "gpos75" }, + { "id": "q34.2", "start": 176300001, "end": 177500000, "type": "gneg" }, + { "id": "q34.3", "start": 177500001, "end": 183200000, "type": "gpos100" }, + { "id": "q35.1", "start": 183200001, "end": 187100000, "type": "gneg" }, + { "id": "q35.2", "start": 187100001, "end": 191154276, "type": "gpos25" } ] }, "5": { - "size": 180915260, - "bands": [ - { - "id": "p11", - "start": 46100001, - "end": 48400000, - "type": "acen" - }, - { - "id": "p12", - "start": 42500001, - "end": 46100000, - "type": "gpos50" - }, - { - "id": "p13.1", - "start": 38400001, - "end": 42500000, - "type": "gneg" - }, - { - "id": "p13.2", - "start": 33800001, - "end": 38400000, - "type": "gpos25" - }, - { - "id": "p13.3", - "start": 28900001, - "end": 33800000, - "type": "gneg" - }, - { - "id": "p14.1", - "start": 24600001, - "end": 28900000, - "type": "gpos100" - }, - { - "id": "p14.2", - "start": 23300001, - "end": 24600000, - "type": "gneg" - }, - { - "id": "p14.3", - "start": 18400001, - "end": 23300000, - "type": "gpos100" - }, - { - "id": "p15.1", - "start": 15000001, - "end": 18400000, - "type": "gneg" - }, - { - "id": "p15.2", - "start": 9800001, - "end": 15000000, - "type": "gpos50" - }, - { - "id": "p15.31", - "start": 6300001, - "end": 9800000, - "type": "gneg" - }, - { - "id": "p15.32", - "start": 4500001, - "end": 6300000, - "type": "gpos25" - }, - { - "id": "p15.33", - "start": 1, - "end": 4500000, - "type": "gneg" - }, - { - "id": "q11.1", - "start": 48400001, - "end": 50700000, - "type": "acen" - }, - { - "id": "q11.2", - "start": 50700001, - "end": 58900000, - "type": "gneg" - }, - { - "id": "q12.1", - "start": 58900001, - "end": 62900000, - "type": "gpos75" - }, - { - "id": "q12.2", - "start": 62900001, - "end": 63200000, - "type": "gneg" - }, - { - "id": "q12.3", - "start": 63200001, - "end": 66700000, - "type": "gpos75" - }, - { - "id": "q13.1", - "start": 66700001, - "end": 68400000, - "type": "gneg" - }, - { - "id": "q13.2", - "start": 68400001, - "end": 73300000, - "type": "gpos50" - }, - { - "id": "q13.3", - "start": 73300001, - "end": 76900000, - "type": "gneg" - }, - { - "id": "q14.1", - "start": 76900001, - "end": 81400000, - "type": "gpos50" - }, - { - "id": "q14.2", - "start": 81400001, - "end": 82800000, - "type": "gneg" - }, - { - "id": "q14.3", - "start": 82800001, - "end": 92300000, - "type": "gpos100" - }, - { - "id": "q15", - "start": 92300001, - "end": 98200000, - "type": "gneg" - }, - { - "id": "q21.1", - "start": 98200001, - "end": 102800000, - "type": "gpos100" - }, - { - "id": "q21.2", - "start": 102800001, - "end": 104500000, - "type": "gneg" - }, - { - "id": "q21.3", - "start": 104500001, - "end": 109600000, - "type": "gpos100" - }, - { - "id": "q22.1", - "start": 109600001, - "end": 111500000, - "type": "gneg" - }, - { - "id": "q22.2", - "start": 111500001, - "end": 113100000, - "type": "gpos50" - }, - { - "id": "q22.3", - "start": 113100001, - "end": 115200000, - "type": "gneg" - }, - { - "id": "q23.1", - "start": 115200001, - "end": 121400000, - "type": "gpos100" - }, - { - "id": "q23.2", - "start": 121400001, - "end": 127300000, - "type": "gneg" - }, - { - "id": "q23.3", - "start": 127300001, - "end": 130600000, - "type": "gpos100" - }, - { - "id": "q31.1", - "start": 130600001, - "end": 136200000, - "type": "gneg" - }, - { - "id": "q31.2", - "start": 136200001, - "end": 139500000, - "type": "gpos25" - }, - { - "id": "q31.3", - "start": 139500001, - "end": 144500000, - "type": "gneg" - }, - { - "id": "q32", - "start": 144500001, - "end": 149800000, - "type": "gpos75" - }, - { - "id": "q33.1", - "start": 149800001, - "end": 152700000, - "type": "gneg" - }, - { - "id": "q33.2", - "start": 152700001, - "end": 155700000, - "type": "gpos50" - }, - { - "id": "q33.3", - "start": 155700001, - "end": 159900000, - "type": "gneg" - }, - { - "id": "q34", - "start": 159900001, - "end": 168500000, - "type": "gpos100" - }, - { - "id": "q35.1", - "start": 168500001, - "end": 172800000, - "type": "gneg" - }, - { - "id": "q35.2", - "start": 172800001, - "end": 176600000, - "type": "gpos25" - }, - { - "id": "q35.3", - "start": 176600001, - "end": 180915260, - "type": "gneg" - } + "size" : 180915260, + "bands" : [ + { "id": "p11", "start": 46100001, "end": 48400000, "type": "acen" }, + { "id": "p12", "start": 42500001, "end": 46100000, "type": "gpos50" }, + { "id": "p13.1", "start": 38400001, "end": 42500000, "type": "gneg" }, + { "id": "p13.2", "start": 33800001, "end": 38400000, "type": "gpos25" }, + { "id": "p13.3", "start": 28900001, "end": 33800000, "type": "gneg" }, + { "id": "p14.1", "start": 24600001, "end": 28900000, "type": "gpos100" }, + { "id": "p14.2", "start": 23300001, "end": 24600000, "type": "gneg" }, + { "id": "p14.3", "start": 18400001, "end": 23300000, "type": "gpos100" }, + { "id": "p15.1", "start": 15000001, "end": 18400000, "type": "gneg" }, + { "id": "p15.2", "start": 9800001, "end": 15000000, "type": "gpos50" }, + { "id": "p15.31", "start": 6300001, "end": 9800000, "type": "gneg" }, + { "id": "p15.32", "start": 4500001, "end": 6300000, "type": "gpos25" }, + { "id": "p15.33", "start": 1, "end": 4500000, "type": "gneg" }, + { "id": "q11.1", "start": 48400001, "end": 50700000, "type": "acen" }, + { "id": "q11.2", "start": 50700001, "end": 58900000, "type": "gneg" }, + { "id": "q12.1", "start": 58900001, "end": 62900000, "type": "gpos75" }, + { "id": "q12.2", "start": 62900001, "end": 63200000, "type": "gneg" }, + { "id": "q12.3", "start": 63200001, "end": 66700000, "type": "gpos75" }, + { "id": "q13.1", "start": 66700001, "end": 68400000, "type": "gneg" }, + { "id": "q13.2", "start": 68400001, "end": 73300000, "type": "gpos50" }, + { "id": "q13.3", "start": 73300001, "end": 76900000, "type": "gneg" }, + { "id": "q14.1", "start": 76900001, "end": 81400000, "type": "gpos50" }, + { "id": "q14.2", "start": 81400001, "end": 82800000, "type": "gneg" }, + { "id": "q14.3", "start": 82800001, "end": 92300000, "type": "gpos100" }, + { "id": "q15", "start": 92300001, "end": 98200000, "type": "gneg" }, + { "id": "q21.1", "start": 98200001, "end": 102800000, "type": "gpos100" }, + { "id": "q21.2", "start": 102800001, "end": 104500000, "type": "gneg" }, + { "id": "q21.3", "start": 104500001, "end": 109600000, "type": "gpos100" }, + { "id": "q22.1", "start": 109600001, "end": 111500000, "type": "gneg" }, + { "id": "q22.2", "start": 111500001, "end": 113100000, "type": "gpos50" }, + { "id": "q22.3", "start": 113100001, "end": 115200000, "type": "gneg" }, + { "id": "q23.1", "start": 115200001, "end": 121400000, "type": "gpos100" }, + { "id": "q23.2", "start": 121400001, "end": 127300000, "type": "gneg" }, + { "id": "q23.3", "start": 127300001, "end": 130600000, "type": "gpos100" }, + { "id": "q31.1", "start": 130600001, "end": 136200000, "type": "gneg" }, + { "id": "q31.2", "start": 136200001, "end": 139500000, "type": "gpos25" }, + { "id": "q31.3", "start": 139500001, "end": 144500000, "type": "gneg" }, + { "id": "q32", "start": 144500001, "end": 149800000, "type": "gpos75" }, + { "id": "q33.1", "start": 149800001, "end": 152700000, "type": "gneg" }, + { "id": "q33.2", "start": 152700001, "end": 155700000, "type": "gpos50" }, + { "id": "q33.3", "start": 155700001, "end": 159900000, "type": "gneg" }, + { "id": "q34", "start": 159900001, "end": 168500000, "type": "gpos100" }, + { "id": "q35.1", "start": 168500001, "end": 172800000, "type": "gneg" }, + { "id": "q35.2", "start": 172800001, "end": 176600000, "type": "gpos25" }, + { "id": "q35.3", "start": 176600001, "end": 180915260, "type": "gneg" } ] }, "6": { - "size": 171115067, - "bands": [ - { - "id": "p11.1", - "start": 58700001, - "end": 61000000, - "type": "acen" - }, - { - "id": "p11.2", - "start": 57000001, - "end": 58700000, - "type": "gneg" - }, - { - "id": "p12.1", - "start": 52900001, - "end": 57000000, - "type": "gpos100" - }, - { - "id": "p12.2", - "start": 51800001, - "end": 52900000, - "type": "gneg" - }, - { - "id": "p12.3", - "start": 46200001, - "end": 51800000, - "type": "gpos100" - }, - { - "id": "p21.1", - "start": 40500001, - "end": 46200000, - "type": "gneg" - }, - { - "id": "p21.2", - "start": 36600001, - "end": 40500000, - "type": "gpos25" - }, - { - "id": "p21.31", - "start": 33500001, - "end": 36600000, - "type": "gneg" - }, - { - "id": "p21.32", - "start": 32100001, - "end": 33500000, - "type": "gpos25" - }, - { - "id": "p21.33", - "start": 30400001, - "end": 32100000, - "type": "gneg" - }, - { - "id": "p22.1", - "start": 27000001, - "end": 30400000, - "type": "gpos50" - }, - { - "id": "p22.2", - "start": 25200001, - "end": 27000000, - "type": "gneg" - }, - { - "id": "p22.3", - "start": 15200001, - "end": 25200000, - "type": "gpos75" - }, - { - "id": "p23", - "start": 13400001, - "end": 15200000, - "type": "gneg" - }, - { - "id": "p24.1", - "start": 11600001, - "end": 13400000, - "type": "gpos25" - }, - { - "id": "p24.2", - "start": 10600001, - "end": 11600000, - "type": "gneg" - }, - { - "id": "p24.3", - "start": 7100001, - "end": 10600000, - "type": "gpos50" - }, - { - "id": "p25.1", - "start": 4200001, - "end": 7100000, - "type": "gneg" - }, - { - "id": "p25.2", - "start": 2300001, - "end": 4200000, - "type": "gpos25" - }, - { - "id": "p25.3", - "start": 1, - "end": 2300000, - "type": "gneg" - }, - { - "id": "q11.1", - "start": 61000001, - "end": 63300000, - "type": "acen" - }, - { - "id": "q11.2", - "start": 63300001, - "end": 63400000, - "type": "gneg" - }, - { - "id": "q12", - "start": 63400001, - "end": 70000000, - "type": "gpos100" - }, - { - "id": "q13", - "start": 70000001, - "end": 75900000, - "type": "gneg" - }, - { - "id": "q14.1", - "start": 75900001, - "end": 83900000, - "type": "gpos50" - }, - { - "id": "q14.2", - "start": 83900001, - "end": 84900000, - "type": "gneg" - }, - { - "id": "q14.3", - "start": 84900001, - "end": 88000000, - "type": "gpos50" - }, - { - "id": "q15", - "start": 88000001, - "end": 93100000, - "type": "gneg" - }, - { - "id": "q16.1", - "start": 93100001, - "end": 99500000, - "type": "gpos100" - }, - { - "id": "q16.2", - "start": 99500001, - "end": 100600000, - "type": "gneg" - }, - { - "id": "q16.3", - "start": 100600001, - "end": 105500000, - "type": "gpos100" - }, - { - "id": "q21", - "start": 105500001, - "end": 114600000, - "type": "gneg" - }, - { - "id": "q22.1", - "start": 114600001, - "end": 118300000, - "type": "gpos75" - }, - { - "id": "q22.2", - "start": 118300001, - "end": 118500000, - "type": "gneg" - }, - { - "id": "q22.31", - "start": 118500001, - "end": 126100000, - "type": "gpos100" - }, - { - "id": "q22.32", - "start": 126100001, - "end": 127100000, - "type": "gneg" - }, - { - "id": "q22.33", - "start": 127100001, - "end": 130300000, - "type": "gpos75" - }, - { - "id": "q23.1", - "start": 130300001, - "end": 131200000, - "type": "gneg" - }, - { - "id": "q23.2", - "start": 131200001, - "end": 135200000, - "type": "gpos50" - }, - { - "id": "q23.3", - "start": 135200001, - "end": 139000000, - "type": "gneg" - }, - { - "id": "q24.1", - "start": 139000001, - "end": 142800000, - "type": "gpos75" - }, - { - "id": "q24.2", - "start": 142800001, - "end": 145600000, - "type": "gneg" - }, - { - "id": "q24.3", - "start": 145600001, - "end": 149000000, - "type": "gpos75" - }, - { - "id": "q25.1", - "start": 149000001, - "end": 152500000, - "type": "gneg" - }, - { - "id": "q25.2", - "start": 152500001, - "end": 155500000, - "type": "gpos50" - }, - { - "id": "q25.3", - "start": 155500001, - "end": 161000000, - "type": "gneg" - }, - { - "id": "q26", - "start": 161000001, - "end": 164500000, - "type": "gpos50" - }, - { - "id": "q27", - "start": 164500001, - "end": 171115067, - "type": "gneg" - } + "size" : 171115067, + "bands" : [ + { "id": "p11.1", "start": 58700001, "end": 61000000, "type": "acen" }, + { "id": "p11.2", "start": 57000001, "end": 58700000, "type": "gneg" }, + { "id": "p12.1", "start": 52900001, "end": 57000000, "type": "gpos100" }, + { "id": "p12.2", "start": 51800001, "end": 52900000, "type": "gneg" }, + { "id": "p12.3", "start": 46200001, "end": 51800000, "type": "gpos100" }, + { "id": "p21.1", "start": 40500001, "end": 46200000, "type": "gneg" }, + { "id": "p21.2", "start": 36600001, "end": 40500000, "type": "gpos25" }, + { "id": "p21.31", "start": 33500001, "end": 36600000, "type": "gneg" }, + { "id": "p21.32", "start": 32100001, "end": 33500000, "type": "gpos25" }, + { "id": "p21.33", "start": 30400001, "end": 32100000, "type": "gneg" }, + { "id": "p22.1", "start": 27000001, "end": 30400000, "type": "gpos50" }, + { "id": "p22.2", "start": 25200001, "end": 27000000, "type": "gneg" }, + { "id": "p22.3", "start": 15200001, "end": 25200000, "type": "gpos75" }, + { "id": "p23", "start": 13400001, "end": 15200000, "type": "gneg" }, + { "id": "p24.1", "start": 11600001, "end": 13400000, "type": "gpos25" }, + { "id": "p24.2", "start": 10600001, "end": 11600000, "type": "gneg" }, + { "id": "p24.3", "start": 7100001, "end": 10600000, "type": "gpos50" }, + { "id": "p25.1", "start": 4200001, "end": 7100000, "type": "gneg" }, + { "id": "p25.2", "start": 2300001, "end": 4200000, "type": "gpos25" }, + { "id": "p25.3", "start": 1, "end": 2300000, "type": "gneg" }, + { "id": "q11.1", "start": 61000001, "end": 63300000, "type": "acen" }, + { "id": "q11.2", "start": 63300001, "end": 63400000, "type": "gneg" }, + { "id": "q12", "start": 63400001, "end": 70000000, "type": "gpos100" }, + { "id": "q13", "start": 70000001, "end": 75900000, "type": "gneg" }, + { "id": "q14.1", "start": 75900001, "end": 83900000, "type": "gpos50" }, + { "id": "q14.2", "start": 83900001, "end": 84900000, "type": "gneg" }, + { "id": "q14.3", "start": 84900001, "end": 88000000, "type": "gpos50" }, + { "id": "q15", "start": 88000001, "end": 93100000, "type": "gneg" }, + { "id": "q16.1", "start": 93100001, "end": 99500000, "type": "gpos100" }, + { "id": "q16.2", "start": 99500001, "end": 100600000, "type": "gneg" }, + { "id": "q16.3", "start": 100600001, "end": 105500000, "type": "gpos100" }, + { "id": "q21", "start": 105500001, "end": 114600000, "type": "gneg" }, + { "id": "q22.1", "start": 114600001, "end": 118300000, "type": "gpos75" }, + { "id": "q22.2", "start": 118300001, "end": 118500000, "type": "gneg" }, + { "id": "q22.31", "start": 118500001, "end": 126100000, "type": "gpos100" }, + { "id": "q22.32", "start": 126100001, "end": 127100000, "type": "gneg" }, + { "id": "q22.33", "start": 127100001, "end": 130300000, "type": "gpos75" }, + { "id": "q23.1", "start": 130300001, "end": 131200000, "type": "gneg" }, + { "id": "q23.2", "start": 131200001, "end": 135200000, "type": "gpos50" }, + { "id": "q23.3", "start": 135200001, "end": 139000000, "type": "gneg" }, + { "id": "q24.1", "start": 139000001, "end": 142800000, "type": "gpos75" }, + { "id": "q24.2", "start": 142800001, "end": 145600000, "type": "gneg" }, + { "id": "q24.3", "start": 145600001, "end": 149000000, "type": "gpos75" }, + { "id": "q25.1", "start": 149000001, "end": 152500000, "type": "gneg" }, + { "id": "q25.2", "start": 152500001, "end": 155500000, "type": "gpos50" }, + { "id": "q25.3", "start": 155500001, "end": 161000000, "type": "gneg" }, + { "id": "q26", "start": 161000001, "end": 164500000, "type": "gpos50" }, + { "id": "q27", "start": 164500001, "end": 171115067, "type": "gneg" } ] }, "7": { - "size": 159138663, - "bands": [ - { - "id": "p11.1", - "start": 58000001, - "end": 59900000, - "type": "acen" - }, - { - "id": "p11.2", - "start": 54000001, - "end": 58000000, - "type": "gneg" - }, - { - "id": "p12.1", - "start": 50500001, - "end": 54000000, - "type": "gpos75" - }, - { - "id": "p12.2", - "start": 49000001, - "end": 50500000, - "type": "gneg" - }, - { - "id": "p12.3", - "start": 45400001, - "end": 49000000, - "type": "gpos75" - }, - { - "id": "p13", - "start": 43300001, - "end": 45400000, - "type": "gneg" - }, - { - "id": "p14.1", - "start": 37200001, - "end": 43300000, - "type": "gpos75" - }, - { - "id": "p14.2", - "start": 35000001, - "end": 37200000, - "type": "gneg" - }, - { - "id": "p14.3", - "start": 28800001, - "end": 35000000, - "type": "gpos75" - }, - { - "id": "p15.1", - "start": 28000001, - "end": 28800000, - "type": "gneg" - }, - { - "id": "p15.2", - "start": 25500001, - "end": 28000000, - "type": "gpos50" - }, - { - "id": "p15.3", - "start": 20900001, - "end": 25500000, - "type": "gneg" - }, - { - "id": "p21.1", - "start": 16500001, - "end": 20900000, - "type": "gpos100" - }, - { - "id": "p21.2", - "start": 13800001, - "end": 16500000, - "type": "gneg" - }, - { - "id": "p21.3", - "start": 7300001, - "end": 13800000, - "type": "gpos100" - }, - { - "id": "p22.1", - "start": 4500001, - "end": 7300000, - "type": "gneg" - }, - { - "id": "p22.2", - "start": 2800001, - "end": 4500000, - "type": "gpos25" - }, - { - "id": "p22.3", - "start": 1, - "end": 2800000, - "type": "gneg" - }, - { - "id": "q11.1", - "start": 59900001, - "end": 61700000, - "type": "acen" - }, - { - "id": "q11.21", - "start": 61700001, - "end": 67000000, - "type": "gneg" - }, - { - "id": "q11.22", - "start": 67000001, - "end": 72200000, - "type": "gpos50" - }, - { - "id": "q11.23", - "start": 72200001, - "end": 77500000, - "type": "gneg" - }, - { - "id": "q21.11", - "start": 77500001, - "end": 86400000, - "type": "gpos100" - }, - { - "id": "q21.12", - "start": 86400001, - "end": 88200000, - "type": "gneg" - }, - { - "id": "q21.13", - "start": 88200001, - "end": 91100000, - "type": "gpos75" - }, - { - "id": "q21.2", - "start": 91100001, - "end": 92800000, - "type": "gneg" - }, - { - "id": "q21.3", - "start": 92800001, - "end": 98000000, - "type": "gpos75" - }, - { - "id": "q22.1", - "start": 98000001, - "end": 103800000, - "type": "gneg" - }, - { - "id": "q22.2", - "start": 103800001, - "end": 104500000, - "type": "gpos50" - }, - { - "id": "q22.3", - "start": 104500001, - "end": 107400000, - "type": "gneg" - }, - { - "id": "q31.1", - "start": 107400001, - "end": 114600000, - "type": "gpos75" - }, - { - "id": "q31.2", - "start": 114600001, - "end": 117400000, - "type": "gneg" - }, - { - "id": "q31.31", - "start": 117400001, - "end": 121100000, - "type": "gpos75" - }, - { - "id": "q31.32", - "start": 121100001, - "end": 123800000, - "type": "gneg" - }, - { - "id": "q31.33", - "start": 123800001, - "end": 127100000, - "type": "gpos75" - }, - { - "id": "q32.1", - "start": 127100001, - "end": 129200000, - "type": "gneg" - }, - { - "id": "q32.2", - "start": 129200001, - "end": 130400000, - "type": "gpos25" - }, - { - "id": "q32.3", - "start": 130400001, - "end": 132600000, - "type": "gneg" - }, - { - "id": "q33", - "start": 132600001, - "end": 138200000, - "type": "gpos50" - }, - { - "id": "q34", - "start": 138200001, - "end": 143100000, - "type": "gneg" - }, - { - "id": "q35", - "start": 143100001, - "end": 147900000, - "type": "gpos75" - }, - { - "id": "q36.1", - "start": 147900001, - "end": 152600000, - "type": "gneg" - }, - { - "id": "q36.2", - "start": 152600001, - "end": 155100000, - "type": "gpos25" - }, - { - "id": "q36.3", - "start": 155100001, - "end": 159138663, - "type": "gneg" - } + "size" : 159138663, + "bands" : [ + { "id": "p11.1", "start": 58000001, "end": 59900000, "type": "acen" }, + { "id": "p11.2", "start": 54000001, "end": 58000000, "type": "gneg" }, + { "id": "p12.1", "start": 50500001, "end": 54000000, "type": "gpos75" }, + { "id": "p12.2", "start": 49000001, "end": 50500000, "type": "gneg" }, + { "id": "p12.3", "start": 45400001, "end": 49000000, "type": "gpos75" }, + { "id": "p13", "start": 43300001, "end": 45400000, "type": "gneg" }, + { "id": "p14.1", "start": 37200001, "end": 43300000, "type": "gpos75" }, + { "id": "p14.2", "start": 35000001, "end": 37200000, "type": "gneg" }, + { "id": "p14.3", "start": 28800001, "end": 35000000, "type": "gpos75" }, + { "id": "p15.1", "start": 28000001, "end": 28800000, "type": "gneg" }, + { "id": "p15.2", "start": 25500001, "end": 28000000, "type": "gpos50" }, + { "id": "p15.3", "start": 20900001, "end": 25500000, "type": "gneg" }, + { "id": "p21.1", "start": 16500001, "end": 20900000, "type": "gpos100" }, + { "id": "p21.2", "start": 13800001, "end": 16500000, "type": "gneg" }, + { "id": "p21.3", "start": 7300001, "end": 13800000, "type": "gpos100" }, + { "id": "p22.1", "start": 4500001, "end": 7300000, "type": "gneg" }, + { "id": "p22.2", "start": 2800001, "end": 4500000, "type": "gpos25" }, + { "id": "p22.3", "start": 1, "end": 2800000, "type": "gneg" }, + { "id": "q11.1", "start": 59900001, "end": 61700000, "type": "acen" }, + { "id": "q11.21", "start": 61700001, "end": 67000000, "type": "gneg" }, + { "id": "q11.22", "start": 67000001, "end": 72200000, "type": "gpos50" }, + { "id": "q11.23", "start": 72200001, "end": 77500000, "type": "gneg" }, + { "id": "q21.11", "start": 77500001, "end": 86400000, "type": "gpos100" }, + { "id": "q21.12", "start": 86400001, "end": 88200000, "type": "gneg" }, + { "id": "q21.13", "start": 88200001, "end": 91100000, "type": "gpos75" }, + { "id": "q21.2", "start": 91100001, "end": 92800000, "type": "gneg" }, + { "id": "q21.3", "start": 92800001, "end": 98000000, "type": "gpos75" }, + { "id": "q22.1", "start": 98000001, "end": 103800000, "type": "gneg" }, + { "id": "q22.2", "start": 103800001, "end": 104500000, "type": "gpos50" }, + { "id": "q22.3", "start": 104500001, "end": 107400000, "type": "gneg" }, + { "id": "q31.1", "start": 107400001, "end": 114600000, "type": "gpos75" }, + { "id": "q31.2", "start": 114600001, "end": 117400000, "type": "gneg" }, + { "id": "q31.31", "start": 117400001, "end": 121100000, "type": "gpos75" }, + { "id": "q31.32", "start": 121100001, "end": 123800000, "type": "gneg" }, + { "id": "q31.33", "start": 123800001, "end": 127100000, "type": "gpos75" }, + { "id": "q32.1", "start": 127100001, "end": 129200000, "type": "gneg" }, + { "id": "q32.2", "start": 129200001, "end": 130400000, "type": "gpos25" }, + { "id": "q32.3", "start": 130400001, "end": 132600000, "type": "gneg" }, + { "id": "q33", "start": 132600001, "end": 138200000, "type": "gpos50" }, + { "id": "q34", "start": 138200001, "end": 143100000, "type": "gneg" }, + { "id": "q35", "start": 143100001, "end": 147900000, "type": "gpos75" }, + { "id": "q36.1", "start": 147900001, "end": 152600000, "type": "gneg" }, + { "id": "q36.2", "start": 152600001, "end": 155100000, "type": "gpos25" }, + { "id": "q36.3", "start": 155100001, "end": 159138663, "type": "gneg" } ] }, "8": { - "size": 146364022, - "bands": [ - { - "id": "p11.1", - "start": 43100001, - "end": 45600000, - "type": "acen" - }, - { - "id": "p11.21", - "start": 39700001, - "end": 43100000, - "type": "gneg" - }, - { - "id": "p11.22", - "start": 38300001, - "end": 39700000, - "type": "gpos25" - }, - { - "id": "p11.23", - "start": 36500001, - "end": 38300000, - "type": "gneg" - }, - { - "id": "p12", - "start": 28800001, - "end": 36500000, - "type": "gpos75" - }, - { - "id": "p21.1", - "start": 27400001, - "end": 28800000, - "type": "gneg" - }, - { - "id": "p21.2", - "start": 23300001, - "end": 27400000, - "type": "gpos50" - }, - { - "id": "p21.3", - "start": 19000001, - "end": 23300000, - "type": "gneg" - }, - { - "id": "p22", - "start": 12700001, - "end": 19000000, - "type": "gpos100" - }, - { - "id": "p23.1", - "start": 6200001, - "end": 12700000, - "type": "gneg" - }, - { - "id": "p23.2", - "start": 2200001, - "end": 6200000, - "type": "gpos75" - }, - { - "id": "p23.3", - "start": 1, - "end": 2200000, - "type": "gneg" - }, - { - "id": "q11.1", - "start": 45600001, - "end": 48100000, - "type": "acen" - }, - { - "id": "q11.21", - "start": 48100001, - "end": 52200000, - "type": "gneg" - }, - { - "id": "q11.22", - "start": 52200001, - "end": 52600000, - "type": "gpos75" - }, - { - "id": "q11.23", - "start": 52600001, - "end": 55500000, - "type": "gneg" - }, - { - "id": "q12.1", - "start": 55500001, - "end": 61600000, - "type": "gpos50" - }, - { - "id": "q12.2", - "start": 61600001, - "end": 62200000, - "type": "gneg" - }, - { - "id": "q12.3", - "start": 62200001, - "end": 66000000, - "type": "gpos50" - }, - { - "id": "q13.1", - "start": 66000001, - "end": 68000000, - "type": "gneg" - }, - { - "id": "q13.2", - "start": 68000001, - "end": 70500000, - "type": "gpos50" - }, - { - "id": "q13.3", - "start": 70500001, - "end": 73900000, - "type": "gneg" - }, - { - "id": "q21.11", - "start": 73900001, - "end": 78300000, - "type": "gpos100" - }, - { - "id": "q21.12", - "start": 78300001, - "end": 80100000, - "type": "gneg" - }, - { - "id": "q21.13", - "start": 80100001, - "end": 84600000, - "type": "gpos75" - }, - { - "id": "q21.2", - "start": 84600001, - "end": 86900000, - "type": "gneg" - }, - { - "id": "q21.3", - "start": 86900001, - "end": 93300000, - "type": "gpos100" - }, - { - "id": "q22.1", - "start": 93300001, - "end": 99000000, - "type": "gneg" - }, - { - "id": "q22.2", - "start": 99000001, - "end": 101600000, - "type": "gpos25" - }, - { - "id": "q22.3", - "start": 101600001, - "end": 106200000, - "type": "gneg" - }, - { - "id": "q23.1", - "start": 106200001, - "end": 110500000, - "type": "gpos75" - }, - { - "id": "q23.2", - "start": 110500001, - "end": 112100000, - "type": "gneg" - }, - { - "id": "q23.3", - "start": 112100001, - "end": 117700000, - "type": "gpos100" - }, - { - "id": "q24.11", - "start": 117700001, - "end": 119200000, - "type": "gneg" - }, - { - "id": "q24.12", - "start": 119200001, - "end": 122500000, - "type": "gpos50" - }, - { - "id": "q24.13", - "start": 122500001, - "end": 127300000, - "type": "gneg" - }, - { - "id": "q24.21", - "start": 127300001, - "end": 131500000, - "type": "gpos50" - }, - { - "id": "q24.22", - "start": 131500001, - "end": 136400000, - "type": "gneg" - }, - { - "id": "q24.23", - "start": 136400001, - "end": 139900000, - "type": "gpos75" - }, - { - "id": "q24.3", - "start": 139900001, - "end": 146364022, - "type": "gneg" - } + "size" : 146364022, + "bands" : [ + { "id": "p11.1", "start": 43100001, "end": 45600000, "type": "acen" }, + { "id": "p11.21", "start": 39700001, "end": 43100000, "type": "gneg" }, + { "id": "p11.22", "start": 38300001, "end": 39700000, "type": "gpos25" }, + { "id": "p11.23", "start": 36500001, "end": 38300000, "type": "gneg" }, + { "id": "p12", "start": 28800001, "end": 36500000, "type": "gpos75" }, + { "id": "p21.1", "start": 27400001, "end": 28800000, "type": "gneg" }, + { "id": "p21.2", "start": 23300001, "end": 27400000, "type": "gpos50" }, + { "id": "p21.3", "start": 19000001, "end": 23300000, "type": "gneg" }, + { "id": "p22", "start": 12700001, "end": 19000000, "type": "gpos100" }, + { "id": "p23.1", "start": 6200001, "end": 12700000, "type": "gneg" }, + { "id": "p23.2", "start": 2200001, "end": 6200000, "type": "gpos75" }, + { "id": "p23.3", "start": 1, "end": 2200000, "type": "gneg" }, + { "id": "q11.1", "start": 45600001, "end": 48100000, "type": "acen" }, + { "id": "q11.21", "start": 48100001, "end": 52200000, "type": "gneg" }, + { "id": "q11.22", "start": 52200001, "end": 52600000, "type": "gpos75" }, + { "id": "q11.23", "start": 52600001, "end": 55500000, "type": "gneg" }, + { "id": "q12.1", "start": 55500001, "end": 61600000, "type": "gpos50" }, + { "id": "q12.2", "start": 61600001, "end": 62200000, "type": "gneg" }, + { "id": "q12.3", "start": 62200001, "end": 66000000, "type": "gpos50" }, + { "id": "q13.1", "start": 66000001, "end": 68000000, "type": "gneg" }, + { "id": "q13.2", "start": 68000001, "end": 70500000, "type": "gpos50" }, + { "id": "q13.3", "start": 70500001, "end": 73900000, "type": "gneg" }, + { "id": "q21.11", "start": 73900001, "end": 78300000, "type": "gpos100" }, + { "id": "q21.12", "start": 78300001, "end": 80100000, "type": "gneg" }, + { "id": "q21.13", "start": 80100001, "end": 84600000, "type": "gpos75" }, + { "id": "q21.2", "start": 84600001, "end": 86900000, "type": "gneg" }, + { "id": "q21.3", "start": 86900001, "end": 93300000, "type": "gpos100" }, + { "id": "q22.1", "start": 93300001, "end": 99000000, "type": "gneg" }, + { "id": "q22.2", "start": 99000001, "end": 101600000, "type": "gpos25" }, + { "id": "q22.3", "start": 101600001, "end": 106200000, "type": "gneg" }, + { "id": "q23.1", "start": 106200001, "end": 110500000, "type": "gpos75" }, + { "id": "q23.2", "start": 110500001, "end": 112100000, "type": "gneg" }, + { "id": "q23.3", "start": 112100001, "end": 117700000, "type": "gpos100" }, + { "id": "q24.11", "start": 117700001, "end": 119200000, "type": "gneg" }, + { "id": "q24.12", "start": 119200001, "end": 122500000, "type": "gpos50" }, + { "id": "q24.13", "start": 122500001, "end": 127300000, "type": "gneg" }, + { "id": "q24.21", "start": 127300001, "end": 131500000, "type": "gpos50" }, + { "id": "q24.22", "start": 131500001, "end": 136400000, "type": "gneg" }, + { "id": "q24.23", "start": 136400001, "end": 139900000, "type": "gpos75" }, + { "id": "q24.3", "start": 139900001, "end": 146364022, "type": "gneg" } ] }, "9": { - "size": 141213431, - "bands": [ - { - "id": "p11.1", - "start": 47300001, - "end": 49000000, - "type": "acen" - }, - { - "id": "p11.2", - "start": 43600001, - "end": 47300000, - "type": "gneg" - }, - { - "id": "p12", - "start": 41000001, - "end": 43600000, - "type": "gpos50" - }, - { - "id": "p13.1", - "start": 38400001, - "end": 41000000, - "type": "gneg" - }, - { - "id": "p13.2", - "start": 36300001, - "end": 38400000, - "type": "gpos25" - }, - { - "id": "p13.3", - "start": 33200001, - "end": 36300000, - "type": "gneg" - }, - { - "id": "p21.1", - "start": 28000001, - "end": 33200000, - "type": "gpos100" - }, - { - "id": "p21.2", - "start": 25600001, - "end": 28000000, - "type": "gneg" - }, - { - "id": "p21.3", - "start": 19900001, - "end": 25600000, - "type": "gpos100" - }, - { - "id": "p22.1", - "start": 18500001, - "end": 19900000, - "type": "gneg" - }, - { - "id": "p22.2", - "start": 16600001, - "end": 18500000, - "type": "gpos25" - }, - { - "id": "p22.3", - "start": 14200001, - "end": 16600000, - "type": "gneg" - }, - { - "id": "p23", - "start": 9000001, - "end": 14200000, - "type": "gpos75" - }, - { - "id": "p24.1", - "start": 4600001, - "end": 9000000, - "type": "gneg" - }, - { - "id": "p24.2", - "start": 2200001, - "end": 4600000, - "type": "gpos25" - }, - { - "id": "p24.3", - "start": 1, - "end": 2200000, - "type": "gneg" - }, - { - "id": "q11", - "start": 49000001, - "end": 50700000, - "type": "acen" - }, - { - "id": "q12", - "start": 50700001, - "end": 65900000, - "type": "gvar" - }, - { - "id": "q13", - "start": 65900001, - "end": 68700000, - "type": "gneg" - }, - { - "id": "q21.11", - "start": 68700001, - "end": 72200000, - "type": "gpos25" - }, - { - "id": "q21.12", - "start": 72200001, - "end": 74000000, - "type": "gneg" - }, - { - "id": "q21.13", - "start": 74000001, - "end": 79200000, - "type": "gpos50" - }, - { - "id": "q21.2", - "start": 79200001, - "end": 81100000, - "type": "gneg" - }, - { - "id": "q21.31", - "start": 81100001, - "end": 84100000, - "type": "gpos50" - }, - { - "id": "q21.32", - "start": 84100001, - "end": 86900000, - "type": "gneg" - }, - { - "id": "q21.33", - "start": 86900001, - "end": 90400000, - "type": "gpos50" - }, - { - "id": "q22.1", - "start": 90400001, - "end": 91800000, - "type": "gneg" - }, - { - "id": "q22.2", - "start": 91800001, - "end": 93900000, - "type": "gpos25" - }, - { - "id": "q22.31", - "start": 93900001, - "end": 96600000, - "type": "gneg" - }, - { - "id": "q22.32", - "start": 96600001, - "end": 99300000, - "type": "gpos25" - }, - { - "id": "q22.33", - "start": 99300001, - "end": 102600000, - "type": "gneg" - }, - { - "id": "q31.1", - "start": 102600001, - "end": 108200000, - "type": "gpos100" - }, - { - "id": "q31.2", - "start": 108200001, - "end": 111300000, - "type": "gneg" - }, - { - "id": "q31.3", - "start": 111300001, - "end": 114900000, - "type": "gpos25" - }, - { - "id": "q32", - "start": 114900001, - "end": 117700000, - "type": "gneg" - }, - { - "id": "q33.1", - "start": 117700001, - "end": 122500000, - "type": "gpos75" - }, - { - "id": "q33.2", - "start": 122500001, - "end": 125800000, - "type": "gneg" - }, - { - "id": "q33.3", - "start": 125800001, - "end": 130300000, - "type": "gpos25" - }, - { - "id": "q34.11", - "start": 130300001, - "end": 133500000, - "type": "gneg" - }, - { - "id": "q34.12", - "start": 133500001, - "end": 134000000, - "type": "gpos25" - }, - { - "id": "q34.13", - "start": 134000001, - "end": 135900000, - "type": "gneg" - }, - { - "id": "q34.2", - "start": 135900001, - "end": 137400000, - "type": "gpos25" - }, - { - "id": "q34.3", - "start": 137400001, - "end": 141213431, - "type": "gneg" - } + "size" : 141213431, + "bands" : [ + { "id": "p11.1", "start": 47300001, "end": 49000000, "type": "acen" }, + { "id": "p11.2", "start": 43600001, "end": 47300000, "type": "gneg" }, + { "id": "p12", "start": 41000001, "end": 43600000, "type": "gpos50" }, + { "id": "p13.1", "start": 38400001, "end": 41000000, "type": "gneg" }, + { "id": "p13.2", "start": 36300001, "end": 38400000, "type": "gpos25" }, + { "id": "p13.3", "start": 33200001, "end": 36300000, "type": "gneg" }, + { "id": "p21.1", "start": 28000001, "end": 33200000, "type": "gpos100" }, + { "id": "p21.2", "start": 25600001, "end": 28000000, "type": "gneg" }, + { "id": "p21.3", "start": 19900001, "end": 25600000, "type": "gpos100" }, + { "id": "p22.1", "start": 18500001, "end": 19900000, "type": "gneg" }, + { "id": "p22.2", "start": 16600001, "end": 18500000, "type": "gpos25" }, + { "id": "p22.3", "start": 14200001, "end": 16600000, "type": "gneg" }, + { "id": "p23", "start": 9000001, "end": 14200000, "type": "gpos75" }, + { "id": "p24.1", "start": 4600001, "end": 9000000, "type": "gneg" }, + { "id": "p24.2", "start": 2200001, "end": 4600000, "type": "gpos25" }, + { "id": "p24.3", "start": 1, "end": 2200000, "type": "gneg" }, + { "id": "q11", "start": 49000001, "end": 50700000, "type": "acen" }, + { "id": "q12", "start": 50700001, "end": 65900000, "type": "gvar" }, + { "id": "q13", "start": 65900001, "end": 68700000, "type": "gneg" }, + { "id": "q21.11", "start": 68700001, "end": 72200000, "type": "gpos25" }, + { "id": "q21.12", "start": 72200001, "end": 74000000, "type": "gneg" }, + { "id": "q21.13", "start": 74000001, "end": 79200000, "type": "gpos50" }, + { "id": "q21.2", "start": 79200001, "end": 81100000, "type": "gneg" }, + { "id": "q21.31", "start": 81100001, "end": 84100000, "type": "gpos50" }, + { "id": "q21.32", "start": 84100001, "end": 86900000, "type": "gneg" }, + { "id": "q21.33", "start": 86900001, "end": 90400000, "type": "gpos50" }, + { "id": "q22.1", "start": 90400001, "end": 91800000, "type": "gneg" }, + { "id": "q22.2", "start": 91800001, "end": 93900000, "type": "gpos25" }, + { "id": "q22.31", "start": 93900001, "end": 96600000, "type": "gneg" }, + { "id": "q22.32", "start": 96600001, "end": 99300000, "type": "gpos25" }, + { "id": "q22.33", "start": 99300001, "end": 102600000, "type": "gneg" }, + { "id": "q31.1", "start": 102600001, "end": 108200000, "type": "gpos100" }, + { "id": "q31.2", "start": 108200001, "end": 111300000, "type": "gneg" }, + { "id": "q31.3", "start": 111300001, "end": 114900000, "type": "gpos25" }, + { "id": "q32", "start": 114900001, "end": 117700000, "type": "gneg" }, + { "id": "q33.1", "start": 117700001, "end": 122500000, "type": "gpos75" }, + { "id": "q33.2", "start": 122500001, "end": 125800000, "type": "gneg" }, + { "id": "q33.3", "start": 125800001, "end": 130300000, "type": "gpos25" }, + { "id": "q34.11", "start": 130300001, "end": 133500000, "type": "gneg" }, + { "id": "q34.12", "start": 133500001, "end": 134000000, "type": "gpos25" }, + { "id": "q34.13", "start": 134000001, "end": 135900000, "type": "gneg" }, + { "id": "q34.2", "start": 135900001, "end": 137400000, "type": "gpos25" }, + { "id": "q34.3", "start": 137400001, "end": 141213431, "type": "gneg" } ] }, "10": { - "size": 135534747, - "bands": [ - { - "id": "p11.1", - "start": 38000001, - "end": 40200000, - "type": "acen" - }, - { - "id": "p11.21", - "start": 34400001, - "end": 38000000, - "type": "gneg" - }, - { - "id": "p11.22", - "start": 31300001, - "end": 34400000, - "type": "gpos25" - }, - { - "id": "p11.23", - "start": 29600001, - "end": 31300000, - "type": "gneg" - }, - { - "id": "p12.1", - "start": 24600001, - "end": 29600000, - "type": "gpos50" - }, - { - "id": "p12.2", - "start": 22600001, - "end": 24600000, - "type": "gneg" - }, - { - "id": "p12.31", - "start": 18700001, - "end": 22600000, - "type": "gpos75" - }, - { - "id": "p12.32", - "start": 18600001, - "end": 18700000, - "type": "gneg" - }, - { - "id": "p12.33", - "start": 17300001, - "end": 18600000, - "type": "gpos75" - }, - { - "id": "p13", - "start": 12200001, - "end": 17300000, - "type": "gneg" - }, - { - "id": "p14", - "start": 6600001, - "end": 12200000, - "type": "gpos75" - }, - { - "id": "p15.1", - "start": 3800001, - "end": 6600000, - "type": "gneg" - }, - { - "id": "p15.2", - "start": 3000001, - "end": 3800000, - "type": "gpos25" - }, - { - "id": "p15.3", - "start": 1, - "end": 3000000, - "type": "gneg" - }, - { - "id": "q11.1", - "start": 40200001, - "end": 42300000, - "type": "acen" - }, - { - "id": "q11.21", - "start": 42300001, - "end": 46100000, - "type": "gneg" - }, - { - "id": "q11.22", - "start": 46100001, - "end": 49900000, - "type": "gpos25" - }, - { - "id": "q11.23", - "start": 49900001, - "end": 52900000, - "type": "gneg" - }, - { - "id": "q21.1", - "start": 52900001, - "end": 61200000, - "type": "gpos100" - }, - { - "id": "q21.2", - "start": 61200001, - "end": 64500000, - "type": "gneg" - }, - { - "id": "q21.3", - "start": 64500001, - "end": 70600000, - "type": "gpos100" - }, - { - "id": "q22.1", - "start": 70600001, - "end": 74900000, - "type": "gneg" - }, - { - "id": "q22.2", - "start": 74900001, - "end": 77700000, - "type": "gpos50" - }, - { - "id": "q22.3", - "start": 77700001, - "end": 82000000, - "type": "gneg" - }, - { - "id": "q23.1", - "start": 82000001, - "end": 87900000, - "type": "gpos100" - }, - { - "id": "q23.2", - "start": 87900001, - "end": 89500000, - "type": "gneg" - }, - { - "id": "q23.31", - "start": 89500001, - "end": 92900000, - "type": "gpos75" - }, - { - "id": "q23.32", - "start": 92900001, - "end": 94100000, - "type": "gneg" - }, - { - "id": "q23.33", - "start": 94100001, - "end": 97000000, - "type": "gpos50" - }, - { - "id": "q24.1", - "start": 97000001, - "end": 99300000, - "type": "gneg" - }, - { - "id": "q24.2", - "start": 99300001, - "end": 101900000, - "type": "gpos50" - }, - { - "id": "q24.31", - "start": 101900001, - "end": 103000000, - "type": "gneg" - }, - { - "id": "q24.32", - "start": 103000001, - "end": 104900000, - "type": "gpos25" - }, - { - "id": "q24.33", - "start": 104900001, - "end": 105800000, - "type": "gneg" - }, - { - "id": "q25.1", - "start": 105800001, - "end": 111900000, - "type": "gpos100" - }, - { - "id": "q25.2", - "start": 111900001, - "end": 114900000, - "type": "gneg" - }, - { - "id": "q25.3", - "start": 114900001, - "end": 119100000, - "type": "gpos75" - }, - { - "id": "q26.11", - "start": 119100001, - "end": 121700000, - "type": "gneg" - }, - { - "id": "q26.12", - "start": 121700001, - "end": 123100000, - "type": "gpos50" - }, - { - "id": "q26.13", - "start": 123100001, - "end": 127500000, - "type": "gneg" - }, - { - "id": "q26.2", - "start": 127500001, - "end": 130600000, - "type": "gpos50" - }, - { - "id": "q26.3", - "start": 130600001, - "end": 135534747, - "type": "gneg" - } + "size" : 135534747, + "bands" : [ + { "id": "p11.1", "start": 38000001, "end": 40200000, "type": "acen" }, + { "id": "p11.21", "start": 34400001, "end": 38000000, "type": "gneg" }, + { "id": "p11.22", "start": 31300001, "end": 34400000, "type": "gpos25" }, + { "id": "p11.23", "start": 29600001, "end": 31300000, "type": "gneg" }, + { "id": "p12.1", "start": 24600001, "end": 29600000, "type": "gpos50" }, + { "id": "p12.2", "start": 22600001, "end": 24600000, "type": "gneg" }, + { "id": "p12.31", "start": 18700001, "end": 22600000, "type": "gpos75" }, + { "id": "p12.32", "start": 18600001, "end": 18700000, "type": "gneg" }, + { "id": "p12.33", "start": 17300001, "end": 18600000, "type": "gpos75" }, + { "id": "p13", "start": 12200001, "end": 17300000, "type": "gneg" }, + { "id": "p14", "start": 6600001, "end": 12200000, "type": "gpos75" }, + { "id": "p15.1", "start": 3800001, "end": 6600000, "type": "gneg" }, + { "id": "p15.2", "start": 3000001, "end": 3800000, "type": "gpos25" }, + { "id": "p15.3", "start": 1, "end": 3000000, "type": "gneg" }, + { "id": "q11.1", "start": 40200001, "end": 42300000, "type": "acen" }, + { "id": "q11.21", "start": 42300001, "end": 46100000, "type": "gneg" }, + { "id": "q11.22", "start": 46100001, "end": 49900000, "type": "gpos25" }, + { "id": "q11.23", "start": 49900001, "end": 52900000, "type": "gneg" }, + { "id": "q21.1", "start": 52900001, "end": 61200000, "type": "gpos100" }, + { "id": "q21.2", "start": 61200001, "end": 64500000, "type": "gneg" }, + { "id": "q21.3", "start": 64500001, "end": 70600000, "type": "gpos100" }, + { "id": "q22.1", "start": 70600001, "end": 74900000, "type": "gneg" }, + { "id": "q22.2", "start": 74900001, "end": 77700000, "type": "gpos50" }, + { "id": "q22.3", "start": 77700001, "end": 82000000, "type": "gneg" }, + { "id": "q23.1", "start": 82000001, "end": 87900000, "type": "gpos100" }, + { "id": "q23.2", "start": 87900001, "end": 89500000, "type": "gneg" }, + { "id": "q23.31", "start": 89500001, "end": 92900000, "type": "gpos75" }, + { "id": "q23.32", "start": 92900001, "end": 94100000, "type": "gneg" }, + { "id": "q23.33", "start": 94100001, "end": 97000000, "type": "gpos50" }, + { "id": "q24.1", "start": 97000001, "end": 99300000, "type": "gneg" }, + { "id": "q24.2", "start": 99300001, "end": 101900000, "type": "gpos50" }, + { "id": "q24.31", "start": 101900001, "end": 103000000, "type": "gneg" }, + { "id": "q24.32", "start": 103000001, "end": 104900000, "type": "gpos25" }, + { "id": "q24.33", "start": 104900001, "end": 105800000, "type": "gneg" }, + { "id": "q25.1", "start": 105800001, "end": 111900000, "type": "gpos100" }, + { "id": "q25.2", "start": 111900001, "end": 114900000, "type": "gneg" }, + { "id": "q25.3", "start": 114900001, "end": 119100000, "type": "gpos75" }, + { "id": "q26.11", "start": 119100001, "end": 121700000, "type": "gneg" }, + { "id": "q26.12", "start": 121700001, "end": 123100000, "type": "gpos50" }, + { "id": "q26.13", "start": 123100001, "end": 127500000, "type": "gneg" }, + { "id": "q26.2", "start": 127500001, "end": 130600000, "type": "gpos50" }, + { "id": "q26.3", "start": 130600001, "end": 135534747, "type": "gneg" } ] }, "11": { - "size": 135006516, - "bands": [ - { - "id": "p11.11", - "start": 51600001, - "end": 53700000, - "type": "acen" - }, - { - "id": "p11.12", - "start": 48800001, - "end": 51600000, - "type": "gpos75" - }, - { - "id": "p11.2", - "start": 43500001, - "end": 48800000, - "type": "gneg" - }, - { - "id": "p12", - "start": 36400001, - "end": 43500000, - "type": "gpos100" - }, - { - "id": "p13", - "start": 31000001, - "end": 36400000, - "type": "gneg" - }, - { - "id": "p14.1", - "start": 27200001, - "end": 31000000, - "type": "gpos75" - }, - { - "id": "p14.2", - "start": 26100001, - "end": 27200000, - "type": "gneg" - }, - { - "id": "p14.3", - "start": 21700001, - "end": 26100000, - "type": "gpos100" - }, - { - "id": "p15.1", - "start": 16200001, - "end": 21700000, - "type": "gneg" - }, - { - "id": "p15.2", - "start": 12700001, - "end": 16200000, - "type": "gpos50" - }, - { - "id": "p15.3", - "start": 10700001, - "end": 12700000, - "type": "gneg" - }, - { - "id": "p15.4", - "start": 2800001, - "end": 10700000, - "type": "gpos50" - }, - { - "id": "p15.5", - "start": 1, - "end": 2800000, - "type": "gneg" - }, - { - "id": "q11", - "start": 53700001, - "end": 55700000, - "type": "acen" - }, - { - "id": "q12.1", - "start": 55700001, - "end": 59900000, - "type": "gpos75" - }, - { - "id": "q12.2", - "start": 59900001, - "end": 61700000, - "type": "gneg" - }, - { - "id": "q12.3", - "start": 61700001, - "end": 63400000, - "type": "gpos25" - }, - { - "id": "q13.1", - "start": 63400001, - "end": 65900000, - "type": "gneg" - }, - { - "id": "q13.2", - "start": 65900001, - "end": 68400000, - "type": "gpos25" - }, - { - "id": "q13.3", - "start": 68400001, - "end": 70400000, - "type": "gneg" - }, - { - "id": "q13.4", - "start": 70400001, - "end": 75200000, - "type": "gpos50" - }, - { - "id": "q13.5", - "start": 75200001, - "end": 77100000, - "type": "gneg" - }, - { - "id": "q14.1", - "start": 77100001, - "end": 85600000, - "type": "gpos100" - }, - { - "id": "q14.2", - "start": 85600001, - "end": 88300000, - "type": "gneg" - }, - { - "id": "q14.3", - "start": 88300001, - "end": 92800000, - "type": "gpos100" - }, - { - "id": "q21", - "start": 92800001, - "end": 97200000, - "type": "gneg" - }, - { - "id": "q22.1", - "start": 97200001, - "end": 102100000, - "type": "gpos100" - }, - { - "id": "q22.2", - "start": 102100001, - "end": 102900000, - "type": "gneg" - }, - { - "id": "q22.3", - "start": 102900001, - "end": 110400000, - "type": "gpos100" - }, - { - "id": "q23.1", - "start": 110400001, - "end": 112500000, - "type": "gneg" - }, - { - "id": "q23.2", - "start": 112500001, - "end": 114500000, - "type": "gpos50" - }, - { - "id": "q23.3", - "start": 114500001, - "end": 121200000, - "type": "gneg" - }, - { - "id": "q24.1", - "start": 121200001, - "end": 123900000, - "type": "gpos50" - }, - { - "id": "q24.2", - "start": 123900001, - "end": 127800000, - "type": "gneg" - }, - { - "id": "q24.3", - "start": 127800001, - "end": 130800000, - "type": "gpos50" - }, - { - "id": "q25", - "start": 130800001, - "end": 135006516, - "type": "gneg" - } + "size" : 135006516, + "bands" : [ + { "id": "p11.11", "start": 51600001, "end": 53700000, "type": "acen" }, + { "id": "p11.12", "start": 48800001, "end": 51600000, "type": "gpos75" }, + { "id": "p11.2", "start": 43500001, "end": 48800000, "type": "gneg" }, + { "id": "p12", "start": 36400001, "end": 43500000, "type": "gpos100" }, + { "id": "p13", "start": 31000001, "end": 36400000, "type": "gneg" }, + { "id": "p14.1", "start": 27200001, "end": 31000000, "type": "gpos75" }, + { "id": "p14.2", "start": 26100001, "end": 27200000, "type": "gneg" }, + { "id": "p14.3", "start": 21700001, "end": 26100000, "type": "gpos100" }, + { "id": "p15.1", "start": 16200001, "end": 21700000, "type": "gneg" }, + { "id": "p15.2", "start": 12700001, "end": 16200000, "type": "gpos50" }, + { "id": "p15.3", "start": 10700001, "end": 12700000, "type": "gneg" }, + { "id": "p15.4", "start": 2800001, "end": 10700000, "type": "gpos50" }, + { "id": "p15.5", "start": 1, "end": 2800000, "type": "gneg" }, + { "id": "q11", "start": 53700001, "end": 55700000, "type": "acen" }, + { "id": "q12.1", "start": 55700001, "end": 59900000, "type": "gpos75" }, + { "id": "q12.2", "start": 59900001, "end": 61700000, "type": "gneg" }, + { "id": "q12.3", "start": 61700001, "end": 63400000, "type": "gpos25" }, + { "id": "q13.1", "start": 63400001, "end": 65900000, "type": "gneg" }, + { "id": "q13.2", "start": 65900001, "end": 68400000, "type": "gpos25" }, + { "id": "q13.3", "start": 68400001, "end": 70400000, "type": "gneg" }, + { "id": "q13.4", "start": 70400001, "end": 75200000, "type": "gpos50" }, + { "id": "q13.5", "start": 75200001, "end": 77100000, "type": "gneg" }, + { "id": "q14.1", "start": 77100001, "end": 85600000, "type": "gpos100" }, + { "id": "q14.2", "start": 85600001, "end": 88300000, "type": "gneg" }, + { "id": "q14.3", "start": 88300001, "end": 92800000, "type": "gpos100" }, + { "id": "q21", "start": 92800001, "end": 97200000, "type": "gneg" }, + { "id": "q22.1", "start": 97200001, "end": 102100000, "type": "gpos100" }, + { "id": "q22.2", "start": 102100001, "end": 102900000, "type": "gneg" }, + { "id": "q22.3", "start": 102900001, "end": 110400000, "type": "gpos100" }, + { "id": "q23.1", "start": 110400001, "end": 112500000, "type": "gneg" }, + { "id": "q23.2", "start": 112500001, "end": 114500000, "type": "gpos50" }, + { "id": "q23.3", "start": 114500001, "end": 121200000, "type": "gneg" }, + { "id": "q24.1", "start": 121200001, "end": 123900000, "type": "gpos50" }, + { "id": "q24.2", "start": 123900001, "end": 127800000, "type": "gneg" }, + { "id": "q24.3", "start": 127800001, "end": 130800000, "type": "gpos50" }, + { "id": "q25", "start": 130800001, "end": 135006516, "type": "gneg" } ] }, "12": { - "size": 133851895, - "bands": [ - { - "id": "p11.1", - "start": 33300001, - "end": 35800000, - "type": "acen" - }, - { - "id": "p11.21", - "start": 30700001, - "end": 33300000, - "type": "gneg" - }, - { - "id": "p11.22", - "start": 27800001, - "end": 30700000, - "type": "gpos50" - }, - { - "id": "p11.23", - "start": 26500001, - "end": 27800000, - "type": "gneg" - }, - { - "id": "p12.1", - "start": 21300001, - "end": 26500000, - "type": "gpos100" - }, - { - "id": "p12.2", - "start": 20000001, - "end": 21300000, - "type": "gneg" - }, - { - "id": "p12.3", - "start": 14800001, - "end": 20000000, - "type": "gpos100" - }, - { - "id": "p13.1", - "start": 12800001, - "end": 14800000, - "type": "gneg" - }, - { - "id": "p13.2", - "start": 10100001, - "end": 12800000, - "type": "gpos75" - }, - { - "id": "p13.31", - "start": 5400001, - "end": 10100000, - "type": "gneg" - }, - { - "id": "p13.32", - "start": 3300001, - "end": 5400000, - "type": "gpos25" - }, - { - "id": "p13.33", - "start": 1, - "end": 3300000, - "type": "gneg" - }, - { - "id": "q11", - "start": 35800001, - "end": 38200000, - "type": "acen" - }, - { - "id": "q12", - "start": 38200001, - "end": 46400000, - "type": "gpos100" - }, - { - "id": "q13.11", - "start": 46400001, - "end": 49100000, - "type": "gneg" - }, - { - "id": "q13.12", - "start": 49100001, - "end": 51500000, - "type": "gpos25" - }, - { - "id": "q13.13", - "start": 51500001, - "end": 54900000, - "type": "gneg" - }, - { - "id": "q13.2", - "start": 54900001, - "end": 56600000, - "type": "gpos25" - }, - { - "id": "q13.3", - "start": 56600001, - "end": 58100000, - "type": "gneg" - }, - { - "id": "q14.1", - "start": 58100001, - "end": 63100000, - "type": "gpos75" - }, - { - "id": "q14.2", - "start": 63100001, - "end": 65100000, - "type": "gneg" - }, - { - "id": "q14.3", - "start": 65100001, - "end": 67700000, - "type": "gpos50" - }, - { - "id": "q15", - "start": 67700001, - "end": 71500000, - "type": "gneg" - }, - { - "id": "q21.1", - "start": 71500001, - "end": 75700000, - "type": "gpos75" - }, - { - "id": "q21.2", - "start": 75700001, - "end": 80300000, - "type": "gneg" - }, - { - "id": "q21.31", - "start": 80300001, - "end": 86700000, - "type": "gpos100" - }, - { - "id": "q21.32", - "start": 86700001, - "end": 89000000, - "type": "gneg" - }, - { - "id": "q21.33", - "start": 89000001, - "end": 92600000, - "type": "gpos100" - }, - { - "id": "q22", - "start": 92600001, - "end": 96200000, - "type": "gneg" - }, - { - "id": "q23.1", - "start": 96200001, - "end": 101600000, - "type": "gpos75" - }, - { - "id": "q23.2", - "start": 101600001, - "end": 103800000, - "type": "gneg" - }, - { - "id": "q23.3", - "start": 103800001, - "end": 109000000, - "type": "gpos50" - }, - { - "id": "q24.11", - "start": 109000001, - "end": 111700000, - "type": "gneg" - }, - { - "id": "q24.12", - "start": 111700001, - "end": 112300000, - "type": "gpos25" - }, - { - "id": "q24.13", - "start": 112300001, - "end": 114300000, - "type": "gneg" - }, - { - "id": "q24.21", - "start": 114300001, - "end": 116800000, - "type": "gpos50" - }, - { - "id": "q24.22", - "start": 116800001, - "end": 118100000, - "type": "gneg" - }, - { - "id": "q24.23", - "start": 118100001, - "end": 120700000, - "type": "gpos50" - }, - { - "id": "q24.31", - "start": 120700001, - "end": 125900000, - "type": "gneg" - }, - { - "id": "q24.32", - "start": 125900001, - "end": 129300000, - "type": "gpos50" - }, - { - "id": "q24.33", - "start": 129300001, - "end": 133851895, - "type": "gneg" - } + "size" : 133851895, + "bands" : [ + { "id": "p11.1", "start": 33300001, "end": 35800000, "type": "acen" }, + { "id": "p11.21", "start": 30700001, "end": 33300000, "type": "gneg" }, + { "id": "p11.22", "start": 27800001, "end": 30700000, "type": "gpos50" }, + { "id": "p11.23", "start": 26500001, "end": 27800000, "type": "gneg" }, + { "id": "p12.1", "start": 21300001, "end": 26500000, "type": "gpos100" }, + { "id": "p12.2", "start": 20000001, "end": 21300000, "type": "gneg" }, + { "id": "p12.3", "start": 14800001, "end": 20000000, "type": "gpos100" }, + { "id": "p13.1", "start": 12800001, "end": 14800000, "type": "gneg" }, + { "id": "p13.2", "start": 10100001, "end": 12800000, "type": "gpos75" }, + { "id": "p13.31", "start": 5400001, "end": 10100000, "type": "gneg" }, + { "id": "p13.32", "start": 3300001, "end": 5400000, "type": "gpos25" }, + { "id": "p13.33", "start": 1, "end": 3300000, "type": "gneg" }, + { "id": "q11", "start": 35800001, "end": 38200000, "type": "acen" }, + { "id": "q12", "start": 38200001, "end": 46400000, "type": "gpos100" }, + { "id": "q13.11", "start": 46400001, "end": 49100000, "type": "gneg" }, + { "id": "q13.12", "start": 49100001, "end": 51500000, "type": "gpos25" }, + { "id": "q13.13", "start": 51500001, "end": 54900000, "type": "gneg" }, + { "id": "q13.2", "start": 54900001, "end": 56600000, "type": "gpos25" }, + { "id": "q13.3", "start": 56600001, "end": 58100000, "type": "gneg" }, + { "id": "q14.1", "start": 58100001, "end": 63100000, "type": "gpos75" }, + { "id": "q14.2", "start": 63100001, "end": 65100000, "type": "gneg" }, + { "id": "q14.3", "start": 65100001, "end": 67700000, "type": "gpos50" }, + { "id": "q15", "start": 67700001, "end": 71500000, "type": "gneg" }, + { "id": "q21.1", "start": 71500001, "end": 75700000, "type": "gpos75" }, + { "id": "q21.2", "start": 75700001, "end": 80300000, "type": "gneg" }, + { "id": "q21.31", "start": 80300001, "end": 86700000, "type": "gpos100" }, + { "id": "q21.32", "start": 86700001, "end": 89000000, "type": "gneg" }, + { "id": "q21.33", "start": 89000001, "end": 92600000, "type": "gpos100" }, + { "id": "q22", "start": 92600001, "end": 96200000, "type": "gneg" }, + { "id": "q23.1", "start": 96200001, "end": 101600000, "type": "gpos75" }, + { "id": "q23.2", "start": 101600001, "end": 103800000, "type": "gneg" }, + { "id": "q23.3", "start": 103800001, "end": 109000000, "type": "gpos50" }, + { "id": "q24.11", "start": 109000001, "end": 111700000, "type": "gneg" }, + { "id": "q24.12", "start": 111700001, "end": 112300000, "type": "gpos25" }, + { "id": "q24.13", "start": 112300001, "end": 114300000, "type": "gneg" }, + { "id": "q24.21", "start": 114300001, "end": 116800000, "type": "gpos50" }, + { "id": "q24.22", "start": 116800001, "end": 118100000, "type": "gneg" }, + { "id": "q24.23", "start": 118100001, "end": 120700000, "type": "gpos50" }, + { "id": "q24.31", "start": 120700001, "end": 125900000, "type": "gneg" }, + { "id": "q24.32", "start": 125900001, "end": 129300000, "type": "gpos50" }, + { "id": "q24.33", "start": 129300001, "end": 133851895, "type": "gneg" } ] }, "13": { - "size": 115169878, - "bands": [ - { - "id": "p11.1", - "start": 16300001, - "end": 17900000, - "type": "acen" - }, - { - "id": "p11.2", - "start": 10000001, - "end": 16300000, - "type": "gvar" - }, - { - "id": "p12", - "start": 4500001, - "end": 10000000, - "type": "stalk" - }, - { - "id": "p13", - "start": 1, - "end": 4500000, - "type": "gvar" - }, - { - "id": "q11", - "start": 17900001, - "end": 19500000, - "type": "acen" - }, - { - "id": "q12.11", - "start": 19500001, - "end": 23300000, - "type": "gneg" - }, - { - "id": "q12.12", - "start": 23300001, - "end": 25500000, - "type": "gpos25" - }, - { - "id": "q12.13", - "start": 25500001, - "end": 27800000, - "type": "gneg" - }, - { - "id": "q12.2", - "start": 27800001, - "end": 28900000, - "type": "gpos25" - }, - { - "id": "q12.3", - "start": 28900001, - "end": 32200000, - "type": "gneg" - }, - { - "id": "q13.1", - "start": 32200001, - "end": 34000000, - "type": "gpos50" - }, - { - "id": "q13.2", - "start": 34000001, - "end": 35500000, - "type": "gneg" - }, - { - "id": "q13.3", - "start": 35500001, - "end": 40100000, - "type": "gpos75" - }, - { - "id": "q14.11", - "start": 40100001, - "end": 45200000, - "type": "gneg" - }, - { - "id": "q14.12", - "start": 45200001, - "end": 45800000, - "type": "gpos25" - }, - { - "id": "q14.13", - "start": 45800001, - "end": 47300000, - "type": "gneg" - }, - { - "id": "q14.2", - "start": 47300001, - "end": 50900000, - "type": "gpos50" - }, - { - "id": "q14.3", - "start": 50900001, - "end": 55300000, - "type": "gneg" - }, - { - "id": "q21.1", - "start": 55300001, - "end": 59600000, - "type": "gpos100" - }, - { - "id": "q21.2", - "start": 59600001, - "end": 62300000, - "type": "gneg" - }, - { - "id": "q21.31", - "start": 62300001, - "end": 65700000, - "type": "gpos75" - }, - { - "id": "q21.32", - "start": 65700001, - "end": 68600000, - "type": "gneg" - }, - { - "id": "q21.33", - "start": 68600001, - "end": 73300000, - "type": "gpos100" - }, - { - "id": "q22.1", - "start": 73300001, - "end": 75400000, - "type": "gneg" - }, - { - "id": "q22.2", - "start": 75400001, - "end": 77200000, - "type": "gpos50" - }, - { - "id": "q22.3", - "start": 77200001, - "end": 79000000, - "type": "gneg" - }, - { - "id": "q31.1", - "start": 79000001, - "end": 87700000, - "type": "gpos100" - }, - { - "id": "q31.2", - "start": 87700001, - "end": 90000000, - "type": "gneg" - }, - { - "id": "q31.3", - "start": 90000001, - "end": 95000000, - "type": "gpos100" - }, - { - "id": "q32.1", - "start": 95000001, - "end": 98200000, - "type": "gneg" - }, - { - "id": "q32.2", - "start": 98200001, - "end": 99300000, - "type": "gpos25" - }, - { - "id": "q32.3", - "start": 99300001, - "end": 101700000, - "type": "gneg" - }, - { - "id": "q33.1", - "start": 101700001, - "end": 104800000, - "type": "gpos100" - }, - { - "id": "q33.2", - "start": 104800001, - "end": 107000000, - "type": "gneg" - }, - { - "id": "q33.3", - "start": 107000001, - "end": 110300000, - "type": "gpos100" - }, - { - "id": "q34", - "start": 110300001, - "end": 115169878, - "type": "gneg" - } + "size" : 115169878, + "bands" : [ + { "id": "p11.1", "start": 16300001, "end": 17900000, "type": "acen" }, + { "id": "p11.2", "start": 10000001, "end": 16300000, "type": "gvar" }, + { "id": "p12", "start": 4500001, "end": 10000000, "type": "stalk" }, + { "id": "p13", "start": 1, "end": 4500000, "type": "gvar" }, + { "id": "q11", "start": 17900001, "end": 19500000, "type": "acen" }, + { "id": "q12.11", "start": 19500001, "end": 23300000, "type": "gneg" }, + { "id": "q12.12", "start": 23300001, "end": 25500000, "type": "gpos25" }, + { "id": "q12.13", "start": 25500001, "end": 27800000, "type": "gneg" }, + { "id": "q12.2", "start": 27800001, "end": 28900000, "type": "gpos25" }, + { "id": "q12.3", "start": 28900001, "end": 32200000, "type": "gneg" }, + { "id": "q13.1", "start": 32200001, "end": 34000000, "type": "gpos50" }, + { "id": "q13.2", "start": 34000001, "end": 35500000, "type": "gneg" }, + { "id": "q13.3", "start": 35500001, "end": 40100000, "type": "gpos75" }, + { "id": "q14.11", "start": 40100001, "end": 45200000, "type": "gneg" }, + { "id": "q14.12", "start": 45200001, "end": 45800000, "type": "gpos25" }, + { "id": "q14.13", "start": 45800001, "end": 47300000, "type": "gneg" }, + { "id": "q14.2", "start": 47300001, "end": 50900000, "type": "gpos50" }, + { "id": "q14.3", "start": 50900001, "end": 55300000, "type": "gneg" }, + { "id": "q21.1", "start": 55300001, "end": 59600000, "type": "gpos100" }, + { "id": "q21.2", "start": 59600001, "end": 62300000, "type": "gneg" }, + { "id": "q21.31", "start": 62300001, "end": 65700000, "type": "gpos75" }, + { "id": "q21.32", "start": 65700001, "end": 68600000, "type": "gneg" }, + { "id": "q21.33", "start": 68600001, "end": 73300000, "type": "gpos100" }, + { "id": "q22.1", "start": 73300001, "end": 75400000, "type": "gneg" }, + { "id": "q22.2", "start": 75400001, "end": 77200000, "type": "gpos50" }, + { "id": "q22.3", "start": 77200001, "end": 79000000, "type": "gneg" }, + { "id": "q31.1", "start": 79000001, "end": 87700000, "type": "gpos100" }, + { "id": "q31.2", "start": 87700001, "end": 90000000, "type": "gneg" }, + { "id": "q31.3", "start": 90000001, "end": 95000000, "type": "gpos100" }, + { "id": "q32.1", "start": 95000001, "end": 98200000, "type": "gneg" }, + { "id": "q32.2", "start": 98200001, "end": 99300000, "type": "gpos25" }, + { "id": "q32.3", "start": 99300001, "end": 101700000, "type": "gneg" }, + { "id": "q33.1", "start": 101700001, "end": 104800000, "type": "gpos100" }, + { "id": "q33.2", "start": 104800001, "end": 107000000, "type": "gneg" }, + { "id": "q33.3", "start": 107000001, "end": 110300000, "type": "gpos100" }, + { "id": "q34", "start": 110300001, "end": 115169878, "type": "gneg" } ] }, "14": { - "size": 107349540, - "bands": [ - { - "id": "p11.1", - "start": 16100001, - "end": 17600000, - "type": "acen" - }, - { - "id": "p11.2", - "start": 8100001, - "end": 16100000, - "type": "gvar" - }, - { - "id": "p12", - "start": 3700001, - "end": 8100000, - "type": "stalk" - }, - { - "id": "p13", - "start": 1, - "end": 3700000, - "type": "gvar" - }, - { - "id": "q11.1", - "start": 17600001, - "end": 19100000, - "type": "acen" - }, - { - "id": "q11.2", - "start": 19100001, - "end": 24600000, - "type": "gneg" - }, - { - "id": "q12", - "start": 24600001, - "end": 33300000, - "type": "gpos100" - }, - { - "id": "q13.1", - "start": 33300001, - "end": 35300000, - "type": "gneg" - }, - { - "id": "q13.2", - "start": 35300001, - "end": 36600000, - "type": "gpos50" - }, - { - "id": "q13.3", - "start": 36600001, - "end": 37800000, - "type": "gneg" - }, - { - "id": "q21.1", - "start": 37800001, - "end": 43500000, - "type": "gpos100" - }, - { - "id": "q21.2", - "start": 43500001, - "end": 47200000, - "type": "gneg" - }, - { - "id": "q21.3", - "start": 47200001, - "end": 50900000, - "type": "gpos100" - }, - { - "id": "q22.1", - "start": 50900001, - "end": 54100000, - "type": "gneg" - }, - { - "id": "q22.2", - "start": 54100001, - "end": 55500000, - "type": "gpos25" - }, - { - "id": "q22.3", - "start": 55500001, - "end": 58100000, - "type": "gneg" - }, - { - "id": "q23.1", - "start": 58100001, - "end": 62100000, - "type": "gpos75" - }, - { - "id": "q23.2", - "start": 62100001, - "end": 64800000, - "type": "gneg" - }, - { - "id": "q23.3", - "start": 64800001, - "end": 67900000, - "type": "gpos50" - }, - { - "id": "q24.1", - "start": 67900001, - "end": 70200000, - "type": "gneg" - }, - { - "id": "q24.2", - "start": 70200001, - "end": 73800000, - "type": "gpos50" - }, - { - "id": "q24.3", - "start": 73800001, - "end": 79300000, - "type": "gneg" - }, - { - "id": "q31.1", - "start": 79300001, - "end": 83600000, - "type": "gpos100" - }, - { - "id": "q31.2", - "start": 83600001, - "end": 84900000, - "type": "gneg" - }, - { - "id": "q31.3", - "start": 84900001, - "end": 89800000, - "type": "gpos100" - }, - { - "id": "q32.11", - "start": 89800001, - "end": 91900000, - "type": "gneg" - }, - { - "id": "q32.12", - "start": 91900001, - "end": 94700000, - "type": "gpos25" - }, - { - "id": "q32.13", - "start": 94700001, - "end": 96300000, - "type": "gneg" - }, - { - "id": "q32.2", - "start": 96300001, - "end": 101400000, - "type": "gpos50" - }, - { - "id": "q32.31", - "start": 101400001, - "end": 103200000, - "type": "gneg" - }, - { - "id": "q32.32", - "start": 103200001, - "end": 104000000, - "type": "gpos50" - }, - { - "id": "q32.33", - "start": 104000001, - "end": 107349540, - "type": "gneg" - } + "size" : 107349540, + "bands" : [ + { "id": "p11.1", "start": 16100001, "end": 17600000, "type": "acen" }, + { "id": "p11.2", "start": 8100001, "end": 16100000, "type": "gvar" }, + { "id": "p12", "start": 3700001, "end": 8100000, "type": "stalk" }, + { "id": "p13", "start": 1, "end": 3700000, "type": "gvar" }, + { "id": "q11.1", "start": 17600001, "end": 19100000, "type": "acen" }, + { "id": "q11.2", "start": 19100001, "end": 24600000, "type": "gneg" }, + { "id": "q12", "start": 24600001, "end": 33300000, "type": "gpos100" }, + { "id": "q13.1", "start": 33300001, "end": 35300000, "type": "gneg" }, + { "id": "q13.2", "start": 35300001, "end": 36600000, "type": "gpos50" }, + { "id": "q13.3", "start": 36600001, "end": 37800000, "type": "gneg" }, + { "id": "q21.1", "start": 37800001, "end": 43500000, "type": "gpos100" }, + { "id": "q21.2", "start": 43500001, "end": 47200000, "type": "gneg" }, + { "id": "q21.3", "start": 47200001, "end": 50900000, "type": "gpos100" }, + { "id": "q22.1", "start": 50900001, "end": 54100000, "type": "gneg" }, + { "id": "q22.2", "start": 54100001, "end": 55500000, "type": "gpos25" }, + { "id": "q22.3", "start": 55500001, "end": 58100000, "type": "gneg" }, + { "id": "q23.1", "start": 58100001, "end": 62100000, "type": "gpos75" }, + { "id": "q23.2", "start": 62100001, "end": 64800000, "type": "gneg" }, + { "id": "q23.3", "start": 64800001, "end": 67900000, "type": "gpos50" }, + { "id": "q24.1", "start": 67900001, "end": 70200000, "type": "gneg" }, + { "id": "q24.2", "start": 70200001, "end": 73800000, "type": "gpos50" }, + { "id": "q24.3", "start": 73800001, "end": 79300000, "type": "gneg" }, + { "id": "q31.1", "start": 79300001, "end": 83600000, "type": "gpos100" }, + { "id": "q31.2", "start": 83600001, "end": 84900000, "type": "gneg" }, + { "id": "q31.3", "start": 84900001, "end": 89800000, "type": "gpos100" }, + { "id": "q32.11", "start": 89800001, "end": 91900000, "type": "gneg" }, + { "id": "q32.12", "start": 91900001, "end": 94700000, "type": "gpos25" }, + { "id": "q32.13", "start": 94700001, "end": 96300000, "type": "gneg" }, + { "id": "q32.2", "start": 96300001, "end": 101400000, "type": "gpos50" }, + { "id": "q32.31", "start": 101400001, "end": 103200000, "type": "gneg" }, + { "id": "q32.32", "start": 103200001, "end": 104000000, "type": "gpos50" }, + { "id": "q32.33", "start": 104000001, "end": 107349540, "type": "gneg" } ] }, "15": { - "size": 102531392, - "bands": [ - { - "id": "p11.1", - "start": 15800001, - "end": 19000000, - "type": "acen" - }, - { - "id": "p11.2", - "start": 8700001, - "end": 15800000, - "type": "gvar" - }, - { - "id": "p12", - "start": 3900001, - "end": 8700000, - "type": "stalk" - }, - { - "id": "p13", - "start": 1, - "end": 3900000, - "type": "gvar" - }, - { - "id": "q11.1", - "start": 19000001, - "end": 20700000, - "type": "acen" - }, - { - "id": "q11.2", - "start": 20700001, - "end": 25700000, - "type": "gneg" - }, - { - "id": "q12", - "start": 25700001, - "end": 28100000, - "type": "gpos50" - }, - { - "id": "q13.1", - "start": 28100001, - "end": 30300000, - "type": "gneg" - }, - { - "id": "q13.2", - "start": 30300001, - "end": 31200000, - "type": "gpos50" - }, - { - "id": "q13.3", - "start": 31200001, - "end": 33600000, - "type": "gneg" - }, - { - "id": "q14", - "start": 33600001, - "end": 40100000, - "type": "gpos75" - }, - { - "id": "q15.1", - "start": 40100001, - "end": 42800000, - "type": "gneg" - }, - { - "id": "q15.2", - "start": 42800001, - "end": 43600000, - "type": "gpos25" - }, - { - "id": "q15.3", - "start": 43600001, - "end": 44800000, - "type": "gneg" - }, - { - "id": "q21.1", - "start": 44800001, - "end": 49500000, - "type": "gpos75" - }, - { - "id": "q21.2", - "start": 49500001, - "end": 52900000, - "type": "gneg" - }, - { - "id": "q21.3", - "start": 52900001, - "end": 59100000, - "type": "gpos75" - }, - { - "id": "q22.1", - "start": 59100001, - "end": 59300000, - "type": "gneg" - }, - { - "id": "q22.2", - "start": 59300001, - "end": 63700000, - "type": "gpos25" - }, - { - "id": "q22.31", - "start": 63700001, - "end": 67200000, - "type": "gneg" - }, - { - "id": "q22.32", - "start": 67200001, - "end": 67300000, - "type": "gpos25" - }, - { - "id": "q22.33", - "start": 67300001, - "end": 67500000, - "type": "gneg" - }, - { - "id": "q23", - "start": 67500001, - "end": 72700000, - "type": "gpos25" - }, - { - "id": "q24.1", - "start": 72700001, - "end": 75200000, - "type": "gneg" - }, - { - "id": "q24.2", - "start": 75200001, - "end": 76600000, - "type": "gpos25" - }, - { - "id": "q24.3", - "start": 76600001, - "end": 78300000, - "type": "gneg" - }, - { - "id": "q25.1", - "start": 78300001, - "end": 81700000, - "type": "gpos50" - }, - { - "id": "q25.2", - "start": 81700001, - "end": 85200000, - "type": "gneg" - }, - { - "id": "q25.3", - "start": 85200001, - "end": 89100000, - "type": "gpos50" - }, - { - "id": "q26.1", - "start": 89100001, - "end": 94300000, - "type": "gneg" - }, - { - "id": "q26.2", - "start": 94300001, - "end": 98500000, - "type": "gpos50" - }, - { - "id": "q26.3", - "start": 98500001, - "end": 102531392, - "type": "gneg" - } + "size" : 102531392, + "bands" : [ + { "id": "p11.1", "start": 15800001, "end": 19000000, "type": "acen" }, + { "id": "p11.2", "start": 8700001, "end": 15800000, "type": "gvar" }, + { "id": "p12", "start": 3900001, "end": 8700000, "type": "stalk" }, + { "id": "p13", "start": 1, "end": 3900000, "type": "gvar" }, + { "id": "q11.1", "start": 19000001, "end": 20700000, "type": "acen" }, + { "id": "q11.2", "start": 20700001, "end": 25700000, "type": "gneg" }, + { "id": "q12", "start": 25700001, "end": 28100000, "type": "gpos50" }, + { "id": "q13.1", "start": 28100001, "end": 30300000, "type": "gneg" }, + { "id": "q13.2", "start": 30300001, "end": 31200000, "type": "gpos50" }, + { "id": "q13.3", "start": 31200001, "end": 33600000, "type": "gneg" }, + { "id": "q14", "start": 33600001, "end": 40100000, "type": "gpos75" }, + { "id": "q15.1", "start": 40100001, "end": 42800000, "type": "gneg" }, + { "id": "q15.2", "start": 42800001, "end": 43600000, "type": "gpos25" }, + { "id": "q15.3", "start": 43600001, "end": 44800000, "type": "gneg" }, + { "id": "q21.1", "start": 44800001, "end": 49500000, "type": "gpos75" }, + { "id": "q21.2", "start": 49500001, "end": 52900000, "type": "gneg" }, + { "id": "q21.3", "start": 52900001, "end": 59100000, "type": "gpos75" }, + { "id": "q22.1", "start": 59100001, "end": 59300000, "type": "gneg" }, + { "id": "q22.2", "start": 59300001, "end": 63700000, "type": "gpos25" }, + { "id": "q22.31", "start": 63700001, "end": 67200000, "type": "gneg" }, + { "id": "q22.32", "start": 67200001, "end": 67300000, "type": "gpos25" }, + { "id": "q22.33", "start": 67300001, "end": 67500000, "type": "gneg" }, + { "id": "q23", "start": 67500001, "end": 72700000, "type": "gpos25" }, + { "id": "q24.1", "start": 72700001, "end": 75200000, "type": "gneg" }, + { "id": "q24.2", "start": 75200001, "end": 76600000, "type": "gpos25" }, + { "id": "q24.3", "start": 76600001, "end": 78300000, "type": "gneg" }, + { "id": "q25.1", "start": 78300001, "end": 81700000, "type": "gpos50" }, + { "id": "q25.2", "start": 81700001, "end": 85200000, "type": "gneg" }, + { "id": "q25.3", "start": 85200001, "end": 89100000, "type": "gpos50" }, + { "id": "q26.1", "start": 89100001, "end": 94300000, "type": "gneg" }, + { "id": "q26.2", "start": 94300001, "end": 98500000, "type": "gpos50" }, + { "id": "q26.3", "start": 98500001, "end": 102531392, "type": "gneg" } ] }, "16": { - "size": 90354753, - "bands": [ - { - "id": "p11.1", - "start": 34600001, - "end": 36600000, - "type": "acen" - }, - { - "id": "p11.2", - "start": 28100001, - "end": 34600000, - "type": "gneg" - }, - { - "id": "p12.1", - "start": 24200001, - "end": 28100000, - "type": "gpos50" - }, - { - "id": "p12.2", - "start": 21200001, - "end": 24200000, - "type": "gneg" - }, - { - "id": "p12.3", - "start": 16800001, - "end": 21200000, - "type": "gpos50" - }, - { - "id": "p13.11", - "start": 14800001, - "end": 16800000, - "type": "gneg" - }, - { - "id": "p13.12", - "start": 12600001, - "end": 14800000, - "type": "gpos50" - }, - { - "id": "p13.13", - "start": 10500001, - "end": 12600000, - "type": "gneg" - }, - { - "id": "p13.2", - "start": 7900001, - "end": 10500000, - "type": "gpos50" - }, - { - "id": "p13.3", - "start": 1, - "end": 7900000, - "type": "gneg" - }, - { - "id": "q11.1", - "start": 36600001, - "end": 38600000, - "type": "acen" - }, - { - "id": "q11.2", - "start": 38600001, - "end": 47000000, - "type": "gvar" - }, - { - "id": "q12.1", - "start": 47000001, - "end": 52600000, - "type": "gneg" - }, - { - "id": "q12.2", - "start": 52600001, - "end": 56700000, - "type": "gpos50" - }, - { - "id": "q13", - "start": 56700001, - "end": 57400000, - "type": "gneg" - }, - { - "id": "q21", - "start": 57400001, - "end": 66700000, - "type": "gpos100" - }, - { - "id": "q22.1", - "start": 66700001, - "end": 70800000, - "type": "gneg" - }, - { - "id": "q22.2", - "start": 70800001, - "end": 72900000, - "type": "gpos50" - }, - { - "id": "q22.3", - "start": 72900001, - "end": 74100000, - "type": "gneg" - }, - { - "id": "q23.1", - "start": 74100001, - "end": 79200000, - "type": "gpos75" - }, - { - "id": "q23.2", - "start": 79200001, - "end": 81700000, - "type": "gneg" - }, - { - "id": "q23.3", - "start": 81700001, - "end": 84200000, - "type": "gpos50" - }, - { - "id": "q24.1", - "start": 84200001, - "end": 87100000, - "type": "gneg" - }, - { - "id": "q24.2", - "start": 87100001, - "end": 88700000, - "type": "gpos25" - }, - { - "id": "q24.3", - "start": 88700001, - "end": 90354753, - "type": "gneg" - } + "size" : 90354753, + "bands" : [ + { "id": "p11.1", "start": 34600001, "end": 36600000, "type": "acen" }, + { "id": "p11.2", "start": 28100001, "end": 34600000, "type": "gneg" }, + { "id": "p12.1", "start": 24200001, "end": 28100000, "type": "gpos50" }, + { "id": "p12.2", "start": 21200001, "end": 24200000, "type": "gneg" }, + { "id": "p12.3", "start": 16800001, "end": 21200000, "type": "gpos50" }, + { "id": "p13.11", "start": 14800001, "end": 16800000, "type": "gneg" }, + { "id": "p13.12", "start": 12600001, "end": 14800000, "type": "gpos50" }, + { "id": "p13.13", "start": 10500001, "end": 12600000, "type": "gneg" }, + { "id": "p13.2", "start": 7900001, "end": 10500000, "type": "gpos50" }, + { "id": "p13.3", "start": 1, "end": 7900000, "type": "gneg" }, + { "id": "q11.1", "start": 36600001, "end": 38600000, "type": "acen" }, + { "id": "q11.2", "start": 38600001, "end": 47000000, "type": "gvar" }, + { "id": "q12.1", "start": 47000001, "end": 52600000, "type": "gneg" }, + { "id": "q12.2", "start": 52600001, "end": 56700000, "type": "gpos50" }, + { "id": "q13", "start": 56700001, "end": 57400000, "type": "gneg" }, + { "id": "q21", "start": 57400001, "end": 66700000, "type": "gpos100" }, + { "id": "q22.1", "start": 66700001, "end": 70800000, "type": "gneg" }, + { "id": "q22.2", "start": 70800001, "end": 72900000, "type": "gpos50" }, + { "id": "q22.3", "start": 72900001, "end": 74100000, "type": "gneg" }, + { "id": "q23.1", "start": 74100001, "end": 79200000, "type": "gpos75" }, + { "id": "q23.2", "start": 79200001, "end": 81700000, "type": "gneg" }, + { "id": "q23.3", "start": 81700001, "end": 84200000, "type": "gpos50" }, + { "id": "q24.1", "start": 84200001, "end": 87100000, "type": "gneg" }, + { "id": "q24.2", "start": 87100001, "end": 88700000, "type": "gpos25" }, + { "id": "q24.3", "start": 88700001, "end": 90354753, "type": "gneg" } ] }, "17": { - "size": 81195210, - "bands": [ - { - "id": "p11.1", - "start": 22200001, - "end": 24000000, - "type": "acen" - }, - { - "id": "p11.2", - "start": 16000001, - "end": 22200000, - "type": "gneg" - }, - { - "id": "p12", - "start": 10700001, - "end": 16000000, - "type": "gpos75" - }, - { - "id": "p13.1", - "start": 6500001, - "end": 10700000, - "type": "gneg" - }, - { - "id": "p13.2", - "start": 3300001, - "end": 6500000, - "type": "gpos50" - }, - { - "id": "p13.3", - "start": 1, - "end": 3300000, - "type": "gneg" - }, - { - "id": "q11.1", - "start": 24000001, - "end": 25800000, - "type": "acen" - }, - { - "id": "q11.2", - "start": 25800001, - "end": 31800000, - "type": "gneg" - }, - { - "id": "q12", - "start": 31800001, - "end": 38100000, - "type": "gpos50" - }, - { - "id": "q21.1", - "start": 38100001, - "end": 38400000, - "type": "gneg" - }, - { - "id": "q21.2", - "start": 38400001, - "end": 40900000, - "type": "gpos25" - }, - { - "id": "q21.31", - "start": 40900001, - "end": 44900000, - "type": "gneg" - }, - { - "id": "q21.32", - "start": 44900001, - "end": 47400000, - "type": "gpos25" - }, - { - "id": "q21.33", - "start": 47400001, - "end": 50200000, - "type": "gneg" - }, - { - "id": "q22", - "start": 50200001, - "end": 57600000, - "type": "gpos75" - }, - { - "id": "q23.1", - "start": 57600001, - "end": 58300000, - "type": "gneg" - }, - { - "id": "q23.2", - "start": 58300001, - "end": 61100000, - "type": "gpos75" - }, - { - "id": "q23.3", - "start": 61100001, - "end": 62600000, - "type": "gneg" - }, - { - "id": "q24.1", - "start": 62600001, - "end": 64200000, - "type": "gpos50" - }, - { - "id": "q24.2", - "start": 64200001, - "end": 67100000, - "type": "gneg" - }, - { - "id": "q24.3", - "start": 67100001, - "end": 70900000, - "type": "gpos75" - }, - { - "id": "q25.1", - "start": 70900001, - "end": 74800000, - "type": "gneg" - }, - { - "id": "q25.2", - "start": 74800001, - "end": 75300000, - "type": "gpos25" - }, - { - "id": "q25.3", - "start": 75300001, - "end": 81195210, - "type": "gneg" - } + "size" : 81195210, + "bands" : [ + { "id": "p11.1", "start": 22200001, "end": 24000000, "type": "acen" }, + { "id": "p11.2", "start": 16000001, "end": 22200000, "type": "gneg" }, + { "id": "p12", "start": 10700001, "end": 16000000, "type": "gpos75" }, + { "id": "p13.1", "start": 6500001, "end": 10700000, "type": "gneg" }, + { "id": "p13.2", "start": 3300001, "end": 6500000, "type": "gpos50" }, + { "id": "p13.3", "start": 1, "end": 3300000, "type": "gneg" }, + { "id": "q11.1", "start": 24000001, "end": 25800000, "type": "acen" }, + { "id": "q11.2", "start": 25800001, "end": 31800000, "type": "gneg" }, + { "id": "q12", "start": 31800001, "end": 38100000, "type": "gpos50" }, + { "id": "q21.1", "start": 38100001, "end": 38400000, "type": "gneg" }, + { "id": "q21.2", "start": 38400001, "end": 40900000, "type": "gpos25" }, + { "id": "q21.31", "start": 40900001, "end": 44900000, "type": "gneg" }, + { "id": "q21.32", "start": 44900001, "end": 47400000, "type": "gpos25" }, + { "id": "q21.33", "start": 47400001, "end": 50200000, "type": "gneg" }, + { "id": "q22", "start": 50200001, "end": 57600000, "type": "gpos75" }, + { "id": "q23.1", "start": 57600001, "end": 58300000, "type": "gneg" }, + { "id": "q23.2", "start": 58300001, "end": 61100000, "type": "gpos75" }, + { "id": "q23.3", "start": 61100001, "end": 62600000, "type": "gneg" }, + { "id": "q24.1", "start": 62600001, "end": 64200000, "type": "gpos50" }, + { "id": "q24.2", "start": 64200001, "end": 67100000, "type": "gneg" }, + { "id": "q24.3", "start": 67100001, "end": 70900000, "type": "gpos75" }, + { "id": "q25.1", "start": 70900001, "end": 74800000, "type": "gneg" }, + { "id": "q25.2", "start": 74800001, "end": 75300000, "type": "gpos25" }, + { "id": "q25.3", "start": 75300001, "end": 81195210, "type": "gneg" } ] }, "18": { - "size": 78077248, - "bands": [ - { - "id": "p11.1", - "start": 15400001, - "end": 17200000, - "type": "acen" - }, - { - "id": "p11.21", - "start": 10900001, - "end": 15400000, - "type": "gneg" - }, - { - "id": "p11.22", - "start": 8500001, - "end": 10900000, - "type": "gpos25" - }, - { - "id": "p11.23", - "start": 7100001, - "end": 8500000, - "type": "gneg" - }, - { - "id": "p11.31", - "start": 2900001, - "end": 7100000, - "type": "gpos50" - }, - { - "id": "p11.32", - "start": 1, - "end": 2900000, - "type": "gneg" - }, - { - "id": "q11.1", - "start": 17200001, - "end": 19000000, - "type": "acen" - }, - { - "id": "q11.2", - "start": 19000001, - "end": 25000000, - "type": "gneg" - }, - { - "id": "q12.1", - "start": 25000001, - "end": 32700000, - "type": "gpos100" - }, - { - "id": "q12.2", - "start": 32700001, - "end": 37200000, - "type": "gneg" - }, - { - "id": "q12.3", - "start": 37200001, - "end": 43500000, - "type": "gpos75" - }, - { - "id": "q21.1", - "start": 43500001, - "end": 48200000, - "type": "gneg" - }, - { - "id": "q21.2", - "start": 48200001, - "end": 53800000, - "type": "gpos75" - }, - { - "id": "q21.31", - "start": 53800001, - "end": 56200000, - "type": "gneg" - }, - { - "id": "q21.32", - "start": 56200001, - "end": 59000000, - "type": "gpos50" - }, - { - "id": "q21.33", - "start": 59000001, - "end": 61600000, - "type": "gneg" - }, - { - "id": "q22.1", - "start": 61600001, - "end": 66800000, - "type": "gpos100" - }, - { - "id": "q22.2", - "start": 66800001, - "end": 68700000, - "type": "gneg" - }, - { - "id": "q22.3", - "start": 68700001, - "end": 73100000, - "type": "gpos25" - }, - { - "id": "q23", - "start": 73100001, - "end": 78077248, - "type": "gneg" - } + "size" : 78077248, + "bands" : [ + { "id": "p11.1", "start": 15400001, "end": 17200000, "type": "acen" }, + { "id": "p11.21", "start": 10900001, "end": 15400000, "type": "gneg" }, + { "id": "p11.22", "start": 8500001, "end": 10900000, "type": "gpos25" }, + { "id": "p11.23", "start": 7100001, "end": 8500000, "type": "gneg" }, + { "id": "p11.31", "start": 2900001, "end": 7100000, "type": "gpos50" }, + { "id": "p11.32", "start": 1, "end": 2900000, "type": "gneg" }, + { "id": "q11.1", "start": 17200001, "end": 19000000, "type": "acen" }, + { "id": "q11.2", "start": 19000001, "end": 25000000, "type": "gneg" }, + { "id": "q12.1", "start": 25000001, "end": 32700000, "type": "gpos100" }, + { "id": "q12.2", "start": 32700001, "end": 37200000, "type": "gneg" }, + { "id": "q12.3", "start": 37200001, "end": 43500000, "type": "gpos75" }, + { "id": "q21.1", "start": 43500001, "end": 48200000, "type": "gneg" }, + { "id": "q21.2", "start": 48200001, "end": 53800000, "type": "gpos75" }, + { "id": "q21.31", "start": 53800001, "end": 56200000, "type": "gneg" }, + { "id": "q21.32", "start": 56200001, "end": 59000000, "type": "gpos50" }, + { "id": "q21.33", "start": 59000001, "end": 61600000, "type": "gneg" }, + { "id": "q22.1", "start": 61600001, "end": 66800000, "type": "gpos100" }, + { "id": "q22.2", "start": 66800001, "end": 68700000, "type": "gneg" }, + { "id": "q22.3", "start": 68700001, "end": 73100000, "type": "gpos25" }, + { "id": "q23", "start": 73100001, "end": 78077248, "type": "gneg" } ] }, "19": { - "size": 59128983, - "bands": [ - { - "id": "p11", - "start": 24400001, - "end": 26500000, - "type": "acen" - }, - { - "id": "p12", - "start": 20000001, - "end": 24400000, - "type": "gvar" - }, - { - "id": "p13.11", - "start": 16300001, - "end": 20000000, - "type": "gneg" - }, - { - "id": "p13.12", - "start": 14000001, - "end": 16300000, - "type": "gpos25" - }, - { - "id": "p13.13", - "start": 13900001, - "end": 14000000, - "type": "gneg" - }, - { - "id": "p13.2", - "start": 6900001, - "end": 13900000, - "type": "gpos25" - }, - { - "id": "p13.3", - "start": 1, - "end": 6900000, - "type": "gneg" - }, - { - "id": "q11", - "start": 26500001, - "end": 28600000, - "type": "acen" - }, - { - "id": "q12", - "start": 28600001, - "end": 32400000, - "type": "gvar" - }, - { - "id": "q13.11", - "start": 32400001, - "end": 35500000, - "type": "gneg" - }, - { - "id": "q13.12", - "start": 35500001, - "end": 38300000, - "type": "gpos25" - }, - { - "id": "q13.13", - "start": 38300001, - "end": 38700000, - "type": "gneg" - }, - { - "id": "q13.2", - "start": 38700001, - "end": 43400000, - "type": "gpos25" - }, - { - "id": "q13.31", - "start": 43400001, - "end": 45200000, - "type": "gneg" - }, - { - "id": "q13.32", - "start": 45200001, - "end": 48000000, - "type": "gpos25" - }, - { - "id": "q13.33", - "start": 48000001, - "end": 51400000, - "type": "gneg" - }, - { - "id": "q13.41", - "start": 51400001, - "end": 53600000, - "type": "gpos25" - }, - { - "id": "q13.42", - "start": 53600001, - "end": 56300000, - "type": "gneg" - }, - { - "id": "q13.43", - "start": 56300001, - "end": 59128983, - "type": "gpos25" - } + "size" : 59128983, + "bands" : [ + { "id": "p11", "start": 24400001, "end": 26500000, "type": "acen" }, + { "id": "p12", "start": 20000001, "end": 24400000, "type": "gvar" }, + { "id": "p13.11", "start": 16300001, "end": 20000000, "type": "gneg" }, + { "id": "p13.12", "start": 14000001, "end": 16300000, "type": "gpos25" }, + { "id": "p13.13", "start": 13900001, "end": 14000000, "type": "gneg" }, + { "id": "p13.2", "start": 6900001, "end": 13900000, "type": "gpos25" }, + { "id": "p13.3", "start": 1, "end": 6900000, "type": "gneg" }, + { "id": "q11", "start": 26500001, "end": 28600000, "type": "acen" }, + { "id": "q12", "start": 28600001, "end": 32400000, "type": "gvar" }, + { "id": "q13.11", "start": 32400001, "end": 35500000, "type": "gneg" }, + { "id": "q13.12", "start": 35500001, "end": 38300000, "type": "gpos25" }, + { "id": "q13.13", "start": 38300001, "end": 38700000, "type": "gneg" }, + { "id": "q13.2", "start": 38700001, "end": 43400000, "type": "gpos25" }, + { "id": "q13.31", "start": 43400001, "end": 45200000, "type": "gneg" }, + { "id": "q13.32", "start": 45200001, "end": 48000000, "type": "gpos25" }, + { "id": "q13.33", "start": 48000001, "end": 51400000, "type": "gneg" }, + { "id": "q13.41", "start": 51400001, "end": 53600000, "type": "gpos25" }, + { "id": "q13.42", "start": 53600001, "end": 56300000, "type": "gneg" }, + { "id": "q13.43", "start": 56300001, "end": 59128983, "type": "gpos25" } ] }, "20": { - "size": 63025520, - "bands": [ - { - "id": "p11.1", - "start": 25600001, - "end": 27500000, - "type": "acen" - }, - { - "id": "p11.21", - "start": 22300001, - "end": 25600000, - "type": "gneg" - }, - { - "id": "p11.22", - "start": 21300001, - "end": 22300000, - "type": "gpos25" - }, - { - "id": "p11.23", - "start": 17900001, - "end": 21300000, - "type": "gneg" - }, - { - "id": "p12.1", - "start": 12100001, - "end": 17900000, - "type": "gpos75" - }, - { - "id": "p12.2", - "start": 9200001, - "end": 12100000, - "type": "gneg" - }, - { - "id": "p12.3", - "start": 5100001, - "end": 9200000, - "type": "gpos75" - }, - { - "id": "p13", - "start": 1, - "end": 5100000, - "type": "gneg" - }, - { - "id": "q11.1", - "start": 27500001, - "end": 29400000, - "type": "acen" - }, - { - "id": "q11.21", - "start": 29400001, - "end": 32100000, - "type": "gneg" - }, - { - "id": "q11.22", - "start": 32100001, - "end": 34400000, - "type": "gpos25" - }, - { - "id": "q11.23", - "start": 34400001, - "end": 37600000, - "type": "gneg" - }, - { - "id": "q12", - "start": 37600001, - "end": 41700000, - "type": "gpos75" - }, - { - "id": "q13.11", - "start": 41700001, - "end": 42100000, - "type": "gneg" - }, - { - "id": "q13.12", - "start": 42100001, - "end": 46400000, - "type": "gpos25" - }, - { - "id": "q13.13", - "start": 46400001, - "end": 49800000, - "type": "gneg" - }, - { - "id": "q13.2", - "start": 49800001, - "end": 55000000, - "type": "gpos75" - }, - { - "id": "q13.31", - "start": 55000001, - "end": 56500000, - "type": "gneg" - }, - { - "id": "q13.32", - "start": 56500001, - "end": 58400000, - "type": "gpos50" - }, - { - "id": "q13.33", - "start": 58400001, - "end": 63025520, - "type": "gneg" - } + "size" : 63025520, + "bands" : [ + { "id": "p11.1", "start": 25600001, "end": 27500000, "type": "acen" }, + { "id": "p11.21", "start": 22300001, "end": 25600000, "type": "gneg" }, + { "id": "p11.22", "start": 21300001, "end": 22300000, "type": "gpos25" }, + { "id": "p11.23", "start": 17900001, "end": 21300000, "type": "gneg" }, + { "id": "p12.1", "start": 12100001, "end": 17900000, "type": "gpos75" }, + { "id": "p12.2", "start": 9200001, "end": 12100000, "type": "gneg" }, + { "id": "p12.3", "start": 5100001, "end": 9200000, "type": "gpos75" }, + { "id": "p13", "start": 1, "end": 5100000, "type": "gneg" }, + { "id": "q11.1", "start": 27500001, "end": 29400000, "type": "acen" }, + { "id": "q11.21", "start": 29400001, "end": 32100000, "type": "gneg" }, + { "id": "q11.22", "start": 32100001, "end": 34400000, "type": "gpos25" }, + { "id": "q11.23", "start": 34400001, "end": 37600000, "type": "gneg" }, + { "id": "q12", "start": 37600001, "end": 41700000, "type": "gpos75" }, + { "id": "q13.11", "start": 41700001, "end": 42100000, "type": "gneg" }, + { "id": "q13.12", "start": 42100001, "end": 46400000, "type": "gpos25" }, + { "id": "q13.13", "start": 46400001, "end": 49800000, "type": "gneg" }, + { "id": "q13.2", "start": 49800001, "end": 55000000, "type": "gpos75" }, + { "id": "q13.31", "start": 55000001, "end": 56500000, "type": "gneg" }, + { "id": "q13.32", "start": 56500001, "end": 58400000, "type": "gpos50" }, + { "id": "q13.33", "start": 58400001, "end": 63025520, "type": "gneg" } ] }, "21": { - "size": 48129895, - "bands": [ - { - "id": "p11.1", - "start": 10900001, - "end": 13200000, - "type": "acen" - }, - { - "id": "p11.2", - "start": 6800001, - "end": 10900000, - "type": "gvar" - }, - { - "id": "p12", - "start": 2800001, - "end": 6800000, - "type": "stalk" - }, - { - "id": "p13", - "start": 1, - "end": 2800000, - "type": "gvar" - }, - { - "id": "q11.1", - "start": 13200001, - "end": 14300000, - "type": "acen" - }, - { - "id": "q11.2", - "start": 14300001, - "end": 16400000, - "type": "gneg" - }, - { - "id": "q21.1", - "start": 16400001, - "end": 24000000, - "type": "gpos100" - }, - { - "id": "q21.2", - "start": 24000001, - "end": 26800000, - "type": "gneg" - }, - { - "id": "q21.3", - "start": 26800001, - "end": 31500000, - "type": "gpos75" - }, - { - "id": "q22.11", - "start": 31500001, - "end": 35800000, - "type": "gneg" - }, - { - "id": "q22.12", - "start": 35800001, - "end": 37800000, - "type": "gpos50" - }, - { - "id": "q22.13", - "start": 37800001, - "end": 39700000, - "type": "gneg" - }, - { - "id": "q22.2", - "start": 39700001, - "end": 42600000, - "type": "gpos50" - }, - { - "id": "q22.3", - "start": 42600001, - "end": 48129895, - "type": "gneg" - } + "size" : 48129895, + "bands" : [ + { "id": "p11.1", "start": 10900001, "end": 13200000, "type": "acen" }, + { "id": "p11.2", "start": 6800001, "end": 10900000, "type": "gvar" }, + { "id": "p12", "start": 2800001, "end": 6800000, "type": "stalk" }, + { "id": "p13", "start": 1, "end": 2800000, "type": "gvar" }, + { "id": "q11.1", "start": 13200001, "end": 14300000, "type": "acen" }, + { "id": "q11.2", "start": 14300001, "end": 16400000, "type": "gneg" }, + { "id": "q21.1", "start": 16400001, "end": 24000000, "type": "gpos100" }, + { "id": "q21.2", "start": 24000001, "end": 26800000, "type": "gneg" }, + { "id": "q21.3", "start": 26800001, "end": 31500000, "type": "gpos75" }, + { "id": "q22.11", "start": 31500001, "end": 35800000, "type": "gneg" }, + { "id": "q22.12", "start": 35800001, "end": 37800000, "type": "gpos50" }, + { "id": "q22.13", "start": 37800001, "end": 39700000, "type": "gneg" }, + { "id": "q22.2", "start": 39700001, "end": 42600000, "type": "gpos50" }, + { "id": "q22.3", "start": 42600001, "end": 48129895, "type": "gneg" } ] }, "22": { - "size": 51304566, - "bands": [ - { - "id": "p11.1", - "start": 12200001, - "end": 14700000, - "type": "acen" - }, - { - "id": "p11.2", - "start": 8300001, - "end": 12200000, - "type": "gvar" - }, - { - "id": "p12", - "start": 3800001, - "end": 8300000, - "type": "stalk" - }, - { - "id": "p13", - "start": 1, - "end": 3800000, - "type": "gvar" - }, - { - "id": "q11.1", - "start": 14700001, - "end": 17900000, - "type": "acen" - }, - { - "id": "q11.21", - "start": 17900001, - "end": 22200000, - "type": "gneg" - }, - { - "id": "q11.22", - "start": 22200001, - "end": 23500000, - "type": "gpos25" - }, - { - "id": "q11.23", - "start": 23500001, - "end": 25900000, - "type": "gneg" - }, - { - "id": "q12.1", - "start": 25900001, - "end": 29600000, - "type": "gpos50" - }, - { - "id": "q12.2", - "start": 29600001, - "end": 32200000, - "type": "gneg" - }, - { - "id": "q12.3", - "start": 32200001, - "end": 37600000, - "type": "gpos50" - }, - { - "id": "q13.1", - "start": 37600001, - "end": 41000000, - "type": "gneg" - }, - { - "id": "q13.2", - "start": 41000001, - "end": 44200000, - "type": "gpos50" - }, - { - "id": "q13.31", - "start": 44200001, - "end": 48400000, - "type": "gneg" - }, - { - "id": "q13.32", - "start": 48400001, - "end": 49400000, - "type": "gpos50" - }, - { - "id": "q13.33", - "start": 49400001, - "end": 51304566, - "type": "gneg" - } + "size" : 51304566, + "bands" : [ + { "id": "p11.1", "start": 12200001, "end": 14700000, "type": "acen" }, + { "id": "p11.2", "start": 8300001, "end": 12200000, "type": "gvar" }, + { "id": "p12", "start": 3800001, "end": 8300000, "type": "stalk" }, + { "id": "p13", "start": 1, "end": 3800000, "type": "gvar" }, + { "id": "q11.1", "start": 14700001, "end": 17900000, "type": "acen" }, + { "id": "q11.21", "start": 17900001, "end": 22200000, "type": "gneg" }, + { "id": "q11.22", "start": 22200001, "end": 23500000, "type": "gpos25" }, + { "id": "q11.23", "start": 23500001, "end": 25900000, "type": "gneg" }, + { "id": "q12.1", "start": 25900001, "end": 29600000, "type": "gpos50" }, + { "id": "q12.2", "start": 29600001, "end": 32200000, "type": "gneg" }, + { "id": "q12.3", "start": 32200001, "end": 37600000, "type": "gpos50" }, + { "id": "q13.1", "start": 37600001, "end": 41000000, "type": "gneg" }, + { "id": "q13.2", "start": 41000001, "end": 44200000, "type": "gpos50" }, + { "id": "q13.31", "start": 44200001, "end": 48400000, "type": "gneg" }, + { "id": "q13.32", "start": 48400001, "end": 49400000, "type": "gpos50" }, + { "id": "q13.33", "start": 49400001, "end": 51304566, "type": "gneg" } ] }, "X": { - "size": 155270560, - "bands": [ - { - "id": "p11.1", - "start": 58100001, - "end": 60600000, - "type": "acen" - }, - { - "id": "p11.21", - "start": 54800001, - "end": 58100000, - "type": "gneg" - }, - { - "id": "p11.22", - "start": 49800001, - "end": 54800000, - "type": "gpos25" - }, - { - "id": "p11.23", - "start": 46400001, - "end": 49800000, - "type": "gneg" - }, - { - "id": "p11.3", - "start": 42400001, - "end": 46400000, - "type": "gpos75" - }, - { - "id": "p11.4", - "start": 37600001, - "end": 42400000, - "type": "gneg" - }, - { - "id": "p21.1", - "start": 31500001, - "end": 37600000, - "type": "gpos100" - }, - { - "id": "p21.2", - "start": 29300001, - "end": 31500000, - "type": "gneg" - }, - { - "id": "p21.3", - "start": 24900001, - "end": 29300000, - "type": "gpos100" - }, - { - "id": "p22.11", - "start": 21900001, - "end": 24900000, - "type": "gneg" - }, - { - "id": "p22.12", - "start": 19300001, - "end": 21900000, - "type": "gpos50" - }, - { - "id": "p22.13", - "start": 17100001, - "end": 19300000, - "type": "gneg" - }, - { - "id": "p22.2", - "start": 9500001, - "end": 17100000, - "type": "gpos50" - }, - { - "id": "p22.31", - "start": 6000001, - "end": 9500000, - "type": "gneg" - }, - { - "id": "p22.32", - "start": 4300001, - "end": 6000000, - "type": "gpos50" - }, - { - "id": "p22.33", - "start": 1, - "end": 4300000, - "type": "gneg" - }, - { - "id": "q11.1", - "start": 60600001, - "end": 63000000, - "type": "acen" - }, - { - "id": "q11.2", - "start": 63000001, - "end": 64600000, - "type": "gneg" - }, - { - "id": "q12", - "start": 64600001, - "end": 67800000, - "type": "gpos50" - }, - { - "id": "q13.1", - "start": 67800001, - "end": 71800000, - "type": "gneg" - }, - { - "id": "q13.2", - "start": 71800001, - "end": 73900000, - "type": "gpos50" - }, - { - "id": "q13.3", - "start": 73900001, - "end": 76000000, - "type": "gneg" - }, - { - "id": "q21.1", - "start": 76000001, - "end": 84600000, - "type": "gpos100" - }, - { - "id": "q21.2", - "start": 84600001, - "end": 86200000, - "type": "gneg" - }, - { - "id": "q21.31", - "start": 86200001, - "end": 91800000, - "type": "gpos100" - }, - { - "id": "q21.32", - "start": 91800001, - "end": 93500000, - "type": "gneg" - }, - { - "id": "q21.33", - "start": 93500001, - "end": 98300000, - "type": "gpos75" - }, - { - "id": "q22.1", - "start": 98300001, - "end": 102600000, - "type": "gneg" - }, - { - "id": "q22.2", - "start": 102600001, - "end": 103700000, - "type": "gpos50" - }, - { - "id": "q22.3", - "start": 103700001, - "end": 108700000, - "type": "gneg" - }, - { - "id": "q23", - "start": 108700001, - "end": 116500000, - "type": "gpos75" - }, - { - "id": "q24", - "start": 116500001, - "end": 120900000, - "type": "gneg" - }, - { - "id": "q25", - "start": 120900001, - "end": 128700000, - "type": "gpos100" - }, - { - "id": "q26.1", - "start": 128700001, - "end": 130400000, - "type": "gneg" - }, - { - "id": "q26.2", - "start": 130400001, - "end": 133600000, - "type": "gpos25" - }, - { - "id": "q26.3", - "start": 133600001, - "end": 138000000, - "type": "gneg" - }, - { - "id": "q27.1", - "start": 138000001, - "end": 140300000, - "type": "gpos75" - }, - { - "id": "q27.2", - "start": 140300001, - "end": 142100000, - "type": "gneg" - }, - { - "id": "q27.3", - "start": 142100001, - "end": 147100000, - "type": "gpos100" - }, - { - "id": "q28", - "start": 147100001, - "end": 155270560, - "type": "gneg" - } + "size" : 155270560, + "bands" : [ + { "id": "p11.1", "start": 58100001, "end": 60600000, "type": "acen" }, + { "id": "p11.21", "start": 54800001, "end": 58100000, "type": "gneg" }, + { "id": "p11.22", "start": 49800001, "end": 54800000, "type": "gpos25" }, + { "id": "p11.23", "start": 46400001, "end": 49800000, "type": "gneg" }, + { "id": "p11.3", "start": 42400001, "end": 46400000, "type": "gpos75" }, + { "id": "p11.4", "start": 37600001, "end": 42400000, "type": "gneg" }, + { "id": "p21.1", "start": 31500001, "end": 37600000, "type": "gpos100" }, + { "id": "p21.2", "start": 29300001, "end": 31500000, "type": "gneg" }, + { "id": "p21.3", "start": 24900001, "end": 29300000, "type": "gpos100" }, + { "id": "p22.11", "start": 21900001, "end": 24900000, "type": "gneg" }, + { "id": "p22.12", "start": 19300001, "end": 21900000, "type": "gpos50" }, + { "id": "p22.13", "start": 17100001, "end": 19300000, "type": "gneg" }, + { "id": "p22.2", "start": 9500001, "end": 17100000, "type": "gpos50" }, + { "id": "p22.31", "start": 6000001, "end": 9500000, "type": "gneg" }, + { "id": "p22.32", "start": 4300001, "end": 6000000, "type": "gpos50" }, + { "id": "p22.33", "start": 1, "end": 4300000, "type": "gneg" }, + { "id": "q11.1", "start": 60600001, "end": 63000000, "type": "acen" }, + { "id": "q11.2", "start": 63000001, "end": 64600000, "type": "gneg" }, + { "id": "q12", "start": 64600001, "end": 67800000, "type": "gpos50" }, + { "id": "q13.1", "start": 67800001, "end": 71800000, "type": "gneg" }, + { "id": "q13.2", "start": 71800001, "end": 73900000, "type": "gpos50" }, + { "id": "q13.3", "start": 73900001, "end": 76000000, "type": "gneg" }, + { "id": "q21.1", "start": 76000001, "end": 84600000, "type": "gpos100" }, + { "id": "q21.2", "start": 84600001, "end": 86200000, "type": "gneg" }, + { "id": "q21.31", "start": 86200001, "end": 91800000, "type": "gpos100" }, + { "id": "q21.32", "start": 91800001, "end": 93500000, "type": "gneg" }, + { "id": "q21.33", "start": 93500001, "end": 98300000, "type": "gpos75" }, + { "id": "q22.1", "start": 98300001, "end": 102600000, "type": "gneg" }, + { "id": "q22.2", "start": 102600001, "end": 103700000, "type": "gpos50" }, + { "id": "q22.3", "start": 103700001, "end": 108700000, "type": "gneg" }, + { "id": "q23", "start": 108700001, "end": 116500000, "type": "gpos75" }, + { "id": "q24", "start": 116500001, "end": 120900000, "type": "gneg" }, + { "id": "q25", "start": 120900001, "end": 128700000, "type": "gpos100" }, + { "id": "q26.1", "start": 128700001, "end": 130400000, "type": "gneg" }, + { "id": "q26.2", "start": 130400001, "end": 133600000, "type": "gpos25" }, + { "id": "q26.3", "start": 133600001, "end": 138000000, "type": "gneg" }, + { "id": "q27.1", "start": 138000001, "end": 140300000, "type": "gpos75" }, + { "id": "q27.2", "start": 140300001, "end": 142100000, "type": "gneg" }, + { "id": "q27.3", "start": 142100001, "end": 147100000, "type": "gpos100" }, + { "id": "q28", "start": 147100001, "end": 155270560, "type": "gneg" } ] }, "Y": { - "size": 59373566, - "bands": [ - { - "id": "p11.1", - "start": 11600001, - "end": 12500000, - "type": "acen" - }, - { - "id": "p11.2", - "start": 3000001, - "end": 11600000, - "type": "gneg" - }, - { - "id": "p11.31", - "start": 2500001, - "end": 3000000, - "type": "gpos50" - }, - { - "id": "p11.32", - "start": 1, - "end": 2500000, - "type": "gneg" - }, - { - "id": "q11.1", - "start": 12500001, - "end": 13400000, - "type": "acen" - }, - { - "id": "q11.21", - "start": 13400001, - "end": 15100000, - "type": "gneg" - }, - { - "id": "q11.221", - "start": 15100001, - "end": 19800000, - "type": "gpos50" - }, - { - "id": "q11.222", - "start": 19800001, - "end": 22100000, - "type": "gneg" - }, - { - "id": "q11.223", - "start": 22100001, - "end": 26200000, - "type": "gpos50" - }, - { - "id": "q11.23", - "start": 26200001, - "end": 28800000, - "type": "gneg" - }, - { - "id": "q12", - "start": 28800001, - "end": 59373566, - "type": "gvar" - } + "size" : 59373566, + "bands" : [ + { "id": "p11.1", "start": 11600001, "end": 12500000, "type": "acen" }, + { "id": "p11.2", "start": 3000001, "end": 11600000, "type": "gneg" }, + { "id": "p11.31", "start": 2500001, "end": 3000000, "type": "gpos50" }, + { "id": "p11.32", "start": 1, "end": 2500000, "type": "gneg" }, + { "id": "q11.1", "start": 12500001, "end": 13400000, "type": "acen" }, + { "id": "q11.21", "start": 13400001, "end": 15100000, "type": "gneg" }, + { "id": "q11.221", "start": 15100001, "end": 19800000, "type": "gpos50" }, + { "id": "q11.222", "start": 19800001, "end": 22100000, "type": "gneg" }, + { "id": "q11.223", "start": 22100001, "end": 26200000, "type": "gpos50" }, + { "id": "q11.23", "start": 26200001, "end": 28800000, "type": "gneg" }, + { "id": "q12", "start": 28800001, "end": 59373566, "type": "gvar" } ] }, "MT": { - "size": 16569, - "bands": [ - { - "start": 1, - "end": 16569 - } + "size" : 16569, + "bands" : [ + { "start": 1, "end": 16569 } ] } -}; +}; \ No newline at end of file diff --git a/js/genomes/grch38.js b/js/genomes/grch38.js index a9fccdd7..ac530789 100644 --- a/js/genomes/grch38.js +++ b/js/genomes/grch38.js @@ -1,5303 +1,990 @@ window.grch38 = { "1": { - "size": 248956422, - "bands": [ - { - "id": "q25.2", - "start": 176100001, - "end": 180300000, - "type": "gpos50" - }, - { - "id": "p34.1", - "start": 43700001, - "end": 46300000, - "type": "gneg" - }, - { - "id": "p36.23", - "start": 7100001, - "end": 9100000, - "type": "gpos25" - }, - { - "id": "p21.3", - "start": 94300001, - "end": 99300000, - "type": "gpos75" - }, - { - "id": "q24.1", - "start": 165500001, - "end": 167200000, - "type": "gpos50" - }, - { - "id": "p36.22", - "start": 9100001, - "end": 12500000, - "type": "gneg" - }, - { - "id": "p35.1", - "start": 32300001, - "end": 34300000, - "type": "gpos25" - }, - { - "id": "p13.3", - "start": 106700001, - "end": 111200000, - "type": "gneg" - }, - { - "id": "q23.2", - "start": 159100001, - "end": 160500000, - "type": "gpos50" - }, - { - "id": "q21.1", - "start": 143200001, - "end": 147500000, - "type": "gneg" - }, - { - "id": "p32.1", - "start": 58500001, - "end": 60800000, - "type": "gneg" - }, - { - "id": "p22.2", - "start": 87900001, - "end": 91500000, - "type": "gpos75" - }, - { - "id": "q24.2", - "start": 167200001, - "end": 170900000, - "type": "gneg" - }, - { - "id": "p34.2", - "start": 39600001, - "end": 43700000, - "type": "gpos25" - }, - { - "id": "q44", - "start": 243500001, - "end": 248956422, - "type": "gneg" - }, - { - "id": "q25.3", - "start": 180300001, - "end": 185800000, - "type": "gneg" - }, - { - "id": "q42.3", - "start": 234600001, - "end": 236400000, - "type": "gneg" - }, - { - "id": "q41", - "start": 214400001, - "end": 223900000, - "type": "gpos100" - }, - { - "id": "p36.33", - "start": 1, - "end": 2300000, - "type": "gneg" - }, - { - "id": "p13.2", - "start": 111200001, - "end": 115500000, - "type": "gpos50" - }, - { - "id": "p32.3", - "start": 50200001, - "end": 55600000, - "type": "gneg" - }, - { - "id": "p36.21", - "start": 12500001, - "end": 15900000, - "type": "gpos50" - }, - { - "id": "p11.2", - "start": 120400001, - "end": 121700000, - "type": "gneg" - }, - { - "id": "p12", - "start": 117200001, - "end": 120400000, - "type": "gpos50" - }, - { - "id": "p13.1", - "start": 115500001, - "end": 117200000, - "type": "gneg" - }, - { - "id": "q24.3", - "start": 170900001, - "end": 173000000, - "type": "gpos75" - }, - { - "id": "q21.3", - "start": 150600001, - "end": 155100000, - "type": "gneg" - }, - { - "id": "p31.2", - "start": 68500001, - "end": 69300000, - "type": "gneg" - }, - { - "id": "p33", - "start": 46300001, - "end": 50200000, - "type": "gpos75" - }, - { - "id": "q42.12", - "start": 224400001, - "end": 226800000, - "type": "gpos25" - }, - { - "id": "p36.13", - "start": 15900001, - "end": 20100000, - "type": "gneg" - }, - { - "id": "p32.2", - "start": 55600001, - "end": 58500000, - "type": "gpos50" - }, - { - "id": "p34.3", - "start": 34300001, - "end": 39600000, - "type": "gneg" - }, - { - "id": "q42.13", - "start": 226800001, - "end": 230500000, - "type": "gneg" - }, - { - "id": "p11.1", - "start": 121700001, - "end": 123400000, - "type": "acen" - }, - { - "id": "p31.3", - "start": 60800001, - "end": 68500000, - "type": "gpos50" - }, - { - "id": "p36.12", - "start": 20100001, - "end": 23600000, - "type": "gpos25" - }, - { - "id": "q25.1", - "start": 173000001, - "end": 176100000, - "type": "gneg" - }, - { - "id": "p21.1", - "start": 101800001, - "end": 106700000, - "type": "gpos100" - }, - { - "id": "p36.11", - "start": 23600001, - "end": 27600000, - "type": "gneg" - }, - { - "id": "q43", - "start": 236400001, - "end": 243500000, - "type": "gpos75" - }, - { - "id": "q32.1", - "start": 198700001, - "end": 207100000, - "type": "gneg" - }, - { - "id": "p31.1", - "start": 69300001, - "end": 84400000, - "type": "gpos100" - }, - { - "id": "q42.11", - "start": 223900001, - "end": 224400000, - "type": "gneg" - }, - { - "id": "p35.3", - "start": 27600001, - "end": 29900000, - "type": "gpos25" - }, - { - "id": "q21.2", - "start": 147500001, - "end": 150600000, - "type": "gpos50" - }, - { - "id": "p22.1", - "start": 91500001, - "end": 94300000, - "type": "gneg" - }, - { - "id": "q31.2", - "start": 190800001, - "end": 193800000, - "type": "gneg" - }, - { - "id": "p36.32", - "start": 2300001, - "end": 5300000, - "type": "gpos25" - }, - { - "id": "p21.2", - "start": 99300001, - "end": 101800000, - "type": "gneg" - }, - { - "id": "q31.3", - "start": 193800001, - "end": 198700000, - "type": "gpos100" - }, - { - "id": "q23.1", - "start": 156600001, - "end": 159100000, - "type": "gneg" - }, - { - "id": "p22.3", - "start": 84400001, - "end": 87900000, - "type": "gneg" - }, - { - "id": "p35.2", - "start": 29900001, - "end": 32300000, - "type": "gneg" - }, - { - "id": "q22", - "start": 155100001, - "end": 156600000, - "type": "gpos50" - }, - { - "id": "q31.1", - "start": 185800001, - "end": 190800000, - "type": "gpos100" - }, - { - "id": "q32.2", - "start": 207100001, - "end": 211300000, - "type": "gpos25" - }, - { - "id": "q12", - "start": 125100001, - "end": 143200000, - "type": "gvar" - }, - { - "id": "q42.2", - "start": 230500001, - "end": 234600000, - "type": "gpos50" - }, - { - "id": "q23.3", - "start": 160500001, - "end": 165500000, - "type": "gneg" - }, - { - "id": "q32.3", - "start": 211300001, - "end": 214400000, - "type": "gneg" - }, - { - "id": "q11", - "start": 123400001, - "end": 125100000, - "type": "acen" - }, - { - "id": "p36.31", - "start": 5300001, - "end": 7100000, - "type": "gneg" - } + "size" : 248956422, + "bands" : [ + { "id": "p11.1", "start": 121700001, "end": 123400000, "type": "acen" }, + { "id": "p11.2", "start": 120400001, "end": 121700000, "type": "gneg" }, + { "id": "p12", "start": 117200001, "end": 120400000, "type": "gpos50" }, + { "id": "p13.1", "start": 115500001, "end": 117200000, "type": "gneg" }, + { "id": "p13.2", "start": 111200001, "end": 115500000, "type": "gpos50" }, + { "id": "p13.3", "start": 106700001, "end": 111200000, "type": "gneg" }, + { "id": "p21.1", "start": 101800001, "end": 106700000, "type": "gpos100" }, + { "id": "p21.2", "start": 99300001, "end": 101800000, "type": "gneg" }, + { "id": "p21.3", "start": 94300001, "end": 99300000, "type": "gpos75" }, + { "id": "p22.1", "start": 91500001, "end": 94300000, "type": "gneg" }, + { "id": "p22.2", "start": 87900001, "end": 91500000, "type": "gpos75" }, + { "id": "p22.3", "start": 84400001, "end": 87900000, "type": "gneg" }, + { "id": "p31.1", "start": 69300001, "end": 84400000, "type": "gpos100" }, + { "id": "p31.2", "start": 68500001, "end": 69300000, "type": "gneg" }, + { "id": "p31.3", "start": 60800001, "end": 68500000, "type": "gpos50" }, + { "id": "p32.1", "start": 58500001, "end": 60800000, "type": "gneg" }, + { "id": "p32.2", "start": 55600001, "end": 58500000, "type": "gpos50" }, + { "id": "p32.3", "start": 50200001, "end": 55600000, "type": "gneg" }, + { "id": "p33", "start": 46300001, "end": 50200000, "type": "gpos75" }, + { "id": "p34.1", "start": 43700001, "end": 46300000, "type": "gneg" }, + { "id": "p34.2", "start": 39600001, "end": 43700000, "type": "gpos25" }, + { "id": "p34.3", "start": 34300001, "end": 39600000, "type": "gneg" }, + { "id": "p35.1", "start": 32300001, "end": 34300000, "type": "gpos25" }, + { "id": "p35.2", "start": 29900001, "end": 32300000, "type": "gneg" }, + { "id": "p35.3", "start": 27600001, "end": 29900000, "type": "gpos25" }, + { "id": "p36.11", "start": 23600001, "end": 27600000, "type": "gneg" }, + { "id": "p36.12", "start": 20100001, "end": 23600000, "type": "gpos25" }, + { "id": "p36.13", "start": 15900001, "end": 20100000, "type": "gneg" }, + { "id": "p36.21", "start": 12500001, "end": 15900000, "type": "gpos50" }, + { "id": "p36.22", "start": 9100001, "end": 12500000, "type": "gneg" }, + { "id": "p36.23", "start": 7100001, "end": 9100000, "type": "gpos25" }, + { "id": "p36.31", "start": 5300001, "end": 7100000, "type": "gneg" }, + { "id": "p36.32", "start": 2300001, "end": 5300000, "type": "gpos25" }, + { "id": "p36.33", "start": 1, "end": 2300000, "type": "gneg" }, + { "id": "q11", "start": 123400001, "end": 125100000, "type": "acen" }, + { "id": "q12", "start": 125100001, "end": 143200000, "type": "gvar" }, + { "id": "q21.1", "start": 143200001, "end": 147500000, "type": "gneg" }, + { "id": "q21.2", "start": 147500001, "end": 150600000, "type": "gpos50" }, + { "id": "q21.3", "start": 150600001, "end": 155100000, "type": "gneg" }, + { "id": "q22", "start": 155100001, "end": 156600000, "type": "gpos50" }, + { "id": "q23.1", "start": 156600001, "end": 159100000, "type": "gneg" }, + { "id": "q23.2", "start": 159100001, "end": 160500000, "type": "gpos50" }, + { "id": "q23.3", "start": 160500001, "end": 165500000, "type": "gneg" }, + { "id": "q24.1", "start": 165500001, "end": 167200000, "type": "gpos50" }, + { "id": "q24.2", "start": 167200001, "end": 170900000, "type": "gneg" }, + { "id": "q24.3", "start": 170900001, "end": 173000000, "type": "gpos75" }, + { "id": "q25.1", "start": 173000001, "end": 176100000, "type": "gneg" }, + { "id": "q25.2", "start": 176100001, "end": 180300000, "type": "gpos50" }, + { "id": "q25.3", "start": 180300001, "end": 185800000, "type": "gneg" }, + { "id": "q31.1", "start": 185800001, "end": 190800000, "type": "gpos100" }, + { "id": "q31.2", "start": 190800001, "end": 193800000, "type": "gneg" }, + { "id": "q31.3", "start": 193800001, "end": 198700000, "type": "gpos100" }, + { "id": "q32.1", "start": 198700001, "end": 207100000, "type": "gneg" }, + { "id": "q32.2", "start": 207100001, "end": 211300000, "type": "gpos25" }, + { "id": "q32.3", "start": 211300001, "end": 214400000, "type": "gneg" }, + { "id": "q41", "start": 214400001, "end": 223900000, "type": "gpos100" }, + { "id": "q42.11", "start": 223900001, "end": 224400000, "type": "gneg" }, + { "id": "q42.12", "start": 224400001, "end": 226800000, "type": "gpos25" }, + { "id": "q42.13", "start": 226800001, "end": 230500000, "type": "gneg" }, + { "id": "q42.2", "start": 230500001, "end": 234600000, "type": "gpos50" }, + { "id": "q42.3", "start": 234600001, "end": 236400000, "type": "gneg" }, + { "id": "q43", "start": 236400001, "end": 243500000, "type": "gpos75" }, + { "id": "q44", "start": 243500001, "end": 248956422, "type": "gneg" } ] }, "2": { - "size": 242193529, - "bands": [ - { - "id": "q22.1", - "start": 136100001, - "end": 141500000, - "type": "gpos100" - }, - { - "id": "q34", - "start": 208200001, - "end": 214500000, - "type": "gpos100" - }, - { - "id": "q12.1", - "start": 102100001, - "end": 105300000, - "type": "gpos50" - }, - { - "id": "q14.1", - "start": 112200001, - "end": 118100000, - "type": "gpos50" - }, - { - "id": "q24.1", - "start": 154000001, - "end": 158900000, - "type": "gpos75" - }, - { - "id": "p23.2", - "start": 27700001, - "end": 29800000, - "type": "gpos25" - }, - { - "id": "p13.3", - "start": 68400001, - "end": 71300000, - "type": "gneg" - }, - { - "id": "q23.2", - "start": 149000001, - "end": 149600000, - "type": "gpos25" - }, - { - "id": "q21.1", - "start": 129100001, - "end": 131700000, - "type": "gneg" - }, - { - "id": "q22.3", - "start": 143400001, - "end": 147900000, - "type": "gpos100" - }, - { - "id": "p22.2", - "start": 36300001, - "end": 38300000, - "type": "gneg" - }, - { - "id": "q37.3", - "start": 236400001, - "end": 242193529, - "type": "gneg" - }, - { - "id": "q33.2", - "start": 202500001, - "end": 204100000, - "type": "gpos50" - }, - { - "id": "q24.2", - "start": 158900001, - "end": 162900000, - "type": "gneg" - }, - { - "id": "q14.3", - "start": 121600001, - "end": 129100000, - "type": "gpos50" - }, - { - "id": "p16.3", - "start": 47500001, - "end": 52600000, - "type": "gpos100" - }, - { - "id": "q14.2", - "start": 118100001, - "end": 121600000, - "type": "gneg" - }, - { - "id": "q11.2", - "start": 96000001, - "end": 102100000, - "type": "gneg" - }, - { - "id": "p13.2", - "start": 71300001, - "end": 73300000, - "type": "gpos50" - }, - { - "id": "p25.2", - "start": 4400001, - "end": 6900000, - "type": "gpos50" - }, - { - "id": "p21", - "start": 41500001, - "end": 47500000, - "type": "gneg" - }, - { - "id": "p15", - "start": 61000001, - "end": 63900000, - "type": "gneg" - }, - { - "id": "p11.2", - "start": 83100001, - "end": 91800000, - "type": "gneg" - }, - { - "id": "p12", - "start": 74800001, - "end": 83100000, - "type": "gpos100" - }, - { - "id": "p16.2", - "start": 52600001, - "end": 54700000, - "type": "gneg" - }, - { - "id": "p13.1", - "start": 73300001, - "end": 74800000, - "type": "gneg" - }, - { - "id": "q33.3", - "start": 204100001, - "end": 208200000, - "type": "gneg" - }, - { - "id": "q24.3", - "start": 162900001, - "end": 168900000, - "type": "gpos75" - }, - { - "id": "q33.1", - "start": 196600001, - "end": 202500000, - "type": "gneg" - }, - { - "id": "q21.3", - "start": 134300001, - "end": 136100000, - "type": "gneg" - }, - { - "id": "p25.3", - "start": 1, - "end": 4400000, - "type": "gneg" - }, - { - "id": "p23.1", - "start": 29800001, - "end": 31800000, - "type": "gneg" - }, - { - "id": "p11.1", - "start": 91800001, - "end": 93900000, - "type": "acen" - }, - { - "id": "p24.1", - "start": 19000001, - "end": 23800000, - "type": "gpos75" - }, - { - "id": "p24.3", - "start": 12000001, - "end": 16500000, - "type": "gpos75" - }, - { - "id": "q32.1", - "start": 182100001, - "end": 188500000, - "type": "gpos75" - }, - { - "id": "q37.2", - "start": 234700001, - "end": 236400000, - "type": "gpos50" - }, - { - "id": "q36.2", - "start": 224300001, - "end": 225200000, - "type": "gneg" - }, - { - "id": "p14", - "start": 63900001, - "end": 68400000, - "type": "gpos50" - }, - { - "id": "q36.3", - "start": 225200001, - "end": 230100000, - "type": "gpos100" - }, - { - "id": "q35", - "start": 214500001, - "end": 220700000, - "type": "gneg" - }, - { - "id": "q21.2", - "start": 131700001, - "end": 134300000, - "type": "gpos25" - }, - { - "id": "p22.1", - "start": 38300001, - "end": 41500000, - "type": "gpos50" - }, - { - "id": "q31.2", - "start": 177100001, - "end": 179700000, - "type": "gpos50" - }, - { - "id": "p25.1", - "start": 6900001, - "end": 12000000, - "type": "gneg" - }, - { - "id": "q12.2", - "start": 105300001, - "end": 106700000, - "type": "gneg" - }, - { - "id": "q31.3", - "start": 179700001, - "end": 182100000, - "type": "gneg" - }, - { - "id": "q23.1", - "start": 147900001, - "end": 149000000, - "type": "gneg" - }, - { - "id": "p22.3", - "start": 31800001, - "end": 36300000, - "type": "gpos75" - }, - { - "id": "q36.1", - "start": 220700001, - "end": 224300000, - "type": "gpos75" - }, - { - "id": "p16.1", - "start": 54700001, - "end": 61000000, - "type": "gpos100" - }, - { - "id": "q13", - "start": 108700001, - "end": 112200000, - "type": "gneg" - }, - { - "id": "q31.1", - "start": 168900001, - "end": 177100000, - "type": "gneg" - }, - { - "id": "p24.2", - "start": 16500001, - "end": 19000000, - "type": "gneg" - }, - { - "id": "q32.2", - "start": 188500001, - "end": 191100000, - "type": "gneg" - }, - { - "id": "q22.2", - "start": 141500001, - "end": 143400000, - "type": "gneg" - }, - { - "id": "p23.3", - "start": 23800001, - "end": 27700000, - "type": "gneg" - }, - { - "id": "q12.3", - "start": 106700001, - "end": 108700000, - "type": "gpos25" - }, - { - "id": "q37.1", - "start": 230100001, - "end": 234700000, - "type": "gneg" - }, - { - "id": "q23.3", - "start": 149600001, - "end": 154000000, - "type": "gneg" - }, - { - "id": "q11.1", - "start": 93900001, - "end": 96000000, - "type": "acen" - }, - { - "id": "q32.3", - "start": 191100001, - "end": 196600000, - "type": "gpos75" - } + "size" : 242193529, + "bands" : [ + { "id": "p11.1", "start": 91800001, "end": 93900000, "type": "acen" }, + { "id": "p11.2", "start": 83100001, "end": 91800000, "type": "gneg" }, + { "id": "p12", "start": 74800001, "end": 83100000, "type": "gpos100" }, + { "id": "p13.1", "start": 73300001, "end": 74800000, "type": "gneg" }, + { "id": "p13.2", "start": 71300001, "end": 73300000, "type": "gpos50" }, + { "id": "p13.3", "start": 68400001, "end": 71300000, "type": "gneg" }, + { "id": "p14", "start": 63900001, "end": 68400000, "type": "gpos50" }, + { "id": "p15", "start": 61000001, "end": 63900000, "type": "gneg" }, + { "id": "p16.1", "start": 54700001, "end": 61000000, "type": "gpos100" }, + { "id": "p16.2", "start": 52600001, "end": 54700000, "type": "gneg" }, + { "id": "p16.3", "start": 47500001, "end": 52600000, "type": "gpos100" }, + { "id": "p21", "start": 41500001, "end": 47500000, "type": "gneg" }, + { "id": "p22.1", "start": 38300001, "end": 41500000, "type": "gpos50" }, + { "id": "p22.2", "start": 36300001, "end": 38300000, "type": "gneg" }, + { "id": "p22.3", "start": 31800001, "end": 36300000, "type": "gpos75" }, + { "id": "p23.1", "start": 29800001, "end": 31800000, "type": "gneg" }, + { "id": "p23.2", "start": 27700001, "end": 29800000, "type": "gpos25" }, + { "id": "p23.3", "start": 23800001, "end": 27700000, "type": "gneg" }, + { "id": "p24.1", "start": 19000001, "end": 23800000, "type": "gpos75" }, + { "id": "p24.2", "start": 16500001, "end": 19000000, "type": "gneg" }, + { "id": "p24.3", "start": 12000001, "end": 16500000, "type": "gpos75" }, + { "id": "p25.1", "start": 6900001, "end": 12000000, "type": "gneg" }, + { "id": "p25.2", "start": 4400001, "end": 6900000, "type": "gpos50" }, + { "id": "p25.3", "start": 1, "end": 4400000, "type": "gneg" }, + { "id": "q11.1", "start": 93900001, "end": 96000000, "type": "acen" }, + { "id": "q11.2", "start": 96000001, "end": 102100000, "type": "gneg" }, + { "id": "q12.1", "start": 102100001, "end": 105300000, "type": "gpos50" }, + { "id": "q12.2", "start": 105300001, "end": 106700000, "type": "gneg" }, + { "id": "q12.3", "start": 106700001, "end": 108700000, "type": "gpos25" }, + { "id": "q13", "start": 108700001, "end": 112200000, "type": "gneg" }, + { "id": "q14.1", "start": 112200001, "end": 118100000, "type": "gpos50" }, + { "id": "q14.2", "start": 118100001, "end": 121600000, "type": "gneg" }, + { "id": "q14.3", "start": 121600001, "end": 129100000, "type": "gpos50" }, + { "id": "q21.1", "start": 129100001, "end": 131700000, "type": "gneg" }, + { "id": "q21.2", "start": 131700001, "end": 134300000, "type": "gpos25" }, + { "id": "q21.3", "start": 134300001, "end": 136100000, "type": "gneg" }, + { "id": "q22.1", "start": 136100001, "end": 141500000, "type": "gpos100" }, + { "id": "q22.2", "start": 141500001, "end": 143400000, "type": "gneg" }, + { "id": "q22.3", "start": 143400001, "end": 147900000, "type": "gpos100" }, + { "id": "q23.1", "start": 147900001, "end": 149000000, "type": "gneg" }, + { "id": "q23.2", "start": 149000001, "end": 149600000, "type": "gpos25" }, + { "id": "q23.3", "start": 149600001, "end": 154000000, "type": "gneg" }, + { "id": "q24.1", "start": 154000001, "end": 158900000, "type": "gpos75" }, + { "id": "q24.2", "start": 158900001, "end": 162900000, "type": "gneg" }, + { "id": "q24.3", "start": 162900001, "end": 168900000, "type": "gpos75" }, + { "id": "q31.1", "start": 168900001, "end": 177100000, "type": "gneg" }, + { "id": "q31.2", "start": 177100001, "end": 179700000, "type": "gpos50" }, + { "id": "q31.3", "start": 179700001, "end": 182100000, "type": "gneg" }, + { "id": "q32.1", "start": 182100001, "end": 188500000, "type": "gpos75" }, + { "id": "q32.2", "start": 188500001, "end": 191100000, "type": "gneg" }, + { "id": "q32.3", "start": 191100001, "end": 196600000, "type": "gpos75" }, + { "id": "q33.1", "start": 196600001, "end": 202500000, "type": "gneg" }, + { "id": "q33.2", "start": 202500001, "end": 204100000, "type": "gpos50" }, + { "id": "q33.3", "start": 204100001, "end": 208200000, "type": "gneg" }, + { "id": "q34", "start": 208200001, "end": 214500000, "type": "gpos100" }, + { "id": "q35", "start": 214500001, "end": 220700000, "type": "gneg" }, + { "id": "q36.1", "start": 220700001, "end": 224300000, "type": "gpos75" }, + { "id": "q36.2", "start": 224300001, "end": 225200000, "type": "gneg" }, + { "id": "q36.3", "start": 225200001, "end": 230100000, "type": "gpos100" }, + { "id": "q37.1", "start": 230100001, "end": 234700000, "type": "gneg" }, + { "id": "q37.2", "start": 234700001, "end": 236400000, "type": "gpos50" }, + { "id": "q37.3", "start": 236400001, "end": 242193529, "type": "gneg" } ] }, "3": { - "size": 198295559, - "bands": [ - { - "id": "q25.2", - "start": 152300001, - "end": 155300000, - "type": "gpos50" - }, - { - "id": "q22.1", - "start": 129500001, - "end": 134000000, - "type": "gpos25" - }, - { - "id": "q12.1", - "start": 98600001, - "end": 100300000, - "type": "gneg" - }, - { - "id": "q26.31", - "start": 171200001, - "end": 176000000, - "type": "gpos75" - }, - { - "id": "q26.33", - "start": 179300001, - "end": 183000000, - "type": "gpos75" - }, - { - "id": "p12.3", - "start": 74100001, - "end": 79800000, - "type": "gpos75" - }, - { - "id": "q27.2", - "start": 184800001, - "end": 186300000, - "type": "gpos25" - }, - { - "id": "p26.2", - "start": 2800001, - "end": 4000000, - "type": "gneg" - }, - { - "id": "q24", - "start": 143100001, - "end": 149200000, - "type": "gpos100" - }, - { - "id": "q21.1", - "start": 122200001, - "end": 124100000, - "type": "gneg" - }, - { - "id": "q26.2", - "start": 167900001, - "end": 171200000, - "type": "gneg" - }, - { - "id": "q22.3", - "start": 136000001, - "end": 139000000, - "type": "gpos25" - }, - { - "id": "p22.2", - "start": 36400001, - "end": 39300000, - "type": "gneg" - }, - { - "id": "q13.2", - "start": 111600001, - "end": 113700000, - "type": "gneg" - }, - { - "id": "p21.32", - "start": 44100001, - "end": 44200000, - "type": "gpos50" - }, - { - "id": "p12.1", - "start": 83500001, - "end": 87100000, - "type": "gpos75" - }, - { - "id": "q25.33", - "start": 159300001, - "end": 161000000, - "type": "gneg" - }, - { - "id": "q11.2", - "start": 94000001, - "end": 98600000, - "type": "gvar" - }, - { - "id": "q29", - "start": 192600001, - "end": 198295559, - "type": "gneg" - }, - { - "id": "p26.3", - "start": 1, - "end": 2800000, - "type": "gpos50" - }, - { - "id": "p25.2", - "start": 11600001, - "end": 13200000, - "type": "gpos25" - }, - { - "id": "q27.3", - "start": 186300001, - "end": 188200000, - "type": "gneg" - }, - { - "id": "p14.3", - "start": 54400001, - "end": 58600000, - "type": "gpos50" - }, - { - "id": "p11.2", - "start": 87100001, - "end": 87800000, - "type": "gneg" - }, - { - "id": "p26.1", - "start": 4000001, - "end": 8100000, - "type": "gpos50" - }, - { - "id": "p14.2", - "start": 58600001, - "end": 63800000, - "type": "gneg" - }, - { - "id": "p21.31", - "start": 44200001, - "end": 50600000, - "type": "gneg" - }, - { - "id": "q13.13", - "start": 108200001, - "end": 111600000, - "type": "gpos50" - }, - { - "id": "q13.12", - "start": 106500001, - "end": 108200000, - "type": "gneg" - }, - { - "id": "q21.3", - "start": 126100001, - "end": 129500000, - "type": "gneg" - }, - { - "id": "p25.3", - "start": 8100001, - "end": 11600000, - "type": "gneg" - }, - { - "id": "p21.33", - "start": 43600001, - "end": 44100000, - "type": "gneg" - }, - { - "id": "q23", - "start": 139000001, - "end": 143100000, - "type": "gneg" - }, - { - "id": "p11.1", - "start": 87800001, - "end": 90900000, - "type": "acen" - }, - { - "id": "p24.1", - "start": 26300001, - "end": 30800000, - "type": "gpos75" - }, - { - "id": "p24.3", - "start": 16300001, - "end": 23800000, - "type": "gpos100" - }, - { - "id": "q25.31", - "start": 155300001, - "end": 157300000, - "type": "gneg" - }, - { - "id": "p23", - "start": 30800001, - "end": 32000000, - "type": "gneg" - }, - { - "id": "q25.1", - "start": 149200001, - "end": 152300000, - "type": "gneg" - }, - { - "id": "p21.1", - "start": 52300001, - "end": 54400000, - "type": "gneg" - }, - { - "id": "q13.33", - "start": 119300001, - "end": 122200000, - "type": "gpos75" - }, - { - "id": "p13", - "start": 69700001, - "end": 74100000, - "type": "gneg" - }, - { - "id": "q13.31", - "start": 113700001, - "end": 117600000, - "type": "gpos75" - }, - { - "id": "q21.2", - "start": 124100001, - "end": 126100000, - "type": "gpos25" - }, - { - "id": "p22.1", - "start": 39300001, - "end": 43600000, - "type": "gpos75" - }, - { - "id": "p14.1", - "start": 63800001, - "end": 69700000, - "type": "gpos50" - }, - { - "id": "p25.1", - "start": 13200001, - "end": 16300000, - "type": "gneg" - }, - { - "id": "q13.32", - "start": 117600001, - "end": 119300000, - "type": "gneg" - }, - { - "id": "q13.11", - "start": 103100001, - "end": 106500000, - "type": "gpos75" - }, - { - "id": "p21.2", - "start": 50600001, - "end": 52300000, - "type": "gpos25" - }, - { - "id": "q12.2", - "start": 100300001, - "end": 101200000, - "type": "gpos25" - }, - { - "id": "q26.32", - "start": 176000001, - "end": 179300000, - "type": "gneg" - }, - { - "id": "p22.3", - "start": 32000001, - "end": 36400000, - "type": "gpos50" - }, - { - "id": "q28", - "start": 188200001, - "end": 192600000, - "type": "gpos75" - }, - { - "id": "q25.32", - "start": 157300001, - "end": 159300000, - "type": "gpos50" - }, - { - "id": "p24.2", - "start": 23800001, - "end": 26300000, - "type": "gneg" - }, - { - "id": "q27.1", - "start": 183000001, - "end": 184800000, - "type": "gneg" - }, - { - "id": "q26.1", - "start": 161000001, - "end": 167900000, - "type": "gpos100" - }, - { - "id": "q22.2", - "start": 134000001, - "end": 136000000, - "type": "gneg" - }, - { - "id": "q12.3", - "start": 101200001, - "end": 103100000, - "type": "gneg" - }, - { - "id": "p12.2", - "start": 79800001, - "end": 83500000, - "type": "gneg" - }, - { - "id": "q11.1", - "start": 90900001, - "end": 94000000, - "type": "acen" - } + "size" : 198295559, + "bands" : [ + { "id": "p11.1", "start": 87800001, "end": 90900000, "type": "acen" }, + { "id": "p11.2", "start": 87100001, "end": 87800000, "type": "gneg" }, + { "id": "p12.1", "start": 83500001, "end": 87100000, "type": "gpos75" }, + { "id": "p12.2", "start": 79800001, "end": 83500000, "type": "gneg" }, + { "id": "p12.3", "start": 74100001, "end": 79800000, "type": "gpos75" }, + { "id": "p13", "start": 69700001, "end": 74100000, "type": "gneg" }, + { "id": "p14.1", "start": 63800001, "end": 69700000, "type": "gpos50" }, + { "id": "p14.2", "start": 58600001, "end": 63800000, "type": "gneg" }, + { "id": "p14.3", "start": 54400001, "end": 58600000, "type": "gpos50" }, + { "id": "p21.1", "start": 52300001, "end": 54400000, "type": "gneg" }, + { "id": "p21.2", "start": 50600001, "end": 52300000, "type": "gpos25" }, + { "id": "p21.31", "start": 44200001, "end": 50600000, "type": "gneg" }, + { "id": "p21.32", "start": 44100001, "end": 44200000, "type": "gpos50" }, + { "id": "p21.33", "start": 43600001, "end": 44100000, "type": "gneg" }, + { "id": "p22.1", "start": 39300001, "end": 43600000, "type": "gpos75" }, + { "id": "p22.2", "start": 36400001, "end": 39300000, "type": "gneg" }, + { "id": "p22.3", "start": 32000001, "end": 36400000, "type": "gpos50" }, + { "id": "p23", "start": 30800001, "end": 32000000, "type": "gneg" }, + { "id": "p24.1", "start": 26300001, "end": 30800000, "type": "gpos75" }, + { "id": "p24.2", "start": 23800001, "end": 26300000, "type": "gneg" }, + { "id": "p24.3", "start": 16300001, "end": 23800000, "type": "gpos100" }, + { "id": "p25.1", "start": 13200001, "end": 16300000, "type": "gneg" }, + { "id": "p25.2", "start": 11600001, "end": 13200000, "type": "gpos25" }, + { "id": "p25.3", "start": 8100001, "end": 11600000, "type": "gneg" }, + { "id": "p26.1", "start": 4000001, "end": 8100000, "type": "gpos50" }, + { "id": "p26.2", "start": 2800001, "end": 4000000, "type": "gneg" }, + { "id": "p26.3", "start": 1, "end": 2800000, "type": "gpos50" }, + { "id": "q11.1", "start": 90900001, "end": 94000000, "type": "acen" }, + { "id": "q11.2", "start": 94000001, "end": 98600000, "type": "gvar" }, + { "id": "q12.1", "start": 98600001, "end": 100300000, "type": "gneg" }, + { "id": "q12.2", "start": 100300001, "end": 101200000, "type": "gpos25" }, + { "id": "q12.3", "start": 101200001, "end": 103100000, "type": "gneg" }, + { "id": "q13.11", "start": 103100001, "end": 106500000, "type": "gpos75" }, + { "id": "q13.12", "start": 106500001, "end": 108200000, "type": "gneg" }, + { "id": "q13.13", "start": 108200001, "end": 111600000, "type": "gpos50" }, + { "id": "q13.2", "start": 111600001, "end": 113700000, "type": "gneg" }, + { "id": "q13.31", "start": 113700001, "end": 117600000, "type": "gpos75" }, + { "id": "q13.32", "start": 117600001, "end": 119300000, "type": "gneg" }, + { "id": "q13.33", "start": 119300001, "end": 122200000, "type": "gpos75" }, + { "id": "q21.1", "start": 122200001, "end": 124100000, "type": "gneg" }, + { "id": "q21.2", "start": 124100001, "end": 126100000, "type": "gpos25" }, + { "id": "q21.3", "start": 126100001, "end": 129500000, "type": "gneg" }, + { "id": "q22.1", "start": 129500001, "end": 134000000, "type": "gpos25" }, + { "id": "q22.2", "start": 134000001, "end": 136000000, "type": "gneg" }, + { "id": "q22.3", "start": 136000001, "end": 139000000, "type": "gpos25" }, + { "id": "q23", "start": 139000001, "end": 143100000, "type": "gneg" }, + { "id": "q24", "start": 143100001, "end": 149200000, "type": "gpos100" }, + { "id": "q25.1", "start": 149200001, "end": 152300000, "type": "gneg" }, + { "id": "q25.2", "start": 152300001, "end": 155300000, "type": "gpos50" }, + { "id": "q25.31", "start": 155300001, "end": 157300000, "type": "gneg" }, + { "id": "q25.32", "start": 157300001, "end": 159300000, "type": "gpos50" }, + { "id": "q25.33", "start": 159300001, "end": 161000000, "type": "gneg" }, + { "id": "q26.1", "start": 161000001, "end": 167900000, "type": "gpos100" }, + { "id": "q26.2", "start": 167900001, "end": 171200000, "type": "gneg" }, + { "id": "q26.31", "start": 171200001, "end": 176000000, "type": "gpos75" }, + { "id": "q26.32", "start": 176000001, "end": 179300000, "type": "gneg" }, + { "id": "q26.33", "start": 179300001, "end": 183000000, "type": "gpos75" }, + { "id": "q27.1", "start": 183000001, "end": 184800000, "type": "gneg" }, + { "id": "q27.2", "start": 184800001, "end": 186300000, "type": "gpos25" }, + { "id": "q27.3", "start": 186300001, "end": 188200000, "type": "gneg" }, + { "id": "q28", "start": 188200001, "end": 192600000, "type": "gpos75" }, + { "id": "q29", "start": 192600001, "end": 198295559, "type": "gneg" } ] }, "4": { - "size": 190214555, - "bands": [ - { - "id": "q22.1", - "start": 87100001, - "end": 92800000, - "type": "gpos75" - }, - { - "id": "q21.21", - "start": 78000001, - "end": 81500000, - "type": "gpos50" - }, - { - "id": "q13.1", - "start": 58500001, - "end": 65500000, - "type": "gpos100" - }, - { - "id": "p15.2", - "start": 21300001, - "end": 27700000, - "type": "gneg" - }, - { - "id": "q31.22", - "start": 145900001, - "end": 147500000, - "type": "gneg" - }, - { - "id": "p15.1", - "start": 27700001, - "end": 35800000, - "type": "gpos100" - }, - { - "id": "q27", - "start": 119900001, - "end": 122800000, - "type": "gneg" - }, - { - "id": "q34.2", - "start": 175400001, - "end": 176600000, - "type": "gneg" - }, - { - "id": "q13.3", - "start": 69400001, - "end": 75300000, - "type": "gpos75" - }, - { - "id": "q24", - "start": 100100001, - "end": 106700000, - "type": "gpos50" - }, - { - "id": "q21.1", - "start": 75300001, - "end": 78000000, - "type": "gneg" - }, - { - "id": "q22.3", - "start": 94200001, - "end": 97900000, - "type": "gpos75" - }, - { - "id": "q34.3", - "start": 176600001, - "end": 182300000, - "type": "gpos100" - }, - { - "id": "q13.2", - "start": 65500001, - "end": 69400000, - "type": "gneg" - }, - { - "id": "q35.2", - "start": 186200001, - "end": 190214555, - "type": "gpos25" - }, - { - "id": "p16.3", - "start": 1, - "end": 4500000, - "type": "gneg" - }, - { - "id": "p15.32", - "start": 15000001, - "end": 17700000, - "type": "gneg" - }, - { - "id": "p12", - "start": 44600001, - "end": 48200000, - "type": "gneg" - }, - { - "id": "p16.2", - "start": 4500001, - "end": 6000000, - "type": "gpos25" - }, - { - "id": "q25", - "start": 106700001, - "end": 113200000, - "type": "gneg" - }, - { - "id": "q31.23", - "start": 147500001, - "end": 150200000, - "type": "gpos25" - }, - { - "id": "q28.3", - "start": 130100001, - "end": 138500000, - "type": "gpos100" - }, - { - "id": "q21.3", - "start": 86000001, - "end": 87100000, - "type": "gneg" - }, - { - "id": "q28.1", - "start": 122800001, - "end": 127900000, - "type": "gpos50" - }, - { - "id": "q34.1", - "start": 171000001, - "end": 175400000, - "type": "gpos75" - }, - { - "id": "p15.31", - "start": 17700001, - "end": 21300000, - "type": "gpos75" - }, - { - "id": "q26", - "start": 113200001, - "end": 119900000, - "type": "gpos75" - }, - { - "id": "q23", - "start": 97900001, - "end": 100100000, - "type": "gneg" - }, - { - "id": "p11", - "start": 48200001, - "end": 50000000, - "type": "acen" - }, - { - "id": "q33", - "start": 169200001, - "end": 171000000, - "type": "gneg" - }, - { - "id": "q31.21", - "start": 140600001, - "end": 145900000, - "type": "gpos25" - }, - { - "id": "q32.1", - "start": 154600001, - "end": 160800000, - "type": "gpos100" - }, - { - "id": "p13", - "start": 41200001, - "end": 44600000, - "type": "gpos50" - }, - { - "id": "p15.33", - "start": 11300001, - "end": 15000000, - "type": "gpos50" - }, - { - "id": "p14", - "start": 35800001, - "end": 41200000, - "type": "gneg" - }, - { - "id": "q21.23", - "start": 83200001, - "end": 86000000, - "type": "gpos25" - }, - { - "id": "q31.3", - "start": 150200001, - "end": 154600000, - "type": "gneg" - }, - { - "id": "q28.2", - "start": 127900001, - "end": 130100000, - "type": "gneg" - }, - { - "id": "q35.1", - "start": 182300001, - "end": 186200000, - "type": "gneg" - }, - { - "id": "p16.1", - "start": 6000001, - "end": 11300000, - "type": "gneg" - }, - { - "id": "q31.1", - "start": 138500001, - "end": 140600000, - "type": "gneg" - }, - { - "id": "q32.2", - "start": 160800001, - "end": 163600000, - "type": "gneg" - }, - { - "id": "q12", - "start": 51800001, - "end": 58500000, - "type": "gneg" - }, - { - "id": "q22.2", - "start": 92800001, - "end": 94200000, - "type": "gneg" - }, - { - "id": "q32.3", - "start": 163600001, - "end": 169200000, - "type": "gpos100" - }, - { - "id": "q11", - "start": 50000001, - "end": 51800000, - "type": "acen" - }, - { - "id": "q21.22", - "start": 81500001, - "end": 83200000, - "type": "gneg" - } + "size" : 190214555, + "bands" : [ + { "id": "p11", "start": 48200001, "end": 50000000, "type": "acen" }, + { "id": "p12", "start": 44600001, "end": 48200000, "type": "gneg" }, + { "id": "p13", "start": 41200001, "end": 44600000, "type": "gpos50" }, + { "id": "p14", "start": 35800001, "end": 41200000, "type": "gneg" }, + { "id": "p15.1", "start": 27700001, "end": 35800000, "type": "gpos100" }, + { "id": "p15.2", "start": 21300001, "end": 27700000, "type": "gneg" }, + { "id": "p15.31", "start": 17700001, "end": 21300000, "type": "gpos75" }, + { "id": "p15.32", "start": 15000001, "end": 17700000, "type": "gneg" }, + { "id": "p15.33", "start": 11300001, "end": 15000000, "type": "gpos50" }, + { "id": "p16.1", "start": 6000001, "end": 11300000, "type": "gneg" }, + { "id": "p16.2", "start": 4500001, "end": 6000000, "type": "gpos25" }, + { "id": "p16.3", "start": 1, "end": 4500000, "type": "gneg" }, + { "id": "q11", "start": 50000001, "end": 51800000, "type": "acen" }, + { "id": "q12", "start": 51800001, "end": 58500000, "type": "gneg" }, + { "id": "q13.1", "start": 58500001, "end": 65500000, "type": "gpos100" }, + { "id": "q13.2", "start": 65500001, "end": 69400000, "type": "gneg" }, + { "id": "q13.3", "start": 69400001, "end": 75300000, "type": "gpos75" }, + { "id": "q21.1", "start": 75300001, "end": 78000000, "type": "gneg" }, + { "id": "q21.21", "start": 78000001, "end": 81500000, "type": "gpos50" }, + { "id": "q21.22", "start": 81500001, "end": 83200000, "type": "gneg" }, + { "id": "q21.23", "start": 83200001, "end": 86000000, "type": "gpos25" }, + { "id": "q21.3", "start": 86000001, "end": 87100000, "type": "gneg" }, + { "id": "q22.1", "start": 87100001, "end": 92800000, "type": "gpos75" }, + { "id": "q22.2", "start": 92800001, "end": 94200000, "type": "gneg" }, + { "id": "q22.3", "start": 94200001, "end": 97900000, "type": "gpos75" }, + { "id": "q23", "start": 97900001, "end": 100100000, "type": "gneg" }, + { "id": "q24", "start": 100100001, "end": 106700000, "type": "gpos50" }, + { "id": "q25", "start": 106700001, "end": 113200000, "type": "gneg" }, + { "id": "q26", "start": 113200001, "end": 119900000, "type": "gpos75" }, + { "id": "q27", "start": 119900001, "end": 122800000, "type": "gneg" }, + { "id": "q28.1", "start": 122800001, "end": 127900000, "type": "gpos50" }, + { "id": "q28.2", "start": 127900001, "end": 130100000, "type": "gneg" }, + { "id": "q28.3", "start": 130100001, "end": 138500000, "type": "gpos100" }, + { "id": "q31.1", "start": 138500001, "end": 140600000, "type": "gneg" }, + { "id": "q31.21", "start": 140600001, "end": 145900000, "type": "gpos25" }, + { "id": "q31.22", "start": 145900001, "end": 147500000, "type": "gneg" }, + { "id": "q31.23", "start": 147500001, "end": 150200000, "type": "gpos25" }, + { "id": "q31.3", "start": 150200001, "end": 154600000, "type": "gneg" }, + { "id": "q32.1", "start": 154600001, "end": 160800000, "type": "gpos100" }, + { "id": "q32.2", "start": 160800001, "end": 163600000, "type": "gneg" }, + { "id": "q32.3", "start": 163600001, "end": 169200000, "type": "gpos100" }, + { "id": "q33", "start": 169200001, "end": 171000000, "type": "gneg" }, + { "id": "q34.1", "start": 171000001, "end": 175400000, "type": "gpos75" }, + { "id": "q34.2", "start": 175400001, "end": 176600000, "type": "gneg" }, + { "id": "q34.3", "start": 176600001, "end": 182300000, "type": "gpos100" }, + { "id": "q35.1", "start": 182300001, "end": 186200000, "type": "gneg" }, + { "id": "q35.2", "start": 186200001, "end": 190214555, "type": "gpos25" } ] }, "5": { - "size": 181538259, - "bands": [ - { - "id": "q22.1", - "start": 110200001, - "end": 112200000, - "type": "gneg" - }, - { - "id": "q34", - "start": 160500001, - "end": 169000000, - "type": "gpos100" - }, - { - "id": "q13.1", - "start": 67400001, - "end": 69100000, - "type": "gneg" - }, - { - "id": "p15.2", - "start": 9900001, - "end": 15000000, - "type": "gpos50" - }, - { - "id": "q12.1", - "start": 59600001, - "end": 63600000, - "type": "gpos75" - }, - { - "id": "q14.1", - "start": 77600001, - "end": 82100000, - "type": "gpos50" - }, - { - "id": "p15.1", - "start": 15000001, - "end": 18400000, - "type": "gneg" - }, - { - "id": "q13.3", - "start": 74000001, - "end": 77600000, - "type": "gneg" - }, - { - "id": "q15", - "start": 93000001, - "end": 98900000, - "type": "gneg" - }, - { - "id": "p13.3", - "start": 28900001, - "end": 33800000, - "type": "gneg" - }, - { - "id": "q23.2", - "start": 122100001, - "end": 127900000, - "type": "gneg" - }, - { - "id": "q21.1", - "start": 98900001, - "end": 103400000, - "type": "gpos100" - }, - { - "id": "q22.3", - "start": 113800001, - "end": 115900000, - "type": "gneg" - }, - { - "id": "q33.2", - "start": 153300001, - "end": 156300000, - "type": "gpos50" - }, - { - "id": "q13.2", - "start": 69100001, - "end": 74000000, - "type": "gpos50" - }, - { - "id": "q35.2", - "start": 173300001, - "end": 177100000, - "type": "gpos25" - }, - { - "id": "q14.3", - "start": 83500001, - "end": 93000000, - "type": "gpos100" - }, - { - "id": "q14.2", - "start": 82100001, - "end": 83500000, - "type": "gneg" - }, - { - "id": "q11.2", - "start": 51400001, - "end": 59600000, - "type": "gneg" - }, - { - "id": "p13.2", - "start": 33800001, - "end": 38400000, - "type": "gpos25" - }, - { - "id": "p14.3", - "start": 18400001, - "end": 23300000, - "type": "gpos100" - }, - { - "id": "p15.32", - "start": 4400001, - "end": 6300000, - "type": "gpos25" - }, - { - "id": "p12", - "start": 42500001, - "end": 46100000, - "type": "gpos50" - }, - { - "id": "p14.2", - "start": 23300001, - "end": 24600000, - "type": "gneg" - }, - { - "id": "p13.1", - "start": 38400001, - "end": 42500000, - "type": "gneg" - }, - { - "id": "q33.3", - "start": 156300001, - "end": 160500000, - "type": "gneg" - }, - { - "id": "q33.1", - "start": 150400001, - "end": 153300000, - "type": "gneg" - }, - { - "id": "q21.3", - "start": 105100001, - "end": 110200000, - "type": "gpos100" - }, - { - "id": "p15.31", - "start": 6300001, - "end": 9900000, - "type": "gneg" - }, - { - "id": "p11", - "start": 46100001, - "end": 48800000, - "type": "acen" - }, - { - "id": "p15.33", - "start": 1, - "end": 4400000, - "type": "gneg" - }, - { - "id": "q32", - "start": 145100001, - "end": 150400000, - "type": "gpos75" - }, - { - "id": "q21.2", - "start": 103400001, - "end": 105100000, - "type": "gneg" - }, - { - "id": "q35.3", - "start": 177100001, - "end": 181538259, - "type": "gneg" - }, - { - "id": "q31.2", - "start": 136900001, - "end": 140100000, - "type": "gpos25" - }, - { - "id": "p14.1", - "start": 24600001, - "end": 28900000, - "type": "gpos100" - }, - { - "id": "q12.2", - "start": 63600001, - "end": 63900000, - "type": "gneg" - }, - { - "id": "q31.3", - "start": 140100001, - "end": 145100000, - "type": "gneg" - }, - { - "id": "q23.1", - "start": 115900001, - "end": 122100000, - "type": "gpos100" - }, - { - "id": "q35.1", - "start": 169000001, - "end": 173300000, - "type": "gneg" - }, - { - "id": "q31.1", - "start": 131200001, - "end": 136900000, - "type": "gneg" - }, - { - "id": "q12.3", - "start": 63900001, - "end": 67400000, - "type": "gpos75" - }, - { - "id": "q22.2", - "start": 112200001, - "end": 113800000, - "type": "gpos50" - }, - { - "id": "q23.3", - "start": 127900001, - "end": 131200000, - "type": "gpos100" - }, - { - "id": "q11.1", - "start": 48800001, - "end": 51400000, - "type": "acen" - } + "size" : 181538259, + "bands" : [ + { "id": "p11", "start": 46100001, "end": 48800000, "type": "acen" }, + { "id": "p12", "start": 42500001, "end": 46100000, "type": "gpos50" }, + { "id": "p13.1", "start": 38400001, "end": 42500000, "type": "gneg" }, + { "id": "p13.2", "start": 33800001, "end": 38400000, "type": "gpos25" }, + { "id": "p13.3", "start": 28900001, "end": 33800000, "type": "gneg" }, + { "id": "p14.1", "start": 24600001, "end": 28900000, "type": "gpos100" }, + { "id": "p14.2", "start": 23300001, "end": 24600000, "type": "gneg" }, + { "id": "p14.3", "start": 18400001, "end": 23300000, "type": "gpos100" }, + { "id": "p15.1", "start": 15000001, "end": 18400000, "type": "gneg" }, + { "id": "p15.2", "start": 9900001, "end": 15000000, "type": "gpos50" }, + { "id": "p15.31", "start": 6300001, "end": 9900000, "type": "gneg" }, + { "id": "p15.32", "start": 4400001, "end": 6300000, "type": "gpos25" }, + { "id": "p15.33", "start": 1, "end": 4400000, "type": "gneg" }, + { "id": "q11.1", "start": 48800001, "end": 51400000, "type": "acen" }, + { "id": "q11.2", "start": 51400001, "end": 59600000, "type": "gneg" }, + { "id": "q12.1", "start": 59600001, "end": 63600000, "type": "gpos75" }, + { "id": "q12.2", "start": 63600001, "end": 63900000, "type": "gneg" }, + { "id": "q12.3", "start": 63900001, "end": 67400000, "type": "gpos75" }, + { "id": "q13.1", "start": 67400001, "end": 69100000, "type": "gneg" }, + { "id": "q13.2", "start": 69100001, "end": 74000000, "type": "gpos50" }, + { "id": "q13.3", "start": 74000001, "end": 77600000, "type": "gneg" }, + { "id": "q14.1", "start": 77600001, "end": 82100000, "type": "gpos50" }, + { "id": "q14.2", "start": 82100001, "end": 83500000, "type": "gneg" }, + { "id": "q14.3", "start": 83500001, "end": 93000000, "type": "gpos100" }, + { "id": "q15", "start": 93000001, "end": 98900000, "type": "gneg" }, + { "id": "q21.1", "start": 98900001, "end": 103400000, "type": "gpos100" }, + { "id": "q21.2", "start": 103400001, "end": 105100000, "type": "gneg" }, + { "id": "q21.3", "start": 105100001, "end": 110200000, "type": "gpos100" }, + { "id": "q22.1", "start": 110200001, "end": 112200000, "type": "gneg" }, + { "id": "q22.2", "start": 112200001, "end": 113800000, "type": "gpos50" }, + { "id": "q22.3", "start": 113800001, "end": 115900000, "type": "gneg" }, + { "id": "q23.1", "start": 115900001, "end": 122100000, "type": "gpos100" }, + { "id": "q23.2", "start": 122100001, "end": 127900000, "type": "gneg" }, + { "id": "q23.3", "start": 127900001, "end": 131200000, "type": "gpos100" }, + { "id": "q31.1", "start": 131200001, "end": 136900000, "type": "gneg" }, + { "id": "q31.2", "start": 136900001, "end": 140100000, "type": "gpos25" }, + { "id": "q31.3", "start": 140100001, "end": 145100000, "type": "gneg" }, + { "id": "q32", "start": 145100001, "end": 150400000, "type": "gpos75" }, + { "id": "q33.1", "start": 150400001, "end": 153300000, "type": "gneg" }, + { "id": "q33.2", "start": 153300001, "end": 156300000, "type": "gpos50" }, + { "id": "q33.3", "start": 156300001, "end": 160500000, "type": "gneg" }, + { "id": "q34", "start": 160500001, "end": 169000000, "type": "gpos100" }, + { "id": "q35.1", "start": 169000001, "end": 173300000, "type": "gneg" }, + { "id": "q35.2", "start": 173300001, "end": 177100000, "type": "gpos25" }, + { "id": "q35.3", "start": 177100001, "end": 181538259, "type": "gneg" } ] }, "6": { - "size": 170805979, - "bands": [ - { - "id": "q25.2", - "start": 152100001, - "end": 155200000, - "type": "gpos50" - }, - { - "id": "q22.1", - "start": 114200001, - "end": 117900000, - "type": "gpos75" - }, - { - "id": "q22.31", - "start": 118100001, - "end": 125800000, - "type": "gpos100" - }, - { - "id": "q14.1", - "start": 75200001, - "end": 83200000, - "type": "gpos50" - }, - { - "id": "q24.1", - "start": 138300001, - "end": 142200000, - "type": "gpos75" - }, - { - "id": "q16.3", - "start": 100000001, - "end": 105000000, - "type": "gpos100" - }, - { - "id": "q27", - "start": 164100001, - "end": 170805979, - "type": "gneg" - }, - { - "id": "p12.3", - "start": 46200001, - "end": 51800000, - "type": "gpos100" - }, - { - "id": "q15", - "start": 87300001, - "end": 92500000, - "type": "gneg" - }, - { - "id": "q23.2", - "start": 130900001, - "end": 134700000, - "type": "gpos50" - }, - { - "id": "p22.2", - "start": 25200001, - "end": 27100000, - "type": "gneg" - }, - { - "id": "q24.2", - "start": 142200001, - "end": 145100000, - "type": "gneg" - }, - { - "id": "q14.3", - "start": 84200001, - "end": 87300000, - "type": "gpos50" - }, - { - "id": "p21.32", - "start": 32100001, - "end": 33500000, - "type": "gpos25" - }, - { - "id": "q25.3", - "start": 155200001, - "end": 160600000, - "type": "gneg" - }, - { - "id": "q21", - "start": 105000001, - "end": 114200000, - "type": "gneg" - }, - { - "id": "q14.2", - "start": 83200001, - "end": 84200000, - "type": "gneg" - }, - { - "id": "p12.1", - "start": 53000001, - "end": 57200000, - "type": "gpos100" - }, - { - "id": "q11.2", - "start": 62600001, - "end": 62700000, - "type": "gneg" - }, - { - "id": "p25.2", - "start": 2300001, - "end": 4200000, - "type": "gpos25" - }, - { - "id": "p11.2", - "start": 57200001, - "end": 58500000, - "type": "gneg" - }, - { - "id": "p21.31", - "start": 33500001, - "end": 36600000, - "type": "gneg" - }, - { - "id": "q24.3", - "start": 145100001, - "end": 148500000, - "type": "gpos75" - }, - { - "id": "p25.3", - "start": 1, - "end": 2300000, - "type": "gneg" - }, - { - "id": "p21.33", - "start": 30500001, - "end": 32100000, - "type": "gneg" - }, - { - "id": "q26", - "start": 160600001, - "end": 164100000, - "type": "gpos50" - }, - { - "id": "p11.1", - "start": 58500001, - "end": 59800000, - "type": "acen" - }, - { - "id": "p24.1", - "start": 11600001, - "end": 13400000, - "type": "gpos25" - }, - { - "id": "p24.3", - "start": 7100001, - "end": 10600000, - "type": "gpos50" - }, - { - "id": "p23", - "start": 13400001, - "end": 15200000, - "type": "gneg" - }, - { - "id": "q25.1", - "start": 148500001, - "end": 152100000, - "type": "gneg" - }, - { - "id": "p21.1", - "start": 40500001, - "end": 46200000, - "type": "gneg" - }, - { - "id": "q22.33", - "start": 126800001, - "end": 130000000, - "type": "gpos75" - }, - { - "id": "p22.1", - "start": 27100001, - "end": 30500000, - "type": "gpos50" - }, - { - "id": "p25.1", - "start": 4200001, - "end": 7100000, - "type": "gneg" - }, - { - "id": "q16.2", - "start": 98900001, - "end": 100000000, - "type": "gneg" - }, - { - "id": "p21.2", - "start": 36600001, - "end": 40500000, - "type": "gpos25" - }, - { - "id": "q23.1", - "start": 130000001, - "end": 130900000, - "type": "gneg" - }, - { - "id": "p22.3", - "start": 15200001, - "end": 25200000, - "type": "gpos75" - }, - { - "id": "q22.32", - "start": 125800001, - "end": 126800000, - "type": "gneg" - }, - { - "id": "q16.1", - "start": 92500001, - "end": 98900000, - "type": "gpos100" - }, - { - "id": "q13", - "start": 69200001, - "end": 75200000, - "type": "gneg" - }, - { - "id": "p24.2", - "start": 10600001, - "end": 11600000, - "type": "gneg" - }, - { - "id": "q22.2", - "start": 117900001, - "end": 118100000, - "type": "gneg" - }, - { - "id": "q12", - "start": 62700001, - "end": 69200000, - "type": "gpos100" - }, - { - "id": "q23.3", - "start": 134700001, - "end": 138300000, - "type": "gneg" - }, - { - "id": "p12.2", - "start": 51800001, - "end": 53000000, - "type": "gneg" - }, - { - "id": "q11.1", - "start": 59800001, - "end": 62600000, - "type": "acen" - } + "size" : 170805979, + "bands" : [ + { "id": "p11.1", "start": 58500001, "end": 59800000, "type": "acen" }, + { "id": "p11.2", "start": 57200001, "end": 58500000, "type": "gneg" }, + { "id": "p12.1", "start": 53000001, "end": 57200000, "type": "gpos100" }, + { "id": "p12.2", "start": 51800001, "end": 53000000, "type": "gneg" }, + { "id": "p12.3", "start": 46200001, "end": 51800000, "type": "gpos100" }, + { "id": "p21.1", "start": 40500001, "end": 46200000, "type": "gneg" }, + { "id": "p21.2", "start": 36600001, "end": 40500000, "type": "gpos25" }, + { "id": "p21.31", "start": 33500001, "end": 36600000, "type": "gneg" }, + { "id": "p21.32", "start": 32100001, "end": 33500000, "type": "gpos25" }, + { "id": "p21.33", "start": 30500001, "end": 32100000, "type": "gneg" }, + { "id": "p22.1", "start": 27100001, "end": 30500000, "type": "gpos50" }, + { "id": "p22.2", "start": 25200001, "end": 27100000, "type": "gneg" }, + { "id": "p22.3", "start": 15200001, "end": 25200000, "type": "gpos75" }, + { "id": "p23", "start": 13400001, "end": 15200000, "type": "gneg" }, + { "id": "p24.1", "start": 11600001, "end": 13400000, "type": "gpos25" }, + { "id": "p24.2", "start": 10600001, "end": 11600000, "type": "gneg" }, + { "id": "p24.3", "start": 7100001, "end": 10600000, "type": "gpos50" }, + { "id": "p25.1", "start": 4200001, "end": 7100000, "type": "gneg" }, + { "id": "p25.2", "start": 2300001, "end": 4200000, "type": "gpos25" }, + { "id": "p25.3", "start": 1, "end": 2300000, "type": "gneg" }, + { "id": "q11.1", "start": 59800001, "end": 62600000, "type": "acen" }, + { "id": "q11.2", "start": 62600001, "end": 62700000, "type": "gneg" }, + { "id": "q12", "start": 62700001, "end": 69200000, "type": "gpos100" }, + { "id": "q13", "start": 69200001, "end": 75200000, "type": "gneg" }, + { "id": "q14.1", "start": 75200001, "end": 83200000, "type": "gpos50" }, + { "id": "q14.2", "start": 83200001, "end": 84200000, "type": "gneg" }, + { "id": "q14.3", "start": 84200001, "end": 87300000, "type": "gpos50" }, + { "id": "q15", "start": 87300001, "end": 92500000, "type": "gneg" }, + { "id": "q16.1", "start": 92500001, "end": 98900000, "type": "gpos100" }, + { "id": "q16.2", "start": 98900001, "end": 100000000, "type": "gneg" }, + { "id": "q16.3", "start": 100000001, "end": 105000000, "type": "gpos100" }, + { "id": "q21", "start": 105000001, "end": 114200000, "type": "gneg" }, + { "id": "q22.1", "start": 114200001, "end": 117900000, "type": "gpos75" }, + { "id": "q22.2", "start": 117900001, "end": 118100000, "type": "gneg" }, + { "id": "q22.31", "start": 118100001, "end": 125800000, "type": "gpos100" }, + { "id": "q22.32", "start": 125800001, "end": 126800000, "type": "gneg" }, + { "id": "q22.33", "start": 126800001, "end": 130000000, "type": "gpos75" }, + { "id": "q23.1", "start": 130000001, "end": 130900000, "type": "gneg" }, + { "id": "q23.2", "start": 130900001, "end": 134700000, "type": "gpos50" }, + { "id": "q23.3", "start": 134700001, "end": 138300000, "type": "gneg" }, + { "id": "q24.1", "start": 138300001, "end": 142200000, "type": "gpos75" }, + { "id": "q24.2", "start": 142200001, "end": 145100000, "type": "gneg" }, + { "id": "q24.3", "start": 145100001, "end": 148500000, "type": "gpos75" }, + { "id": "q25.1", "start": 148500001, "end": 152100000, "type": "gneg" }, + { "id": "q25.2", "start": 152100001, "end": 155200000, "type": "gpos50" }, + { "id": "q25.3", "start": 155200001, "end": 160600000, "type": "gneg" }, + { "id": "q26", "start": 160600001, "end": 164100000, "type": "gpos50" }, + { "id": "q27", "start": 164100001, "end": 170805979, "type": "gneg" } ] }, "7": { - "size": 159345973, - "bands": [ - { - "id": "q22.1", - "start": 98400001, - "end": 104200000, - "type": "gneg" - }, - { - "id": "q11.21", - "start": 62100001, - "end": 67500000, - "type": "gneg" - }, - { - "id": "q34", - "start": 138500001, - "end": 143400000, - "type": "gneg" - }, - { - "id": "p15.2", - "start": 25500001, - "end": 27900000, - "type": "gpos50" - }, - { - "id": "p21.3", - "start": 7200001, - "end": 13700000, - "type": "gpos100" - }, - { - "id": "p15.1", - "start": 27900001, - "end": 28800000, - "type": "gneg" - }, - { - "id": "p12.3", - "start": 45400001, - "end": 49000000, - "type": "gpos75" - }, - { - "id": "q11.22", - "start": 67500001, - "end": 72700000, - "type": "gpos50" - }, - { - "id": "q22.3", - "start": 104900001, - "end": 107800000, - "type": "gneg" - }, - { - "id": "p22.2", - "start": 2800001, - "end": 4500000, - "type": "gpos25" - }, - { - "id": "q31.31", - "start": 117700001, - "end": 121400000, - "type": "gpos75" - }, - { - "id": "p12.1", - "start": 50500001, - "end": 53900000, - "type": "gpos75" - }, - { - "id": "p14.3", - "start": 28800001, - "end": 34900000, - "type": "gpos75" - }, - { - "id": "p11.2", - "start": 53900001, - "end": 58100000, - "type": "gneg" - }, - { - "id": "p14.2", - "start": 34900001, - "end": 37100000, - "type": "gneg" - }, - { - "id": "q21.13", - "start": 88500001, - "end": 91500000, - "type": "gpos75" - }, - { - "id": "q21.3", - "start": 93300001, - "end": 98400000, - "type": "gpos75" - }, - { - "id": "q31.33", - "start": 124100001, - "end": 127500000, - "type": "gpos75" - }, - { - "id": "q31.32", - "start": 121400001, - "end": 124100000, - "type": "gneg" - }, - { - "id": "p11.1", - "start": 58100001, - "end": 60100000, - "type": "acen" - }, - { - "id": "q33", - "start": 132900001, - "end": 138500000, - "type": "gpos50" - }, - { - "id": "p21.1", - "start": 16500001, - "end": 20900000, - "type": "gpos100" - }, - { - "id": "q21.11", - "start": 77900001, - "end": 86700000, - "type": "gpos100" - }, - { - "id": "q32.1", - "start": 127500001, - "end": 129600000, - "type": "gneg" - }, - { - "id": "p13", - "start": 43300001, - "end": 45400000, - "type": "gneg" - }, - { - "id": "q36.2", - "start": 152800001, - "end": 155200000, - "type": "gpos25" - }, - { - "id": "q11.23", - "start": 72700001, - "end": 77900000, - "type": "gneg" - }, - { - "id": "q36.3", - "start": 155200001, - "end": 159345973, - "type": "gneg" - }, - { - "id": "q35", - "start": 143400001, - "end": 148200000, - "type": "gpos75" - }, - { - "id": "p22.1", - "start": 4500001, - "end": 7200000, - "type": "gneg" - }, - { - "id": "q21.2", - "start": 91500001, - "end": 93300000, - "type": "gneg" - }, - { - "id": "p14.1", - "start": 37100001, - "end": 43300000, - "type": "gpos75" - }, - { - "id": "q31.2", - "start": 115000001, - "end": 117700000, - "type": "gneg" - }, - { - "id": "p21.2", - "start": 13700001, - "end": 16500000, - "type": "gneg" - }, - { - "id": "p22.3", - "start": 1, - "end": 2800000, - "type": "gneg" - }, - { - "id": "q36.1", - "start": 148200001, - "end": 152800000, - "type": "gneg" - }, - { - "id": "p15.3", - "start": 20900001, - "end": 25500000, - "type": "gneg" - }, - { - "id": "q31.1", - "start": 107800001, - "end": 115000000, - "type": "gpos75" - }, - { - "id": "q32.2", - "start": 129600001, - "end": 130800000, - "type": "gpos25" - }, - { - "id": "q22.2", - "start": 104200001, - "end": 104900000, - "type": "gpos50" - }, - { - "id": "p12.2", - "start": 49000001, - "end": 50500000, - "type": "gneg" - }, - { - "id": "q11.1", - "start": 60100001, - "end": 62100000, - "type": "acen" - }, - { - "id": "q32.3", - "start": 130800001, - "end": 132900000, - "type": "gneg" - }, - { - "id": "q21.12", - "start": 86700001, - "end": 88500000, - "type": "gneg" - } + "size" : 159345973, + "bands" : [ + { "id": "p11.1", "start": 58100001, "end": 60100000, "type": "acen" }, + { "id": "p11.2", "start": 53900001, "end": 58100000, "type": "gneg" }, + { "id": "p12.1", "start": 50500001, "end": 53900000, "type": "gpos75" }, + { "id": "p12.2", "start": 49000001, "end": 50500000, "type": "gneg" }, + { "id": "p12.3", "start": 45400001, "end": 49000000, "type": "gpos75" }, + { "id": "p13", "start": 43300001, "end": 45400000, "type": "gneg" }, + { "id": "p14.1", "start": 37100001, "end": 43300000, "type": "gpos75" }, + { "id": "p14.2", "start": 34900001, "end": 37100000, "type": "gneg" }, + { "id": "p14.3", "start": 28800001, "end": 34900000, "type": "gpos75" }, + { "id": "p15.1", "start": 27900001, "end": 28800000, "type": "gneg" }, + { "id": "p15.2", "start": 25500001, "end": 27900000, "type": "gpos50" }, + { "id": "p15.3", "start": 20900001, "end": 25500000, "type": "gneg" }, + { "id": "p21.1", "start": 16500001, "end": 20900000, "type": "gpos100" }, + { "id": "p21.2", "start": 13700001, "end": 16500000, "type": "gneg" }, + { "id": "p21.3", "start": 7200001, "end": 13700000, "type": "gpos100" }, + { "id": "p22.1", "start": 4500001, "end": 7200000, "type": "gneg" }, + { "id": "p22.2", "start": 2800001, "end": 4500000, "type": "gpos25" }, + { "id": "p22.3", "start": 1, "end": 2800000, "type": "gneg" }, + { "id": "q11.1", "start": 60100001, "end": 62100000, "type": "acen" }, + { "id": "q11.21", "start": 62100001, "end": 67500000, "type": "gneg" }, + { "id": "q11.22", "start": 67500001, "end": 72700000, "type": "gpos50" }, + { "id": "q11.23", "start": 72700001, "end": 77900000, "type": "gneg" }, + { "id": "q21.11", "start": 77900001, "end": 86700000, "type": "gpos100" }, + { "id": "q21.12", "start": 86700001, "end": 88500000, "type": "gneg" }, + { "id": "q21.13", "start": 88500001, "end": 91500000, "type": "gpos75" }, + { "id": "q21.2", "start": 91500001, "end": 93300000, "type": "gneg" }, + { "id": "q21.3", "start": 93300001, "end": 98400000, "type": "gpos75" }, + { "id": "q22.1", "start": 98400001, "end": 104200000, "type": "gneg" }, + { "id": "q22.2", "start": 104200001, "end": 104900000, "type": "gpos50" }, + { "id": "q22.3", "start": 104900001, "end": 107800000, "type": "gneg" }, + { "id": "q31.1", "start": 107800001, "end": 115000000, "type": "gpos75" }, + { "id": "q31.2", "start": 115000001, "end": 117700000, "type": "gneg" }, + { "id": "q31.31", "start": 117700001, "end": 121400000, "type": "gpos75" }, + { "id": "q31.32", "start": 121400001, "end": 124100000, "type": "gneg" }, + { "id": "q31.33", "start": 124100001, "end": 127500000, "type": "gpos75" }, + { "id": "q32.1", "start": 127500001, "end": 129600000, "type": "gneg" }, + { "id": "q32.2", "start": 129600001, "end": 130800000, "type": "gpos25" }, + { "id": "q32.3", "start": 130800001, "end": 132900000, "type": "gneg" }, + { "id": "q33", "start": 132900001, "end": 138500000, "type": "gpos50" }, + { "id": "q34", "start": 138500001, "end": 143400000, "type": "gneg" }, + { "id": "q35", "start": 143400001, "end": 148200000, "type": "gpos75" }, + { "id": "q36.1", "start": 148200001, "end": 152800000, "type": "gneg" }, + { "id": "q36.2", "start": 152800001, "end": 155200000, "type": "gpos25" }, + { "id": "q36.3", "start": 155200001, "end": 159345973, "type": "gneg" } ] }, "8": { - "size": 145138636, - "bands": [ - { - "id": "q22.1", - "start": 92300001, - "end": 97900000, - "type": "gneg" - }, - { - "id": "q11.21", - "start": 47200001, - "end": 51300000, - "type": "gneg" - }, - { - "id": "q13.1", - "start": 65100001, - "end": 67100000, - "type": "gneg" - }, - { - "id": "q12.1", - "start": 54600001, - "end": 60600000, - "type": "gpos50" - }, - { - "id": "p21.3", - "start": 19200001, - "end": 23500000, - "type": "gneg" - }, - { - "id": "p23.2", - "start": 2300001, - "end": 6300000, - "type": "gpos75" - }, - { - "id": "q13.3", - "start": 69600001, - "end": 72000000, - "type": "gneg" - }, - { - "id": "q23.2", - "start": 109500001, - "end": 111100000, - "type": "gneg" - }, - { - "id": "q11.22", - "start": 51300001, - "end": 51700000, - "type": "gpos75" - }, - { - "id": "q22.3", - "start": 100500001, - "end": 105100000, - "type": "gneg" - }, - { - "id": "q13.2", - "start": 67100001, - "end": 69600000, - "type": "gpos50" - }, - { - "id": "p11.22", - "start": 38500001, - "end": 39900000, - "type": "gpos25" - }, - { - "id": "q24.22", - "start": 130400001, - "end": 135400000, - "type": "gneg" - }, - { - "id": "q24.13", - "start": 121500001, - "end": 126300000, - "type": "gneg" - }, - { - "id": "p11.23", - "start": 36700001, - "end": 38500000, - "type": "gneg" - }, - { - "id": "p12", - "start": 29000001, - "end": 36700000, - "type": "gpos75" - }, - { - "id": "q24.3", - "start": 138900001, - "end": 145138636, - "type": "gneg" - }, - { - "id": "q21.13", - "start": 74700001, - "end": 83500000, - "type": "gpos75" - }, - { - "id": "q21.3", - "start": 85900001, - "end": 92300000, - "type": "gpos100" - }, - { - "id": "p23.1", - "start": 6300001, - "end": 12800000, - "type": "gneg" - }, - { - "id": "p11.1", - "start": 43200001, - "end": 45200000, - "type": "acen" - }, - { - "id": "p21.1", - "start": 27500001, - "end": 29000000, - "type": "gneg" - }, - { - "id": "q21.11", - "start": 72000001, - "end": 74600000, - "type": "gpos100" - }, - { - "id": "p22", - "start": 12800001, - "end": 19200000, - "type": "gpos100" - }, - { - "id": "q11.23", - "start": 51700001, - "end": 54600000, - "type": "gneg" - }, - { - "id": "q21.2", - "start": 83500001, - "end": 85900000, - "type": "gneg" - }, - { - "id": "q24.23", - "start": 135400001, - "end": 138900000, - "type": "gpos75" - }, - { - "id": "p21.2", - "start": 23500001, - "end": 27500000, - "type": "gpos50" - }, - { - "id": "q12.2", - "start": 60600001, - "end": 61300000, - "type": "gneg" - }, - { - "id": "q23.1", - "start": 105100001, - "end": 109500000, - "type": "gpos75" - }, - { - "id": "p11.21", - "start": 39900001, - "end": 43200000, - "type": "gneg" - }, - { - "id": "q24.21", - "start": 126300001, - "end": 130400000, - "type": "gpos50" - }, - { - "id": "q24.12", - "start": 118300001, - "end": 121500000, - "type": "gpos50" - }, - { - "id": "p23.3", - "start": 1, - "end": 2300000, - "type": "gneg" - }, - { - "id": "q12.3", - "start": 61300001, - "end": 65100000, - "type": "gpos50" - }, - { - "id": "q22.2", - "start": 97900001, - "end": 100500000, - "type": "gpos25" - }, - { - "id": "q24.11", - "start": 116700001, - "end": 118300000, - "type": "gneg" - }, - { - "id": "q23.3", - "start": 111100001, - "end": 116700000, - "type": "gpos100" - }, - { - "id": "q11.1", - "start": 45200001, - "end": 47200000, - "type": "acen" - }, - { - "id": "q21.12", - "start": 74600001, - "end": 74700000, - "type": "gneg" - } + "size" : 145138636, + "bands" : [ + { "id": "p11.1", "start": 43200001, "end": 45200000, "type": "acen" }, + { "id": "p11.21", "start": 39900001, "end": 43200000, "type": "gneg" }, + { "id": "p11.22", "start": 38500001, "end": 39900000, "type": "gpos25" }, + { "id": "p11.23", "start": 36700001, "end": 38500000, "type": "gneg" }, + { "id": "p12", "start": 29000001, "end": 36700000, "type": "gpos75" }, + { "id": "p21.1", "start": 27500001, "end": 29000000, "type": "gneg" }, + { "id": "p21.2", "start": 23500001, "end": 27500000, "type": "gpos50" }, + { "id": "p21.3", "start": 19200001, "end": 23500000, "type": "gneg" }, + { "id": "p22", "start": 12800001, "end": 19200000, "type": "gpos100" }, + { "id": "p23.1", "start": 6300001, "end": 12800000, "type": "gneg" }, + { "id": "p23.2", "start": 2300001, "end": 6300000, "type": "gpos75" }, + { "id": "p23.3", "start": 1, "end": 2300000, "type": "gneg" }, + { "id": "q11.1", "start": 45200001, "end": 47200000, "type": "acen" }, + { "id": "q11.21", "start": 47200001, "end": 51300000, "type": "gneg" }, + { "id": "q11.22", "start": 51300001, "end": 51700000, "type": "gpos75" }, + { "id": "q11.23", "start": 51700001, "end": 54600000, "type": "gneg" }, + { "id": "q12.1", "start": 54600001, "end": 60600000, "type": "gpos50" }, + { "id": "q12.2", "start": 60600001, "end": 61300000, "type": "gneg" }, + { "id": "q12.3", "start": 61300001, "end": 65100000, "type": "gpos50" }, + { "id": "q13.1", "start": 65100001, "end": 67100000, "type": "gneg" }, + { "id": "q13.2", "start": 67100001, "end": 69600000, "type": "gpos50" }, + { "id": "q13.3", "start": 69600001, "end": 72000000, "type": "gneg" }, + { "id": "q21.11", "start": 72000001, "end": 74600000, "type": "gpos100" }, + { "id": "q21.12", "start": 74600001, "end": 74700000, "type": "gneg" }, + { "id": "q21.13", "start": 74700001, "end": 83500000, "type": "gpos75" }, + { "id": "q21.2", "start": 83500001, "end": 85900000, "type": "gneg" }, + { "id": "q21.3", "start": 85900001, "end": 92300000, "type": "gpos100" }, + { "id": "q22.1", "start": 92300001, "end": 97900000, "type": "gneg" }, + { "id": "q22.2", "start": 97900001, "end": 100500000, "type": "gpos25" }, + { "id": "q22.3", "start": 100500001, "end": 105100000, "type": "gneg" }, + { "id": "q23.1", "start": 105100001, "end": 109500000, "type": "gpos75" }, + { "id": "q23.2", "start": 109500001, "end": 111100000, "type": "gneg" }, + { "id": "q23.3", "start": 111100001, "end": 116700000, "type": "gpos100" }, + { "id": "q24.11", "start": 116700001, "end": 118300000, "type": "gneg" }, + { "id": "q24.12", "start": 118300001, "end": 121500000, "type": "gpos50" }, + { "id": "q24.13", "start": 121500001, "end": 126300000, "type": "gneg" }, + { "id": "q24.21", "start": 126300001, "end": 130400000, "type": "gpos50" }, + { "id": "q24.22", "start": 130400001, "end": 135400000, "type": "gneg" }, + { "id": "q24.23", "start": 135400001, "end": 138900000, "type": "gpos75" }, + { "id": "q24.3", "start": 138900001, "end": 145138636, "type": "gneg" } ] }, "9": { - "size": 138394717, - "bands": [ - { - "id": "q22.1", - "start": 87800001, - "end": 89200000, - "type": "gneg" - }, - { - "id": "q21.32", - "start": 81500001, - "end": 84300000, - "type": "gneg" - }, - { - "id": "q22.31", - "start": 91200001, - "end": 93900000, - "type": "gneg" - }, - { - "id": "p21.3", - "start": 19900001, - "end": 25600000, - "type": "gpos100" - }, - { - "id": "q34.2", - "start": 133100001, - "end": 134500000, - "type": "gpos25" - }, - { - "id": "p13.3", - "start": 33200001, - "end": 36300000, - "type": "gneg" - }, - { - "id": "p22.2", - "start": 16600001, - "end": 18500000, - "type": "gpos25" - }, - { - "id": "q34.3", - "start": 134500001, - "end": 138394717, - "type": "gneg" - }, - { - "id": "q33.2", - "start": 119800001, - "end": 123100000, - "type": "gneg" - }, - { - "id": "q34.12", - "start": 130600001, - "end": 131100000, - "type": "gpos25" - }, - { - "id": "p13.2", - "start": 36300001, - "end": 37900000, - "type": "gpos25" - }, - { - "id": "q21.33", - "start": 84300001, - "end": 87800000, - "type": "gpos50" - }, - { - "id": "p11.2", - "start": 40000001, - "end": 42200000, - "type": "gneg" - }, - { - "id": "p12", - "start": 39000001, - "end": 40000000, - "type": "gpos50" - }, - { - "id": "p13.1", - "start": 37900001, - "end": 39000000, - "type": "gneg" - }, - { - "id": "q33.3", - "start": 123100001, - "end": 127500000, - "type": "gpos25" - }, - { - "id": "q21.13", - "start": 71300001, - "end": 76600000, - "type": "gpos50" - }, - { - "id": "q34.13", - "start": 131100001, - "end": 133100000, - "type": "gneg" - }, - { - "id": "q33.1", - "start": 114900001, - "end": 119800000, - "type": "gpos75" - }, - { - "id": "q34.11", - "start": 127500001, - "end": 130600000, - "type": "gneg" - }, - { - "id": "p11.1", - "start": 42200001, - "end": 43000000, - "type": "acen" - }, - { - "id": "p24.1", - "start": 4600001, - "end": 9000000, - "type": "gneg" - }, - { - "id": "p24.3", - "start": 1, - "end": 2200000, - "type": "gneg" - }, - { - "id": "p23", - "start": 9000001, - "end": 14200000, - "type": "gpos75" - }, - { - "id": "p21.1", - "start": 28000001, - "end": 33200000, - "type": "gpos100" - }, - { - "id": "q21.11", - "start": 65000001, - "end": 69300000, - "type": "gpos25" - }, - { - "id": "q21.31", - "start": 78500001, - "end": 81500000, - "type": "gpos50" - }, - { - "id": "q22.33", - "start": 96500001, - "end": 99800000, - "type": "gneg" - }, - { - "id": "q32", - "start": 112100001, - "end": 114900000, - "type": "gneg" - }, - { - "id": "p22.1", - "start": 18500001, - "end": 19900000, - "type": "gneg" - }, - { - "id": "q21.2", - "start": 76600001, - "end": 78500000, - "type": "gneg" - }, - { - "id": "q31.2", - "start": 105400001, - "end": 108500000, - "type": "gneg" - }, - { - "id": "p21.2", - "start": 25600001, - "end": 28000000, - "type": "gneg" - }, - { - "id": "q31.3", - "start": 108500001, - "end": 112100000, - "type": "gpos25" - }, - { - "id": "p22.3", - "start": 14200001, - "end": 16600000, - "type": "gneg" - }, - { - "id": "q22.32", - "start": 93900001, - "end": 96500000, - "type": "gpos25" - }, - { - "id": "q13", - "start": 61500001, - "end": 65000000, - "type": "gneg" - }, - { - "id": "p24.2", - "start": 2200001, - "end": 4600000, - "type": "gpos25" - }, - { - "id": "q31.1", - "start": 99800001, - "end": 105400000, - "type": "gpos100" - }, - { - "id": "q12", - "start": 45500001, - "end": 61500000, - "type": "gvar" - }, - { - "id": "q22.2", - "start": 89200001, - "end": 91200000, - "type": "gpos25" - }, - { - "id": "q11", - "start": 43000001, - "end": 45500000, - "type": "acen" - }, - { - "id": "q21.12", - "start": 69300001, - "end": 71300000, - "type": "gneg" - } + "size" : 138394717, + "bands" : [ + { "id": "p11.1", "start": 42200001, "end": 43000000, "type": "acen" }, + { "id": "p11.2", "start": 40000001, "end": 42200000, "type": "gneg" }, + { "id": "p12", "start": 39000001, "end": 40000000, "type": "gpos50" }, + { "id": "p13.1", "start": 37900001, "end": 39000000, "type": "gneg" }, + { "id": "p13.2", "start": 36300001, "end": 37900000, "type": "gpos25" }, + { "id": "p13.3", "start": 33200001, "end": 36300000, "type": "gneg" }, + { "id": "p21.1", "start": 28000001, "end": 33200000, "type": "gpos100" }, + { "id": "p21.2", "start": 25600001, "end": 28000000, "type": "gneg" }, + { "id": "p21.3", "start": 19900001, "end": 25600000, "type": "gpos100" }, + { "id": "p22.1", "start": 18500001, "end": 19900000, "type": "gneg" }, + { "id": "p22.2", "start": 16600001, "end": 18500000, "type": "gpos25" }, + { "id": "p22.3", "start": 14200001, "end": 16600000, "type": "gneg" }, + { "id": "p23", "start": 9000001, "end": 14200000, "type": "gpos75" }, + { "id": "p24.1", "start": 4600001, "end": 9000000, "type": "gneg" }, + { "id": "p24.2", "start": 2200001, "end": 4600000, "type": "gpos25" }, + { "id": "p24.3", "start": 1, "end": 2200000, "type": "gneg" }, + { "id": "q11", "start": 43000001, "end": 45500000, "type": "acen" }, + { "id": "q12", "start": 45500001, "end": 61500000, "type": "gvar" }, + { "id": "q13", "start": 61500001, "end": 65000000, "type": "gneg" }, + { "id": "q21.11", "start": 65000001, "end": 69300000, "type": "gpos25" }, + { "id": "q21.12", "start": 69300001, "end": 71300000, "type": "gneg" }, + { "id": "q21.13", "start": 71300001, "end": 76600000, "type": "gpos50" }, + { "id": "q21.2", "start": 76600001, "end": 78500000, "type": "gneg" }, + { "id": "q21.31", "start": 78500001, "end": 81500000, "type": "gpos50" }, + { "id": "q21.32", "start": 81500001, "end": 84300000, "type": "gneg" }, + { "id": "q21.33", "start": 84300001, "end": 87800000, "type": "gpos50" }, + { "id": "q22.1", "start": 87800001, "end": 89200000, "type": "gneg" }, + { "id": "q22.2", "start": 89200001, "end": 91200000, "type": "gpos25" }, + { "id": "q22.31", "start": 91200001, "end": 93900000, "type": "gneg" }, + { "id": "q22.32", "start": 93900001, "end": 96500000, "type": "gpos25" }, + { "id": "q22.33", "start": 96500001, "end": 99800000, "type": "gneg" }, + { "id": "q31.1", "start": 99800001, "end": 105400000, "type": "gpos100" }, + { "id": "q31.2", "start": 105400001, "end": 108500000, "type": "gneg" }, + { "id": "q31.3", "start": 108500001, "end": 112100000, "type": "gpos25" }, + { "id": "q32", "start": 112100001, "end": 114900000, "type": "gneg" }, + { "id": "q33.1", "start": 114900001, "end": 119800000, "type": "gpos75" }, + { "id": "q33.2", "start": 119800001, "end": 123100000, "type": "gneg" }, + { "id": "q33.3", "start": 123100001, "end": 127500000, "type": "gpos25" }, + { "id": "q34.11", "start": 127500001, "end": 130600000, "type": "gneg" }, + { "id": "q34.12", "start": 130600001, "end": 131100000, "type": "gpos25" }, + { "id": "q34.13", "start": 131100001, "end": 133100000, "type": "gneg" }, + { "id": "q34.2", "start": 133100001, "end": 134500000, "type": "gpos25" }, + { "id": "q34.3", "start": 134500001, "end": 138394717, "type": "gneg" } ] }, "10": { - "size": 133797422, - "bands": [ - { - "id": "q25.2", - "start": 110100001, - "end": 113100000, - "type": "gneg" - }, - { - "id": "q22.1", - "start": 68800001, - "end": 73100000, - "type": "gneg" - }, - { - "id": "q11.21", - "start": 41600001, - "end": 45500000, - "type": "gneg" - }, - { - "id": "p15.2", - "start": 3000001, - "end": 3800000, - "type": "gpos25" - }, - { - "id": "q23.33", - "start": 92300001, - "end": 95300000, - "type": "gpos50" - }, - { - "id": "q24.31", - "start": 100100001, - "end": 101200000, - "type": "gneg" - }, - { - "id": "q24.1", - "start": 95300001, - "end": 97500000, - "type": "gneg" - }, - { - "id": "p15.1", - "start": 3800001, - "end": 6600000, - "type": "gneg" - }, - { - "id": "p12.33", - "start": 17300001, - "end": 18300000, - "type": "gpos75" - }, - { - "id": "q23.2", - "start": 86100001, - "end": 87700000, - "type": "gneg" - }, - { - "id": "q21.1", - "start": 51100001, - "end": 59400000, - "type": "gpos100" - }, - { - "id": "q11.22", - "start": 45500001, - "end": 48600000, - "type": "gpos25" - }, - { - "id": "q26.2", - "start": 125700001, - "end": 128800000, - "type": "gpos50" - }, - { - "id": "q22.3", - "start": 75900001, - "end": 80300000, - "type": "gneg" - }, - { - "id": "q24.2", - "start": 97500001, - "end": 100100000, - "type": "gpos50" - }, - { - "id": "p12.31", - "start": 18400001, - "end": 22300000, - "type": "gpos75" - }, - { - "id": "p11.22", - "start": 31100001, - "end": 34200000, - "type": "gpos25" - }, - { - "id": "q25.3", - "start": 113100001, - "end": 117300000, - "type": "gpos75" - }, - { - "id": "q23.32", - "start": 91100001, - "end": 92300000, - "type": "gneg" - }, - { - "id": "p12.1", - "start": 24300001, - "end": 29300000, - "type": "gpos50" - }, - { - "id": "p11.23", - "start": 29300001, - "end": 31100000, - "type": "gneg" - }, - { - "id": "q26.12", - "start": 119900001, - "end": 121400000, - "type": "gpos50" - }, - { - "id": "q24.33", - "start": 103100001, - "end": 104000000, - "type": "gneg" - }, - { - "id": "q21.3", - "start": 62800001, - "end": 68800000, - "type": "gpos100" - }, - { - "id": "p11.1", - "start": 38000001, - "end": 39800000, - "type": "acen" - }, - { - "id": "q24.32", - "start": 101200001, - "end": 103100000, - "type": "gpos25" - }, - { - "id": "q26.13", - "start": 121400001, - "end": 125700000, - "type": "gneg" - }, - { - "id": "q25.1", - "start": 104000001, - "end": 110100000, - "type": "gpos100" - }, - { - "id": "p13", - "start": 12200001, - "end": 17300000, - "type": "gneg" - }, - { - "id": "p14", - "start": 6600001, - "end": 12200000, - "type": "gpos75" - }, - { - "id": "q11.23", - "start": 48600001, - "end": 51100000, - "type": "gneg" - }, - { - "id": "q23.31", - "start": 87700001, - "end": 91100000, - "type": "gpos75" - }, - { - "id": "p12.32", - "start": 18300001, - "end": 18400000, - "type": "gneg" - }, - { - "id": "q21.2", - "start": 59400001, - "end": 62800000, - "type": "gneg" - }, - { - "id": "q26.3", - "start": 128800001, - "end": 133797422, - "type": "gneg" - }, - { - "id": "q23.1", - "start": 80300001, - "end": 86100000, - "type": "gpos100" - }, - { - "id": "p11.21", - "start": 34200001, - "end": 38000000, - "type": "gneg" - }, - { - "id": "p15.3", - "start": 1, - "end": 3000000, - "type": "gneg" - }, - { - "id": "q22.2", - "start": 73100001, - "end": 75900000, - "type": "gpos50" - }, - { - "id": "q11.1", - "start": 39800001, - "end": 41600000, - "type": "acen" - }, - { - "id": "p12.2", - "start": 22300001, - "end": 24300000, - "type": "gneg" - }, - { - "id": "q26.11", - "start": 117300001, - "end": 119900000, - "type": "gneg" - } + "size" : 133797422, + "bands" : [ + { "id": "p11.1", "start": 38000001, "end": 39800000, "type": "acen" }, + { "id": "p11.21", "start": 34200001, "end": 38000000, "type": "gneg" }, + { "id": "p11.22", "start": 31100001, "end": 34200000, "type": "gpos25" }, + { "id": "p11.23", "start": 29300001, "end": 31100000, "type": "gneg" }, + { "id": "p12.1", "start": 24300001, "end": 29300000, "type": "gpos50" }, + { "id": "p12.2", "start": 22300001, "end": 24300000, "type": "gneg" }, + { "id": "p12.31", "start": 18400001, "end": 22300000, "type": "gpos75" }, + { "id": "p12.32", "start": 18300001, "end": 18400000, "type": "gneg" }, + { "id": "p12.33", "start": 17300001, "end": 18300000, "type": "gpos75" }, + { "id": "p13", "start": 12200001, "end": 17300000, "type": "gneg" }, + { "id": "p14", "start": 6600001, "end": 12200000, "type": "gpos75" }, + { "id": "p15.1", "start": 3800001, "end": 6600000, "type": "gneg" }, + { "id": "p15.2", "start": 3000001, "end": 3800000, "type": "gpos25" }, + { "id": "p15.3", "start": 1, "end": 3000000, "type": "gneg" }, + { "id": "q11.1", "start": 39800001, "end": 41600000, "type": "acen" }, + { "id": "q11.21", "start": 41600001, "end": 45500000, "type": "gneg" }, + { "id": "q11.22", "start": 45500001, "end": 48600000, "type": "gpos25" }, + { "id": "q11.23", "start": 48600001, "end": 51100000, "type": "gneg" }, + { "id": "q21.1", "start": 51100001, "end": 59400000, "type": "gpos100" }, + { "id": "q21.2", "start": 59400001, "end": 62800000, "type": "gneg" }, + { "id": "q21.3", "start": 62800001, "end": 68800000, "type": "gpos100" }, + { "id": "q22.1", "start": 68800001, "end": 73100000, "type": "gneg" }, + { "id": "q22.2", "start": 73100001, "end": 75900000, "type": "gpos50" }, + { "id": "q22.3", "start": 75900001, "end": 80300000, "type": "gneg" }, + { "id": "q23.1", "start": 80300001, "end": 86100000, "type": "gpos100" }, + { "id": "q23.2", "start": 86100001, "end": 87700000, "type": "gneg" }, + { "id": "q23.31", "start": 87700001, "end": 91100000, "type": "gpos75" }, + { "id": "q23.32", "start": 91100001, "end": 92300000, "type": "gneg" }, + { "id": "q23.33", "start": 92300001, "end": 95300000, "type": "gpos50" }, + { "id": "q24.1", "start": 95300001, "end": 97500000, "type": "gneg" }, + { "id": "q24.2", "start": 97500001, "end": 100100000, "type": "gpos50" }, + { "id": "q24.31", "start": 100100001, "end": 101200000, "type": "gneg" }, + { "id": "q24.32", "start": 101200001, "end": 103100000, "type": "gpos25" }, + { "id": "q24.33", "start": 103100001, "end": 104000000, "type": "gneg" }, + { "id": "q25.1", "start": 104000001, "end": 110100000, "type": "gpos100" }, + { "id": "q25.2", "start": 110100001, "end": 113100000, "type": "gneg" }, + { "id": "q25.3", "start": 113100001, "end": 117300000, "type": "gpos75" }, + { "id": "q26.11", "start": 117300001, "end": 119900000, "type": "gneg" }, + { "id": "q26.12", "start": 119900001, "end": 121400000, "type": "gpos50" }, + { "id": "q26.13", "start": 121400001, "end": 125700000, "type": "gneg" }, + { "id": "q26.2", "start": 125700001, "end": 128800000, "type": "gpos50" }, + { "id": "q26.3", "start": 128800001, "end": 133797422, "type": "gneg" } ] }, "11": { - "size": 135086622, - "bands": [ - { - "id": "q22.1", - "start": 97400001, - "end": 102300000, - "type": "gpos100" - }, - { - "id": "p11.12", - "start": 48800001, - "end": 51000000, - "type": "gpos75" - }, - { - "id": "q13.1", - "start": 63600001, - "end": 66100000, - "type": "gneg" - }, - { - "id": "p15.2", - "start": 13800001, - "end": 16900000, - "type": "gpos50" - }, - { - "id": "q12.1", - "start": 55800001, - "end": 60100000, - "type": "gpos75" - }, - { - "id": "p15.4", - "start": 2800001, - "end": 11700000, - "type": "gpos50" - }, - { - "id": "q14.1", - "start": 77400001, - "end": 85900000, - "type": "gpos100" - }, - { - "id": "q24.1", - "start": 121300001, - "end": 124000000, - "type": "gpos50" - }, - { - "id": "q13.4", - "start": 70500001, - "end": 75500000, - "type": "gpos50" - }, - { - "id": "p15.1", - "start": 16900001, - "end": 22000000, - "type": "gneg" - }, - { - "id": "q13.3", - "start": 68700001, - "end": 70500000, - "type": "gneg" - }, - { - "id": "q23.2", - "start": 112700001, - "end": 114600000, - "type": "gpos50" - }, - { - "id": "q22.3", - "start": 103000001, - "end": 110600000, - "type": "gpos100" - }, - { - "id": "q24.2", - "start": 124000001, - "end": 127900000, - "type": "gneg" - }, - { - "id": "q13.2", - "start": 66100001, - "end": 68700000, - "type": "gpos25" - }, - { - "id": "p11.11", - "start": 51000001, - "end": 53400000, - "type": "acen" - }, - { - "id": "q14.3", - "start": 88600001, - "end": 93000000, - "type": "gpos100" - }, - { - "id": "q21", - "start": 93000001, - "end": 97400000, - "type": "gneg" - }, - { - "id": "q14.2", - "start": 85900001, - "end": 88600000, - "type": "gneg" - }, - { - "id": "q13.5", - "start": 75500001, - "end": 77400000, - "type": "gneg" - }, - { - "id": "p14.3", - "start": 22000001, - "end": 26200000, - "type": "gpos100" - }, - { - "id": "p11.2", - "start": 43400001, - "end": 48800000, - "type": "gneg" - }, - { - "id": "p12", - "start": 36400001, - "end": 43400000, - "type": "gpos100" - }, - { - "id": "p14.2", - "start": 26200001, - "end": 27200000, - "type": "gneg" - }, - { - "id": "q25", - "start": 130900001, - "end": 135086622, - "type": "gneg" - }, - { - "id": "q24.3", - "start": 127900001, - "end": 130900000, - "type": "gpos50" - }, - { - "id": "p13", - "start": 31000001, - "end": 36400000, - "type": "gneg" - }, - { - "id": "p15.5", - "start": 1, - "end": 2800000, - "type": "gneg" - }, - { - "id": "p14.1", - "start": 27200001, - "end": 31000000, - "type": "gpos75" - }, - { - "id": "q12.2", - "start": 60100001, - "end": 61900000, - "type": "gneg" - }, - { - "id": "q23.1", - "start": 110600001, - "end": 112700000, - "type": "gneg" - }, - { - "id": "p15.3", - "start": 11700001, - "end": 13800000, - "type": "gneg" - }, - { - "id": "q12.3", - "start": 61900001, - "end": 63600000, - "type": "gpos25" - }, - { - "id": "q22.2", - "start": 102300001, - "end": 103000000, - "type": "gneg" - }, - { - "id": "q23.3", - "start": 114600001, - "end": 121300000, - "type": "gneg" - }, - { - "id": "q11", - "start": 53400001, - "end": 55800000, - "type": "acen" - } + "size" : 135086622, + "bands" : [ + { "id": "p11.11", "start": 51000001, "end": 53400000, "type": "acen" }, + { "id": "p11.12", "start": 48800001, "end": 51000000, "type": "gpos75" }, + { "id": "p11.2", "start": 43400001, "end": 48800000, "type": "gneg" }, + { "id": "p12", "start": 36400001, "end": 43400000, "type": "gpos100" }, + { "id": "p13", "start": 31000001, "end": 36400000, "type": "gneg" }, + { "id": "p14.1", "start": 27200001, "end": 31000000, "type": "gpos75" }, + { "id": "p14.2", "start": 26200001, "end": 27200000, "type": "gneg" }, + { "id": "p14.3", "start": 22000001, "end": 26200000, "type": "gpos100" }, + { "id": "p15.1", "start": 16900001, "end": 22000000, "type": "gneg" }, + { "id": "p15.2", "start": 13800001, "end": 16900000, "type": "gpos50" }, + { "id": "p15.3", "start": 11700001, "end": 13800000, "type": "gneg" }, + { "id": "p15.4", "start": 2800001, "end": 11700000, "type": "gpos50" }, + { "id": "p15.5", "start": 1, "end": 2800000, "type": "gneg" }, + { "id": "q11", "start": 53400001, "end": 55800000, "type": "acen" }, + { "id": "q12.1", "start": 55800001, "end": 60100000, "type": "gpos75" }, + { "id": "q12.2", "start": 60100001, "end": 61900000, "type": "gneg" }, + { "id": "q12.3", "start": 61900001, "end": 63600000, "type": "gpos25" }, + { "id": "q13.1", "start": 63600001, "end": 66100000, "type": "gneg" }, + { "id": "q13.2", "start": 66100001, "end": 68700000, "type": "gpos25" }, + { "id": "q13.3", "start": 68700001, "end": 70500000, "type": "gneg" }, + { "id": "q13.4", "start": 70500001, "end": 75500000, "type": "gpos50" }, + { "id": "q13.5", "start": 75500001, "end": 77400000, "type": "gneg" }, + { "id": "q14.1", "start": 77400001, "end": 85900000, "type": "gpos100" }, + { "id": "q14.2", "start": 85900001, "end": 88600000, "type": "gneg" }, + { "id": "q14.3", "start": 88600001, "end": 93000000, "type": "gpos100" }, + { "id": "q21", "start": 93000001, "end": 97400000, "type": "gneg" }, + { "id": "q22.1", "start": 97400001, "end": 102300000, "type": "gpos100" }, + { "id": "q22.2", "start": 102300001, "end": 103000000, "type": "gneg" }, + { "id": "q22.3", "start": 103000001, "end": 110600000, "type": "gpos100" }, + { "id": "q23.1", "start": 110600001, "end": 112700000, "type": "gneg" }, + { "id": "q23.2", "start": 112700001, "end": 114600000, "type": "gpos50" }, + { "id": "q23.3", "start": 114600001, "end": 121300000, "type": "gneg" }, + { "id": "q24.1", "start": 121300001, "end": 124000000, "type": "gpos50" }, + { "id": "q24.2", "start": 124000001, "end": 127900000, "type": "gneg" }, + { "id": "q24.3", "start": 127900001, "end": 130900000, "type": "gpos50" }, + { "id": "q25", "start": 130900001, "end": 135086622, "type": "gneg" } ] }, "12": { - "size": 133275309, - "bands": [ - { - "id": "q21.32", - "start": 86300001, - "end": 88600000, - "type": "gneg" - }, - { - "id": "q14.1", - "start": 57700001, - "end": 62700000, - "type": "gpos75" - }, - { - "id": "q24.31", - "start": 120300001, - "end": 125400000, - "type": "gneg" - }, - { - "id": "q13.3", - "start": 56200001, - "end": 57700000, - "type": "gneg" - }, - { - "id": "p12.3", - "start": 14600001, - "end": 19800000, - "type": "gpos100" - }, - { - "id": "q15", - "start": 67300001, - "end": 71100000, - "type": "gneg" - }, - { - "id": "q23.2", - "start": 101200001, - "end": 103500000, - "type": "gneg" - }, - { - "id": "q21.1", - "start": 71100001, - "end": 75300000, - "type": "gpos75" - }, - { - "id": "q13.2", - "start": 54500001, - "end": 56200000, - "type": "gpos25" - }, - { - "id": "q14.3", - "start": 64700001, - "end": 67300000, - "type": "gpos50" - }, - { - "id": "p11.22", - "start": 27600001, - "end": 30500000, - "type": "gpos50" - }, - { - "id": "q24.22", - "start": 116400001, - "end": 117700000, - "type": "gneg" - }, - { - "id": "q24.13", - "start": 111900001, - "end": 113900000, - "type": "gneg" - }, - { - "id": "q14.2", - "start": 62700001, - "end": 64700000, - "type": "gneg" - }, - { - "id": "p12.1", - "start": 21100001, - "end": 26300000, - "type": "gpos100" - }, - { - "id": "p13.33", - "start": 1, - "end": 3200000, - "type": "gneg" - }, - { - "id": "p11.23", - "start": 26300001, - "end": 27600000, - "type": "gneg" - }, - { - "id": "p13.2", - "start": 10000001, - "end": 12600000, - "type": "gpos75" - }, - { - "id": "q21.33", - "start": 88600001, - "end": 92200000, - "type": "gpos100" - }, - { - "id": "p13.32", - "start": 3200001, - "end": 5300000, - "type": "gpos25" - }, - { - "id": "p13.1", - "start": 12600001, - "end": 14600000, - "type": "gneg" - }, - { - "id": "q13.12", - "start": 48700001, - "end": 51100000, - "type": "gpos25" - }, - { - "id": "q13.13", - "start": 51100001, - "end": 54500000, - "type": "gneg" - }, - { - "id": "q24.33", - "start": 128700001, - "end": 133275309, - "type": "gneg" - }, - { - "id": "p11.1", - "start": 33200001, - "end": 35500000, - "type": "acen" - }, - { - "id": "q24.32", - "start": 125400001, - "end": 128700000, - "type": "gpos50" - }, - { - "id": "q21.31", - "start": 79900001, - "end": 86300000, - "type": "gpos100" - }, - { - "id": "q21.2", - "start": 75300001, - "end": 79900000, - "type": "gneg" - }, - { - "id": "q24.23", - "start": 117700001, - "end": 120300000, - "type": "gpos50" - }, - { - "id": "q13.11", - "start": 46000001, - "end": 48700000, - "type": "gneg" - }, - { - "id": "q23.1", - "start": 95800001, - "end": 101200000, - "type": "gpos75" - }, - { - "id": "p11.21", - "start": 30500001, - "end": 33200000, - "type": "gneg" - }, - { - "id": "q24.21", - "start": 113900001, - "end": 116400000, - "type": "gpos50" - }, - { - "id": "q24.12", - "start": 111300001, - "end": 111900000, - "type": "gpos25" - }, - { - "id": "q22", - "start": 92200001, - "end": 95800000, - "type": "gneg" - }, - { - "id": "p13.31", - "start": 5300001, - "end": 10000000, - "type": "gneg" - }, - { - "id": "q12", - "start": 37800001, - "end": 46000000, - "type": "gpos100" - }, - { - "id": "q24.11", - "start": 108600001, - "end": 111300000, - "type": "gneg" - }, - { - "id": "p12.2", - "start": 19800001, - "end": 21100000, - "type": "gneg" - }, - { - "id": "q23.3", - "start": 103500001, - "end": 108600000, - "type": "gpos50" - }, - { - "id": "q11", - "start": 35500001, - "end": 37800000, - "type": "acen" - } + "size" : 133275309, + "bands" : [ + { "id": "p11.1", "start": 33200001, "end": 35500000, "type": "acen" }, + { "id": "p11.21", "start": 30500001, "end": 33200000, "type": "gneg" }, + { "id": "p11.22", "start": 27600001, "end": 30500000, "type": "gpos50" }, + { "id": "p11.23", "start": 26300001, "end": 27600000, "type": "gneg" }, + { "id": "p12.1", "start": 21100001, "end": 26300000, "type": "gpos100" }, + { "id": "p12.2", "start": 19800001, "end": 21100000, "type": "gneg" }, + { "id": "p12.3", "start": 14600001, "end": 19800000, "type": "gpos100" }, + { "id": "p13.1", "start": 12600001, "end": 14600000, "type": "gneg" }, + { "id": "p13.2", "start": 10000001, "end": 12600000, "type": "gpos75" }, + { "id": "p13.31", "start": 5300001, "end": 10000000, "type": "gneg" }, + { "id": "p13.32", "start": 3200001, "end": 5300000, "type": "gpos25" }, + { "id": "p13.33", "start": 1, "end": 3200000, "type": "gneg" }, + { "id": "q11", "start": 35500001, "end": 37800000, "type": "acen" }, + { "id": "q12", "start": 37800001, "end": 46000000, "type": "gpos100" }, + { "id": "q13.11", "start": 46000001, "end": 48700000, "type": "gneg" }, + { "id": "q13.12", "start": 48700001, "end": 51100000, "type": "gpos25" }, + { "id": "q13.13", "start": 51100001, "end": 54500000, "type": "gneg" }, + { "id": "q13.2", "start": 54500001, "end": 56200000, "type": "gpos25" }, + { "id": "q13.3", "start": 56200001, "end": 57700000, "type": "gneg" }, + { "id": "q14.1", "start": 57700001, "end": 62700000, "type": "gpos75" }, + { "id": "q14.2", "start": 62700001, "end": 64700000, "type": "gneg" }, + { "id": "q14.3", "start": 64700001, "end": 67300000, "type": "gpos50" }, + { "id": "q15", "start": 67300001, "end": 71100000, "type": "gneg" }, + { "id": "q21.1", "start": 71100001, "end": 75300000, "type": "gpos75" }, + { "id": "q21.2", "start": 75300001, "end": 79900000, "type": "gneg" }, + { "id": "q21.31", "start": 79900001, "end": 86300000, "type": "gpos100" }, + { "id": "q21.32", "start": 86300001, "end": 88600000, "type": "gneg" }, + { "id": "q21.33", "start": 88600001, "end": 92200000, "type": "gpos100" }, + { "id": "q22", "start": 92200001, "end": 95800000, "type": "gneg" }, + { "id": "q23.1", "start": 95800001, "end": 101200000, "type": "gpos75" }, + { "id": "q23.2", "start": 101200001, "end": 103500000, "type": "gneg" }, + { "id": "q23.3", "start": 103500001, "end": 108600000, "type": "gpos50" }, + { "id": "q24.11", "start": 108600001, "end": 111300000, "type": "gneg" }, + { "id": "q24.12", "start": 111300001, "end": 111900000, "type": "gpos25" }, + { "id": "q24.13", "start": 111900001, "end": 113900000, "type": "gneg" }, + { "id": "q24.21", "start": 113900001, "end": 116400000, "type": "gpos50" }, + { "id": "q24.22", "start": 116400001, "end": 117700000, "type": "gneg" }, + { "id": "q24.23", "start": 117700001, "end": 120300000, "type": "gpos50" }, + { "id": "q24.31", "start": 120300001, "end": 125400000, "type": "gneg" }, + { "id": "q24.32", "start": 125400001, "end": 128700000, "type": "gpos50" }, + { "id": "q24.33", "start": 128700001, "end": 133275309, "type": "gneg" } ] }, "13": { - "size": 114364328, - "bands": [ - { - "id": "q22.1", - "start": 72800001, - "end": 74900000, - "type": "gneg" - }, - { - "id": "q34", - "start": 109600001, - "end": 114364328, - "type": "gneg" - }, - { - "id": "q13.1", - "start": 31600001, - "end": 33400000, - "type": "gpos50" - }, - { - "id": "q21.32", - "start": 65200001, - "end": 68100000, - "type": "gneg" - }, - { - "id": "q14.13", - "start": 45200001, - "end": 46700000, - "type": "gneg" - }, - { - "id": "q13.3", - "start": 34900001, - "end": 39500000, - "type": "gpos75" - }, - { - "id": "q21.1", - "start": 54700001, - "end": 59000000, - "type": "gpos100" - }, - { - "id": "q22.3", - "start": 76700001, - "end": 78500000, - "type": "gneg" - }, - { - "id": "q33.2", - "start": 104200001, - "end": 106400000, - "type": "gneg" - }, - { - "id": "q13.2", - "start": 33400001, - "end": 34900000, - "type": "gneg" - }, - { - "id": "q14.3", - "start": 50300001, - "end": 54700000, - "type": "gneg" - }, - { - "id": "q14.2", - "start": 46700001, - "end": 50300000, - "type": "gpos50" - }, - { - "id": "q12.12", - "start": 22600001, - "end": 24900000, - "type": "gpos25" - }, - { - "id": "q21.33", - "start": 68100001, - "end": 72800000, - "type": "gpos100" - }, - { - "id": "q12.13", - "start": 24900001, - "end": 27200000, - "type": "gneg" - }, - { - "id": "p11.2", - "start": 10100001, - "end": 16500000, - "type": "gvar" - }, - { - "id": "p12", - "start": 4600001, - "end": 10100000, - "type": "stalk" - }, - { - "id": "q33.3", - "start": 106400001, - "end": 109600000, - "type": "gpos100" - }, - { - "id": "q33.1", - "start": 101100001, - "end": 104200000, - "type": "gpos100" - }, - { - "id": "p11.1", - "start": 16500001, - "end": 17700000, - "type": "acen" - }, - { - "id": "q12.11", - "start": 18900001, - "end": 22600000, - "type": "gneg" - }, - { - "id": "p13", - "start": 1, - "end": 4600000, - "type": "gvar" - }, - { - "id": "q21.31", - "start": 61800001, - "end": 65200000, - "type": "gpos75" - }, - { - "id": "q32.1", - "start": 94400001, - "end": 97500000, - "type": "gneg" - }, - { - "id": "q14.12", - "start": 44600001, - "end": 45200000, - "type": "gpos25" - }, - { - "id": "q21.2", - "start": 59000001, - "end": 61800000, - "type": "gneg" - }, - { - "id": "q31.2", - "start": 87100001, - "end": 89400000, - "type": "gneg" - }, - { - "id": "q12.2", - "start": 27200001, - "end": 28300000, - "type": "gpos25" - }, - { - "id": "q31.3", - "start": 89400001, - "end": 94400000, - "type": "gpos100" - }, - { - "id": "q31.1", - "start": 78500001, - "end": 87100000, - "type": "gpos100" - }, - { - "id": "q12.3", - "start": 28300001, - "end": 31600000, - "type": "gneg" - }, - { - "id": "q22.2", - "start": 74900001, - "end": 76700000, - "type": "gpos50" - }, - { - "id": "q32.2", - "start": 97500001, - "end": 98700000, - "type": "gpos25" - }, - { - "id": "q14.11", - "start": 39500001, - "end": 44600000, - "type": "gneg" - }, - { - "id": "q11", - "start": 17700001, - "end": 18900000, - "type": "acen" - }, - { - "id": "q32.3", - "start": 98700001, - "end": 101100000, - "type": "gneg" - } + "size" : 114364328, + "bands" : [ + { "id": "p11.1", "start": 16500001, "end": 17700000, "type": "acen" }, + { "id": "p11.2", "start": 10100001, "end": 16500000, "type": "gvar" }, + { "id": "p12", "start": 4600001, "end": 10100000, "type": "stalk" }, + { "id": "p13", "start": 1, "end": 4600000, "type": "gvar" }, + { "id": "q11", "start": 17700001, "end": 18900000, "type": "acen" }, + { "id": "q12.11", "start": 18900001, "end": 22600000, "type": "gneg" }, + { "id": "q12.12", "start": 22600001, "end": 24900000, "type": "gpos25" }, + { "id": "q12.13", "start": 24900001, "end": 27200000, "type": "gneg" }, + { "id": "q12.2", "start": 27200001, "end": 28300000, "type": "gpos25" }, + { "id": "q12.3", "start": 28300001, "end": 31600000, "type": "gneg" }, + { "id": "q13.1", "start": 31600001, "end": 33400000, "type": "gpos50" }, + { "id": "q13.2", "start": 33400001, "end": 34900000, "type": "gneg" }, + { "id": "q13.3", "start": 34900001, "end": 39500000, "type": "gpos75" }, + { "id": "q14.11", "start": 39500001, "end": 44600000, "type": "gneg" }, + { "id": "q14.12", "start": 44600001, "end": 45200000, "type": "gpos25" }, + { "id": "q14.13", "start": 45200001, "end": 46700000, "type": "gneg" }, + { "id": "q14.2", "start": 46700001, "end": 50300000, "type": "gpos50" }, + { "id": "q14.3", "start": 50300001, "end": 54700000, "type": "gneg" }, + { "id": "q21.1", "start": 54700001, "end": 59000000, "type": "gpos100" }, + { "id": "q21.2", "start": 59000001, "end": 61800000, "type": "gneg" }, + { "id": "q21.31", "start": 61800001, "end": 65200000, "type": "gpos75" }, + { "id": "q21.32", "start": 65200001, "end": 68100000, "type": "gneg" }, + { "id": "q21.33", "start": 68100001, "end": 72800000, "type": "gpos100" }, + { "id": "q22.1", "start": 72800001, "end": 74900000, "type": "gneg" }, + { "id": "q22.2", "start": 74900001, "end": 76700000, "type": "gpos50" }, + { "id": "q22.3", "start": 76700001, "end": 78500000, "type": "gneg" }, + { "id": "q31.1", "start": 78500001, "end": 87100000, "type": "gpos100" }, + { "id": "q31.2", "start": 87100001, "end": 89400000, "type": "gneg" }, + { "id": "q31.3", "start": 89400001, "end": 94400000, "type": "gpos100" }, + { "id": "q32.1", "start": 94400001, "end": 97500000, "type": "gneg" }, + { "id": "q32.2", "start": 97500001, "end": 98700000, "type": "gpos25" }, + { "id": "q32.3", "start": 98700001, "end": 101100000, "type": "gneg" }, + { "id": "q33.1", "start": 101100001, "end": 104200000, "type": "gpos100" }, + { "id": "q33.2", "start": 104200001, "end": 106400000, "type": "gneg" }, + { "id": "q33.3", "start": 106400001, "end": 109600000, "type": "gpos100" }, + { "id": "q34", "start": 109600001, "end": 114364328, "type": "gneg" } ] }, "14": { - "size": 107043718, - "bands": [ - { - "id": "q32.32", - "start": 102700001, - "end": 103500000, - "type": "gpos50" - }, - { - "id": "q22.1", - "start": 50400001, - "end": 53600000, - "type": "gneg" - }, - { - "id": "q13.1", - "start": 32900001, - "end": 34800000, - "type": "gneg" - }, - { - "id": "q24.1", - "start": 67400001, - "end": 69800000, - "type": "gneg" - }, - { - "id": "q13.3", - "start": 36100001, - "end": 37400000, - "type": "gneg" - }, - { - "id": "q23.2", - "start": 61600001, - "end": 64300000, - "type": "gneg" - }, - { - "id": "q21.1", - "start": 37400001, - "end": 43000000, - "type": "gpos100" - }, - { - "id": "q22.3", - "start": 55000001, - "end": 57600000, - "type": "gneg" - }, - { - "id": "q24.2", - "start": 69800001, - "end": 73300000, - "type": "gpos50" - }, - { - "id": "q13.2", - "start": 34800001, - "end": 36100000, - "type": "gpos50" - }, - { - "id": "q11.2", - "start": 18200001, - "end": 24100000, - "type": "gneg" - }, - { - "id": "p11.2", - "start": 8000001, - "end": 16100000, - "type": "gvar" - }, - { - "id": "p12", - "start": 3600001, - "end": 8000000, - "type": "stalk" - }, - { - "id": "q32.11", - "start": 89300001, - "end": 91400000, - "type": "gneg" - }, - { - "id": "q24.3", - "start": 73300001, - "end": 78800000, - "type": "gneg" - }, - { - "id": "q32.13", - "start": 94200001, - "end": 95800000, - "type": "gneg" - }, - { - "id": "q21.3", - "start": 46700001, - "end": 50400000, - "type": "gpos100" - }, - { - "id": "p11.1", - "start": 16100001, - "end": 17200000, - "type": "acen" - }, - { - "id": "p13", - "start": 1, - "end": 3600000, - "type": "gvar" - }, - { - "id": "q32.31", - "start": 100900001, - "end": 102700000, - "type": "gneg" - }, - { - "id": "q21.2", - "start": 43000001, - "end": 46700000, - "type": "gneg" - }, - { - "id": "q31.2", - "start": 83100001, - "end": 84400000, - "type": "gneg" - }, - { - "id": "q32.33", - "start": 103500001, - "end": 107043718, - "type": "gneg" - }, - { - "id": "q23.1", - "start": 57600001, - "end": 61600000, - "type": "gpos75" - }, - { - "id": "q31.3", - "start": 84400001, - "end": 89300000, - "type": "gpos100" - }, - { - "id": "q32.12", - "start": 91400001, - "end": 94200000, - "type": "gpos25" - }, - { - "id": "q31.1", - "start": 78800001, - "end": 83100000, - "type": "gpos100" - }, - { - "id": "q22.2", - "start": 53600001, - "end": 55000000, - "type": "gpos25" - }, - { - "id": "q12", - "start": 24100001, - "end": 32900000, - "type": "gpos100" - }, - { - "id": "q32.2", - "start": 95800001, - "end": 100900000, - "type": "gpos50" - }, - { - "id": "q11.1", - "start": 17200001, - "end": 18200000, - "type": "acen" - }, - { - "id": "q23.3", - "start": 64300001, - "end": 67400000, - "type": "gpos50" - } + "size" : 107043718, + "bands" : [ + { "id": "p11.1", "start": 16100001, "end": 17200000, "type": "acen" }, + { "id": "p11.2", "start": 8000001, "end": 16100000, "type": "gvar" }, + { "id": "p12", "start": 3600001, "end": 8000000, "type": "stalk" }, + { "id": "p13", "start": 1, "end": 3600000, "type": "gvar" }, + { "id": "q11.1", "start": 17200001, "end": 18200000, "type": "acen" }, + { "id": "q11.2", "start": 18200001, "end": 24100000, "type": "gneg" }, + { "id": "q12", "start": 24100001, "end": 32900000, "type": "gpos100" }, + { "id": "q13.1", "start": 32900001, "end": 34800000, "type": "gneg" }, + { "id": "q13.2", "start": 34800001, "end": 36100000, "type": "gpos50" }, + { "id": "q13.3", "start": 36100001, "end": 37400000, "type": "gneg" }, + { "id": "q21.1", "start": 37400001, "end": 43000000, "type": "gpos100" }, + { "id": "q21.2", "start": 43000001, "end": 46700000, "type": "gneg" }, + { "id": "q21.3", "start": 46700001, "end": 50400000, "type": "gpos100" }, + { "id": "q22.1", "start": 50400001, "end": 53600000, "type": "gneg" }, + { "id": "q22.2", "start": 53600001, "end": 55000000, "type": "gpos25" }, + { "id": "q22.3", "start": 55000001, "end": 57600000, "type": "gneg" }, + { "id": "q23.1", "start": 57600001, "end": 61600000, "type": "gpos75" }, + { "id": "q23.2", "start": 61600001, "end": 64300000, "type": "gneg" }, + { "id": "q23.3", "start": 64300001, "end": 67400000, "type": "gpos50" }, + { "id": "q24.1", "start": 67400001, "end": 69800000, "type": "gneg" }, + { "id": "q24.2", "start": 69800001, "end": 73300000, "type": "gpos50" }, + { "id": "q24.3", "start": 73300001, "end": 78800000, "type": "gneg" }, + { "id": "q31.1", "start": 78800001, "end": 83100000, "type": "gpos100" }, + { "id": "q31.2", "start": 83100001, "end": 84400000, "type": "gneg" }, + { "id": "q31.3", "start": 84400001, "end": 89300000, "type": "gpos100" }, + { "id": "q32.11", "start": 89300001, "end": 91400000, "type": "gneg" }, + { "id": "q32.12", "start": 91400001, "end": 94200000, "type": "gpos25" }, + { "id": "q32.13", "start": 94200001, "end": 95800000, "type": "gneg" }, + { "id": "q32.2", "start": 95800001, "end": 100900000, "type": "gpos50" }, + { "id": "q32.31", "start": 100900001, "end": 102700000, "type": "gneg" }, + { "id": "q32.32", "start": 102700001, "end": 103500000, "type": "gpos50" }, + { "id": "q32.33", "start": 103500001, "end": 107043718, "type": "gneg" } ] }, "15": { - "size": 101991189, - "bands": [ - { - "id": "q25.2", - "start": 81400001, - "end": 84700000, - "type": "gneg" - }, - { - "id": "q22.1", - "start": 58800001, - "end": 59000000, - "type": "gneg" - }, - { - "id": "q13.1", - "start": 27800001, - "end": 30000000, - "type": "gneg" - }, - { - "id": "q22.31", - "start": 63400001, - "end": 66900000, - "type": "gneg" - }, - { - "id": "q24.1", - "start": 72400001, - "end": 74900000, - "type": "gneg" - }, - { - "id": "q13.3", - "start": 30900001, - "end": 33400000, - "type": "gneg" - }, - { - "id": "q21.1", - "start": 44500001, - "end": 49200000, - "type": "gpos75" - }, - { - "id": "q26.2", - "start": 93800001, - "end": 98000000, - "type": "gpos50" - }, - { - "id": "q24.2", - "start": 74900001, - "end": 76300000, - "type": "gpos25" - }, - { - "id": "q13.2", - "start": 30000001, - "end": 30900000, - "type": "gpos50" - }, - { - "id": "q25.3", - "start": 84700001, - "end": 88500000, - "type": "gpos50" - }, - { - "id": "q14", - "start": 33400001, - "end": 39800000, - "type": "gpos75" - }, - { - "id": "q11.2", - "start": 20500001, - "end": 25500000, - "type": "gneg" - }, - { - "id": "p11.2", - "start": 9700001, - "end": 17500000, - "type": "gvar" - }, - { - "id": "q15.1", - "start": 39800001, - "end": 42500000, - "type": "gneg" - }, - { - "id": "p12", - "start": 4200001, - "end": 9700000, - "type": "stalk" - }, - { - "id": "q15.3", - "start": 43300001, - "end": 44500000, - "type": "gneg" - }, - { - "id": "q24.3", - "start": 76300001, - "end": 78000000, - "type": "gneg" - }, - { - "id": "q21.3", - "start": 52600001, - "end": 58800000, - "type": "gpos75" - }, - { - "id": "p11.1", - "start": 17500001, - "end": 19000000, - "type": "acen" - }, - { - "id": "q23", - "start": 67200001, - "end": 72400000, - "type": "gpos25" - }, - { - "id": "q25.1", - "start": 78000001, - "end": 81400000, - "type": "gpos50" - }, - { - "id": "p13", - "start": 1, - "end": 4200000, - "type": "gvar" - }, - { - "id": "q22.33", - "start": 67000001, - "end": 67200000, - "type": "gneg" - }, - { - "id": "q21.2", - "start": 49200001, - "end": 52600000, - "type": "gneg" - }, - { - "id": "q15.2", - "start": 42500001, - "end": 43300000, - "type": "gpos25" - }, - { - "id": "q26.3", - "start": 98000001, - "end": 101991189, - "type": "gneg" - }, - { - "id": "q22.32", - "start": 66900001, - "end": 67000000, - "type": "gpos25" - }, - { - "id": "q12", - "start": 25500001, - "end": 27800000, - "type": "gpos50" - }, - { - "id": "q22.2", - "start": 59000001, - "end": 63400000, - "type": "gpos25" - }, - { - "id": "q26.1", - "start": 88500001, - "end": 93800000, - "type": "gneg" - }, - { - "id": "q11.1", - "start": 19000001, - "end": 20500000, - "type": "acen" - } + "size" : 101991189, + "bands" : [ + { "id": "p11.1", "start": 17500001, "end": 19000000, "type": "acen" }, + { "id": "p11.2", "start": 9700001, "end": 17500000, "type": "gvar" }, + { "id": "p12", "start": 4200001, "end": 9700000, "type": "stalk" }, + { "id": "p13", "start": 1, "end": 4200000, "type": "gvar" }, + { "id": "q11.1", "start": 19000001, "end": 20500000, "type": "acen" }, + { "id": "q11.2", "start": 20500001, "end": 25500000, "type": "gneg" }, + { "id": "q12", "start": 25500001, "end": 27800000, "type": "gpos50" }, + { "id": "q13.1", "start": 27800001, "end": 30000000, "type": "gneg" }, + { "id": "q13.2", "start": 30000001, "end": 30900000, "type": "gpos50" }, + { "id": "q13.3", "start": 30900001, "end": 33400000, "type": "gneg" }, + { "id": "q14", "start": 33400001, "end": 39800000, "type": "gpos75" }, + { "id": "q15.1", "start": 39800001, "end": 42500000, "type": "gneg" }, + { "id": "q15.2", "start": 42500001, "end": 43300000, "type": "gpos25" }, + { "id": "q15.3", "start": 43300001, "end": 44500000, "type": "gneg" }, + { "id": "q21.1", "start": 44500001, "end": 49200000, "type": "gpos75" }, + { "id": "q21.2", "start": 49200001, "end": 52600000, "type": "gneg" }, + { "id": "q21.3", "start": 52600001, "end": 58800000, "type": "gpos75" }, + { "id": "q22.1", "start": 58800001, "end": 59000000, "type": "gneg" }, + { "id": "q22.2", "start": 59000001, "end": 63400000, "type": "gpos25" }, + { "id": "q22.31", "start": 63400001, "end": 66900000, "type": "gneg" }, + { "id": "q22.32", "start": 66900001, "end": 67000000, "type": "gpos25" }, + { "id": "q22.33", "start": 67000001, "end": 67200000, "type": "gneg" }, + { "id": "q23", "start": 67200001, "end": 72400000, "type": "gpos25" }, + { "id": "q24.1", "start": 72400001, "end": 74900000, "type": "gneg" }, + { "id": "q24.2", "start": 74900001, "end": 76300000, "type": "gpos25" }, + { "id": "q24.3", "start": 76300001, "end": 78000000, "type": "gneg" }, + { "id": "q25.1", "start": 78000001, "end": 81400000, "type": "gpos50" }, + { "id": "q25.2", "start": 81400001, "end": 84700000, "type": "gneg" }, + { "id": "q25.3", "start": 84700001, "end": 88500000, "type": "gpos50" }, + { "id": "q26.1", "start": 88500001, "end": 93800000, "type": "gneg" }, + { "id": "q26.2", "start": 93800001, "end": 98000000, "type": "gpos50" }, + { "id": "q26.3", "start": 98000001, "end": 101991189, "type": "gneg" } ] }, "16": { - "size": 90338345, - "bands": [ - { - "id": "q22.1", - "start": 66600001, - "end": 70800000, - "type": "gneg" - }, - { - "id": "q24.3", - "start": 88700001, - "end": 90338345, - "type": "gneg" - }, - { - "id": "q12.1", - "start": 47000001, - "end": 52600000, - "type": "gneg" - }, - { - "id": "p11.1", - "start": 35300001, - "end": 36800000, - "type": "acen" - }, - { - "id": "q24.1", - "start": 84100001, - "end": 87000000, - "type": "gneg" - }, - { - "id": "p12.3", - "start": 16700001, - "end": 21200000, - "type": "gpos50" - }, - { - "id": "p13.3", - "start": 1, - "end": 7800000, - "type": "gneg" - }, - { - "id": "q23.2", - "start": 79200001, - "end": 81600000, - "type": "gneg" - }, - { - "id": "q22.3", - "start": 72800001, - "end": 74100000, - "type": "gneg" - }, - { - "id": "q24.2", - "start": 87000001, - "end": 88700000, - "type": "gpos25" - }, - { - "id": "q21", - "start": 57300001, - "end": 66600000, - "type": "gpos100" - }, - { - "id": "p13.12", - "start": 12500001, - "end": 14700000, - "type": "gpos50" - }, - { - "id": "p12.1", - "start": 24200001, - "end": 28500000, - "type": "gpos50" - }, - { - "id": "q11.2", - "start": 38400001, - "end": 47000000, - "type": "gvar" - }, - { - "id": "p13.11", - "start": 14700001, - "end": 16700000, - "type": "gneg" - }, - { - "id": "p13.2", - "start": 7800001, - "end": 10400000, - "type": "gpos50" - }, - { - "id": "q12.2", - "start": 52600001, - "end": 56000000, - "type": "gpos50" - }, - { - "id": "q23.1", - "start": 74100001, - "end": 79200000, - "type": "gpos75" - }, - { - "id": "q13", - "start": 56000001, - "end": 57300000, - "type": "gneg" - }, - { - "id": "p11.2", - "start": 28500001, - "end": 35300000, - "type": "gneg" - }, - { - "id": "q22.2", - "start": 70800001, - "end": 72800000, - "type": "gpos50" - }, - { - "id": "p13.13", - "start": 10400001, - "end": 12500000, - "type": "gneg" - }, - { - "id": "q23.3", - "start": 81600001, - "end": 84100000, - "type": "gpos50" - }, - { - "id": "p12.2", - "start": 21200001, - "end": 24200000, - "type": "gneg" - }, - { - "id": "q11.1", - "start": 36800001, - "end": 38400000, - "type": "acen" - } + "size" : 90338345, + "bands" : [ + { "id": "p11.1", "start": 35300001, "end": 36800000, "type": "acen" }, + { "id": "p11.2", "start": 28500001, "end": 35300000, "type": "gneg" }, + { "id": "p12.1", "start": 24200001, "end": 28500000, "type": "gpos50" }, + { "id": "p12.2", "start": 21200001, "end": 24200000, "type": "gneg" }, + { "id": "p12.3", "start": 16700001, "end": 21200000, "type": "gpos50" }, + { "id": "p13.11", "start": 14700001, "end": 16700000, "type": "gneg" }, + { "id": "p13.12", "start": 12500001, "end": 14700000, "type": "gpos50" }, + { "id": "p13.13", "start": 10400001, "end": 12500000, "type": "gneg" }, + { "id": "p13.2", "start": 7800001, "end": 10400000, "type": "gpos50" }, + { "id": "p13.3", "start": 1, "end": 7800000, "type": "gneg" }, + { "id": "q11.1", "start": 36800001, "end": 38400000, "type": "acen" }, + { "id": "q11.2", "start": 38400001, "end": 47000000, "type": "gvar" }, + { "id": "q12.1", "start": 47000001, "end": 52600000, "type": "gneg" }, + { "id": "q12.2", "start": 52600001, "end": 56000000, "type": "gpos50" }, + { "id": "q13", "start": 56000001, "end": 57300000, "type": "gneg" }, + { "id": "q21", "start": 57300001, "end": 66600000, "type": "gpos100" }, + { "id": "q22.1", "start": 66600001, "end": 70800000, "type": "gneg" }, + { "id": "q22.2", "start": 70800001, "end": 72800000, "type": "gpos50" }, + { "id": "q22.3", "start": 72800001, "end": 74100000, "type": "gneg" }, + { "id": "q23.1", "start": 74100001, "end": 79200000, "type": "gpos75" }, + { "id": "q23.2", "start": 79200001, "end": 81600000, "type": "gneg" }, + { "id": "q23.3", "start": 81600001, "end": 84100000, "type": "gpos50" }, + { "id": "q24.1", "start": 84100001, "end": 87000000, "type": "gneg" }, + { "id": "q24.2", "start": 87000001, "end": 88700000, "type": "gpos25" }, + { "id": "q24.3", "start": 88700001, "end": 90338345, "type": "gneg" } ] }, "17": { - "size": 83257441, - "bands": [ - { - "id": "q25.2", - "start": 76800001, - "end": 77200000, - "type": "gpos25" - }, - { - "id": "q24.3", - "start": 69100001, - "end": 72900000, - "type": "gpos75" - }, - { - "id": "q21.32", - "start": 46800001, - "end": 49300000, - "type": "gpos25" - }, - { - "id": "p11.1", - "start": 22700001, - "end": 25100000, - "type": "acen" - }, - { - "id": "q24.1", - "start": 64600001, - "end": 66200000, - "type": "gpos50" - }, - { - "id": "p13.3", - "start": 1, - "end": 3400000, - "type": "gneg" - }, - { - "id": "q25.1", - "start": 72900001, - "end": 76800000, - "type": "gneg" - }, - { - "id": "q23.2", - "start": 60200001, - "end": 63100000, - "type": "gpos75" - }, - { - "id": "q21.31", - "start": 42800001, - "end": 46800000, - "type": "gneg" - }, - { - "id": "q21.1", - "start": 39800001, - "end": 40200000, - "type": "gneg" - }, - { - "id": "q24.2", - "start": 66200001, - "end": 69100000, - "type": "gneg" - }, - { - "id": "q25.3", - "start": 77200001, - "end": 83257441, - "type": "gneg" - }, - { - "id": "q21.2", - "start": 40200001, - "end": 42800000, - "type": "gpos25" - }, - { - "id": "q11.2", - "start": 27400001, - "end": 33500000, - "type": "gneg" - }, - { - "id": "p13.2", - "start": 3400001, - "end": 6500000, - "type": "gpos50" - }, - { - "id": "q21.33", - "start": 49300001, - "end": 52100000, - "type": "gneg" - }, - { - "id": "q23.1", - "start": 59500001, - "end": 60200000, - "type": "gneg" - }, - { - "id": "p11.2", - "start": 16100001, - "end": 22700000, - "type": "gneg" - }, - { - "id": "q22", - "start": 52100001, - "end": 59500000, - "type": "gpos75" - }, - { - "id": "q12", - "start": 33500001, - "end": 39800000, - "type": "gpos50" - }, - { - "id": "q23.3", - "start": 63100001, - "end": 64600000, - "type": "gneg" - }, - { - "id": "q11.1", - "start": 25100001, - "end": 27400000, - "type": "acen" - }, - { - "id": "p12", - "start": 10800001, - "end": 16100000, - "type": "gpos75" - }, - { - "id": "p13.1", - "start": 6500001, - "end": 10800000, - "type": "gneg" - } + "size" : 83257441, + "bands" : [ + { "id": "p11.1", "start": 22700001, "end": 25100000, "type": "acen" }, + { "id": "p11.2", "start": 16100001, "end": 22700000, "type": "gneg" }, + { "id": "p12", "start": 10800001, "end": 16100000, "type": "gpos75" }, + { "id": "p13.1", "start": 6500001, "end": 10800000, "type": "gneg" }, + { "id": "p13.2", "start": 3400001, "end": 6500000, "type": "gpos50" }, + { "id": "p13.3", "start": 1, "end": 3400000, "type": "gneg" }, + { "id": "q11.1", "start": 25100001, "end": 27400000, "type": "acen" }, + { "id": "q11.2", "start": 27400001, "end": 33500000, "type": "gneg" }, + { "id": "q12", "start": 33500001, "end": 39800000, "type": "gpos50" }, + { "id": "q21.1", "start": 39800001, "end": 40200000, "type": "gneg" }, + { "id": "q21.2", "start": 40200001, "end": 42800000, "type": "gpos25" }, + { "id": "q21.31", "start": 42800001, "end": 46800000, "type": "gneg" }, + { "id": "q21.32", "start": 46800001, "end": 49300000, "type": "gpos25" }, + { "id": "q21.33", "start": 49300001, "end": 52100000, "type": "gneg" }, + { "id": "q22", "start": 52100001, "end": 59500000, "type": "gpos75" }, + { "id": "q23.1", "start": 59500001, "end": 60200000, "type": "gneg" }, + { "id": "q23.2", "start": 60200001, "end": 63100000, "type": "gpos75" }, + { "id": "q23.3", "start": 63100001, "end": 64600000, "type": "gneg" }, + { "id": "q24.1", "start": 64600001, "end": 66200000, "type": "gpos50" }, + { "id": "q24.2", "start": 66200001, "end": 69100000, "type": "gneg" }, + { "id": "q24.3", "start": 69100001, "end": 72900000, "type": "gpos75" }, + { "id": "q25.1", "start": 72900001, "end": 76800000, "type": "gneg" }, + { "id": "q25.2", "start": 76800001, "end": 77200000, "type": "gpos25" }, + { "id": "q25.3", "start": 77200001, "end": 83257441, "type": "gneg" } ] }, "18": { - "size": 80373285, - "bands": [ - { - "id": "q22.1", - "start": 63900001, - "end": 69100000, - "type": "gpos100" - }, - { - "id": "q21.32", - "start": 58600001, - "end": 61300000, - "type": "gpos50" - }, - { - "id": "q12.1", - "start": 27500001, - "end": 35100000, - "type": "gpos100" - }, - { - "id": "q23", - "start": 75400001, - "end": 80373285, - "type": "gneg" - }, - { - "id": "p11.1", - "start": 15400001, - "end": 18500000, - "type": "acen" - }, - { - "id": "p11.31", - "start": 2900001, - "end": 7200000, - "type": "gpos50" - }, - { - "id": "q21.31", - "start": 56200001, - "end": 58600000, - "type": "gneg" - }, - { - "id": "q21.1", - "start": 45900001, - "end": 50700000, - "type": "gneg" - }, - { - "id": "q22.3", - "start": 71000001, - "end": 75400000, - "type": "gpos25" - }, - { - "id": "p11.22", - "start": 8500001, - "end": 10900000, - "type": "gpos25" - }, - { - "id": "q21.2", - "start": 50700001, - "end": 56200000, - "type": "gpos75" - }, - { - "id": "q11.2", - "start": 21500001, - "end": 27500000, - "type": "gneg" - }, - { - "id": "p11.23", - "start": 7200001, - "end": 8500000, - "type": "gneg" - }, - { - "id": "q12.2", - "start": 35100001, - "end": 39500000, - "type": "gneg" - }, - { - "id": "q21.33", - "start": 61300001, - "end": 63900000, - "type": "gneg" - }, - { - "id": "p11.32", - "start": 1, - "end": 2900000, - "type": "gneg" - }, - { - "id": "p11.21", - "start": 10900001, - "end": 15400000, - "type": "gneg" - }, - { - "id": "q22.2", - "start": 69100001, - "end": 71000000, - "type": "gneg" - }, - { - "id": "q12.3", - "start": 39500001, - "end": 45900000, - "type": "gpos75" - }, - { - "id": "q11.1", - "start": 18500001, - "end": 21500000, - "type": "acen" - } + "size" : 80373285, + "bands" : [ + { "id": "p11.1", "start": 15400001, "end": 18500000, "type": "acen" }, + { "id": "p11.21", "start": 10900001, "end": 15400000, "type": "gneg" }, + { "id": "p11.22", "start": 8500001, "end": 10900000, "type": "gpos25" }, + { "id": "p11.23", "start": 7200001, "end": 8500000, "type": "gneg" }, + { "id": "p11.31", "start": 2900001, "end": 7200000, "type": "gpos50" }, + { "id": "p11.32", "start": 1, "end": 2900000, "type": "gneg" }, + { "id": "q11.1", "start": 18500001, "end": 21500000, "type": "acen" }, + { "id": "q11.2", "start": 21500001, "end": 27500000, "type": "gneg" }, + { "id": "q12.1", "start": 27500001, "end": 35100000, "type": "gpos100" }, + { "id": "q12.2", "start": 35100001, "end": 39500000, "type": "gneg" }, + { "id": "q12.3", "start": 39500001, "end": 45900000, "type": "gpos75" }, + { "id": "q21.1", "start": 45900001, "end": 50700000, "type": "gneg" }, + { "id": "q21.2", "start": 50700001, "end": 56200000, "type": "gpos75" }, + { "id": "q21.31", "start": 56200001, "end": 58600000, "type": "gneg" }, + { "id": "q21.32", "start": 58600001, "end": 61300000, "type": "gpos50" }, + { "id": "q21.33", "start": 61300001, "end": 63900000, "type": "gneg" }, + { "id": "q22.1", "start": 63900001, "end": 69100000, "type": "gpos100" }, + { "id": "q22.2", "start": 69100001, "end": 71000000, "type": "gneg" }, + { "id": "q22.3", "start": 71000001, "end": 75400000, "type": "gpos25" }, + { "id": "q23", "start": 75400001, "end": 80373285, "type": "gneg" } ] }, "19": { - "size": 58617616, - "bands": [ - { - "id": "q13.13", - "start": 37800001, - "end": 38200000, - "type": "gneg" - }, - { - "id": "q13.12", - "start": 35100001, - "end": 37800000, - "type": "gpos25" - }, - { - "id": "q13.42", - "start": 53100001, - "end": 55800000, - "type": "gneg" - }, - { - "id": "p11", - "start": 24200001, - "end": 26200000, - "type": "acen" - }, - { - "id": "p13.3", - "start": 1, - "end": 6900000, - "type": "gneg" - }, - { - "id": "q13.33", - "start": 47500001, - "end": 50900000, - "type": "gneg" - }, - { - "id": "q13.2", - "start": 38200001, - "end": 42900000, - "type": "gpos25" - }, - { - "id": "q13.31", - "start": 42900001, - "end": 44700000, - "type": "gneg" - }, - { - "id": "p13.12", - "start": 13800001, - "end": 16100000, - "type": "gpos25" - }, - { - "id": "q13.41", - "start": 50900001, - "end": 53100000, - "type": "gpos25" - }, - { - "id": "q13.43", - "start": 55800001, - "end": 58617616, - "type": "gpos25" - }, - { - "id": "p13.11", - "start": 16100001, - "end": 19900000, - "type": "gneg" - }, - { - "id": "p13.2", - "start": 6900001, - "end": 12600000, - "type": "gpos25" - }, - { - "id": "q13.11", - "start": 31900001, - "end": 35100000, - "type": "gneg" - }, - { - "id": "q13.32", - "start": 44700001, - "end": 47500000, - "type": "gpos25" - }, - { - "id": "p13.13", - "start": 12600001, - "end": 13800000, - "type": "gneg" - }, - { - "id": "q12", - "start": 28100001, - "end": 31900000, - "type": "gvar" - }, - { - "id": "p12", - "start": 19900001, - "end": 24200000, - "type": "gvar" - }, - { - "id": "q11", - "start": 26200001, - "end": 28100000, - "type": "acen" - } + "size" : 58617616, + "bands" : [ + { "id": "p11", "start": 24200001, "end": 26200000, "type": "acen" }, + { "id": "p12", "start": 19900001, "end": 24200000, "type": "gvar" }, + { "id": "p13.11", "start": 16100001, "end": 19900000, "type": "gneg" }, + { "id": "p13.12", "start": 13800001, "end": 16100000, "type": "gpos25" }, + { "id": "p13.13", "start": 12600001, "end": 13800000, "type": "gneg" }, + { "id": "p13.2", "start": 6900001, "end": 12600000, "type": "gpos25" }, + { "id": "p13.3", "start": 1, "end": 6900000, "type": "gneg" }, + { "id": "q11", "start": 26200001, "end": 28100000, "type": "acen" }, + { "id": "q12", "start": 28100001, "end": 31900000, "type": "gvar" }, + { "id": "q13.11", "start": 31900001, "end": 35100000, "type": "gneg" }, + { "id": "q13.12", "start": 35100001, "end": 37800000, "type": "gpos25" }, + { "id": "q13.13", "start": 37800001, "end": 38200000, "type": "gneg" }, + { "id": "q13.2", "start": 38200001, "end": 42900000, "type": "gpos25" }, + { "id": "q13.31", "start": 42900001, "end": 44700000, "type": "gneg" }, + { "id": "q13.32", "start": 44700001, "end": 47500000, "type": "gpos25" }, + { "id": "q13.33", "start": 47500001, "end": 50900000, "type": "gneg" }, + { "id": "q13.41", "start": 50900001, "end": 53100000, "type": "gpos25" }, + { "id": "q13.42", "start": 53100001, "end": 55800000, "type": "gneg" }, + { "id": "q13.43", "start": 55800001, "end": 58617616, "type": "gpos25" } ] }, "20": { - "size": 64444167, - "bands": [ - { - "id": "q13.13", - "start": 47800001, - "end": 51200000, - "type": "gneg" - }, - { - "id": "q13.12", - "start": 43500001, - "end": 47800000, - "type": "gpos25" - }, - { - "id": "q11.21", - "start": 30400001, - "end": 33500000, - "type": "gneg" - }, - { - "id": "p11.1", - "start": 25700001, - "end": 28100000, - "type": "acen" - }, - { - "id": "p12.3", - "start": 5100001, - "end": 9200000, - "type": "gpos75" - }, - { - "id": "q13.33", - "start": 59700001, - "end": 64444167, - "type": "gneg" - }, - { - "id": "q11.22", - "start": 33500001, - "end": 35800000, - "type": "gpos25" - }, - { - "id": "p13", - "start": 1, - "end": 5100000, - "type": "gneg" - }, - { - "id": "q13.2", - "start": 51200001, - "end": 56400000, - "type": "gpos75" - }, - { - "id": "q11.23", - "start": 35800001, - "end": 39000000, - "type": "gneg" - }, - { - "id": "p11.22", - "start": 21300001, - "end": 22300000, - "type": "gpos25" - }, - { - "id": "q13.31", - "start": 56400001, - "end": 57800000, - "type": "gneg" - }, - { - "id": "p12.1", - "start": 12000001, - "end": 17900000, - "type": "gpos75" - }, - { - "id": "p11.23", - "start": 17900001, - "end": 21300000, - "type": "gneg" - }, - { - "id": "q13.32", - "start": 57800001, - "end": 59700000, - "type": "gpos50" - }, - { - "id": "q13.11", - "start": 43100001, - "end": 43500000, - "type": "gneg" - }, - { - "id": "p11.21", - "start": 22300001, - "end": 25700000, - "type": "gneg" - }, - { - "id": "q12", - "start": 39000001, - "end": 43100000, - "type": "gpos75" - }, - { - "id": "p12.2", - "start": 9200001, - "end": 12000000, - "type": "gneg" - }, - { - "id": "q11.1", - "start": 28100001, - "end": 30400000, - "type": "acen" - } + "size" : 64444167, + "bands" : [ + { "id": "p11.1", "start": 25700001, "end": 28100000, "type": "acen" }, + { "id": "p11.21", "start": 22300001, "end": 25700000, "type": "gneg" }, + { "id": "p11.22", "start": 21300001, "end": 22300000, "type": "gpos25" }, + { "id": "p11.23", "start": 17900001, "end": 21300000, "type": "gneg" }, + { "id": "p12.1", "start": 12000001, "end": 17900000, "type": "gpos75" }, + { "id": "p12.2", "start": 9200001, "end": 12000000, "type": "gneg" }, + { "id": "p12.3", "start": 5100001, "end": 9200000, "type": "gpos75" }, + { "id": "p13", "start": 1, "end": 5100000, "type": "gneg" }, + { "id": "q11.1", "start": 28100001, "end": 30400000, "type": "acen" }, + { "id": "q11.21", "start": 30400001, "end": 33500000, "type": "gneg" }, + { "id": "q11.22", "start": 33500001, "end": 35800000, "type": "gpos25" }, + { "id": "q11.23", "start": 35800001, "end": 39000000, "type": "gneg" }, + { "id": "q12", "start": 39000001, "end": 43100000, "type": "gpos75" }, + { "id": "q13.11", "start": 43100001, "end": 43500000, "type": "gneg" }, + { "id": "q13.12", "start": 43500001, "end": 47800000, "type": "gpos25" }, + { "id": "q13.13", "start": 47800001, "end": 51200000, "type": "gneg" }, + { "id": "q13.2", "start": 51200001, "end": 56400000, "type": "gpos75" }, + { "id": "q13.31", "start": 56400001, "end": 57800000, "type": "gneg" }, + { "id": "q13.32", "start": 57800001, "end": 59700000, "type": "gpos50" }, + { "id": "q13.33", "start": 59700001, "end": 64444167, "type": "gneg" } ] }, "21": { - "size": 46709983, - "bands": [ - { - "id": "q22.13", - "start": 36400001, - "end": 38300000, - "type": "gneg" - }, - { - "id": "q21.2", - "start": 22600001, - "end": 25500000, - "type": "gneg" - }, - { - "id": "q21.3", - "start": 25500001, - "end": 30200000, - "type": "gpos75" - }, - { - "id": "q11.2", - "start": 13000001, - "end": 15000000, - "type": "gneg" - }, - { - "id": "q22.12", - "start": 34400001, - "end": 36400000, - "type": "gpos50" - }, - { - "id": "p11.1", - "start": 10900001, - "end": 12000000, - "type": "acen" - }, - { - "id": "q22.11", - "start": 30200001, - "end": 34400000, - "type": "gneg" - }, - { - "id": "p11.2", - "start": 7000001, - "end": 10900000, - "type": "gvar" - }, - { - "id": "p13", - "start": 1, - "end": 3100000, - "type": "gvar" - }, - { - "id": "q21.1", - "start": 15000001, - "end": 22600000, - "type": "gpos100" - }, - { - "id": "q22.3", - "start": 41200001, - "end": 46709983, - "type": "gneg" - }, - { - "id": "q22.2", - "start": 38300001, - "end": 41200000, - "type": "gpos50" - }, - { - "id": "p12", - "start": 3100001, - "end": 7000000, - "type": "stalk" - }, - { - "id": "q11.1", - "start": 12000001, - "end": 13000000, - "type": "acen" - } + "size" : 46709983, + "bands" : [ + { "id": "p11.1", "start": 10900001, "end": 12000000, "type": "acen" }, + { "id": "p11.2", "start": 7000001, "end": 10900000, "type": "gvar" }, + { "id": "p12", "start": 3100001, "end": 7000000, "type": "stalk" }, + { "id": "p13", "start": 1, "end": 3100000, "type": "gvar" }, + { "id": "q11.1", "start": 12000001, "end": 13000000, "type": "acen" }, + { "id": "q11.2", "start": 13000001, "end": 15000000, "type": "gneg" }, + { "id": "q21.1", "start": 15000001, "end": 22600000, "type": "gpos100" }, + { "id": "q21.2", "start": 22600001, "end": 25500000, "type": "gneg" }, + { "id": "q21.3", "start": 25500001, "end": 30200000, "type": "gpos75" }, + { "id": "q22.11", "start": 30200001, "end": 34400000, "type": "gneg" }, + { "id": "q22.12", "start": 34400001, "end": 36400000, "type": "gpos50" }, + { "id": "q22.13", "start": 36400001, "end": 38300000, "type": "gneg" }, + { "id": "q22.2", "start": 38300001, "end": 41200000, "type": "gpos50" }, + { "id": "q22.3", "start": 41200001, "end": 46709983, "type": "gneg" } ] }, "22": { - "size": 50818468, - "bands": [ - { - "id": "q11.21", - "start": 17400001, - "end": 21700000, - "type": "gneg" - }, - { - "id": "q13.1", - "start": 37200001, - "end": 40600000, - "type": "gneg" - }, - { - "id": "q12.1", - "start": 25500001, - "end": 29200000, - "type": "gpos50" - }, - { - "id": "p11.1", - "start": 13700001, - "end": 15000000, - "type": "acen" - }, - { - "id": "q13.33", - "start": 49100001, - "end": 50818468, - "type": "gneg" - }, - { - "id": "p13", - "start": 1, - "end": 4300000, - "type": "gvar" - }, - { - "id": "q11.22", - "start": 21700001, - "end": 23100000, - "type": "gpos25" - }, - { - "id": "q13.2", - "start": 40600001, - "end": 43800000, - "type": "gpos50" - }, - { - "id": "q11.23", - "start": 23100001, - "end": 25500000, - "type": "gneg" - }, - { - "id": "q13.31", - "start": 43800001, - "end": 48100000, - "type": "gneg" - }, - { - "id": "q12.2", - "start": 29200001, - "end": 31800000, - "type": "gneg" - }, - { - "id": "q13.32", - "start": 48100001, - "end": 49100000, - "type": "gpos50" - }, - { - "id": "p11.2", - "start": 9400001, - "end": 13700000, - "type": "gvar" - }, - { - "id": "q12.3", - "start": 31800001, - "end": 37200000, - "type": "gpos50" - }, - { - "id": "q11.1", - "start": 15000001, - "end": 17400000, - "type": "acen" - }, - { - "id": "p12", - "start": 4300001, - "end": 9400000, - "type": "stalk" - } + "size" : 50818468, + "bands" : [ + { "id": "p11.1", "start": 13700001, "end": 15000000, "type": "acen" }, + { "id": "p11.2", "start": 9400001, "end": 13700000, "type": "gvar" }, + { "id": "p12", "start": 4300001, "end": 9400000, "type": "stalk" }, + { "id": "p13", "start": 1, "end": 4300000, "type": "gvar" }, + { "id": "q11.1", "start": 15000001, "end": 17400000, "type": "acen" }, + { "id": "q11.21", "start": 17400001, "end": 21700000, "type": "gneg" }, + { "id": "q11.22", "start": 21700001, "end": 23100000, "type": "gpos25" }, + { "id": "q11.23", "start": 23100001, "end": 25500000, "type": "gneg" }, + { "id": "q12.1", "start": 25500001, "end": 29200000, "type": "gpos50" }, + { "id": "q12.2", "start": 29200001, "end": 31800000, "type": "gneg" }, + { "id": "q12.3", "start": 31800001, "end": 37200000, "type": "gpos50" }, + { "id": "q13.1", "start": 37200001, "end": 40600000, "type": "gneg" }, + { "id": "q13.2", "start": 40600001, "end": 43800000, "type": "gpos50" }, + { "id": "q13.31", "start": 43800001, "end": 48100000, "type": "gneg" }, + { "id": "q13.32", "start": 48100001, "end": 49100000, "type": "gpos50" }, + { "id": "q13.33", "start": 49100001, "end": 50818468, "type": "gneg" } ] }, "X": { - "size": 156040895, - "bands": [ - { - "id": "q22.1", - "start": 99100001, - "end": 103300000, - "type": "gneg" - }, - { - "id": "q13.1", - "start": 68500001, - "end": 73000000, - "type": "gneg" - }, - { - "id": "q21.32", - "start": 92700001, - "end": 94300000, - "type": "gneg" - }, - { - "id": "p21.3", - "start": 24900001, - "end": 29300000, - "type": "gpos100" - }, - { - "id": "q13.3", - "start": 74700001, - "end": 76800000, - "type": "gneg" - }, - { - "id": "q27.2", - "start": 141200001, - "end": 143000000, - "type": "gneg" - }, - { - "id": "q24", - "start": 117400001, - "end": 121800000, - "type": "gneg" - }, - { - "id": "q21.1", - "start": 76800001, - "end": 85400000, - "type": "gpos100" - }, - { - "id": "q26.2", - "start": 131300001, - "end": 134500000, - "type": "gpos25" - }, - { - "id": "q22.3", - "start": 104500001, - "end": 109400000, - "type": "gneg" - }, - { - "id": "p22.2", - "start": 9600001, - "end": 17400000, - "type": "gpos50" - }, - { - "id": "q13.2", - "start": 73000001, - "end": 74700000, - "type": "gpos50" - }, - { - "id": "p11.22", - "start": 50100001, - "end": 54800000, - "type": "gpos25" - }, - { - "id": "q11.2", - "start": 63800001, - "end": 65400000, - "type": "gneg" - }, - { - "id": "p11.23", - "start": 47600001, - "end": 50100000, - "type": "gneg" - }, - { - "id": "q21.33", - "start": 94300001, - "end": 99100000, - "type": "gpos75" - }, - { - "id": "p22.12", - "start": 19200001, - "end": 21900000, - "type": "gpos50" - }, - { - "id": "q27.3", - "start": 143000001, - "end": 148000000, - "type": "gpos100" - }, - { - "id": "p22.31", - "start": 6100001, - "end": 9600000, - "type": "gneg" - }, - { - "id": "p11.3", - "start": 42500001, - "end": 47600000, - "type": "gpos75" - }, - { - "id": "q25", - "start": 121800001, - "end": 129500000, - "type": "gpos100" - }, - { - "id": "p22.32", - "start": 4400001, - "end": 6100000, - "type": "gpos50" - }, - { - "id": "p22.33", - "start": 1, - "end": 4400000, - "type": "gneg" - }, - { - "id": "p11.1", - "start": 58100001, - "end": 61000000, - "type": "acen" - }, - { - "id": "q23", - "start": 109400001, - "end": 117400000, - "type": "gpos75" - }, - { - "id": "p11.4", - "start": 37800001, - "end": 42500000, - "type": "gneg" - }, - { - "id": "p21.1", - "start": 31500001, - "end": 37800000, - "type": "gpos100" - }, - { - "id": "p22.13", - "start": 17400001, - "end": 19200000, - "type": "gneg" - }, - { - "id": "q21.31", - "start": 87000001, - "end": 92700000, - "type": "gpos100" - }, - { - "id": "p22.11", - "start": 21900001, - "end": 24900000, - "type": "gneg" - }, - { - "id": "q21.2", - "start": 85400001, - "end": 87000000, - "type": "gneg" - }, - { - "id": "p21.2", - "start": 29300001, - "end": 31500000, - "type": "gneg" - }, - { - "id": "q26.3", - "start": 134500001, - "end": 138900000, - "type": "gneg" - }, - { - "id": "p11.21", - "start": 54800001, - "end": 58100000, - "type": "gneg" - }, - { - "id": "q28", - "start": 148000001, - "end": 156040895, - "type": "gneg" - }, - { - "id": "q27.1", - "start": 138900001, - "end": 141200000, - "type": "gpos75" - }, - { - "id": "q26.1", - "start": 129500001, - "end": 131300000, - "type": "gneg" - }, - { - "id": "q12", - "start": 65400001, - "end": 68500000, - "type": "gpos50" - }, - { - "id": "q22.2", - "start": 103300001, - "end": 104500000, - "type": "gpos50" - }, - { - "id": "q11.1", - "start": 61000001, - "end": 63800000, - "type": "acen" - } + "size" : 156040895, + "bands" : [ + { "id": "p11.1", "start": 58100001, "end": 61000000, "type": "acen" }, + { "id": "p11.21", "start": 54800001, "end": 58100000, "type": "gneg" }, + { "id": "p11.22", "start": 50100001, "end": 54800000, "type": "gpos25" }, + { "id": "p11.23", "start": 47600001, "end": 50100000, "type": "gneg" }, + { "id": "p11.3", "start": 42500001, "end": 47600000, "type": "gpos75" }, + { "id": "p11.4", "start": 37800001, "end": 42500000, "type": "gneg" }, + { "id": "p21.1", "start": 31500001, "end": 37800000, "type": "gpos100" }, + { "id": "p21.2", "start": 29300001, "end": 31500000, "type": "gneg" }, + { "id": "p21.3", "start": 24900001, "end": 29300000, "type": "gpos100" }, + { "id": "p22.11", "start": 21900001, "end": 24900000, "type": "gneg" }, + { "id": "p22.12", "start": 19200001, "end": 21900000, "type": "gpos50" }, + { "id": "p22.13", "start": 17400001, "end": 19200000, "type": "gneg" }, + { "id": "p22.2", "start": 9600001, "end": 17400000, "type": "gpos50" }, + { "id": "p22.31", "start": 6100001, "end": 9600000, "type": "gneg" }, + { "id": "p22.32", "start": 4400001, "end": 6100000, "type": "gpos50" }, + { "id": "p22.33", "start": 1, "end": 4400000, "type": "gneg" }, + { "id": "q11.1", "start": 61000001, "end": 63800000, "type": "acen" }, + { "id": "q11.2", "start": 63800001, "end": 65400000, "type": "gneg" }, + { "id": "q12", "start": 65400001, "end": 68500000, "type": "gpos50" }, + { "id": "q13.1", "start": 68500001, "end": 73000000, "type": "gneg" }, + { "id": "q13.2", "start": 73000001, "end": 74700000, "type": "gpos50" }, + { "id": "q13.3", "start": 74700001, "end": 76800000, "type": "gneg" }, + { "id": "q21.1", "start": 76800001, "end": 85400000, "type": "gpos100" }, + { "id": "q21.2", "start": 85400001, "end": 87000000, "type": "gneg" }, + { "id": "q21.31", "start": 87000001, "end": 92700000, "type": "gpos100" }, + { "id": "q21.32", "start": 92700001, "end": 94300000, "type": "gneg" }, + { "id": "q21.33", "start": 94300001, "end": 99100000, "type": "gpos75" }, + { "id": "q22.1", "start": 99100001, "end": 103300000, "type": "gneg" }, + { "id": "q22.2", "start": 103300001, "end": 104500000, "type": "gpos50" }, + { "id": "q22.3", "start": 104500001, "end": 109400000, "type": "gneg" }, + { "id": "q23", "start": 109400001, "end": 117400000, "type": "gpos75" }, + { "id": "q24", "start": 117400001, "end": 121800000, "type": "gneg" }, + { "id": "q25", "start": 121800001, "end": 129500000, "type": "gpos100" }, + { "id": "q26.1", "start": 129500001, "end": 131300000, "type": "gneg" }, + { "id": "q26.2", "start": 131300001, "end": 134500000, "type": "gpos25" }, + { "id": "q26.3", "start": 134500001, "end": 138900000, "type": "gneg" }, + { "id": "q27.1", "start": 138900001, "end": 141200000, "type": "gpos75" }, + { "id": "q27.2", "start": 141200001, "end": 143000000, "type": "gneg" }, + { "id": "q27.3", "start": 143000001, "end": 148000000, "type": "gpos100" }, + { "id": "q28", "start": 148000001, "end": 156040895, "type": "gneg" } ] }, "Y": { - "size": 57227415, - "bands": [ - { - "id": "q11.21", - "start": 10600001, - "end": 12400000, - "type": "gneg" - }, - { - "id": "p11.1", - "start": 10300001, - "end": 10400000, - "type": "acen" - }, - { - "id": "q11.221", - "start": 12400001, - "end": 17100000, - "type": "gpos50" - }, - { - "id": "q11.223", - "start": 19600001, - "end": 23800000, - "type": "gpos50" - }, - { - "id": "p11.32", - "start": 1, - "end": 300000, - "type": "gneg" - }, - { - "id": "p11.31", - "start": 300001, - "end": 600000, - "type": "gpos50" - }, - { - "id": "p11.2", - "start": 600001, - "end": 10300000, - "type": "gneg" - }, - { - "id": "q11.222", - "start": 17100001, - "end": 19600000, - "type": "gneg" - }, - { - "id": "q12", - "start": 26600001, - "end": 57227415, - "type": "gvar" - }, - { - "id": "q11.1", - "start": 10400001, - "end": 10600000, - "type": "acen" - }, - { - "id": "q11.23", - "start": 23800001, - "end": 26600000, - "type": "gneg" - } + "size" : 57227415, + "bands" : [ + { "id": "p11.1", "start": 10300001, "end": 10400000, "type": "acen" }, + { "id": "p11.2", "start": 600001, "end": 10300000, "type": "gneg" }, + { "id": "p11.31", "start": 300001, "end": 600000, "type": "gpos50" }, + { "id": "p11.32", "start": 1, "end": 300000, "type": "gneg" }, + { "id": "q11.1", "start": 10400001, "end": 10600000, "type": "acen" }, + { "id": "q11.21", "start": 10600001, "end": 12400000, "type": "gneg" }, + { "id": "q11.221", "start": 12400001, "end": 17100000, "type": "gpos50" }, + { "id": "q11.222", "start": 17100001, "end": 19600000, "type": "gneg" }, + { "id": "q11.223", "start": 19600001, "end": 23800000, "type": "gpos50" }, + { "id": "q11.23", "start": 23800001, "end": 26600000, "type": "gneg" }, + { "id": "q12", "start": 26600001, "end": 57227415, "type": "gvar" } ] }, "MT": { - "size": 16569, - "bands": [ - { - "start": 1, - "end": 16569 - } + "size" : 16569, + "bands" : [ + { "start": 1, "end": 16569 } ] } }; \ No newline at end of file diff --git a/js/genomes/node.js b/js/genomes/node.js index f915963d..75cdd668 100644 --- a/js/genomes/node.js +++ b/js/genomes/node.js @@ -52,7 +52,7 @@ for (var i=0; i Date: Mon, 30 Nov 2015 16:45:56 +0000 Subject: [PATCH 03/59] Removed duplicate parameters --- js/plugins/karyotype.js | 3 --- 1 file changed, 3 deletions(-) diff --git a/js/plugins/karyotype.js b/js/plugins/karyotype.js index 1916d8ca..983fe555 100644 --- a/js/plugins/karyotype.js +++ b/js/plugins/karyotype.js @@ -17,11 +17,8 @@ Genoverse.Plugins.karyotype = function () { name : 'Chr ' + this.chr, height : 20, featureHeight : 20, - featureMargin : { top: 0, right: 0, bottom: 0, left: 0 }, border : false, legend : false, - url : false, - allData : true, unsortable : true, click: function (e) { From 7c26b88df0b4da85563950ff66242b2fcf2cc12a Mon Sep 17 00:00:00 2001 From: Simon Brent Date: Mon, 30 Nov 2015 16:46:11 +0000 Subject: [PATCH 04/59] Fixed track ordering in control panel --- js/plugins/controlPanel.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/plugins/controlPanel.js b/js/plugins/controlPanel.js index 8186f5a5..d4b60c40 100644 --- a/js/plugins/controlPanel.js +++ b/js/plugins/controlPanel.js @@ -256,7 +256,7 @@ Genoverse.Plugins.controlPanel = function () { currentTracks.data('listTracks')(); if (browser.tracksLibrary && browser.tracksLibrary.length) { - var tracksLibrary = $.map(browser.tracksLibrary, function (track) { return track.prototype.name ? [[ track.prototype.name.toLowerCase(), track ]] : undefined }).sort(function (a, b) { return b < a }); + var tracksLibrary = $.map(browser.tracksLibrary, function (track) { return track.prototype.name ? [[ track.prototype.name.toLowerCase(), track ]] : undefined }).sort(function (a, b) { return a[0] > b[0] ? 1 : -1 }); for (var i = 0; i < tracksLibrary.length; i++) { (function (track) { From 87cb2aceef3697b35288f3b19c3f43ab520ac48c Mon Sep 17 00:00:00 2001 From: Simon Brent Date: Mon, 30 Nov 2015 16:48:30 +0000 Subject: [PATCH 05/59] Fixed featureFilters on tracks with length settings --- js/Track.js | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/js/Track.js b/js/Track.js index 581f5dcd..d0fbeebe 100644 --- a/js/Track.js +++ b/js/Track.js @@ -177,9 +177,9 @@ Genoverse.Track = Base.extend({ }, setLengthMap: function () { - var extendArgs = [ true, {} ]; var featureFilters = []; - var settings, baseSetting, value, j, deepCopy; + var configSettings = []; + var settings, value, j, deepCopy; this.lengthMap = []; this.models = {}; @@ -190,7 +190,7 @@ Genoverse.Track = Base.extend({ settings = this.getConfig(i); if (settings) { - extendArgs.push(settings); + configSettings.push(settings); if (settings.featureFilter) { featureFilters.push(settings.featureFilter); @@ -198,14 +198,11 @@ Genoverse.Track = Base.extend({ } } - if (extendArgs.length > 2) { - baseSetting = $.extend.apply($, extendArgs.concat({ featureFilters: featureFilters })); + if (configSettings.length) { + configSettings = $.extend.apply($, [ true, {} ].concat(configSettings, { featureFilters: featureFilters })); - if (this[1]) { - $.extend(this[1], baseSetting); - } else { - this[1] = baseSetting; - } + // Force a lengthMap to exist. All entries in lengthMap get configSettings applied to them below + this[1] = this[1] || {}; } // Find all scale-map like keys @@ -224,6 +221,8 @@ Genoverse.Track = Base.extend({ } for (var i = 0; i < this.lengthMap.length; i++) { + $.extend(this.lengthMap[i][1], configSettings); + if (this.lengthMap[i][1].model && this.lengthMap[i][1].view) { continue; } From 715d0dbf6631ad17504e4801c24d4f479fb695cd Mon Sep 17 00:00:00 2001 From: Simon Brent Date: Mon, 30 Nov 2015 16:49:48 +0000 Subject: [PATCH 06/59] Improve sortable legend initial track positioning --- js/Track/library/Legend.js | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/js/Track/library/Legend.js b/js/Track/library/Legend.js index 5410e52f..daaf66b7 100644 --- a/js/Track/library/Legend.js +++ b/js/Track/library/Legend.js @@ -123,7 +123,16 @@ Genoverse.Track.Legend = Genoverse.Track.Static.extend({ this.legends[i].controller.makeImage({}); } }, - afterUpdateTrackOrder: function () { + afterUpdateTrackOrder: function (e, ui) { + var track = ui.item.data('track'); + var legendTrack = this.legends[track.id] || track.legendTrack; + + // If a legend track, or a track with a sortable legend has been reordered, set a fixedOrder property to ensure that its lockToTrack status is ignored from now on. + // This allows a legend to initially be locked to a track, but then to be reordered once the browser has been initialized + if (legendTrack && legendTrack.lockToTrack && legendTrack.unsortable === false) { + legendTrack.fixedOrder = true; + } + for (var i in this.legends) { this.legends[i].updateOrder(); } @@ -173,7 +182,7 @@ Genoverse.Track.Legend = Genoverse.Track.Static.extend({ }, updateOrder: function () { - if (!this.tracks.length) { + if (!this.tracks.length || this.fixedOrder) { return; } From e9e10f534e7f03c2777d3e3949da53c6999653e5 Mon Sep 17 00:00:00 2001 From: Simon Brent Date: Mon, 30 Nov 2015 16:50:27 +0000 Subject: [PATCH 07/59] Stop requesting too much data, due to modifications to dataBuffer.start --- js/Track/Model.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/js/Track/Model.js b/js/Track/Model.js index 805102fd..a578e56b 100644 --- a/js/Track/Model.js +++ b/js/Track/Model.js @@ -33,6 +33,8 @@ Genoverse.Track.Model = Base.extend({ this.urlParams = this.urlParams || {}; // hash of URL params this.xhrFields = this.xhrFields || {}; + this.dataBufferStart = this.dataBuffer.start; // Remember original dataBuffer.start, since dataBuffer.start is updated based on browser scale, in setLabelBuffer + if (!this._url) { this._url = this.url; // Remember original url } @@ -65,7 +67,7 @@ Genoverse.Track.Model = Base.extend({ }, setLabelBuffer: function (buffer) { - this.dataBuffer.start = Math.max(this.dataBuffer.start, buffer); + this.dataBuffer.start = Math.max(this.dataBufferStart, buffer); }, getData: function (start, end, done) { From c37f2f7a14945096455f4b53e6331efbdaa7dc21 Mon Sep 17 00:00:00 2001 From: Simon Brent Date: Mon, 30 Nov 2015 16:52:13 +0000 Subject: [PATCH 08/59] Improvements to saving track config Save autoHeight, height, and config properties always - this stop bugs when a track definition is extended on creation so that defaults aren't what they were expected to be. Only save height change on user action. --- js/Genoverse.js | 30 +++++++++--------------------- js/Track/Controller.js | 8 ++++---- 2 files changed, 13 insertions(+), 25 deletions(-) diff --git a/js/Genoverse.js b/js/Genoverse.js index 9188f367..0ca7220b 100644 --- a/js/Genoverse.js +++ b/js/Genoverse.js @@ -287,32 +287,20 @@ var Genoverse = Base.extend({ for (var i = 0; i < this.tracks.length; i++) { if (this.tracks[i].id && !(this.tracks[i] instanceof Genoverse.Track.Legend) && !(this.tracks[i] instanceof Genoverse.Track.HighlightRegion)) { + // when saving height, initialHeight is the height of the track once margins have been added, while defaultHeight is the DEFINED height of the track. + // Subtracting the difference between them gives you back the correct height to input back into the track when loading configuration conf = { - id : this.tracks[i].id, - namespace : this.tracks[i].namespace, - order : this.tracks[i].order + id : this.tracks[i].id, + namespace : this.tracks[i].namespace, + order : this.tracks[i].order, + autoHeight : this.tracks[i].autoHeight, + height : this.tracks[i].height - (this.tracks[i].initialHeight - this.tracks[i].defaultHeight) }; - // defaultAutoHeight is likely to be undefined, while autoHeight will be true or false - if (this.tracks[i].autoHeight !== !!this.tracks[i].defaultAutoHeight) { - conf.autoHeight = this.tracks[i].autoHeight; - } - - if (!this.tracks[i].autoHeight && ( - ( this.tracks[i].defaultAutoHeight && this.tracks[i].height !== this.tracks[i].prop('fullVisibleHeight')) || - (!this.tracks[i].defaultAutoHeight && this.tracks[i].height !== this.tracks[i].initialHeight) - )) { - // initialHeight is the height of the track once margins have been added, while defaultHeight is the DEFINED height of the track - // Subtracting the difference between them gives you back the correct height to input back into the track when loading configuration - conf.height = this.tracks[i].height - (this.tracks[i].initialHeight - this.tracks[i].defaultHeight); - } - if (this.tracks[i].config) { for (j in this.tracks[i].config) { - if (this.tracks[i].config[j] !== this.tracks[i].defaultConfig[j]) { - conf.config = conf.config || {}; - conf.config[j] = this.tracks[i].config[j]; - } + conf.config = conf.config || {}; + conf.config[j] = this.tracks[i].config[j]; } } diff --git a/js/Track/Controller.js b/js/Track/Controller.js index cf77028d..5d56f1ae 100644 --- a/js/Track/Controller.js +++ b/js/Track/Controller.js @@ -148,7 +148,7 @@ Genoverse.Track.Controller = Base.extend({ var height = this.messageContainer.show().outerHeight(true); if (height > this.prop('height')) { - this.resize(height); + this.resize(height, undefined, false); } messages = null; @@ -224,7 +224,7 @@ Genoverse.Track.Controller = Base.extend({ if (autoHeight || this.prop('labels') === 'separate') { this.resize(autoHeight ? this.fullVisibleHeight : this.prop('height'), this.labelTop, false); } else { - this.toggleExpander(); + this.toggleExpander(false); } }, @@ -243,7 +243,7 @@ Genoverse.Track.Controller = Base.extend({ } }, - toggleExpander: function () { + toggleExpander: function (saveConfig) { if (this.prop('resizable') !== true) { return; } @@ -263,7 +263,7 @@ Genoverse.Track.Controller = Base.extend({ var h = this.messageContainer.outerHeight(true); if (h > height) { - this.resize(h); + this.resize(h, undefined, saveConfig); } this.expander = (this.expander || $('
').width(this.width).appendTo(this.container).on('click', function () { From e53ab40930a2bbc7d5bcb479f7a33c60b5ded6bc Mon Sep 17 00:00:00 2001 From: Simon Brent Date: Mon, 30 Nov 2015 16:54:04 +0000 Subject: [PATCH 09/59] Force newest popup menu above all others --- js/Genoverse.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/js/Genoverse.js b/js/Genoverse.js index 0ca7220b..075b3248 100644 --- a/js/Genoverse.js +++ b/js/Genoverse.js @@ -1217,6 +1217,8 @@ var Genoverse = Base.extend({ } feature.menuEl = menu.appendTo(this.superContainer || this.container); + } else { + feature.menuEl.appendTo(this.superContainer || this.container); // Move the menu to the end of the container again, so that it will always be on top of other menus } this.menus = this.menus.add(feature.menuEl); From c2333853e3eba66eff717ba9a639355611f09e87 Mon Sep 17 00:00:00 2001 From: Simon Brent Date: Mon, 25 Jan 2016 11:38:11 +0000 Subject: [PATCH 10/59] Added BAM file display, + library cleanup --- css/genoverse.css | 4 + expanded.html | 7 +- js/Track/Model/File.js | 37 +- js/Track/Model/File/BAM.js | 42 + js/Track/Model/File/GFF.js | 6 +- js/Track/library/File.js | 6 +- js/Track/library/File/BAM.js | 30 + js/genoverse.combined.js | 267 +- js/genoverse.combined.nojquery.js | 267 +- js/lib/FRegion.js | 119 - js/lib/dalliance-lib.js | 3955 +++++++++++++++++++++++++++++ js/lib/dalliance-lib.min.js | 71 + js/lib/jszlib/LICENSE.txt | 29 - js/lib/jszlib/README.md | 22 - js/lib/jszlib/demo/gzip-test.html | 10 - js/lib/jszlib/demo/gzip-test.js | 73 - js/lib/jszlib/js/inflate.js | 2153 ---------------- js/lib/url.js | 12 - js/plugins/fileDrop.js | 52 +- 19 files changed, 4634 insertions(+), 2528 deletions(-) create mode 100644 js/Track/Model/File/BAM.js create mode 100644 js/Track/library/File/BAM.js delete mode 100644 js/lib/FRegion.js create mode 100644 js/lib/dalliance-lib.js create mode 100644 js/lib/dalliance-lib.min.js delete mode 100644 js/lib/jszlib/LICENSE.txt delete mode 100644 js/lib/jszlib/README.md delete mode 100644 js/lib/jszlib/demo/gzip-test.html delete mode 100644 js/lib/jszlib/demo/gzip-test.js delete mode 100644 js/lib/jszlib/js/inflate.js delete mode 100644 js/lib/url.js diff --git a/css/genoverse.css b/css/genoverse.css index 978d1007..3f60ac2a 100644 --- a/css/genoverse.css +++ b/css/genoverse.css @@ -339,6 +339,10 @@ white-space: nowrap; } +.gv-menu.gv-wrap-values .gv-menu-content table td:last-child { + word-break: break-word; +} + .gv-menu .gv-menu-button { color: #FFF; cursor: pointer; diff --git a/expanded.html b/expanded.html index a6af81a6..7cd0a8bf 100644 --- a/expanded.html +++ b/expanded.html @@ -22,6 +22,7 @@ + @@ -57,15 +58,17 @@ - + + + + - diff --git a/js/Track/Model/File.js b/js/Track/Model/File.js index ea3c1a4b..3bed4610 100644 --- a/js/Track/Model/File.js +++ b/js/Track/Model/File.js @@ -1,3 +1,36 @@ Genoverse.Track.Model.File = Genoverse.Track.Model.extend({ - dataType : 'text' -}); \ No newline at end of file + dataType: 'text', + + init: function () { + if (this.isLocal) { + this.url = false; + } + + if (!this.largeFile) { + this.allData = true; + } + + this.base.apply(this, arguments); + }, + + getData: function () { + var model = this; + + if (this.isLocal && this.dataFile) { + var reader = new FileReader(); + var deferred = $.Deferred(); + + reader.onload = function (e) { + deferred.done(function () { + this.receiveData(e.target.result, 1, this.browser.chromosomeSize); + }).resolveWith(model); + }; + + reader.readAsText(this.dataFile); + + return deferred; + } else { + return this.base.apply(this, arguments); + } + } +}); diff --git a/js/Track/Model/File/BAM.js b/js/Track/Model/File/BAM.js new file mode 100644 index 00000000..b3b3b13f --- /dev/null +++ b/js/Track/Model/File/BAM.js @@ -0,0 +1,42 @@ +Genoverse.Track.Model.File.BAM = Genoverse.Track.Model.File.extend({ + getData: function (start, end) { + var model = this; + var deferred = $.Deferred(); + + if (!this.bamFile) { + if (this.url) { + this.bamFile = new dallianceLib.URLFetchable(this.url); + this.baiFile = new dallianceLib.URLFetchable(this.url + this.prop('indexExt')); + } else if (this.dataFile && this.indexFile) { + this.bamFile = new dallianceLib.BlobFetchable(this.dataFile); + this.baiFile = new dallianceLib.BlobFetchable(this.indexFile); + } + } + + dallianceLib.makeBam(this.bamFile, this.baiFile, null, function (bam, makeBamError) { + if (makeBamError) { + console.log(makeBamError); + } else { + bam.fetch(model.browser.chr, start, end, function (features, fetchBamError) { + if (fetchBamError) { + console.log(fetchBamError); + } else { + model.receiveData(features, start, end); + deferred.resolveWith(model); + } + }); + } + }); + + return deferred; + }, + + insertFeature: function (feature) { + feature.id = feature.readName + ':' + feature.pos; + feature.start = feature.pos + 1; + feature.end = feature.start + feature.seq.length; + feature.sequence = feature.seq; + + return this.base(feature); + } +}); diff --git a/js/Track/Model/File/GFF.js b/js/Track/Model/File/GFF.js index 77da31f4..62c3ab7e 100644 --- a/js/Track/Model/File/GFF.js +++ b/js/Track/Model/File/GFF.js @@ -1,18 +1,18 @@ Genoverse.Track.Model.File.GFF = Genoverse.Track.Model.File.extend({ parseData: function (text) { var lines = text.split('\n'); - + for (var i = 0; i < lines.length; i++) { if (!lines[i].length || lines[i].indexOf('#') === 0) { continue; } - + var fields = lines[i].split('\t'); if (fields.length < 5) { continue; } - + if (fields[0] === this.browser.chr || fields[0].toLowerCase() === 'chr' + this.browser.chr || fields[0].match('[^1-9]' + this.browser.chr + '$')) { this.insertFeature({ id : fields.slice(0, 5).join('|'), diff --git a/js/Track/library/File.js b/js/Track/library/File.js index 66f12081..c663e66b 100644 --- a/js/Track/library/File.js +++ b/js/Track/library/File.js @@ -1,6 +1,10 @@ Genoverse.Track.File = Genoverse.Track.extend({ setInterface: function () { this.base(); - this._interface.data = 'model'; + + this._interface.isLocal = 'model'; + this._interface.dataFile = 'model'; + this._interface.indexFile = 'model'; + this._interface.largeFile = 'model'; } }); diff --git a/js/Track/library/File/BAM.js b/js/Track/library/File/BAM.js new file mode 100644 index 00000000..62f33335 --- /dev/null +++ b/js/Track/library/File/BAM.js @@ -0,0 +1,30 @@ +Genoverse.Track.File.BAM = Genoverse.Track.File.extend({ + name : 'BAM', + indexExt : '.bai', + threshold : 100000, + largeFile : true, + model : Genoverse.Track.Model.File.BAM, + view : Genoverse.Track.View.Sequence.extend({ + bump : true, + autoHeight : true + }), + + click: function () { + var menu = this.base.apply(this, arguments); + + if (menu) { + menu.addClass('gv-wrap-values'); + } + + return menu; + }, + + populateMenu: function (feature) { + var f = $.extend({ title: feature.readName }, feature); + + delete f.sequence; + delete f.id; + + return this.base(f); + } +}); diff --git a/js/genoverse.combined.js b/js/genoverse.combined.js index 4be854fe..0d5cdf64 100644 --- a/js/genoverse.combined.js +++ b/js/genoverse.combined.js @@ -1265,6 +1265,79 @@ RTree.Rectangle.make_MBR = function(nodes, rect) { return(rect); }; +(function(){function D(){}function z(){this.was=[0]}function C(a,b,c){this.hufts=new Int32Array(4320);this.window=new Uint8Array(c);this.end=c;this.checkfn=b;this.mode=0;this.reset(a,null);this.index=this.table=this.left=0;this.blens=null;this.bb=new Int32Array(1);this.tb=new Int32Array(1);this.codes=new E;this.check=this.write=this.read=this.bitb=this.bitk=this.last=0;this.inftree=new F}function E(){}function F(){}function y(a,b,c,d,h){if(0!=h){if(!a)throw"Undef src";if(!c)throw"Undef dest";if(0== +b&&h==a.length)c.set(a,d);else if(W)a=a.subarray(b,b+h),c.set(a,d);else if(1==a.BYTES_PER_ELEMENT&&100=d&&56320<=h&&57343>=h&&(d=65536+((d&1023)<<10)+(h&1023),c++),127>=d?b+=String.fromCharCode(d):2047>=d?b+=String.fromCharCode(192|d>>>6&31,128|d&63):65535>=d?b+=String.fromCharCode(224| +d>>>12&15,128|d>>>6&63,128|d&63):2097151>=d&&(b+=String.fromCharCode(240|d>>>18&7,128|d>>>12&63,128|d>>>6&63,128|d&63));a=Array(b.length>>2);for(c=0;c>5]|=(b.charCodeAt(c/8)&255)<<24-c%32;b=8*b.length;a[b>>5]|=128<<24-b%32;a[(b+64>>9<<4)+15]=b;b=Array(80);c=1732584193;d=-271733879;h=-1732584194;for(var e=271733878,g=-1009589776,f=0;fl;l++){if(16>l)b[l]=a[f+l];else{var t=b[l-3]^b[l-8]^b[l-14]^b[l- +16];b[l]=t<<1|t>>>31}var t=c<<5|c>>>27,s;s=20>l?d&h|~d&e:40>l?d^h^e:60>l?d&h|d&e|h&e:d^h^e;t=A(A(t,s),A(A(g,b[l]),20>l?1518500249:40>l?1859775393:60>l?-1894007588:-899497514));g=e;e=h;h=d<<30|d>>>2;d=c;c=t}c=A(c,k);d=A(d,m);h=A(h,p);e=A(e,q);g=A(g,n)}a=[c,d,h,e,g];b="";for(c=0;c<32*a.length;c+=8)b+=String.fromCharCode(a[c>>5]>>>24-c%32&255);a=b;b="";c=a.length;for(d=0;de;e++)b=8*d+6*e>8*a.length?b+"": +b+"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt(h>>>6*(3-e)&63);return b}function A(a,b){var c=(a&65535)+(b&65535);return(a>>16)+(b>>16)+(c>>16)<<16|c&65535}function L(a,b){this.block=a;this.offset=b}function H(a,b,c){var d=4294967296*(a[b+6]&255)+16777216*(a[b+5]&255)+65536*(a[b+4]&255)+256*(a[b+3]&255)+(a[b+2]&255);a=a[b+1]<<8|a[b];return 0!=d||0!=a||c?new L(d,a):null}function M(a,b){b=Math.min(b||1,a.byteLength-50);for(var c=[],d=[0],h=0;d[0]>26);c<=1+(b>>26);++c)d.push(c);for(c= +9+(a>>23);c<=9+(b>>23);++c)d.push(c);for(c=73+(a>>20);c<=73+(b>>20);++c)d.push(c);for(c=585+(a>>17);c<=585+(b>>17);++c)d.push(c);for(c=4681+(a>>14);c<=4681+(b>>14);++c)d.push(c);return d}function G(a){this.blob=a}function B(a,b,c,d){d||("object"===typeof b?(d=b,b=void 0):d={});this.url=a;this.start=b||0;c&&(this.end=c);this.opts=d}function O(a){if(!a)return null;for(var b=new Uint8Array(a.length),c=0;cb&&(b=-b,nowrap=1);if(8>b||15>4)+8>a.istate.wbits){a.istate.mode=13;a.msg="invalid window size";a.istate.marker=5;break}a.istate.mode=1;case 1:if(0==a.avail_in)return c;c=b;a.avail_in--;a.total_in++;d=a.next_in[a.next_in_index++]&255;if(0!=((a.istate.method<<8)+d)%31){a.istate.mode=13;a.msg="incorrect header check";a.istate.marker=5;break}if(0==(d&32)){a.istate.mode=7;break}a.istate.mode=2;case 2:if(0==a.avail_in)return c;c=b;a.avail_in--;a.total_in++;a.istate.need=(a.next_in[a.next_in_index++]& +255)<<24&4278190080;a.istate.mode=3;case 3:if(0==a.avail_in)return c;c=b;a.avail_in--;a.total_in++;a.istate.need+=(a.next_in[a.next_in_index++]&255)<<16&16711680;a.istate.mode=4;case 4:if(0==a.avail_in)return c;c=b;a.avail_in--;a.total_in++;a.istate.need+=(a.next_in[a.next_in_index++]&255)<<8&65280;a.istate.mode=5;case 5:if(0==a.avail_in)return c;a.avail_in--;a.total_in++;a.istate.need+=a.next_in[a.next_in_index++]&255;a.adler=a.istate.need;a.istate.mode=6;return 2;case 6:return a.istate.mode=13, +a.msg="need dictionary",a.istate.marker=0,-2;case 7:c=a.istate.blocks.proc(a,c);if(-3==c){a.istate.mode=13;a.istate.marker=0;break}0==c&&(c=b);if(1!=c)return c;c=b;a.istate.blocks.reset(a,a.istate.was);if(0!=a.istate.nowrap){a.istate.mode=12;break}a.istate.mode=8;case 8:if(0==a.avail_in)return c;c=b;a.avail_in--;a.total_in++;a.istate.need=(a.next_in[a.next_in_index++]&255)<<24&4278190080;a.istate.mode=9;case 9:if(0==a.avail_in)return c;c=b;a.avail_in--;a.total_in++;a.istate.need+=(a.next_in[a.next_in_index++]& +255)<<16&16711680;a.istate.mode=10;case 10:if(0==a.avail_in)return c;c=b;a.avail_in--;a.total_in++;a.istate.need+=(a.next_in[a.next_in_index++]&255)<<8&65280;a.istate.mode=11;case 11:if(0==a.avail_in)return c;c=b;a.avail_in--;a.total_in++;a.istate.need+=a.next_in[a.next_in_index++]&255;if(a.istate.was[0]!=a.istate.need){a.istate.mode=13;a.msg="incorrect data check";a.istate.marker=5;break}a.istate.mode=12;case 12:return 1;case 13:return-3;default:return-2}};z.prototype.inflateSetDictionary=function(a, +b,c){var d=0,h=c;if(null==a||null==a.istate||6!=a.istate.mode)return-2;if(a._adler.adler32(1,b,0,c)!=a.adler)return-3;a.adler=a._adler.adler32(0,null,0,0);h>=1<d;)a.next_in[c]==ga[d]?d++:d=0!=a.next_in[c]?0:4-d,c++,b--;a.total_in+=c-a.next_in_index;a.next_in_index=c;a.avail_in=b;a.istate.marker=d;if(4!=d)return-3;b=a.total_in;c=a.total_out;this.inflateReset(a);a.total_in=b;a.total_out=c;a.istate.mode=7;return 0};z.prototype.inflateSyncPoint=function(a){return null==a||null==a.istate||null==a.istate.blocks?-2:a.istate.blocks.sync_point()};var S=[16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15];C.prototype.reset=function(a,b){b&&(b[0]=this.check);6==this.mode&& +this.codes.free(a);this.read=this.write=this.bitb=this.bitk=this.mode=0;this.checkfn&&(a.adler=this.check=a._adler.adler32(0,null,0,0))};C.prototype.proc=function(a,b){var c,d,h,e,g,f,k;e=a.next_in_index;g=a.avail_in;d=this.bitb;h=this.bitk;f=this.write;for(k=fh;){if(0!=g)b=0;else return this.bitb=d,this.bitk=h,a.avail_in=g,a.total_in+=e-a.next_in_index,a.next_in_index=e,this.write=f,this.inflate_flush(a,b);g--;d|=(a.next_in[e++]& +255)<>>1){case 0:d>>>=3;h-=3;c=h&7;d>>>=c;h-=c;this.mode=1;break;case 1:var m=new Int32Array(1),p=new Int32Array(1),q=[],n=[];c=p;var l=q,t=n;m[0]=9;c[0]=5;l[0]=aa;t[0]=ba;this.codes.init(m[0],p[0],q[0],0,n[0],0,a);d>>>=3;h-=3;this.mode=6;break;case 2:d>>>=3;h-=3;this.mode=3;break;case 3:return d>>>=3,h-=3,this.mode=13,a.msg="invalid block type",b=-3,this.bitb=d,this.bitk=h,a.avail_in=g,a.total_in+=e-a.next_in_index,a.next_in_index=e,this.write=f,this.inflate_flush(a, +b)}break;case 1:for(;32>h;){if(0!=g)b=0;else return this.bitb=d,this.bitk=h,a.avail_in=g,a.total_in+=e-a.next_in_index,a.next_in_index=e,this.write=f,this.inflate_flush(a,b);g--;d|=(a.next_in[e++]&255)<>>16&65535)!=(d&65535))return this.mode=13,a.msg="invalid stored block lengths",b=-3,this.bitb=d,this.bitk=h,a.avail_in=g,a.total_in+=e-a.next_in_index,a.next_in_index=e,this.write=f,this.inflate_flush(a,b);this.left=d&65535;d=h=0;this.mode=0!=this.left?2:0!=this.last?7:0;break;case 2:if(0== +g)return this.bitb=d,this.bitk=h,a.avail_in=g,a.total_in+=e-a.next_in_index,a.next_in_index=e,write=f,this.inflate_flush(a,b);if(0==k&&(f==end&&0!=read&&(f=0,k=fg&&(c=g);c>k&&(c=k);y(a.next_in,e,this.window,f,c);e+=c;g-=c;f+=c;k-=c;if(0!=(this.left-=c))break;this.mode=0!=this.last?7:0;break;case 3:for(;14>h;){if(0!=g)b=0;else return this.bitb=d,this.bitk=h,a.avail_in=g,a.total_in+=e-a.next_in_index,a.next_in_index=e,this.write=f,this.inflate_flush(a,b);g--;d|=(a.next_in[e++]&255)<>5&31))return this.mode=9,a.msg="too many length or distance symbols",b=-3,this.bitb=d,this.bitk=h,a.avail_in= +g,a.total_in+=e-a.next_in_index,a.next_in_index=e,this.write=f,this.inflate_flush(a,b);c=258+(c&31)+(c>>5&31);if(null==this.blens||this.blens.length>>=14;h-=14;this.index=0;mode=4;case 4:for(;this.index<4+(this.table>>>10);){for(;3>h;){if(0!=g)b=0;else return this.bitb=d,this.bitk=h,a.avail_in=g,a.total_in+=e-a.next_in_index,a.next_in_index=e,this.write=f,this.inflate_flush(a,b);g--;d|=(a.next_in[e++]&255)<>>=3;h-=3}for(;19>this.index;)this.blens[S[this.index++]]=0;this.bb[0]=7;c=this.inftree.inflate_trees_bits(this.blens,this.bb,this.tb,this.hufts,a);if(0!=c)return b=c,-3==b&&(this.blens=null,this.mode=9),this.bitb=d,this.bitk=h,a.avail_in=g,a.total_in+=e-a.next_in_index,a.next_in_index=e,write=f,this.inflate_flush(a,b);this.index=0;this.mode=5;case 5:for(;;){c=this.table;if(!(this.index<258+(c&31)+(c>>5&31)))break;for(c=this.bb[0];hp)d>>>=c,h-=c,this.blens[this.index++]=p;else{k=18==p?7:p-14;for(m=18==p?11:3;h>>=c;h-=c;m+=d&x[k];d>>>= +k;h-=k;k=this.index;c=this.table;if(k+m>258+(c&31)+(c>>5&31)||16==p&&1>k)return this.blens=null,this.mode=9,a.msg="invalid bit length repeat",b=-3,this.bitb=d,this.bitk=h,a.avail_in=g,a.total_in+=e-a.next_in_index,a.next_in_index=e,this.write=f,this.inflate_flush(a,b);p=16==p?this.blens[k-1]:0;do this.blens[k++]=p;while(0!=--m);this.index=k}}this.tb[0]=-1;m=new Int32Array(1);p=new Int32Array(1);q=new Int32Array(1);n=new Int32Array(1);m[0]=9;p[0]=6;c=this.table;c=this.inftree.inflate_trees_dynamic(257+ +(c&31),1+(c>>5&31),this.blens,m,p,q,n,this.hufts,a);if(0!=c)return-3==c&&(this.blens=null,this.mode=13),b=c,this.bitb=d,this.bitk=h,a.avail_in=g,a.total_in+=e-a.next_in_index,a.next_in_index=e,this.write=f,this.inflate_flush(a,b);this.codes.init(m[0],p[0],this.hufts,q[0],this.hufts,n[0],a);this.mode=6;case 6:this.bitb=d;this.bitk=h;a.avail_in=g;a.total_in+=e-a.next_in_index;a.next_in_index=e;this.write=f;if(1!=(b=this.codes.proc(this,a,b)))return this.inflate_flush(a,b);b=0;this.codes.free(a);e=a.next_in_index; +g=a.avail_in;d=this.bitb;h=this.bitk;f=this.write;k=fa.avail_out&&(c=a.avail_out);0!=c&&-5==b&&(b=0);a.avail_out-=c;a.total_out+=c;null!=this.checkfn&&(a.adler=this.check=a._adler.adler32(this.check,this.window,h,c));y(this.window,h,a.next_out,d,c);d+=c;h+=c;h==this.end&&(h=0,this.write==this.end&&(this.write=0),c=this.write-h,c>a.avail_out&&(c=a.avail_out),0!=c&&-5==b&&(b=0),a.avail_out-=c,a.total_out+=c,null!=this.checkfn&&(a.adler=this.check=a._adler.adler32(this.check, +this.window,h,c)),y(this.window,h,a.next_out,d,c),d+=c,h+=c);a.next_out_index=d;this.read=h;return b};E.prototype.init=function(a,b,c,d,h,e,g){this.mode=0;this.lbits=a;this.dbits=b;this.ltree=c;this.ltree_index=d;this.dtree=h;this.dtree_index=e;this.tree=null};E.prototype.proc=function(a,b,c){var d,h,e=0,g=0,f=0,k,m,p,f=b.next_in_index;k=b.avail_in;e=a.bitb;g=a.bitk;m=a.write;for(p=m>>=this.tree[d+1];g-=this.tree[d+1];h=this.tree[d];if(0==h){this.lit=this.tree[d+2];this.mode=6;break}if(0!=(h&16)){this.get=h&15;this.len=this.tree[d+2];this.mode=2;break}if(0==(h&64)){this.need=h;this.tree_index=d/3+this.tree[d+2];break}if(0!=(h&32)){this.mode=7;break}this.mode=9;b.msg="invalid literal/length code";c=-3;a.bitb=e;a.bitk=g;b.avail_in=k;b.total_in+=f-b.next_in_index;b.next_in_index=f;a.write=m;return a.inflate_flush(b, +c);case 2:for(d=this.get;g>=d;g-=d;this.need=this.dbits;this.tree=this.dtree;this.tree_index=this.dtree_index;this.mode=3;case 3:for(d=this.need;g>=this.tree[d+1];g-=this.tree[d+1];h=this.tree[d];if(0!=(h&16)){this.get=h&15;this.dist=this.tree[d+2];this.mode=4;break}if(0==(h&64)){this.need=h;this.tree_index=d/3+this.tree[d+2];break}this.mode=9;b.msg="invalid distance code";c=-3;a.bitb=e;a.bitk=g;b.avail_in=k;b.total_in+=f-b.next_in_index;b.next_in_index=f;a.write=m;return a.inflate_flush(b,c);case 4:for(d=this.get;g>=d;g-=d;this.mode=5;case 5:for(d=m-this.dist;0>d;)d+=a.end;for(;0!=this.len;){if(0==p&&(m==a.end&&0!=a.read&&(m=0,p=mn;)t--,q|=(f.next_in[l++]&255)<>=m[v+1],n-=m[v+1],g.window[s++]=m[v+2],w--;else{do{q>>=m[v+1];n-=m[v+1];if(0!=(b&16)){b&=15;r=m[v+2]+(q&x[b]);q>>=b;for(n-=b;15> +n;)t--,q|=(f.next_in[l++]&255)<>=m[v+1],n-=m[v+1],0!=(b&16)){for(b&=15;n>=b;n-=b;w-=r;if(s>=k)k=s-k,g.window[s++]=g.window[k++],g.window[s++]=g.window[k++],r-=2;else{k=s-k;do k+=g.end;while(0>k);b=g.end-k;if(r>b){r-=b;if(0s-k){do g.window[s++]=g.window[k++];while(0!=--b)}else y(g.window,k,g.window,s,b),s+=b;k=0}}do g.window[s++]=g.window[k++];while(0!=--r);break}else if(0==(b&64))k+= +m[v+2],k+=q&x[b],v=3*(p+k),b=m[v];else return f.msg="invalid distance code",r=f.avail_in-t,r=n>>3>3:r,t+=r,l-=r,n-=r<<3,g.bitb=q,g.bitk=n,f.avail_in=t,f.total_in+=l-f.next_in_index,f.next_in_index=l,g.write=s,-3;while(1);break}if(0==(b&64)){if(k+=m[v+2],k+=q&x[b],v=3*(p+k),0==(b=m[v])){q>>=m[v+1];n-=m[v+1];g.window[s++]=m[v+2];w--;break}}else{if(0!=(b&32))return r=f.avail_in-t,r=n>>3>3:r,t+=r,l-=r,n-=r<<3,g.bitb=q,g.bitk=n,f.avail_in=t,f.total_in+=l-f.next_in_index,f.next_in_index=l,g.write= +s,1;f.msg="invalid literal/length code";r=f.avail_in-t;r=n>>3>3:r;t+=r;l-=r;n-=r<<3;g.bitb=q;g.bitk=n;f.avail_in=t;f.total_in+=l-f.next_in_index;f.next_in_index=l;g.write=s;return-3}}while(1)}}while(258<=w&&10<=t);r=f.avail_in-t;r=n>>3>3:r;l-=r;g.bitb=q;g.bitk=n-(r<<3);f.avail_in=t+r;f.total_in+=l-f.next_in_index;f.next_in_index=l;g.write=s;return 0};F.prototype.huft_build=function(a,b,c,d,h,e,g,f,k,m,p){var q,n,l,t,s,w,u,r,v;w=0;n=c;do this.c[a[b+w]]++,w++,n--;while(0!=n);if(this.c[0]== +c)return g[0]=-1,f[0]=0;s=f[0];for(l=1;15>=l&&0==this.c[l];l++);t=l;sn&&(s=n);f[0]=s;for(f=1<(f-=this.c[l]))return-3;if(0>(f-=this.c[n]))return-3;this.c[n]+=f;this.x[1]=l=0;w=1;for(u=2;0!=--n;)this.x[u]=l+=this.c[w],u++,w++;w=n=0;do 0!=(l=a[b+w])&&(this.v[this.x[l]++]=n),w++;while(++nr+s;){b++;r+=s;v=m-r;v=v>s?s:v;if((q=1<<(l= +t-r))>a+1&&(q-=a+1,u=t,l>>r-s,this.r[2]=u-this.u[b-1]-l,y(this.r,0,k,3*(this.u[b-1]+l),3)):g[0]=u}this.r[1]=t-r;w>=c?this.r[0]=192:p[w]this.v[w]?0:96,this.r[2]=this.v[w++]):(this.r[0]=e[this.v[w]-d]+16+64,this.r[2]=h[this.v[w++]-d]);q=1<>>r;l>>= +1)n^=l;n^=l;for(l=(1<b;b++)this.c[b]=0;for(b=0;3>b;b++)this.r[b]=0;y(this.c,0,this.u,0,15);y(this.c,0,this.x,0,16)};var W="function"===typeof(new Uint8Array(1)).subarray;L.prototype.toString=function(){return""+this.block+":"+this.offset};G.prototype.slice=function(a,b){var c;c=this.blob.slice?b?this.blob.slice(a,a+b):this.blob.slice(a): +b?this.blob.webkitSlice(a,a+b):this.blob.webkitSlice(a);return new G(c)};G.prototype.salted=function(){return this};G.prototype.fetch="undefined"!==typeof FileReader?function(a){var b=new FileReader;b.onloadend=function(c){a(O(b.result))};b.readAsBinaryString(this.blob)}:function(a){var b=new FileReaderSync;try{var c=b.readAsArrayBuffer(this.blob);a(c)}catch(d){a(null,d)}};B.prototype.slice=function(a,b){if(0>a)throw"Bad slice "+a;var c=this.start,d=this.end,c=c&&a?c+a:a||c;return new B(this.url, +c,b&&c?c+b-1:d||b-1,this.opts)};var T=0,U=0<=navigator.userAgent.indexOf("Safari")&&0>navigator.userAgent.indexOf("Chrome");B.prototype.fetchAsText=function(a){var b=this;this.getURL().then(function(c){try{var d=new XMLHttpRequest;(U||b.opts.salt)&&0>c.indexOf("?")&&(c=c+"?salt="+K(""+Date.now()+","+ ++T));d.open("GET",c,!0);if(b.end){if(1E8e.indexOf("?")&&(e=e+"?salt="+K(""+Date.now()+","+ ++T));f.open("GET",e,!0);f.overrideMimeType("text/plain; charset=x-user-defined");if(c.end){if(1E8m?g:a).push(new N(n,l));f+=16}else f+=16*p}e=u(d,f);h=null;b=Math.min(b>>14,e-1);c=Math.min(c>> +14,e-1);for(e=b;e<=c;++e)(b=H(d,f+4+8*e))&&(!h||b.block=h.block&&c.maxv.offset>=h.offset&&d.push(c);g=d;d=[];for(e=0;e=k.length)return d(p);if(n){var a=new Uint8Array(n),a=g.readBamRecords(a,k[q].minv.offset,p,b,c,f,h);n=null;++q;return a?d(p):e()}var m=k[q],a=m.minv.block;g.data.slice(a,m.maxv.block+65536-a).fetch(function(a){n=M(a,m.maxv.block-m.minv.block+1);return e()})}var g=this;h=h||{};var f=this.chrToIndex[a],k;if(void 0===f)k=[];else{if(null===this.indices[f]&&this.indexChunks.chunks[f]){var m=this.indexChunks.chunks[f];return this.bai.slice(m[0],m[1]).fetch(function(e){e= +new Uint8Array(e);this.indices[f]=e;return this.fetch(a,b,c,d,h)}.bind(this))}(k=this.blocksForRange(f,b,c))||d(null,"Error in index fetch")}var p=[],q=0,n;e()};var V="=ACxGxxxTxxxxxxN".split(""),ha="MIDNSHP=X???????".split("");I.prototype.readBamRecords=function(a,b,c,d,h,e,g){for(;;){var f=u(a,b),f=b+f+4;if(f>=a.length)return!1;var k=new Z,m=u(a,b+4),p=u(a,b+8),q=u(a,b+12),n=(q&65280)>>8,l=q&255,q=u(a,b+16),t=(q&4294901760)>>16,s=q&65535,q=u(a,b+20),w=u(a,b+24),x=u(a,b+28);u(a,b+32);k.segment=this.indexToChr[m]; +k.flag=t;k.pos=p;k.mq=n;g.light&&(k.seqLength=q);if(!g.light){0<=w&&(k.nextSegment=this.indexToChr[w],k.nextPos=x);n="";for(p=0;p>4)+ha[n&15],b+=4;k.cigar=l;s="";l=q+1>>1;for(p=0;p>4],s.length=d)void 0!==e&&m!=e||c.push(k);if(k.pos>h)return!0;b=f}};window.dallianceLib={URLFetchable:B,BlobFetchable:G,makeBam:function(a,b,c,d,h){a.slice(0,10).fetch(function(e){return e?R(a,b,c,d,h):d(null,"Couldn't access BAM.")},{timeout:5E3})}}})(); + + var $ = jQuery; // Make sure we have local $ (this is for combined script in a function) var Genoverse = Base.extend({ // Defaults @@ -5114,41 +5187,86 @@ Genoverse.Track.View.Transcript.Ensembl = Genoverse.Track.View.Transcript.extend }); Genoverse.Track.Model.File = Genoverse.Track.Model.extend({ - dataType : 'text' + dataType: 'text', + + init: function () { + if (this.isLocal) { + this.url = false; + } + + if (!this.largeFile) { + this.allData = true; + } + + this.base.apply(this, arguments); + }, + + getData: function () { + var model = this; + + if (this.isLocal && this.dataFile) { + var reader = new FileReader(); + var deferred = $.Deferred(); + + reader.onload = function (e) { + deferred.done(function () { + this.receiveData(e.target.result, 1, this.browser.chromosomeSize); + }).resolveWith(model); + }; + + reader.readAsText(this.dataFile); + + return deferred; + } else { + return this.base.apply(this, arguments); + } + } }); -Genoverse.Track.Model.File.GFF = Genoverse.Track.Model.File.extend({ - parseData: function (text) { - var lines = text.split('\n'); - - for (var i = 0; i < lines.length; i++) { - if (!lines[i].length || lines[i].indexOf('#') === 0) { - continue; - } - - var fields = lines[i].split('\t'); - if (fields.length < 5) { - continue; +Genoverse.Track.Model.File.BAM = Genoverse.Track.Model.File.extend({ + getData: function (start, end) { + var model = this; + var deferred = $.Deferred(); + + if (!this.bamFile) { + if (this.url) { + this.bamFile = new dallianceLib.URLFetchable(this.url); + this.baiFile = new dallianceLib.URLFetchable(this.url + this.prop('indexExt')); + } else if (this.dataFile && this.indexFile) { + this.bamFile = new dallianceLib.BlobFetchable(this.dataFile); + this.baiFile = new dallianceLib.BlobFetchable(this.indexFile); } - - if (fields[0] === this.browser.chr || fields[0].toLowerCase() === 'chr' + this.browser.chr || fields[0].match('[^1-9]' + this.browser.chr + '$')) { - this.insertFeature({ - id : fields.slice(0, 5).join('|'), - start : parseInt(fields[3], 10), - end : parseInt(fields[4], 10), - source : fields[1], - type : fields[2], - score : fields[5], - strand : fields[6] + '1', - label : fields[1] + ' ' + fields[2] + ' ' + fields[3] + '-' + fields[4] + } + + dallianceLib.makeBam(this.bamFile, this.baiFile, null, function (bam, makeBamError) { + if (makeBamError) { + console.log(makeBamError); + } else { + bam.fetch(model.browser.chr, start, end, function (features, fetchBamError) { + if (fetchBamError) { + console.log(fetchBamError); + } else { + model.receiveData(features, start, end); + deferred.resolveWith(model); + } }); } - } + }); + + return deferred; + }, + + insertFeature: function (feature) { + feature.id = feature.readName + ':' + feature.pos; + feature.start = feature.pos + 1; + feature.end = feature.start + feature.seq.length; + feature.sequence = feature.seq; + + return this.base(feature); } }); -Genoverse.Track.Model.File.GTF = Genoverse.Track.Model.File.GFF; Genoverse.Track.Model.File.BED = Genoverse.Track.Model.File.extend({ parseData: function (text) { @@ -5197,6 +5315,39 @@ Genoverse.Track.Model.File.BED = Genoverse.Track.Model.File.extend({ } }); +Genoverse.Track.Model.File.GFF = Genoverse.Track.Model.File.extend({ + parseData: function (text) { + var lines = text.split('\n'); + + for (var i = 0; i < lines.length; i++) { + if (!lines[i].length || lines[i].indexOf('#') === 0) { + continue; + } + + var fields = lines[i].split('\t'); + + if (fields.length < 5) { + continue; + } + + if (fields[0] === this.browser.chr || fields[0].toLowerCase() === 'chr' + this.browser.chr || fields[0].match('[^1-9]' + this.browser.chr + '$')) { + this.insertFeature({ + id : fields.slice(0, 5).join('|'), + start : parseInt(fields[3], 10), + end : parseInt(fields[4], 10), + source : fields[1], + type : fields[2], + score : fields[5], + strand : fields[6] + '1', + label : fields[1] + ' ' + fields[2] + ' ' + fields[3] + '-' + fields[4] + }); + } + } + } +}); + +Genoverse.Track.Model.File.GTF = Genoverse.Track.Model.File.GFF; + Genoverse.Track.Chromosome = Genoverse.Track.extend({ id : 'chromosome', margin : 1, @@ -5495,28 +5646,47 @@ Genoverse.Track.dbSNP = Genoverse.Track.extend({ Genoverse.Track.File = Genoverse.Track.extend({ setInterface: function () { this.base(); - this._interface.data = 'model'; + + this._interface.isLocal = 'model'; + this._interface.dataFile = 'model'; + this._interface.indexFile = 'model'; + this._interface.largeFile = 'model'; } }); -Genoverse.Track.File.GFF = Genoverse.Track.File.extend({ - name : 'GFF', - model : Genoverse.Track.Model.File.GFF, - bump : true, - height : 100, - featureHeight : 5 -}); +Genoverse.Track.File.BAM = Genoverse.Track.File.extend({ + name : 'BAM', + indexExt : '.bai', + threshold : 100000, + largeFile : true, + model : Genoverse.Track.Model.File.BAM, + view : Genoverse.Track.View.Sequence.extend({ + bump : true, + autoHeight : true + }), -Genoverse.Track.File.GTF = Genoverse.Track.File.GFF; + click: function () { + var menu = this.base.apply(this, arguments); -Genoverse.Track.File.GFF3 = Genoverse.Track.File.extend({ - name : 'GFF3', - model : Genoverse.Track.Model.Transcript.GFF3, - view : Genoverse.Track.View.Transcript, - bump : true + if (menu) { + menu.addClass('gv-wrap-values'); + } + + return menu; + }, + + populateMenu: function (feature) { + var f = $.extend({ title: feature.readName }, feature); + + delete f.sequence; + delete f.id; + + return this.base(f); + } }); + Genoverse.Track.File.BED = Genoverse.Track.File.extend({ name : 'BED', model : Genoverse.Track.Model.File.BED, @@ -5542,6 +5712,23 @@ Genoverse.Track.File.BED = Genoverse.Track.File.extend({ } }); +Genoverse.Track.File.GFF = Genoverse.Track.File.extend({ + name : 'GFF', + model : Genoverse.Track.Model.File.GFF, + bump : true, + height : 100, + featureHeight : 5 +}); + +Genoverse.Track.File.GTF = Genoverse.Track.File.GFF; + +Genoverse.Track.File.GFF3 = Genoverse.Track.File.extend({ + name : 'GFF3', + model : Genoverse.Track.Model.Transcript.GFF3, + view : Genoverse.Track.View.Transcript, + bump : true +}); + Genoverse.Track.File.VCF = Genoverse.Track.File.extend({ name : 'VCF', model : Genoverse.Track.Model.SequenceVariation.VCF, diff --git a/js/genoverse.combined.nojquery.js b/js/genoverse.combined.nojquery.js index a622e15f..181460a9 100644 --- a/js/genoverse.combined.nojquery.js +++ b/js/genoverse.combined.nojquery.js @@ -1260,6 +1260,79 @@ RTree.Rectangle.make_MBR = function(nodes, rect) { return(rect); }; +(function(){function D(){}function z(){this.was=[0]}function C(a,b,c){this.hufts=new Int32Array(4320);this.window=new Uint8Array(c);this.end=c;this.checkfn=b;this.mode=0;this.reset(a,null);this.index=this.table=this.left=0;this.blens=null;this.bb=new Int32Array(1);this.tb=new Int32Array(1);this.codes=new E;this.check=this.write=this.read=this.bitb=this.bitk=this.last=0;this.inftree=new F}function E(){}function F(){}function y(a,b,c,d,h){if(0!=h){if(!a)throw"Undef src";if(!c)throw"Undef dest";if(0== +b&&h==a.length)c.set(a,d);else if(W)a=a.subarray(b,b+h),c.set(a,d);else if(1==a.BYTES_PER_ELEMENT&&100=d&&56320<=h&&57343>=h&&(d=65536+((d&1023)<<10)+(h&1023),c++),127>=d?b+=String.fromCharCode(d):2047>=d?b+=String.fromCharCode(192|d>>>6&31,128|d&63):65535>=d?b+=String.fromCharCode(224| +d>>>12&15,128|d>>>6&63,128|d&63):2097151>=d&&(b+=String.fromCharCode(240|d>>>18&7,128|d>>>12&63,128|d>>>6&63,128|d&63));a=Array(b.length>>2);for(c=0;c>5]|=(b.charCodeAt(c/8)&255)<<24-c%32;b=8*b.length;a[b>>5]|=128<<24-b%32;a[(b+64>>9<<4)+15]=b;b=Array(80);c=1732584193;d=-271733879;h=-1732584194;for(var e=271733878,g=-1009589776,f=0;fl;l++){if(16>l)b[l]=a[f+l];else{var t=b[l-3]^b[l-8]^b[l-14]^b[l- +16];b[l]=t<<1|t>>>31}var t=c<<5|c>>>27,s;s=20>l?d&h|~d&e:40>l?d^h^e:60>l?d&h|d&e|h&e:d^h^e;t=A(A(t,s),A(A(g,b[l]),20>l?1518500249:40>l?1859775393:60>l?-1894007588:-899497514));g=e;e=h;h=d<<30|d>>>2;d=c;c=t}c=A(c,k);d=A(d,m);h=A(h,p);e=A(e,q);g=A(g,n)}a=[c,d,h,e,g];b="";for(c=0;c<32*a.length;c+=8)b+=String.fromCharCode(a[c>>5]>>>24-c%32&255);a=b;b="";c=a.length;for(d=0;de;e++)b=8*d+6*e>8*a.length?b+"": +b+"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt(h>>>6*(3-e)&63);return b}function A(a,b){var c=(a&65535)+(b&65535);return(a>>16)+(b>>16)+(c>>16)<<16|c&65535}function L(a,b){this.block=a;this.offset=b}function H(a,b,c){var d=4294967296*(a[b+6]&255)+16777216*(a[b+5]&255)+65536*(a[b+4]&255)+256*(a[b+3]&255)+(a[b+2]&255);a=a[b+1]<<8|a[b];return 0!=d||0!=a||c?new L(d,a):null}function M(a,b){b=Math.min(b||1,a.byteLength-50);for(var c=[],d=[0],h=0;d[0]>26);c<=1+(b>>26);++c)d.push(c);for(c= +9+(a>>23);c<=9+(b>>23);++c)d.push(c);for(c=73+(a>>20);c<=73+(b>>20);++c)d.push(c);for(c=585+(a>>17);c<=585+(b>>17);++c)d.push(c);for(c=4681+(a>>14);c<=4681+(b>>14);++c)d.push(c);return d}function G(a){this.blob=a}function B(a,b,c,d){d||("object"===typeof b?(d=b,b=void 0):d={});this.url=a;this.start=b||0;c&&(this.end=c);this.opts=d}function O(a){if(!a)return null;for(var b=new Uint8Array(a.length),c=0;cb&&(b=-b,nowrap=1);if(8>b||15>4)+8>a.istate.wbits){a.istate.mode=13;a.msg="invalid window size";a.istate.marker=5;break}a.istate.mode=1;case 1:if(0==a.avail_in)return c;c=b;a.avail_in--;a.total_in++;d=a.next_in[a.next_in_index++]&255;if(0!=((a.istate.method<<8)+d)%31){a.istate.mode=13;a.msg="incorrect header check";a.istate.marker=5;break}if(0==(d&32)){a.istate.mode=7;break}a.istate.mode=2;case 2:if(0==a.avail_in)return c;c=b;a.avail_in--;a.total_in++;a.istate.need=(a.next_in[a.next_in_index++]& +255)<<24&4278190080;a.istate.mode=3;case 3:if(0==a.avail_in)return c;c=b;a.avail_in--;a.total_in++;a.istate.need+=(a.next_in[a.next_in_index++]&255)<<16&16711680;a.istate.mode=4;case 4:if(0==a.avail_in)return c;c=b;a.avail_in--;a.total_in++;a.istate.need+=(a.next_in[a.next_in_index++]&255)<<8&65280;a.istate.mode=5;case 5:if(0==a.avail_in)return c;a.avail_in--;a.total_in++;a.istate.need+=a.next_in[a.next_in_index++]&255;a.adler=a.istate.need;a.istate.mode=6;return 2;case 6:return a.istate.mode=13, +a.msg="need dictionary",a.istate.marker=0,-2;case 7:c=a.istate.blocks.proc(a,c);if(-3==c){a.istate.mode=13;a.istate.marker=0;break}0==c&&(c=b);if(1!=c)return c;c=b;a.istate.blocks.reset(a,a.istate.was);if(0!=a.istate.nowrap){a.istate.mode=12;break}a.istate.mode=8;case 8:if(0==a.avail_in)return c;c=b;a.avail_in--;a.total_in++;a.istate.need=(a.next_in[a.next_in_index++]&255)<<24&4278190080;a.istate.mode=9;case 9:if(0==a.avail_in)return c;c=b;a.avail_in--;a.total_in++;a.istate.need+=(a.next_in[a.next_in_index++]& +255)<<16&16711680;a.istate.mode=10;case 10:if(0==a.avail_in)return c;c=b;a.avail_in--;a.total_in++;a.istate.need+=(a.next_in[a.next_in_index++]&255)<<8&65280;a.istate.mode=11;case 11:if(0==a.avail_in)return c;c=b;a.avail_in--;a.total_in++;a.istate.need+=a.next_in[a.next_in_index++]&255;if(a.istate.was[0]!=a.istate.need){a.istate.mode=13;a.msg="incorrect data check";a.istate.marker=5;break}a.istate.mode=12;case 12:return 1;case 13:return-3;default:return-2}};z.prototype.inflateSetDictionary=function(a, +b,c){var d=0,h=c;if(null==a||null==a.istate||6!=a.istate.mode)return-2;if(a._adler.adler32(1,b,0,c)!=a.adler)return-3;a.adler=a._adler.adler32(0,null,0,0);h>=1<d;)a.next_in[c]==ga[d]?d++:d=0!=a.next_in[c]?0:4-d,c++,b--;a.total_in+=c-a.next_in_index;a.next_in_index=c;a.avail_in=b;a.istate.marker=d;if(4!=d)return-3;b=a.total_in;c=a.total_out;this.inflateReset(a);a.total_in=b;a.total_out=c;a.istate.mode=7;return 0};z.prototype.inflateSyncPoint=function(a){return null==a||null==a.istate||null==a.istate.blocks?-2:a.istate.blocks.sync_point()};var S=[16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15];C.prototype.reset=function(a,b){b&&(b[0]=this.check);6==this.mode&& +this.codes.free(a);this.read=this.write=this.bitb=this.bitk=this.mode=0;this.checkfn&&(a.adler=this.check=a._adler.adler32(0,null,0,0))};C.prototype.proc=function(a,b){var c,d,h,e,g,f,k;e=a.next_in_index;g=a.avail_in;d=this.bitb;h=this.bitk;f=this.write;for(k=fh;){if(0!=g)b=0;else return this.bitb=d,this.bitk=h,a.avail_in=g,a.total_in+=e-a.next_in_index,a.next_in_index=e,this.write=f,this.inflate_flush(a,b);g--;d|=(a.next_in[e++]& +255)<>>1){case 0:d>>>=3;h-=3;c=h&7;d>>>=c;h-=c;this.mode=1;break;case 1:var m=new Int32Array(1),p=new Int32Array(1),q=[],n=[];c=p;var l=q,t=n;m[0]=9;c[0]=5;l[0]=aa;t[0]=ba;this.codes.init(m[0],p[0],q[0],0,n[0],0,a);d>>>=3;h-=3;this.mode=6;break;case 2:d>>>=3;h-=3;this.mode=3;break;case 3:return d>>>=3,h-=3,this.mode=13,a.msg="invalid block type",b=-3,this.bitb=d,this.bitk=h,a.avail_in=g,a.total_in+=e-a.next_in_index,a.next_in_index=e,this.write=f,this.inflate_flush(a, +b)}break;case 1:for(;32>h;){if(0!=g)b=0;else return this.bitb=d,this.bitk=h,a.avail_in=g,a.total_in+=e-a.next_in_index,a.next_in_index=e,this.write=f,this.inflate_flush(a,b);g--;d|=(a.next_in[e++]&255)<>>16&65535)!=(d&65535))return this.mode=13,a.msg="invalid stored block lengths",b=-3,this.bitb=d,this.bitk=h,a.avail_in=g,a.total_in+=e-a.next_in_index,a.next_in_index=e,this.write=f,this.inflate_flush(a,b);this.left=d&65535;d=h=0;this.mode=0!=this.left?2:0!=this.last?7:0;break;case 2:if(0== +g)return this.bitb=d,this.bitk=h,a.avail_in=g,a.total_in+=e-a.next_in_index,a.next_in_index=e,write=f,this.inflate_flush(a,b);if(0==k&&(f==end&&0!=read&&(f=0,k=fg&&(c=g);c>k&&(c=k);y(a.next_in,e,this.window,f,c);e+=c;g-=c;f+=c;k-=c;if(0!=(this.left-=c))break;this.mode=0!=this.last?7:0;break;case 3:for(;14>h;){if(0!=g)b=0;else return this.bitb=d,this.bitk=h,a.avail_in=g,a.total_in+=e-a.next_in_index,a.next_in_index=e,this.write=f,this.inflate_flush(a,b);g--;d|=(a.next_in[e++]&255)<>5&31))return this.mode=9,a.msg="too many length or distance symbols",b=-3,this.bitb=d,this.bitk=h,a.avail_in= +g,a.total_in+=e-a.next_in_index,a.next_in_index=e,this.write=f,this.inflate_flush(a,b);c=258+(c&31)+(c>>5&31);if(null==this.blens||this.blens.length>>=14;h-=14;this.index=0;mode=4;case 4:for(;this.index<4+(this.table>>>10);){for(;3>h;){if(0!=g)b=0;else return this.bitb=d,this.bitk=h,a.avail_in=g,a.total_in+=e-a.next_in_index,a.next_in_index=e,this.write=f,this.inflate_flush(a,b);g--;d|=(a.next_in[e++]&255)<>>=3;h-=3}for(;19>this.index;)this.blens[S[this.index++]]=0;this.bb[0]=7;c=this.inftree.inflate_trees_bits(this.blens,this.bb,this.tb,this.hufts,a);if(0!=c)return b=c,-3==b&&(this.blens=null,this.mode=9),this.bitb=d,this.bitk=h,a.avail_in=g,a.total_in+=e-a.next_in_index,a.next_in_index=e,write=f,this.inflate_flush(a,b);this.index=0;this.mode=5;case 5:for(;;){c=this.table;if(!(this.index<258+(c&31)+(c>>5&31)))break;for(c=this.bb[0];hp)d>>>=c,h-=c,this.blens[this.index++]=p;else{k=18==p?7:p-14;for(m=18==p?11:3;h>>=c;h-=c;m+=d&x[k];d>>>= +k;h-=k;k=this.index;c=this.table;if(k+m>258+(c&31)+(c>>5&31)||16==p&&1>k)return this.blens=null,this.mode=9,a.msg="invalid bit length repeat",b=-3,this.bitb=d,this.bitk=h,a.avail_in=g,a.total_in+=e-a.next_in_index,a.next_in_index=e,this.write=f,this.inflate_flush(a,b);p=16==p?this.blens[k-1]:0;do this.blens[k++]=p;while(0!=--m);this.index=k}}this.tb[0]=-1;m=new Int32Array(1);p=new Int32Array(1);q=new Int32Array(1);n=new Int32Array(1);m[0]=9;p[0]=6;c=this.table;c=this.inftree.inflate_trees_dynamic(257+ +(c&31),1+(c>>5&31),this.blens,m,p,q,n,this.hufts,a);if(0!=c)return-3==c&&(this.blens=null,this.mode=13),b=c,this.bitb=d,this.bitk=h,a.avail_in=g,a.total_in+=e-a.next_in_index,a.next_in_index=e,this.write=f,this.inflate_flush(a,b);this.codes.init(m[0],p[0],this.hufts,q[0],this.hufts,n[0],a);this.mode=6;case 6:this.bitb=d;this.bitk=h;a.avail_in=g;a.total_in+=e-a.next_in_index;a.next_in_index=e;this.write=f;if(1!=(b=this.codes.proc(this,a,b)))return this.inflate_flush(a,b);b=0;this.codes.free(a);e=a.next_in_index; +g=a.avail_in;d=this.bitb;h=this.bitk;f=this.write;k=fa.avail_out&&(c=a.avail_out);0!=c&&-5==b&&(b=0);a.avail_out-=c;a.total_out+=c;null!=this.checkfn&&(a.adler=this.check=a._adler.adler32(this.check,this.window,h,c));y(this.window,h,a.next_out,d,c);d+=c;h+=c;h==this.end&&(h=0,this.write==this.end&&(this.write=0),c=this.write-h,c>a.avail_out&&(c=a.avail_out),0!=c&&-5==b&&(b=0),a.avail_out-=c,a.total_out+=c,null!=this.checkfn&&(a.adler=this.check=a._adler.adler32(this.check, +this.window,h,c)),y(this.window,h,a.next_out,d,c),d+=c,h+=c);a.next_out_index=d;this.read=h;return b};E.prototype.init=function(a,b,c,d,h,e,g){this.mode=0;this.lbits=a;this.dbits=b;this.ltree=c;this.ltree_index=d;this.dtree=h;this.dtree_index=e;this.tree=null};E.prototype.proc=function(a,b,c){var d,h,e=0,g=0,f=0,k,m,p,f=b.next_in_index;k=b.avail_in;e=a.bitb;g=a.bitk;m=a.write;for(p=m>>=this.tree[d+1];g-=this.tree[d+1];h=this.tree[d];if(0==h){this.lit=this.tree[d+2];this.mode=6;break}if(0!=(h&16)){this.get=h&15;this.len=this.tree[d+2];this.mode=2;break}if(0==(h&64)){this.need=h;this.tree_index=d/3+this.tree[d+2];break}if(0!=(h&32)){this.mode=7;break}this.mode=9;b.msg="invalid literal/length code";c=-3;a.bitb=e;a.bitk=g;b.avail_in=k;b.total_in+=f-b.next_in_index;b.next_in_index=f;a.write=m;return a.inflate_flush(b, +c);case 2:for(d=this.get;g>=d;g-=d;this.need=this.dbits;this.tree=this.dtree;this.tree_index=this.dtree_index;this.mode=3;case 3:for(d=this.need;g>=this.tree[d+1];g-=this.tree[d+1];h=this.tree[d];if(0!=(h&16)){this.get=h&15;this.dist=this.tree[d+2];this.mode=4;break}if(0==(h&64)){this.need=h;this.tree_index=d/3+this.tree[d+2];break}this.mode=9;b.msg="invalid distance code";c=-3;a.bitb=e;a.bitk=g;b.avail_in=k;b.total_in+=f-b.next_in_index;b.next_in_index=f;a.write=m;return a.inflate_flush(b,c);case 4:for(d=this.get;g>=d;g-=d;this.mode=5;case 5:for(d=m-this.dist;0>d;)d+=a.end;for(;0!=this.len;){if(0==p&&(m==a.end&&0!=a.read&&(m=0,p=mn;)t--,q|=(f.next_in[l++]&255)<>=m[v+1],n-=m[v+1],g.window[s++]=m[v+2],w--;else{do{q>>=m[v+1];n-=m[v+1];if(0!=(b&16)){b&=15;r=m[v+2]+(q&x[b]);q>>=b;for(n-=b;15> +n;)t--,q|=(f.next_in[l++]&255)<>=m[v+1],n-=m[v+1],0!=(b&16)){for(b&=15;n>=b;n-=b;w-=r;if(s>=k)k=s-k,g.window[s++]=g.window[k++],g.window[s++]=g.window[k++],r-=2;else{k=s-k;do k+=g.end;while(0>k);b=g.end-k;if(r>b){r-=b;if(0s-k){do g.window[s++]=g.window[k++];while(0!=--b)}else y(g.window,k,g.window,s,b),s+=b;k=0}}do g.window[s++]=g.window[k++];while(0!=--r);break}else if(0==(b&64))k+= +m[v+2],k+=q&x[b],v=3*(p+k),b=m[v];else return f.msg="invalid distance code",r=f.avail_in-t,r=n>>3>3:r,t+=r,l-=r,n-=r<<3,g.bitb=q,g.bitk=n,f.avail_in=t,f.total_in+=l-f.next_in_index,f.next_in_index=l,g.write=s,-3;while(1);break}if(0==(b&64)){if(k+=m[v+2],k+=q&x[b],v=3*(p+k),0==(b=m[v])){q>>=m[v+1];n-=m[v+1];g.window[s++]=m[v+2];w--;break}}else{if(0!=(b&32))return r=f.avail_in-t,r=n>>3>3:r,t+=r,l-=r,n-=r<<3,g.bitb=q,g.bitk=n,f.avail_in=t,f.total_in+=l-f.next_in_index,f.next_in_index=l,g.write= +s,1;f.msg="invalid literal/length code";r=f.avail_in-t;r=n>>3>3:r;t+=r;l-=r;n-=r<<3;g.bitb=q;g.bitk=n;f.avail_in=t;f.total_in+=l-f.next_in_index;f.next_in_index=l;g.write=s;return-3}}while(1)}}while(258<=w&&10<=t);r=f.avail_in-t;r=n>>3>3:r;l-=r;g.bitb=q;g.bitk=n-(r<<3);f.avail_in=t+r;f.total_in+=l-f.next_in_index;f.next_in_index=l;g.write=s;return 0};F.prototype.huft_build=function(a,b,c,d,h,e,g,f,k,m,p){var q,n,l,t,s,w,u,r,v;w=0;n=c;do this.c[a[b+w]]++,w++,n--;while(0!=n);if(this.c[0]== +c)return g[0]=-1,f[0]=0;s=f[0];for(l=1;15>=l&&0==this.c[l];l++);t=l;sn&&(s=n);f[0]=s;for(f=1<(f-=this.c[l]))return-3;if(0>(f-=this.c[n]))return-3;this.c[n]+=f;this.x[1]=l=0;w=1;for(u=2;0!=--n;)this.x[u]=l+=this.c[w],u++,w++;w=n=0;do 0!=(l=a[b+w])&&(this.v[this.x[l]++]=n),w++;while(++nr+s;){b++;r+=s;v=m-r;v=v>s?s:v;if((q=1<<(l= +t-r))>a+1&&(q-=a+1,u=t,l>>r-s,this.r[2]=u-this.u[b-1]-l,y(this.r,0,k,3*(this.u[b-1]+l),3)):g[0]=u}this.r[1]=t-r;w>=c?this.r[0]=192:p[w]this.v[w]?0:96,this.r[2]=this.v[w++]):(this.r[0]=e[this.v[w]-d]+16+64,this.r[2]=h[this.v[w++]-d]);q=1<>>r;l>>= +1)n^=l;n^=l;for(l=(1<b;b++)this.c[b]=0;for(b=0;3>b;b++)this.r[b]=0;y(this.c,0,this.u,0,15);y(this.c,0,this.x,0,16)};var W="function"===typeof(new Uint8Array(1)).subarray;L.prototype.toString=function(){return""+this.block+":"+this.offset};G.prototype.slice=function(a,b){var c;c=this.blob.slice?b?this.blob.slice(a,a+b):this.blob.slice(a): +b?this.blob.webkitSlice(a,a+b):this.blob.webkitSlice(a);return new G(c)};G.prototype.salted=function(){return this};G.prototype.fetch="undefined"!==typeof FileReader?function(a){var b=new FileReader;b.onloadend=function(c){a(O(b.result))};b.readAsBinaryString(this.blob)}:function(a){var b=new FileReaderSync;try{var c=b.readAsArrayBuffer(this.blob);a(c)}catch(d){a(null,d)}};B.prototype.slice=function(a,b){if(0>a)throw"Bad slice "+a;var c=this.start,d=this.end,c=c&&a?c+a:a||c;return new B(this.url, +c,b&&c?c+b-1:d||b-1,this.opts)};var T=0,U=0<=navigator.userAgent.indexOf("Safari")&&0>navigator.userAgent.indexOf("Chrome");B.prototype.fetchAsText=function(a){var b=this;this.getURL().then(function(c){try{var d=new XMLHttpRequest;(U||b.opts.salt)&&0>c.indexOf("?")&&(c=c+"?salt="+K(""+Date.now()+","+ ++T));d.open("GET",c,!0);if(b.end){if(1E8e.indexOf("?")&&(e=e+"?salt="+K(""+Date.now()+","+ ++T));f.open("GET",e,!0);f.overrideMimeType("text/plain; charset=x-user-defined");if(c.end){if(1E8m?g:a).push(new N(n,l));f+=16}else f+=16*p}e=u(d,f);h=null;b=Math.min(b>>14,e-1);c=Math.min(c>> +14,e-1);for(e=b;e<=c;++e)(b=H(d,f+4+8*e))&&(!h||b.block=h.block&&c.maxv.offset>=h.offset&&d.push(c);g=d;d=[];for(e=0;e=k.length)return d(p);if(n){var a=new Uint8Array(n),a=g.readBamRecords(a,k[q].minv.offset,p,b,c,f,h);n=null;++q;return a?d(p):e()}var m=k[q],a=m.minv.block;g.data.slice(a,m.maxv.block+65536-a).fetch(function(a){n=M(a,m.maxv.block-m.minv.block+1);return e()})}var g=this;h=h||{};var f=this.chrToIndex[a],k;if(void 0===f)k=[];else{if(null===this.indices[f]&&this.indexChunks.chunks[f]){var m=this.indexChunks.chunks[f];return this.bai.slice(m[0],m[1]).fetch(function(e){e= +new Uint8Array(e);this.indices[f]=e;return this.fetch(a,b,c,d,h)}.bind(this))}(k=this.blocksForRange(f,b,c))||d(null,"Error in index fetch")}var p=[],q=0,n;e()};var V="=ACxGxxxTxxxxxxN".split(""),ha="MIDNSHP=X???????".split("");I.prototype.readBamRecords=function(a,b,c,d,h,e,g){for(;;){var f=u(a,b),f=b+f+4;if(f>=a.length)return!1;var k=new Z,m=u(a,b+4),p=u(a,b+8),q=u(a,b+12),n=(q&65280)>>8,l=q&255,q=u(a,b+16),t=(q&4294901760)>>16,s=q&65535,q=u(a,b+20),w=u(a,b+24),x=u(a,b+28);u(a,b+32);k.segment=this.indexToChr[m]; +k.flag=t;k.pos=p;k.mq=n;g.light&&(k.seqLength=q);if(!g.light){0<=w&&(k.nextSegment=this.indexToChr[w],k.nextPos=x);n="";for(p=0;p>4)+ha[n&15],b+=4;k.cigar=l;s="";l=q+1>>1;for(p=0;p>4],s.length=d)void 0!==e&&m!=e||c.push(k);if(k.pos>h)return!0;b=f}};window.dallianceLib={URLFetchable:B,BlobFetchable:G,makeBam:function(a,b,c,d,h){a.slice(0,10).fetch(function(e){return e?R(a,b,c,d,h):d(null,"Couldn't access BAM.")},{timeout:5E3})}}})(); + + var $ = jQuery; // Make sure we have local $ (this is for combined script in a function) var Genoverse = Base.extend({ // Defaults @@ -5109,41 +5182,86 @@ Genoverse.Track.View.Transcript.Ensembl = Genoverse.Track.View.Transcript.extend }); Genoverse.Track.Model.File = Genoverse.Track.Model.extend({ - dataType : 'text' + dataType: 'text', + + init: function () { + if (this.isLocal) { + this.url = false; + } + + if (!this.largeFile) { + this.allData = true; + } + + this.base.apply(this, arguments); + }, + + getData: function () { + var model = this; + + if (this.isLocal && this.dataFile) { + var reader = new FileReader(); + var deferred = $.Deferred(); + + reader.onload = function (e) { + deferred.done(function () { + this.receiveData(e.target.result, 1, this.browser.chromosomeSize); + }).resolveWith(model); + }; + + reader.readAsText(this.dataFile); + + return deferred; + } else { + return this.base.apply(this, arguments); + } + } }); -Genoverse.Track.Model.File.GFF = Genoverse.Track.Model.File.extend({ - parseData: function (text) { - var lines = text.split('\n'); - - for (var i = 0; i < lines.length; i++) { - if (!lines[i].length || lines[i].indexOf('#') === 0) { - continue; - } - - var fields = lines[i].split('\t'); - if (fields.length < 5) { - continue; +Genoverse.Track.Model.File.BAM = Genoverse.Track.Model.File.extend({ + getData: function (start, end) { + var model = this; + var deferred = $.Deferred(); + + if (!this.bamFile) { + if (this.url) { + this.bamFile = new dallianceLib.URLFetchable(this.url); + this.baiFile = new dallianceLib.URLFetchable(this.url + this.prop('indexExt')); + } else if (this.dataFile && this.indexFile) { + this.bamFile = new dallianceLib.BlobFetchable(this.dataFile); + this.baiFile = new dallianceLib.BlobFetchable(this.indexFile); } - - if (fields[0] === this.browser.chr || fields[0].toLowerCase() === 'chr' + this.browser.chr || fields[0].match('[^1-9]' + this.browser.chr + '$')) { - this.insertFeature({ - id : fields.slice(0, 5).join('|'), - start : parseInt(fields[3], 10), - end : parseInt(fields[4], 10), - source : fields[1], - type : fields[2], - score : fields[5], - strand : fields[6] + '1', - label : fields[1] + ' ' + fields[2] + ' ' + fields[3] + '-' + fields[4] + } + + dallianceLib.makeBam(this.bamFile, this.baiFile, null, function (bam, makeBamError) { + if (makeBamError) { + console.log(makeBamError); + } else { + bam.fetch(model.browser.chr, start, end, function (features, fetchBamError) { + if (fetchBamError) { + console.log(fetchBamError); + } else { + model.receiveData(features, start, end); + deferred.resolveWith(model); + } }); } - } + }); + + return deferred; + }, + + insertFeature: function (feature) { + feature.id = feature.readName + ':' + feature.pos; + feature.start = feature.pos + 1; + feature.end = feature.start + feature.seq.length; + feature.sequence = feature.seq; + + return this.base(feature); } }); -Genoverse.Track.Model.File.GTF = Genoverse.Track.Model.File.GFF; Genoverse.Track.Model.File.BED = Genoverse.Track.Model.File.extend({ parseData: function (text) { @@ -5192,6 +5310,39 @@ Genoverse.Track.Model.File.BED = Genoverse.Track.Model.File.extend({ } }); +Genoverse.Track.Model.File.GFF = Genoverse.Track.Model.File.extend({ + parseData: function (text) { + var lines = text.split('\n'); + + for (var i = 0; i < lines.length; i++) { + if (!lines[i].length || lines[i].indexOf('#') === 0) { + continue; + } + + var fields = lines[i].split('\t'); + + if (fields.length < 5) { + continue; + } + + if (fields[0] === this.browser.chr || fields[0].toLowerCase() === 'chr' + this.browser.chr || fields[0].match('[^1-9]' + this.browser.chr + '$')) { + this.insertFeature({ + id : fields.slice(0, 5).join('|'), + start : parseInt(fields[3], 10), + end : parseInt(fields[4], 10), + source : fields[1], + type : fields[2], + score : fields[5], + strand : fields[6] + '1', + label : fields[1] + ' ' + fields[2] + ' ' + fields[3] + '-' + fields[4] + }); + } + } + } +}); + +Genoverse.Track.Model.File.GTF = Genoverse.Track.Model.File.GFF; + Genoverse.Track.Chromosome = Genoverse.Track.extend({ id : 'chromosome', margin : 1, @@ -5490,28 +5641,47 @@ Genoverse.Track.dbSNP = Genoverse.Track.extend({ Genoverse.Track.File = Genoverse.Track.extend({ setInterface: function () { this.base(); - this._interface.data = 'model'; + + this._interface.isLocal = 'model'; + this._interface.dataFile = 'model'; + this._interface.indexFile = 'model'; + this._interface.largeFile = 'model'; } }); -Genoverse.Track.File.GFF = Genoverse.Track.File.extend({ - name : 'GFF', - model : Genoverse.Track.Model.File.GFF, - bump : true, - height : 100, - featureHeight : 5 -}); +Genoverse.Track.File.BAM = Genoverse.Track.File.extend({ + name : 'BAM', + indexExt : '.bai', + threshold : 100000, + largeFile : true, + model : Genoverse.Track.Model.File.BAM, + view : Genoverse.Track.View.Sequence.extend({ + bump : true, + autoHeight : true + }), -Genoverse.Track.File.GTF = Genoverse.Track.File.GFF; + click: function () { + var menu = this.base.apply(this, arguments); -Genoverse.Track.File.GFF3 = Genoverse.Track.File.extend({ - name : 'GFF3', - model : Genoverse.Track.Model.Transcript.GFF3, - view : Genoverse.Track.View.Transcript, - bump : true + if (menu) { + menu.addClass('gv-wrap-values'); + } + + return menu; + }, + + populateMenu: function (feature) { + var f = $.extend({ title: feature.readName }, feature); + + delete f.sequence; + delete f.id; + + return this.base(f); + } }); + Genoverse.Track.File.BED = Genoverse.Track.File.extend({ name : 'BED', model : Genoverse.Track.Model.File.BED, @@ -5537,6 +5707,23 @@ Genoverse.Track.File.BED = Genoverse.Track.File.extend({ } }); +Genoverse.Track.File.GFF = Genoverse.Track.File.extend({ + name : 'GFF', + model : Genoverse.Track.Model.File.GFF, + bump : true, + height : 100, + featureHeight : 5 +}); + +Genoverse.Track.File.GTF = Genoverse.Track.File.GFF; + +Genoverse.Track.File.GFF3 = Genoverse.Track.File.extend({ + name : 'GFF3', + model : Genoverse.Track.Model.Transcript.GFF3, + view : Genoverse.Track.View.Transcript, + bump : true +}); + Genoverse.Track.File.VCF = Genoverse.Track.File.extend({ name : 'VCF', model : Genoverse.Track.Model.SequenceVariation.VCF, diff --git a/js/lib/FRegion.js b/js/lib/FRegion.js deleted file mode 100644 index 34b1ece2..00000000 --- a/js/lib/FRegion.js +++ /dev/null @@ -1,119 +0,0 @@ -var FRegion = function(features){ - var _features = new Array(); - var _featuresSortedByEnds = new Array(); - var _isSorted = false; - - if (features && typeof features == 'object') { - _features = features; - } - - this.insert = function (element) { - _features.push(element); - _isSorted = false; - } - - this.add = function (array) { - _features.concat(array); - _isSorted = false; - } - - this.sort = function (force) { - if (_isSorted && !force) return; - - _features.sort(function (a, b) { return a.start - b.start }); - - _features.every(function(element, index){ - element.index = index; - return true; - }) - - // Shallow copy of the features array, to be sorted by feature ends - _featuresSortedByEnds = _features.slice(); - _featuresSortedByEnds.sort(function (a, b) { return a.end - b.end }); - - _isSorted = true; - } - - this.bruteForceSearch = function (bounds) { - var features = new Array(); - var a = bounds.x; - var b = a + bounds.w; - - for (var i = 0; i < _features.length; i++) { - if (_features[i].start < b && _features[i].end > a) { - features.push(_features[i]); - } - } - return features; - } - - this.binarySearch = function (bounds) { - if (!_isSorted) this.sort(); - - var a = bounds.x; - var b = a + bounds.w; - - var iA = this.findFirstEndingAfterX(a); - var iB = this.findLastStartingBeforeX(b); - - if (_features[iA].start < b && _features[iA].end > a) { - return _features.slice(iA, iB + 1); - } else { - return []; - } - } - - /* search for nearest element to the left of x within indexes iStart, iEnd - */ - this.findLastStartingBeforeX = function (x, iStart, iEnd) { - if (!_isSorted) this.sort(); - - // Check last element - if (_featuresSortedByEnds[_featuresSortedByEnds.length-1].end < x) - return _featuresSortedByEnds[_featuresSortedByEnds.length-1].index; - - if (iStart === undefined) iStart = 0; - if (iEnd === undefined) iEnd = _features.length - 1; - var iMiddle = Math.floor((iEnd+iStart)/2); - - if (iStart == iMiddle) { - return iStart; - } else if (_features[iMiddle].start < x) { - return this.findLastStartingBeforeX(x, iMiddle, iEnd); - } else if (_features[iMiddle].start >= x) { - return this.findLastStartingBeforeX(x, iStart, iMiddle); - } - } - - this.findFirstEndingAfterX = function (x, iStart, iEnd) { - if (!_isSorted) this.sort(); - - // Check first element - if (_featuresSortedByEnds[0].end > x) - return _featuresSortedByEnds[0].index; - - if (iStart === undefined) iStart = 0; - if (iEnd === undefined) iEnd = _featuresSortedByEnds.length - 1; - var iMiddle = Math.ceil((iEnd+iStart)/2); - - if (iEnd == iMiddle) { - // Return real index (position) in the original array - return _featuresSortedByEnds[iEnd].index; - } else if (_featuresSortedByEnds[iMiddle].end < x) { - return this.findFirstEndingAfterX(x, iMiddle, iEnd); - } else if (_featuresSortedByEnds[iMiddle].end >= x) { - return this.findFirstEndingAfterX(x, iStart, iMiddle); - } - } - - this.search = function (bounds) { - if (!_features.length) return []; - - //return this.bruteForceSearch(bounds); - return this.binarySearch(bounds); - } - - this.getElement = function (i) { - return _features[i]; - } -} diff --git a/js/lib/dalliance-lib.js b/js/lib/dalliance-lib.js new file mode 100644 index 00000000..f24a4f36 --- /dev/null +++ b/js/lib/dalliance-lib.js @@ -0,0 +1,3955 @@ +(function () { + // Javascript ZLib + // By Thomas Down 2010-2011 + // + // Based very heavily on portions of jzlib (by ymnk@jcraft.com), who in + // turn credits Jean-loup Gailly and Mark Adler for the original zlib code. + // + // inflate.js: ZLib inflate code + // + // + // Shared constants + // + var MAX_WBITS = 15; // 32K LZ77 window + var DEF_WBITS = MAX_WBITS; + var MAX_MEM_LEVEL = 9; + var MANY = 1440; + var BMAX = 15; + + // preset dictionary flag in zlib header + var PRESET_DICT = 0x20; + + var Z_NO_FLUSH = 0; + var Z_PARTIAL_FLUSH = 1; + var Z_SYNC_FLUSH = 2; + var Z_FULL_FLUSH = 3; + var Z_FINISH = 4; + + var Z_DEFLATED = 8; + + var Z_OK = 0; + var Z_STREAM_END = 1; + var Z_NEED_DICT = 2; + var Z_ERRNO = -1; + var Z_STREAM_ERROR = -2; + var Z_DATA_ERROR = -3; + var Z_MEM_ERROR = -4; + var Z_BUF_ERROR = -5; + var Z_VERSION_ERROR = -6; + + var METHOD = 0; // waiting for method byte + var FLAG = 1; // waiting for flag byte + var DICT4 = 2; // four dictionary check bytes to go + var DICT3 = 3; // three dictionary check bytes to go + var DICT2 = 4; // two dictionary check bytes to go + var DICT1 = 5; // one dictionary check byte to go + var DICT0 = 6; // waiting for inflateSetDictionary + var BLOCKS = 7; // decompressing blocks + var CHECK4 = 8; // four check bytes to go + var CHECK3 = 9; // three check bytes to go + var CHECK2 = 10; // two check bytes to go + var CHECK1 = 11; // one check byte to go + var DONE = 12; // finished check, done + var BAD = 13; // got an error--stay here + + var inflate_mask = [0x00000000, 0x00000001, 0x00000003, 0x00000007, 0x0000000f, 0x0000001f, 0x0000003f, 0x0000007f, 0x000000ff, 0x000001ff, 0x000003ff, 0x000007ff, 0x00000fff, 0x00001fff, 0x00003fff, 0x00007fff, 0x0000ffff]; + + var IB_TYPE = 0; // get type bits (3, including end bit) + var IB_LENS = 1; // get lengths for stored + var IB_STORED = 2; // processing stored block + var IB_TABLE = 3; // get table lengths + var IB_BTREE = 4; // get bit lengths tree for a dynamic block + var IB_DTREE = 5; // get length, distance trees for a dynamic block + var IB_CODES = 6; // processing fixed or dynamic block + var IB_DRY = 7; // output remaining window bytes + var IB_DONE = 8; // finished last block, done + var IB_BAD = 9; // ot a data error--stuck here + + var fixed_bl = 9; + var fixed_bd = 5; + + var fixed_tl = [ + 96, 7, 256, 0, 8, 80, 0, 8, 16, 84, 8, 115, + 82, 7, 31, 0, 8, 112, 0, 8, 48, 0, 9, 192, + 80, 7, 10, 0, 8, 96, 0, 8, 32, 0, 9, 160, + 0, 8, 0, 0, 8, 128, 0, 8, 64, 0, 9, 224, + 80, 7, 6, 0, 8, 88, 0, 8, 24, 0, 9, 144, + 83, 7, 59, 0, 8, 120, 0, 8, 56, 0, 9, 208, + 81, 7, 17, 0, 8, 104, 0, 8, 40, 0, 9, 176, + 0, 8, 8, 0, 8, 136, 0, 8, 72, 0, 9, 240, + 80, 7, 4, 0, 8, 84, 0, 8, 20, 85, 8, 227, + 83, 7, 43, 0, 8, 116, 0, 8, 52, 0, 9, 200, + 81, 7, 13, 0, 8, 100, 0, 8, 36, 0, 9, 168, + 0, 8, 4, 0, 8, 132, 0, 8, 68, 0, 9, 232, + 80, 7, 8, 0, 8, 92, 0, 8, 28, 0, 9, 152, + 84, 7, 83, 0, 8, 124, 0, 8, 60, 0, 9, 216, + 82, 7, 23, 0, 8, 108, 0, 8, 44, 0, 9, 184, + 0, 8, 12, 0, 8, 140, 0, 8, 76, 0, 9, 248, + 80, 7, 3, 0, 8, 82, 0, 8, 18, 85, 8, 163, + 83, 7, 35, 0, 8, 114, 0, 8, 50, 0, 9, 196, + 81, 7, 11, 0, 8, 98, 0, 8, 34, 0, 9, 164, + 0, 8, 2, 0, 8, 130, 0, 8, 66, 0, 9, 228, + 80, 7, 7, 0, 8, 90, 0, 8, 26, 0, 9, 148, + 84, 7, 67, 0, 8, 122, 0, 8, 58, 0, 9, 212, + 82, 7, 19, 0, 8, 106, 0, 8, 42, 0, 9, 180, + 0, 8, 10, 0, 8, 138, 0, 8, 74, 0, 9, 244, + 80, 7, 5, 0, 8, 86, 0, 8, 22, 192, 8, 0, + 83, 7, 51, 0, 8, 118, 0, 8, 54, 0, 9, 204, + 81, 7, 15, 0, 8, 102, 0, 8, 38, 0, 9, 172, + 0, 8, 6, 0, 8, 134, 0, 8, 70, 0, 9, 236, + 80, 7, 9, 0, 8, 94, 0, 8, 30, 0, 9, 156, + 84, 7, 99, 0, 8, 126, 0, 8, 62, 0, 9, 220, + 82, 7, 27, 0, 8, 110, 0, 8, 46, 0, 9, 188, + 0, 8, 14, 0, 8, 142, 0, 8, 78, 0, 9, 252, + 96, 7, 256, 0, 8, 81, 0, 8, 17, 85, 8, 131, + 82, 7, 31, 0, 8, 113, 0, 8, 49, 0, 9, 194, + 80, 7, 10, 0, 8, 97, 0, 8, 33, 0, 9, 162, + 0, 8, 1, 0, 8, 129, 0, 8, 65, 0, 9, 226, + 80, 7, 6, 0, 8, 89, 0, 8, 25, 0, 9, 146, + 83, 7, 59, 0, 8, 121, 0, 8, 57, 0, 9, 210, + 81, 7, 17, 0, 8, 105, 0, 8, 41, 0, 9, 178, + 0, 8, 9, 0, 8, 137, 0, 8, 73, 0, 9, 242, + 80, 7, 4, 0, 8, 85, 0, 8, 21, 80, 8, 258, + 83, 7, 43, 0, 8, 117, 0, 8, 53, 0, 9, 202, + 81, 7, 13, 0, 8, 101, 0, 8, 37, 0, 9, 170, + 0, 8, 5, 0, 8, 133, 0, 8, 69, 0, 9, 234, + 80, 7, 8, 0, 8, 93, 0, 8, 29, 0, 9, 154, + 84, 7, 83, 0, 8, 125, 0, 8, 61, 0, 9, 218, + 82, 7, 23, 0, 8, 109, 0, 8, 45, 0, 9, 186, + 0, 8, 13, 0, 8, 141, 0, 8, 77, 0, 9, 250, + 80, 7, 3, 0, 8, 83, 0, 8, 19, 85, 8, 195, + 83, 7, 35, 0, 8, 115, 0, 8, 51, 0, 9, 198, + 81, 7, 11, 0, 8, 99, 0, 8, 35, 0, 9, 166, + 0, 8, 3, 0, 8, 131, 0, 8, 67, 0, 9, 230, + 80, 7, 7, 0, 8, 91, 0, 8, 27, 0, 9, 150, + 84, 7, 67, 0, 8, 123, 0, 8, 59, 0, 9, 214, + 82, 7, 19, 0, 8, 107, 0, 8, 43, 0, 9, 182, + 0, 8, 11, 0, 8, 139, 0, 8, 75, 0, 9, 246, + 80, 7, 5, 0, 8, 87, 0, 8, 23, 192, 8, 0, + 83, 7, 51, 0, 8, 119, 0, 8, 55, 0, 9, 206, + 81, 7, 15, 0, 8, 103, 0, 8, 39, 0, 9, 174, + 0, 8, 7, 0, 8, 135, 0, 8, 71, 0, 9, 238, + 80, 7, 9, 0, 8, 95, 0, 8, 31, 0, 9, 158, + 84, 7, 99, 0, 8, 127, 0, 8, 63, 0, 9, 222, + 82, 7, 27, 0, 8, 111, 0, 8, 47, 0, 9, 190, + 0, 8, 15, 0, 8, 143, 0, 8, 79, 0, 9, 254, + 96, 7, 256, 0, 8, 80, 0, 8, 16, 84, 8, 115, + 82, 7, 31, 0, 8, 112, 0, 8, 48, 0, 9, 193, + + 80, 7, 10, 0, 8, 96, 0, 8, 32, 0, 9, 161, + 0, 8, 0, 0, 8, 128, 0, 8, 64, 0, 9, 225, + 80, 7, 6, 0, 8, 88, 0, 8, 24, 0, 9, 145, + 83, 7, 59, 0, 8, 120, 0, 8, 56, 0, 9, 209, + 81, 7, 17, 0, 8, 104, 0, 8, 40, 0, 9, 177, + 0, 8, 8, 0, 8, 136, 0, 8, 72, 0, 9, 241, + 80, 7, 4, 0, 8, 84, 0, 8, 20, 85, 8, 227, + 83, 7, 43, 0, 8, 116, 0, 8, 52, 0, 9, 201, + 81, 7, 13, 0, 8, 100, 0, 8, 36, 0, 9, 169, + 0, 8, 4, 0, 8, 132, 0, 8, 68, 0, 9, 233, + 80, 7, 8, 0, 8, 92, 0, 8, 28, 0, 9, 153, + 84, 7, 83, 0, 8, 124, 0, 8, 60, 0, 9, 217, + 82, 7, 23, 0, 8, 108, 0, 8, 44, 0, 9, 185, + 0, 8, 12, 0, 8, 140, 0, 8, 76, 0, 9, 249, + 80, 7, 3, 0, 8, 82, 0, 8, 18, 85, 8, 163, + 83, 7, 35, 0, 8, 114, 0, 8, 50, 0, 9, 197, + 81, 7, 11, 0, 8, 98, 0, 8, 34, 0, 9, 165, + 0, 8, 2, 0, 8, 130, 0, 8, 66, 0, 9, 229, + 80, 7, 7, 0, 8, 90, 0, 8, 26, 0, 9, 149, + 84, 7, 67, 0, 8, 122, 0, 8, 58, 0, 9, 213, + 82, 7, 19, 0, 8, 106, 0, 8, 42, 0, 9, 181, + 0, 8, 10, 0, 8, 138, 0, 8, 74, 0, 9, 245, + 80, 7, 5, 0, 8, 86, 0, 8, 22, 192, 8, 0, + 83, 7, 51, 0, 8, 118, 0, 8, 54, 0, 9, 205, + 81, 7, 15, 0, 8, 102, 0, 8, 38, 0, 9, 173, + 0, 8, 6, 0, 8, 134, 0, 8, 70, 0, 9, 237, + 80, 7, 9, 0, 8, 94, 0, 8, 30, 0, 9, 157, + 84, 7, 99, 0, 8, 126, 0, 8, 62, 0, 9, 221, + 82, 7, 27, 0, 8, 110, 0, 8, 46, 0, 9, 189, + 0, 8, 14, 0, 8, 142, 0, 8, 78, 0, 9, 253, + 96, 7, 256, 0, 8, 81, 0, 8, 17, 85, 8, 131, + 82, 7, 31, 0, 8, 113, 0, 8, 49, 0, 9, 195, + 80, 7, 10, 0, 8, 97, 0, 8, 33, 0, 9, 163, + 0, 8, 1, 0, 8, 129, 0, 8, 65, 0, 9, 227, + 80, 7, 6, 0, 8, 89, 0, 8, 25, 0, 9, 147, + 83, 7, 59, 0, 8, 121, 0, 8, 57, 0, 9, 211, + 81, 7, 17, 0, 8, 105, 0, 8, 41, 0, 9, 179, + 0, 8, 9, 0, 8, 137, 0, 8, 73, 0, 9, 243, + 80, 7, 4, 0, 8, 85, 0, 8, 21, 80, 8, 258, + 83, 7, 43, 0, 8, 117, 0, 8, 53, 0, 9, 203, + 81, 7, 13, 0, 8, 101, 0, 8, 37, 0, 9, 171, + 0, 8, 5, 0, 8, 133, 0, 8, 69, 0, 9, 235, + 80, 7, 8, 0, 8, 93, 0, 8, 29, 0, 9, 155, + 84, 7, 83, 0, 8, 125, 0, 8, 61, 0, 9, 219, + 82, 7, 23, 0, 8, 109, 0, 8, 45, 0, 9, 187, + 0, 8, 13, 0, 8, 141, 0, 8, 77, 0, 9, 251, + 80, 7, 3, 0, 8, 83, 0, 8, 19, 85, 8, 195, + 83, 7, 35, 0, 8, 115, 0, 8, 51, 0, 9, 199, + 81, 7, 11, 0, 8, 99, 0, 8, 35, 0, 9, 167, + 0, 8, 3, 0, 8, 131, 0, 8, 67, 0, 9, 231, + 80, 7, 7, 0, 8, 91, 0, 8, 27, 0, 9, 151, + 84, 7, 67, 0, 8, 123, 0, 8, 59, 0, 9, 215, + 82, 7, 19, 0, 8, 107, 0, 8, 43, 0, 9, 183, + 0, 8, 11, 0, 8, 139, 0, 8, 75, 0, 9, 247, + 80, 7, 5, 0, 8, 87, 0, 8, 23, 192, 8, 0, + 83, 7, 51, 0, 8, 119, 0, 8, 55, 0, 9, 207, + 81, 7, 15, 0, 8, 103, 0, 8, 39, 0, 9, 175, + 0, 8, 7, 0, 8, 135, 0, 8, 71, 0, 9, 239, + 80, 7, 9, 0, 8, 95, 0, 8, 31, 0, 9, 159, + 84, 7, 99, 0, 8, 127, 0, 8, 63, 0, 9, 223, + 82, 7, 27, 0, 8, 111, 0, 8, 47, 0, 9, 191, + 0, 8, 15, 0, 8, 143, 0, 8, 79, 0, 9, 255 + ]; + var fixed_td = [ + 80, 5, 1, 87, 5, 257, 83, 5, 17, 91, 5, 4097, + 81, 5, 5, 89, 5, 1025, 85, 5, 65, 93, 5, 16385, + 80, 5, 3, 88, 5, 513, 84, 5, 33, 92, 5, 8193, + 82, 5, 9, 90, 5, 2049, 86, 5, 129, 192, 5, 24577, + 80, 5, 2, 87, 5, 385, 83, 5, 25, 91, 5, 6145, + 81, 5, 7, 89, 5, 1537, 85, 5, 97, 93, 5, 24577, + 80, 5, 4, 88, 5, 769, 84, 5, 49, 92, 5, 12289, + 82, 5, 13, 90, 5, 3073, 86, 5, 193, 192, 5, 24577 + ]; + + // Tables for deflate from PKZIP's appnote.txt. + var cplens = [ // Copy lengths for literal codes 257..285 + 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, + 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0 + ]; + + // see note #13 above about 258 + var cplext = [ // Extra bits for literal codes 257..285 + 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, + 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 112, 112 // 112==invalid + ]; + + var cpdist = [ // Copy offsets for distance codes 0..29 + 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, + 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, + 8193, 12289, 16385, 24577 + ]; + + var cpdext = [ // Extra bits for distance codes + 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, + 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, + 12, 12, 13, 13 + ]; + + // + // ZStream.java + // + + function ZStream() {} + + ZStream.prototype.inflateInit = function(w, nowrap) { + if (!w) { + w = DEF_WBITS; + } + + if (nowrap) { + nowrap = false; + } + + this.istate = new Inflate(); + + return this.istate.inflateInit(this, nowrap ? -w : w); + }; + + ZStream.prototype.inflate = function(f) { + if (this.istate == null) { + return Z_STREAM_ERROR; + } + + return this.istate.inflate(this, f); + }; + + ZStream.prototype.inflateEnd = function() { + if (this.istate == null) { + return Z_STREAM_ERROR; + } + + var ret = istate.inflateEnd(this); + this.istate = null; + return ret; + }; + + ZStream.prototype.inflateSync = function() { + // if(istate == null) return Z_STREAM_ERROR; + return istate.inflateSync(this); + }; + + ZStream.prototype.inflateSetDictionary = function(dictionary, dictLength) { + // if(istate == null) return Z_STREAM_ERROR; + return istate.inflateSetDictionary(this, dictionary, dictLength); + }; + + /* + + public int deflateInit(int level){ + return deflateInit(level, MAX_WBITS); + } + public int deflateInit(int level, boolean nowrap){ + return deflateInit(level, MAX_WBITS, nowrap); + } + public int deflateInit(int level, int bits){ + return deflateInit(level, bits, false); + } + public int deflateInit(int level, int bits, boolean nowrap){ + dstate=new Deflate(); + return dstate.deflateInit(this, level, nowrap?-bits:bits); + } + public int deflate(int flush){ + if(dstate==null){ + return Z_STREAM_ERROR; + } + return dstate.deflate(this, flush); + } + public int deflateEnd(){ + if(dstate==null) return Z_STREAM_ERROR; + int ret=dstate.deflateEnd(); + dstate=null; + return ret; + } + public int deflateParams(int level, int strategy){ + if(dstate==null) return Z_STREAM_ERROR; + return dstate.deflateParams(this, level, strategy); + } + public int deflateSetDictionary (byte[] dictionary, int dictLength){ + if(dstate == null) + return Z_STREAM_ERROR; + return dstate.deflateSetDictionary(this, dictionary, dictLength); + } + + */ + + /* + // Flush as much pending output as possible. All deflate() output goes + // through this function so some applications may wish to modify it + // to avoid allocating a large strm->next_out buffer and copying into it. + // (See also read_buf()). + void flush_pending(){ + int len=dstate.pending; + + if(len>avail_out) len=avail_out; + if(len==0) return; + + if(dstate.pending_buf.length<=dstate.pending_out || + next_out.length<=next_out_index || + dstate.pending_buf.length<(dstate.pending_out+len) || + next_out.length<(next_out_index+len)){ + System.out.println(dstate.pending_buf.length+", "+dstate.pending_out+ + ", "+next_out.length+", "+next_out_index+", "+len); + System.out.println("avail_out="+avail_out); + } + + System.arraycopy(dstate.pending_buf, dstate.pending_out, + next_out, next_out_index, len); + + next_out_index+=len; + dstate.pending_out+=len; + total_out+=len; + avail_out-=len; + dstate.pending-=len; + if(dstate.pending==0){ + dstate.pending_out=0; + } + } + + // Read a new buffer from the current input stream, update the adler32 + // and total number of bytes read. All deflate() input goes through + // this function so some applications may wish to modify it to avoid + // allocating a large strm->next_in buffer and copying from it. + // (See also flush_pending()). + int read_buf(byte[] buf, int start, int size) { + int len=avail_in; + + if(len>size) len=size; + if(len==0) return 0; + + avail_in-=len; + + if(dstate.noheader==0) { + adler=_adler.adler32(adler, next_in, next_in_index, len); + } + System.arraycopy(next_in, next_in_index, buf, start, len); + next_in_index += len; + total_in += len; + return len; + } + + public void free(){ + next_in=null; + next_out=null; + msg=null; + _adler=null; + } + } + */ + + + // + // Inflate.java + // + + function Inflate() { + this.was = [0]; + } + + Inflate.prototype.inflateReset = function(z) { + if (z == null || z.istate == null) { + return Z_STREAM_ERROR; + } + + z.total_in = z.total_out = 0; + z.msg = null; + z.istate.mode = z.istate.nowrap != 0 ? BLOCKS : METHOD; + z.istate.blocks.reset(z, null); + return Z_OK; + }; + + Inflate.prototype.inflateEnd = function(z) { + if (this.blocks != null) { + this.blocks.free(z); + } + + this.blocks = null; + return Z_OK; + }; + + Inflate.prototype.inflateInit = function(z, w) { + z.msg = null; + this.blocks = null; + + // handle undocumented nowrap option (no zlib header or check) + nowrap = 0; + + if (w < 0) { + w = -w; + nowrap = 1; + } + + // set window size + if (w < 8 || w > 15) { + this.inflateEnd(z); + return Z_STREAM_ERROR; + } + + this.wbits = w; + + z.istate.blocks = new InfBlocks(z, z.istate.nowrap != 0 ? null : this, 1 << w); + + // reset state + this.inflateReset(z); + return Z_OK; + }; + + Inflate.prototype.inflate = function(z, f) { + var r, b; + + if (z == null || z.istate == null || z.next_in == null) { + return Z_STREAM_ERROR; + } + + f = f == Z_FINISH ? Z_BUF_ERROR : Z_OK; + r = Z_BUF_ERROR; + + while (true) { + switch (z.istate.mode) { + case METHOD: + + if (z.avail_in == 0) { + return r; + } + + r = f; + + z.avail_in--; + z.total_in++; + + if (((z.istate.method = z.next_in[z.next_in_index++]) & 0xf) != Z_DEFLATED) { + z.istate.mode = BAD; + z.msg = "unknown compression method"; + z.istate.marker = 5; // can't try inflateSync + break; + } + + if ((z.istate.method >> 4) + 8 > z.istate.wbits) { + z.istate.mode = BAD; + z.msg = "invalid window size"; + z.istate.marker = 5; // can't try inflateSync + break; + } + + z.istate.mode = FLAG; + case FLAG: + if (z.avail_in == 0) { + return r; + } + + r = f; + + z.avail_in--; + z.total_in++; + b = (z.next_in[z.next_in_index++]) & 0xff; + + if ((((z.istate.method << 8) + b) % 31) != 0) { + z.istate.mode = BAD; + z.msg = "incorrect header check"; + z.istate.marker = 5; // can't try inflateSync + break; + } + + if ((b & PRESET_DICT) == 0) { + z.istate.mode = BLOCKS; + break; + } + + z.istate.mode = DICT4; + case DICT4: + if (z.avail_in == 0) { + return r; + } + + r = f; + + z.avail_in--; + z.total_in++; + z.istate.need = ((z.next_in[z.next_in_index++] & 0xff) << 24) & 0xff000000; + z.istate.mode = DICT3; + case DICT3: + if (z.avail_in == 0) { + return r; + } + + r = f; + + z.avail_in--; + z.total_in++; + z.istate.need += ((z.next_in[z.next_in_index++] & 0xff) << 16) & 0xff0000; + z.istate.mode = DICT2; + case DICT2: + if (z.avail_in == 0) { + return r; + } + + r = f; + + z.avail_in--; + z.total_in++; + z.istate.need += ((z.next_in[z.next_in_index++] & 0xff) << 8) & 0xff00; + z.istate.mode = DICT1; + case DICT1: + if (z.avail_in == 0) { + return r; + } + + r = f; + + z.avail_in--; + z.total_in++; + z.istate.need += (z.next_in[z.next_in_index++] & 0xff); + z.adler = z.istate.need; + z.istate.mode = DICT0; + return Z_NEED_DICT; + case DICT0: + z.istate.mode = BAD; + z.msg = "need dictionary"; + z.istate.marker = 0; // can try inflateSync + return Z_STREAM_ERROR; + case BLOCKS: + r = z.istate.blocks.proc(z, r); + + if (r == Z_DATA_ERROR) { + z.istate.mode = BAD; + z.istate.marker = 0; // can try inflateSync + break; + } + + if (r == Z_OK) { + r = f; + } + + if (r != Z_STREAM_END) { + return r; + } + + r = f; + z.istate.blocks.reset(z, z.istate.was); + + if (z.istate.nowrap != 0) { + z.istate.mode = DONE; + break; + } + + z.istate.mode = CHECK4; + case CHECK4: + if (z.avail_in == 0) { + return r; + } + + r = f; + + z.avail_in--; + z.total_in++; + z.istate.need = ((z.next_in[z.next_in_index++] & 0xff) << 24) & 0xff000000; + z.istate.mode = CHECK3; + case CHECK3: + if (z.avail_in == 0) { + return r; + } + + r = f; + + z.avail_in--; + z.total_in++; + z.istate.need += ((z.next_in[z.next_in_index++] & 0xff) << 16) & 0xff0000; + z.istate.mode = CHECK2; + case CHECK2: + if (z.avail_in == 0) { + return r; + } + + r = f; + + z.avail_in--; + z.total_in++; + z.istate.need += ((z.next_in[z.next_in_index++] & 0xff) << 8) & 0xff00; + z.istate.mode = CHECK1; + case CHECK1: + if (z.avail_in == 0) { + return r; + } + + r = f; + + z.avail_in--; + z.total_in++; + z.istate.need += (z.next_in[z.next_in_index++] & 0xff); + + if (((z.istate.was[0])) != ((z.istate.need))) { + z.istate.mode = BAD; + z.msg = "incorrect data check"; + z.istate.marker = 5; // can't try inflateSync + break; + } + + z.istate.mode = DONE; + case DONE: + return Z_STREAM_END; + case BAD: + return Z_DATA_ERROR; + default: + return Z_STREAM_ERROR; + } + } + }; + + Inflate.prototype.inflateSetDictionary = function(z, dictionary, dictLength) { + var index = 0; + var length = dictLength; + + if (z == null || z.istate == null || z.istate.mode != DICT0) { + return Z_STREAM_ERROR; + } + + if (z._adler.adler32(1, dictionary, 0, dictLength) != z.adler) { + return Z_DATA_ERROR; + } + + z.adler = z._adler.adler32(0, null, 0, 0); + + if (length >= (1 << z.istate.wbits)) { + length = (1 << z.istate.wbits) - 1; + index = dictLength - length; + } + + z.istate.blocks.set_dictionary(dictionary, index, length); + z.istate.mode = BLOCKS; + return Z_OK; + }; + + // static private byte[] mark = {(byte)0, (byte)0, (byte)0xff, (byte)0xff}; + var mark = [0, 0, 255, 255]; + + Inflate.prototype.inflateSync = function(z) { + var n; // number of bytes to look at + var p; // pointer to bytes + var m; // number of marker bytes found in a row + var r, w; // temporaries to save total_in and total_out + + // set up + if (z == null || z.istate == null) { + return Z_STREAM_ERROR; + } + + if (z.istate.mode != BAD) { + z.istate.mode = BAD; + z.istate.marker = 0; + } + + if ((n = z.avail_in) == 0) { + return Z_BUF_ERROR; + } + + p = z.next_in_index; + m = z.istate.marker; + + // search + while (n != 0 && m < 4) { + if (z.next_in[p] == mark[m]) { + m++; + } else if (z.next_in[p] != 0) { + m = 0; + } else { + m = 4 - m; + } + + p++; + n--; + } + + // restore + z.total_in += p - z.next_in_index; + z.next_in_index = p; + z.avail_in = n; + z.istate.marker = m; + + // return no joy or set up to restart on a new block + if (m != 4) { + return Z_DATA_ERROR; + } + + r = z.total_in; + w = z.total_out; + this.inflateReset(z); + z.total_in = r; + z.total_out = w; + z.istate.mode = BLOCKS; + return Z_OK; + }; + + // Returns true if inflate is currently at the end of a block generated + // by Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP + // implementation to provide an additional safety check. PPP uses Z_SYNC_FLUSH + // but removes the length bytes of the resulting empty stored block. When + // decompressing, PPP checks that at the end of input packet, inflate is + // waiting for these length bytes. + Inflate.prototype.inflateSyncPoint = function(z) { + if (z == null || z.istate == null || z.istate.blocks == null) { + return Z_STREAM_ERROR; + } + + return z.istate.blocks.sync_point(); + }; + + + // + // InfBlocks.java + // + + var INFBLOCKS_BORDER = [16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15]; + + function InfBlocks(z, checkfn, w) { + this.hufts = new Int32Array(MANY * 3); + this.window = new Uint8Array(w); + this.end = w; + this.checkfn = checkfn; + this.mode = IB_TYPE; + this.reset(z, null); + + this.left = 0; // if STORED, bytes left to copy + + this.table = 0; // table lengths (14 bits) + this.index = 0; // index into blens (or border) + this.blens = null; // bit lengths of codes + this.bb = new Int32Array(1); // bit length tree depth + this.tb = new Int32Array(1); // bit length decoding tree + + this.codes = new InfCodes(); + + this.last = 0; // true if this block is the last block + + // mode independent information + this.bitk = 0; // bits in bit buffer + this.bitb = 0; // bit buffer + this.read = 0; // window read pointer + this.write = 0; // window write pointer + this.check = 0; // check on output + + this.inftree = new InfTree(); + } + + InfBlocks.prototype.reset = function(z, c) { + if (c) { + c[0] = this.check; + } + + if (this.mode == IB_CODES) { + this.codes.free(z); + } + + this.mode = IB_TYPE; + this.bitk = 0; + this.bitb = 0; + this.read = this.write = 0; + + if (this.checkfn) { + z.adler = this.check = z._adler.adler32(0, null, 0, 0); + } + }; + + InfBlocks.prototype.proc = function(z, r) { + var t; // temporary storage + var b; // bit buffer + var k; // bits in bit buffer + var p; // input data pointer + var n; // bytes available there + var q; // output window write pointer + var m; // bytes to end of window or read pointer + + // copy input/output information to locals (UPDATE macro restores) + { + p = z.next_in_index; + n = z.avail_in; + b = this.bitb; + k = this.bitk; + } { + q = this.write; + m = (q < this.read ? this.read - q - 1 : this.end - q); + } + + // process input based on current state + while (true) { + switch (this.mode) { + case IB_TYPE: + while (k < (3)) { + if (n != 0) { + r = Z_OK; + } else { + this.bitb = b; + this.bitk = k; + z.avail_in = n; + z.total_in += p - z.next_in_index; + z.next_in_index = p; + this.write = q; + return this.inflate_flush(z, r); + } + + n--; + b |= (z.next_in[p++] & 0xff) << k; + k += 8; + } + + t = (b & 7); + this.last = t & 1; + + switch (t >>> 1) { + case 0: // stored + { + b >>>= (3); + k -= (3); + } + + t = k & 7; // go to byte boundary + + { + b >>>= (t); + k -= (t); + } + + this.mode = IB_LENS; // get length of stored block + break; + case 1: // fixed + { + var bl = new Int32Array(1); + var bd = new Int32Array(1); + var tl = []; + var td = []; + + inflate_trees_fixed(bl, bd, tl, td, z); + this.codes.init(bl[0], bd[0], tl[0], 0, td[0], 0, z); + } + + { + b >>>= (3); + k -= (3); + } + + this.mode = IB_CODES; + break; + case 2: // dynamic + { + b >>>= (3);k -= (3); + } + + this.mode = IB_TABLE; + break; + case 3: // illegal + { + b >>>= (3);k -= (3); + } + + this.mode = BAD; + z.msg = "invalid block type"; + r = Z_DATA_ERROR; + + this.bitb = b; + this.bitk = k; + z.avail_in = n; + z.total_in += p - z.next_in_index; + z.next_in_index = p; + this.write = q; + return this.inflate_flush(z, r); + } + + break; + case IB_LENS: + while (k < (32)) { + if (n != 0) { + r = Z_OK; + } else { + this.bitb = b; + this.bitk = k; + z.avail_in = n; + z.total_in += p - z.next_in_index; + z.next_in_index = p; + this.write = q; + return this.inflate_flush(z, r); + } + + n--; + b |= (z.next_in[p++] & 0xff) << k; + k += 8; + } + + if ((((~b) >>> 16) & 0xffff) != (b & 0xffff)) { + this.mode = BAD; + z.msg = "invalid stored block lengths"; + r = Z_DATA_ERROR; + + this.bitb = b; + this.bitk = k; + z.avail_in = n; + z.total_in += p - z.next_in_index; + z.next_in_index = p; + this.write = q; + return this.inflate_flush(z, r); + } + + this.left = (b & 0xffff); + b = k = 0; // dump bits + this.mode = this.left != 0 ? IB_STORED : (this.last != 0 ? IB_DRY : IB_TYPE); + break; + case IB_STORED: + if (n == 0) { + this.bitb = b; + this.bitk = k; + z.avail_in = n; + z.total_in += p - z.next_in_index; + z.next_in_index = p; + write = q; + return this.inflate_flush(z, r); + } + + if (m == 0) { + if (q == end && read != 0) { + q = 0; + m = (q < this.read ? this.read - q - 1 : this.end - q); + } + + if (m == 0) { + this.write = q; + r = this.inflate_flush(z, r); + q = this.write; + m = (q < this.read ? this.read - q - 1 : this.end - q); + + if (q == this.end && this.read != 0) { + q = 0; + m = (q < this.read ? this.read - q - 1 : this.end - q); + } + + if (m == 0) { + this.bitb = b; + this.bitk = k; + z.avail_in = n; + z.total_in += p - z.next_in_index; + z.next_in_index = p; + this.write = q; + return this.inflate_flush(z, r); + } + } + } + + r = Z_OK; + + t = this.left; + + if (t > n) { + t = n; + } + + if (t > m) { + t = m; + } + + arrayCopy(z.next_in, p, this.window, q, t); + p += t; + n -= t; + q += t; + m -= t; + + if ((this.left -= t) != 0) { + break; + } + + this.mode = (this.last != 0 ? IB_DRY : IB_TYPE); + break; + case IB_TABLE: + while (k < (14)) { + if (n != 0) { + r = Z_OK; + } else { + this.bitb = b; + this.bitk = k; + z.avail_in = n; + z.total_in += p - z.next_in_index; + z.next_in_index = p; + this.write = q; + return this.inflate_flush(z, r); + } + + n--; + b |= (z.next_in[p++] & 0xff) << k; + k += 8; + } + + this.table = t = (b & 0x3fff); + + if ((t & 0x1f) > 29 || ((t >> 5) & 0x1f) > 29) { + this.mode = IB_BAD; + z.msg = "too many length or distance symbols"; + r = Z_DATA_ERROR; + + this.bitb = b; + this.bitk = k; + z.avail_in = n; + z.total_in += p - z.next_in_index; + z.next_in_index = p; + this.write = q; + return this.inflate_flush(z, r); + } + + t = 258 + (t & 0x1f) + ((t >> 5) & 0x1f); + + if (this.blens == null || this.blens.length < t) { + this.blens = new Int32Array(t); + } else { + for (var i = 0; i < t; i++) { + this.blens[i] = 0; + } + } + + { + b >>>= (14); + k -= (14); + } + + this.index = 0; + mode = IB_BTREE; + case IB_BTREE: + while (this.index < 4 + (this.table >>> 10)) { + while (k < (3)) { + if (n != 0) { + r = Z_OK; + } else { + this.bitb = b; + this.bitk = k; + z.avail_in = n; + z.total_in += p - z.next_in_index; + z.next_in_index = p; + this.write = q; + return this.inflate_flush(z, r); + } + + n--; + b |= (z.next_in[p++] & 0xff) << k; + k += 8; + } + + this.blens[INFBLOCKS_BORDER[this.index++]] = b & 7; + + { + b >>>= (3); + k -= (3); + } + } + + while (this.index < 19) { + this.blens[INFBLOCKS_BORDER[this.index++]] = 0; + } + + this.bb[0] = 7; + t = this.inftree.inflate_trees_bits(this.blens, this.bb, this.tb, this.hufts, z); + + if (t != Z_OK) { + r = t; + + if (r == Z_DATA_ERROR) { + this.blens = null; + this.mode = IB_BAD; + } + + this.bitb = b; + this.bitk = k; + z.avail_in = n; + z.total_in += p - z.next_in_index; + z.next_in_index = p; + write = q; + return this.inflate_flush(z, r); + } + + this.index = 0; + this.mode = IB_DTREE; + case IB_DTREE: + while (true) { + t = this.table; + + if (!(this.index < 258 + (t & 0x1f) + ((t >> 5) & 0x1f))) { + break; + } + + var h; //int[] + var i, j, c; + + t = this.bb[0]; + + while (k < (t)) { + if (n != 0) { + r = Z_OK; + } else { + this.bitb = b; + this.bitk = k; + z.avail_in = n; + z.total_in += p - z.next_in_index; + z.next_in_index = p; + this.write = q; + return this.inflate_flush(z, r); + } + + n--; + b |= (z.next_in[p++] & 0xff) << k; + k += 8; + } + + // if (this.tb[0]==-1){ + // dlog("null..."); + // } + + t = this.hufts[(this.tb[0] + (b & inflate_mask[t])) * 3 + 1]; + c = this.hufts[(this.tb[0] + (b & inflate_mask[t])) * 3 + 2]; + + if (c < 16) { + b >>>= (t); + k -= (t); + this.blens[this.index++] = c; + } else { // c == 16..18 + i = c == 18 ? 7 : c - 14; + j = c == 18 ? 11 : 3; + + while (k < (t + i)) { + if (n != 0) { + r = Z_OK; + } else { + this.bitb = b; + this.bitk = k; + z.avail_in = n; + z.total_in += p - z.next_in_index; + z.next_in_index = p; + this.write = q; + return this.inflate_flush(z, r); + } + + n--; + b |= (z.next_in[p++] & 0xff) << k; + k += 8; + } + + b >>>= (t); + k -= (t); + + j += (b & inflate_mask[i]); + + b >>>= (i); + k -= (i); + + i = this.index; + t = this.table; + + if (i + j > 258 + (t & 0x1f) + ((t >> 5) & 0x1f) || (c == 16 && i < 1)) { + this.blens = null; + this.mode = IB_BAD; + z.msg = "invalid bit length repeat"; + r = Z_DATA_ERROR; + + this.bitb = b; + this.bitk = k; + z.avail_in = n; + z.total_in += p - z.next_in_index; + z.next_in_index = p; + this.write = q; + return this.inflate_flush(z, r); + } + + c = c == 16 ? this.blens[i - 1] : 0; + + do { + this.blens[i++] = c; + } while (--j != 0); + + this.index = i; + } + } + + this.tb[0] = -1; + + { + var bl = new Int32Array(1); + var bd = new Int32Array(1); + var tl = new Int32Array(1); + var td = new Int32Array(1); + bl[0] = 9; // must be <= 9 for lookahead assumptions + bd[0] = 6; // must be <= 9 for lookahead assumptions + + t = this.table; + t = this.inftree.inflate_trees_dynamic(257 + (t & 0x1f), 1 + ((t >> 5) & 0x1f), this.blens, bl, bd, tl, td, this.hufts, z); + + if (t != Z_OK) { + if (t == Z_DATA_ERROR) { + this.blens = null; + this.mode = BAD; + } + + r = t; + + this.bitb = b; + this.bitk = k; + z.avail_in = n; + z.total_in += p - z.next_in_index; + z.next_in_index = p; + this.write = q; + return this.inflate_flush(z, r); + } + this.codes.init(bl[0], bd[0], this.hufts, tl[0], this.hufts, td[0], z); + } + + this.mode = IB_CODES; + case IB_CODES: + this.bitb = b; + this.bitk = k; + z.avail_in = n; + z.total_in += p - z.next_in_index; + z.next_in_index = p; + this.write = q; + + if ((r = this.codes.proc(this, z, r)) != Z_STREAM_END) { + return this.inflate_flush(z, r); + } + + r = Z_OK; + this.codes.free(z); + + p = z.next_in_index; + n = z.avail_in; + b = this.bitb; + k = this.bitk; + q = this.write; + m = (q < this.read ? this.read - q - 1 : this.end - q); + + if (this.last == 0) { + this.mode = IB_TYPE; + break; + } + + this.mode = IB_DRY; + case IB_DRY: + this.write = q; + r = this.inflate_flush(z, r); + q = this.write; + m = (q < this.read ? this.read - q - 1 : this.end - q); + + if (this.read != this.write) { + this.bitb = b; + this.bitk = k; + z.avail_in = n; + z.total_in += p - z.next_in_index; + z.next_in_index = p; + this.write = q; + return this.inflate_flush(z, r); + } + + mode = DONE; + case IB_DONE: + r = Z_STREAM_END; + + this.bitb = b; + this.bitk = k; + z.avail_in = n; + z.total_in += p - z.next_in_index; + z.next_in_index = p; + this.write = q; + return this.inflate_flush(z, r); + case IB_BAD: + r = Z_DATA_ERROR; + + this.bitb = b; + this.bitk = k; + z.avail_in = n; + z.total_in += p - z.next_in_index; + z.next_in_index = p; + this.write = q; + return this.inflate_flush(z, r); + default: + r = Z_STREAM_ERROR; + + this.bitb = b; + this.bitk = k; + z.avail_in = n; + z.total_in += p - z.next_in_index; + z.next_in_index = p; + this.write = q; + return this.inflate_flush(z, r); + } + } + }; + + InfBlocks.prototype.free = function(z) { + this.reset(z, null); + this.window = null; + this.hufts = null; + }; + + InfBlocks.prototype.set_dictionary = function(d, start, n) { + arrayCopy(d, start, window, 0, n); + this.read = this.write = n; + }; + + // Returns true if inflate is currently at the end of a block generated + // by Z_SYNC_FLUSH or Z_FULL_FLUSH. + InfBlocks.prototype.sync_point = function() { + return this.mode == IB_LENS; + }; + + // copy as much as possible from the sliding window to the output area + InfBlocks.prototype.inflate_flush = function(z, r) { + var n; + var p; + var q; + + // local copies of source and destination pointers + p = z.next_out_index; + q = this.read; + + // compute number of bytes to copy as far as end of window + n = ((q <= this.write ? this.write : this.end) - q); + + if (n > z.avail_out) { + n = z.avail_out; + } + + if (n != 0 && r == Z_BUF_ERROR) { + r = Z_OK; + } + + // update counters + z.avail_out -= n; + z.total_out += n; + + // update check information + if (this.checkfn != null) { + z.adler = this.check = z._adler.adler32(this.check, this.window, q, n); + } + + // copy as far as end of window + arrayCopy(this.window, q, z.next_out, p, n); + p += n; + q += n; + + // see if more to copy at beginning of window + if (q == this.end) { + // wrap pointers + q = 0; + + if (this.write == this.end) { + this.write = 0; + } + + // compute bytes to copy + n = this.write - q; + + if (n > z.avail_out) { + n = z.avail_out; + } + + if (n != 0 && r == Z_BUF_ERROR) { + r = Z_OK; + } + + // update counters + z.avail_out -= n; + z.total_out += n; + + // update check information + if (this.checkfn != null) { + z.adler = this.check = z._adler.adler32(this.check, this.window, q, n); + } + + // copy + arrayCopy(this.window, q, z.next_out, p, n); + p += n; + q += n; + } + + // update pointers + z.next_out_index = p; + this.read = q; + + // done + return r; + }; + + // + // InfCodes.java + // + + var IC_START = 0; // x: set up for LEN + var IC_LEN = 1; // i: get length/literal/eob next + var IC_LENEXT = 2; // i: getting length extra (have base) + var IC_DIST = 3; // i: get distance next + var IC_DISTEXT = 4; // i: getting distance extra + var IC_COPY = 5; // o: copying bytes in window, waiting for space + var IC_LIT = 6; // o: got literal, waiting for output space + var IC_WASH = 7; // o: got eob, possibly still output waiting + var IC_END = 8; // x: got eob and all data flushed + var IC_BADCODE = 9; // x: got error + + function InfCodes() {} + + InfCodes.prototype.init = function(bl, bd, tl, tl_index, td, td_index, z) { + this.mode = IC_START; + this.lbits = bl; + this.dbits = bd; + this.ltree = tl; + this.ltree_index = tl_index; + this.dtree = td; + this.dtree_index = td_index; + this.tree = null; + }; + + InfCodes.prototype.proc = function(s, z, r) { + var j; // temporary storage + var t; // temporary pointer (int[]) + var tindex; // temporary pointer + var e; // extra bits or operation + var b = 0; // bit buffer + var k = 0; // bits in bit buffer + var p = 0; // input data pointer + var n; // bytes available there + var q; // output window write pointer + var m; // bytes to end of window or read pointer + var f; // pointer to copy strings from + + // copy input/output information to locals (UPDATE macro restores) + p = z.next_in_index; + n = z.avail_in; + b = s.bitb; + k = s.bitk; + q = s.write; + m = q < s.read ? s.read - q - 1 : s.end - q; + + // process input and output based on current state + while (true) { + switch (this.mode) { + // waiting for "i:"=input, "o:"=output, "x:"=nothing + case IC_START: // x: set up for LEN + if (m >= 258 && n >= 10) { + s.bitb = b; + s.bitk = k; + z.avail_in = n; + z.total_in += p - z.next_in_index; + z.next_in_index = p; + s.write = q; + r = this.inflate_fast(this.lbits, this.dbits, this.ltree, this.ltree_index, this.dtree, this.dtree_index, s, z); + p = z.next_in_index; + n = z.avail_in; + b = s.bitb; + k = s.bitk; + q = s.write; + m = q < s.read ? s.read - q - 1 : s.end - q; + + if (r != Z_OK) { + this.mode = r == Z_STREAM_END ? IC_WASH : IC_BADCODE; + break; + } + } + + this.need = this.lbits; + this.tree = this.ltree; + this.tree_index = this.ltree_index; + + this.mode = IC_LEN; + case IC_LEN: // i: get length/literal/eob next + j = this.need; + + while (k < (j)) { + if (n != 0) { + r = Z_OK; + } else { + s.bitb = b; + s.bitk = k; + z.avail_in = n; + z.total_in += p - z.next_in_index; + z.next_in_index = p; + s.write = q; + return s.inflate_flush(z, r); + } + + n--; + b |= (z.next_in[p++] & 0xff) << k; + k += 8; + } + + tindex = (this.tree_index + (b & inflate_mask[j])) * 3; + + b >>>= (this.tree[tindex + 1]); + k -= (this.tree[tindex + 1]); + + e = this.tree[tindex]; + + if (e == 0) { // literal + this.lit = this.tree[tindex + 2]; + this.mode = IC_LIT; + break; + } + + if ((e & 16) != 0) { // length + this.get = e & 15; + this.len = this.tree[tindex + 2]; + this.mode = IC_LENEXT; + break; + } + + if ((e & 64) == 0) { // next table + this.need = e; + this.tree_index = tindex / 3 + this.tree[tindex + 2]; + break; + } + + if ((e & 32) != 0) { // end of block + this.mode = IC_WASH; + break; + } + + this.mode = IC_BADCODE; // invalid code + z.msg = "invalid literal/length code"; + r = Z_DATA_ERROR; + + s.bitb = b; + s.bitk = k; + z.avail_in = n; + z.total_in += p - z.next_in_index; + z.next_in_index = p; + s.write = q; + return s.inflate_flush(z, r); + case IC_LENEXT: // i: getting length extra (have base) + j = this.get; + + while (k < (j)) { + if (n != 0) { + r = Z_OK; + } else { + s.bitb = b; + s.bitk = k; + z.avail_in = n; + z.total_in += p - z.next_in_index; + z.next_in_index = p; + s.write = q; + return s.inflate_flush(z, r); + } + + n--; + b |= (z.next_in[p++] & 0xff) << k; + k += 8; + } + + this.len += (b & inflate_mask[j]); + + b >>= j; + k -= j; + + this.need = this.dbits; + this.tree = this.dtree; + this.tree_index = this.dtree_index; + this.mode = IC_DIST; + case IC_DIST: // i: get distance next + j = this.need; + + while (k < (j)) { + if (n != 0) { + r = Z_OK; + } else { + s.bitb = b; + s.bitk = k; + z.avail_in = n; + z.total_in += p - z.next_in_index; + z.next_in_index = p; + s.write = q; + return s.inflate_flush(z, r); + } + + n--; + b |= (z.next_in[p++] & 0xff) << k; + k += 8; + } + + tindex = (this.tree_index + (b & inflate_mask[j])) * 3; + + b >>= this.tree[tindex + 1]; + k -= this.tree[tindex + 1]; + + e = (this.tree[tindex]); + + if ((e & 16) != 0) { // distance + this.get = e & 15; + this.dist = this.tree[tindex + 2]; + this.mode = IC_DISTEXT; + break; + } + + if ((e & 64) == 0) { // next table + this.need = e; + this.tree_index = tindex / 3 + this.tree[tindex + 2]; + break; + } + + this.mode = IC_BADCODE; // invalid code + z.msg = "invalid distance code"; + r = Z_DATA_ERROR; + + s.bitb = b; + s.bitk = k; + z.avail_in = n; + z.total_in += p - z.next_in_index; + z.next_in_index = p; + s.write = q; + return s.inflate_flush(z, r); + case IC_DISTEXT: // i: getting distance extra + j = this.get; + + while (k < (j)) { + if (n != 0) { + r = Z_OK; + } else { + s.bitb = b; + s.bitk = k; + z.avail_in = n; + z.total_in += p - z.next_in_index; + z.next_in_index = p; + s.write = q; + return s.inflate_flush(z, r); + } + + n--; + b |= (z.next_in[p++] & 0xff) << k; + k += 8; + } + + this.dist += (b & inflate_mask[j]); + + b >>= j; + k -= j; + + this.mode = IC_COPY; + case IC_COPY: // o: copying bytes in window, waiting for space + f = q - this.dist; + + while (f < 0) { // modulo window size-"while" instead + f += s.end; // of "if" handles invalid distances + } + + while (this.len != 0) { + if (m == 0) { + if (q == s.end && s.read != 0) { + q = 0; + m = q < s.read ? s.read - q - 1 : s.end - q; + } + + if (m == 0) { + s.write = q; + r = s.inflate_flush(z, r); + q = s.write; + m = q < s.read ? s.read - q - 1 : s.end - q; + + if (q == s.end && s.read != 0) { + q = 0; + m = q < s.read ? s.read - q - 1 : s.end - q; + } + + if (m == 0) { + s.bitb = b; + s.bitk = k; + z.avail_in = n; + z.total_in += p - z.next_in_index; + z.next_in_index = p; + s.write = q; + return s.inflate_flush(z, r); + } + } + } + + s.window[q++] = s.window[f++]; + m--; + + if (f == s.end) { + f = 0; + } + + this.len--; + } + + this.mode = IC_START; + break; + case IC_LIT: // o: got literal, waiting for output space + if (m == 0) { + if (q == s.end && s.read != 0) { + q = 0; + m = q < s.read ? s.read - q - 1 : s.end - q; + } + + if (m == 0) { + s.write = q; + r = s.inflate_flush(z, r); + q = s.write; + m = q < s.read ? s.read - q - 1 : s.end - q; + + if (q == s.end && s.read != 0) { + q = 0; + m = q < s.read ? s.read - q - 1 : s.end - q; + } + + if (m == 0) { + s.bitb = b; + s.bitk = k; + z.avail_in = n; + z.total_in += p - z.next_in_index; + z.next_in_index = p; + s.write = q; + return s.inflate_flush(z, r); + } + } + } + + r = Z_OK; + + s.window[q++] = this.lit; + m--; + + this.mode = IC_START; + break; + case IC_WASH: // o: got eob, possibly more output + if (k > 7) { // return unused byte, if any + k -= 8; + n++; + p--; // can always return one + } + + s.write = q; + r = s.inflate_flush(z, r); + q = s.write; + m = q < s.read ? s.read - q - 1 : s.end - q; + + if (s.read != s.write) { + s.bitb = b; + s.bitk = k; + z.avail_in = n; + z.total_in += p - z.next_in_index; + z.next_in_index = p; + s.write = q; + return s.inflate_flush(z, r); + } + + this.mode = IC_END; + case IC_END: + r = Z_STREAM_END; + s.bitb = b; + s.bitk = k; + z.avail_in = n; + z.total_in += p - z.next_in_index; + z.next_in_index = p; + s.write = q; + return s.inflate_flush(z, r); + case IC_BADCODE: // x: got error + + r = Z_DATA_ERROR; + + s.bitb = b; + s.bitk = k; + z.avail_in = n; + z.total_in += p - z.next_in_index; + z.next_in_index = p; + s.write = q; + return s.inflate_flush(z, r); + default: + r = Z_STREAM_ERROR; + + s.bitb = b; + s.bitk = k; + z.avail_in = n; + z.total_in += p - z.next_in_index; + z.next_in_index = p; + s.write = q; + return s.inflate_flush(z, r); + } + } + }; + + InfCodes.prototype.free = function(z) { + // ZFREE(z, c); + }; + + // Called with number of bytes left to write in window at least 258 + // (the maximum string length) and number of input bytes available + // at least ten. The ten bytes are six bytes for the longest length/ + // distance pair plus four bytes for overloading the bit buffer. + + InfCodes.prototype.inflate_fast = function(bl, bd, tl, tl_index, td, td_index, s, z) { + var t; // temporary pointer + var tp; // temporary pointer (int[]) + var tp_index; // temporary pointer + var e; // extra bits or operation + var b; // bit buffer + var k; // bits in bit buffer + var p; // input data pointer + var n; // bytes available there + var q; // output window write pointer + var m; // bytes to end of window or read pointer + var ml; // mask for literal/length tree + var md; // mask for distance tree + var c; // bytes to copy + var d; // distance back to copy from + var r; // copy source pointer + + var tp_index_t_3; // (tp_index+t)*3 + + // load input, output, bit values + p = z.next_in_index; + n = z.avail_in; + b = s.bitb; + k = s.bitk; + q = s.write; + m = q < s.read ? s.read - q - 1 : s.end - q; + + // initialize masks + ml = inflate_mask[bl]; + md = inflate_mask[bd]; + + // do until not enough input or output space for fast loop + do { // assume called with m >= 258 && n >= 10 + // get literal/length code + while (k < (20)) { // max bits for literal/length code + n--; + b |= (z.next_in[p++] & 0xff) << k; + k += 8; + } + + t = b & ml; + tp = tl; + tp_index = tl_index; + tp_index_t_3 = (tp_index + t) * 3; + + if ((e = tp[tp_index_t_3]) == 0) { + b >>= (tp[tp_index_t_3 + 1]); + k -= (tp[tp_index_t_3 + 1]); + + s.window[q++] = tp[tp_index_t_3 + 2]; + m--; + continue; + } + + do { + b >>= (tp[tp_index_t_3 + 1]); + k -= (tp[tp_index_t_3 + 1]); + + if ((e & 16) != 0) { + e &= 15; + c = tp[tp_index_t_3 + 2] + (b & inflate_mask[e]); + + b >>= e; + k -= e; + + // decode distance base of block to copy + while (k < (15)) { // max bits for distance code + n--; + b |= (z.next_in[p++] & 0xff) << k; + k += 8; + } + + t = b & md; + tp = td; + tp_index = td_index; + tp_index_t_3 = (tp_index + t) * 3; + e = tp[tp_index_t_3]; + + do { + b >>= (tp[tp_index_t_3 + 1]); + k -= (tp[tp_index_t_3 + 1]); + + if ((e & 16) != 0) { + // get extra bits to add to distance base + e &= 15; + + while (k < (e)) { // get extra bits (up to 13) + n--; + b |= (z.next_in[p++] & 0xff) << k; + k += 8; + } + + d = tp[tp_index_t_3 + 2] + (b & inflate_mask[e]); + + b >>= (e); + k -= (e); + + // do the copy + m -= c; + + if (q >= d) { // offset before dest + // just copy + r = q - d; + + if (q - r > 0 && 2 > (q - r)) { + s.window[q++] = s.window[r++]; // minimum count is three, + s.window[q++] = s.window[r++]; // so unroll loop a little + c -= 2; + } else { + s.window[q++] = s.window[r++]; // minimum count is three, + s.window[q++] = s.window[r++]; // so unroll loop a little + c -= 2; + } + } else { // else offset after destination + r = q - d; + + do { + r += s.end; // force pointer in window + } while (r < 0); // covers invalid distances + + e = s.end - r; + + if (c > e) { // if source crosses, + c -= e; // wrapped copy + + if (q - r > 0 && e > (q - r)) { + do { + s.window[q++] = s.window[r++]; + } while (--e != 0); + } else { + arrayCopy(s.window, r, s.window, q, e); + q += e; + r += e; + e = 0; + } + + r = 0; // copy rest from start of window + } + } + + // copy all or what's left + do { + s.window[q++] = s.window[r++]; + } while (--c != 0); + + break; + } else if ((e & 64) == 0) { + t += tp[tp_index_t_3 + 2]; + t += (b & inflate_mask[e]); + tp_index_t_3 = (tp_index + t) * 3; + e = tp[tp_index_t_3]; + } else { + z.msg = "invalid distance code"; + + c = z.avail_in - n; + c = (k >> 3) < c ? k >> 3 : c; + n += c; + p -= c; + k -= c << 3; + + s.bitb = b; + s.bitk = k; + z.avail_in = n; + z.total_in += p - z.next_in_index; + z.next_in_index = p; + s.write = q; + + return Z_DATA_ERROR; + } + } while (true); + + break; + } + + if ((e & 64) == 0) { + t += tp[tp_index_t_3 + 2]; + t += (b & inflate_mask[e]); + tp_index_t_3 = (tp_index + t) * 3; + + if ((e = tp[tp_index_t_3]) == 0) { + b >>= (tp[tp_index_t_3 + 1]); + k -= (tp[tp_index_t_3 + 1]); + + s.window[q++] = tp[tp_index_t_3 + 2]; + m--; + break; + } + } else if ((e & 32) != 0) { + c = z.avail_in - n; + c = (k >> 3) < c ? k >> 3 : c; + n += c; + p -= c; + k -= c << 3; + + s.bitb = b; + s.bitk = k; + z.avail_in = n; + z.total_in += p - z.next_in_index; + z.next_in_index = p; + s.write = q; + + return Z_STREAM_END; + } else { + z.msg = "invalid literal/length code"; + + c = z.avail_in - n; + c = (k >> 3) < c ? k >> 3 : c; + n += c; + p -= c; + k -= c << 3; + + s.bitb = b; + s.bitk = k; + z.avail_in = n; + z.total_in += p - z.next_in_index; + z.next_in_index = p; + s.write = q; + + return Z_DATA_ERROR; + } + } while (true); + } while (m >= 258 && n >= 10); + + // not enough input or output--restore pointers and return + c = z.avail_in - n; + c = (k >> 3) < c ? k >> 3 : c; + n += c; + p -= c; + k -= c << 3; + + s.bitb = b; + s.bitk = k; + z.avail_in = n; + z.total_in += p - z.next_in_index; + z.next_in_index = p; + s.write = q; + + return Z_OK; + }; + + // + // InfTree.java + // + + function InfTree() {} + + InfTree.prototype.huft_build = function(b, bindex, n, s, d, e, t, m, hp, hn, v) { + // Given a list of code lengths and a maximum table size, make a set of + // tables to decode that set of codes. Return Z_OK on success, Z_BUF_ERROR + // if the given code set is incomplete (the tables are still built in this + // case), Z_DATA_ERROR if the input is invalid (an over-subscribed set of + // lengths), or Z_MEM_ERROR if not enough memory. + + var a; // counter for codes of length k + var f; // i repeats in table every f entries + var g; // maximum code length + var h; // table level + var i; // counter, current code + var j; // counter + var k; // number of bits in current code + var l; // bits per table (returned in m) + var mask; // (1 << w) - 1, to avoid cc -O bug on HP + var p; // pointer into c[], b[], or v[] + var q; // points to current table + var w; // bits before this table == (l * h) + var xp; // pointer into x + var y; // number of dummy codes added + var z; // number of entries in current table + + // Generate counts for each bit length + + p = 0; + i = n; + + do { + this.c[b[bindex + p]]++; + p++; + i--; // assume all entries <= BMAX + } while (i != 0); + + if (this.c[0] == n) { // null input--all zero length codes + t[0] = -1; + m[0] = 0; + return Z_OK; + } + + // Find minimum and maximum length, bound *m by those + l = m[0]; + + for (j = 1; j <= BMAX; j++) { + if (this.c[j] != 0) { + break; + } + } + + k = j; // minimum code length + + if (l < j) { + l = j; + } + + for (i = BMAX; i != 0; i--) { + if (this.c[i] != 0) { + break; + } + } + + g = i; // maximum code length + + if (l > i) { + l = i; + } + + m[0] = l; + + // Adjust last length count to fill out codes, if needed + for (y = 1 << j; j < i; j++, y <<= 1) { + if ((y -= this.c[j]) < 0) { + return Z_DATA_ERROR; + } + } + + if ((y -= this.c[i]) < 0) { + return Z_DATA_ERROR; + } + + this.c[i] += y; + + // Generate starting offsets into the value table for each length + this.x[1] = j = 0; + p = 1; + xp = 2; + + while (--i != 0) { // note that i == g from above + this.x[xp] = (j += this.c[p]); + xp++; + p++; + } + + // Make a table of values in order of bit lengths + i = 0; + p = 0; + + do { + if ((j = b[bindex + p]) != 0) { + this.v[this.x[j]++] = i; + } + p++; + } while (++i < n); + + n = this.x[g]; // set n to length of v + + // Generate the Huffman codes and for each, make the table entries + this.x[0] = i = 0; // first Huffman code is zero + p = 0; // grab values in bit order + h = -1; // no tables yet--level -1 + w = -l; // bits decoded == (l * h) + this.u[0] = 0; // just to keep compilers happy + q = 0; // ditto + z = 0; // ditto + + // go through the bit lengths (k already is bits in shortest code) + for (; k <= g; k++) { + a = this.c[k]; + + while (a-- != 0) { + // here i is the Huffman code of length k bits for value *p + // make tables up to required level + while (k > w + l) { + h++; + w += l; // previous table always l bits + // compute minimum size table less than or equal to l bits + z = g - w; + z = (z > l) ? l : z; // table size upper limit + + if ((f = 1 << (j = k - w)) > a + 1) { // try a k-w bit table + // too few codes for k-w bit table + f -= a + 1; // deduct codes from patterns left + xp = k; + + if (j < z) { + while (++j < z) { // try smaller tables up to z bits + if ((f <<= 1) <= this.c[++xp]) { + break; // enough codes to use up j bits + } + + f -= this.c[xp]; // else deduct codes from patterns + } + } + } + + z = 1 << j; // table entries for j-bit table + + // allocate new table + if (this.hn[0] + z > MANY) { // (note: doesn't matter for fixed) + return Z_DATA_ERROR; // overflow of MANY + } + + this.u[h] = q = /*hp+*/ this.hn[0]; // DEBUG + this.hn[0] += z; + + // connect to last table, if there is one + if (h != 0) { + this.x[h] = i; // save pattern for backing up + this.r[0] = j; // bits in this table + this.r[1] = l; // bits to dump before this table + j = i >>> (w - l); + this.r[2] = (q - this.u[h - 1] - j); // offset to this table + arrayCopy(this.r, 0, hp, (this.u[h - 1] + j) * 3, 3); // connect to last table + } else { + t[0] = q; // first table is returned result + } + } + + // set up table entry in r + this.r[1] = (k - w); + + if (p >= n) { + this.r[0] = 128 + 64; // out of values--invalid code + } else if (v[p] < s) { + this.r[0] = (this.v[p] < 256 ? 0 : 32 + 64); // 256 is end-of-block + this.r[2] = this.v[p++]; // simple code is just the value + } else { + this.r[0] = (e[this.v[p] - s] + 16 + 64); // non-simple--look up in lists + this.r[2] = d[this.v[p++] - s]; + } + + // fill code-like entries with r + f = 1 << (k - w); + + for (j = i >>> w; j < z; j += f) { + arrayCopy(this.r, 0, hp, (q + j) * 3, 3); + } + + // backwards increment the k-bit code i + for (j = 1 << (k - 1); (i & j) != 0; j >>>= 1) { + i ^= j; + } + + i ^= j; + + // backup over finished tables + mask = (1 << w) - 1; // needed on HP, cc -O bug + + while ((i & mask) != this.x[h]) { + h--; // don't need to update q + w -= l; + mask = (1 << w) - 1; + } + } + } + + // Return Z_BUF_ERROR if we were given an incomplete table + return y != 0 && g != 1 ? Z_BUF_ERROR : Z_OK; + }; + + InfTree.prototype.inflate_trees_bits = function(c, bb, tb, hp, z) { + var result; + this.initWorkArea(19); + this.hn[0] = 0; + result = this.huft_build(c, 0, 19, 19, null, null, tb, bb, hp, this.hn, this.v); + + if (result == Z_DATA_ERROR) { + z.msg = "oversubscribed dynamic bit lengths tree"; + } else if (result == Z_BUF_ERROR || bb[0] == 0) { + z.msg = "incomplete dynamic bit lengths tree"; + result = Z_DATA_ERROR; + } + + return result; + }; + + InfTree.prototype.inflate_trees_dynamic = function(nl, nd, c, bl, bd, tl, td, hp, z) { + var result; + + // build literal/length tree + this.initWorkArea(288); + this.hn[0] = 0; + result = this.huft_build(c, 0, nl, 257, cplens, cplext, tl, bl, hp, this.hn, this.v); + + if (result != Z_OK || bl[0] == 0) { + if (result == Z_DATA_ERROR) { + z.msg = "oversubscribed literal/length tree"; + } else if (result != Z_MEM_ERROR) { + z.msg = "incomplete literal/length tree"; + result = Z_DATA_ERROR; + } + + return result; + } + + // build distance tree + this.initWorkArea(288); + result = this.huft_build(c, nl, nd, 0, cpdist, cpdext, td, bd, hp, this.hn, this.v); + + if (result != Z_OK || (bd[0] == 0 && nl > 257)) { + if (result == Z_DATA_ERROR) { + z.msg = "oversubscribed distance tree"; + } else if (result == Z_BUF_ERROR) { + z.msg = "incomplete distance tree"; + result = Z_DATA_ERROR; + } else if (result != Z_MEM_ERROR) { + z.msg = "empty distance tree with lengths"; + result = Z_DATA_ERROR; + } + + return result; + } + + return Z_OK; + }; + + /* + static int inflate_trees_fixed(int[] bl, //literal desired/actual bit depth + int[] bd, //distance desired/actual bit depth + int[][] tl,//literal/length tree result + int[][] td,//distance tree result + ZStream z //for memory allocation + ){ + + */ + + function inflate_trees_fixed(bl, bd, tl, td, z) { + bl[0] = fixed_bl; + bd[0] = fixed_bd; + tl[0] = fixed_tl; + td[0] = fixed_td; + return Z_OK; + } + + InfTree.prototype.initWorkArea = function(vsize) { + if (this.hn == null) { + this.hn = new Int32Array(1); + this.v = new Int32Array(vsize); + this.c = new Int32Array(BMAX + 1); + this.r = new Int32Array(3); + this.u = new Int32Array(BMAX); + this.x = new Int32Array(BMAX + 1); + } + + if (this.v.length < vsize) { + this.v = new Int32Array(vsize); + } + + for (var i = 0; i < vsize; i++) { + this.v[i] = 0; + } + + for (var i = 0; i < BMAX + 1; i++) { + this.c[i] = 0; + } + + for (var i = 0; i < 3; i++) { + this.r[i] = 0; + } + + // for(int i=0; i 100) { + arrayCopy_fast(new Uint8Array(src.buffer, src.byteOffset + srcOffset, count), dest, destOffset); + } else { + arrayCopy_slow(src, srcOffset, dest, destOffset, count); + } + } + + function arrayCopy_slow(src, srcOffset, dest, destOffset, count) { + // dlog('_slow call: srcOffset=' + srcOffset + '; destOffset=' + destOffset + '; count=' + count); + for (var i = 0; i < count; ++i) { + dest[destOffset + i] = src[srcOffset + i]; + } + } + + function arrayCopy_fast(src, dest, destOffset) { + dest.set(src, destOffset); + } + + // largest prime smaller than 65536 + var ADLER_BASE = 65521; + // NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 + var ADLER_NMAX = 5552; + + function adler32(adler, /* byte[] */ buf, index, len) { + if (buf == null) { + return 1; + } + + var s1 = adler & 0xffff; + var s2 = (adler >> 16) & 0xffff; + var k; + + while (len > 0) { + k = len < ADLER_NMAX ? len : ADLER_NMAX; + len -= k; + + while (k >= 16) { + s1 += buf[index++] & 0xff; + s2 += s1; + s1 += buf[index++] & 0xff; + s2 += s1; + s1 += buf[index++] & 0xff; + s2 += s1; + s1 += buf[index++] & 0xff; + s2 += s1; + s1 += buf[index++] & 0xff; + s2 += s1; + s1 += buf[index++] & 0xff; + s2 += s1; + s1 += buf[index++] & 0xff; + s2 += s1; + s1 += buf[index++] & 0xff; + s2 += s1; + s1 += buf[index++] & 0xff; + s2 += s1; + s1 += buf[index++] & 0xff; + s2 += s1; + s1 += buf[index++] & 0xff; + s2 += s1; + s1 += buf[index++] & 0xff; + s2 += s1; + s1 += buf[index++] & 0xff; + s2 += s1; + s1 += buf[index++] & 0xff; + s2 += s1; + s1 += buf[index++] & 0xff; + s2 += s1; + s1 += buf[index++] & 0xff; + s2 += s1; + k -= 16; + } + + if (k != 0) { + do { + s1 += buf[index++] & 0xff; + s2 += s1; + } while (--k != 0); + } + + s1 %= ADLER_BASE; + s2 %= ADLER_BASE; + } + + return (s2 << 16) | s1; + } + + function inflateBuffer(buffer, start, length, afterUncOffset) { + if (!start) { + buffer = new Uint8Array(buffer); + } else if (!length) { + buffer = new Uint8Array(buffer, start, buffer.byteLength - start); + } else { + buffer = new Uint8Array(buffer, start, length); + } + + var z = new ZStream(); + z.inflateInit(DEF_WBITS, true); + z.next_in = buffer; + z.next_in_index = 0; + z.avail_in = buffer.length; + + var oBlockList = []; + var totalSize = 0; + + while (true) { + var obuf = new Uint8Array(32000); + z.next_out = obuf; + z.next_out_index = 0; + z.avail_out = obuf.length; + var status = z.inflate(Z_NO_FLUSH); + + if (status != Z_OK && status != Z_STREAM_END && status != Z_BUF_ERROR) { + throw z.msg; + } + + if (z.avail_out != 0) { + var newob = new Uint8Array(obuf.length - z.avail_out); + arrayCopy(obuf, 0, newob, 0, (obuf.length - z.avail_out)); + obuf = newob; + } + + oBlockList.push(obuf); + totalSize += obuf.length; + + if (status == Z_STREAM_END || status == Z_BUF_ERROR) { + break; + } + } + + if (afterUncOffset) { + afterUncOffset[0] = (start || 0) + z.next_in_index; + } + + if (oBlockList.length == 1) { + return oBlockList[0].buffer; + } else { + var out = new Uint8Array(totalSize); + var cursor = 0; + + for (var i = 0; i < oBlockList.length; ++i) { + var b = oBlockList[i]; + arrayCopy(b, 0, out, cursor, b.length); + cursor += b.length; + } + + return out.buffer; + } + } + + /*-------------------------------------------------------------------------------------------------------------------------------*/ + + /* + * A JavaScript implementation of the Secure Hash Algorithm, SHA-1, as defined + * in FIPS 180-1 + * Version 2.2 Copyright Paul Johnston 2000 - 2009. + * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet + * Distributed under the BSD License + * See http://pajhome.org.uk/crypt/md5 for details. + */ + + /* + * Configurable variables. You may need to tweak these to be compatible with + * the server-side, but the defaults work in most cases. + */ + var hexcase = 0; /* hex output format. 0 - lowercase; 1 - uppercase */ + var b64pad = ""; /* base-64 pad character. "=" for strict RFC compliance */ + + /* + * These are the functions you'll usually want to call + * They take string arguments and return either hex or base-64 encoded strings + */ + function hex_sha1(s) { + return rstr2hex(rstr_sha1(str2rstr_utf8(s))); + } + + function b64_sha1(s) { + return rstr2b64(rstr_sha1(str2rstr_utf8(s))); + } + + function any_sha1(s, e) { + return rstr2any(rstr_sha1(str2rstr_utf8(s)), e); + } + + function hex_hmac_sha1(k, d) { + return rstr2hex(rstr_hmac_sha1(str2rstr_utf8(k), str2rstr_utf8(d))); + } + + function b64_hmac_sha1(k, d) { + return rstr2b64(rstr_hmac_sha1(str2rstr_utf8(k), str2rstr_utf8(d))); + } + + function any_hmac_sha1(k, d, e) { + return rstr2any(rstr_hmac_sha1(str2rstr_utf8(k), str2rstr_utf8(d)), e); + } + + /* + * Perform a simple self-test to see if the VM is working + */ + function sha1_vm_test() { + return hex_sha1("abc").toLowerCase() == "a9993e364706816aba3e25717850c26c9cd0d89d"; + } + + /* + * Calculate the SHA1 of a raw string + */ + function rstr_sha1(s) { + return binb2rstr(binb_sha1(rstr2binb(s), s.length * 8)); + } + + /* + * Calculate the HMAC-SHA1 of a key and some data (raw strings) + */ + function rstr_hmac_sha1(key, data) { + var bkey = rstr2binb(key); + + if (bkey.length > 16) { + bkey = binb_sha1(bkey, key.length * 8); + } + + var ipad = Array(16), opad = Array(16); + + for (var i = 0; i < 16; i++) { + ipad[i] = bkey[i] ^ 0x36363636; + opad[i] = bkey[i] ^ 0x5C5C5C5C; + } + + var hash = binb_sha1(ipad.concat(rstr2binb(data)), 512 + data.length * 8); + return binb2rstr(binb_sha1(opad.concat(hash), 512 + 160)); + } + + /* + * Convert a raw string to a hex string + */ + function rstr2hex(input) { + // try { hexcase } catch(e) { hexcase=0; } + var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef"; + var output = ""; + var x; + + for (var i = 0; i < input.length; i++) { + x = input.charCodeAt(i); + output += hex_tab.charAt((x >>> 4) & 0x0F) + hex_tab.charAt(x & 0x0F); + } + + return output; + } + + /* + * Convert a raw string to a base-64 string + */ + function rstr2b64(input) { + // try { b64pad } catch(e) { b64pad=''; } + var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + var output = ""; + var len = input.length; + + for (var i = 0; i < len; i += 3) { + var triplet = (input.charCodeAt(i) << 16) | (i + 1 < len ? input.charCodeAt(i + 1) << 8 : 0) | (i + 2 < len ? input.charCodeAt(i + 2) : 0); + + for (var j = 0; j < 4; j++) { + if (i * 8 + j * 6 > input.length * 8) { + output += b64pad; + } else { + output += tab.charAt((triplet >>> 6 * (3 - j)) & 0x3F); + } + } + } + + return output; + } + + /* + * Convert a raw string to an arbitrary string encoding + */ + function rstr2any(input, encoding) { + var divisor = encoding.length; + var remainders = Array(); + var i, q, x, quotient; + + /* Convert to an array of 16-bit big-endian values, forming the dividend */ + var dividend = Array(Math.ceil(input.length / 2)); + + for (i = 0; i < dividend.length; i++) { + dividend[i] = (input.charCodeAt(i * 2) << 8) | input.charCodeAt(i * 2 + 1); + } + + /* + * Repeatedly perform a long division. The binary array forms the dividend, + * the length of the encoding is the divisor. Once computed, the quotient + * forms the dividend for the next step. We stop when the dividend is zero. + * All remainders are stored for later use. + */ + while (dividend.length > 0) { + quotient = Array(); + x = 0; + + for (i = 0; i < dividend.length; i++) { + x = (x << 16) + dividend[i]; + q = Math.floor(x / divisor); + x -= q * divisor; + + if (quotient.length > 0 || q > 0) { + quotient[quotient.length] = q; + } + } + + remainders[remainders.length] = x; + dividend = quotient; + } + + /* Convert the remainders to the output string */ + var output = ""; + + for (i = remainders.length - 1; i >= 0; i--) { + output += encoding.charAt(remainders[i]); + } + + /* Append leading zero equivalents */ + var full_length = Math.ceil(input.length * 8 / (Math.log(encoding.length) / Math.log(2))); + + for (i = output.length; i < full_length; i++) { + output = encoding[0] + output; + } + + return output; + } + + /* + * Encode a string as utf-8. + * For efficiency, this assumes the input is valid utf-16. + */ + function str2rstr_utf8(input) { + var output = ""; + var i = -1; + var x, y; + + while (++i < input.length) { + /* Decode utf-16 surrogate pairs */ + x = input.charCodeAt(i); + y = i + 1 < input.length ? input.charCodeAt(i + 1) : 0; + + if (0xD800 <= x && x <= 0xDBFF && 0xDC00 <= y && y <= 0xDFFF) { + x = 0x10000 + ((x & 0x03FF) << 10) + (y & 0x03FF); + i++; + } + + /* Encode output as utf-8 */ + if (x <= 0x7F) { + output += String.fromCharCode(x); + } else if (x <= 0x7FF) { + output += String.fromCharCode(0xC0 | ((x >>> 6) & 0x1F), 0x80 | (x & 0x3F)); + } else if (x <= 0xFFFF) { + output += String.fromCharCode(0xE0 | ((x >>> 12) & 0x0F), 0x80 | ((x >>> 6) & 0x3F), 0x80 | (x & 0x3F)); + } else if (x <= 0x1FFFFF) { + output += String.fromCharCode(0xF0 | ((x >>> 18) & 0x07), 0x80 | ((x >>> 12) & 0x3F), 0x80 | ((x >>> 6) & 0x3F), 0x80 | (x & 0x3F)); + } + } + + return output; + } + + /* + * Encode a string as utf-16 + */ + function str2rstr_utf16le(input) { + var output = ""; + + for (var i = 0; i < input.length; i++) { + output += String.fromCharCode(input.charCodeAt(i) & 0xFF, (input.charCodeAt(i) >>> 8) & 0xFF); + } + + return output; + } + + function str2rstr_utf16be(input) { + var output = ""; + + for (var i = 0; i < input.length; i++) { + output += String.fromCharCode((input.charCodeAt(i) >>> 8) & 0xFF, input.charCodeAt(i) & 0xFF); + } + + return output; + } + + /* + * Convert a raw string to an array of big-endian words + * Characters >255 have their high-byte silently ignored. + */ + function rstr2binb(input) { + var output = Array(input.length >> 2); + + for (var i = 0; i < output.length; i++) { + output[i] = 0; + } + + for (var i = 0; i < input.length * 8; i += 8) { + output[i >> 5] |= (input.charCodeAt(i / 8) & 0xFF) << (24 - i % 32); + } + + return output; + } + + /* + * Convert an array of big-endian words to a string + */ + function binb2rstr(input) { + var output = ""; + + for (var i = 0; i < input.length * 32; i += 8) { + output += String.fromCharCode((input[i >> 5] >>> (24 - i % 32)) & 0xFF); + } + + return output; + } + + /* + * Calculate the SHA-1 of an array of big-endian words, and a bit length + */ + function binb_sha1(x, len) { + /* append padding */ + x[len >> 5] |= 0x80 << (24 - len % 32); + x[((len + 64 >> 9) << 4) + 15] = len; + + var w = Array(80); + var a = 1732584193; + var b = -271733879; + var c = -1732584194; + var d = 271733878; + var e = -1009589776; + + for (var i = 0; i < x.length; i += 16) { + var olda = a; + var oldb = b; + var oldc = c; + var oldd = d; + var olde = e; + + for (var j = 0; j < 80; j++) { + if (j < 16) { + w[j] = x[i + j]; + } else { + w[j] = bit_rol(w[j - 3] ^ w[j - 8] ^ w[j - 14] ^ w[j - 16], 1); + } + + var t = safe_add(safe_add(bit_rol(a, 5), sha1_ft(j, b, c, d)), safe_add(safe_add(e, w[j]), sha1_kt(j))); + e = d; + d = c; + c = bit_rol(b, 30); + b = a; + a = t; + } + + a = safe_add(a, olda); + b = safe_add(b, oldb); + c = safe_add(c, oldc); + d = safe_add(d, oldd); + e = safe_add(e, olde); + } + + return Array(a, b, c, d, e); + } + + /* + * Perform the appropriate triplet combination function for the current + * iteration + */ + function sha1_ft(t, b, c, d) { + if (t < 20) { + return (b & c) | ((~b) & d); + } + + if (t < 40) { + return b ^ c ^ d; + } + + if (t < 60) { + return (b & c) | (b & d) | (c & d); + } + + return b ^ c ^ d; + } + + /* + * Determine the appropriate additive constant for the current iteration + */ + function sha1_kt(t) { + return (t < 20) ? 1518500249 : (t < 40) ? 1859775393 : (t < 60) ? -1894007588 : -899497514; + } + + /* + * Add integers, wrapping at 2^32. This uses 16-bit operations internally + * to work around bugs in some JS interpreters. + */ + function safe_add(x, y) { + var lsw = (x & 0xFFFF) + (y & 0xFFFF); + var msw = (x >> 16) + (y >> 16) + (lsw >> 16); + return (msw << 16) | (lsw & 0xFFFF); + } + + /* + * Bitwise rotate a 32-bit number to the left. + */ + function bit_rol(num, cnt) { + return (num << cnt) | (num >>> (32 - cnt)); + } + + /*-------------------------------------------------------------------------------------------------------------------------------*/ + + // + // Dalliance Genome Explorer + // (c) Thomas Down 2006-2011 + // + // js: common support for lh3's file formats + // + + function Vob(b, o) { + this.block = b; + this.offset = o; + } + + Vob.prototype.toString = function() { + return '' + this.block + ':' + this.offset; + }; + + function readVob(ba, offset, allowZero) { + var block = ((ba[offset + 6] & 0xff) * 0x100000000) + ((ba[offset + 5] & 0xff) * 0x1000000) + ((ba[offset + 4] & 0xff) * 0x10000) + ((ba[offset + 3] & 0xff) * 0x100) + ((ba[offset + 2] & 0xff)); + var bint = (ba[offset + 1] << 8) | (ba[offset]); + + if (block == 0 && bint == 0 && !allowZero) { + return null; // Should only happen in the linear index? + } else { + return new Vob(block, bint); + } + } + + function unbgzf(data, lim) { + lim = Math.min(lim || 1, data.byteLength - 50); + var oBlockList = []; + var ptr = [0]; + var totalSize = 0; + + while (ptr[0] < lim) { + var ba = new Uint8Array(data, ptr[0], 12); // FIXME is this enough for all credible BGZF block headers? + var xlen = (ba[11] << 8) | (ba[10]); + // dlog('xlen[' + (ptr[0]) +']=' + xlen); + var unc = inflateBuffer(data, 12 + xlen + ptr[0], Math.min(65536, data.byteLength - 12 - xlen - ptr[0]), ptr); + ptr[0] += 8; + totalSize += unc.byteLength; + oBlockList.push(unc); + } + + if (oBlockList.length == 1) { + return oBlockList[0]; + } else { + var out = new Uint8Array(totalSize); + var cursor = 0; + + for (var i = 0; i < oBlockList.length; ++i) { + var b = new Uint8Array(oBlockList[i]); + arrayCopy(b, 0, out, cursor, b.length); + cursor += b.length; + } + + return out.buffer; + } + } + + function Chunk(minv, maxv) { + this.minv = minv; + this.maxv = maxv; + } + + + // + // Binning (transliterated from SAM1.3 spec) + // + + /* calculate bin given an alignment covering [beg,end) (zero-based, half-close-half-open) */ + function reg2bin(beg, end) { + --end; + + if (beg >> 14 == end >> 14) { + return ((1 << 15) - 1) / 7 + (beg >> 14); + } + + if (beg >> 17 == end >> 17) { + return ((1 << 12) - 1) / 7 + (beg >> 17); + } + + if (beg >> 20 == end >> 20) { + return ((1 << 9) - 1) / 7 + (beg >> 20); + } + + if (beg >> 23 == end >> 23) { + return ((1 << 6) - 1) / 7 + (beg >> 23); + } + + if (beg >> 26 == end >> 26) { + return ((1 << 3) - 1) / 7 + (beg >> 26); + } + + return 0; + } + + /* calculate the list of bins that may overlap with region [beg,end) (zero-based) */ + var MAX_BIN = (((1 << 18) - 1) / 7); + + function reg2bins(beg, end) { + var i = 0, k, list = []; + --end; + list.push(0); + + for (k = 1 + (beg >> 26); k <= 1 + (end >> 26); ++k) { + list.push(k); + } + + for (k = 9 + (beg >> 23); k <= 9 + (end >> 23); ++k) { + list.push(k); + } + + for (k = 73 + (beg >> 20); k <= 73 + (end >> 20); ++k) { + list.push(k); + } + + for (k = 585 + (beg >> 17); k <= 585 + (end >> 17); ++k) { + list.push(k); + } + + for (k = 4681 + (beg >> 14); k <= 4681 + (end >> 14); ++k) { + list.push(k); + } + + return list; + } + + /*-------------------------------------------------------------------------------------------------------------------------------*/ + + // + // Dalliance Genome Explorer + // (c) Thomas Down 2006-2011 + // + // bin.js general binary data support + // + + function shallowCopy(o) { + var n = {}; + + for (var k in o) { + n[k] = o[k]; + } + + return n; + } + + function BlobFetchable(b) { + this.blob = b; + } + + BlobFetchable.prototype.slice = function(start, length) { + var b; + + if (this.blob.slice) { + if (length) { + b = this.blob.slice(start, start + length); + } else { + b = this.blob.slice(start); + } + } else { + if (length) { + b = this.blob.webkitSlice(start, start + length); + } else { + b = this.blob.webkitSlice(start); + } + } + + return new BlobFetchable(b); + }; + + BlobFetchable.prototype.salted = function() { + return this; + }; + + if (typeof(FileReader) !== 'undefined') { + // console.log('defining async BlobFetchable.fetch'); + + BlobFetchable.prototype.fetch = function(callback) { + var reader = new FileReader(); + + reader.onloadend = function(ev) { + callback(bstringToBuffer(reader.result)); + }; + + reader.readAsBinaryString(this.blob); + }; + } else { + // if (console && console.log) + // console.log('defining sync BlobFetchable.fetch'); + + BlobFetchable.prototype.fetch = function(callback) { + var reader = new FileReaderSync(); + + try { + var res = reader.readAsArrayBuffer(this.blob); + callback(res); + } catch (e) { + callback(null, e); + } + }; + } + + function URLFetchable(url, start, end, opts) { + if (!opts) { + if (typeof start === 'object') { + opts = start; + start = undefined; + } else { + opts = {}; + } + } + + this.url = url; + this.start = start || 0; + + if (end) { + this.end = end; + } + + this.opts = opts; + } + + URLFetchable.prototype.slice = function(s, l) { + if (s < 0) { + throw 'Bad slice ' + s; + } + + var ns = this.start, ne = this.end; + + if (ns && s) { + ns = ns + s; + } else { + ns = s || ns; + } + + if (l && ns) { + ne = ns + l - 1; + } else { + ne = ne || l - 1; + } + + return new URLFetchable(this.url, ns, ne, this.opts); + }; + + var seed = 0; + var isSafari = navigator.userAgent.indexOf('Safari') >= 0 && navigator.userAgent.indexOf('Chrome') < 0; + + URLFetchable.prototype.fetchAsText = function(callback) { + var thisB = this; + + this.getURL().then(function(url) { + try { + var req = new XMLHttpRequest(); + var length; + + if ((isSafari || thisB.opts.salt) && url.indexOf('?') < 0) { + url = url + '?salt=' + b64_sha1('' + Date.now() + ',' + (++seed)); + } + + req.open('GET', url, true); + + if (thisB.end) { + if (thisB.end - thisB.start > 100000000) { + throw 'Monster fetch!'; + } + + req.setRequestHeader('Range', 'bytes=' + thisB.start + '-' + thisB.end); + length = thisB.end - thisB.start + 1; + } + + req.onreadystatechange = function() { + if (req.readyState == 4) { + if (req.status == 200 || req.status == 206) { + return callback(req.responseText); + } else { + return callback(null); + } + } + }; + + if (thisB.opts.credentials) { + req.withCredentials = true; + } + + req.send(''); + } catch (e) { + return callback(null); + } + }).fail(function(err) { + console.log(err); + return callback(null, err); + }); + }; + + URLFetchable.prototype.salted = function() { + var o = shallowCopy(this.opts); + o.salt = true; + return new URLFetchable(this.url, this.start, this.end, o); + }; + + URLFetchable.prototype.getURL = function() { + if (this.opts.resolver) { + return this.opts.resolver(this.url).then(function(urlOrObj) { + if (typeof urlOrObj === 'string') { + return urlOrObj; + } else { + return urlOrObj.url; + } + }); + } else { + return $.Deferred().resolve(this.url); + } + }; + + URLFetchable.prototype.fetch = function(callback, opts) { + var thisB = this; + + opts = opts || {}; + var attempt = opts.attempt || 1; + var truncatedLength = opts.truncatedLength; + + if (attempt > 3) { + return callback(null); + } + + this.getURL().then(function(url) { + try { + var timeout; + + if (opts.timeout && !thisB.opts.credentials) { + timeout = setTimeout( + function() { + console.log('timing out ' + url); + req.abort(); + return callback(null, 'Timeout'); + }, + opts.timeout + ); + } + + var req = new XMLHttpRequest(); + var length; + + if ((isSafari || thisB.opts.salt) && url.indexOf('?') < 0) { + url = url + '?salt=' + b64_sha1('' + Date.now() + ',' + (++seed)); + } + + req.open('GET', url, true); + req.overrideMimeType('text/plain; charset=x-user-defined'); + + if (thisB.end) { + if (thisB.end - thisB.start > 100000000) { + throw 'Monster fetch!'; + } + + req.setRequestHeader('Range', 'bytes=' + thisB.start + '-' + thisB.end); + length = thisB.end - thisB.start + 1; + } + + req.responseType = 'arraybuffer'; + req.onreadystatechange = function() { + if (req.readyState == 4) { + if (timeout) { + clearTimeout(timeout); + } + + if (req.status == 200 || req.status == 206) { + if (req.response) { + var bl = req.response.byteLength; + + if (length && length != bl && (!truncatedLength || bl != truncatedLength)) { + return thisB.fetch(callback, { + attempt: attempt + 1, + truncatedLength: bl + }); + } else { + return callback(req.response); + } + } else if (req.mozResponseArrayBuffer) { + return callback(req.mozResponseArrayBuffer); + } else { + var r = req.responseText; + + if (length && length != r.length && (!truncatedLength || r.length != truncatedLength)) { + return thisB.fetch(callback, { + attempt: attempt + 1, + truncatedLength: r.length + }); + } else { + return callback(bstringToBuffer(req.responseText)); + } + } + } else { + return thisB.fetch(callback, { + attempt: attempt + 1 + }); + } + } + }; + + if (thisB.opts.credentials) { + req.withCredentials = true; + } + req.send(''); + } catch (e) { + return callback(null); + } + }).fail(function(err) { + console.log(err); + return callback(null, err); + }); + }; + + function bstringToBuffer(result) { + if (!result) { + return null; + } + + var ba = new Uint8Array(result.length); + + for (var i = 0; i < ba.length; ++i) { + ba[i] = result.charCodeAt(i); + } + + return ba.buffer; + } + + // Read from Uint8Array + function readFloat(buf, offset) { + var convertBuffer = new ArrayBuffer(8); + var ba = new Uint8Array(convertBuffer); + var fa = new Float32Array(convertBuffer); + + ba[0] = buf[offset]; + ba[1] = buf[offset + 1]; + ba[2] = buf[offset + 2]; + ba[3] = buf[offset + 3]; + + return fa[0]; + } + + function readInt64(ba, offset) { + return (ba[offset + 7] << 24) | (ba[offset + 6] << 16) | (ba[offset + 5] << 8) | (ba[offset + 4]); + } + + function readInt(ba, offset) { + return (ba[offset + 3] << 24) | (ba[offset + 2] << 16) | (ba[offset + 1] << 8) | (ba[offset]); + } + + function readShort(ba, offset) { + return (ba[offset + 1] << 8) | (ba[offset]); + } + + function readByte(ba, offset) { + return ba[offset]; + } + + function readIntBE(ba, offset) { + return (ba[offset] << 24) | (ba[offset + 1] << 16) | (ba[offset + 2] << 8) | (ba[offset + 3]); + } + + /*-------------------------------------------------------------------------------------------------------------------------------*/ + + // + // Dalliance Genome Explorer + // (c) Thomas Down 2006-2011 + // + // bam.js: indexed binary alignments + // + + var BAM_MAGIC = 0x14d4142; + var BAI_MAGIC = 0x1494142; + + var BamFlags = { + MULTIPLE_SEGMENTS: 0x1, + ALL_SEGMENTS_ALIGN: 0x2, + SEGMENT_UNMAPPED: 0x4, + NEXT_SEGMENT_UNMAPPED: 0x8, + REVERSE_COMPLEMENT: 0x10, + NEXT_REVERSE_COMPLEMENT: 0x20, + FIRST_SEGMENT: 0x40, + LAST_SEGMENT: 0x80, + SECONDARY_ALIGNMENT: 0x100, + QC_FAIL: 0x200, + DUPLICATE: 0x400, + SUPPLEMENTARY: 0x800 + }; + + function BamFile() {} + + // Calculate the length (in bytes) of the BAI ref starting at offset. + // Returns {nbin, length, minBlockIndex} + function _getBaiRefLength(uncba, offset) { + var p = offset; + var nbin = readInt(uncba, p); + p += 4; + + for (var b = 0; b < nbin; ++b) { + var bin = readInt(uncba, p); + var nchnk = readInt(uncba, p + 4); + p += 8 + (nchnk * 16); + } + + var nintv = readInt(uncba, p); + p += 4; + + var minBlockIndex = 1000000000; + var q = p; + + for (var i = 0; i < nintv; ++i) { + var v = readVob(uncba, q); + q += 8; + + if (v) { + var bi = v.block; + if (v.offset > 0) { + bi += 65536; + } + + if (bi < minBlockIndex) { + minBlockIndex = bi; + } + + break; + } + } + + p += (nintv * 8); + + return { + minBlockIndex: minBlockIndex, + nbin: nbin, + length: p - offset + }; + } + + function makeBam(data, bai, indexChunks, callback, attempted) { + // Do an initial probe on the BAM file to catch any mixed-content errors. + data.slice(0, 10).fetch(function(header) { + if (header) { + return makeBam2(data, bai, indexChunks, callback, attempted); + } else { + return callback(null, "Couldn't access BAM."); + } + }, { + timeout: 5000 + }); + } + + function makeBam2(data, bai, indexChunks, callback, attempted) { + var bam = new BamFile(); + bam.data = data; + bam.bai = bai; + bam.indexChunks = indexChunks; + + var minBlockIndex = bam.indexChunks ? bam.indexChunks.minBlockIndex : 1000000000; + + // Fills out bam.chrToIndex and bam.indexToChr based on the first few bytes of the BAM. + function parseBamHeader(r) { + if (!r) { + return callback(null, "Couldn't access BAM"); + } + + var unc = unbgzf(r, r.byteLength); + var uncba = new Uint8Array(unc); + + var magic = readInt(uncba, 0); + + if (magic != BAM_MAGIC) { + return callback(null, "Not a BAM file, magic=0x" + magic.toString(16)); + } + + var headLen = readInt(uncba, 4); + var header = ''; + + for (var i = 0; i < headLen; ++i) { + header += String.fromCharCode(uncba[i + 8]); + } + + var nRef = readInt(uncba, headLen + 8); + var p = headLen + 12; + + bam.chrToIndex = {}; + bam.indexToChr = []; + + for (var i = 0; i < nRef; ++i) { + var lName = readInt(uncba, p); + var name = ''; + + for (var j = 0; j < lName - 1; ++j) { + name += String.fromCharCode(uncba[p + 4 + j]); + } + + var lRef = readInt(uncba, p + lName + 4); + bam.chrToIndex[name] = i; + + if (name.indexOf('chr') == 0) { + bam.chrToIndex[name.substring(3)] = i; + } else { + bam.chrToIndex['chr' + name] = i; + } + + bam.indexToChr.push(name); + + p = p + 8 + lName; + } + + if (bam.indices) { + return callback(bam); + } + } + + function parseBai(header) { + if (!header) { + return "Couldn't access BAI"; + } + + var uncba = new Uint8Array(header); + var baiMagic = readInt(uncba, 0); + + if (baiMagic != BAI_MAGIC) { + return callback(null, 'Not a BAI file, magic=0x' + baiMagic.toString(16)); + } + + var nref = readInt(uncba, 4); + + bam.indices = []; + + var p = 8; + + for (var ref = 0; ref < nref; ++ref) { + var blockStart = p; + var o = _getBaiRefLength(uncba, blockStart); + p += o.length; + + minBlockIndex = Math.min(o.minBlockIndex, minBlockIndex); + + var nbin = o.nbin; + + if (nbin > 0) { + bam.indices[ref] = new Uint8Array(header, blockStart, p - blockStart); + } + } + + return true; + } + + if (!bam.indexChunks) { + bam.bai.fetch(function(header) { // Do we really need to fetch the whole thing? :-( + var result = parseBai(header); + + if (result !== true) { + if (bam.bai.url && typeof(attempted) === "undefined") { + // Already attempted x.bam.bai not there so now trying x.bai + bam.bai.url = bam.data.url.replace(new RegExp('.bam$'), '.bai'); + + // True lets us know we are making a second attempt + makeBam2(data, bam.bai, indexChunks, callback, true); + } else { + // We've attempted x.bam.bai & x.bai and nothing worked + callback(null, result); + } + } else { + bam.data.slice(0, minBlockIndex).fetch(parseBamHeader); + } + }); // Timeout on first request to catch Chrome mixed-content error. + } else { + var chunks = bam.indexChunks.chunks; + bam.indices = []; + + for (var i = 0; i < chunks.length; i++) { + bam.indices[i] = null; // To be filled out lazily as needed + } + + bam.data.slice(0, minBlockIndex).fetch(parseBamHeader); + } + } + + BamFile.prototype.blocksForRange = function(refId, min, max) { + var index = this.indices[refId]; + if (!index) { + return []; + } + + var intBinsL = reg2bins(min, max); + var intBins = []; + + for (var i = 0; i < intBinsL.length; ++i) { + intBins[intBinsL[i]] = true; + } + + var leafChunks = [], otherChunks = []; + var nbin = readInt(index, 0); + var p = 4; + + for (var b = 0; b < nbin; ++b) { + var bin = readInt(index, p); + var nchnk = readInt(index, p + 4); + // dlog('bin=' + bin + '; nchnk=' + nchnk); + p += 8; + + if (intBins[bin]) { + for (var c = 0; c < nchnk; ++c) { + var cs = readVob(index, p); + var ce = readVob(index, p + 8); + (bin < 4681 ? otherChunks : leafChunks).push(new Chunk(cs, ce)); + p += 16; + } + } else { + p += (nchnk * 16); + } + } + + // console.log('leafChunks = ' + miniJSONify(leafChunks)); + // console.log('otherChunks = ' + miniJSONify(otherChunks)); + + var nintv = readInt(index, p); + var lowest = null; + var minLin = Math.min(min >> 14, nintv - 1), maxLin = Math.min(max >> 14, nintv - 1); + + for (var i = minLin; i <= maxLin; ++i) { + var lb = readVob(index, p + 4 + (i * 8)); + + if (!lb) { + continue; + } + + if (!lowest || lb.block < lowest.block || lb.offset < lowest.offset) { + lowest = lb; + } + } + + // console.log('Lowest LB = ' + lowest); + + var prunedOtherChunks = []; + + if (lowest != null) { + for (var i = 0; i < otherChunks.length; ++i) { + var chnk = otherChunks[i]; + + if (chnk.maxv.block >= lowest.block && chnk.maxv.offset >= lowest.offset) { + prunedOtherChunks.push(chnk); + } + } + } + + // console.log('prunedOtherChunks = ' + miniJSONify(prunedOtherChunks)); + otherChunks = prunedOtherChunks; + + var intChunks = []; + + for (var i = 0; i < otherChunks.length; ++i) { + intChunks.push(otherChunks[i]); + } + + for (var i = 0; i < leafChunks.length; ++i) { + intChunks.push(leafChunks[i]); + } + + intChunks.sort(function(c0, c1) { + var dif = c0.minv.block - c1.minv.block; + + if (dif != 0) { + return dif; + } else { + return c0.minv.offset - c1.minv.offset; + } + }); + + var mergedChunks = []; + + if (intChunks.length > 0) { + var cur = intChunks[0]; + + for (var i = 1; i < intChunks.length; ++i) { + var nc = intChunks[i]; + + if (nc.minv.block == cur.maxv.block /* && nc.minv.offset == cur.maxv.offset */ ) { // no point splitting mid-block + cur = new Chunk(cur.minv, nc.maxv); + } else { + mergedChunks.push(cur); + cur = nc; + } + } + + mergedChunks.push(cur); + } + + // console.log('mergedChunks = ' + miniJSONify(mergedChunks)); + + return mergedChunks; + }; + + BamFile.prototype.fetch = function(chr, min, max, callback, opts) { + var thisB = this; + opts = opts || {}; + + var chrId = this.chrToIndex[chr]; + var chunks; + + if (chrId === undefined) { + chunks = []; + } else { + // Fetch this portion of the BAI if it hasn't been loaded yet. + if (this.indices[chrId] === null && this.indexChunks.chunks[chrId]) { + var start_stop = this.indexChunks.chunks[chrId]; + + return this.bai.slice(start_stop[0], start_stop[1]).fetch(function(data) { + var buffer = new Uint8Array(data); + this.indices[chrId] = buffer; + return this.fetch(chr, min, max, callback, opts); + }.bind(this)); + } + + chunks = this.blocksForRange(chrId, min, max); + + if (!chunks) { + callback(null, 'Error in index fetch'); + } + } + + var records = []; + var index = 0; + var data; + + function tramp() { + if (index >= chunks.length) { + return callback(records); + } else if (!data) { + var c = chunks[index]; + var fetchMin = c.minv.block; + var fetchMax = c.maxv.block + (1 << 16); // *sigh* + // console.log('fetching ' + fetchMin + ':' + fetchMax); + thisB.data.slice(fetchMin, fetchMax - fetchMin).fetch(function(r) { + data = unbgzf(r, c.maxv.block - c.minv.block + 1); + return tramp(); + }); + } else { + var ba = new Uint8Array(data); + var finished = thisB.readBamRecords(ba, chunks[index].minv.offset, records, min, max, chrId, opts); + data = null; + ++index; + + if (finished) { + return callback(records); + } else { + return tramp(); + } + } + } + + tramp(); + }; + + var SEQRET_DECODER = ['=', 'A', 'C', 'x', 'G', 'x', 'x', 'x', 'T', 'x', 'x', 'x', 'x', 'x', 'x', 'N']; + var CIGAR_DECODER = ['M', 'I', 'D', 'N', 'S', 'H', 'P', '=', 'X', '?', '?', '?', '?', '?', '?', '?']; + + function BamRecord() {} + + BamFile.prototype.readBamRecords = function(ba, offset, sink, min, max, chrId, opts) { + while (true) { + var blockSize = readInt(ba, offset); + var blockEnd = offset + blockSize + 4; + + if (blockEnd >= ba.length) { + return false; + } + + var record = new BamRecord(); + + var refID = readInt(ba, offset + 4); + var pos = readInt(ba, offset + 8); + + var bmn = readInt(ba, offset + 12); + var bin = (bmn & 0xffff0000) >> 16; + var mq = (bmn & 0xff00) >> 8; + var nl = bmn & 0xff; + + var flag_nc = readInt(ba, offset + 16); + var flag = (flag_nc & 0xffff0000) >> 16; + var nc = flag_nc & 0xffff; + + var lseq = readInt(ba, offset + 20); + + var nextRef = readInt(ba, offset + 24); + var nextPos = readInt(ba, offset + 28); + + var tlen = readInt(ba, offset + 32); + + record.segment = this.indexToChr[refID]; + record.flag = flag; + record.pos = pos; + record.mq = mq; + + if (opts.light) { + record.seqLength = lseq; + } + + if (!opts.light) { + if (nextRef >= 0) { + record.nextSegment = this.indexToChr[nextRef]; + record.nextPos = nextPos; + } + + var readName = ''; + + for (var j = 0; j < nl - 1; ++j) { + readName += String.fromCharCode(ba[offset + 36 + j]); + } + + record.readName = readName; + + var p = offset + 36 + nl; + + var cigar = ''; + + for (var c = 0; c < nc; ++c) { + var cigop = readInt(ba, p); + cigar = cigar + (cigop >> 4) + CIGAR_DECODER[cigop & 0xf]; + p += 4; + } + + record.cigar = cigar; + + var seq = ''; + var seqBytes = (lseq + 1) >> 1; + + for (var j = 0; j < seqBytes; ++j) { + var sb = ba[p + j]; + seq += SEQRET_DECODER[(sb & 0xf0) >> 4]; + + if (seq.length < lseq) { + seq += SEQRET_DECODER[(sb & 0x0f)]; + } + } + + p += seqBytes; + record.seq = seq; + + var qseq = ''; + + for (var j = 0; j < lseq; ++j) { + qseq += String.fromCharCode(ba[p + j] + 33); + } + + p += lseq; + record.quals = qseq; + + while (p < blockEnd) { + var tag = String.fromCharCode(ba[p], ba[p + 1]); + var type = String.fromCharCode(ba[p + 2]); + var value; + + if (type == 'A') { + value = String.fromCharCode(ba[p + 3]); + p += 4; + } else if (type == 'i' || type == 'I') { + value = readInt(ba, p + 3); + p += 7; + } else if (type == 'c' || type == 'C') { + value = ba[p + 3]; + p += 4; + } else if (type == 's' || type == 'S') { + value = readShort(ba, p + 3); + p += 5; + } else if (type == 'f') { + value = readFloat(ba, p + 3); + p += 7; + } else if (type == 'Z' || type == 'H') { + p += 3; + value = ''; + + for (;;) { + var cc = ba[p++]; + + if (cc == 0) { + break; + } else { + value += String.fromCharCode(cc); + } + } + } else if (type == 'B') { + var atype = String.fromCharCode(ba[p + 3]); + var alen = readInt(ba, p + 4); + var elen; + var reader; + + if (atype == 'i' || atype == 'I' || atype == 'f') { + elen = 4; + + if (atype == 'f') { + reader = readFloat; + } else { + reader = readInt; + } + } else if (atype == 's' || atype == 'S') { + elen = 2; + reader = readShort; + } else if (atype == 'c' || atype == 'C') { + elen = 1; + reader = readByte; + } else { + throw 'Unknown array type ' + atype; + } + + p += 8; + value = []; + + for (var i = 0; i < alen; ++i) { + value.push(reader(ba, p)); + p += elen; + } + } else { + throw 'Unknown type ' + type; + } + + record[tag] = value; + } + } + + if (!min || record.pos <= max && record.pos + lseq >= min) { + if (chrId === undefined || refID == chrId) { + sink.push(record); + } + } + + if (record.pos > max) { + return true; + } + + offset = blockEnd; + } + + // Exits via top of loop. + }; + + /*-------------------------------------------------------------------------------------------------------------------------------*/ + + window.dallianceLib = { + URLFetchable : URLFetchable, + BlobFetchable : BlobFetchable, + makeBam : makeBam + }; +})(); \ No newline at end of file diff --git a/js/lib/dalliance-lib.min.js b/js/lib/dalliance-lib.min.js new file mode 100644 index 00000000..d16a30df --- /dev/null +++ b/js/lib/dalliance-lib.min.js @@ -0,0 +1,71 @@ +(function(){function D(){}function z(){this.was=[0]}function C(a,b,c){this.hufts=new Int32Array(4320);this.window=new Uint8Array(c);this.end=c;this.checkfn=b;this.mode=0;this.reset(a,null);this.index=this.table=this.left=0;this.blens=null;this.bb=new Int32Array(1);this.tb=new Int32Array(1);this.codes=new E;this.check=this.write=this.read=this.bitb=this.bitk=this.last=0;this.inftree=new F}function E(){}function F(){}function y(a,b,c,d,h){if(0!=h){if(!a)throw"Undef src";if(!c)throw"Undef dest";if(0== +b&&h==a.length)c.set(a,d);else if(W)a=a.subarray(b,b+h),c.set(a,d);else if(1==a.BYTES_PER_ELEMENT&&100=d&&56320<=h&&57343>=h&&(d=65536+((d&1023)<<10)+(h&1023),c++),127>=d?b+=String.fromCharCode(d):2047>=d?b+=String.fromCharCode(192|d>>>6&31,128|d&63):65535>=d?b+=String.fromCharCode(224| +d>>>12&15,128|d>>>6&63,128|d&63):2097151>=d&&(b+=String.fromCharCode(240|d>>>18&7,128|d>>>12&63,128|d>>>6&63,128|d&63));a=Array(b.length>>2);for(c=0;c>5]|=(b.charCodeAt(c/8)&255)<<24-c%32;b=8*b.length;a[b>>5]|=128<<24-b%32;a[(b+64>>9<<4)+15]=b;b=Array(80);c=1732584193;d=-271733879;h=-1732584194;for(var e=271733878,g=-1009589776,f=0;fl;l++){if(16>l)b[l]=a[f+l];else{var t=b[l-3]^b[l-8]^b[l-14]^b[l- +16];b[l]=t<<1|t>>>31}var t=c<<5|c>>>27,s;s=20>l?d&h|~d&e:40>l?d^h^e:60>l?d&h|d&e|h&e:d^h^e;t=A(A(t,s),A(A(g,b[l]),20>l?1518500249:40>l?1859775393:60>l?-1894007588:-899497514));g=e;e=h;h=d<<30|d>>>2;d=c;c=t}c=A(c,k);d=A(d,m);h=A(h,p);e=A(e,q);g=A(g,n)}a=[c,d,h,e,g];b="";for(c=0;c<32*a.length;c+=8)b+=String.fromCharCode(a[c>>5]>>>24-c%32&255);a=b;b="";c=a.length;for(d=0;de;e++)b=8*d+6*e>8*a.length?b+"": +b+"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt(h>>>6*(3-e)&63);return b}function A(a,b){var c=(a&65535)+(b&65535);return(a>>16)+(b>>16)+(c>>16)<<16|c&65535}function L(a,b){this.block=a;this.offset=b}function H(a,b,c){var d=4294967296*(a[b+6]&255)+16777216*(a[b+5]&255)+65536*(a[b+4]&255)+256*(a[b+3]&255)+(a[b+2]&255);a=a[b+1]<<8|a[b];return 0!=d||0!=a||c?new L(d,a):null}function M(a,b){b=Math.min(b||1,a.byteLength-50);for(var c=[],d=[0],h=0;d[0]>26);c<=1+(b>>26);++c)d.push(c);for(c= +9+(a>>23);c<=9+(b>>23);++c)d.push(c);for(c=73+(a>>20);c<=73+(b>>20);++c)d.push(c);for(c=585+(a>>17);c<=585+(b>>17);++c)d.push(c);for(c=4681+(a>>14);c<=4681+(b>>14);++c)d.push(c);return d}function G(a){this.blob=a}function B(a,b,c,d){d||("object"===typeof b?(d=b,b=void 0):d={});this.url=a;this.start=b||0;c&&(this.end=c);this.opts=d}function O(a){if(!a)return null;for(var b=new Uint8Array(a.length),c=0;cb&&(b=-b,nowrap=1);if(8>b||15>4)+8>a.istate.wbits){a.istate.mode=13;a.msg="invalid window size";a.istate.marker=5;break}a.istate.mode=1;case 1:if(0==a.avail_in)return c;c=b;a.avail_in--;a.total_in++;d=a.next_in[a.next_in_index++]&255;if(0!=((a.istate.method<<8)+d)%31){a.istate.mode=13;a.msg="incorrect header check";a.istate.marker=5;break}if(0==(d&32)){a.istate.mode=7;break}a.istate.mode=2;case 2:if(0==a.avail_in)return c;c=b;a.avail_in--;a.total_in++;a.istate.need=(a.next_in[a.next_in_index++]& +255)<<24&4278190080;a.istate.mode=3;case 3:if(0==a.avail_in)return c;c=b;a.avail_in--;a.total_in++;a.istate.need+=(a.next_in[a.next_in_index++]&255)<<16&16711680;a.istate.mode=4;case 4:if(0==a.avail_in)return c;c=b;a.avail_in--;a.total_in++;a.istate.need+=(a.next_in[a.next_in_index++]&255)<<8&65280;a.istate.mode=5;case 5:if(0==a.avail_in)return c;a.avail_in--;a.total_in++;a.istate.need+=a.next_in[a.next_in_index++]&255;a.adler=a.istate.need;a.istate.mode=6;return 2;case 6:return a.istate.mode=13, +a.msg="need dictionary",a.istate.marker=0,-2;case 7:c=a.istate.blocks.proc(a,c);if(-3==c){a.istate.mode=13;a.istate.marker=0;break}0==c&&(c=b);if(1!=c)return c;c=b;a.istate.blocks.reset(a,a.istate.was);if(0!=a.istate.nowrap){a.istate.mode=12;break}a.istate.mode=8;case 8:if(0==a.avail_in)return c;c=b;a.avail_in--;a.total_in++;a.istate.need=(a.next_in[a.next_in_index++]&255)<<24&4278190080;a.istate.mode=9;case 9:if(0==a.avail_in)return c;c=b;a.avail_in--;a.total_in++;a.istate.need+=(a.next_in[a.next_in_index++]& +255)<<16&16711680;a.istate.mode=10;case 10:if(0==a.avail_in)return c;c=b;a.avail_in--;a.total_in++;a.istate.need+=(a.next_in[a.next_in_index++]&255)<<8&65280;a.istate.mode=11;case 11:if(0==a.avail_in)return c;c=b;a.avail_in--;a.total_in++;a.istate.need+=a.next_in[a.next_in_index++]&255;if(a.istate.was[0]!=a.istate.need){a.istate.mode=13;a.msg="incorrect data check";a.istate.marker=5;break}a.istate.mode=12;case 12:return 1;case 13:return-3;default:return-2}};z.prototype.inflateSetDictionary=function(a, +b,c){var d=0,h=c;if(null==a||null==a.istate||6!=a.istate.mode)return-2;if(a._adler.adler32(1,b,0,c)!=a.adler)return-3;a.adler=a._adler.adler32(0,null,0,0);h>=1<d;)a.next_in[c]==ga[d]?d++:d=0!=a.next_in[c]?0:4-d,c++,b--;a.total_in+=c-a.next_in_index;a.next_in_index=c;a.avail_in=b;a.istate.marker=d;if(4!=d)return-3;b=a.total_in;c=a.total_out;this.inflateReset(a);a.total_in=b;a.total_out=c;a.istate.mode=7;return 0};z.prototype.inflateSyncPoint=function(a){return null==a||null==a.istate||null==a.istate.blocks?-2:a.istate.blocks.sync_point()};var S=[16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15];C.prototype.reset=function(a,b){b&&(b[0]=this.check);6==this.mode&& +this.codes.free(a);this.read=this.write=this.bitb=this.bitk=this.mode=0;this.checkfn&&(a.adler=this.check=a._adler.adler32(0,null,0,0))};C.prototype.proc=function(a,b){var c,d,h,e,g,f,k;e=a.next_in_index;g=a.avail_in;d=this.bitb;h=this.bitk;f=this.write;for(k=fh;){if(0!=g)b=0;else return this.bitb=d,this.bitk=h,a.avail_in=g,a.total_in+=e-a.next_in_index,a.next_in_index=e,this.write=f,this.inflate_flush(a,b);g--;d|=(a.next_in[e++]& +255)<>>1){case 0:d>>>=3;h-=3;c=h&7;d>>>=c;h-=c;this.mode=1;break;case 1:var m=new Int32Array(1),p=new Int32Array(1),q=[],n=[];c=p;var l=q,t=n;m[0]=9;c[0]=5;l[0]=aa;t[0]=ba;this.codes.init(m[0],p[0],q[0],0,n[0],0,a);d>>>=3;h-=3;this.mode=6;break;case 2:d>>>=3;h-=3;this.mode=3;break;case 3:return d>>>=3,h-=3,this.mode=13,a.msg="invalid block type",b=-3,this.bitb=d,this.bitk=h,a.avail_in=g,a.total_in+=e-a.next_in_index,a.next_in_index=e,this.write=f,this.inflate_flush(a, +b)}break;case 1:for(;32>h;){if(0!=g)b=0;else return this.bitb=d,this.bitk=h,a.avail_in=g,a.total_in+=e-a.next_in_index,a.next_in_index=e,this.write=f,this.inflate_flush(a,b);g--;d|=(a.next_in[e++]&255)<>>16&65535)!=(d&65535))return this.mode=13,a.msg="invalid stored block lengths",b=-3,this.bitb=d,this.bitk=h,a.avail_in=g,a.total_in+=e-a.next_in_index,a.next_in_index=e,this.write=f,this.inflate_flush(a,b);this.left=d&65535;d=h=0;this.mode=0!=this.left?2:0!=this.last?7:0;break;case 2:if(0== +g)return this.bitb=d,this.bitk=h,a.avail_in=g,a.total_in+=e-a.next_in_index,a.next_in_index=e,write=f,this.inflate_flush(a,b);if(0==k&&(f==end&&0!=read&&(f=0,k=fg&&(c=g);c>k&&(c=k);y(a.next_in,e,this.window,f,c);e+=c;g-=c;f+=c;k-=c;if(0!=(this.left-=c))break;this.mode=0!=this.last?7:0;break;case 3:for(;14>h;){if(0!=g)b=0;else return this.bitb=d,this.bitk=h,a.avail_in=g,a.total_in+=e-a.next_in_index,a.next_in_index=e,this.write=f,this.inflate_flush(a,b);g--;d|=(a.next_in[e++]&255)<>5&31))return this.mode=9,a.msg="too many length or distance symbols",b=-3,this.bitb=d,this.bitk=h,a.avail_in= +g,a.total_in+=e-a.next_in_index,a.next_in_index=e,this.write=f,this.inflate_flush(a,b);c=258+(c&31)+(c>>5&31);if(null==this.blens||this.blens.length>>=14;h-=14;this.index=0;mode=4;case 4:for(;this.index<4+(this.table>>>10);){for(;3>h;){if(0!=g)b=0;else return this.bitb=d,this.bitk=h,a.avail_in=g,a.total_in+=e-a.next_in_index,a.next_in_index=e,this.write=f,this.inflate_flush(a,b);g--;d|=(a.next_in[e++]&255)<>>=3;h-=3}for(;19>this.index;)this.blens[S[this.index++]]=0;this.bb[0]=7;c=this.inftree.inflate_trees_bits(this.blens,this.bb,this.tb,this.hufts,a);if(0!=c)return b=c,-3==b&&(this.blens=null,this.mode=9),this.bitb=d,this.bitk=h,a.avail_in=g,a.total_in+=e-a.next_in_index,a.next_in_index=e,write=f,this.inflate_flush(a,b);this.index=0;this.mode=5;case 5:for(;;){c=this.table;if(!(this.index<258+(c&31)+(c>>5&31)))break;for(c=this.bb[0];hp)d>>>=c,h-=c,this.blens[this.index++]=p;else{k=18==p?7:p-14;for(m=18==p?11:3;h>>=c;h-=c;m+=d&x[k];d>>>= +k;h-=k;k=this.index;c=this.table;if(k+m>258+(c&31)+(c>>5&31)||16==p&&1>k)return this.blens=null,this.mode=9,a.msg="invalid bit length repeat",b=-3,this.bitb=d,this.bitk=h,a.avail_in=g,a.total_in+=e-a.next_in_index,a.next_in_index=e,this.write=f,this.inflate_flush(a,b);p=16==p?this.blens[k-1]:0;do this.blens[k++]=p;while(0!=--m);this.index=k}}this.tb[0]=-1;m=new Int32Array(1);p=new Int32Array(1);q=new Int32Array(1);n=new Int32Array(1);m[0]=9;p[0]=6;c=this.table;c=this.inftree.inflate_trees_dynamic(257+ +(c&31),1+(c>>5&31),this.blens,m,p,q,n,this.hufts,a);if(0!=c)return-3==c&&(this.blens=null,this.mode=13),b=c,this.bitb=d,this.bitk=h,a.avail_in=g,a.total_in+=e-a.next_in_index,a.next_in_index=e,this.write=f,this.inflate_flush(a,b);this.codes.init(m[0],p[0],this.hufts,q[0],this.hufts,n[0],a);this.mode=6;case 6:this.bitb=d;this.bitk=h;a.avail_in=g;a.total_in+=e-a.next_in_index;a.next_in_index=e;this.write=f;if(1!=(b=this.codes.proc(this,a,b)))return this.inflate_flush(a,b);b=0;this.codes.free(a);e=a.next_in_index; +g=a.avail_in;d=this.bitb;h=this.bitk;f=this.write;k=fa.avail_out&&(c=a.avail_out);0!=c&&-5==b&&(b=0);a.avail_out-=c;a.total_out+=c;null!=this.checkfn&&(a.adler=this.check=a._adler.adler32(this.check,this.window,h,c));y(this.window,h,a.next_out,d,c);d+=c;h+=c;h==this.end&&(h=0,this.write==this.end&&(this.write=0),c=this.write-h,c>a.avail_out&&(c=a.avail_out),0!=c&&-5==b&&(b=0),a.avail_out-=c,a.total_out+=c,null!=this.checkfn&&(a.adler=this.check=a._adler.adler32(this.check, +this.window,h,c)),y(this.window,h,a.next_out,d,c),d+=c,h+=c);a.next_out_index=d;this.read=h;return b};E.prototype.init=function(a,b,c,d,h,e,g){this.mode=0;this.lbits=a;this.dbits=b;this.ltree=c;this.ltree_index=d;this.dtree=h;this.dtree_index=e;this.tree=null};E.prototype.proc=function(a,b,c){var d,h,e=0,g=0,f=0,k,m,p,f=b.next_in_index;k=b.avail_in;e=a.bitb;g=a.bitk;m=a.write;for(p=m>>=this.tree[d+1];g-=this.tree[d+1];h=this.tree[d];if(0==h){this.lit=this.tree[d+2];this.mode=6;break}if(0!=(h&16)){this.get=h&15;this.len=this.tree[d+2];this.mode=2;break}if(0==(h&64)){this.need=h;this.tree_index=d/3+this.tree[d+2];break}if(0!=(h&32)){this.mode=7;break}this.mode=9;b.msg="invalid literal/length code";c=-3;a.bitb=e;a.bitk=g;b.avail_in=k;b.total_in+=f-b.next_in_index;b.next_in_index=f;a.write=m;return a.inflate_flush(b, +c);case 2:for(d=this.get;g>=d;g-=d;this.need=this.dbits;this.tree=this.dtree;this.tree_index=this.dtree_index;this.mode=3;case 3:for(d=this.need;g>=this.tree[d+1];g-=this.tree[d+1];h=this.tree[d];if(0!=(h&16)){this.get=h&15;this.dist=this.tree[d+2];this.mode=4;break}if(0==(h&64)){this.need=h;this.tree_index=d/3+this.tree[d+2];break}this.mode=9;b.msg="invalid distance code";c=-3;a.bitb=e;a.bitk=g;b.avail_in=k;b.total_in+=f-b.next_in_index;b.next_in_index=f;a.write=m;return a.inflate_flush(b,c);case 4:for(d=this.get;g>=d;g-=d;this.mode=5;case 5:for(d=m-this.dist;0>d;)d+=a.end;for(;0!=this.len;){if(0==p&&(m==a.end&&0!=a.read&&(m=0,p=mn;)t--,q|=(f.next_in[l++]&255)<>=m[v+1],n-=m[v+1],g.window[s++]=m[v+2],w--;else{do{q>>=m[v+1];n-=m[v+1];if(0!=(b&16)){b&=15;r=m[v+2]+(q&x[b]);q>>=b;for(n-=b;15> +n;)t--,q|=(f.next_in[l++]&255)<>=m[v+1],n-=m[v+1],0!=(b&16)){for(b&=15;n>=b;n-=b;w-=r;if(s>=k)k=s-k,g.window[s++]=g.window[k++],g.window[s++]=g.window[k++],r-=2;else{k=s-k;do k+=g.end;while(0>k);b=g.end-k;if(r>b){r-=b;if(0s-k){do g.window[s++]=g.window[k++];while(0!=--b)}else y(g.window,k,g.window,s,b),s+=b;k=0}}do g.window[s++]=g.window[k++];while(0!=--r);break}else if(0==(b&64))k+= +m[v+2],k+=q&x[b],v=3*(p+k),b=m[v];else return f.msg="invalid distance code",r=f.avail_in-t,r=n>>3>3:r,t+=r,l-=r,n-=r<<3,g.bitb=q,g.bitk=n,f.avail_in=t,f.total_in+=l-f.next_in_index,f.next_in_index=l,g.write=s,-3;while(1);break}if(0==(b&64)){if(k+=m[v+2],k+=q&x[b],v=3*(p+k),0==(b=m[v])){q>>=m[v+1];n-=m[v+1];g.window[s++]=m[v+2];w--;break}}else{if(0!=(b&32))return r=f.avail_in-t,r=n>>3>3:r,t+=r,l-=r,n-=r<<3,g.bitb=q,g.bitk=n,f.avail_in=t,f.total_in+=l-f.next_in_index,f.next_in_index=l,g.write= +s,1;f.msg="invalid literal/length code";r=f.avail_in-t;r=n>>3>3:r;t+=r;l-=r;n-=r<<3;g.bitb=q;g.bitk=n;f.avail_in=t;f.total_in+=l-f.next_in_index;f.next_in_index=l;g.write=s;return-3}}while(1)}}while(258<=w&&10<=t);r=f.avail_in-t;r=n>>3>3:r;l-=r;g.bitb=q;g.bitk=n-(r<<3);f.avail_in=t+r;f.total_in+=l-f.next_in_index;f.next_in_index=l;g.write=s;return 0};F.prototype.huft_build=function(a,b,c,d,h,e,g,f,k,m,p){var q,n,l,t,s,w,u,r,v;w=0;n=c;do this.c[a[b+w]]++,w++,n--;while(0!=n);if(this.c[0]== +c)return g[0]=-1,f[0]=0;s=f[0];for(l=1;15>=l&&0==this.c[l];l++);t=l;sn&&(s=n);f[0]=s;for(f=1<(f-=this.c[l]))return-3;if(0>(f-=this.c[n]))return-3;this.c[n]+=f;this.x[1]=l=0;w=1;for(u=2;0!=--n;)this.x[u]=l+=this.c[w],u++,w++;w=n=0;do 0!=(l=a[b+w])&&(this.v[this.x[l]++]=n),w++;while(++nr+s;){b++;r+=s;v=m-r;v=v>s?s:v;if((q=1<<(l= +t-r))>a+1&&(q-=a+1,u=t,l>>r-s,this.r[2]=u-this.u[b-1]-l,y(this.r,0,k,3*(this.u[b-1]+l),3)):g[0]=u}this.r[1]=t-r;w>=c?this.r[0]=192:p[w]this.v[w]?0:96,this.r[2]=this.v[w++]):(this.r[0]=e[this.v[w]-d]+16+64,this.r[2]=h[this.v[w++]-d]);q=1<>>r;l>>= +1)n^=l;n^=l;for(l=(1<b;b++)this.c[b]=0;for(b=0;3>b;b++)this.r[b]=0;y(this.c,0,this.u,0,15);y(this.c,0,this.x,0,16)};var W="function"===typeof(new Uint8Array(1)).subarray;L.prototype.toString=function(){return""+this.block+":"+this.offset};G.prototype.slice=function(a,b){var c;c=this.blob.slice?b?this.blob.slice(a,a+b):this.blob.slice(a): +b?this.blob.webkitSlice(a,a+b):this.blob.webkitSlice(a);return new G(c)};G.prototype.salted=function(){return this};G.prototype.fetch="undefined"!==typeof FileReader?function(a){var b=new FileReader;b.onloadend=function(c){a(O(b.result))};b.readAsBinaryString(this.blob)}:function(a){var b=new FileReaderSync;try{var c=b.readAsArrayBuffer(this.blob);a(c)}catch(d){a(null,d)}};B.prototype.slice=function(a,b){if(0>a)throw"Bad slice "+a;var c=this.start,d=this.end,c=c&&a?c+a:a||c;return new B(this.url, +c,b&&c?c+b-1:d||b-1,this.opts)};var T=0,U=0<=navigator.userAgent.indexOf("Safari")&&0>navigator.userAgent.indexOf("Chrome");B.prototype.fetchAsText=function(a){var b=this;this.getURL().then(function(c){try{var d=new XMLHttpRequest;(U||b.opts.salt)&&0>c.indexOf("?")&&(c=c+"?salt="+K(""+Date.now()+","+ ++T));d.open("GET",c,!0);if(b.end){if(1E8e.indexOf("?")&&(e=e+"?salt="+K(""+Date.now()+","+ ++T));f.open("GET",e,!0);f.overrideMimeType("text/plain; charset=x-user-defined");if(c.end){if(1E8m?g:a).push(new N(n,l));f+=16}else f+=16*p}e=u(d,f);h=null;b=Math.min(b>>14,e-1);c=Math.min(c>> +14,e-1);for(e=b;e<=c;++e)(b=H(d,f+4+8*e))&&(!h||b.block=h.block&&c.maxv.offset>=h.offset&&d.push(c);g=d;d=[];for(e=0;e=k.length)return d(p);if(n){var a=new Uint8Array(n),a=g.readBamRecords(a,k[q].minv.offset,p,b,c,f,h);n=null;++q;return a?d(p):e()}var m=k[q],a=m.minv.block;g.data.slice(a,m.maxv.block+65536-a).fetch(function(a){n=M(a,m.maxv.block-m.minv.block+1);return e()})}var g=this;h=h||{};var f=this.chrToIndex[a],k;if(void 0===f)k=[];else{if(null===this.indices[f]&&this.indexChunks.chunks[f]){var m=this.indexChunks.chunks[f];return this.bai.slice(m[0],m[1]).fetch(function(e){e= +new Uint8Array(e);this.indices[f]=e;return this.fetch(a,b,c,d,h)}.bind(this))}(k=this.blocksForRange(f,b,c))||d(null,"Error in index fetch")}var p=[],q=0,n;e()};var V="=ACxGxxxTxxxxxxN".split(""),ha="MIDNSHP=X???????".split("");I.prototype.readBamRecords=function(a,b,c,d,h,e,g){for(;;){var f=u(a,b),f=b+f+4;if(f>=a.length)return!1;var k=new Z,m=u(a,b+4),p=u(a,b+8),q=u(a,b+12),n=(q&65280)>>8,l=q&255,q=u(a,b+16),t=(q&4294901760)>>16,s=q&65535,q=u(a,b+20),w=u(a,b+24),x=u(a,b+28);u(a,b+32);k.segment=this.indexToChr[m]; +k.flag=t;k.pos=p;k.mq=n;g.light&&(k.seqLength=q);if(!g.light){0<=w&&(k.nextSegment=this.indexToChr[w],k.nextPos=x);n="";for(p=0;p>4)+ha[n&15],b+=4;k.cigar=l;s="";l=q+1>>1;for(p=0;p>4],s.length=d)void 0!==e&&m!=e||c.push(k);if(k.pos>h)return!0;b=f}};window.dallianceLib={URLFetchable:B,BlobFetchable:G,makeBam:function(a,b,c,d,h){a.slice(0,10).fetch(function(e){return e?R(a,b,c,d,h):d(null,"Couldn't access BAM.")},{timeout:5E3})}}})(); diff --git a/js/lib/jszlib/LICENSE.txt b/js/lib/jszlib/LICENSE.txt deleted file mode 100644 index d03a0b75..00000000 --- a/js/lib/jszlib/LICENSE.txt +++ /dev/null @@ -1,29 +0,0 @@ -jszlib is a Javascript zlib port based closely on jzlib, and is distributed -under the same BSD-style licence. - ------------------------------------------------------------------------------- -Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/js/lib/jszlib/README.md b/js/lib/jszlib/README.md deleted file mode 100644 index 809e11a3..00000000 --- a/js/lib/jszlib/README.md +++ /dev/null @@ -1,22 +0,0 @@ -JSZLib -====== - -JSZlib is a Javascript implementation of zlib, for modern web browsers. It uses -typed arrays instead of binary strings for storing data. Simplistic testing suggests -that this can give about a 2-fold speedup, and also means that JSZlib is a good -match for tools which use ArrayBuffers and/or typed arrays to access binary data. - -JSZlib currently just implements the "inflate" part of zlib, but there will hopefully -be a port of the "deflate" portion in the future. - -JSZlib is based very closely on jzlib (http://www.jcraft.com/jzlib/), and is distributed -under the same (BSD-style) license. The author of jzlib, ymnk, in turn credits Jean-loup -Gailly and Mark Adler for the original zlib code. - -Using it --------- - -Simplest way is just to call jszlib_uncompress. Takes an ArrayBuffer, returns an ArrayBuffer, -throws an exception if something breaks. You can also use a ZStream class which behaves -much like ZStream from jzlib. This might be useful if you need to uncompress partial data -- -some kinds of streaming network protocol, for instance -- but is overkill for most applications. \ No newline at end of file diff --git a/js/lib/jszlib/demo/gzip-test.html b/js/lib/jszlib/demo/gzip-test.html deleted file mode 100644 index c1222f89..00000000 --- a/js/lib/jszlib/demo/gzip-test.html +++ /dev/null @@ -1,10 +0,0 @@ - - - - - -

JSZLib test

-
-
- - diff --git a/js/lib/jszlib/demo/gzip-test.js b/js/lib/jszlib/demo/gzip-test.js deleted file mode 100644 index 99025cb5..00000000 --- a/js/lib/jszlib/demo/gzip-test.js +++ /dev/null @@ -1,73 +0,0 @@ -var DATA = [31,139,8,8,141,124,72,77,0,3,103,122,105,112,45,116,101,115,116,46,116,120,116,0,53,144,205,113,67,49,8,132,239,169,98,11,240,188,42,146,91,174,41,128,72,107,135,25,253,89,2,143,203,15,242,75,110,66,192,178,251,125,246,201,10,29,203,43,114,47,125,98,169,65,42,237,130,212,219,98,50,154,79,72,214,161,75,147,182,27,88,52,186,139,57,54,64,245,85,123,134,177,142,216,214,150,52,107,246,102,112,67,145,239,208,7,237,212,38,170,220,154,64,138,222,93,14,124,25,216,180,134,56,170,238,199,35,74,169,23,220,93,23,90,95,54,61,131,79,206,164,38,166,189,193,75,145,154,250,169,188,135,194,212,190,244,146,212,17,195,160,132,243,26,158,250,153,32,78,217,129,247,45,41,110,132,78,15,39,103,88,109,152,28,147,63,108,153,51,146,199,199,163,23,31,113,142,97,39,146,130,107,17,73,75,249,71,20,129,28,87,191,169,24,218,54,132,33,51,10,159,7,62,158,137,195,232,155,99,48,232,41,9,83,204,37,31,154,197,246,70,164,24,179,107,102,219,20,55,169,56,154,188,12,217,185,209,175,215,192,44,200,92,156,187,91,123,217,54,100,3,210,192,177,254,184,122,61,222,126,1,248,169,137,153,191,1,0,0]; - - -function handle() { - if (typeof ArrayBuffer !== 'function') { - dlog('We seem to be running on a browser without ArrayBuffer support'); - } - - var a = new Uint8Array(DATA.length); - for (var i = 0; i < DATA.length; ++i) { - a[i] = DATA[i]; - } - var inputBuffer = a.buffer; - - dlog('id1=' + a[0]); - dlog('id2=' + a[1]); - dlog('method=' + a[2]); - dlog('flags= ' + a[3]); - if (a[3] & 8) { - var idx = 10; - var name = '' - while (a[idx] != 0) { - name += String.fromCharCode(a[idx]); - ++idx; - } - dlog('Original name is ' + name); - } - - var resultBuffer = jszlib_inflate_buffer(inputBuffer, idx + 1, a.length - idx - 1); - dlog('Uncompressed size: ' + resultBuffer.length); - var s = '' - var resultBB = new Uint8Array(resultBuffer); - for (i = 0; i < resultBB.length; ++i) { - s += String.fromCharCode(resultBB[i]); - } - dlog(s); -} - -function dlog(msg) { - var logHolder = document.getElementById('log'); - if (logHolder) { - logHolder.appendChild(makeElement('p', msg)); - } -} - -function makeElement(tag, children, attribs, styles) -{ - var ele = document.createElement(tag); - if (children) { - if (! (children instanceof Array)) { - children = [children]; - } - for (var i = 0; i < children.length; ++i) { - var c = children[i]; - if (typeof c == 'string') { - c = document.createTextNode(c); - } - ele.appendChild(c); - } - } - - if (attribs) { - for (var l in attribs) { - ele[l] = attribs[l]; - } - } - if (styles) { - for (var l in styles) { - ele.style[l] = styles[l]; - } - } - return ele; -} \ No newline at end of file diff --git a/js/lib/jszlib/js/inflate.js b/js/lib/jszlib/js/inflate.js deleted file mode 100644 index a0b6af59..00000000 --- a/js/lib/jszlib/js/inflate.js +++ /dev/null @@ -1,2153 +0,0 @@ -/* -*- mode: javascript; c-basic-offset: 4; indent-tabs-mode: nil -*- */ - -// -// Javascript ZLib -// By Thomas Down 2010-2011 -// -// Based very heavily on portions of jzlib (by ymnk@jcraft.com), who in -// turn credits Jean-loup Gailly and Mark Adler for the original zlib code. -// -// inflate.js: ZLib inflate code -// - -// -// Shared constants -// - -var MAX_WBITS=15; // 32K LZ77 window -var DEF_WBITS=MAX_WBITS; -var MAX_MEM_LEVEL=9; -var MANY=1440; -var BMAX = 15; - -// preset dictionary flag in zlib header -var PRESET_DICT=0x20; - -var Z_NO_FLUSH=0; -var Z_PARTIAL_FLUSH=1; -var Z_SYNC_FLUSH=2; -var Z_FULL_FLUSH=3; -var Z_FINISH=4; - -var Z_DEFLATED=8; - -var Z_OK=0; -var Z_STREAM_END=1; -var Z_NEED_DICT=2; -var Z_ERRNO=-1; -var Z_STREAM_ERROR=-2; -var Z_DATA_ERROR=-3; -var Z_MEM_ERROR=-4; -var Z_BUF_ERROR=-5; -var Z_VERSION_ERROR=-6; - -var METHOD=0; // waiting for method byte -var FLAG=1; // waiting for flag byte -var DICT4=2; // four dictionary check bytes to go -var DICT3=3; // three dictionary check bytes to go -var DICT2=4; // two dictionary check bytes to go -var DICT1=5; // one dictionary check byte to go -var DICT0=6; // waiting for inflateSetDictionary -var BLOCKS=7; // decompressing blocks -var CHECK4=8; // four check bytes to go -var CHECK3=9; // three check bytes to go -var CHECK2=10; // two check bytes to go -var CHECK1=11; // one check byte to go -var DONE=12; // finished check, done -var BAD=13; // got an error--stay here - -var inflate_mask = [0x00000000, 0x00000001, 0x00000003, 0x00000007, 0x0000000f, 0x0000001f, 0x0000003f, 0x0000007f, 0x000000ff, 0x000001ff, 0x000003ff, 0x000007ff, 0x00000fff, 0x00001fff, 0x00003fff, 0x00007fff, 0x0000ffff]; - -var IB_TYPE=0; // get type bits (3, including end bit) -var IB_LENS=1; // get lengths for stored -var IB_STORED=2;// processing stored block -var IB_TABLE=3; // get table lengths -var IB_BTREE=4; // get bit lengths tree for a dynamic block -var IB_DTREE=5; // get length, distance trees for a dynamic block -var IB_CODES=6; // processing fixed or dynamic block -var IB_DRY=7; // output remaining window bytes -var IB_DONE=8; // finished last block, done -var IB_BAD=9; // ot a data error--stuck here - -var fixed_bl = 9; -var fixed_bd = 5; - -var fixed_tl = [ - 96,7,256, 0,8,80, 0,8,16, 84,8,115, - 82,7,31, 0,8,112, 0,8,48, 0,9,192, - 80,7,10, 0,8,96, 0,8,32, 0,9,160, - 0,8,0, 0,8,128, 0,8,64, 0,9,224, - 80,7,6, 0,8,88, 0,8,24, 0,9,144, - 83,7,59, 0,8,120, 0,8,56, 0,9,208, - 81,7,17, 0,8,104, 0,8,40, 0,9,176, - 0,8,8, 0,8,136, 0,8,72, 0,9,240, - 80,7,4, 0,8,84, 0,8,20, 85,8,227, - 83,7,43, 0,8,116, 0,8,52, 0,9,200, - 81,7,13, 0,8,100, 0,8,36, 0,9,168, - 0,8,4, 0,8,132, 0,8,68, 0,9,232, - 80,7,8, 0,8,92, 0,8,28, 0,9,152, - 84,7,83, 0,8,124, 0,8,60, 0,9,216, - 82,7,23, 0,8,108, 0,8,44, 0,9,184, - 0,8,12, 0,8,140, 0,8,76, 0,9,248, - 80,7,3, 0,8,82, 0,8,18, 85,8,163, - 83,7,35, 0,8,114, 0,8,50, 0,9,196, - 81,7,11, 0,8,98, 0,8,34, 0,9,164, - 0,8,2, 0,8,130, 0,8,66, 0,9,228, - 80,7,7, 0,8,90, 0,8,26, 0,9,148, - 84,7,67, 0,8,122, 0,8,58, 0,9,212, - 82,7,19, 0,8,106, 0,8,42, 0,9,180, - 0,8,10, 0,8,138, 0,8,74, 0,9,244, - 80,7,5, 0,8,86, 0,8,22, 192,8,0, - 83,7,51, 0,8,118, 0,8,54, 0,9,204, - 81,7,15, 0,8,102, 0,8,38, 0,9,172, - 0,8,6, 0,8,134, 0,8,70, 0,9,236, - 80,7,9, 0,8,94, 0,8,30, 0,9,156, - 84,7,99, 0,8,126, 0,8,62, 0,9,220, - 82,7,27, 0,8,110, 0,8,46, 0,9,188, - 0,8,14, 0,8,142, 0,8,78, 0,9,252, - 96,7,256, 0,8,81, 0,8,17, 85,8,131, - 82,7,31, 0,8,113, 0,8,49, 0,9,194, - 80,7,10, 0,8,97, 0,8,33, 0,9,162, - 0,8,1, 0,8,129, 0,8,65, 0,9,226, - 80,7,6, 0,8,89, 0,8,25, 0,9,146, - 83,7,59, 0,8,121, 0,8,57, 0,9,210, - 81,7,17, 0,8,105, 0,8,41, 0,9,178, - 0,8,9, 0,8,137, 0,8,73, 0,9,242, - 80,7,4, 0,8,85, 0,8,21, 80,8,258, - 83,7,43, 0,8,117, 0,8,53, 0,9,202, - 81,7,13, 0,8,101, 0,8,37, 0,9,170, - 0,8,5, 0,8,133, 0,8,69, 0,9,234, - 80,7,8, 0,8,93, 0,8,29, 0,9,154, - 84,7,83, 0,8,125, 0,8,61, 0,9,218, - 82,7,23, 0,8,109, 0,8,45, 0,9,186, - 0,8,13, 0,8,141, 0,8,77, 0,9,250, - 80,7,3, 0,8,83, 0,8,19, 85,8,195, - 83,7,35, 0,8,115, 0,8,51, 0,9,198, - 81,7,11, 0,8,99, 0,8,35, 0,9,166, - 0,8,3, 0,8,131, 0,8,67, 0,9,230, - 80,7,7, 0,8,91, 0,8,27, 0,9,150, - 84,7,67, 0,8,123, 0,8,59, 0,9,214, - 82,7,19, 0,8,107, 0,8,43, 0,9,182, - 0,8,11, 0,8,139, 0,8,75, 0,9,246, - 80,7,5, 0,8,87, 0,8,23, 192,8,0, - 83,7,51, 0,8,119, 0,8,55, 0,9,206, - 81,7,15, 0,8,103, 0,8,39, 0,9,174, - 0,8,7, 0,8,135, 0,8,71, 0,9,238, - 80,7,9, 0,8,95, 0,8,31, 0,9,158, - 84,7,99, 0,8,127, 0,8,63, 0,9,222, - 82,7,27, 0,8,111, 0,8,47, 0,9,190, - 0,8,15, 0,8,143, 0,8,79, 0,9,254, - 96,7,256, 0,8,80, 0,8,16, 84,8,115, - 82,7,31, 0,8,112, 0,8,48, 0,9,193, - - 80,7,10, 0,8,96, 0,8,32, 0,9,161, - 0,8,0, 0,8,128, 0,8,64, 0,9,225, - 80,7,6, 0,8,88, 0,8,24, 0,9,145, - 83,7,59, 0,8,120, 0,8,56, 0,9,209, - 81,7,17, 0,8,104, 0,8,40, 0,9,177, - 0,8,8, 0,8,136, 0,8,72, 0,9,241, - 80,7,4, 0,8,84, 0,8,20, 85,8,227, - 83,7,43, 0,8,116, 0,8,52, 0,9,201, - 81,7,13, 0,8,100, 0,8,36, 0,9,169, - 0,8,4, 0,8,132, 0,8,68, 0,9,233, - 80,7,8, 0,8,92, 0,8,28, 0,9,153, - 84,7,83, 0,8,124, 0,8,60, 0,9,217, - 82,7,23, 0,8,108, 0,8,44, 0,9,185, - 0,8,12, 0,8,140, 0,8,76, 0,9,249, - 80,7,3, 0,8,82, 0,8,18, 85,8,163, - 83,7,35, 0,8,114, 0,8,50, 0,9,197, - 81,7,11, 0,8,98, 0,8,34, 0,9,165, - 0,8,2, 0,8,130, 0,8,66, 0,9,229, - 80,7,7, 0,8,90, 0,8,26, 0,9,149, - 84,7,67, 0,8,122, 0,8,58, 0,9,213, - 82,7,19, 0,8,106, 0,8,42, 0,9,181, - 0,8,10, 0,8,138, 0,8,74, 0,9,245, - 80,7,5, 0,8,86, 0,8,22, 192,8,0, - 83,7,51, 0,8,118, 0,8,54, 0,9,205, - 81,7,15, 0,8,102, 0,8,38, 0,9,173, - 0,8,6, 0,8,134, 0,8,70, 0,9,237, - 80,7,9, 0,8,94, 0,8,30, 0,9,157, - 84,7,99, 0,8,126, 0,8,62, 0,9,221, - 82,7,27, 0,8,110, 0,8,46, 0,9,189, - 0,8,14, 0,8,142, 0,8,78, 0,9,253, - 96,7,256, 0,8,81, 0,8,17, 85,8,131, - 82,7,31, 0,8,113, 0,8,49, 0,9,195, - 80,7,10, 0,8,97, 0,8,33, 0,9,163, - 0,8,1, 0,8,129, 0,8,65, 0,9,227, - 80,7,6, 0,8,89, 0,8,25, 0,9,147, - 83,7,59, 0,8,121, 0,8,57, 0,9,211, - 81,7,17, 0,8,105, 0,8,41, 0,9,179, - 0,8,9, 0,8,137, 0,8,73, 0,9,243, - 80,7,4, 0,8,85, 0,8,21, 80,8,258, - 83,7,43, 0,8,117, 0,8,53, 0,9,203, - 81,7,13, 0,8,101, 0,8,37, 0,9,171, - 0,8,5, 0,8,133, 0,8,69, 0,9,235, - 80,7,8, 0,8,93, 0,8,29, 0,9,155, - 84,7,83, 0,8,125, 0,8,61, 0,9,219, - 82,7,23, 0,8,109, 0,8,45, 0,9,187, - 0,8,13, 0,8,141, 0,8,77, 0,9,251, - 80,7,3, 0,8,83, 0,8,19, 85,8,195, - 83,7,35, 0,8,115, 0,8,51, 0,9,199, - 81,7,11, 0,8,99, 0,8,35, 0,9,167, - 0,8,3, 0,8,131, 0,8,67, 0,9,231, - 80,7,7, 0,8,91, 0,8,27, 0,9,151, - 84,7,67, 0,8,123, 0,8,59, 0,9,215, - 82,7,19, 0,8,107, 0,8,43, 0,9,183, - 0,8,11, 0,8,139, 0,8,75, 0,9,247, - 80,7,5, 0,8,87, 0,8,23, 192,8,0, - 83,7,51, 0,8,119, 0,8,55, 0,9,207, - 81,7,15, 0,8,103, 0,8,39, 0,9,175, - 0,8,7, 0,8,135, 0,8,71, 0,9,239, - 80,7,9, 0,8,95, 0,8,31, 0,9,159, - 84,7,99, 0,8,127, 0,8,63, 0,9,223, - 82,7,27, 0,8,111, 0,8,47, 0,9,191, - 0,8,15, 0,8,143, 0,8,79, 0,9,255 -]; -var fixed_td = [ - 80,5,1, 87,5,257, 83,5,17, 91,5,4097, - 81,5,5, 89,5,1025, 85,5,65, 93,5,16385, - 80,5,3, 88,5,513, 84,5,33, 92,5,8193, - 82,5,9, 90,5,2049, 86,5,129, 192,5,24577, - 80,5,2, 87,5,385, 83,5,25, 91,5,6145, - 81,5,7, 89,5,1537, 85,5,97, 93,5,24577, - 80,5,4, 88,5,769, 84,5,49, 92,5,12289, - 82,5,13, 90,5,3073, 86,5,193, 192,5,24577 -]; - - // Tables for deflate from PKZIP's appnote.txt. - var cplens = [ // Copy lengths for literal codes 257..285 - 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, - 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0 - ]; - - // see note #13 above about 258 - var cplext = [ // Extra bits for literal codes 257..285 - 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, - 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 112, 112 // 112==invalid - ]; - - var cpdist = [ // Copy offsets for distance codes 0..29 - 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, - 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, - 8193, 12289, 16385, 24577 - ]; - - var cpdext = [ // Extra bits for distance codes - 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, - 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, - 12, 12, 13, 13]; - -// -// ZStream.java -// - -function ZStream() { -} - - -ZStream.prototype.inflateInit = function(w, nowrap) { - if (!w) { - w = DEF_WBITS; - } - if (nowrap) { - nowrap = false; - } - this.istate = new Inflate(); - return this.istate.inflateInit(this, nowrap?-w:w); -} - -ZStream.prototype.inflate = function(f) { - if(this.istate==null) return Z_STREAM_ERROR; - return this.istate.inflate(this, f); -} - -ZStream.prototype.inflateEnd = function(){ - if(this.istate==null) return Z_STREAM_ERROR; - var ret=istate.inflateEnd(this); - this.istate = null; - return ret; -} -ZStream.prototype.inflateSync = function(){ - // if(istate == null) return Z_STREAM_ERROR; - return istate.inflateSync(this); -} -ZStream.prototype.inflateSetDictionary = function(dictionary, dictLength){ - // if(istate == null) return Z_STREAM_ERROR; - return istate.inflateSetDictionary(this, dictionary, dictLength); -} - -/* - - public int deflateInit(int level){ - return deflateInit(level, MAX_WBITS); - } - public int deflateInit(int level, boolean nowrap){ - return deflateInit(level, MAX_WBITS, nowrap); - } - public int deflateInit(int level, int bits){ - return deflateInit(level, bits, false); - } - public int deflateInit(int level, int bits, boolean nowrap){ - dstate=new Deflate(); - return dstate.deflateInit(this, level, nowrap?-bits:bits); - } - public int deflate(int flush){ - if(dstate==null){ - return Z_STREAM_ERROR; - } - return dstate.deflate(this, flush); - } - public int deflateEnd(){ - if(dstate==null) return Z_STREAM_ERROR; - int ret=dstate.deflateEnd(); - dstate=null; - return ret; - } - public int deflateParams(int level, int strategy){ - if(dstate==null) return Z_STREAM_ERROR; - return dstate.deflateParams(this, level, strategy); - } - public int deflateSetDictionary (byte[] dictionary, int dictLength){ - if(dstate == null) - return Z_STREAM_ERROR; - return dstate.deflateSetDictionary(this, dictionary, dictLength); - } - -*/ - -/* - // Flush as much pending output as possible. All deflate() output goes - // through this function so some applications may wish to modify it - // to avoid allocating a large strm->next_out buffer and copying into it. - // (See also read_buf()). - void flush_pending(){ - int len=dstate.pending; - - if(len>avail_out) len=avail_out; - if(len==0) return; - - if(dstate.pending_buf.length<=dstate.pending_out || - next_out.length<=next_out_index || - dstate.pending_buf.length<(dstate.pending_out+len) || - next_out.length<(next_out_index+len)){ - System.out.println(dstate.pending_buf.length+", "+dstate.pending_out+ - ", "+next_out.length+", "+next_out_index+", "+len); - System.out.println("avail_out="+avail_out); - } - - System.arraycopy(dstate.pending_buf, dstate.pending_out, - next_out, next_out_index, len); - - next_out_index+=len; - dstate.pending_out+=len; - total_out+=len; - avail_out-=len; - dstate.pending-=len; - if(dstate.pending==0){ - dstate.pending_out=0; - } - } - - // Read a new buffer from the current input stream, update the adler32 - // and total number of bytes read. All deflate() input goes through - // this function so some applications may wish to modify it to avoid - // allocating a large strm->next_in buffer and copying from it. - // (See also flush_pending()). - int read_buf(byte[] buf, int start, int size) { - int len=avail_in; - - if(len>size) len=size; - if(len==0) return 0; - - avail_in-=len; - - if(dstate.noheader==0) { - adler=_adler.adler32(adler, next_in, next_in_index, len); - } - System.arraycopy(next_in, next_in_index, buf, start, len); - next_in_index += len; - total_in += len; - return len; - } - - public void free(){ - next_in=null; - next_out=null; - msg=null; - _adler=null; - } -} -*/ - - -// -// Inflate.java -// - -function Inflate() { - this.was = [0]; -} - -Inflate.prototype.inflateReset = function(z) { - if(z == null || z.istate == null) return Z_STREAM_ERROR; - - z.total_in = z.total_out = 0; - z.msg = null; - z.istate.mode = z.istate.nowrap!=0 ? BLOCKS : METHOD; - z.istate.blocks.reset(z, null); - return Z_OK; -} - -Inflate.prototype.inflateEnd = function(z){ - if(this.blocks != null) - this.blocks.free(z); - this.blocks=null; - return Z_OK; -} - -Inflate.prototype.inflateInit = function(z, w){ - z.msg = null; - this.blocks = null; - - // handle undocumented nowrap option (no zlib header or check) - nowrap = 0; - if(w < 0){ - w = - w; - nowrap = 1; - } - - // set window size - if(w<8 ||w>15){ - this.inflateEnd(z); - return Z_STREAM_ERROR; - } - this.wbits=w; - - z.istate.blocks=new InfBlocks(z, - z.istate.nowrap!=0 ? null : this, - 1<>4)+8>z.istate.wbits){ - z.istate.mode = BAD; - z.msg="invalid window size"; - z.istate.marker = 5; // can't try inflateSync - break; - } - z.istate.mode=FLAG; - case FLAG: - - if(z.avail_in==0)return r;r=f; - - z.avail_in--; z.total_in++; - b = (z.next_in[z.next_in_index++])&0xff; - - if((((z.istate.method << 8)+b) % 31)!=0){ - z.istate.mode = BAD; - z.msg = "incorrect header check"; - z.istate.marker = 5; // can't try inflateSync - break; - } - - if((b&PRESET_DICT)==0){ - z.istate.mode = BLOCKS; - break; - } - z.istate.mode = DICT4; - case DICT4: - - if(z.avail_in==0)return r;r=f; - - z.avail_in--; z.total_in++; - z.istate.need=((z.next_in[z.next_in_index++]&0xff)<<24)&0xff000000; - z.istate.mode=DICT3; - case DICT3: - - if(z.avail_in==0)return r;r=f; - - z.avail_in--; z.total_in++; - z.istate.need+=((z.next_in[z.next_in_index++]&0xff)<<16)&0xff0000; - z.istate.mode=DICT2; - case DICT2: - - if(z.avail_in==0)return r;r=f; - - z.avail_in--; z.total_in++; - z.istate.need+=((z.next_in[z.next_in_index++]&0xff)<<8)&0xff00; - z.istate.mode=DICT1; - case DICT1: - - if(z.avail_in==0)return r;r=f; - - z.avail_in--; z.total_in++; - z.istate.need += (z.next_in[z.next_in_index++]&0xff); - z.adler = z.istate.need; - z.istate.mode = DICT0; - return Z_NEED_DICT; - case DICT0: - z.istate.mode = BAD; - z.msg = "need dictionary"; - z.istate.marker = 0; // can try inflateSync - return Z_STREAM_ERROR; - case BLOCKS: - - r = z.istate.blocks.proc(z, r); - if(r == Z_DATA_ERROR){ - z.istate.mode = BAD; - z.istate.marker = 0; // can try inflateSync - break; - } - if(r == Z_OK){ - r = f; - } - if(r != Z_STREAM_END){ - return r; - } - r = f; - z.istate.blocks.reset(z, z.istate.was); - if(z.istate.nowrap!=0){ - z.istate.mode=DONE; - break; - } - z.istate.mode=CHECK4; - case CHECK4: - - if(z.avail_in==0)return r;r=f; - - z.avail_in--; z.total_in++; - z.istate.need=((z.next_in[z.next_in_index++]&0xff)<<24)&0xff000000; - z.istate.mode=CHECK3; - case CHECK3: - - if(z.avail_in==0)return r;r=f; - - z.avail_in--; z.total_in++; - z.istate.need+=((z.next_in[z.next_in_index++]&0xff)<<16)&0xff0000; - z.istate.mode = CHECK2; - case CHECK2: - - if(z.avail_in==0)return r;r=f; - - z.avail_in--; z.total_in++; - z.istate.need+=((z.next_in[z.next_in_index++]&0xff)<<8)&0xff00; - z.istate.mode = CHECK1; - case CHECK1: - - if(z.avail_in==0)return r;r=f; - - z.avail_in--; z.total_in++; - z.istate.need+=(z.next_in[z.next_in_index++]&0xff); - - if(((z.istate.was[0])) != ((z.istate.need))){ - z.istate.mode = BAD; - z.msg = "incorrect data check"; - z.istate.marker = 5; // can't try inflateSync - break; - } - - z.istate.mode = DONE; - case DONE: - return Z_STREAM_END; - case BAD: - return Z_DATA_ERROR; - default: - return Z_STREAM_ERROR; - } - } - } - - -Inflate.prototype.inflateSetDictionary = function(z, dictionary, dictLength) { - var index=0; - var length = dictLength; - if(z==null || z.istate == null|| z.istate.mode != DICT0) - return Z_STREAM_ERROR; - - if(z._adler.adler32(1, dictionary, 0, dictLength)!=z.adler){ - return Z_DATA_ERROR; - } - - z.adler = z._adler.adler32(0, null, 0, 0); - - if(length >= (1<>> 1){ - case 0: // stored - {b>>>=(3);k-=(3);} - t = k & 7; // go to byte boundary - - {b>>>=(t);k-=(t);} - this.mode = IB_LENS; // get length of stored block - break; - case 1: // fixed - { - var bl=new Int32Array(1); - var bd=new Int32Array(1); - var tl=[]; - var td=[]; - - inflate_trees_fixed(bl, bd, tl, td, z); - this.codes.init(bl[0], bd[0], tl[0], 0, td[0], 0, z); - } - - {b>>>=(3);k-=(3);} - - this.mode = IB_CODES; - break; - case 2: // dynamic - - {b>>>=(3);k-=(3);} - - this.mode = IB_TABLE; - break; - case 3: // illegal - - {b>>>=(3);k-=(3);} - this.mode = BAD; - z.msg = "invalid block type"; - r = Z_DATA_ERROR; - - this.bitb=b; this.bitk=k; - z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; - this.write=q; - return this.inflate_flush(z,r); - } - break; - case IB_LENS: - while(k<(32)){ - if(n!=0){ - r=Z_OK; - } - else{ - this.bitb=b; this.bitk=k; - z.avail_in=n; - z.total_in+=p-z.next_in_index;z.next_in_index=p; - this.write=q; - return this.inflate_flush(z,r); - }; - n--; - b|=(z.next_in[p++]&0xff)<>> 16) & 0xffff) != (b & 0xffff)){ - this.mode = BAD; - z.msg = "invalid stored block lengths"; - r = Z_DATA_ERROR; - - this.bitb=b; this.bitk=k; - z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; - this.write=q; - return this.inflate_flush(z,r); - } - this.left = (b & 0xffff); - b = k = 0; // dump bits - this.mode = left!=0 ? IB_STORED : (this.last!=0 ? IB_DRY : IB_TYPE); - break; - case IB_STORED: - if (n == 0){ - this.bitb=b; this.bitk=k; - z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; - write=q; - return this.inflate_flush(z,r); - } - - if(m==0){ - if(q==end&&read!=0){ - q=0; m=(qn) t = n; - if(t>m) t = m; - arrayCopy(z.next_in, p, window, q, t); - p += t; n -= t; - q += t; m -= t; - if ((this.left -= t) != 0) - break; - this.mode = (this.last != 0 ? IB_DRY : IB_TYPE); - break; - case IB_TABLE: - - while(k<(14)){ - if(n!=0){ - r=Z_OK; - } - else{ - this.bitb=b; this.bitk=k; - z.avail_in=n; - z.total_in+=p-z.next_in_index;z.next_in_index=p; - this.write=q; - return this.inflate_flush(z,r); - }; - n--; - b|=(z.next_in[p++]&0xff)< 29 || ((t >> 5) & 0x1f) > 29) - { - this.mode = IB_BAD; - z.msg = "too many length or distance symbols"; - r = Z_DATA_ERROR; - - this.bitb=b; this.bitk=k; - z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; - this.write=q; - return this.inflate_flush(z,r); - } - t = 258 + (t & 0x1f) + ((t >> 5) & 0x1f); - if(this.blens==null || this.blens.length>>=(14);k-=(14);} - - this.index = 0; - mode = IB_BTREE; - case IB_BTREE: - while (this.index < 4 + (this.table >>> 10)){ - while(k<(3)){ - if(n!=0){ - r=Z_OK; - } - else{ - this.bitb=b; this.bitk=k; - z.avail_in=n; - z.total_in+=p-z.next_in_index;z.next_in_index=p; - this.write=q; - return this.inflate_flush(z,r); - }; - n--; - b|=(z.next_in[p++]&0xff)<>>=(3);k-=(3);} - } - - while(this.index < 19){ - this.blens[INFBLOCKS_BORDER[this.index++]] = 0; - } - - this.bb[0] = 7; - t = this.inftree.inflate_trees_bits(this.blens, this.bb, this.tb, this.hufts, z); - if (t != Z_OK){ - r = t; - if (r == Z_DATA_ERROR){ - this.blens=null; - this.mode = IB_BAD; - } - - this.bitb=b; this.bitk=k; - z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; - write=q; - return this.inflate_flush(z,r); - } - - this.index = 0; - this.mode = IB_DTREE; - case IB_DTREE: - while (true){ - t = this.table; - if(!(this.index < 258 + (t & 0x1f) + ((t >> 5) & 0x1f))){ - break; - } - - var h; //int[] - var i, j, c; - - t = this.bb[0]; - - while(k<(t)){ - if(n!=0){ - r=Z_OK; - } - else{ - this.bitb=b; this.bitk=k; - z.avail_in=n; - z.total_in+=p-z.next_in_index;z.next_in_index=p; - this.write=q; - return this.inflate_flush(z,r); - }; - n--; - b|=(z.next_in[p++]&0xff)<>>=(t);k-=(t); - this.blens[this.index++] = c; - } - else { // c == 16..18 - i = c == 18 ? 7 : c - 14; - j = c == 18 ? 11 : 3; - - while(k<(t+i)){ - if(n!=0){ - r=Z_OK; - } - else{ - this.bitb=b; this.bitk=k; - z.avail_in=n; - z.total_in+=p-z.next_in_index;z.next_in_index=p; - this.write=q; - return this.inflate_flush(z,r); - }; - n--; - b|=(z.next_in[p++]&0xff)<>>=(t);k-=(t); - - j += (b & inflate_mask[i]); - - b>>>=(i);k-=(i); - - i = this.index; - t = this.table; - if (i + j > 258 + (t & 0x1f) + ((t >> 5) & 0x1f) || - (c == 16 && i < 1)){ - this.blens=null; - this.mode = IB_BAD; - z.msg = "invalid bit length repeat"; - r = Z_DATA_ERROR; - - this.bitb=b; this.bitk=k; - z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; - this.write=q; - return this.inflate_flush(z,r); - } - - c = c == 16 ? this.blens[i-1] : 0; - do{ - this.blens[i++] = c; - } - while (--j!=0); - this.index = i; - } - } - - this.tb[0]=-1; - { - var bl=new Int32Array(1); - var bd=new Int32Array(1); - var tl=new Int32Array(1); - var td=new Int32Array(1); - bl[0] = 9; // must be <= 9 for lookahead assumptions - bd[0] = 6; // must be <= 9 for lookahead assumptions - - t = this.table; - t = this.inftree.inflate_trees_dynamic(257 + (t & 0x1f), - 1 + ((t >> 5) & 0x1f), - this.blens, bl, bd, tl, td, this.hufts, z); - - if (t != Z_OK){ - if (t == Z_DATA_ERROR){ - this.blens=null; - this.mode = BAD; - } - r = t; - - this.bitb=b; this.bitk=k; - z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; - this.write=q; - return this.inflate_flush(z,r); - } - this.codes.init(bl[0], bd[0], this.hufts, tl[0], this.hufts, td[0], z); - } - this.mode = IB_CODES; - case IB_CODES: - this.bitb=b; this.bitk=k; - z.avail_in=n; z.total_in+=p-z.next_in_index;z.next_in_index=p; - this.write=q; - - if ((r = this.codes.proc(this, z, r)) != Z_STREAM_END){ - return this.inflate_flush(z, r); - } - r = Z_OK; - this.codes.free(z); - - p=z.next_in_index; n=z.avail_in;b=this.bitb;k=this.bitk; - q=this.write;m = (q < this.read ? this.read-q-1 : this.end-q); - - if (this.last==0){ - this.mode = IB_TYPE; - break; - } - this.mode = IB_DRY; - case IB_DRY: - this.write=q; - r = this.inflate_flush(z, r); - q=this.write; m = (q < this.read ? this.read-q-1 : this.end-q); - if (this.read != this.write){ - this.bitb=b; this.bitk=k; - z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; - this.write=q; - return this.inflate_flush(z, r); - } - mode = DONE; - case IB_DONE: - r = Z_STREAM_END; - - this.bitb=b; this.bitk=k; - z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; - this.write=q; - return this.inflate_flush(z, r); - case IB_BAD: - r = Z_DATA_ERROR; - - this.bitb=b; this.bitk=k; - z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; - this.write=q; - return this.inflate_flush(z, r); - - default: - r = Z_STREAM_ERROR; - - this.bitb=b; this.bitk=k; - z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; - this.write=q; - return this.inflate_flush(z, r); - } - } - } - -InfBlocks.prototype.free = function(z){ - this.reset(z, null); - this.window=null; - this.hufts=null; -} - -InfBlocks.prototype.set_dictionary = function(d, start, n){ - arrayCopy(d, start, window, 0, n); - this.read = this.write = n; -} - - // Returns true if inflate is currently at the end of a block generated - // by Z_SYNC_FLUSH or Z_FULL_FLUSH. -InfBlocks.prototype.sync_point = function(){ - return this.mode == IB_LENS; -} - - // copy as much as possible from the sliding window to the output area -InfBlocks.prototype.inflate_flush = function(z, r){ - var n; - var p; - var q; - - // local copies of source and destination pointers - p = z.next_out_index; - q = this.read; - - // compute number of bytes to copy as far as end of window - n = ((q <= this.write ? this.write : this.end) - q); - if (n > z.avail_out) n = z.avail_out; - if (n!=0 && r == Z_BUF_ERROR) r = Z_OK; - - // update counters - z.avail_out -= n; - z.total_out += n; - - // update check information - if(this.checkfn != null) - z.adler=this.check=z._adler.adler32(this.check, this.window, q, n); - - // copy as far as end of window - arrayCopy(this.window, q, z.next_out, p, n); - p += n; - q += n; - - // see if more to copy at beginning of window - if (q == this.end){ - // wrap pointers - q = 0; - if (this.write == this.end) - this.write = 0; - - // compute bytes to copy - n = this.write - q; - if (n > z.avail_out) n = z.avail_out; - if (n!=0 && r == Z_BUF_ERROR) r = Z_OK; - - // update counters - z.avail_out -= n; - z.total_out += n; - - // update check information - if(this.checkfn != null) - z.adler=this.check=z._adler.adler32(this.check, this.window, q, n); - - // copy - arrayCopy(this.window, q, z.next_out, p, n); - p += n; - q += n; - } - - // update pointers - z.next_out_index = p; - this.read = q; - - // done - return r; - } - -// -// InfCodes.java -// - -var IC_START=0; // x: set up for LEN -var IC_LEN=1; // i: get length/literal/eob next -var IC_LENEXT=2; // i: getting length extra (have base) -var IC_DIST=3; // i: get distance next -var IC_DISTEXT=4;// i: getting distance extra -var IC_COPY=5; // o: copying bytes in window, waiting for space -var IC_LIT=6; // o: got literal, waiting for output space -var IC_WASH=7; // o: got eob, possibly still output waiting -var IC_END=8; // x: got eob and all data flushed -var IC_BADCODE=9;// x: got error - -function InfCodes() { -} - -InfCodes.prototype.init = function(bl, bd, tl, tl_index, td, td_index, z) { - this.mode=IC_START; - this.lbits=bl; - this.dbits=bd; - this.ltree=tl; - this.ltree_index=tl_index; - this.dtree = td; - this.dtree_index=td_index; - this.tree=null; -} - -InfCodes.prototype.proc = function(s, z, r){ - var j; // temporary storage - var t; // temporary pointer (int[]) - var tindex; // temporary pointer - var e; // extra bits or operation - var b=0; // bit buffer - var k=0; // bits in bit buffer - var p=0; // input data pointer - var n; // bytes available there - var q; // output window write pointer - var m; // bytes to end of window or read pointer - var f; // pointer to copy strings from - - // copy input/output information to locals (UPDATE macro restores) - p=z.next_in_index;n=z.avail_in;b=s.bitb;k=s.bitk; - q=s.write;m=q= 258 && n >= 10){ - - s.bitb=b;s.bitk=k; - z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; - s.write=q; - r = this.inflate_fast(this.lbits, this.dbits, - this.ltree, this.ltree_index, - this.dtree, this.dtree_index, - s, z); - - p=z.next_in_index;n=z.avail_in;b=s.bitb;k=s.bitk; - q=s.write;m=q>>=(this.tree[tindex+1]); - k-=(this.tree[tindex+1]); - - e=this.tree[tindex]; - - if(e == 0){ // literal - this.lit = this.tree[tindex+2]; - this.mode = IC_LIT; - break; - } - if((e & 16)!=0 ){ // length - this.get = e & 15; - this.len = this.tree[tindex+2]; - this.mode = IC_LENEXT; - break; - } - if ((e & 64) == 0){ // next table - this.need = e; - this.tree_index = tindex/3 + this.tree[tindex+2]; - break; - } - if ((e & 32)!=0){ // end of block - this.mode = IC_WASH; - break; - } - this.mode = IC_BADCODE; // invalid code - z.msg = "invalid literal/length code"; - r = Z_DATA_ERROR; - - s.bitb=b;s.bitk=k; - z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; - s.write=q; - return s.inflate_flush(z,r); - - case IC_LENEXT: // i: getting length extra (have base) - j = this.get; - - while(k<(j)){ - if(n!=0)r=Z_OK; - else{ - - s.bitb=b;s.bitk=k; - z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; - s.write=q; - return s.inflate_flush(z,r); - } - n--; b|=(z.next_in[p++]&0xff)<>=j; - k-=j; - - this.need = this.dbits; - this.tree = this.dtree; - this.tree_index = this.dtree_index; - this.mode = IC_DIST; - case IC_DIST: // i: get distance next - j = this.need; - - while(k<(j)){ - if(n!=0)r=Z_OK; - else{ - - s.bitb=b;s.bitk=k; - z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; - s.write=q; - return s.inflate_flush(z,r); - } - n--; b|=(z.next_in[p++]&0xff)<>=this.tree[tindex+1]; - k-=this.tree[tindex+1]; - - e = (this.tree[tindex]); - if((e & 16)!=0){ // distance - this.get = e & 15; - this.dist = this.tree[tindex+2]; - this.mode = IC_DISTEXT; - break; - } - if ((e & 64) == 0){ // next table - this.need = e; - this.tree_index = tindex/3 + this.tree[tindex+2]; - break; - } - this.mode = IC_BADCODE; // invalid code - z.msg = "invalid distance code"; - r = Z_DATA_ERROR; - - s.bitb=b;s.bitk=k; - z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; - s.write=q; - return s.inflate_flush(z,r); - - case IC_DISTEXT: // i: getting distance extra - j = this.get; - - while(k<(j)){ - if(n!=0)r=Z_OK; - else{ - - s.bitb=b;s.bitk=k; - z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; - s.write=q; - return s.inflate_flush(z,r); - } - n--; b|=(z.next_in[p++]&0xff)<>=j; - k-=j; - - this.mode = IC_COPY; - case IC_COPY: // o: copying bytes in window, waiting for space - f = q - this.dist; - while(f < 0){ // modulo window size-"while" instead - f += s.end; // of "if" handles invalid distances - } - while (this.len!=0){ - - if(m==0){ - if(q==s.end&&s.read!=0){q=0;m=q 7){ // return unused byte, if any - k -= 8; - n++; - p--; // can always return one - } - - s.write=q; r=s.inflate_flush(z,r); - q=s.write;m=q= 258 && n >= 10 - // get literal/length code - while(k<(20)){ // max bits for literal/length code - n--; - b|=(z.next_in[p++]&0xff)<>=(tp[tp_index_t_3+1]); k-=(tp[tp_index_t_3+1]); - - s.window[q++] = tp[tp_index_t_3+2]; - m--; - continue; - } - do { - - b>>=(tp[tp_index_t_3+1]); k-=(tp[tp_index_t_3+1]); - - if((e&16)!=0){ - e &= 15; - c = tp[tp_index_t_3+2] + (b & inflate_mask[e]); - - b>>=e; k-=e; - - // decode distance base of block to copy - while(k<(15)){ // max bits for distance code - n--; - b|=(z.next_in[p++]&0xff)<>=(tp[tp_index_t_3+1]); k-=(tp[tp_index_t_3+1]); - - if((e&16)!=0){ - // get extra bits to add to distance base - e &= 15; - while(k<(e)){ // get extra bits (up to 13) - n--; - b|=(z.next_in[p++]&0xff)<>=(e); k-=(e); - - // do the copy - m -= c; - if (q >= d){ // offset before dest - // just copy - r=q-d; - if(q-r>0 && 2>(q-r)){ - s.window[q++]=s.window[r++]; // minimum count is three, - s.window[q++]=s.window[r++]; // so unroll loop a little - c-=2; - } - else{ - s.window[q++]=s.window[r++]; // minimum count is three, - s.window[q++]=s.window[r++]; // so unroll loop a little - c-=2; - } - } - else{ // else offset after destination - r=q-d; - do{ - r+=s.end; // force pointer in window - }while(r<0); // covers invalid distances - e=s.end-r; - if(c>e){ // if source crosses, - c-=e; // wrapped copy - if(q-r>0 && e>(q-r)){ - do{s.window[q++] = s.window[r++];} - while(--e!=0); - } - else{ - arrayCopy(s.window, r, s.window, q, e); - q+=e; r+=e; e=0; - } - r = 0; // copy rest from start of window - } - - } - - // copy all or what's left - do{s.window[q++] = s.window[r++];} - while(--c!=0); - break; - } - else if((e&64)==0){ - t+=tp[tp_index_t_3+2]; - t+=(b&inflate_mask[e]); - tp_index_t_3=(tp_index+t)*3; - e=tp[tp_index_t_3]; - } - else{ - z.msg = "invalid distance code"; - - c=z.avail_in-n;c=(k>>3)>3:c;n+=c;p-=c;k-=c<<3; - - s.bitb=b;s.bitk=k; - z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; - s.write=q; - - return Z_DATA_ERROR; - } - } - while(true); - break; - } - - if((e&64)==0){ - t+=tp[tp_index_t_3+2]; - t+=(b&inflate_mask[e]); - tp_index_t_3=(tp_index+t)*3; - if((e=tp[tp_index_t_3])==0){ - - b>>=(tp[tp_index_t_3+1]); k-=(tp[tp_index_t_3+1]); - - s.window[q++]=tp[tp_index_t_3+2]; - m--; - break; - } - } - else if((e&32)!=0){ - - c=z.avail_in-n;c=(k>>3)>3:c;n+=c;p-=c;k-=c<<3; - - s.bitb=b;s.bitk=k; - z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; - s.write=q; - - return Z_STREAM_END; - } - else{ - z.msg="invalid literal/length code"; - - c=z.avail_in-n;c=(k>>3)>3:c;n+=c;p-=c;k-=c<<3; - - s.bitb=b;s.bitk=k; - z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; - s.write=q; - - return Z_DATA_ERROR; - } - } - while(true); - } - while(m>=258 && n>= 10); - - // not enough input or output--restore pointers and return - c=z.avail_in-n;c=(k>>3)>3:c;n+=c;p-=c;k-=c<<3; - - s.bitb=b;s.bitk=k; - z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; - s.write=q; - - return Z_OK; -} - -// -// InfTree.java -// - -function InfTree() { -} - -InfTree.prototype.huft_build = function(b, bindex, n, s, d, e, t, m, hp, hn, v) { - - // Given a list of code lengths and a maximum table size, make a set of - // tables to decode that set of codes. Return Z_OK on success, Z_BUF_ERROR - // if the given code set is incomplete (the tables are still built in this - // case), Z_DATA_ERROR if the input is invalid (an over-subscribed set of - // lengths), or Z_MEM_ERROR if not enough memory. - - var a; // counter for codes of length k - var f; // i repeats in table every f entries - var g; // maximum code length - var h; // table level - var i; // counter, current code - var j; // counter - var k; // number of bits in current code - var l; // bits per table (returned in m) - var mask; // (1 << w) - 1, to avoid cc -O bug on HP - var p; // pointer into c[], b[], or v[] - var q; // points to current table - var w; // bits before this table == (l * h) - var xp; // pointer into x - var y; // number of dummy codes added - var z; // number of entries in current table - - // Generate counts for each bit length - - p = 0; i = n; - do { - this.c[b[bindex+p]]++; p++; i--; // assume all entries <= BMAX - }while(i!=0); - - if(this.c[0] == n){ // null input--all zero length codes - t[0] = -1; - m[0] = 0; - return Z_OK; - } - - // Find minimum and maximum length, bound *m by those - l = m[0]; - for (j = 1; j <= BMAX; j++) - if(this.c[j]!=0) break; - k = j; // minimum code length - if(l < j){ - l = j; - } - for (i = BMAX; i!=0; i--){ - if(this.c[i]!=0) break; - } - g = i; // maximum code length - if(l > i){ - l = i; - } - m[0] = l; - - // Adjust last length count to fill out codes, if needed - for (y = 1 << j; j < i; j++, y <<= 1){ - if ((y -= this.c[j]) < 0){ - return Z_DATA_ERROR; - } - } - if ((y -= this.c[i]) < 0){ - return Z_DATA_ERROR; - } - this.c[i] += y; - - // Generate starting offsets into the value table for each length - this.x[1] = j = 0; - p = 1; xp = 2; - while (--i!=0) { // note that i == g from above - this.x[xp] = (j += this.c[p]); - xp++; - p++; - } - - // Make a table of values in order of bit lengths - i = 0; p = 0; - do { - if ((j = b[bindex+p]) != 0){ - this.v[this.x[j]++] = i; - } - p++; - } - while (++i < n); - n = this.x[g]; // set n to length of v - - // Generate the Huffman codes and for each, make the table entries - this.x[0] = i = 0; // first Huffman code is zero - p = 0; // grab values in bit order - h = -1; // no tables yet--level -1 - w = -l; // bits decoded == (l * h) - this.u[0] = 0; // just to keep compilers happy - q = 0; // ditto - z = 0; // ditto - - // go through the bit lengths (k already is bits in shortest code) - for (; k <= g; k++){ - a = this.c[k]; - while (a--!=0){ - // here i is the Huffman code of length k bits for value *p - // make tables up to required level - while (k > w + l){ - h++; - w += l; // previous table always l bits - // compute minimum size table less than or equal to l bits - z = g - w; - z = (z > l) ? l : z; // table size upper limit - if((f=1<<(j=k-w))>a+1){ // try a k-w bit table - // too few codes for k-w bit table - f -= a + 1; // deduct codes from patterns left - xp = k; - if(j < z){ - while (++j < z){ // try smaller tables up to z bits - if((f <<= 1) <= this.c[++xp]) - break; // enough codes to use up j bits - f -= this.c[xp]; // else deduct codes from patterns - } - } - } - z = 1 << j; // table entries for j-bit table - - // allocate new table - if (this.hn[0] + z > MANY){ // (note: doesn't matter for fixed) - return Z_DATA_ERROR; // overflow of MANY - } - this.u[h] = q = /*hp+*/ this.hn[0]; // DEBUG - this.hn[0] += z; - - // connect to last table, if there is one - if(h!=0){ - this.x[h]=i; // save pattern for backing up - this.r[0]=j; // bits in this table - this.r[1]=l; // bits to dump before this table - j=i>>>(w - l); - this.r[2] = (q - this.u[h-1] - j); // offset to this table - arrayCopy(this.r, 0, hp, (this.u[h-1]+j)*3, 3); // connect to last table - } - else{ - t[0] = q; // first table is returned result - } - } - - // set up table entry in r - this.r[1] = (k - w); - if (p >= n){ - this.r[0] = 128 + 64; // out of values--invalid code - } - else if (v[p] < s){ - this.r[0] = (this.v[p] < 256 ? 0 : 32 + 64); // 256 is end-of-block - this.r[2] = this.v[p++]; // simple code is just the value - } - else{ - this.r[0]=(e[this.v[p]-s]+16+64); // non-simple--look up in lists - this.r[2]=d[this.v[p++] - s]; - } - - // fill code-like entries with r - f=1<<(k-w); - for (j=i>>>w;j>>= 1){ - i ^= j; - } - i ^= j; - - // backup over finished tables - mask = (1 << w) - 1; // needed on HP, cc -O bug - while ((i & mask) != this.x[h]){ - h--; // don't need to update q - w -= l; - mask = (1 << w) - 1; - } - } - } - // Return Z_BUF_ERROR if we were given an incomplete table - return y != 0 && g != 1 ? Z_BUF_ERROR : Z_OK; -} - -InfTree.prototype.inflate_trees_bits = function(c, bb, tb, hp, z) { - var result; - this.initWorkArea(19); - this.hn[0]=0; - result = this.huft_build(c, 0, 19, 19, null, null, tb, bb, hp, this.hn, this.v); - - if(result == Z_DATA_ERROR){ - z.msg = "oversubscribed dynamic bit lengths tree"; - } - else if(result == Z_BUF_ERROR || bb[0] == 0){ - z.msg = "incomplete dynamic bit lengths tree"; - result = Z_DATA_ERROR; - } - return result; -} - -InfTree.prototype.inflate_trees_dynamic = function(nl, nd, c, bl, bd, tl, td, hp, z) { - var result; - - // build literal/length tree - this.initWorkArea(288); - this.hn[0]=0; - result = this.huft_build(c, 0, nl, 257, cplens, cplext, tl, bl, hp, this.hn, this.v); - if (result != Z_OK || bl[0] == 0){ - if(result == Z_DATA_ERROR){ - z.msg = "oversubscribed literal/length tree"; - } - else if (result != Z_MEM_ERROR){ - z.msg = "incomplete literal/length tree"; - result = Z_DATA_ERROR; - } - return result; - } - - // build distance tree - this.initWorkArea(288); - result = this.huft_build(c, nl, nd, 0, cpdist, cpdext, td, bd, hp, this.hn, this.v); - - if (result != Z_OK || (bd[0] == 0 && nl > 257)){ - if (result == Z_DATA_ERROR){ - z.msg = "oversubscribed distance tree"; - } - else if (result == Z_BUF_ERROR) { - z.msg = "incomplete distance tree"; - result = Z_DATA_ERROR; - } - else if (result != Z_MEM_ERROR){ - z.msg = "empty distance tree with lengths"; - result = Z_DATA_ERROR; - } - return result; - } - - return Z_OK; -} -/* - static int inflate_trees_fixed(int[] bl, //literal desired/actual bit depth - int[] bd, //distance desired/actual bit depth - int[][] tl,//literal/length tree result - int[][] td,//distance tree result - ZStream z //for memory allocation - ){ - -*/ - -function inflate_trees_fixed(bl, bd, tl, td, z) { - bl[0]=fixed_bl; - bd[0]=fixed_bd; - tl[0]=fixed_tl; - td[0]=fixed_td; - return Z_OK; -} - -InfTree.prototype.initWorkArea = function(vsize){ - if(this.hn==null){ - this.hn=new Int32Array(1); - this.v=new Int32Array(vsize); - this.c=new Int32Array(BMAX+1); - this.r=new Int32Array(3); - this.u=new Int32Array(BMAX); - this.x=new Int32Array(BMAX+1); - } - if(this.v.length 100) { - arrayCopy_fast(new Uint8Array(src.buffer, src.byteOffset + srcOffset, count), dest, destOffset); - } else { - arrayCopy_slow(src, srcOffset, dest, destOffset, count); - } - -} - -function arrayCopy_slow(src, srcOffset, dest, destOffset, count) { - - // dlog('_slow call: srcOffset=' + srcOffset + '; destOffset=' + destOffset + '; count=' + count); - - for (var i = 0; i < count; ++i) { - dest[destOffset + i] = src[srcOffset + i]; - } -} - -function arrayCopy_fast(src, dest, destOffset) { - dest.set(src, destOffset); -} - - - // largest prime smaller than 65536 -var ADLER_BASE=65521; - // NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 -var ADLER_NMAX=5552; - -function adler32(adler, /* byte[] */ buf, index, len){ - if(buf == null){ return 1; } - - var s1=adler&0xffff; - var s2=(adler>>16)&0xffff; - var k; - - while(len > 0) { - k=len=16){ - s1+=buf[index++]&0xff; s2+=s1; - s1+=buf[index++]&0xff; s2+=s1; - s1+=buf[index++]&0xff; s2+=s1; - s1+=buf[index++]&0xff; s2+=s1; - s1+=buf[index++]&0xff; s2+=s1; - s1+=buf[index++]&0xff; s2+=s1; - s1+=buf[index++]&0xff; s2+=s1; - s1+=buf[index++]&0xff; s2+=s1; - s1+=buf[index++]&0xff; s2+=s1; - s1+=buf[index++]&0xff; s2+=s1; - s1+=buf[index++]&0xff; s2+=s1; - s1+=buf[index++]&0xff; s2+=s1; - s1+=buf[index++]&0xff; s2+=s1; - s1+=buf[index++]&0xff; s2+=s1; - s1+=buf[index++]&0xff; s2+=s1; - s1+=buf[index++]&0xff; s2+=s1; - k-=16; - } - if(k!=0){ - do{ - s1+=buf[index++]&0xff; s2+=s1; - } - while(--k!=0); - } - s1%=ADLER_BASE; - s2%=ADLER_BASE; - } - return (s2<<16)|s1; -} - - - -function jszlib_inflate_buffer(buffer, start, length, afterUncOffset) { - if (!start) { - buffer = new Uint8Array(buffer); - } else { - buffer = new Uint8Array(buffer, start, length); - } - - var z = new ZStream(); - z.inflateInit(DEF_WBITS, true); - z.next_in = buffer; - z.next_in_index = 0; - z.avail_in = buffer.length; - - var oBlockList = []; - var totalSize = 0; - while (true) { - var obuf = new Uint8Array(32000); - z.next_out = obuf; - z.next_out_index = 0; - z.avail_out = obuf.length; - var status = z.inflate(Z_NO_FLUSH); - if (status != Z_OK && status != Z_STREAM_END) { - throw z.msg; - } - if (z.avail_out != 0) { - var newob = new Uint8Array(obuf.length - z.avail_out); - arrayCopy(obuf, 0, newob, 0, (obuf.length - z.avail_out)); - obuf = newob; - } - oBlockList.push(obuf); - totalSize += obuf.length; - if (status == Z_STREAM_END) { - break; - } - } - - if (afterUncOffset) { - afterUncOffset[0] = (start || 0) + z.next_in_index; - } - - if (oBlockList.length == 1) { - return oBlockList[0].buffer; - } else { - var out = new Uint8Array(totalSize); - var cursor = 0; - for (var i = 0; i < oBlockList.length; ++i) { - var b = oBlockList[i]; - arrayCopy(b, 0, out, cursor, b.length); - cursor += b.length; - } - return out.buffer; - } -} \ No newline at end of file diff --git a/js/lib/url.js b/js/lib/url.js deleted file mode 100644 index 7018d9d3..00000000 --- a/js/lib/url.js +++ /dev/null @@ -1,12 +0,0 @@ -/* -* -* URL Utils -* -* */ - -var getURLParameter = function(name, defaultvalue) { - var value = decodeURIComponent((new RegExp('[?|&]' + name + '=' + '([^&;]+?)(&|#|;|$)'). - exec(location.search)||[,""])[1].replace(/\+/g, '%20'))||null; - - return (value != null ? value : defaultvalue); -} diff --git a/js/plugins/fileDrop.js b/js/plugins/fileDrop.js index 971f6726..0f4181ed 100644 --- a/js/plugins/fileDrop.js +++ b/js/plugins/fileDrop.js @@ -23,30 +23,38 @@ Genoverse.Plugins.fileDrop = function () { e.preventDefault(); e.stopPropagation(); - var files = e.originalEvent.dataTransfer.files; + // Sort in order to ensure that .bam files are before their .bam.bai files + var files = $.map(e.originalEvent.dataTransfer.files, function (f) { return f; }).sort(function (a, b) { return a.name < b.name ? -1 : 1 }); for (var i = 0; i < files.length; i++) { - var file = files[i]; - var reader = new FileReader(); - - reader.onload = function (event) { - var track = Genoverse.Track.File[((file.name.match(/\.(\w+)$/))[1]).toUpperCase()].extend({ - name : file.name, - info : 'Local file `' + file.name + '`, size: ' + file.size + ' bytes', - allData : true, - url : false, - data : event.target.result, - getData : function () { - return $.Deferred().done(function () { - this.receiveData(this.data, 1, this.browser.chromosomeSize); - }).resolveWith(this); - } - }); - - browser.addTrack(track, browser.tracks.length - 1); - }; - - reader.readAsText(file); + var file = files[i]; + var ext = (file.name.match(/\.(\w+)$/))[1]; + var track = Genoverse.Track.File[ext.toUpperCase()]; + var indexFile; + + if (typeof track === 'undefined') { + return; + } + + if (track.prototype.indexExt) { + i++; + + if ((files[i] || {}).name !== file.name + track.prototype.indexExt) { + continue; + } + + indexFile = files[i]; + } + + track = track.extend({ + name : file.name, + info : 'Local file `' + file.name + '`, size: ' + file.size + ' bytes', + isLocal : true, + dataFile : file, + indexFile : indexFile + }); + + browser.addTrack(track, browser.tracks.length - 1); } return false; From 0001705beb925c81aef3724d7fb4bf7a2e7b882b Mon Sep 17 00:00:00 2001 From: Simon Brent Date: Tue, 23 Feb 2016 11:17:38 +0000 Subject: [PATCH 11/59] Whitespace --- js/Track/Controller/Stranded.js | 22 +- js/Track/Model/File/BED.js | 10 +- js/Track/Model/Sequence.js | 16 +- js/Track/Model/Sequence/Fasta.js | 24 +- js/Track/Model/SequenceVariation/VCF.js | 18 +- js/Track/Model/Stranded.js | 8 +- js/Track/Model/Transcript/GFF3.js | 32 +- js/Track/View/Sequence/Variation.js | 54 +- js/genoverse.combined.js | 1758 ++++++++++++----------- js/genoverse.combined.nojquery.js | 1758 ++++++++++++----------- js/lib/Base.js | 246 ++-- js/lib/dalliance/js/bam.js | 2 +- js/lib/dalliance/js/bin.js | 2 +- js/lib/dalliance/js/das.js | 66 +- js/lib/dalliance/js/utils.js | 24 +- js/lib/jquery.hashchange.js | 2 +- js/lib/jquery.mousehold.js | 2 +- js/lib/jquery.mousewheel.js | 18 +- js/lib/rtree.js | 1254 ++++++++-------- 19 files changed, 2742 insertions(+), 2574 deletions(-) diff --git a/js/Track/Controller/Stranded.js b/js/Track/Controller/Stranded.js index 9abc8f86..65dd1f6a 100644 --- a/js/Track/Controller/Stranded.js +++ b/js/Track/Controller/Stranded.js @@ -1,38 +1,38 @@ Genoverse.Track.Controller.Stranded = Genoverse.Track.Controller.extend({ constructor: function (properties) { this.base(properties); - + if (typeof this._makeImage === 'function') { return; } - + var strand = this.prop('strand'); var featureStrand = this.prop('featureStrand'); - + if (strand === -1) { this._makeImage = this.track.makeReverseImage ? $.proxy(this.track.makeReverseImage, this) : this.makeImage; this.makeImage = $.noop; } else { strand = this.prop('strand', 1); - + this._makeImage = this.makeImage; this.makeImage = this.makeForwardImage; this.reverseTrack = this.browser.addTrack(this.track.constructor.extend({ strand: -1, url: false, forwardTrack: this }), this.browser.tracks.length).controller; } - + if (!featureStrand) { this.prop('featureStrand', strand); } - + if (!(this.model instanceof Genoverse.Track.Model.Stranded)) { this.track.lengthMap.push([ -9e99, { model: Genoverse.Track.Model.Stranded }]); } }, - + makeForwardImage: function (params) { var reverseTrack = this.prop('reverseTrack'); var rtn = this._makeImage(params); - + if (rtn && typeof rtn.done === 'function') { rtn.done(function () { reverseTrack._makeImage(params, rtn); @@ -41,14 +41,14 @@ Genoverse.Track.Controller.Stranded = Genoverse.Track.Controller.extend({ reverseTrack._makeImage(params, rtn); } }, - + destroy: function () { if (this.removing) { return; } - + this.removing = true; - + this.browser.removeTrack((this.prop('forwardTrack') || this.prop('reverseTrack')).track); this.base(); } diff --git a/js/Track/Model/File/BED.js b/js/Track/Model/File/BED.js index 794bb04e..7bbe3f91 100644 --- a/js/Track/Model/File/BED.js +++ b/js/Track/Model/File/BED.js @@ -1,14 +1,14 @@ Genoverse.Track.Model.File.BED = Genoverse.Track.Model.File.extend({ parseData: function (text) { var lines = text.split('\n'); - + for (var i = 0; i < lines.length; i++) { var fields = lines[i].split('\t'); - + if (fields.length < 3) { continue; } - + if (fields[0] === this.browser.chr || fields[0].toLowerCase() === 'chr' + this.browser.chr || fields[0].match('[^1-9]' + this.browser.chr + '$')) { var score = parseFloat(fields[4], 10); var color = '#000000'; @@ -29,7 +29,7 @@ Genoverse.Track.Model.File.BED = Genoverse.Track.Model.File.extend({ }); } } - }, + }, // As per https://genome.ucsc.edu/FAQ/FAQformat.html#format1 specification scoreColor: function (score) { @@ -43,4 +43,4 @@ Genoverse.Track.Model.File.BED = Genoverse.Track.Model.File.extend({ if (score <= 944) { return 'rgb(21,21,21)'; } return '#000000'; } -}); \ No newline at end of file +}); \ No newline at end of file diff --git a/js/Track/Model/Sequence.js b/js/Track/Model/Sequence.js index 5a807c57..b95ea071 100644 --- a/js/Track/Model/Sequence.js +++ b/js/Track/Model/Sequence.js @@ -2,34 +2,34 @@ // assumes that the data source responds with raw sequence text // see Fasta model for more specific example Genoverse.Track.Model.Sequence = Genoverse.Track.Model.extend({ - threshold : 100000, + threshold : 100000, chunkSize : 1000, buffer : 0, dataType : 'text', - + init: function () { this.base(); this.chunks = {}; }, - + getData: function (start, end) { start = start - start % this.chunkSize + 1; end = end + this.chunkSize - end % this.chunkSize; return this.base(start, end); }, - + parseData: function (data, start, end) { data = data.replace(/\n/g, ''); - + if (this.prop('lowerCase')) { data = data.toLowerCase(); } - + for (var i = 0; i < data.length; i += this.chunkSize) { if (this.chunks[start + i]) { continue; } - + var feature = { id : start + i, start : start + i, @@ -37,7 +37,7 @@ Genoverse.Track.Model.Sequence = Genoverse.Track.Model.extend({ sequence : data.substr(i, this.chunkSize), sort : start + i }; - + this.chunks[feature.start] = feature; this.insertFeature(feature); } diff --git a/js/Track/Model/Sequence/Fasta.js b/js/Track/Model/Sequence/Fasta.js index ec5f80fc..51241d19 100644 --- a/js/Track/Model/Sequence/Fasta.js +++ b/js/Track/Model/Sequence/Fasta.js @@ -1,22 +1,22 @@ Genoverse.Track.Model.Sequence.Fasta = Genoverse.Track.Model.Sequence.extend({ url : 'http://genoverse.org/data/Homo_sapiens.GRCh37.72.dna.chromosome.1.fa', // Example url - + // Following settings could be left undefined and will be detected automatically via .getStartByte() startByte : undefined, // Byte in the file where the sequence actually starts lineLength : undefined, // Length of the sequence line in the file - + // TODO: Check if URL provided - + getData: function (start, end) { var deferred = $.Deferred(); - + $.when(this.getStartByte()).done(function () { start = start - start % this.chunkSize + 1; end = end + this.chunkSize - end % this.chunkSize; - + var startByte = start - 1 + Math.floor((start - 1) / this.lineLength) + this.startByte; var endByte = end - 1 + Math.floor((end - 1) / this.lineLength) + this.startByte; - + $.ajax({ url : this.parseURL(start, end), dataType : this.dataType, @@ -27,33 +27,33 @@ Genoverse.Track.Model.Sequence.Fasta = Genoverse.Track.Model.Sequence.extend({ error : this.track.controller.showError }).done(function () { deferred.resolveWith(this); }).fail(function () { deferred.rejectWith(this); }); }).fail(function () { deferred.rejectWith(this); }); - + return deferred; }, - + getStartByte: function () { if (this.startByteRequest) { return this.startByteRequest; } - + if (this.startByte === undefined || this.lineLength === undefined) { this.startByteRequest = $.ajax({ url : this.parseURL(), dataType : 'text', context : this, headers : { 'Range': 'bytes=0-300' }, - xhrFields : this.xhrFields, + xhrFields : this.xhrFields, success : function (data) { if (data.indexOf('>') === 0) { this.startByte = data.indexOf('\n') + 1; } else { this.startByte = 0; } - + this.lineLength = data.indexOf('\n', this.startByte) - this.startByte; } }); - + return this.startByteRequest; } } diff --git a/js/Track/Model/SequenceVariation/VCF.js b/js/Track/Model/SequenceVariation/VCF.js index f3c91772..e8355514 100644 --- a/js/Track/Model/SequenceVariation/VCF.js +++ b/js/Track/Model/SequenceVariation/VCF.js @@ -1,30 +1,30 @@ Genoverse.Track.Model.SequenceVariation.VCF = Genoverse.Track.Model.SequenceVariation.extend({ dataType: 'text', - + parseData: function (text) { var lines = text.split('\n'); - + for (var i = 0; i < lines.length; i++) { if (!lines[i].length || lines[i].indexOf('#') === 0) { continue; } - + var fields = lines[i].split('\t'); - + if (fields.length < 5) { continue; } - + if (fields[0] === this.browser.chr || fields[0] === 'chr' + this.browser.chr) { var id = fields.slice(0, 3).join('|'); var start = parseInt(fields[1], 10); var alleles = fields[4].split(','); - + alleles.unshift(fields[3]); - + for (var j = 0; j < alleles.length; j++) { var end = start + alleles[j].length - 1; - + this.insertFeature({ id : id + '|' + alleles[j], sort : j, @@ -36,7 +36,7 @@ Genoverse.Track.Model.SequenceVariation.VCF = Genoverse.Track.Model.SequenceVari label : alleles[j], labelColor : '#FFFFFF', originalFeature : fields - }); + }); } } } diff --git a/js/Track/Model/Stranded.js b/js/Track/Model/Stranded.js index 936350a4..01c2c9a3 100644 --- a/js/Track/Model/Stranded.js +++ b/js/Track/Model/Stranded.js @@ -1,21 +1,21 @@ Genoverse.Track.Model.Stranded = Genoverse.Track.Model.extend({ init: function (reset) { this.base(reset); - + if (!reset) { var otherTrack = this.prop('forwardTrack'); - + if (otherTrack) { this.features = otherTrack.prop('features'); this.featuresById = otherTrack.prop('featuresById'); } } }, - + setURL: function (urlParams, update) { this.base($.extend(urlParams || this.urlParams, { strand: this.track.featureStrand }), update); }, - + findFeatures: function () { var strand = this.track.featureStrand; return $.grep(this.base.apply(this, arguments), function (feature) { return feature.strand === strand; }); diff --git a/js/Track/Model/Transcript/GFF3.js b/js/Track/Model/Transcript/GFF3.js index f16f9452..9756d6b2 100644 --- a/js/Track/Model/Transcript/GFF3.js +++ b/js/Track/Model/Transcript/GFF3.js @@ -1,31 +1,31 @@ // Basic GFF3 model for transcripts -// See http://www.broadinstitute.org/annotation/gebo/help/gff3.html +// See http://www.broadinstitute.org/annotation/gebo/help/gff3.html Genoverse.Track.Model.Transcript.GFF3 = Genoverse.Track.Model.Transcript.extend({ dataType : 'text', - - // Transcript structure map for column 3 (type) + + // Transcript structure map for column 3 (type) typeMap : { exon : 'exon', cds : 'cds' }, - + parseData: function (text) { var lines = text.split('\n'); - + for (var i = 0; i < lines.length; i++) { if (!lines[i].length || lines[i].indexOf('#') === 0) { continue; } - + var fields = lines[i].split('\t'); - + if (fields.length < 5) { continue; } - + if (fields[0] === this.browser.chr || fields[0].toLowerCase() === 'chr' + this.browser.chr || fields[0].match('[^1-9]' + this.browser.chr + '$')) { var feature = {}; - + feature.id = fields.slice(0, 5).join('|'); feature.start = parseInt(fields[3], 10); feature.end = parseInt(fields[4], 10); @@ -33,19 +33,19 @@ Genoverse.Track.Model.Transcript.GFF3 = Genoverse.Track.Model.Transcript.extend( feature.type = fields[2]; feature.score = fields[5]; feature.strand = fields[6] + '1'; - + if (fields[8]) { var frame = fields[8].split(';'); - + for (var j = 0; j < frame.length; j++) { var keyValue = frame[j].split('='); - + if (keyValue.length === 2) { feature[keyValue[0].toLowerCase()] = keyValue[1]; } } } - + // sub-feature came earlier than parent feature if (feature.parent && !this.featuresById[feature.parent]) { this.featuresById[feature.parent] = { @@ -53,7 +53,7 @@ Genoverse.Track.Model.Transcript.GFF3 = Genoverse.Track.Model.Transcript.extend( cds : [] }; } - + if (feature.parent && feature.type.toLowerCase() === this.typeMap.exon.toLowerCase()) { if (!$.grep(this.featuresById[feature.parent].exons, function (exon) { return exon.id === feature.id; }).length) { this.featuresById[feature.parent].exons.push(feature); @@ -65,9 +65,9 @@ Genoverse.Track.Model.Transcript.GFF3 = Genoverse.Track.Model.Transcript.extend( } else if (!feature.parent) { feature.label = feature.name || feature.id || ''; $.extend(feature, { label: feature.name || feature.id || '', exons: [], cds: [] }, this.featuresById[feature.id] || {}); - + delete this.featuresById[feature.id]; - + this.insertFeature(feature); } } diff --git a/js/Track/View/Sequence/Variation.js b/js/Track/View/Sequence/Variation.js index 5be58926..3734e7f3 100644 --- a/js/Track/View/Sequence/Variation.js +++ b/js/Track/View/Sequence/Variation.js @@ -3,64 +3,64 @@ Genoverse.Track.View.SequenceVariation = Genoverse.Track.View.Sequence.extend({ featureMargin : { top: 0, right: 0, bottom: 4, left: 0 }, bump : true, showLegend : false, - + positionFeature: function (feature, params) { var position = feature.position[params.scale]; - + if (feature.alt_allele) { if (!position.positioned) { position.reference = { end: position.start + feature.ref_allele.length * params.scale }; } - + position.reference.x = position.reference.end - params.scaledStart; } - + this.base(feature, params); }, - + bumpFeature: function (bounds, feature) { if (feature.alt_allele) { this.base.apply(this, arguments); } }, - + draw: function (features, featureContext, labelContext, scale) { var drawing = { seq: [], snv: [] }; - + for (var i = 0; i < features.length; i++) { drawing[features[i].alt_allele ? 'snv' : 'seq'].push(features[i]); } - + this.base(drawing.seq, featureContext, labelContext, scale); this.highlightSNVs(drawing.snv, featureContext, scale); this.base(drawing.snv, featureContext, labelContext, scale); this.outlineSNVs(drawing.snv, featureContext, scale); // Redraw the outline for SNVs, since the feature will have been drawn on top of some of the outline created by highlightSNVs }, - + highlightSNVs: function (features, context, scale) { var position, positionX, positionY; - + for (var i = 0; i < features.length; i++) { position = features[i].position[scale]; positionX = [ position.X, position.reference.x, position.X + position.width ]; - + if (positionX[2] < 0 || positionX[0] > this.width) { continue; } - + if (positionX[0] < 0 || positionX[2] > this.width) { this.truncateForDrawing(positionX); } - + positionY = [ 0, position.Y - this.featureMargin.bottom / 2, position.Y, position.Y + this.featureHeight ]; - + if (!features[i].highlightColor) { this.setHighlightColor(features[i]); } - + context.strokeStyle = context.fillStyle = features[i].highlightColor; context.lineWidth = 2; - + context.beginPath(); context.moveTo(positionX[0], positionY[0]); context.lineTo(positionX[1], positionY[0]); @@ -70,45 +70,45 @@ Genoverse.Track.View.SequenceVariation = Genoverse.Track.View.Sequence.extend({ context.lineTo(positionX[0], positionY[3]); context.closePath(); context.stroke(); - + context.lineWidth = 1; context.globalAlpha = 0.5; - + context.fill(); - + context.globalAlpha = 1; } }, - + outlineSNVs: function (features, context, scale) { var position, positionX, positionY; - + for (var i = 0; i < features.length; i++) { position = features[i].position[scale]; positionX = [ position.X, position.X + position.width ]; positionY = [ position.Y, position.Y + this.featureHeight ]; - + context.strokeStyle = features[i].highlightColor; - + context.lineWidth = 2; - + context.beginPath(); context.moveTo(positionX[1], positionY[0]); context.lineTo(positionX[1], positionY[1]); context.lineTo(positionX[0], positionY[1]); context.lineTo(positionX[0], positionY[0]); context.stroke(); - + context.lineWidth = 1; } }, - + truncateForDrawing: function (positionX) { for (var i in positionX) { positionX[i] = Math.min(Math.max(positionX[i], -1), this.width + 1); } }, - + setHighlightColor: function (feature) { feature.highlightColor = feature.alt_allele === '-' || feature.alt_allele.length < feature.ref_allele.length ? '#D31D00' : '#1DD300'; } diff --git a/js/genoverse.combined.js b/js/genoverse.combined.js index 0d5cdf64..3c1808b3 100644 --- a/js/genoverse.combined.js +++ b/js/genoverse.combined.js @@ -20,7 +20,7 @@ * Thanks to: Seamus Leahy for adding deltaX and deltaY * * Version: 3.0.6 - * + * * Requires: 1.2.2+ */ @@ -44,7 +44,7 @@ $.event.special.mousewheel = { this.onmousewheel = handler; } }, - + teardown: function() { if ( this.removeEventListener ) { for ( var i=types.length; i; ) { @@ -60,7 +60,7 @@ $.fn.extend({ mousewheel: function(fn) { return fn ? this.bind("mousewheel", fn) : this.trigger("mousewheel"); }, - + unmousewheel: function(fn) { return this.unbind("mousewheel", fn); } @@ -71,27 +71,27 @@ function handler(event) { var orgEvent = event || window.event, args = [].slice.call( arguments, 1 ), delta = 0, returnValue = true, deltaX = 0, deltaY = 0; event = $.event.fix(orgEvent); event.type = "mousewheel"; - + // Old school scrollwheel delta if ( orgEvent.wheelDelta ) { delta = orgEvent.wheelDelta/120; } if ( orgEvent.detail ) { delta = -orgEvent.detail/3; } - + // New school multidimensional scroll (touchpads) deltas deltaY = delta; - + // Gecko if ( orgEvent.axis !== undefined && orgEvent.axis === orgEvent.HORIZONTAL_AXIS ) { deltaY = 0; deltaX = -1*delta; } - + // Webkit if ( orgEvent.wheelDeltaY !== undefined ) { deltaY = orgEvent.wheelDeltaY/120; } if ( orgEvent.wheelDeltaX !== undefined ) { deltaX = -1*orgEvent.wheelDeltaX/120; } - + // Add event and delta to the front of the arguments args.unshift(event, delta, deltaX, deltaY); - + return ($.event.dispatch || $.event.handle).apply(this, args); } @@ -142,7 +142,7 @@ $.fn.mousehold = function(timeout, f) { if (fireStep == 1) f.call(this, 1); fireStep = 0; } - + $(this).mouseout(clearMousehold); $(this).mouseup(clearMousehold); }) @@ -412,153 +412,153 @@ $.fn.mousehold = function(timeout, f) { })(jQuery); /* - Base.js, version 1.1 - Copyright 2006-2007, Dean Edwards - License: http://www.opensource.org/licenses/mit-license.php + Base.js, version 1.1 + Copyright 2006-2007, Dean Edwards + License: http://www.opensource.org/licenses/mit-license.php */ var Base = function() { - // dummy + // dummy }; Base.extend = function(_instance, _static) { // subclass - var extend = Base.prototype.extend; - - // build the prototype - Base._prototyping = true; - var proto = new this; - extend.call(proto, _instance); - delete Base._prototyping; - - // create the wrapper for the constructor function - //var constructor = proto.constructor.valueOf(); //-dean - var constructor = proto.constructor; - var klass = proto.constructor = function() { - if (!Base._prototyping) { - if (this._constructing || this.constructor == klass) { // instantiation - this._constructing = true; - constructor.apply(this, arguments); - delete this._constructing; - } else if (arguments[0] != null) { // casting - return (arguments[0].extend || extend).call(arguments[0], proto); - } - } - }; - - // build the class interface - klass.ancestor = this; - klass.extend = this.extend; - klass.forEach = this.forEach; - klass.implement = this.implement; - klass.prototype = proto; - klass.toString = this.toString; - klass.valueOf = function(type) { - //return (type == "object") ? klass : constructor; //-dean - return (type == "object") ? klass : constructor.valueOf(); - }; - extend.call(klass, _static); - // class initialisation - if (typeof klass.init == "function") klass.init(); - return klass; + var extend = Base.prototype.extend; + + // build the prototype + Base._prototyping = true; + var proto = new this; + extend.call(proto, _instance); + delete Base._prototyping; + + // create the wrapper for the constructor function + //var constructor = proto.constructor.valueOf(); //-dean + var constructor = proto.constructor; + var klass = proto.constructor = function() { + if (!Base._prototyping) { + if (this._constructing || this.constructor == klass) { // instantiation + this._constructing = true; + constructor.apply(this, arguments); + delete this._constructing; + } else if (arguments[0] != null) { // casting + return (arguments[0].extend || extend).call(arguments[0], proto); + } + } + }; + + // build the class interface + klass.ancestor = this; + klass.extend = this.extend; + klass.forEach = this.forEach; + klass.implement = this.implement; + klass.prototype = proto; + klass.toString = this.toString; + klass.valueOf = function(type) { + //return (type == "object") ? klass : constructor; //-dean + return (type == "object") ? klass : constructor.valueOf(); + }; + extend.call(klass, _static); + // class initialisation + if (typeof klass.init == "function") klass.init(); + return klass; }; -Base.prototype = { - extend: function(source, value) { - if (arguments.length > 1) { // extending with a name/value pair - var ancestor = this[source]; - if (ancestor && (typeof value == "function") && // overriding a method? - // the valueOf() comparison is to avoid circular references - (!ancestor.valueOf || ancestor.valueOf() != value.valueOf()) && - /\bbase\b/.test(value)) { - // get the underlying method - var method = value.valueOf(); - // override - value = function() { - var previous = this.base || Base.prototype.base; - this.base = ancestor; - var returnValue = method.apply(this, arguments); - this.base = previous; - return returnValue; - }; - // point to the underlying method - value.valueOf = function(type) { - return (type == "object") ? value : method; - }; - value.toString = Base.toString; - } - this[source] = value; - } else if (source) { // extending with an object literal - var extend = Base.prototype.extend; - // if this object has a customised extend method then use it - if (!Base._prototyping && typeof this != "function") { - extend = this.extend || extend; - } - var proto = {toSource: null}; - // do the "toString" and other methods manually - var hidden = ["constructor", "toString", "valueOf"]; - // if we are prototyping then include the constructor - var i = Base._prototyping ? 0 : 1; - while (key = hidden[i++]) { - if (source[key] != proto[key]) { - extend.call(this, key, source[key]); - - } - } - // copy each of the source object's properties to this object - for (var key in source) { - if (!proto[key]) extend.call(this, key, source[key]); - } - } - return this; - }, +Base.prototype = { + extend: function(source, value) { + if (arguments.length > 1) { // extending with a name/value pair + var ancestor = this[source]; + if (ancestor && (typeof value == "function") && // overriding a method? + // the valueOf() comparison is to avoid circular references + (!ancestor.valueOf || ancestor.valueOf() != value.valueOf()) && + /\bbase\b/.test(value)) { + // get the underlying method + var method = value.valueOf(); + // override + value = function() { + var previous = this.base || Base.prototype.base; + this.base = ancestor; + var returnValue = method.apply(this, arguments); + this.base = previous; + return returnValue; + }; + // point to the underlying method + value.valueOf = function(type) { + return (type == "object") ? value : method; + }; + value.toString = Base.toString; + } + this[source] = value; + } else if (source) { // extending with an object literal + var extend = Base.prototype.extend; + // if this object has a customised extend method then use it + if (!Base._prototyping && typeof this != "function") { + extend = this.extend || extend; + } + var proto = {toSource: null}; + // do the "toString" and other methods manually + var hidden = ["constructor", "toString", "valueOf"]; + // if we are prototyping then include the constructor + var i = Base._prototyping ? 0 : 1; + while (key = hidden[i++]) { + if (source[key] != proto[key]) { + extend.call(this, key, source[key]); - base: function() { - // call this method from any other method to invoke that method's ancestor - } + } + } + // copy each of the source object's properties to this object + for (var key in source) { + if (!proto[key]) extend.call(this, key, source[key]); + } + } + return this; + }, + + base: function() { + // call this method from any other method to invoke that method's ancestor + } }; // initialise Base = Base.extend({ - constructor: function() { - this.extend(arguments[0]); - } + constructor: function() { + this.extend(arguments[0]); + } }, { - ancestor: Object, - version: "1.1", - - forEach: function(object, block, context) { - for (var key in object) { - if (this.prototype[key] === undefined) { - block.call(context, object[key], key, object); - } - } - }, - - implement: function() { - for (var i = 0; i < arguments.length; i++) { - if (typeof arguments[i] == "function") { - // if it's a function, call it - arguments[i](this.prototype); - } else { - // add the interface using the extend method - this.prototype.extend(arguments[i]); - } - } - return this; - }, - - toString: function() { - return String(this.valueOf()); - } + ancestor: Object, + version: "1.1", + + forEach: function(object, block, context) { + for (var key in object) { + if (this.prototype[key] === undefined) { + block.call(context, object[key], key, object); + } + } + }, + + implement: function() { + for (var i = 0; i < arguments.length; i++) { + if (typeof arguments[i] == "function") { + // if it's a function, call it + arguments[i](this.prototype); + } else { + // add the interface using the extend method + this.prototype.extend(arguments[i]); + } + } + return this; + }, + + toString: function() { + return String(this.valueOf()); + } }); -/****************************************************************************** - rtree.js - General-Purpose Non-Recursive Javascript R-Tree Library - Version 0.6.2, December 5st 2009 +/****************************************************************************** + rtree.js - General-Purpose Non-Recursive Javascript R-Tree Library + Version 0.6.2, December 5st 2009 Copyright (c) 2009 Jon-Carlos Rivera - + Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including @@ -566,10 +566,10 @@ Base = Base.extend({ distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - + The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND @@ -578,7 +578,7 @@ Base = Base.extend({ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - Jon-Carlos Rivera - imbcmdth@hotmail.com + Jon-Carlos Rivera - imbcmdth@hotmail.com ******************************************************************************/ /** @@ -586,22 +586,22 @@ Base = Base.extend({ * @constructor */ var RTree = function(width){ - // Variables to control tree-dimensions - var _Min_Width = 3; // Minimum width of any node before a merge - var _Max_Width = 6; // Maximum width of any node before a split - if(!isNaN(width)){ _Min_Width = Math.floor(width/2.0); _Max_Width = width;} - // Start with an empty root-tree - var _T = {x:0, y:0, w:0, h:0, id:"root", nodes:[] }; - - var isArray = function(o) { - return Object.prototype.toString.call(o) === '[object Array]'; - }; + // Variables to control tree-dimensions + var _Min_Width = 3; // Minimum width of any node before a merge + var _Max_Width = 6; // Maximum width of any node before a split + if(!isNaN(width)){ _Min_Width = Math.floor(width/2.0); _Max_Width = width;} + // Start with an empty root-tree + var _T = {x:0, y:0, w:0, h:0, id:"root", nodes:[] }; + + var isArray = function(o) { + return Object.prototype.toString.call(o) === '[object Array]'; + }; - /* @function - * @description Function to generate unique strings for element IDs - * @param {String} n The prefix to use for the IDs generated. - * @return {String} A guarenteed unique ID. - */ + /* @function + * @description Function to generate unique strings for element IDs + * @param {String} n The prefix to use for the IDs generated. + * @return {String} A guarenteed unique ID. + */ var _name_to_id = (function() { // hide our idCache inside this closure var idCache = {}; @@ -618,538 +618,538 @@ var RTree = function(width){ } })(); - // This is my special addition to the world of r-trees - // every other (simple) method I found produced crap trees - // this skews insertions to prefering squarer and emptier nodes - RTree.Rectangle.squarified_ratio = function(l, w, fill) { - // Area of new enlarged rectangle - var lperi = (l + w) / 2.0; // Average size of a side of the new rectangle - var larea = l * w; // Area of new rectangle - // return the ratio of the perimeter to the area - the closer to 1 we are, - // the more "square" a rectangle is. conversly, when approaching zero the - // more elongated a rectangle is - var lgeo = larea / (lperi*lperi); - return(larea * fill / lgeo); - }; - - /* find the best specific node(s) for object to be deleted from - * [ leaf node parent ] = _remove_subtree(rectangle, object, root) - * @private - */ - var _remove_subtree = function(rect, obj, root) { - var hit_stack = []; // Contains the elements that overlap - var count_stack = []; // Contains the elements that overlap - var ret_array = []; - var current_depth = 1; - - if(!rect || !RTree.Rectangle.overlap_rectangle(rect, root)) - return ret_array; - - var ret_obj = {x:rect.x, y:rect.y, w:rect.w, h:rect.h, target:obj}; - - count_stack.push(root.nodes.length); - hit_stack.push(root); - - do { - var tree = hit_stack.pop(); - var i = count_stack.pop()-1; - - if("target" in ret_obj) { // We are searching for a target - while(i >= 0) { - var ltree = tree.nodes[i]; - if(RTree.Rectangle.overlap_rectangle(ret_obj, ltree)) { - if( (ret_obj.target && "leaf" in ltree && ltree.leaf === ret_obj.target) - ||(!ret_obj.target && ("leaf" in ltree || RTree.Rectangle.contains_rectangle(ltree, ret_obj)))) { // A Match !! - // Yup we found a match... - // we can cancel search and start walking up the list - if("nodes" in ltree) {// If we are deleting a node not a leaf... - ret_array = _search_subtree(ltree, true, [], ltree); - tree.nodes.splice(i, 1); - } else { - ret_array = tree.nodes.splice(i, 1); - } - // Resize MBR down... - RTree.Rectangle.make_MBR(tree.nodes, tree); - delete ret_obj.target; - if(tree.nodes.length < _Min_Width) { // Underflow - ret_obj.nodes = _search_subtree(tree, true, [], tree); - } - break; - }/* else if("load" in ltree) { // A load - }*/ else if("nodes" in ltree) { // Not a Leaf - current_depth += 1; - count_stack.push(i); - hit_stack.push(tree); - tree = ltree; - i = ltree.nodes.length; - } - } - i -= 1; - } - } else if("nodes" in ret_obj) { // We are unsplitting - tree.nodes.splice(i+1, 1); // Remove unsplit node - // ret_obj.nodes contains a list of elements removed from the tree so far - if(tree.nodes.length > 0) - RTree.Rectangle.make_MBR(tree.nodes, tree); - for(var t = 0;t 0 && tree.nodes.length < _Min_Width) { // Underflow..AGAIN! - ret_obj.nodes = _search_subtree(tree, true, ret_obj.nodes, tree); - tree.nodes.length = 0; - }else { - delete ret_obj.nodes; // Just start resizing - } - } else { // we are just resizing - RTree.Rectangle.make_MBR(tree.nodes, tree); - } - current_depth -= 1; - }while(hit_stack.length > 0); - - return(ret_array); - }; + // This is my special addition to the world of r-trees + // every other (simple) method I found produced crap trees + // this skews insertions to prefering squarer and emptier nodes + RTree.Rectangle.squarified_ratio = function(l, w, fill) { + // Area of new enlarged rectangle + var lperi = (l + w) / 2.0; // Average size of a side of the new rectangle + var larea = l * w; // Area of new rectangle + // return the ratio of the perimeter to the area - the closer to 1 we are, + // the more "square" a rectangle is. conversly, when approaching zero the + // more elongated a rectangle is + var lgeo = larea / (lperi*lperi); + return(larea * fill / lgeo); + }; - /* choose the best damn node for rectangle to be inserted into - * [ leaf node parent ] = _choose_leaf_subtree(rectangle, root to start search at) - * @private - */ - var _choose_leaf_subtree = function(rect, root) { - var best_choice_index = -1; - var best_choice_stack = []; - var best_choice_area; - - var load_callback = function(local_tree, local_node){ - return(function(data) { - local_tree._attach_data(local_node, data); - }); - }; - - best_choice_stack.push(root); - var nodes = root.nodes; - - do { - if(best_choice_index != -1) { - best_choice_stack.push(nodes[best_choice_index]); - nodes = nodes[best_choice_index].nodes; - best_choice_index = -1; - } - - for(var i = nodes.length-1; i >= 0; i--) { - var ltree = nodes[i]; - if("leaf" in ltree) { - // Bail out of everything and start inserting - best_choice_index = -1; - break; - } /*else if(ltree.load) { - throw( "Can't insert into partially loaded tree ... yet!"); - //jQuery.getJSON(ltree.load, load_callback(this, ltree)); - //delete ltree.load; - }*/ - // Area of new enlarged rectangle - var old_lratio = RTree.Rectangle.squarified_ratio(ltree.w, ltree.h, ltree.nodes.length+1); - - // Enlarge rectangle to fit new rectangle - var nw = Math.max(ltree.x+ltree.w, rect.x+rect.w) - Math.min(ltree.x, rect.x); - var nh = Math.max(ltree.y+ltree.h, rect.y+rect.h) - Math.min(ltree.y, rect.y); - - // Area of new enlarged rectangle - var lratio = RTree.Rectangle.squarified_ratio(nw, nh, ltree.nodes.length+2); - - if(best_choice_index < 0 || Math.abs(lratio - old_lratio) < best_choice_area) { - best_choice_area = Math.abs(lratio - old_lratio); best_choice_index = i; - } - } - }while(best_choice_index != -1); - - return(best_choice_stack); - }; + /* find the best specific node(s) for object to be deleted from + * [ leaf node parent ] = _remove_subtree(rectangle, object, root) + * @private + */ + var _remove_subtree = function(rect, obj, root) { + var hit_stack = []; // Contains the elements that overlap + var count_stack = []; // Contains the elements that overlap + var ret_array = []; + var current_depth = 1; - /* split a set of nodes into two roughly equally-filled nodes - * [ an array of two new arrays of nodes ] = linear_split(array of nodes) - * @private - */ - var _linear_split = function(nodes) { - var n = _pick_linear(nodes); - while(nodes.length > 0) { - _pick_next(nodes, n[0], n[1]); - } - return(n); - }; - - /* insert the best source rectangle into the best fitting parent node: a or b - * [] = pick_next(array of source nodes, target node array a, target node array b) - * @private - */ - var _pick_next = function(nodes, a, b) { - // Area of new enlarged rectangle - var area_a = RTree.Rectangle.squarified_ratio(a.w, a.h, a.nodes.length+1); - var area_b = RTree.Rectangle.squarified_ratio(b.w, b.h, b.nodes.length+1); - var high_area_delta; - var high_area_node; - var lowest_growth_group; - - for(var i = nodes.length-1; i>=0;i--) { - var l = nodes[i]; - var new_area_a = {}; - new_area_a.x = Math.min(a.x, l.x); new_area_a.y = Math.min(a.y, l.y); - new_area_a.w = Math.max(a.x+a.w, l.x+l.w) - new_area_a.x; new_area_a.h = Math.max(a.y+a.h, l.y+l.h) - new_area_a.y; - var change_new_area_a = Math.abs(RTree.Rectangle.squarified_ratio(new_area_a.w, new_area_a.h, a.nodes.length+2) - area_a); - - var new_area_b = {}; - new_area_b.x = Math.min(b.x, l.x); new_area_b.y = Math.min(b.y, l.y); - new_area_b.w = Math.max(b.x+b.w, l.x+l.w) - new_area_b.x; new_area_b.h = Math.max(b.y+b.h, l.y+l.h) - new_area_b.y; - var change_new_area_b = Math.abs(RTree.Rectangle.squarified_ratio(new_area_b.w, new_area_b.h, b.nodes.length+2) - area_b); - - if( !high_area_node || !high_area_delta || Math.abs( change_new_area_b - change_new_area_a ) < high_area_delta ) { - high_area_node = i; - high_area_delta = Math.abs(change_new_area_b-change_new_area_a); - lowest_growth_group = change_new_area_b < change_new_area_a ? b : a; - } - } - var temp_node = nodes.splice(high_area_node, 1)[0]; - if(a.nodes.length + nodes.length + 1 <= _Min_Width) { - a.nodes.push(temp_node); - RTree.Rectangle.expand_rectangle(a, temp_node); - } else if(b.nodes.length + nodes.length + 1 <= _Min_Width) { - b.nodes.push(temp_node); - RTree.Rectangle.expand_rectangle(b, temp_node); - } - else { - lowest_growth_group.nodes.push(temp_node); - RTree.Rectangle.expand_rectangle(lowest_growth_group, temp_node); - } - }; + if(!rect || !RTree.Rectangle.overlap_rectangle(rect, root)) + return ret_array; + + var ret_obj = {x:rect.x, y:rect.y, w:rect.w, h:rect.h, target:obj}; + + count_stack.push(root.nodes.length); + hit_stack.push(root); + + do { + var tree = hit_stack.pop(); + var i = count_stack.pop()-1; + + if("target" in ret_obj) { // We are searching for a target + while(i >= 0) { + var ltree = tree.nodes[i]; + if(RTree.Rectangle.overlap_rectangle(ret_obj, ltree)) { + if( (ret_obj.target && "leaf" in ltree && ltree.leaf === ret_obj.target) + ||(!ret_obj.target && ("leaf" in ltree || RTree.Rectangle.contains_rectangle(ltree, ret_obj)))) { // A Match !! + // Yup we found a match... + // we can cancel search and start walking up the list + if("nodes" in ltree) {// If we are deleting a node not a leaf... + ret_array = _search_subtree(ltree, true, [], ltree); + tree.nodes.splice(i, 1); + } else { + ret_array = tree.nodes.splice(i, 1); + } + // Resize MBR down... + RTree.Rectangle.make_MBR(tree.nodes, tree); + delete ret_obj.target; + if(tree.nodes.length < _Min_Width) { // Underflow + ret_obj.nodes = _search_subtree(tree, true, [], tree); + } + break; + }/* else if("load" in ltree) { // A load + }*/ else if("nodes" in ltree) { // Not a Leaf + current_depth += 1; + count_stack.push(i); + hit_stack.push(tree); + tree = ltree; + i = ltree.nodes.length; + } + } + i -= 1; + } + } else if("nodes" in ret_obj) { // We are unsplitting + tree.nodes.splice(i+1, 1); // Remove unsplit node + // ret_obj.nodes contains a list of elements removed from the tree so far + if(tree.nodes.length > 0) + RTree.Rectangle.make_MBR(tree.nodes, tree); + for(var t = 0;t 0 && tree.nodes.length < _Min_Width) { // Underflow..AGAIN! + ret_obj.nodes = _search_subtree(tree, true, ret_obj.nodes, tree); + tree.nodes.length = 0; + }else { + delete ret_obj.nodes; // Just start resizing + } + } else { // we are just resizing + RTree.Rectangle.make_MBR(tree.nodes, tree); + } + current_depth -= 1; + }while(hit_stack.length > 0); + + return(ret_array); + }; + + /* choose the best damn node for rectangle to be inserted into + * [ leaf node parent ] = _choose_leaf_subtree(rectangle, root to start search at) + * @private + */ + var _choose_leaf_subtree = function(rect, root) { + var best_choice_index = -1; + var best_choice_stack = []; + var best_choice_area; + + var load_callback = function(local_tree, local_node){ + return(function(data) { + local_tree._attach_data(local_node, data); + }); + }; + + best_choice_stack.push(root); + var nodes = root.nodes; + + do { + if(best_choice_index != -1) { + best_choice_stack.push(nodes[best_choice_index]); + nodes = nodes[best_choice_index].nodes; + best_choice_index = -1; + } + + for(var i = nodes.length-1; i >= 0; i--) { + var ltree = nodes[i]; + if("leaf" in ltree) { + // Bail out of everything and start inserting + best_choice_index = -1; + break; + } /*else if(ltree.load) { + throw( "Can't insert into partially loaded tree ... yet!"); + //jQuery.getJSON(ltree.load, load_callback(this, ltree)); + //delete ltree.load; + }*/ + // Area of new enlarged rectangle + var old_lratio = RTree.Rectangle.squarified_ratio(ltree.w, ltree.h, ltree.nodes.length+1); + + // Enlarge rectangle to fit new rectangle + var nw = Math.max(ltree.x+ltree.w, rect.x+rect.w) - Math.min(ltree.x, rect.x); + var nh = Math.max(ltree.y+ltree.h, rect.y+rect.h) - Math.min(ltree.y, rect.y); + + // Area of new enlarged rectangle + var lratio = RTree.Rectangle.squarified_ratio(nw, nh, ltree.nodes.length+2); + + if(best_choice_index < 0 || Math.abs(lratio - old_lratio) < best_choice_area) { + best_choice_area = Math.abs(lratio - old_lratio); best_choice_index = i; + } + } + }while(best_choice_index != -1); + + return(best_choice_stack); + }; + + /* split a set of nodes into two roughly equally-filled nodes + * [ an array of two new arrays of nodes ] = linear_split(array of nodes) + * @private + */ + var _linear_split = function(nodes) { + var n = _pick_linear(nodes); + while(nodes.length > 0) { + _pick_next(nodes, n[0], n[1]); + } + return(n); + }; - /* pick the "best" two starter nodes to use as seeds using the "linear" criteria - * [ an array of two new arrays of nodes ] = pick_linear(array of source nodes) - * @private - */ - var _pick_linear = function(nodes) { - var lowest_high_x = nodes.length-1; - var highest_low_x = 0; - var lowest_high_y = nodes.length-1; - var highest_low_y = 0; + /* insert the best source rectangle into the best fitting parent node: a or b + * [] = pick_next(array of source nodes, target node array a, target node array b) + * @private + */ + var _pick_next = function(nodes, a, b) { + // Area of new enlarged rectangle + var area_a = RTree.Rectangle.squarified_ratio(a.w, a.h, a.nodes.length+1); + var area_b = RTree.Rectangle.squarified_ratio(b.w, b.h, b.nodes.length+1); + var high_area_delta; + var high_area_node; + var lowest_growth_group; + + for(var i = nodes.length-1; i>=0;i--) { + var l = nodes[i]; + var new_area_a = {}; + new_area_a.x = Math.min(a.x, l.x); new_area_a.y = Math.min(a.y, l.y); + new_area_a.w = Math.max(a.x+a.w, l.x+l.w) - new_area_a.x; new_area_a.h = Math.max(a.y+a.h, l.y+l.h) - new_area_a.y; + var change_new_area_a = Math.abs(RTree.Rectangle.squarified_ratio(new_area_a.w, new_area_a.h, a.nodes.length+2) - area_a); + + var new_area_b = {}; + new_area_b.x = Math.min(b.x, l.x); new_area_b.y = Math.min(b.y, l.y); + new_area_b.w = Math.max(b.x+b.w, l.x+l.w) - new_area_b.x; new_area_b.h = Math.max(b.y+b.h, l.y+l.h) - new_area_b.y; + var change_new_area_b = Math.abs(RTree.Rectangle.squarified_ratio(new_area_b.w, new_area_b.h, b.nodes.length+2) - area_b); + + if( !high_area_node || !high_area_delta || Math.abs( change_new_area_b - change_new_area_a ) < high_area_delta ) { + high_area_node = i; + high_area_delta = Math.abs(change_new_area_b-change_new_area_a); + lowest_growth_group = change_new_area_b < change_new_area_a ? b : a; + } + } + var temp_node = nodes.splice(high_area_node, 1)[0]; + if(a.nodes.length + nodes.length + 1 <= _Min_Width) { + a.nodes.push(temp_node); + RTree.Rectangle.expand_rectangle(a, temp_node); + } else if(b.nodes.length + nodes.length + 1 <= _Min_Width) { + b.nodes.push(temp_node); + RTree.Rectangle.expand_rectangle(b, temp_node); + } + else { + lowest_growth_group.nodes.push(temp_node); + RTree.Rectangle.expand_rectangle(lowest_growth_group, temp_node); + } + }; + + /* pick the "best" two starter nodes to use as seeds using the "linear" criteria + * [ an array of two new arrays of nodes ] = pick_linear(array of source nodes) + * @private + */ + var _pick_linear = function(nodes) { + var lowest_high_x = nodes.length-1; + var highest_low_x = 0; + var lowest_high_y = nodes.length-1; + var highest_low_y = 0; var t1, t2; - - for(var i = nodes.length-2; i>=0;i--) { - var l = nodes[i]; - if(l.x > nodes[highest_low_x].x ) highest_low_x = i; - else if(l.x+l.w < nodes[lowest_high_x].x+nodes[lowest_high_x].w) lowest_high_x = i; - if(l.y > nodes[highest_low_y].y ) highest_low_y = i; - else if(l.y+l.h < nodes[lowest_high_y].y+nodes[lowest_high_y].h) lowest_high_y = i; - } - var dx = Math.abs((nodes[lowest_high_x].x+nodes[lowest_high_x].w) - nodes[highest_low_x].x); - var dy = Math.abs((nodes[lowest_high_y].y+nodes[lowest_high_y].h) - nodes[highest_low_y].y); - if( dx > dy ) { - if(lowest_high_x > highest_low_x) { - t1 = nodes.splice(lowest_high_x, 1)[0]; - t2 = nodes.splice(highest_low_x, 1)[0]; - } else { - t2 = nodes.splice(highest_low_x, 1)[0]; - t1 = nodes.splice(lowest_high_x, 1)[0]; - } - } else { - if(lowest_high_y > highest_low_y) { - t1 = nodes.splice(lowest_high_y, 1)[0]; - t2 = nodes.splice(highest_low_y, 1)[0]; - } else { - t2 = nodes.splice(highest_low_y, 1)[0]; - t1 = nodes.splice(lowest_high_y, 1)[0]; - } - } - return([{x:t1.x, y:t1.y, w:t1.w, h:t1.h, nodes:[t1]}, - {x:t2.x, y:t2.y, w:t2.w, h:t2.h, nodes:[t2]} ]); - }; - - var _attach_data = function(node, more_tree){ - node.nodes = more_tree.nodes; - node.x = more_tree.x; node.y = more_tree.y; - node.w = more_tree.w; node.h = more_tree.h; - return(node); - }; - /* non-recursive internal search function - * [ nodes | objects ] = _search_subtree(rectangle, [return node data], [array to fill], root to begin search at) - * @private - */ - var _search_subtree = function(rect, return_node, return_array, root) { - var hit_stack = []; // Contains the elements that overlap - - if(!RTree.Rectangle.overlap_rectangle(rect, root)) - return(return_array); - - var load_callback = function(local_tree, local_node){ - return(function(data) { - local_tree._attach_data(local_node, data); - }); - }; - - hit_stack.push(root.nodes); - - do { - var nodes = hit_stack.pop(); - - for(var i = nodes.length-1; i >= 0; i--) { - var ltree = nodes[i]; - if(RTree.Rectangle.overlap_rectangle(rect, ltree)) { - if("nodes" in ltree) { // Not a Leaf - hit_stack.push(ltree.nodes); - } else if("leaf" in ltree) { // A Leaf !! - if(!return_node) - return_array.push(ltree.leaf); - else - return_array.push(ltree); - }/* else if("load" in ltree) { // We need to fetch a URL for some more tree data - jQuery.getJSON(ltree.load, load_callback(this, ltree)); - delete ltree.load; - // i++; // Replay this entry - }*/ - } - } - }while(hit_stack.length > 0); - - return(return_array); - }; - - /* non-recursive internal insert function - * [] = _insert_subtree(rectangle, object to insert, root to begin insertion at) - * @private - */ - var _insert_subtree = function(node, root) { - var bc; // Best Current node - // Initial insertion is special because we resize the Tree and we don't - // care about any overflow (seriously, how can the first object overflow?) - if(root.nodes.length == 0) { - root.x = node.x; root.y = node.y; - root.w = node.w; root.h = node.h; - root.nodes.push(node); - return; - } - - // Find the best fitting leaf node - // choose_leaf returns an array of all tree levels (including root) - // that were traversed while trying to find the leaf - var tree_stack = _choose_leaf_subtree(node, root); - var ret_obj = node;//{x:rect.x,y:rect.y,w:rect.w,h:rect.h, leaf:obj}; - - // Walk back up the tree resizing and inserting as needed - do { - //handle the case of an empty node (from a split) - if(bc && "nodes" in bc && bc.nodes.length == 0) { - var pbc = bc; // Past bc - bc = tree_stack.pop(); - for(var t=0;t 0); - }; + for(var i = nodes.length-2; i>=0;i--) { + var l = nodes[i]; + if(l.x > nodes[highest_low_x].x ) highest_low_x = i; + else if(l.x+l.w < nodes[lowest_high_x].x+nodes[lowest_high_x].w) lowest_high_x = i; + if(l.y > nodes[highest_low_y].y ) highest_low_y = i; + else if(l.y+l.h < nodes[lowest_high_y].y+nodes[lowest_high_y].h) lowest_high_y = i; + } + var dx = Math.abs((nodes[lowest_high_x].x+nodes[lowest_high_x].w) - nodes[highest_low_x].x); + var dy = Math.abs((nodes[lowest_high_y].y+nodes[lowest_high_y].h) - nodes[highest_low_y].y); + if( dx > dy ) { + if(lowest_high_x > highest_low_x) { + t1 = nodes.splice(lowest_high_x, 1)[0]; + t2 = nodes.splice(highest_low_x, 1)[0]; + } else { + t2 = nodes.splice(highest_low_x, 1)[0]; + t1 = nodes.splice(lowest_high_x, 1)[0]; + } + } else { + if(lowest_high_y > highest_low_y) { + t1 = nodes.splice(lowest_high_y, 1)[0]; + t2 = nodes.splice(highest_low_y, 1)[0]; + } else { + t2 = nodes.splice(highest_low_y, 1)[0]; + t1 = nodes.splice(lowest_high_y, 1)[0]; + } + } + return([{x:t1.x, y:t1.y, w:t1.w, h:t1.h, nodes:[t1]}, + {x:t2.x, y:t2.y, w:t2.w, h:t2.h, nodes:[t2]} ]); + }; - /* quick 'n' dirty function for plugins or manually drawing the tree - * [ tree ] = RTree.get_tree(): returns the raw tree data. useful for adding - * @public - * !! DEPRECATED !! - */ - this.get_tree = function() { - return _T; - }; - - /* quick 'n' dirty function for plugins or manually loading the tree - * [ tree ] = RTree.set_tree(sub-tree, where to attach): returns the raw tree data. useful for adding - * @public - * !! DEPRECATED !! - */ - this.set_tree = function(new_tree, where) { - if(!where) - where = _T; - return(_attach_data(where, new_tree)); - }; - - /* non-recursive search function - * [ nodes | objects ] = RTree.search(rectangle, [return node data], [array to fill]) - * @public - */ - this.search = function(rect, return_node, return_array) { - if(arguments.length < 1) - throw "Wrong number of arguments. RT.Search requires at least a bounding rectangle." - - switch(arguments.length) { - case 1: - arguments[1] = false;// Add an "return node" flag - may be removed in future - case 2: - arguments[2] = []; // Add an empty array to contain results - case 3: - arguments[3] = _T; // Add root node to end of argument list - default: - arguments.length = 4; - } - return(_search_subtree.apply(this, arguments)); - }; - - /* partially-recursive toJSON function - * [ string ] = RTree.toJSON([rectangle], [tree]) - * @public - */ - this.toJSON = function(rect, tree) { - var hit_stack = []; // Contains the elements that overlap - var count_stack = []; // Contains the elements that overlap - var return_stack = {}; // Contains the elements that overlap - var max_depth = 3; // This triggers recursion and tree-splitting - var current_depth = 1; - var return_string = ""; - - if(rect && !RTree.Rectangle.overlap_rectangle(rect, _T)) - return ""; - - if(!tree) { - count_stack.push(_T.nodes.length); - hit_stack.push(_T.nodes); - return_string += "var main_tree = {x:"+_T.x.toFixed()+",y:"+_T.y.toFixed()+",w:"+_T.w.toFixed()+",h:"+_T.h.toFixed()+",nodes:["; - } else { - max_depth += 4; - count_stack.push(tree.nodes.length); - hit_stack.push(tree.nodes); - return_string += "var main_tree = {x:"+tree.x.toFixed()+",y:"+tree.y.toFixed()+",w:"+tree.w.toFixed()+",h:"+tree.h.toFixed()+",nodes:["; - } - - do { - var nodes = hit_stack.pop(); - var i = count_stack.pop()-1; - - if(i >= 0 && i < nodes.length-1) - return_string += ","; - - while(i >= 0) { - var ltree = nodes[i]; - if(!rect || RTree.Rectangle.overlap_rectangle(rect, ltree)) { - if(ltree.nodes) { // Not a Leaf - if(current_depth >= max_depth) { - var len = return_stack.length; - var nam = _name_to_id("saved_subtree"); - return_string += "{x:"+ltree.x.toFixed()+",y:"+ltree.y.toFixed()+",w:"+ltree.w.toFixed()+",h:"+ltree.h.toFixed()+",load:'"+nam+".js'}"; - return_stack[nam] = this.toJSON(rect, ltree); - if(i > 0) - return_string += "," - } else { - return_string += "{x:"+ltree.x.toFixed()+",y:"+ltree.y.toFixed()+",w:"+ltree.w.toFixed()+",h:"+ltree.h.toFixed()+",nodes:["; - current_depth += 1; - count_stack.push(i); - hit_stack.push(nodes); - nodes = ltree.nodes; - i = ltree.nodes.length; - } - } else if(ltree.leaf) { // A Leaf !! - var data = ltree.leaf.toJSON ? ltree.leaf.toJSON() : JSON.stringify(ltree.leaf); - return_string += "{x:"+ltree.x.toFixed()+",y:"+ltree.y.toFixed()+",w:"+ltree.w.toFixed()+",h:"+ltree.h.toFixed()+",leaf:" + data + "}"; - if(i > 0) - return_string += "," - } else if(ltree.load) { // A load - return_string += "{x:"+ltree.x.toFixed()+",y:"+ltree.y.toFixed()+",w:"+ltree.w.toFixed()+",h:"+ltree.h.toFixed()+",load:'" + ltree.load + "'}"; - if(i > 0) - return_string += "," - } - } - i -= 1; - } - if(i < 0) { - return_string += "]}"; current_depth -= 1; - } - }while(hit_stack.length > 0); - - return_string+=";"; - - for(var my_key in return_stack) { - return_string += "\nvar " + my_key + " = function(){" + return_stack[my_key] + " return(main_tree);};"; - } - return(return_string); - }; - - /* non-recursive function that deletes a specific - * [ number ] = RTree.remove(rectangle, obj) - */ - this.remove = function(rect, obj) { - if(arguments.length < 1) - throw "Wrong number of arguments. RT.remove requires at least a bounding rectangle." - - switch(arguments.length) { - case 1: - arguments[1] = false; // obj == false for conditionals - case 2: - arguments[2] = _T; // Add root node to end of argument list - default: - arguments.length = 3; - } - if(arguments[1] === false) { // Do area-wide delete - var numberdeleted = 0; - var ret_array = []; - do { - numberdeleted=ret_array.length; - ret_array = ret_array.concat(_remove_subtree.apply(this, arguments)); - }while( numberdeleted != ret_array.length); - return ret_array; - } - else { // Delete a specific item - return(_remove_subtree.apply(this, arguments)); - } - }; - - /* non-recursive insert function - * [] = RTree.insert(rectangle, object to insert) - */ - this.insert = function(rect, obj) { - if(arguments.length < 2) - throw "Wrong number of arguments. RT.Insert requires at least a bounding rectangle and an object." - - return(_insert_subtree({x:rect.x,y:rect.y,w:rect.w,h:rect.h,leaf:obj}, _T)); - }; - - /* non-recursive delete function - * [deleted object] = RTree.remove(rectangle, [object to delete]) - */ + var _attach_data = function(node, more_tree){ + node.nodes = more_tree.nodes; + node.x = more_tree.x; node.y = more_tree.y; + node.w = more_tree.w; node.h = more_tree.h; + return(node); + }; + + /* non-recursive internal search function + * [ nodes | objects ] = _search_subtree(rectangle, [return node data], [array to fill], root to begin search at) + * @private + */ + var _search_subtree = function(rect, return_node, return_array, root) { + var hit_stack = []; // Contains the elements that overlap + + if(!RTree.Rectangle.overlap_rectangle(rect, root)) + return(return_array); + + var load_callback = function(local_tree, local_node){ + return(function(data) { + local_tree._attach_data(local_node, data); + }); + }; + + hit_stack.push(root.nodes); + + do { + var nodes = hit_stack.pop(); + + for(var i = nodes.length-1; i >= 0; i--) { + var ltree = nodes[i]; + if(RTree.Rectangle.overlap_rectangle(rect, ltree)) { + if("nodes" in ltree) { // Not a Leaf + hit_stack.push(ltree.nodes); + } else if("leaf" in ltree) { // A Leaf !! + if(!return_node) + return_array.push(ltree.leaf); + else + return_array.push(ltree); + }/* else if("load" in ltree) { // We need to fetch a URL for some more tree data + jQuery.getJSON(ltree.load, load_callback(this, ltree)); + delete ltree.load; + // i++; // Replay this entry + }*/ + } + } + }while(hit_stack.length > 0); + + return(return_array); + }; + + /* non-recursive internal insert function + * [] = _insert_subtree(rectangle, object to insert, root to begin insertion at) + * @private + */ + var _insert_subtree = function(node, root) { + var bc; // Best Current node + // Initial insertion is special because we resize the Tree and we don't + // care about any overflow (seriously, how can the first object overflow?) + if(root.nodes.length == 0) { + root.x = node.x; root.y = node.y; + root.w = node.w; root.h = node.h; + root.nodes.push(node); + return; + } + + // Find the best fitting leaf node + // choose_leaf returns an array of all tree levels (including root) + // that were traversed while trying to find the leaf + var tree_stack = _choose_leaf_subtree(node, root); + var ret_obj = node;//{x:rect.x,y:rect.y,w:rect.w,h:rect.h, leaf:obj}; + + // Walk back up the tree resizing and inserting as needed + do { + //handle the case of an empty node (from a split) + if(bc && "nodes" in bc && bc.nodes.length == 0) { + var pbc = bc; // Past bc + bc = tree_stack.pop(); + for(var t=0;t 0); + }; + + /* quick 'n' dirty function for plugins or manually drawing the tree + * [ tree ] = RTree.get_tree(): returns the raw tree data. useful for adding + * @public + * !! DEPRECATED !! + */ + this.get_tree = function() { + return _T; + }; + + /* quick 'n' dirty function for plugins or manually loading the tree + * [ tree ] = RTree.set_tree(sub-tree, where to attach): returns the raw tree data. useful for adding + * @public + * !! DEPRECATED !! + */ + this.set_tree = function(new_tree, where) { + if(!where) + where = _T; + return(_attach_data(where, new_tree)); + }; + + /* non-recursive search function + * [ nodes | objects ] = RTree.search(rectangle, [return node data], [array to fill]) + * @public + */ + this.search = function(rect, return_node, return_array) { + if(arguments.length < 1) + throw "Wrong number of arguments. RT.Search requires at least a bounding rectangle." + + switch(arguments.length) { + case 1: + arguments[1] = false;// Add an "return node" flag - may be removed in future + case 2: + arguments[2] = []; // Add an empty array to contain results + case 3: + arguments[3] = _T; // Add root node to end of argument list + default: + arguments.length = 4; + } + return(_search_subtree.apply(this, arguments)); + }; + + /* partially-recursive toJSON function + * [ string ] = RTree.toJSON([rectangle], [tree]) + * @public + */ + this.toJSON = function(rect, tree) { + var hit_stack = []; // Contains the elements that overlap + var count_stack = []; // Contains the elements that overlap + var return_stack = {}; // Contains the elements that overlap + var max_depth = 3; // This triggers recursion and tree-splitting + var current_depth = 1; + var return_string = ""; + + if(rect && !RTree.Rectangle.overlap_rectangle(rect, _T)) + return ""; + + if(!tree) { + count_stack.push(_T.nodes.length); + hit_stack.push(_T.nodes); + return_string += "var main_tree = {x:"+_T.x.toFixed()+",y:"+_T.y.toFixed()+",w:"+_T.w.toFixed()+",h:"+_T.h.toFixed()+",nodes:["; + } else { + max_depth += 4; + count_stack.push(tree.nodes.length); + hit_stack.push(tree.nodes); + return_string += "var main_tree = {x:"+tree.x.toFixed()+",y:"+tree.y.toFixed()+",w:"+tree.w.toFixed()+",h:"+tree.h.toFixed()+",nodes:["; + } + + do { + var nodes = hit_stack.pop(); + var i = count_stack.pop()-1; + + if(i >= 0 && i < nodes.length-1) + return_string += ","; + + while(i >= 0) { + var ltree = nodes[i]; + if(!rect || RTree.Rectangle.overlap_rectangle(rect, ltree)) { + if(ltree.nodes) { // Not a Leaf + if(current_depth >= max_depth) { + var len = return_stack.length; + var nam = _name_to_id("saved_subtree"); + return_string += "{x:"+ltree.x.toFixed()+",y:"+ltree.y.toFixed()+",w:"+ltree.w.toFixed()+",h:"+ltree.h.toFixed()+",load:'"+nam+".js'}"; + return_stack[nam] = this.toJSON(rect, ltree); + if(i > 0) + return_string += "," + } else { + return_string += "{x:"+ltree.x.toFixed()+",y:"+ltree.y.toFixed()+",w:"+ltree.w.toFixed()+",h:"+ltree.h.toFixed()+",nodes:["; + current_depth += 1; + count_stack.push(i); + hit_stack.push(nodes); + nodes = ltree.nodes; + i = ltree.nodes.length; + } + } else if(ltree.leaf) { // A Leaf !! + var data = ltree.leaf.toJSON ? ltree.leaf.toJSON() : JSON.stringify(ltree.leaf); + return_string += "{x:"+ltree.x.toFixed()+",y:"+ltree.y.toFixed()+",w:"+ltree.w.toFixed()+",h:"+ltree.h.toFixed()+",leaf:" + data + "}"; + if(i > 0) + return_string += "," + } else if(ltree.load) { // A load + return_string += "{x:"+ltree.x.toFixed()+",y:"+ltree.y.toFixed()+",w:"+ltree.w.toFixed()+",h:"+ltree.h.toFixed()+",load:'" + ltree.load + "'}"; + if(i > 0) + return_string += "," + } + } + i -= 1; + } + if(i < 0) { + return_string += "]}"; current_depth -= 1; + } + }while(hit_stack.length > 0); + + return_string+=";"; + + for(var my_key in return_stack) { + return_string += "\nvar " + my_key + " = function(){" + return_stack[my_key] + " return(main_tree);};"; + } + return(return_string); + }; + + /* non-recursive function that deletes a specific + * [ number ] = RTree.remove(rectangle, obj) + */ + this.remove = function(rect, obj) { + if(arguments.length < 1) + throw "Wrong number of arguments. RT.remove requires at least a bounding rectangle." + + switch(arguments.length) { + case 1: + arguments[1] = false; // obj == false for conditionals + case 2: + arguments[2] = _T; // Add root node to end of argument list + default: + arguments.length = 3; + } + if(arguments[1] === false) { // Do area-wide delete + var numberdeleted = 0; + var ret_array = []; + do { + numberdeleted=ret_array.length; + ret_array = ret_array.concat(_remove_subtree.apply(this, arguments)); + }while( numberdeleted != ret_array.length); + return ret_array; + } + else { // Delete a specific item + return(_remove_subtree.apply(this, arguments)); + } + }; + + /* non-recursive insert function + * [] = RTree.insert(rectangle, object to insert) + */ + this.insert = function(rect, obj) { + if(arguments.length < 2) + throw "Wrong number of arguments. RT.Insert requires at least a bounding rectangle and an object." + + return(_insert_subtree({x:rect.x,y:rect.y,w:rect.w,h:rect.h,leaf:obj}, _T)); + }; + + /* non-recursive delete function + * [deleted object] = RTree.remove(rectangle, [object to delete]) + */ //End of RTree }; @@ -1157,60 +1157,60 @@ var RTree = function(width){ /* Rectangle - Generic rectangle object - Not yet used */ RTree.Rectangle = function(ix, iy, iw, ih) { // new Rectangle(bounds) or new Rectangle(x, y, w, h) - var x, x2, y, y2, w, h; + var x, x2, y, y2, w, h; + + if(ix.x) { + x = ix.x; y = ix.y; + if(ix.w !== 0 && !ix.w && ix.x2){ + w = ix.x2-ix.x; h = ix.y2-ix.y; + } else { + w = ix.w; h = ix.h; + } + x2 = x + w; y2 = y + h; // For extra fastitude + } else { + x = ix; y = iy; w = iw; h = ih; + x2 = x + w; y2 = y + h; // For extra fastitude + } + this.x1 = this.x = function(){return x;}; + this.y1 = this.y = function(){return y;}; + this.x2 = function(){return x2;}; + this.y2 = function(){return y2;}; + this.w = function(){return w;}; + this.h = function(){return h;}; + + this.toJSON = function() { + return('{"x":'+x.toString()+', "y":'+y.toString()+', "w":'+w.toString()+', "h":'+h.toString()+'}'); + }; + + this.overlap = function(a) { + return(this.x() < a.x2() && this.x2() > a.x() && this.y() < a.y2() && this.y2() > a.y()); + }; + + this.expand = function(a) { + var nx = Math.min(this.x(), a.x()); + var ny = Math.min(this.y(), a.y()); + w = Math.max(this.x2(), a.x2()) - nx; + h = Math.max(this.y2(), a.y2()) - ny; + x = nx; y = ny; + return(this); + }; + + this.setRect = function(ix, iy, iw, ih) { + var x, x2, y, y2, w, h; if(ix.x) { - x = ix.x; y = ix.y; - if(ix.w !== 0 && !ix.w && ix.x2){ - w = ix.x2-ix.x; h = ix.y2-ix.y; - } else { - w = ix.w; h = ix.h; - } - x2 = x + w; y2 = y + h; // For extra fastitude - } else { - x = ix; y = iy; w = iw; h = ih; - x2 = x + w; y2 = y + h; // For extra fastitude - } - - this.x1 = this.x = function(){return x;}; - this.y1 = this.y = function(){return y;}; - this.x2 = function(){return x2;}; - this.y2 = function(){return y2;}; - this.w = function(){return w;}; - this.h = function(){return h;}; - - this.toJSON = function() { - return('{"x":'+x.toString()+', "y":'+y.toString()+', "w":'+w.toString()+', "h":'+h.toString()+'}'); - }; - - this.overlap = function(a) { - return(this.x() < a.x2() && this.x2() > a.x() && this.y() < a.y2() && this.y2() > a.y()); - }; - - this.expand = function(a) { - var nx = Math.min(this.x(), a.x()); - var ny = Math.min(this.y(), a.y()); - w = Math.max(this.x2(), a.x2()) - nx; - h = Math.max(this.y2(), a.y2()) - ny; - x = nx; y = ny; - return(this); - }; - - this.setRect = function(ix, iy, iw, ih) { - var x, x2, y, y2, w, h; - if(ix.x) { - x = ix.x; y = ix.y; - if(ix.w !== 0 && !ix.w && ix.x2) { - w = ix.x2-ix.x; h = ix.y2-ix.y; - } else { - w = ix.w; h = ix.h; - } - x2 = x + w; y2 = y + h; // For extra fastitude - } else { - x = ix; y = iy; w = iw; h = ih; - x2 = x + w; y2 = y + h; // For extra fastitude - } - }; + x = ix.x; y = ix.y; + if(ix.w !== 0 && !ix.w && ix.x2) { + w = ix.x2-ix.x; h = ix.y2-ix.y; + } else { + w = ix.w; h = ix.h; + } + x2 = x + w; y2 = y + h; // For extra fastitude + } else { + x = ix; y = iy; w = iw; h = ih; + x2 = x + w; y2 = y + h; // For extra fastitude + } + }; //End of RTree.Rectangle }; @@ -1220,7 +1220,7 @@ RTree.Rectangle = function(ix, iy, iw, ih) { // new Rectangle(bounds) or new Rec * @static function */ RTree.Rectangle.overlap_rectangle = function(a, b) { - return(a.x < (b.x+b.w) && (a.x+a.w) > b.x && a.y < (b.y+b.h) && (a.y+a.h) > b.y); + return(a.x < (b.x+b.w) && (a.x+a.w) > b.x && a.y < (b.y+b.h) && (a.y+a.h) > b.y); }; /* returns true if rectangle a is contained in rectangle b @@ -1228,20 +1228,20 @@ RTree.Rectangle.overlap_rectangle = function(a, b) { * @static function */ RTree.Rectangle.contains_rectangle = function(a, b) { - return((a.x+a.w) <= (b.x+b.w) && a.x >= b.x && (a.y+a.h) <= (b.y+b.h) && a.y >= b.y); + return((a.x+a.w) <= (b.x+b.w) && a.x >= b.x && (a.y+a.h) <= (b.y+b.h) && a.y >= b.y); }; /* expands rectangle A to include rectangle B, rectangle B is untouched * [ rectangle a ] = expand_rectangle(rectangle a, rectangle b) * @static function */ -RTree.Rectangle.expand_rectangle = function(a, b) { - var nx = Math.min(a.x, b.x); - var ny = Math.min(a.y, b.y); - a.w = Math.max(a.x+a.w, b.x+b.w) - nx; - a.h = Math.max(a.y+a.h, b.y+b.h) - ny; - a.x = nx; a.y = ny; - return(a); +RTree.Rectangle.expand_rectangle = function(a, b) { + var nx = Math.min(a.x, b.x); + var ny = Math.min(a.y, b.y); + a.w = Math.max(a.x+a.w, b.x+b.w) - nx; + a.h = Math.max(a.y+a.h, b.y+b.h) - ny; + a.x = nx; a.y = ny; + return(a); }; /* generates a minimally bounding rectangle for all rectangles in @@ -1251,18 +1251,18 @@ RTree.Rectangle.expand_rectangle = function(a, b) { * @static function */ RTree.Rectangle.make_MBR = function(nodes, rect) { - if(nodes.length < 1) - return({x:0, y:0, w:0, h:0}); - //throw "make_MBR: nodes must contain at least one rectangle!"; - if(!rect) - rect = {x:nodes[0].x, y:nodes[0].y, w:nodes[0].w, h:nodes[0].h}; - else - rect.x = nodes[0].x; rect.y = nodes[0].y; rect.w = nodes[0].w; rect.h = nodes[0].h; - - for(var i = nodes.length-1; i>0; i--) - RTree.Rectangle.expand_rectangle(rect, nodes[i]); - - return(rect); + if(nodes.length < 1) + return({x:0, y:0, w:0, h:0}); + //throw "make_MBR: nodes must contain at least one rectangle!"; + if(!rect) + rect = {x:nodes[0].x, y:nodes[0].y, w:nodes[0].w, h:nodes[0].h}; + else + rect.x = nodes[0].x; rect.y = nodes[0].y; rect.w = nodes[0].w; rect.h = nodes[0].h; + + for(var i = nodes.length-1; i>0; i--) + RTree.Rectangle.expand_rectangle(rect, nodes[i]); + + return(rect); }; (function(){function D(){}function z(){this.was=[0]}function C(a,b,c){this.hufts=new Int32Array(4320);this.window=new Uint8Array(c);this.end=c;this.checkfn=b;this.mode=0;this.reset(a,null);this.index=this.table=this.left=0;this.blens=null;this.bb=new Int32Array(1);this.tb=new Int32Array(1);this.codes=new E;this.check=this.write=this.read=this.bitb=this.bitk=this.last=0;this.inftree=new F}function E(){}function F(){}function y(a,b,c,d,h){if(0!=h){if(!a)throw"Undef src";if(!c)throw"Undef dest";if(0== @@ -1373,6 +1373,8 @@ var Genoverse = Base.extend({ return this.die('Your browser does not support this functionality'); } + config = config || {}; + config.container = $(config.container); // Make sure container is a jquery object, jquery recognises itself automatically if (!(config.container && config.container.length)) { @@ -2467,37 +2469,86 @@ var Genoverse = Base.extend({ } }), - makeMenu: function (feature, event, track) { - if (!feature.menuEl) { - var browser = this; - var menu = this.menuTemplate.clone(true).data({ browser: this, feature: feature }); - var content = $('.gv-menu-content', menu).remove(); - var loading = $('.gv-menu-loading', menu); - var getMenu = track ? track.controller.populateMenu(feature) : feature; - var isDeferred = typeof getMenu === 'object' && typeof getMenu.promise === 'function'; - var i, j, table, el, start, end, linkData, key, columns, colspan; + makeMenu: function (features, event, track) { + if (!features) { + return false; + } - function focus() { - var data = $(this).data(); - var length = data.end - data.start + 1; - var context = Math.max(Math.round(length / 4), 25); + if (!$.isArray(features)) { + features = [ features ]; + } - browser.moveTo(data.start - context, data.end + context, true); + if (features.length === 0) { + return false; + } else if (features.length === 1) { + return this.makeFeatureMenu(features[0], event, track); + } - return false; - } + var browser = this; + var menu = this.menuTemplate.clone(true).data({ browser: this }); + var table = $('.gv-menu-content', menu).addClass('gv-menu-content-first').find('table'); + + $('.gv-focus, .gv-highlight, .gv-menu-loading', menu).remove(); + $('.gv-title', menu).html(features.length + ' features'); + + $.each(features.sort(function (a, b) { return a.start - b.start; }), function (i, feature) { + var location = feature.chr + ':' + feature.start + (feature.end === feature.start ? '' : '-' + feature.end); + var title = feature.menuLabel || feature.name || ($.isArray(feature.label) ? feature.label.join(' ') : feature.label) || (feature.id + ''); - function highlight() { - browser.addHighlight($(this).data()); + $('').html(title.match(location) ? title : (location + ' ' + title)).on('click', function (e) { + browser.makeFeatureMenu(feature, e, track); return false; - } + }).appendTo($('').appendTo($('').appendTo(table))); + }); + + menu.appendTo(this.superContainer || this.container).show(); + + if (event) { + menu.css({ left: 0, top: 0 }).position({ of: event, my: 'left top', collision: 'flipfit' }); + } + + this.menus = this.menus.add(menu); + + if (track) { + track.prop('menus', track.prop('menus').add(menu)); + } + + return menu; + }, + + makeFeatureMenu: function (feature, e, track) { + var browser = this; + var container = this.superContainer || this.container; + var menu, content, loading, getMenu, isDeferred, i, j, el, start, end, linkData, key, columns, colspan; + + function focus() { + var data = $(this).data(); + var length = data.end - data.start + 1; + var context = Math.max(Math.round(length / 4), 25); + + browser.moveTo(data.start - context, data.end + context, true); + + return false; + } + + function highlight() { + browser.addHighlight($(this).data()); + return false; + } + + if (!feature.menuEl) { + menu = browser.menuTemplate.clone(true).data({ browser: browser, feature: feature }); + content = $('.gv-menu-content', menu).remove(); + loading = $('.gv-menu-loading', menu); + getMenu = track ? track.controller.populateMenu(feature) : feature; + isDeferred = typeof getMenu === 'object' && typeof getMenu.promise === 'function'; if (isDeferred) { loading.show(); } $.when(getMenu).done(function (properties) { - if (Object.prototype.toString.call(properties) !== '[object Array]') { + if (!$.isArray(properties)) { properties = [ properties ]; } @@ -2506,7 +2557,7 @@ var Genoverse = Base.extend({ el = content.clone().addClass(i ? '' : 'gv-menu-content-first').appendTo(menu); start = parseInt(typeof properties[i].start !== 'undefined' ? properties[i].start : feature.start, 10); end = parseInt(typeof properties[i].end !== 'undefined' ? properties[i].end : feature.end, 10); - columns = Math.max.apply(Math, $.map(properties[i], function (v) { return Object.prototype.toString.call(v) === '[object Array]' ? v.length : 1; })); + columns = Math.max.apply(Math, $.map(properties[i], function (v) { return $.isArray(v) ? v.length : 1; })); $('.gv-title', el)[properties[i].title ? 'html' : 'remove'](properties[i].title); @@ -2529,7 +2580,7 @@ var Genoverse = Base.extend({ table += '' + key + ''; if (!colspan) { - if (Object.prototype.toString.call(properties[i][key]) === '[object Array]') { + if ($.isArray(properties[i][key])) { for (j = 0; j < properties[i][key].length; j++) { table += '' + properties[i][key][j] + ''; } @@ -2544,7 +2595,7 @@ var Genoverse = Base.extend({ } } - $('table', el).html(table); + $('table', el)[table ? 'html' : 'remove'](table); } if (isDeferred) { @@ -2556,12 +2607,12 @@ var Genoverse = Base.extend({ menu.addClass(track.id).data('track', track); } - feature.menuEl = menu.appendTo(this.superContainer || this.container); + feature.menuEl = menu.appendTo(container); } else { - feature.menuEl.appendTo(this.superContainer || this.container); // Move the menu to the end of the container again, so that it will always be on top of other menus + feature.menuEl.appendTo(container); // Move the menu to the end of the container again, so that it will always be on top of other menus } - this.menus = this.menus.add(feature.menuEl); + browser.menus = browser.menus.add(feature.menuEl); if (track) { track.prop('menus', track.prop('menus').add(feature.menuEl)); @@ -2569,8 +2620,8 @@ var Genoverse = Base.extend({ feature.menuEl.show(); // Must show before positioning, else position will be wrong - if (event) { - feature.menuEl.css({ left: 0, top: 0 }).position({ of: event, my: 'left top', collision: 'flipfit' }); + if (e) { + feature.menuEl.css({ left: 0, top: 0 }).position({ of: e, my: 'left top', collision: 'flipfit' }); } return feature.menuEl; @@ -2674,6 +2725,11 @@ var Genoverse = Base.extend({ destroy: function () { this.onTracks('destructor'); (this.superContainer || this.container).empty(); + + if (this.zoomInHighlight) { + this.zoomInHighlight.add(this.zoomOutHighlight).remove(); + } + $(window).add(document).off(this.eventNamespace); for (var key in this) { @@ -2902,6 +2958,33 @@ Genoverse.Track = Base.extend({ } } + /* + * Abandon all hope! If you've tracked a bug to this line of code, be afraid. + * It will almost certainly be due to the wonderful way the javascript objects work. + * + * Consider the following: + * + * var Obj = function () {}; + * + * Obj.prototype = { + * scalar : 1, + * array : [ 1, 2, 3 ], + * hash : { a: 1, b : 2 } + * }; + * + * var x = new Obj(); + * + * x.scalar = 10; + * x.array[0] = 10; + * x.hash.a = 10; + * + * var y = new Obj(); + * + * y is now { scalar: 1, array: [ 10, 2, 3 ], hash: { a: 10, b : 2 } }, since memory locations of objects in prototypes are shared. + * + * This has been the cause of numerous Genoverse bugs in the past, due to property sharing between different tracks, models, views, and controllers. + * See also the line a bit further down: this[obj].constructor.extend(mvcSettings[obj].func); + */ this.extend(trackSettings); for (i = 0; i < 3; i++) { @@ -2925,6 +3008,7 @@ Genoverse.Track = Base.extend({ } } + // Abandon all hope! (see above) this[obj].constructor.extend(mvcSettings[obj].func); if (obj === 'model' && typeof test.url !== 'undefined') { @@ -4469,21 +4553,21 @@ Genoverse.Track.Controller.Stranded = Genoverse.Track.Controller.extend({ Genoverse.Track.Model.Stranded = Genoverse.Track.Model.extend({ init: function (reset) { this.base(reset); - + if (!reset) { var otherTrack = this.prop('forwardTrack'); - + if (otherTrack) { this.features = otherTrack.prop('features'); this.featuresById = otherTrack.prop('featuresById'); } } }, - + setURL: function (urlParams, update) { this.base($.extend(urlParams || this.urlParams, { strand: this.track.featureStrand }), update); }, - + findFeatures: function () { var strand = this.track.featureStrand; return $.grep(this.base.apply(this, arguments), function (feature) { return feature.strand === strand; }); @@ -4524,34 +4608,34 @@ Genoverse.Track.Controller.Sequence = Genoverse.Track.Controller.extend({ // assumes that the data source responds with raw sequence text // see Fasta model for more specific example Genoverse.Track.Model.Sequence = Genoverse.Track.Model.extend({ - threshold : 100000, + threshold : 100000, chunkSize : 1000, buffer : 0, dataType : 'text', - + init: function () { this.base(); this.chunks = {}; }, - + getData: function (start, end) { start = start - start % this.chunkSize + 1; end = end + this.chunkSize - end % this.chunkSize; return this.base(start, end); }, - + parseData: function (data, start, end) { data = data.replace(/\n/g, ''); - + if (this.prop('lowerCase')) { data = data.toLowerCase(); } - + for (var i = 0; i < data.length; i += this.chunkSize) { if (this.chunks[start + i]) { continue; } - + var feature = { id : start + i, start : start + i, @@ -4559,7 +4643,7 @@ Genoverse.Track.Model.Sequence = Genoverse.Track.Model.extend({ sequence : data.substr(i, this.chunkSize), sort : start + i }; - + this.chunks[feature.start] = feature; this.insertFeature(feature); } @@ -4569,23 +4653,23 @@ Genoverse.Track.Model.Sequence = Genoverse.Track.Model.extend({ Genoverse.Track.Model.Sequence.Fasta = Genoverse.Track.Model.Sequence.extend({ url : 'http://genoverse.org/data/Homo_sapiens.GRCh37.72.dna.chromosome.1.fa', // Example url - + // Following settings could be left undefined and will be detected automatically via .getStartByte() startByte : undefined, // Byte in the file where the sequence actually starts lineLength : undefined, // Length of the sequence line in the file - + // TODO: Check if URL provided - + getData: function (start, end) { var deferred = $.Deferred(); - + $.when(this.getStartByte()).done(function () { start = start - start % this.chunkSize + 1; end = end + this.chunkSize - end % this.chunkSize; - + var startByte = start - 1 + Math.floor((start - 1) / this.lineLength) + this.startByte; var endByte = end - 1 + Math.floor((end - 1) / this.lineLength) + this.startByte; - + $.ajax({ url : this.parseURL(start, end), dataType : this.dataType, @@ -4596,33 +4680,33 @@ Genoverse.Track.Model.Sequence.Fasta = Genoverse.Track.Model.Sequence.extend({ error : this.track.controller.showError }).done(function () { deferred.resolveWith(this); }).fail(function () { deferred.rejectWith(this); }); }).fail(function () { deferred.rejectWith(this); }); - + return deferred; }, - + getStartByte: function () { if (this.startByteRequest) { return this.startByteRequest; } - + if (this.startByte === undefined || this.lineLength === undefined) { this.startByteRequest = $.ajax({ url : this.parseURL(), dataType : 'text', context : this, headers : { 'Range': 'bytes=0-300' }, - xhrFields : this.xhrFields, + xhrFields : this.xhrFields, success : function (data) { if (data.indexOf('>') === 0) { this.startByte = data.indexOf('\n') + 1; } else { this.startByte = 0; } - + this.lineLength = data.indexOf('\n', this.startByte) - this.startByte; } }); - + return this.startByteRequest; } } @@ -4771,31 +4855,31 @@ Genoverse.Track.Model.SequenceVariation = Genoverse.Track.Model.extend({ Genoverse.Track.Model.SequenceVariation.VCF = Genoverse.Track.Model.SequenceVariation.extend({ dataType: 'text', - + parseData: function (text) { var lines = text.split('\n'); - + for (var i = 0; i < lines.length; i++) { if (!lines[i].length || lines[i].indexOf('#') === 0) { continue; } - + var fields = lines[i].split('\t'); - + if (fields.length < 5) { continue; } - + if (fields[0] === this.browser.chr || fields[0] === 'chr' + this.browser.chr) { var id = fields.slice(0, 3).join('|'); var start = parseInt(fields[1], 10); var alleles = fields[4].split(','); - + alleles.unshift(fields[3]); - + for (var j = 0; j < alleles.length; j++) { var end = start + alleles[j].length - 1; - + this.insertFeature({ id : id + '|' + alleles[j], sort : j, @@ -4807,7 +4891,7 @@ Genoverse.Track.Model.SequenceVariation.VCF = Genoverse.Track.Model.SequenceVari label : alleles[j], labelColor : '#FFFFFF', originalFeature : fields - }); + }); } } } @@ -4942,33 +5026,33 @@ Genoverse.Track.Model.Transcript.Ensembl = Genoverse.Track.Model.Transcript.exte // Basic GFF3 model for transcripts -// See http://www.broadinstitute.org/annotation/gebo/help/gff3.html +// See http://www.broadinstitute.org/annotation/gebo/help/gff3.html Genoverse.Track.Model.Transcript.GFF3 = Genoverse.Track.Model.Transcript.extend({ dataType : 'text', - - // Transcript structure map for column 3 (type) + + // Transcript structure map for column 3 (type) typeMap : { exon : 'exon', cds : 'cds' }, - + parseData: function (text) { var lines = text.split('\n'); - + for (var i = 0; i < lines.length; i++) { if (!lines[i].length || lines[i].indexOf('#') === 0) { continue; } - + var fields = lines[i].split('\t'); - + if (fields.length < 5) { continue; } - + if (fields[0] === this.browser.chr || fields[0].toLowerCase() === 'chr' + this.browser.chr || fields[0].match('[^1-9]' + this.browser.chr + '$')) { var feature = {}; - + feature.id = fields.slice(0, 5).join('|'); feature.start = parseInt(fields[3], 10); feature.end = parseInt(fields[4], 10); @@ -4976,19 +5060,19 @@ Genoverse.Track.Model.Transcript.GFF3 = Genoverse.Track.Model.Transcript.extend( feature.type = fields[2]; feature.score = fields[5]; feature.strand = fields[6] + '1'; - + if (fields[8]) { var frame = fields[8].split(';'); - + for (var j = 0; j < frame.length; j++) { var keyValue = frame[j].split('='); - + if (keyValue.length === 2) { feature[keyValue[0].toLowerCase()] = keyValue[1]; } } } - + // sub-feature came earlier than parent feature if (feature.parent && !this.featuresById[feature.parent]) { this.featuresById[feature.parent] = { @@ -4996,7 +5080,7 @@ Genoverse.Track.Model.Transcript.GFF3 = Genoverse.Track.Model.Transcript.extend( cds : [] }; } - + if (feature.parent && feature.type.toLowerCase() === this.typeMap.exon.toLowerCase()) { if (!$.grep(this.featuresById[feature.parent].exons, function (exon) { return exon.id === feature.id; }).length) { this.featuresById[feature.parent].exons.push(feature); @@ -5008,9 +5092,9 @@ Genoverse.Track.Model.Transcript.GFF3 = Genoverse.Track.Model.Transcript.extend( } else if (!feature.parent) { feature.label = feature.name || feature.id || ''; $.extend(feature, { label: feature.name || feature.id || '', exons: [], cds: [] }, this.featuresById[feature.id] || {}); - + delete this.featuresById[feature.id]; - + this.insertFeature(feature); } } @@ -5271,14 +5355,14 @@ Genoverse.Track.Model.File.BAM = Genoverse.Track.Model.File.extend({ Genoverse.Track.Model.File.BED = Genoverse.Track.Model.File.extend({ parseData: function (text) { var lines = text.split('\n'); - + for (var i = 0; i < lines.length; i++) { var fields = lines[i].split('\t'); - + if (fields.length < 3) { continue; } - + if (fields[0] === this.browser.chr || fields[0].toLowerCase() === 'chr' + this.browser.chr || fields[0].match('[^1-9]' + this.browser.chr + '$')) { var score = parseFloat(fields[4], 10); var color = '#000000'; @@ -5299,7 +5383,7 @@ Genoverse.Track.Model.File.BED = Genoverse.Track.Model.File.extend({ }); } } - }, + }, // As per https://genome.ucsc.edu/FAQ/FAQformat.html#format1 specification scoreColor: function (score) { @@ -5313,7 +5397,7 @@ Genoverse.Track.Model.File.BED = Genoverse.Track.Model.File.extend({ if (score <= 944) { return 'rgb(21,21,21)'; } return '#000000'; } -}); +}); Genoverse.Track.Model.File.GFF = Genoverse.Track.Model.File.extend({ parseData: function (text) { diff --git a/js/genoverse.combined.nojquery.js b/js/genoverse.combined.nojquery.js index 181460a9..0ad12977 100644 --- a/js/genoverse.combined.nojquery.js +++ b/js/genoverse.combined.nojquery.js @@ -15,7 +15,7 @@ * Thanks to: Seamus Leahy for adding deltaX and deltaY * * Version: 3.0.6 - * + * * Requires: 1.2.2+ */ @@ -39,7 +39,7 @@ $.event.special.mousewheel = { this.onmousewheel = handler; } }, - + teardown: function() { if ( this.removeEventListener ) { for ( var i=types.length; i; ) { @@ -55,7 +55,7 @@ $.fn.extend({ mousewheel: function(fn) { return fn ? this.bind("mousewheel", fn) : this.trigger("mousewheel"); }, - + unmousewheel: function(fn) { return this.unbind("mousewheel", fn); } @@ -66,27 +66,27 @@ function handler(event) { var orgEvent = event || window.event, args = [].slice.call( arguments, 1 ), delta = 0, returnValue = true, deltaX = 0, deltaY = 0; event = $.event.fix(orgEvent); event.type = "mousewheel"; - + // Old school scrollwheel delta if ( orgEvent.wheelDelta ) { delta = orgEvent.wheelDelta/120; } if ( orgEvent.detail ) { delta = -orgEvent.detail/3; } - + // New school multidimensional scroll (touchpads) deltas deltaY = delta; - + // Gecko if ( orgEvent.axis !== undefined && orgEvent.axis === orgEvent.HORIZONTAL_AXIS ) { deltaY = 0; deltaX = -1*delta; } - + // Webkit if ( orgEvent.wheelDeltaY !== undefined ) { deltaY = orgEvent.wheelDeltaY/120; } if ( orgEvent.wheelDeltaX !== undefined ) { deltaX = -1*orgEvent.wheelDeltaX/120; } - + // Add event and delta to the front of the arguments args.unshift(event, delta, deltaX, deltaY); - + return ($.event.dispatch || $.event.handle).apply(this, args); } @@ -137,7 +137,7 @@ $.fn.mousehold = function(timeout, f) { if (fireStep == 1) f.call(this, 1); fireStep = 0; } - + $(this).mouseout(clearMousehold); $(this).mouseup(clearMousehold); }) @@ -407,153 +407,153 @@ $.fn.mousehold = function(timeout, f) { })(jQuery); /* - Base.js, version 1.1 - Copyright 2006-2007, Dean Edwards - License: http://www.opensource.org/licenses/mit-license.php + Base.js, version 1.1 + Copyright 2006-2007, Dean Edwards + License: http://www.opensource.org/licenses/mit-license.php */ var Base = function() { - // dummy + // dummy }; Base.extend = function(_instance, _static) { // subclass - var extend = Base.prototype.extend; - - // build the prototype - Base._prototyping = true; - var proto = new this; - extend.call(proto, _instance); - delete Base._prototyping; - - // create the wrapper for the constructor function - //var constructor = proto.constructor.valueOf(); //-dean - var constructor = proto.constructor; - var klass = proto.constructor = function() { - if (!Base._prototyping) { - if (this._constructing || this.constructor == klass) { // instantiation - this._constructing = true; - constructor.apply(this, arguments); - delete this._constructing; - } else if (arguments[0] != null) { // casting - return (arguments[0].extend || extend).call(arguments[0], proto); - } - } - }; - - // build the class interface - klass.ancestor = this; - klass.extend = this.extend; - klass.forEach = this.forEach; - klass.implement = this.implement; - klass.prototype = proto; - klass.toString = this.toString; - klass.valueOf = function(type) { - //return (type == "object") ? klass : constructor; //-dean - return (type == "object") ? klass : constructor.valueOf(); - }; - extend.call(klass, _static); - // class initialisation - if (typeof klass.init == "function") klass.init(); - return klass; + var extend = Base.prototype.extend; + + // build the prototype + Base._prototyping = true; + var proto = new this; + extend.call(proto, _instance); + delete Base._prototyping; + + // create the wrapper for the constructor function + //var constructor = proto.constructor.valueOf(); //-dean + var constructor = proto.constructor; + var klass = proto.constructor = function() { + if (!Base._prototyping) { + if (this._constructing || this.constructor == klass) { // instantiation + this._constructing = true; + constructor.apply(this, arguments); + delete this._constructing; + } else if (arguments[0] != null) { // casting + return (arguments[0].extend || extend).call(arguments[0], proto); + } + } + }; + + // build the class interface + klass.ancestor = this; + klass.extend = this.extend; + klass.forEach = this.forEach; + klass.implement = this.implement; + klass.prototype = proto; + klass.toString = this.toString; + klass.valueOf = function(type) { + //return (type == "object") ? klass : constructor; //-dean + return (type == "object") ? klass : constructor.valueOf(); + }; + extend.call(klass, _static); + // class initialisation + if (typeof klass.init == "function") klass.init(); + return klass; }; -Base.prototype = { - extend: function(source, value) { - if (arguments.length > 1) { // extending with a name/value pair - var ancestor = this[source]; - if (ancestor && (typeof value == "function") && // overriding a method? - // the valueOf() comparison is to avoid circular references - (!ancestor.valueOf || ancestor.valueOf() != value.valueOf()) && - /\bbase\b/.test(value)) { - // get the underlying method - var method = value.valueOf(); - // override - value = function() { - var previous = this.base || Base.prototype.base; - this.base = ancestor; - var returnValue = method.apply(this, arguments); - this.base = previous; - return returnValue; - }; - // point to the underlying method - value.valueOf = function(type) { - return (type == "object") ? value : method; - }; - value.toString = Base.toString; - } - this[source] = value; - } else if (source) { // extending with an object literal - var extend = Base.prototype.extend; - // if this object has a customised extend method then use it - if (!Base._prototyping && typeof this != "function") { - extend = this.extend || extend; - } - var proto = {toSource: null}; - // do the "toString" and other methods manually - var hidden = ["constructor", "toString", "valueOf"]; - // if we are prototyping then include the constructor - var i = Base._prototyping ? 0 : 1; - while (key = hidden[i++]) { - if (source[key] != proto[key]) { - extend.call(this, key, source[key]); - - } - } - // copy each of the source object's properties to this object - for (var key in source) { - if (!proto[key]) extend.call(this, key, source[key]); - } - } - return this; - }, +Base.prototype = { + extend: function(source, value) { + if (arguments.length > 1) { // extending with a name/value pair + var ancestor = this[source]; + if (ancestor && (typeof value == "function") && // overriding a method? + // the valueOf() comparison is to avoid circular references + (!ancestor.valueOf || ancestor.valueOf() != value.valueOf()) && + /\bbase\b/.test(value)) { + // get the underlying method + var method = value.valueOf(); + // override + value = function() { + var previous = this.base || Base.prototype.base; + this.base = ancestor; + var returnValue = method.apply(this, arguments); + this.base = previous; + return returnValue; + }; + // point to the underlying method + value.valueOf = function(type) { + return (type == "object") ? value : method; + }; + value.toString = Base.toString; + } + this[source] = value; + } else if (source) { // extending with an object literal + var extend = Base.prototype.extend; + // if this object has a customised extend method then use it + if (!Base._prototyping && typeof this != "function") { + extend = this.extend || extend; + } + var proto = {toSource: null}; + // do the "toString" and other methods manually + var hidden = ["constructor", "toString", "valueOf"]; + // if we are prototyping then include the constructor + var i = Base._prototyping ? 0 : 1; + while (key = hidden[i++]) { + if (source[key] != proto[key]) { + extend.call(this, key, source[key]); - base: function() { - // call this method from any other method to invoke that method's ancestor - } + } + } + // copy each of the source object's properties to this object + for (var key in source) { + if (!proto[key]) extend.call(this, key, source[key]); + } + } + return this; + }, + + base: function() { + // call this method from any other method to invoke that method's ancestor + } }; // initialise Base = Base.extend({ - constructor: function() { - this.extend(arguments[0]); - } + constructor: function() { + this.extend(arguments[0]); + } }, { - ancestor: Object, - version: "1.1", - - forEach: function(object, block, context) { - for (var key in object) { - if (this.prototype[key] === undefined) { - block.call(context, object[key], key, object); - } - } - }, - - implement: function() { - for (var i = 0; i < arguments.length; i++) { - if (typeof arguments[i] == "function") { - // if it's a function, call it - arguments[i](this.prototype); - } else { - // add the interface using the extend method - this.prototype.extend(arguments[i]); - } - } - return this; - }, - - toString: function() { - return String(this.valueOf()); - } + ancestor: Object, + version: "1.1", + + forEach: function(object, block, context) { + for (var key in object) { + if (this.prototype[key] === undefined) { + block.call(context, object[key], key, object); + } + } + }, + + implement: function() { + for (var i = 0; i < arguments.length; i++) { + if (typeof arguments[i] == "function") { + // if it's a function, call it + arguments[i](this.prototype); + } else { + // add the interface using the extend method + this.prototype.extend(arguments[i]); + } + } + return this; + }, + + toString: function() { + return String(this.valueOf()); + } }); -/****************************************************************************** - rtree.js - General-Purpose Non-Recursive Javascript R-Tree Library - Version 0.6.2, December 5st 2009 +/****************************************************************************** + rtree.js - General-Purpose Non-Recursive Javascript R-Tree Library + Version 0.6.2, December 5st 2009 Copyright (c) 2009 Jon-Carlos Rivera - + Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including @@ -561,10 +561,10 @@ Base = Base.extend({ distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - + The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND @@ -573,7 +573,7 @@ Base = Base.extend({ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - Jon-Carlos Rivera - imbcmdth@hotmail.com + Jon-Carlos Rivera - imbcmdth@hotmail.com ******************************************************************************/ /** @@ -581,22 +581,22 @@ Base = Base.extend({ * @constructor */ var RTree = function(width){ - // Variables to control tree-dimensions - var _Min_Width = 3; // Minimum width of any node before a merge - var _Max_Width = 6; // Maximum width of any node before a split - if(!isNaN(width)){ _Min_Width = Math.floor(width/2.0); _Max_Width = width;} - // Start with an empty root-tree - var _T = {x:0, y:0, w:0, h:0, id:"root", nodes:[] }; - - var isArray = function(o) { - return Object.prototype.toString.call(o) === '[object Array]'; - }; + // Variables to control tree-dimensions + var _Min_Width = 3; // Minimum width of any node before a merge + var _Max_Width = 6; // Maximum width of any node before a split + if(!isNaN(width)){ _Min_Width = Math.floor(width/2.0); _Max_Width = width;} + // Start with an empty root-tree + var _T = {x:0, y:0, w:0, h:0, id:"root", nodes:[] }; + + var isArray = function(o) { + return Object.prototype.toString.call(o) === '[object Array]'; + }; - /* @function - * @description Function to generate unique strings for element IDs - * @param {String} n The prefix to use for the IDs generated. - * @return {String} A guarenteed unique ID. - */ + /* @function + * @description Function to generate unique strings for element IDs + * @param {String} n The prefix to use for the IDs generated. + * @return {String} A guarenteed unique ID. + */ var _name_to_id = (function() { // hide our idCache inside this closure var idCache = {}; @@ -613,538 +613,538 @@ var RTree = function(width){ } })(); - // This is my special addition to the world of r-trees - // every other (simple) method I found produced crap trees - // this skews insertions to prefering squarer and emptier nodes - RTree.Rectangle.squarified_ratio = function(l, w, fill) { - // Area of new enlarged rectangle - var lperi = (l + w) / 2.0; // Average size of a side of the new rectangle - var larea = l * w; // Area of new rectangle - // return the ratio of the perimeter to the area - the closer to 1 we are, - // the more "square" a rectangle is. conversly, when approaching zero the - // more elongated a rectangle is - var lgeo = larea / (lperi*lperi); - return(larea * fill / lgeo); - }; - - /* find the best specific node(s) for object to be deleted from - * [ leaf node parent ] = _remove_subtree(rectangle, object, root) - * @private - */ - var _remove_subtree = function(rect, obj, root) { - var hit_stack = []; // Contains the elements that overlap - var count_stack = []; // Contains the elements that overlap - var ret_array = []; - var current_depth = 1; - - if(!rect || !RTree.Rectangle.overlap_rectangle(rect, root)) - return ret_array; - - var ret_obj = {x:rect.x, y:rect.y, w:rect.w, h:rect.h, target:obj}; - - count_stack.push(root.nodes.length); - hit_stack.push(root); - - do { - var tree = hit_stack.pop(); - var i = count_stack.pop()-1; - - if("target" in ret_obj) { // We are searching for a target - while(i >= 0) { - var ltree = tree.nodes[i]; - if(RTree.Rectangle.overlap_rectangle(ret_obj, ltree)) { - if( (ret_obj.target && "leaf" in ltree && ltree.leaf === ret_obj.target) - ||(!ret_obj.target && ("leaf" in ltree || RTree.Rectangle.contains_rectangle(ltree, ret_obj)))) { // A Match !! - // Yup we found a match... - // we can cancel search and start walking up the list - if("nodes" in ltree) {// If we are deleting a node not a leaf... - ret_array = _search_subtree(ltree, true, [], ltree); - tree.nodes.splice(i, 1); - } else { - ret_array = tree.nodes.splice(i, 1); - } - // Resize MBR down... - RTree.Rectangle.make_MBR(tree.nodes, tree); - delete ret_obj.target; - if(tree.nodes.length < _Min_Width) { // Underflow - ret_obj.nodes = _search_subtree(tree, true, [], tree); - } - break; - }/* else if("load" in ltree) { // A load - }*/ else if("nodes" in ltree) { // Not a Leaf - current_depth += 1; - count_stack.push(i); - hit_stack.push(tree); - tree = ltree; - i = ltree.nodes.length; - } - } - i -= 1; - } - } else if("nodes" in ret_obj) { // We are unsplitting - tree.nodes.splice(i+1, 1); // Remove unsplit node - // ret_obj.nodes contains a list of elements removed from the tree so far - if(tree.nodes.length > 0) - RTree.Rectangle.make_MBR(tree.nodes, tree); - for(var t = 0;t 0 && tree.nodes.length < _Min_Width) { // Underflow..AGAIN! - ret_obj.nodes = _search_subtree(tree, true, ret_obj.nodes, tree); - tree.nodes.length = 0; - }else { - delete ret_obj.nodes; // Just start resizing - } - } else { // we are just resizing - RTree.Rectangle.make_MBR(tree.nodes, tree); - } - current_depth -= 1; - }while(hit_stack.length > 0); - - return(ret_array); - }; + // This is my special addition to the world of r-trees + // every other (simple) method I found produced crap trees + // this skews insertions to prefering squarer and emptier nodes + RTree.Rectangle.squarified_ratio = function(l, w, fill) { + // Area of new enlarged rectangle + var lperi = (l + w) / 2.0; // Average size of a side of the new rectangle + var larea = l * w; // Area of new rectangle + // return the ratio of the perimeter to the area - the closer to 1 we are, + // the more "square" a rectangle is. conversly, when approaching zero the + // more elongated a rectangle is + var lgeo = larea / (lperi*lperi); + return(larea * fill / lgeo); + }; - /* choose the best damn node for rectangle to be inserted into - * [ leaf node parent ] = _choose_leaf_subtree(rectangle, root to start search at) - * @private - */ - var _choose_leaf_subtree = function(rect, root) { - var best_choice_index = -1; - var best_choice_stack = []; - var best_choice_area; - - var load_callback = function(local_tree, local_node){ - return(function(data) { - local_tree._attach_data(local_node, data); - }); - }; - - best_choice_stack.push(root); - var nodes = root.nodes; - - do { - if(best_choice_index != -1) { - best_choice_stack.push(nodes[best_choice_index]); - nodes = nodes[best_choice_index].nodes; - best_choice_index = -1; - } - - for(var i = nodes.length-1; i >= 0; i--) { - var ltree = nodes[i]; - if("leaf" in ltree) { - // Bail out of everything and start inserting - best_choice_index = -1; - break; - } /*else if(ltree.load) { - throw( "Can't insert into partially loaded tree ... yet!"); - //jQuery.getJSON(ltree.load, load_callback(this, ltree)); - //delete ltree.load; - }*/ - // Area of new enlarged rectangle - var old_lratio = RTree.Rectangle.squarified_ratio(ltree.w, ltree.h, ltree.nodes.length+1); - - // Enlarge rectangle to fit new rectangle - var nw = Math.max(ltree.x+ltree.w, rect.x+rect.w) - Math.min(ltree.x, rect.x); - var nh = Math.max(ltree.y+ltree.h, rect.y+rect.h) - Math.min(ltree.y, rect.y); - - // Area of new enlarged rectangle - var lratio = RTree.Rectangle.squarified_ratio(nw, nh, ltree.nodes.length+2); - - if(best_choice_index < 0 || Math.abs(lratio - old_lratio) < best_choice_area) { - best_choice_area = Math.abs(lratio - old_lratio); best_choice_index = i; - } - } - }while(best_choice_index != -1); - - return(best_choice_stack); - }; + /* find the best specific node(s) for object to be deleted from + * [ leaf node parent ] = _remove_subtree(rectangle, object, root) + * @private + */ + var _remove_subtree = function(rect, obj, root) { + var hit_stack = []; // Contains the elements that overlap + var count_stack = []; // Contains the elements that overlap + var ret_array = []; + var current_depth = 1; - /* split a set of nodes into two roughly equally-filled nodes - * [ an array of two new arrays of nodes ] = linear_split(array of nodes) - * @private - */ - var _linear_split = function(nodes) { - var n = _pick_linear(nodes); - while(nodes.length > 0) { - _pick_next(nodes, n[0], n[1]); - } - return(n); - }; - - /* insert the best source rectangle into the best fitting parent node: a or b - * [] = pick_next(array of source nodes, target node array a, target node array b) - * @private - */ - var _pick_next = function(nodes, a, b) { - // Area of new enlarged rectangle - var area_a = RTree.Rectangle.squarified_ratio(a.w, a.h, a.nodes.length+1); - var area_b = RTree.Rectangle.squarified_ratio(b.w, b.h, b.nodes.length+1); - var high_area_delta; - var high_area_node; - var lowest_growth_group; - - for(var i = nodes.length-1; i>=0;i--) { - var l = nodes[i]; - var new_area_a = {}; - new_area_a.x = Math.min(a.x, l.x); new_area_a.y = Math.min(a.y, l.y); - new_area_a.w = Math.max(a.x+a.w, l.x+l.w) - new_area_a.x; new_area_a.h = Math.max(a.y+a.h, l.y+l.h) - new_area_a.y; - var change_new_area_a = Math.abs(RTree.Rectangle.squarified_ratio(new_area_a.w, new_area_a.h, a.nodes.length+2) - area_a); - - var new_area_b = {}; - new_area_b.x = Math.min(b.x, l.x); new_area_b.y = Math.min(b.y, l.y); - new_area_b.w = Math.max(b.x+b.w, l.x+l.w) - new_area_b.x; new_area_b.h = Math.max(b.y+b.h, l.y+l.h) - new_area_b.y; - var change_new_area_b = Math.abs(RTree.Rectangle.squarified_ratio(new_area_b.w, new_area_b.h, b.nodes.length+2) - area_b); - - if( !high_area_node || !high_area_delta || Math.abs( change_new_area_b - change_new_area_a ) < high_area_delta ) { - high_area_node = i; - high_area_delta = Math.abs(change_new_area_b-change_new_area_a); - lowest_growth_group = change_new_area_b < change_new_area_a ? b : a; - } - } - var temp_node = nodes.splice(high_area_node, 1)[0]; - if(a.nodes.length + nodes.length + 1 <= _Min_Width) { - a.nodes.push(temp_node); - RTree.Rectangle.expand_rectangle(a, temp_node); - } else if(b.nodes.length + nodes.length + 1 <= _Min_Width) { - b.nodes.push(temp_node); - RTree.Rectangle.expand_rectangle(b, temp_node); - } - else { - lowest_growth_group.nodes.push(temp_node); - RTree.Rectangle.expand_rectangle(lowest_growth_group, temp_node); - } - }; + if(!rect || !RTree.Rectangle.overlap_rectangle(rect, root)) + return ret_array; + + var ret_obj = {x:rect.x, y:rect.y, w:rect.w, h:rect.h, target:obj}; + + count_stack.push(root.nodes.length); + hit_stack.push(root); + + do { + var tree = hit_stack.pop(); + var i = count_stack.pop()-1; + + if("target" in ret_obj) { // We are searching for a target + while(i >= 0) { + var ltree = tree.nodes[i]; + if(RTree.Rectangle.overlap_rectangle(ret_obj, ltree)) { + if( (ret_obj.target && "leaf" in ltree && ltree.leaf === ret_obj.target) + ||(!ret_obj.target && ("leaf" in ltree || RTree.Rectangle.contains_rectangle(ltree, ret_obj)))) { // A Match !! + // Yup we found a match... + // we can cancel search and start walking up the list + if("nodes" in ltree) {// If we are deleting a node not a leaf... + ret_array = _search_subtree(ltree, true, [], ltree); + tree.nodes.splice(i, 1); + } else { + ret_array = tree.nodes.splice(i, 1); + } + // Resize MBR down... + RTree.Rectangle.make_MBR(tree.nodes, tree); + delete ret_obj.target; + if(tree.nodes.length < _Min_Width) { // Underflow + ret_obj.nodes = _search_subtree(tree, true, [], tree); + } + break; + }/* else if("load" in ltree) { // A load + }*/ else if("nodes" in ltree) { // Not a Leaf + current_depth += 1; + count_stack.push(i); + hit_stack.push(tree); + tree = ltree; + i = ltree.nodes.length; + } + } + i -= 1; + } + } else if("nodes" in ret_obj) { // We are unsplitting + tree.nodes.splice(i+1, 1); // Remove unsplit node + // ret_obj.nodes contains a list of elements removed from the tree so far + if(tree.nodes.length > 0) + RTree.Rectangle.make_MBR(tree.nodes, tree); + for(var t = 0;t 0 && tree.nodes.length < _Min_Width) { // Underflow..AGAIN! + ret_obj.nodes = _search_subtree(tree, true, ret_obj.nodes, tree); + tree.nodes.length = 0; + }else { + delete ret_obj.nodes; // Just start resizing + } + } else { // we are just resizing + RTree.Rectangle.make_MBR(tree.nodes, tree); + } + current_depth -= 1; + }while(hit_stack.length > 0); + + return(ret_array); + }; + + /* choose the best damn node for rectangle to be inserted into + * [ leaf node parent ] = _choose_leaf_subtree(rectangle, root to start search at) + * @private + */ + var _choose_leaf_subtree = function(rect, root) { + var best_choice_index = -1; + var best_choice_stack = []; + var best_choice_area; + + var load_callback = function(local_tree, local_node){ + return(function(data) { + local_tree._attach_data(local_node, data); + }); + }; + + best_choice_stack.push(root); + var nodes = root.nodes; + + do { + if(best_choice_index != -1) { + best_choice_stack.push(nodes[best_choice_index]); + nodes = nodes[best_choice_index].nodes; + best_choice_index = -1; + } + + for(var i = nodes.length-1; i >= 0; i--) { + var ltree = nodes[i]; + if("leaf" in ltree) { + // Bail out of everything and start inserting + best_choice_index = -1; + break; + } /*else if(ltree.load) { + throw( "Can't insert into partially loaded tree ... yet!"); + //jQuery.getJSON(ltree.load, load_callback(this, ltree)); + //delete ltree.load; + }*/ + // Area of new enlarged rectangle + var old_lratio = RTree.Rectangle.squarified_ratio(ltree.w, ltree.h, ltree.nodes.length+1); + + // Enlarge rectangle to fit new rectangle + var nw = Math.max(ltree.x+ltree.w, rect.x+rect.w) - Math.min(ltree.x, rect.x); + var nh = Math.max(ltree.y+ltree.h, rect.y+rect.h) - Math.min(ltree.y, rect.y); + + // Area of new enlarged rectangle + var lratio = RTree.Rectangle.squarified_ratio(nw, nh, ltree.nodes.length+2); + + if(best_choice_index < 0 || Math.abs(lratio - old_lratio) < best_choice_area) { + best_choice_area = Math.abs(lratio - old_lratio); best_choice_index = i; + } + } + }while(best_choice_index != -1); + + return(best_choice_stack); + }; + + /* split a set of nodes into two roughly equally-filled nodes + * [ an array of two new arrays of nodes ] = linear_split(array of nodes) + * @private + */ + var _linear_split = function(nodes) { + var n = _pick_linear(nodes); + while(nodes.length > 0) { + _pick_next(nodes, n[0], n[1]); + } + return(n); + }; - /* pick the "best" two starter nodes to use as seeds using the "linear" criteria - * [ an array of two new arrays of nodes ] = pick_linear(array of source nodes) - * @private - */ - var _pick_linear = function(nodes) { - var lowest_high_x = nodes.length-1; - var highest_low_x = 0; - var lowest_high_y = nodes.length-1; - var highest_low_y = 0; + /* insert the best source rectangle into the best fitting parent node: a or b + * [] = pick_next(array of source nodes, target node array a, target node array b) + * @private + */ + var _pick_next = function(nodes, a, b) { + // Area of new enlarged rectangle + var area_a = RTree.Rectangle.squarified_ratio(a.w, a.h, a.nodes.length+1); + var area_b = RTree.Rectangle.squarified_ratio(b.w, b.h, b.nodes.length+1); + var high_area_delta; + var high_area_node; + var lowest_growth_group; + + for(var i = nodes.length-1; i>=0;i--) { + var l = nodes[i]; + var new_area_a = {}; + new_area_a.x = Math.min(a.x, l.x); new_area_a.y = Math.min(a.y, l.y); + new_area_a.w = Math.max(a.x+a.w, l.x+l.w) - new_area_a.x; new_area_a.h = Math.max(a.y+a.h, l.y+l.h) - new_area_a.y; + var change_new_area_a = Math.abs(RTree.Rectangle.squarified_ratio(new_area_a.w, new_area_a.h, a.nodes.length+2) - area_a); + + var new_area_b = {}; + new_area_b.x = Math.min(b.x, l.x); new_area_b.y = Math.min(b.y, l.y); + new_area_b.w = Math.max(b.x+b.w, l.x+l.w) - new_area_b.x; new_area_b.h = Math.max(b.y+b.h, l.y+l.h) - new_area_b.y; + var change_new_area_b = Math.abs(RTree.Rectangle.squarified_ratio(new_area_b.w, new_area_b.h, b.nodes.length+2) - area_b); + + if( !high_area_node || !high_area_delta || Math.abs( change_new_area_b - change_new_area_a ) < high_area_delta ) { + high_area_node = i; + high_area_delta = Math.abs(change_new_area_b-change_new_area_a); + lowest_growth_group = change_new_area_b < change_new_area_a ? b : a; + } + } + var temp_node = nodes.splice(high_area_node, 1)[0]; + if(a.nodes.length + nodes.length + 1 <= _Min_Width) { + a.nodes.push(temp_node); + RTree.Rectangle.expand_rectangle(a, temp_node); + } else if(b.nodes.length + nodes.length + 1 <= _Min_Width) { + b.nodes.push(temp_node); + RTree.Rectangle.expand_rectangle(b, temp_node); + } + else { + lowest_growth_group.nodes.push(temp_node); + RTree.Rectangle.expand_rectangle(lowest_growth_group, temp_node); + } + }; + + /* pick the "best" two starter nodes to use as seeds using the "linear" criteria + * [ an array of two new arrays of nodes ] = pick_linear(array of source nodes) + * @private + */ + var _pick_linear = function(nodes) { + var lowest_high_x = nodes.length-1; + var highest_low_x = 0; + var lowest_high_y = nodes.length-1; + var highest_low_y = 0; var t1, t2; - - for(var i = nodes.length-2; i>=0;i--) { - var l = nodes[i]; - if(l.x > nodes[highest_low_x].x ) highest_low_x = i; - else if(l.x+l.w < nodes[lowest_high_x].x+nodes[lowest_high_x].w) lowest_high_x = i; - if(l.y > nodes[highest_low_y].y ) highest_low_y = i; - else if(l.y+l.h < nodes[lowest_high_y].y+nodes[lowest_high_y].h) lowest_high_y = i; - } - var dx = Math.abs((nodes[lowest_high_x].x+nodes[lowest_high_x].w) - nodes[highest_low_x].x); - var dy = Math.abs((nodes[lowest_high_y].y+nodes[lowest_high_y].h) - nodes[highest_low_y].y); - if( dx > dy ) { - if(lowest_high_x > highest_low_x) { - t1 = nodes.splice(lowest_high_x, 1)[0]; - t2 = nodes.splice(highest_low_x, 1)[0]; - } else { - t2 = nodes.splice(highest_low_x, 1)[0]; - t1 = nodes.splice(lowest_high_x, 1)[0]; - } - } else { - if(lowest_high_y > highest_low_y) { - t1 = nodes.splice(lowest_high_y, 1)[0]; - t2 = nodes.splice(highest_low_y, 1)[0]; - } else { - t2 = nodes.splice(highest_low_y, 1)[0]; - t1 = nodes.splice(lowest_high_y, 1)[0]; - } - } - return([{x:t1.x, y:t1.y, w:t1.w, h:t1.h, nodes:[t1]}, - {x:t2.x, y:t2.y, w:t2.w, h:t2.h, nodes:[t2]} ]); - }; - - var _attach_data = function(node, more_tree){ - node.nodes = more_tree.nodes; - node.x = more_tree.x; node.y = more_tree.y; - node.w = more_tree.w; node.h = more_tree.h; - return(node); - }; - /* non-recursive internal search function - * [ nodes | objects ] = _search_subtree(rectangle, [return node data], [array to fill], root to begin search at) - * @private - */ - var _search_subtree = function(rect, return_node, return_array, root) { - var hit_stack = []; // Contains the elements that overlap - - if(!RTree.Rectangle.overlap_rectangle(rect, root)) - return(return_array); - - var load_callback = function(local_tree, local_node){ - return(function(data) { - local_tree._attach_data(local_node, data); - }); - }; - - hit_stack.push(root.nodes); - - do { - var nodes = hit_stack.pop(); - - for(var i = nodes.length-1; i >= 0; i--) { - var ltree = nodes[i]; - if(RTree.Rectangle.overlap_rectangle(rect, ltree)) { - if("nodes" in ltree) { // Not a Leaf - hit_stack.push(ltree.nodes); - } else if("leaf" in ltree) { // A Leaf !! - if(!return_node) - return_array.push(ltree.leaf); - else - return_array.push(ltree); - }/* else if("load" in ltree) { // We need to fetch a URL for some more tree data - jQuery.getJSON(ltree.load, load_callback(this, ltree)); - delete ltree.load; - // i++; // Replay this entry - }*/ - } - } - }while(hit_stack.length > 0); - - return(return_array); - }; - - /* non-recursive internal insert function - * [] = _insert_subtree(rectangle, object to insert, root to begin insertion at) - * @private - */ - var _insert_subtree = function(node, root) { - var bc; // Best Current node - // Initial insertion is special because we resize the Tree and we don't - // care about any overflow (seriously, how can the first object overflow?) - if(root.nodes.length == 0) { - root.x = node.x; root.y = node.y; - root.w = node.w; root.h = node.h; - root.nodes.push(node); - return; - } - - // Find the best fitting leaf node - // choose_leaf returns an array of all tree levels (including root) - // that were traversed while trying to find the leaf - var tree_stack = _choose_leaf_subtree(node, root); - var ret_obj = node;//{x:rect.x,y:rect.y,w:rect.w,h:rect.h, leaf:obj}; - - // Walk back up the tree resizing and inserting as needed - do { - //handle the case of an empty node (from a split) - if(bc && "nodes" in bc && bc.nodes.length == 0) { - var pbc = bc; // Past bc - bc = tree_stack.pop(); - for(var t=0;t 0); - }; + for(var i = nodes.length-2; i>=0;i--) { + var l = nodes[i]; + if(l.x > nodes[highest_low_x].x ) highest_low_x = i; + else if(l.x+l.w < nodes[lowest_high_x].x+nodes[lowest_high_x].w) lowest_high_x = i; + if(l.y > nodes[highest_low_y].y ) highest_low_y = i; + else if(l.y+l.h < nodes[lowest_high_y].y+nodes[lowest_high_y].h) lowest_high_y = i; + } + var dx = Math.abs((nodes[lowest_high_x].x+nodes[lowest_high_x].w) - nodes[highest_low_x].x); + var dy = Math.abs((nodes[lowest_high_y].y+nodes[lowest_high_y].h) - nodes[highest_low_y].y); + if( dx > dy ) { + if(lowest_high_x > highest_low_x) { + t1 = nodes.splice(lowest_high_x, 1)[0]; + t2 = nodes.splice(highest_low_x, 1)[0]; + } else { + t2 = nodes.splice(highest_low_x, 1)[0]; + t1 = nodes.splice(lowest_high_x, 1)[0]; + } + } else { + if(lowest_high_y > highest_low_y) { + t1 = nodes.splice(lowest_high_y, 1)[0]; + t2 = nodes.splice(highest_low_y, 1)[0]; + } else { + t2 = nodes.splice(highest_low_y, 1)[0]; + t1 = nodes.splice(lowest_high_y, 1)[0]; + } + } + return([{x:t1.x, y:t1.y, w:t1.w, h:t1.h, nodes:[t1]}, + {x:t2.x, y:t2.y, w:t2.w, h:t2.h, nodes:[t2]} ]); + }; - /* quick 'n' dirty function for plugins or manually drawing the tree - * [ tree ] = RTree.get_tree(): returns the raw tree data. useful for adding - * @public - * !! DEPRECATED !! - */ - this.get_tree = function() { - return _T; - }; - - /* quick 'n' dirty function for plugins or manually loading the tree - * [ tree ] = RTree.set_tree(sub-tree, where to attach): returns the raw tree data. useful for adding - * @public - * !! DEPRECATED !! - */ - this.set_tree = function(new_tree, where) { - if(!where) - where = _T; - return(_attach_data(where, new_tree)); - }; - - /* non-recursive search function - * [ nodes | objects ] = RTree.search(rectangle, [return node data], [array to fill]) - * @public - */ - this.search = function(rect, return_node, return_array) { - if(arguments.length < 1) - throw "Wrong number of arguments. RT.Search requires at least a bounding rectangle." - - switch(arguments.length) { - case 1: - arguments[1] = false;// Add an "return node" flag - may be removed in future - case 2: - arguments[2] = []; // Add an empty array to contain results - case 3: - arguments[3] = _T; // Add root node to end of argument list - default: - arguments.length = 4; - } - return(_search_subtree.apply(this, arguments)); - }; - - /* partially-recursive toJSON function - * [ string ] = RTree.toJSON([rectangle], [tree]) - * @public - */ - this.toJSON = function(rect, tree) { - var hit_stack = []; // Contains the elements that overlap - var count_stack = []; // Contains the elements that overlap - var return_stack = {}; // Contains the elements that overlap - var max_depth = 3; // This triggers recursion and tree-splitting - var current_depth = 1; - var return_string = ""; - - if(rect && !RTree.Rectangle.overlap_rectangle(rect, _T)) - return ""; - - if(!tree) { - count_stack.push(_T.nodes.length); - hit_stack.push(_T.nodes); - return_string += "var main_tree = {x:"+_T.x.toFixed()+",y:"+_T.y.toFixed()+",w:"+_T.w.toFixed()+",h:"+_T.h.toFixed()+",nodes:["; - } else { - max_depth += 4; - count_stack.push(tree.nodes.length); - hit_stack.push(tree.nodes); - return_string += "var main_tree = {x:"+tree.x.toFixed()+",y:"+tree.y.toFixed()+",w:"+tree.w.toFixed()+",h:"+tree.h.toFixed()+",nodes:["; - } - - do { - var nodes = hit_stack.pop(); - var i = count_stack.pop()-1; - - if(i >= 0 && i < nodes.length-1) - return_string += ","; - - while(i >= 0) { - var ltree = nodes[i]; - if(!rect || RTree.Rectangle.overlap_rectangle(rect, ltree)) { - if(ltree.nodes) { // Not a Leaf - if(current_depth >= max_depth) { - var len = return_stack.length; - var nam = _name_to_id("saved_subtree"); - return_string += "{x:"+ltree.x.toFixed()+",y:"+ltree.y.toFixed()+",w:"+ltree.w.toFixed()+",h:"+ltree.h.toFixed()+",load:'"+nam+".js'}"; - return_stack[nam] = this.toJSON(rect, ltree); - if(i > 0) - return_string += "," - } else { - return_string += "{x:"+ltree.x.toFixed()+",y:"+ltree.y.toFixed()+",w:"+ltree.w.toFixed()+",h:"+ltree.h.toFixed()+",nodes:["; - current_depth += 1; - count_stack.push(i); - hit_stack.push(nodes); - nodes = ltree.nodes; - i = ltree.nodes.length; - } - } else if(ltree.leaf) { // A Leaf !! - var data = ltree.leaf.toJSON ? ltree.leaf.toJSON() : JSON.stringify(ltree.leaf); - return_string += "{x:"+ltree.x.toFixed()+",y:"+ltree.y.toFixed()+",w:"+ltree.w.toFixed()+",h:"+ltree.h.toFixed()+",leaf:" + data + "}"; - if(i > 0) - return_string += "," - } else if(ltree.load) { // A load - return_string += "{x:"+ltree.x.toFixed()+",y:"+ltree.y.toFixed()+",w:"+ltree.w.toFixed()+",h:"+ltree.h.toFixed()+",load:'" + ltree.load + "'}"; - if(i > 0) - return_string += "," - } - } - i -= 1; - } - if(i < 0) { - return_string += "]}"; current_depth -= 1; - } - }while(hit_stack.length > 0); - - return_string+=";"; - - for(var my_key in return_stack) { - return_string += "\nvar " + my_key + " = function(){" + return_stack[my_key] + " return(main_tree);};"; - } - return(return_string); - }; - - /* non-recursive function that deletes a specific - * [ number ] = RTree.remove(rectangle, obj) - */ - this.remove = function(rect, obj) { - if(arguments.length < 1) - throw "Wrong number of arguments. RT.remove requires at least a bounding rectangle." - - switch(arguments.length) { - case 1: - arguments[1] = false; // obj == false for conditionals - case 2: - arguments[2] = _T; // Add root node to end of argument list - default: - arguments.length = 3; - } - if(arguments[1] === false) { // Do area-wide delete - var numberdeleted = 0; - var ret_array = []; - do { - numberdeleted=ret_array.length; - ret_array = ret_array.concat(_remove_subtree.apply(this, arguments)); - }while( numberdeleted != ret_array.length); - return ret_array; - } - else { // Delete a specific item - return(_remove_subtree.apply(this, arguments)); - } - }; - - /* non-recursive insert function - * [] = RTree.insert(rectangle, object to insert) - */ - this.insert = function(rect, obj) { - if(arguments.length < 2) - throw "Wrong number of arguments. RT.Insert requires at least a bounding rectangle and an object." - - return(_insert_subtree({x:rect.x,y:rect.y,w:rect.w,h:rect.h,leaf:obj}, _T)); - }; - - /* non-recursive delete function - * [deleted object] = RTree.remove(rectangle, [object to delete]) - */ + var _attach_data = function(node, more_tree){ + node.nodes = more_tree.nodes; + node.x = more_tree.x; node.y = more_tree.y; + node.w = more_tree.w; node.h = more_tree.h; + return(node); + }; + + /* non-recursive internal search function + * [ nodes | objects ] = _search_subtree(rectangle, [return node data], [array to fill], root to begin search at) + * @private + */ + var _search_subtree = function(rect, return_node, return_array, root) { + var hit_stack = []; // Contains the elements that overlap + + if(!RTree.Rectangle.overlap_rectangle(rect, root)) + return(return_array); + + var load_callback = function(local_tree, local_node){ + return(function(data) { + local_tree._attach_data(local_node, data); + }); + }; + + hit_stack.push(root.nodes); + + do { + var nodes = hit_stack.pop(); + + for(var i = nodes.length-1; i >= 0; i--) { + var ltree = nodes[i]; + if(RTree.Rectangle.overlap_rectangle(rect, ltree)) { + if("nodes" in ltree) { // Not a Leaf + hit_stack.push(ltree.nodes); + } else if("leaf" in ltree) { // A Leaf !! + if(!return_node) + return_array.push(ltree.leaf); + else + return_array.push(ltree); + }/* else if("load" in ltree) { // We need to fetch a URL for some more tree data + jQuery.getJSON(ltree.load, load_callback(this, ltree)); + delete ltree.load; + // i++; // Replay this entry + }*/ + } + } + }while(hit_stack.length > 0); + + return(return_array); + }; + + /* non-recursive internal insert function + * [] = _insert_subtree(rectangle, object to insert, root to begin insertion at) + * @private + */ + var _insert_subtree = function(node, root) { + var bc; // Best Current node + // Initial insertion is special because we resize the Tree and we don't + // care about any overflow (seriously, how can the first object overflow?) + if(root.nodes.length == 0) { + root.x = node.x; root.y = node.y; + root.w = node.w; root.h = node.h; + root.nodes.push(node); + return; + } + + // Find the best fitting leaf node + // choose_leaf returns an array of all tree levels (including root) + // that were traversed while trying to find the leaf + var tree_stack = _choose_leaf_subtree(node, root); + var ret_obj = node;//{x:rect.x,y:rect.y,w:rect.w,h:rect.h, leaf:obj}; + + // Walk back up the tree resizing and inserting as needed + do { + //handle the case of an empty node (from a split) + if(bc && "nodes" in bc && bc.nodes.length == 0) { + var pbc = bc; // Past bc + bc = tree_stack.pop(); + for(var t=0;t 0); + }; + + /* quick 'n' dirty function for plugins or manually drawing the tree + * [ tree ] = RTree.get_tree(): returns the raw tree data. useful for adding + * @public + * !! DEPRECATED !! + */ + this.get_tree = function() { + return _T; + }; + + /* quick 'n' dirty function for plugins or manually loading the tree + * [ tree ] = RTree.set_tree(sub-tree, where to attach): returns the raw tree data. useful for adding + * @public + * !! DEPRECATED !! + */ + this.set_tree = function(new_tree, where) { + if(!where) + where = _T; + return(_attach_data(where, new_tree)); + }; + + /* non-recursive search function + * [ nodes | objects ] = RTree.search(rectangle, [return node data], [array to fill]) + * @public + */ + this.search = function(rect, return_node, return_array) { + if(arguments.length < 1) + throw "Wrong number of arguments. RT.Search requires at least a bounding rectangle." + + switch(arguments.length) { + case 1: + arguments[1] = false;// Add an "return node" flag - may be removed in future + case 2: + arguments[2] = []; // Add an empty array to contain results + case 3: + arguments[3] = _T; // Add root node to end of argument list + default: + arguments.length = 4; + } + return(_search_subtree.apply(this, arguments)); + }; + + /* partially-recursive toJSON function + * [ string ] = RTree.toJSON([rectangle], [tree]) + * @public + */ + this.toJSON = function(rect, tree) { + var hit_stack = []; // Contains the elements that overlap + var count_stack = []; // Contains the elements that overlap + var return_stack = {}; // Contains the elements that overlap + var max_depth = 3; // This triggers recursion and tree-splitting + var current_depth = 1; + var return_string = ""; + + if(rect && !RTree.Rectangle.overlap_rectangle(rect, _T)) + return ""; + + if(!tree) { + count_stack.push(_T.nodes.length); + hit_stack.push(_T.nodes); + return_string += "var main_tree = {x:"+_T.x.toFixed()+",y:"+_T.y.toFixed()+",w:"+_T.w.toFixed()+",h:"+_T.h.toFixed()+",nodes:["; + } else { + max_depth += 4; + count_stack.push(tree.nodes.length); + hit_stack.push(tree.nodes); + return_string += "var main_tree = {x:"+tree.x.toFixed()+",y:"+tree.y.toFixed()+",w:"+tree.w.toFixed()+",h:"+tree.h.toFixed()+",nodes:["; + } + + do { + var nodes = hit_stack.pop(); + var i = count_stack.pop()-1; + + if(i >= 0 && i < nodes.length-1) + return_string += ","; + + while(i >= 0) { + var ltree = nodes[i]; + if(!rect || RTree.Rectangle.overlap_rectangle(rect, ltree)) { + if(ltree.nodes) { // Not a Leaf + if(current_depth >= max_depth) { + var len = return_stack.length; + var nam = _name_to_id("saved_subtree"); + return_string += "{x:"+ltree.x.toFixed()+",y:"+ltree.y.toFixed()+",w:"+ltree.w.toFixed()+",h:"+ltree.h.toFixed()+",load:'"+nam+".js'}"; + return_stack[nam] = this.toJSON(rect, ltree); + if(i > 0) + return_string += "," + } else { + return_string += "{x:"+ltree.x.toFixed()+",y:"+ltree.y.toFixed()+",w:"+ltree.w.toFixed()+",h:"+ltree.h.toFixed()+",nodes:["; + current_depth += 1; + count_stack.push(i); + hit_stack.push(nodes); + nodes = ltree.nodes; + i = ltree.nodes.length; + } + } else if(ltree.leaf) { // A Leaf !! + var data = ltree.leaf.toJSON ? ltree.leaf.toJSON() : JSON.stringify(ltree.leaf); + return_string += "{x:"+ltree.x.toFixed()+",y:"+ltree.y.toFixed()+",w:"+ltree.w.toFixed()+",h:"+ltree.h.toFixed()+",leaf:" + data + "}"; + if(i > 0) + return_string += "," + } else if(ltree.load) { // A load + return_string += "{x:"+ltree.x.toFixed()+",y:"+ltree.y.toFixed()+",w:"+ltree.w.toFixed()+",h:"+ltree.h.toFixed()+",load:'" + ltree.load + "'}"; + if(i > 0) + return_string += "," + } + } + i -= 1; + } + if(i < 0) { + return_string += "]}"; current_depth -= 1; + } + }while(hit_stack.length > 0); + + return_string+=";"; + + for(var my_key in return_stack) { + return_string += "\nvar " + my_key + " = function(){" + return_stack[my_key] + " return(main_tree);};"; + } + return(return_string); + }; + + /* non-recursive function that deletes a specific + * [ number ] = RTree.remove(rectangle, obj) + */ + this.remove = function(rect, obj) { + if(arguments.length < 1) + throw "Wrong number of arguments. RT.remove requires at least a bounding rectangle." + + switch(arguments.length) { + case 1: + arguments[1] = false; // obj == false for conditionals + case 2: + arguments[2] = _T; // Add root node to end of argument list + default: + arguments.length = 3; + } + if(arguments[1] === false) { // Do area-wide delete + var numberdeleted = 0; + var ret_array = []; + do { + numberdeleted=ret_array.length; + ret_array = ret_array.concat(_remove_subtree.apply(this, arguments)); + }while( numberdeleted != ret_array.length); + return ret_array; + } + else { // Delete a specific item + return(_remove_subtree.apply(this, arguments)); + } + }; + + /* non-recursive insert function + * [] = RTree.insert(rectangle, object to insert) + */ + this.insert = function(rect, obj) { + if(arguments.length < 2) + throw "Wrong number of arguments. RT.Insert requires at least a bounding rectangle and an object." + + return(_insert_subtree({x:rect.x,y:rect.y,w:rect.w,h:rect.h,leaf:obj}, _T)); + }; + + /* non-recursive delete function + * [deleted object] = RTree.remove(rectangle, [object to delete]) + */ //End of RTree }; @@ -1152,60 +1152,60 @@ var RTree = function(width){ /* Rectangle - Generic rectangle object - Not yet used */ RTree.Rectangle = function(ix, iy, iw, ih) { // new Rectangle(bounds) or new Rectangle(x, y, w, h) - var x, x2, y, y2, w, h; + var x, x2, y, y2, w, h; + + if(ix.x) { + x = ix.x; y = ix.y; + if(ix.w !== 0 && !ix.w && ix.x2){ + w = ix.x2-ix.x; h = ix.y2-ix.y; + } else { + w = ix.w; h = ix.h; + } + x2 = x + w; y2 = y + h; // For extra fastitude + } else { + x = ix; y = iy; w = iw; h = ih; + x2 = x + w; y2 = y + h; // For extra fastitude + } + this.x1 = this.x = function(){return x;}; + this.y1 = this.y = function(){return y;}; + this.x2 = function(){return x2;}; + this.y2 = function(){return y2;}; + this.w = function(){return w;}; + this.h = function(){return h;}; + + this.toJSON = function() { + return('{"x":'+x.toString()+', "y":'+y.toString()+', "w":'+w.toString()+', "h":'+h.toString()+'}'); + }; + + this.overlap = function(a) { + return(this.x() < a.x2() && this.x2() > a.x() && this.y() < a.y2() && this.y2() > a.y()); + }; + + this.expand = function(a) { + var nx = Math.min(this.x(), a.x()); + var ny = Math.min(this.y(), a.y()); + w = Math.max(this.x2(), a.x2()) - nx; + h = Math.max(this.y2(), a.y2()) - ny; + x = nx; y = ny; + return(this); + }; + + this.setRect = function(ix, iy, iw, ih) { + var x, x2, y, y2, w, h; if(ix.x) { - x = ix.x; y = ix.y; - if(ix.w !== 0 && !ix.w && ix.x2){ - w = ix.x2-ix.x; h = ix.y2-ix.y; - } else { - w = ix.w; h = ix.h; - } - x2 = x + w; y2 = y + h; // For extra fastitude - } else { - x = ix; y = iy; w = iw; h = ih; - x2 = x + w; y2 = y + h; // For extra fastitude - } - - this.x1 = this.x = function(){return x;}; - this.y1 = this.y = function(){return y;}; - this.x2 = function(){return x2;}; - this.y2 = function(){return y2;}; - this.w = function(){return w;}; - this.h = function(){return h;}; - - this.toJSON = function() { - return('{"x":'+x.toString()+', "y":'+y.toString()+', "w":'+w.toString()+', "h":'+h.toString()+'}'); - }; - - this.overlap = function(a) { - return(this.x() < a.x2() && this.x2() > a.x() && this.y() < a.y2() && this.y2() > a.y()); - }; - - this.expand = function(a) { - var nx = Math.min(this.x(), a.x()); - var ny = Math.min(this.y(), a.y()); - w = Math.max(this.x2(), a.x2()) - nx; - h = Math.max(this.y2(), a.y2()) - ny; - x = nx; y = ny; - return(this); - }; - - this.setRect = function(ix, iy, iw, ih) { - var x, x2, y, y2, w, h; - if(ix.x) { - x = ix.x; y = ix.y; - if(ix.w !== 0 && !ix.w && ix.x2) { - w = ix.x2-ix.x; h = ix.y2-ix.y; - } else { - w = ix.w; h = ix.h; - } - x2 = x + w; y2 = y + h; // For extra fastitude - } else { - x = ix; y = iy; w = iw; h = ih; - x2 = x + w; y2 = y + h; // For extra fastitude - } - }; + x = ix.x; y = ix.y; + if(ix.w !== 0 && !ix.w && ix.x2) { + w = ix.x2-ix.x; h = ix.y2-ix.y; + } else { + w = ix.w; h = ix.h; + } + x2 = x + w; y2 = y + h; // For extra fastitude + } else { + x = ix; y = iy; w = iw; h = ih; + x2 = x + w; y2 = y + h; // For extra fastitude + } + }; //End of RTree.Rectangle }; @@ -1215,7 +1215,7 @@ RTree.Rectangle = function(ix, iy, iw, ih) { // new Rectangle(bounds) or new Rec * @static function */ RTree.Rectangle.overlap_rectangle = function(a, b) { - return(a.x < (b.x+b.w) && (a.x+a.w) > b.x && a.y < (b.y+b.h) && (a.y+a.h) > b.y); + return(a.x < (b.x+b.w) && (a.x+a.w) > b.x && a.y < (b.y+b.h) && (a.y+a.h) > b.y); }; /* returns true if rectangle a is contained in rectangle b @@ -1223,20 +1223,20 @@ RTree.Rectangle.overlap_rectangle = function(a, b) { * @static function */ RTree.Rectangle.contains_rectangle = function(a, b) { - return((a.x+a.w) <= (b.x+b.w) && a.x >= b.x && (a.y+a.h) <= (b.y+b.h) && a.y >= b.y); + return((a.x+a.w) <= (b.x+b.w) && a.x >= b.x && (a.y+a.h) <= (b.y+b.h) && a.y >= b.y); }; /* expands rectangle A to include rectangle B, rectangle B is untouched * [ rectangle a ] = expand_rectangle(rectangle a, rectangle b) * @static function */ -RTree.Rectangle.expand_rectangle = function(a, b) { - var nx = Math.min(a.x, b.x); - var ny = Math.min(a.y, b.y); - a.w = Math.max(a.x+a.w, b.x+b.w) - nx; - a.h = Math.max(a.y+a.h, b.y+b.h) - ny; - a.x = nx; a.y = ny; - return(a); +RTree.Rectangle.expand_rectangle = function(a, b) { + var nx = Math.min(a.x, b.x); + var ny = Math.min(a.y, b.y); + a.w = Math.max(a.x+a.w, b.x+b.w) - nx; + a.h = Math.max(a.y+a.h, b.y+b.h) - ny; + a.x = nx; a.y = ny; + return(a); }; /* generates a minimally bounding rectangle for all rectangles in @@ -1246,18 +1246,18 @@ RTree.Rectangle.expand_rectangle = function(a, b) { * @static function */ RTree.Rectangle.make_MBR = function(nodes, rect) { - if(nodes.length < 1) - return({x:0, y:0, w:0, h:0}); - //throw "make_MBR: nodes must contain at least one rectangle!"; - if(!rect) - rect = {x:nodes[0].x, y:nodes[0].y, w:nodes[0].w, h:nodes[0].h}; - else - rect.x = nodes[0].x; rect.y = nodes[0].y; rect.w = nodes[0].w; rect.h = nodes[0].h; - - for(var i = nodes.length-1; i>0; i--) - RTree.Rectangle.expand_rectangle(rect, nodes[i]); - - return(rect); + if(nodes.length < 1) + return({x:0, y:0, w:0, h:0}); + //throw "make_MBR: nodes must contain at least one rectangle!"; + if(!rect) + rect = {x:nodes[0].x, y:nodes[0].y, w:nodes[0].w, h:nodes[0].h}; + else + rect.x = nodes[0].x; rect.y = nodes[0].y; rect.w = nodes[0].w; rect.h = nodes[0].h; + + for(var i = nodes.length-1; i>0; i--) + RTree.Rectangle.expand_rectangle(rect, nodes[i]); + + return(rect); }; (function(){function D(){}function z(){this.was=[0]}function C(a,b,c){this.hufts=new Int32Array(4320);this.window=new Uint8Array(c);this.end=c;this.checkfn=b;this.mode=0;this.reset(a,null);this.index=this.table=this.left=0;this.blens=null;this.bb=new Int32Array(1);this.tb=new Int32Array(1);this.codes=new E;this.check=this.write=this.read=this.bitb=this.bitk=this.last=0;this.inftree=new F}function E(){}function F(){}function y(a,b,c,d,h){if(0!=h){if(!a)throw"Undef src";if(!c)throw"Undef dest";if(0== @@ -1368,6 +1368,8 @@ var Genoverse = Base.extend({ return this.die('Your browser does not support this functionality'); } + config = config || {}; + config.container = $(config.container); // Make sure container is a jquery object, jquery recognises itself automatically if (!(config.container && config.container.length)) { @@ -2462,37 +2464,86 @@ var Genoverse = Base.extend({ } }), - makeMenu: function (feature, event, track) { - if (!feature.menuEl) { - var browser = this; - var menu = this.menuTemplate.clone(true).data({ browser: this, feature: feature }); - var content = $('.gv-menu-content', menu).remove(); - var loading = $('.gv-menu-loading', menu); - var getMenu = track ? track.controller.populateMenu(feature) : feature; - var isDeferred = typeof getMenu === 'object' && typeof getMenu.promise === 'function'; - var i, j, table, el, start, end, linkData, key, columns, colspan; + makeMenu: function (features, event, track) { + if (!features) { + return false; + } - function focus() { - var data = $(this).data(); - var length = data.end - data.start + 1; - var context = Math.max(Math.round(length / 4), 25); + if (!$.isArray(features)) { + features = [ features ]; + } - browser.moveTo(data.start - context, data.end + context, true); + if (features.length === 0) { + return false; + } else if (features.length === 1) { + return this.makeFeatureMenu(features[0], event, track); + } - return false; - } + var browser = this; + var menu = this.menuTemplate.clone(true).data({ browser: this }); + var table = $('.gv-menu-content', menu).addClass('gv-menu-content-first').find('table'); + + $('.gv-focus, .gv-highlight, .gv-menu-loading', menu).remove(); + $('.gv-title', menu).html(features.length + ' features'); + + $.each(features.sort(function (a, b) { return a.start - b.start; }), function (i, feature) { + var location = feature.chr + ':' + feature.start + (feature.end === feature.start ? '' : '-' + feature.end); + var title = feature.menuLabel || feature.name || ($.isArray(feature.label) ? feature.label.join(' ') : feature.label) || (feature.id + ''); - function highlight() { - browser.addHighlight($(this).data()); + $('').html(title.match(location) ? title : (location + ' ' + title)).on('click', function (e) { + browser.makeFeatureMenu(feature, e, track); return false; - } + }).appendTo($('').appendTo($('').appendTo(table))); + }); + + menu.appendTo(this.superContainer || this.container).show(); + + if (event) { + menu.css({ left: 0, top: 0 }).position({ of: event, my: 'left top', collision: 'flipfit' }); + } + + this.menus = this.menus.add(menu); + + if (track) { + track.prop('menus', track.prop('menus').add(menu)); + } + + return menu; + }, + + makeFeatureMenu: function (feature, e, track) { + var browser = this; + var container = this.superContainer || this.container; + var menu, content, loading, getMenu, isDeferred, i, j, el, start, end, linkData, key, columns, colspan; + + function focus() { + var data = $(this).data(); + var length = data.end - data.start + 1; + var context = Math.max(Math.round(length / 4), 25); + + browser.moveTo(data.start - context, data.end + context, true); + + return false; + } + + function highlight() { + browser.addHighlight($(this).data()); + return false; + } + + if (!feature.menuEl) { + menu = browser.menuTemplate.clone(true).data({ browser: browser, feature: feature }); + content = $('.gv-menu-content', menu).remove(); + loading = $('.gv-menu-loading', menu); + getMenu = track ? track.controller.populateMenu(feature) : feature; + isDeferred = typeof getMenu === 'object' && typeof getMenu.promise === 'function'; if (isDeferred) { loading.show(); } $.when(getMenu).done(function (properties) { - if (Object.prototype.toString.call(properties) !== '[object Array]') { + if (!$.isArray(properties)) { properties = [ properties ]; } @@ -2501,7 +2552,7 @@ var Genoverse = Base.extend({ el = content.clone().addClass(i ? '' : 'gv-menu-content-first').appendTo(menu); start = parseInt(typeof properties[i].start !== 'undefined' ? properties[i].start : feature.start, 10); end = parseInt(typeof properties[i].end !== 'undefined' ? properties[i].end : feature.end, 10); - columns = Math.max.apply(Math, $.map(properties[i], function (v) { return Object.prototype.toString.call(v) === '[object Array]' ? v.length : 1; })); + columns = Math.max.apply(Math, $.map(properties[i], function (v) { return $.isArray(v) ? v.length : 1; })); $('.gv-title', el)[properties[i].title ? 'html' : 'remove'](properties[i].title); @@ -2524,7 +2575,7 @@ var Genoverse = Base.extend({ table += '' + key + ''; if (!colspan) { - if (Object.prototype.toString.call(properties[i][key]) === '[object Array]') { + if ($.isArray(properties[i][key])) { for (j = 0; j < properties[i][key].length; j++) { table += '' + properties[i][key][j] + ''; } @@ -2539,7 +2590,7 @@ var Genoverse = Base.extend({ } } - $('table', el).html(table); + $('table', el)[table ? 'html' : 'remove'](table); } if (isDeferred) { @@ -2551,12 +2602,12 @@ var Genoverse = Base.extend({ menu.addClass(track.id).data('track', track); } - feature.menuEl = menu.appendTo(this.superContainer || this.container); + feature.menuEl = menu.appendTo(container); } else { - feature.menuEl.appendTo(this.superContainer || this.container); // Move the menu to the end of the container again, so that it will always be on top of other menus + feature.menuEl.appendTo(container); // Move the menu to the end of the container again, so that it will always be on top of other menus } - this.menus = this.menus.add(feature.menuEl); + browser.menus = browser.menus.add(feature.menuEl); if (track) { track.prop('menus', track.prop('menus').add(feature.menuEl)); @@ -2564,8 +2615,8 @@ var Genoverse = Base.extend({ feature.menuEl.show(); // Must show before positioning, else position will be wrong - if (event) { - feature.menuEl.css({ left: 0, top: 0 }).position({ of: event, my: 'left top', collision: 'flipfit' }); + if (e) { + feature.menuEl.css({ left: 0, top: 0 }).position({ of: e, my: 'left top', collision: 'flipfit' }); } return feature.menuEl; @@ -2669,6 +2720,11 @@ var Genoverse = Base.extend({ destroy: function () { this.onTracks('destructor'); (this.superContainer || this.container).empty(); + + if (this.zoomInHighlight) { + this.zoomInHighlight.add(this.zoomOutHighlight).remove(); + } + $(window).add(document).off(this.eventNamespace); for (var key in this) { @@ -2897,6 +2953,33 @@ Genoverse.Track = Base.extend({ } } + /* + * Abandon all hope! If you've tracked a bug to this line of code, be afraid. + * It will almost certainly be due to the wonderful way the javascript objects work. + * + * Consider the following: + * + * var Obj = function () {}; + * + * Obj.prototype = { + * scalar : 1, + * array : [ 1, 2, 3 ], + * hash : { a: 1, b : 2 } + * }; + * + * var x = new Obj(); + * + * x.scalar = 10; + * x.array[0] = 10; + * x.hash.a = 10; + * + * var y = new Obj(); + * + * y is now { scalar: 1, array: [ 10, 2, 3 ], hash: { a: 10, b : 2 } }, since memory locations of objects in prototypes are shared. + * + * This has been the cause of numerous Genoverse bugs in the past, due to property sharing between different tracks, models, views, and controllers. + * See also the line a bit further down: this[obj].constructor.extend(mvcSettings[obj].func); + */ this.extend(trackSettings); for (i = 0; i < 3; i++) { @@ -2920,6 +3003,7 @@ Genoverse.Track = Base.extend({ } } + // Abandon all hope! (see above) this[obj].constructor.extend(mvcSettings[obj].func); if (obj === 'model' && typeof test.url !== 'undefined') { @@ -4464,21 +4548,21 @@ Genoverse.Track.Controller.Stranded = Genoverse.Track.Controller.extend({ Genoverse.Track.Model.Stranded = Genoverse.Track.Model.extend({ init: function (reset) { this.base(reset); - + if (!reset) { var otherTrack = this.prop('forwardTrack'); - + if (otherTrack) { this.features = otherTrack.prop('features'); this.featuresById = otherTrack.prop('featuresById'); } } }, - + setURL: function (urlParams, update) { this.base($.extend(urlParams || this.urlParams, { strand: this.track.featureStrand }), update); }, - + findFeatures: function () { var strand = this.track.featureStrand; return $.grep(this.base.apply(this, arguments), function (feature) { return feature.strand === strand; }); @@ -4519,34 +4603,34 @@ Genoverse.Track.Controller.Sequence = Genoverse.Track.Controller.extend({ // assumes that the data source responds with raw sequence text // see Fasta model for more specific example Genoverse.Track.Model.Sequence = Genoverse.Track.Model.extend({ - threshold : 100000, + threshold : 100000, chunkSize : 1000, buffer : 0, dataType : 'text', - + init: function () { this.base(); this.chunks = {}; }, - + getData: function (start, end) { start = start - start % this.chunkSize + 1; end = end + this.chunkSize - end % this.chunkSize; return this.base(start, end); }, - + parseData: function (data, start, end) { data = data.replace(/\n/g, ''); - + if (this.prop('lowerCase')) { data = data.toLowerCase(); } - + for (var i = 0; i < data.length; i += this.chunkSize) { if (this.chunks[start + i]) { continue; } - + var feature = { id : start + i, start : start + i, @@ -4554,7 +4638,7 @@ Genoverse.Track.Model.Sequence = Genoverse.Track.Model.extend({ sequence : data.substr(i, this.chunkSize), sort : start + i }; - + this.chunks[feature.start] = feature; this.insertFeature(feature); } @@ -4564,23 +4648,23 @@ Genoverse.Track.Model.Sequence = Genoverse.Track.Model.extend({ Genoverse.Track.Model.Sequence.Fasta = Genoverse.Track.Model.Sequence.extend({ url : 'http://genoverse.org/data/Homo_sapiens.GRCh37.72.dna.chromosome.1.fa', // Example url - + // Following settings could be left undefined and will be detected automatically via .getStartByte() startByte : undefined, // Byte in the file where the sequence actually starts lineLength : undefined, // Length of the sequence line in the file - + // TODO: Check if URL provided - + getData: function (start, end) { var deferred = $.Deferred(); - + $.when(this.getStartByte()).done(function () { start = start - start % this.chunkSize + 1; end = end + this.chunkSize - end % this.chunkSize; - + var startByte = start - 1 + Math.floor((start - 1) / this.lineLength) + this.startByte; var endByte = end - 1 + Math.floor((end - 1) / this.lineLength) + this.startByte; - + $.ajax({ url : this.parseURL(start, end), dataType : this.dataType, @@ -4591,33 +4675,33 @@ Genoverse.Track.Model.Sequence.Fasta = Genoverse.Track.Model.Sequence.extend({ error : this.track.controller.showError }).done(function () { deferred.resolveWith(this); }).fail(function () { deferred.rejectWith(this); }); }).fail(function () { deferred.rejectWith(this); }); - + return deferred; }, - + getStartByte: function () { if (this.startByteRequest) { return this.startByteRequest; } - + if (this.startByte === undefined || this.lineLength === undefined) { this.startByteRequest = $.ajax({ url : this.parseURL(), dataType : 'text', context : this, headers : { 'Range': 'bytes=0-300' }, - xhrFields : this.xhrFields, + xhrFields : this.xhrFields, success : function (data) { if (data.indexOf('>') === 0) { this.startByte = data.indexOf('\n') + 1; } else { this.startByte = 0; } - + this.lineLength = data.indexOf('\n', this.startByte) - this.startByte; } }); - + return this.startByteRequest; } } @@ -4766,31 +4850,31 @@ Genoverse.Track.Model.SequenceVariation = Genoverse.Track.Model.extend({ Genoverse.Track.Model.SequenceVariation.VCF = Genoverse.Track.Model.SequenceVariation.extend({ dataType: 'text', - + parseData: function (text) { var lines = text.split('\n'); - + for (var i = 0; i < lines.length; i++) { if (!lines[i].length || lines[i].indexOf('#') === 0) { continue; } - + var fields = lines[i].split('\t'); - + if (fields.length < 5) { continue; } - + if (fields[0] === this.browser.chr || fields[0] === 'chr' + this.browser.chr) { var id = fields.slice(0, 3).join('|'); var start = parseInt(fields[1], 10); var alleles = fields[4].split(','); - + alleles.unshift(fields[3]); - + for (var j = 0; j < alleles.length; j++) { var end = start + alleles[j].length - 1; - + this.insertFeature({ id : id + '|' + alleles[j], sort : j, @@ -4802,7 +4886,7 @@ Genoverse.Track.Model.SequenceVariation.VCF = Genoverse.Track.Model.SequenceVari label : alleles[j], labelColor : '#FFFFFF', originalFeature : fields - }); + }); } } } @@ -4937,33 +5021,33 @@ Genoverse.Track.Model.Transcript.Ensembl = Genoverse.Track.Model.Transcript.exte // Basic GFF3 model for transcripts -// See http://www.broadinstitute.org/annotation/gebo/help/gff3.html +// See http://www.broadinstitute.org/annotation/gebo/help/gff3.html Genoverse.Track.Model.Transcript.GFF3 = Genoverse.Track.Model.Transcript.extend({ dataType : 'text', - - // Transcript structure map for column 3 (type) + + // Transcript structure map for column 3 (type) typeMap : { exon : 'exon', cds : 'cds' }, - + parseData: function (text) { var lines = text.split('\n'); - + for (var i = 0; i < lines.length; i++) { if (!lines[i].length || lines[i].indexOf('#') === 0) { continue; } - + var fields = lines[i].split('\t'); - + if (fields.length < 5) { continue; } - + if (fields[0] === this.browser.chr || fields[0].toLowerCase() === 'chr' + this.browser.chr || fields[0].match('[^1-9]' + this.browser.chr + '$')) { var feature = {}; - + feature.id = fields.slice(0, 5).join('|'); feature.start = parseInt(fields[3], 10); feature.end = parseInt(fields[4], 10); @@ -4971,19 +5055,19 @@ Genoverse.Track.Model.Transcript.GFF3 = Genoverse.Track.Model.Transcript.extend( feature.type = fields[2]; feature.score = fields[5]; feature.strand = fields[6] + '1'; - + if (fields[8]) { var frame = fields[8].split(';'); - + for (var j = 0; j < frame.length; j++) { var keyValue = frame[j].split('='); - + if (keyValue.length === 2) { feature[keyValue[0].toLowerCase()] = keyValue[1]; } } } - + // sub-feature came earlier than parent feature if (feature.parent && !this.featuresById[feature.parent]) { this.featuresById[feature.parent] = { @@ -4991,7 +5075,7 @@ Genoverse.Track.Model.Transcript.GFF3 = Genoverse.Track.Model.Transcript.extend( cds : [] }; } - + if (feature.parent && feature.type.toLowerCase() === this.typeMap.exon.toLowerCase()) { if (!$.grep(this.featuresById[feature.parent].exons, function (exon) { return exon.id === feature.id; }).length) { this.featuresById[feature.parent].exons.push(feature); @@ -5003,9 +5087,9 @@ Genoverse.Track.Model.Transcript.GFF3 = Genoverse.Track.Model.Transcript.extend( } else if (!feature.parent) { feature.label = feature.name || feature.id || ''; $.extend(feature, { label: feature.name || feature.id || '', exons: [], cds: [] }, this.featuresById[feature.id] || {}); - + delete this.featuresById[feature.id]; - + this.insertFeature(feature); } } @@ -5266,14 +5350,14 @@ Genoverse.Track.Model.File.BAM = Genoverse.Track.Model.File.extend({ Genoverse.Track.Model.File.BED = Genoverse.Track.Model.File.extend({ parseData: function (text) { var lines = text.split('\n'); - + for (var i = 0; i < lines.length; i++) { var fields = lines[i].split('\t'); - + if (fields.length < 3) { continue; } - + if (fields[0] === this.browser.chr || fields[0].toLowerCase() === 'chr' + this.browser.chr || fields[0].match('[^1-9]' + this.browser.chr + '$')) { var score = parseFloat(fields[4], 10); var color = '#000000'; @@ -5294,7 +5378,7 @@ Genoverse.Track.Model.File.BED = Genoverse.Track.Model.File.extend({ }); } } - }, + }, // As per https://genome.ucsc.edu/FAQ/FAQformat.html#format1 specification scoreColor: function (score) { @@ -5308,7 +5392,7 @@ Genoverse.Track.Model.File.BED = Genoverse.Track.Model.File.extend({ if (score <= 944) { return 'rgb(21,21,21)'; } return '#000000'; } -}); +}); Genoverse.Track.Model.File.GFF = Genoverse.Track.Model.File.extend({ parseData: function (text) { diff --git a/js/lib/Base.js b/js/lib/Base.js index 1ca421aa..81278c64 100644 --- a/js/lib/Base.js +++ b/js/lib/Base.js @@ -1,140 +1,140 @@ /* - Base.js, version 1.1 - Copyright 2006-2007, Dean Edwards - License: http://www.opensource.org/licenses/mit-license.php + Base.js, version 1.1 + Copyright 2006-2007, Dean Edwards + License: http://www.opensource.org/licenses/mit-license.php */ var Base = function() { - // dummy + // dummy }; Base.extend = function(_instance, _static) { // subclass - var extend = Base.prototype.extend; - - // build the prototype - Base._prototyping = true; - var proto = new this; - extend.call(proto, _instance); - delete Base._prototyping; - - // create the wrapper for the constructor function - //var constructor = proto.constructor.valueOf(); //-dean - var constructor = proto.constructor; - var klass = proto.constructor = function() { - if (!Base._prototyping) { - if (this._constructing || this.constructor == klass) { // instantiation - this._constructing = true; - constructor.apply(this, arguments); - delete this._constructing; - } else if (arguments[0] != null) { // casting - return (arguments[0].extend || extend).call(arguments[0], proto); - } - } - }; - - // build the class interface - klass.ancestor = this; - klass.extend = this.extend; - klass.forEach = this.forEach; - klass.implement = this.implement; - klass.prototype = proto; - klass.toString = this.toString; - klass.valueOf = function(type) { - //return (type == "object") ? klass : constructor; //-dean - return (type == "object") ? klass : constructor.valueOf(); - }; - extend.call(klass, _static); - // class initialisation - if (typeof klass.init == "function") klass.init(); - return klass; + var extend = Base.prototype.extend; + + // build the prototype + Base._prototyping = true; + var proto = new this; + extend.call(proto, _instance); + delete Base._prototyping; + + // create the wrapper for the constructor function + //var constructor = proto.constructor.valueOf(); //-dean + var constructor = proto.constructor; + var klass = proto.constructor = function() { + if (!Base._prototyping) { + if (this._constructing || this.constructor == klass) { // instantiation + this._constructing = true; + constructor.apply(this, arguments); + delete this._constructing; + } else if (arguments[0] != null) { // casting + return (arguments[0].extend || extend).call(arguments[0], proto); + } + } + }; + + // build the class interface + klass.ancestor = this; + klass.extend = this.extend; + klass.forEach = this.forEach; + klass.implement = this.implement; + klass.prototype = proto; + klass.toString = this.toString; + klass.valueOf = function(type) { + //return (type == "object") ? klass : constructor; //-dean + return (type == "object") ? klass : constructor.valueOf(); + }; + extend.call(klass, _static); + // class initialisation + if (typeof klass.init == "function") klass.init(); + return klass; }; -Base.prototype = { - extend: function(source, value) { - if (arguments.length > 1) { // extending with a name/value pair - var ancestor = this[source]; - if (ancestor && (typeof value == "function") && // overriding a method? - // the valueOf() comparison is to avoid circular references - (!ancestor.valueOf || ancestor.valueOf() != value.valueOf()) && - /\bbase\b/.test(value)) { - // get the underlying method - var method = value.valueOf(); - // override - value = function() { - var previous = this.base || Base.prototype.base; - this.base = ancestor; - var returnValue = method.apply(this, arguments); - this.base = previous; - return returnValue; - }; - // point to the underlying method - value.valueOf = function(type) { - return (type == "object") ? value : method; - }; - value.toString = Base.toString; - } - this[source] = value; - } else if (source) { // extending with an object literal - var extend = Base.prototype.extend; - // if this object has a customised extend method then use it - if (!Base._prototyping && typeof this != "function") { - extend = this.extend || extend; - } - var proto = {toSource: null}; - // do the "toString" and other methods manually - var hidden = ["constructor", "toString", "valueOf"]; - // if we are prototyping then include the constructor - var i = Base._prototyping ? 0 : 1; - while (key = hidden[i++]) { - if (source[key] != proto[key]) { - extend.call(this, key, source[key]); +Base.prototype = { + extend: function(source, value) { + if (arguments.length > 1) { // extending with a name/value pair + var ancestor = this[source]; + if (ancestor && (typeof value == "function") && // overriding a method? + // the valueOf() comparison is to avoid circular references + (!ancestor.valueOf || ancestor.valueOf() != value.valueOf()) && + /\bbase\b/.test(value)) { + // get the underlying method + var method = value.valueOf(); + // override + value = function() { + var previous = this.base || Base.prototype.base; + this.base = ancestor; + var returnValue = method.apply(this, arguments); + this.base = previous; + return returnValue; + }; + // point to the underlying method + value.valueOf = function(type) { + return (type == "object") ? value : method; + }; + value.toString = Base.toString; + } + this[source] = value; + } else if (source) { // extending with an object literal + var extend = Base.prototype.extend; + // if this object has a customised extend method then use it + if (!Base._prototyping && typeof this != "function") { + extend = this.extend || extend; + } + var proto = {toSource: null}; + // do the "toString" and other methods manually + var hidden = ["constructor", "toString", "valueOf"]; + // if we are prototyping then include the constructor + var i = Base._prototyping ? 0 : 1; + while (key = hidden[i++]) { + if (source[key] != proto[key]) { + extend.call(this, key, source[key]); - } - } - // copy each of the source object's properties to this object - for (var key in source) { - if (!proto[key]) extend.call(this, key, source[key]); - } - } - return this; - }, + } + } + // copy each of the source object's properties to this object + for (var key in source) { + if (!proto[key]) extend.call(this, key, source[key]); + } + } + return this; + }, - base: function() { - // call this method from any other method to invoke that method's ancestor - } + base: function() { + // call this method from any other method to invoke that method's ancestor + } }; // initialise Base = Base.extend({ - constructor: function() { - this.extend(arguments[0]); - } + constructor: function() { + this.extend(arguments[0]); + } }, { - ancestor: Object, - version: "1.1", - - forEach: function(object, block, context) { - for (var key in object) { - if (this.prototype[key] === undefined) { - block.call(context, object[key], key, object); - } - } - }, - - implement: function() { - for (var i = 0; i < arguments.length; i++) { - if (typeof arguments[i] == "function") { - // if it's a function, call it - arguments[i](this.prototype); - } else { - // add the interface using the extend method - this.prototype.extend(arguments[i]); - } - } - return this; - }, - - toString: function() { - return String(this.valueOf()); - } + ancestor: Object, + version: "1.1", + + forEach: function(object, block, context) { + for (var key in object) { + if (this.prototype[key] === undefined) { + block.call(context, object[key], key, object); + } + } + }, + + implement: function() { + for (var i = 0; i < arguments.length; i++) { + if (typeof arguments[i] == "function") { + // if it's a function, call it + arguments[i](this.prototype); + } else { + // add the interface using the extend method + this.prototype.extend(arguments[i]); + } + } + return this; + }, + + toString: function() { + return String(this.valueOf()); + } }); diff --git a/js/lib/dalliance/js/bam.js b/js/lib/dalliance/js/bam.js index 80b7597d..ed3cae30 100644 --- a/js/lib/dalliance/js/bam.js +++ b/js/lib/dalliance/js/bam.js @@ -1,6 +1,6 @@ /* -*- mode: javascript; c-basic-offset: 4; indent-tabs-mode: nil -*- */ -// +// // Dalliance Genome Explorer // (c) Thomas Down 2006-2011 // diff --git a/js/lib/dalliance/js/bin.js b/js/lib/dalliance/js/bin.js index 4c2cd101..cac40466 100644 --- a/js/lib/dalliance/js/bin.js +++ b/js/lib/dalliance/js/bin.js @@ -1,6 +1,6 @@ /* -*- mode: javascript; c-basic-offset: 4; indent-tabs-mode: nil -*- */ -// +// // Dalliance Genome Explorer // (c) Thomas Down 2006-2011 // diff --git a/js/lib/dalliance/js/das.js b/js/lib/dalliance/js/das.js index 57ec028c..aabd5ac9 100644 --- a/js/lib/dalliance/js/das.js +++ b/js/lib/dalliance/js/das.js @@ -1,6 +1,6 @@ /* -*- mode: javascript; c-basic-offset: 4; indent-tabs-mode: nil -*- */ -// +// // Dalliance Genome Explorer // (c) Thomas Down 2006-2010 // @@ -82,12 +82,12 @@ DASSource.prototype.entryPoints = function(callback) { } var entryPoints = new Array(); - + var segs = responseXML.getElementsByTagName('SEGMENT'); for (var i = 0; i < segs.length; ++i) { var seg = segs[i]; var segId = seg.getAttribute('id'); - + var segSize = seg.getAttribute('size'); var segMin, segMax; if (segSize) { @@ -107,9 +107,9 @@ DASSource.prototype.entryPoints = function(callback) { segDesc = seg.firstChild.nodeValue; } entryPoints.push(new DASSegment(segId, segMin, segMax, segDesc)); - } + } callback(entryPoints); - }); + }); } // @@ -133,7 +133,7 @@ DASSource.prototype.sequence = function(segment, callback) { return; } else { var seqs = new Array(); - + var segs = responseXML.getElementsByTagName('SEQUENCE'); for (var i = 0; i < segs.length; ++i) { var seg = segs[i]; @@ -159,7 +159,7 @@ DASSource.prototype.sequence = function(segment, callback) { } seqs.push(new DASSequence(segId, segMin, segMax, segAlpha, segSeq)); } - + callback(seqs); } }); @@ -224,18 +224,18 @@ DASSource.prototype.features = function(segment, options, callback) { } } } - + if (options.maxbins) { filters.push('maxbins=' + options.maxbins); } - + if (filters.length > 0) { dasURI = this.dasBaseURI + 'features?' + filters.join(';'); } else { callback([], 'No filters specified'); } - } - + } + this.doCrossDomainRequest(dasURI, function(responseXML, req) { if (!responseXML) { @@ -266,12 +266,12 @@ DASSource.prototype.features = function(segment, options, callback) { min: segmentXML.getAttribute('start'), max: segmentXML.getAttribute('stop') }; - + var featureXMLs = segmentXML.getElementsByTagName('FEATURE'); for (var i = 0; i < featureXMLs.length; ++i) { var feature = featureXMLs[i]; var dasFeature = new DASFeature(); - + dasFeature.segment = segmentID; dasFeature.id = feature.getAttribute('id'); dasFeature.label = feature.getAttribute('label'); @@ -316,7 +316,7 @@ DASSource.prototype.features = function(segment, options, callback) { if (!dasFeature.type && dasFeature.typeId) { dasFeature.type = dasFeature.typeId; // FIXME? } - + dasFeature.method = elementValue(feature, "METHOD"); { var ori = elementValue(feature, "ORIENTATION"); @@ -328,7 +328,7 @@ DASSource.prototype.features = function(segment, options, callback) { dasFeature.score = elementValue(feature, "SCORE"); dasFeature.links = dasLinksOf(feature); dasFeature.notes = dasNotesOf(feature); - + var groups = feature.getElementsByTagName("GROUP"); for (var gi = 0; gi < groups.length; ++gi) { var groupXML = groups[gi]; @@ -360,7 +360,7 @@ DASSource.prototype.features = function(segment, options, callback) { } } } - + { var pec = feature.getElementsByTagName('PART'); if (pec.length > 0) { @@ -381,11 +381,11 @@ DASSource.prototype.features = function(segment, options, callback) { dasFeature.parents = parents; } } - + features.push(dasFeature); } } - + callback(features, undefined, segmentMap); }, function (err) { @@ -424,7 +424,7 @@ DASSource.prototype.alignments = function(segment, options, callback) { }; ali.objects[obj.id] = obj; } - + var blockXMLs = aliXML.getElementsByTagName('block'); for (var bi = 0; bi < blockXMLs.length; ++bi) { var blockXML = blockXMLs[bi]; @@ -445,8 +445,8 @@ DASSource.prototype.alignments = function(segment, options, callback) { block.segments.push(seg); } ali.blocks.push(block); - } - + } + alignments.push(ali); } callback(alignments); @@ -508,14 +508,14 @@ DASSource.prototype.stylesheet = function(successCB, failureCB) { if (!responseXML) { if (failureCB) { failureCB(); - } + } return; } var stylesheet = new DASStylesheet(); var typeXMLs = responseXML.getElementsByTagName('TYPE'); for (var i = 0; i < typeXMLs.length; ++i) { var typeStyle = typeXMLs[i]; - + var filter = {}; filter.type = typeStyle.getAttribute('id'); // Am I right in thinking that this makes DASSTYLE XML invalid? Ugh. filter.label = typeStyle.getAttribute('label'); @@ -528,7 +528,7 @@ DASSource.prototype.stylesheet = function(successCB, failureCB) { var style = new DASStyle(); style.glyph = glyph.localName; var child = glyph.firstChild; - + while (child) { if (child.nodeType == Node.ELEMENT_NODE) { // alert(child.localName); @@ -545,13 +545,13 @@ DASSource.prototype.stylesheet = function(successCB, failureCB) { // // sources command -// +// function DASRegistry(uri, opts) { opts = opts || {}; this.uri = uri; - this.opts = opts; + this.opts = opts; } DASRegistry.prototype.sources = function(callback, failure, opts) @@ -581,7 +581,7 @@ DASRegistry.prototype.sources = function(callback, failure, opts) return; } - var sources = []; + var sources = []; var sourceXMLs = responseXML.getElementsByTagName('SOURCE'); for (var si = 0; si < sourceXMLs.length; ++si) { var sourceXML = sourceXMLs[si]; @@ -601,13 +601,13 @@ DASRegistry.prototype.sources = function(callback, failure, opts) coord.version = coordXML.getAttribute('version'); coords.push(coord); } - + var caps = []; var capXMLs = versionXML.getElementsByTagName('CAPABILITY'); var uri; for (var ci = 0; ci < capXMLs.length; ++ci) { var capXML = capXMLs[ci]; - + caps.push(capXML.getAttribute('type')); if (capXML.getAttribute('type') == 'das1:features') { @@ -621,7 +621,7 @@ DASRegistry.prototype.sources = function(callback, failure, opts) for (var pi = 0; pi < propXMLs.length; ++pi) { pusho(props, propXMLs[pi].getAttribute('name'), propXMLs[pi].getAttribute('value')); } - + if (uri) { var source = new DASSource(uri, { source_uri: sourceXML.getAttribute('uri'), @@ -634,7 +634,7 @@ DASRegistry.prototype.sources = function(callback, failure, opts) sources.push(source); } } - + callback(sources); }); } @@ -661,7 +661,7 @@ function childElementOf(element) do { if (child.nodeType == Node.ELEMENT_NODE) { return child; - } + } child = child.nextSibling; } while (child != null); } @@ -679,7 +679,7 @@ function dasLinksOf(element) links.push(new DASLink(linkXML.firstChild ? linkXML.firstChild.nodeValue : 'Unknown', linkXML.getAttribute('href'))); } } - + return links; } diff --git a/js/lib/dalliance/js/utils.js b/js/lib/dalliance/js/utils.js index 80e9a700..0397b3fa 100644 --- a/js/lib/dalliance/js/utils.js +++ b/js/lib/dalliance/js/utils.js @@ -1,6 +1,6 @@ /* -*- mode: javascript; c-basic-offset: 4; indent-tabs-mode: nil -*- */ -// +// // Dalliance Genome Explorer // (c) Thomas Down 2006-2010 // @@ -141,7 +141,7 @@ function makeElement(tag, children, attribs, styles) ele.appendChild(c); } } - + if (attribs) { for (var l in attribs) { ele[l] = attribs[l]; @@ -170,7 +170,7 @@ function makeElementNS(namespace, tag, children, attribs) ele.appendChild(c); } } - + setAttrs(ele, attribs); return ele; } @@ -325,15 +325,15 @@ Awaited.prototype.await = function(f) { function textXHR(url, callback, opts) { var req = new XMLHttpRequest(); req.onreadystatechange = function() { - if (req.readyState == 4) { - if (req.status >= 300) { - callback(null, 'Error code ' + req.status); - } else { - callback(req.responseText); - } - } + if (req.readyState == 4) { + if (req.status >= 300) { + callback(null, 'Error code ' + req.status); + } else { + callback(req.responseText); + } + } }; - + req.open('GET', url, true); req.responseType = 'text'; @@ -361,7 +361,7 @@ function relativeURL(base, rel) { // // Missing APIs -// +// if (!('trim' in String.prototype)) { String.prototype.trim = function() { diff --git a/js/lib/jquery.hashchange.js b/js/lib/jquery.hashchange.js index 3c607bae..6fb01d9a 100644 --- a/js/lib/jquery.hashchange.js +++ b/js/lib/jquery.hashchange.js @@ -1,7 +1,7 @@ /* * jQuery hashchange event - v1.3 - 7/21/2010 * http://benalman.com/projects/jquery-hashchange-plugin/ - * + * * Copyright (c) 2010 "Cowboy" Ben Alman * Dual licensed under the MIT and GPL licenses. * http://benalman.com/about/license/ diff --git a/js/lib/jquery.mousehold.js b/js/lib/jquery.mousehold.js index b9c2ba0d..1d376c30 100644 --- a/js/lib/jquery.mousehold.js +++ b/js/lib/jquery.mousehold.js @@ -43,7 +43,7 @@ $.fn.mousehold = function(timeout, f) { if (fireStep == 1) f.call(this, 1); fireStep = 0; } - + $(this).mouseout(clearMousehold); $(this).mouseup(clearMousehold); }) diff --git a/js/lib/jquery.mousewheel.js b/js/lib/jquery.mousewheel.js index f1d5f72f..bf766be6 100644 --- a/js/lib/jquery.mousewheel.js +++ b/js/lib/jquery.mousewheel.js @@ -6,7 +6,7 @@ * Thanks to: Seamus Leahy for adding deltaX and deltaY * * Version: 3.0.6 - * + * * Requires: 1.2.2+ */ @@ -30,7 +30,7 @@ $.event.special.mousewheel = { this.onmousewheel = handler; } }, - + teardown: function() { if ( this.removeEventListener ) { for ( var i=types.length; i; ) { @@ -46,7 +46,7 @@ $.fn.extend({ mousewheel: function(fn) { return fn ? this.bind("mousewheel", fn) : this.trigger("mousewheel"); }, - + unmousewheel: function(fn) { return this.unbind("mousewheel", fn); } @@ -57,27 +57,27 @@ function handler(event) { var orgEvent = event || window.event, args = [].slice.call( arguments, 1 ), delta = 0, returnValue = true, deltaX = 0, deltaY = 0; event = $.event.fix(orgEvent); event.type = "mousewheel"; - + // Old school scrollwheel delta if ( orgEvent.wheelDelta ) { delta = orgEvent.wheelDelta/120; } if ( orgEvent.detail ) { delta = -orgEvent.detail/3; } - + // New school multidimensional scroll (touchpads) deltas deltaY = delta; - + // Gecko if ( orgEvent.axis !== undefined && orgEvent.axis === orgEvent.HORIZONTAL_AXIS ) { deltaY = 0; deltaX = -1*delta; } - + // Webkit if ( orgEvent.wheelDeltaY !== undefined ) { deltaY = orgEvent.wheelDeltaY/120; } if ( orgEvent.wheelDeltaX !== undefined ) { deltaX = -1*orgEvent.wheelDeltaX/120; } - + // Add event and delta to the front of the arguments args.unshift(event, delta, deltaX, deltaY); - + return ($.event.dispatch || $.event.handle).apply(this, args); } diff --git a/js/lib/rtree.js b/js/lib/rtree.js index 11fd3564..47d0159d 100644 --- a/js/lib/rtree.js +++ b/js/lib/rtree.js @@ -1,9 +1,9 @@ -/****************************************************************************** - rtree.js - General-Purpose Non-Recursive Javascript R-Tree Library - Version 0.6.2, December 5st 2009 +/****************************************************************************** + rtree.js - General-Purpose Non-Recursive Javascript R-Tree Library + Version 0.6.2, December 5st 2009 Copyright (c) 2009 Jon-Carlos Rivera - + Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including @@ -11,10 +11,10 @@ distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - + The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND @@ -23,7 +23,7 @@ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - Jon-Carlos Rivera - imbcmdth@hotmail.com + Jon-Carlos Rivera - imbcmdth@hotmail.com ******************************************************************************/ /** @@ -31,22 +31,22 @@ * @constructor */ var RTree = function(width){ - // Variables to control tree-dimensions - var _Min_Width = 3; // Minimum width of any node before a merge - var _Max_Width = 6; // Maximum width of any node before a split - if(!isNaN(width)){ _Min_Width = Math.floor(width/2.0); _Max_Width = width;} - // Start with an empty root-tree - var _T = {x:0, y:0, w:0, h:0, id:"root", nodes:[] }; - - var isArray = function(o) { - return Object.prototype.toString.call(o) === '[object Array]'; - }; - - /* @function - * @description Function to generate unique strings for element IDs - * @param {String} n The prefix to use for the IDs generated. - * @return {String} A guarenteed unique ID. - */ + // Variables to control tree-dimensions + var _Min_Width = 3; // Minimum width of any node before a merge + var _Max_Width = 6; // Maximum width of any node before a split + if(!isNaN(width)){ _Min_Width = Math.floor(width/2.0); _Max_Width = width;} + // Start with an empty root-tree + var _T = {x:0, y:0, w:0, h:0, id:"root", nodes:[] }; + + var isArray = function(o) { + return Object.prototype.toString.call(o) === '[object Array]'; + }; + + /* @function + * @description Function to generate unique strings for element IDs + * @param {String} n The prefix to use for the IDs generated. + * @return {String} A guarenteed unique ID. + */ var _name_to_id = (function() { // hide our idCache inside this closure var idCache = {}; @@ -63,538 +63,538 @@ var RTree = function(width){ } })(); - // This is my special addition to the world of r-trees - // every other (simple) method I found produced crap trees - // this skews insertions to prefering squarer and emptier nodes - RTree.Rectangle.squarified_ratio = function(l, w, fill) { - // Area of new enlarged rectangle - var lperi = (l + w) / 2.0; // Average size of a side of the new rectangle - var larea = l * w; // Area of new rectangle - // return the ratio of the perimeter to the area - the closer to 1 we are, - // the more "square" a rectangle is. conversly, when approaching zero the - // more elongated a rectangle is - var lgeo = larea / (lperi*lperi); - return(larea * fill / lgeo); - }; - - /* find the best specific node(s) for object to be deleted from - * [ leaf node parent ] = _remove_subtree(rectangle, object, root) - * @private - */ - var _remove_subtree = function(rect, obj, root) { - var hit_stack = []; // Contains the elements that overlap - var count_stack = []; // Contains the elements that overlap - var ret_array = []; - var current_depth = 1; - - if(!rect || !RTree.Rectangle.overlap_rectangle(rect, root)) - return ret_array; - - var ret_obj = {x:rect.x, y:rect.y, w:rect.w, h:rect.h, target:obj}; - - count_stack.push(root.nodes.length); - hit_stack.push(root); - - do { - var tree = hit_stack.pop(); - var i = count_stack.pop()-1; - - if("target" in ret_obj) { // We are searching for a target - while(i >= 0) { - var ltree = tree.nodes[i]; - if(RTree.Rectangle.overlap_rectangle(ret_obj, ltree)) { - if( (ret_obj.target && "leaf" in ltree && ltree.leaf === ret_obj.target) - ||(!ret_obj.target && ("leaf" in ltree || RTree.Rectangle.contains_rectangle(ltree, ret_obj)))) { // A Match !! - // Yup we found a match... - // we can cancel search and start walking up the list - if("nodes" in ltree) {// If we are deleting a node not a leaf... - ret_array = _search_subtree(ltree, true, [], ltree); - tree.nodes.splice(i, 1); - } else { - ret_array = tree.nodes.splice(i, 1); - } - // Resize MBR down... - RTree.Rectangle.make_MBR(tree.nodes, tree); - delete ret_obj.target; - if(tree.nodes.length < _Min_Width) { // Underflow - ret_obj.nodes = _search_subtree(tree, true, [], tree); - } - break; - }/* else if("load" in ltree) { // A load - }*/ else if("nodes" in ltree) { // Not a Leaf - current_depth += 1; - count_stack.push(i); - hit_stack.push(tree); - tree = ltree; - i = ltree.nodes.length; - } - } - i -= 1; - } - } else if("nodes" in ret_obj) { // We are unsplitting - tree.nodes.splice(i+1, 1); // Remove unsplit node - // ret_obj.nodes contains a list of elements removed from the tree so far - if(tree.nodes.length > 0) - RTree.Rectangle.make_MBR(tree.nodes, tree); - for(var t = 0;t 0 && tree.nodes.length < _Min_Width) { // Underflow..AGAIN! - ret_obj.nodes = _search_subtree(tree, true, ret_obj.nodes, tree); - tree.nodes.length = 0; - }else { - delete ret_obj.nodes; // Just start resizing - } - } else { // we are just resizing - RTree.Rectangle.make_MBR(tree.nodes, tree); - } - current_depth -= 1; - }while(hit_stack.length > 0); - - return(ret_array); - }; - - /* choose the best damn node for rectangle to be inserted into - * [ leaf node parent ] = _choose_leaf_subtree(rectangle, root to start search at) - * @private - */ - var _choose_leaf_subtree = function(rect, root) { - var best_choice_index = -1; - var best_choice_stack = []; - var best_choice_area; - - var load_callback = function(local_tree, local_node){ - return(function(data) { - local_tree._attach_data(local_node, data); - }); - }; - - best_choice_stack.push(root); - var nodes = root.nodes; - - do { - if(best_choice_index != -1) { - best_choice_stack.push(nodes[best_choice_index]); - nodes = nodes[best_choice_index].nodes; - best_choice_index = -1; - } - - for(var i = nodes.length-1; i >= 0; i--) { - var ltree = nodes[i]; - if("leaf" in ltree) { - // Bail out of everything and start inserting - best_choice_index = -1; - break; - } /*else if(ltree.load) { - throw( "Can't insert into partially loaded tree ... yet!"); - //jQuery.getJSON(ltree.load, load_callback(this, ltree)); - //delete ltree.load; - }*/ - // Area of new enlarged rectangle - var old_lratio = RTree.Rectangle.squarified_ratio(ltree.w, ltree.h, ltree.nodes.length+1); - - // Enlarge rectangle to fit new rectangle - var nw = Math.max(ltree.x+ltree.w, rect.x+rect.w) - Math.min(ltree.x, rect.x); - var nh = Math.max(ltree.y+ltree.h, rect.y+rect.h) - Math.min(ltree.y, rect.y); - - // Area of new enlarged rectangle - var lratio = RTree.Rectangle.squarified_ratio(nw, nh, ltree.nodes.length+2); - - if(best_choice_index < 0 || Math.abs(lratio - old_lratio) < best_choice_area) { - best_choice_area = Math.abs(lratio - old_lratio); best_choice_index = i; - } - } - }while(best_choice_index != -1); - - return(best_choice_stack); - }; - - /* split a set of nodes into two roughly equally-filled nodes - * [ an array of two new arrays of nodes ] = linear_split(array of nodes) - * @private - */ - var _linear_split = function(nodes) { - var n = _pick_linear(nodes); - while(nodes.length > 0) { - _pick_next(nodes, n[0], n[1]); - } - return(n); - }; - - /* insert the best source rectangle into the best fitting parent node: a or b - * [] = pick_next(array of source nodes, target node array a, target node array b) - * @private - */ - var _pick_next = function(nodes, a, b) { - // Area of new enlarged rectangle - var area_a = RTree.Rectangle.squarified_ratio(a.w, a.h, a.nodes.length+1); - var area_b = RTree.Rectangle.squarified_ratio(b.w, b.h, b.nodes.length+1); - var high_area_delta; - var high_area_node; - var lowest_growth_group; - - for(var i = nodes.length-1; i>=0;i--) { - var l = nodes[i]; - var new_area_a = {}; - new_area_a.x = Math.min(a.x, l.x); new_area_a.y = Math.min(a.y, l.y); - new_area_a.w = Math.max(a.x+a.w, l.x+l.w) - new_area_a.x; new_area_a.h = Math.max(a.y+a.h, l.y+l.h) - new_area_a.y; - var change_new_area_a = Math.abs(RTree.Rectangle.squarified_ratio(new_area_a.w, new_area_a.h, a.nodes.length+2) - area_a); - - var new_area_b = {}; - new_area_b.x = Math.min(b.x, l.x); new_area_b.y = Math.min(b.y, l.y); - new_area_b.w = Math.max(b.x+b.w, l.x+l.w) - new_area_b.x; new_area_b.h = Math.max(b.y+b.h, l.y+l.h) - new_area_b.y; - var change_new_area_b = Math.abs(RTree.Rectangle.squarified_ratio(new_area_b.w, new_area_b.h, b.nodes.length+2) - area_b); - - if( !high_area_node || !high_area_delta || Math.abs( change_new_area_b - change_new_area_a ) < high_area_delta ) { - high_area_node = i; - high_area_delta = Math.abs(change_new_area_b-change_new_area_a); - lowest_growth_group = change_new_area_b < change_new_area_a ? b : a; - } - } - var temp_node = nodes.splice(high_area_node, 1)[0]; - if(a.nodes.length + nodes.length + 1 <= _Min_Width) { - a.nodes.push(temp_node); - RTree.Rectangle.expand_rectangle(a, temp_node); - } else if(b.nodes.length + nodes.length + 1 <= _Min_Width) { - b.nodes.push(temp_node); - RTree.Rectangle.expand_rectangle(b, temp_node); - } - else { - lowest_growth_group.nodes.push(temp_node); - RTree.Rectangle.expand_rectangle(lowest_growth_group, temp_node); - } - }; - - /* pick the "best" two starter nodes to use as seeds using the "linear" criteria - * [ an array of two new arrays of nodes ] = pick_linear(array of source nodes) - * @private - */ - var _pick_linear = function(nodes) { - var lowest_high_x = nodes.length-1; - var highest_low_x = 0; - var lowest_high_y = nodes.length-1; - var highest_low_y = 0; + // This is my special addition to the world of r-trees + // every other (simple) method I found produced crap trees + // this skews insertions to prefering squarer and emptier nodes + RTree.Rectangle.squarified_ratio = function(l, w, fill) { + // Area of new enlarged rectangle + var lperi = (l + w) / 2.0; // Average size of a side of the new rectangle + var larea = l * w; // Area of new rectangle + // return the ratio of the perimeter to the area - the closer to 1 we are, + // the more "square" a rectangle is. conversly, when approaching zero the + // more elongated a rectangle is + var lgeo = larea / (lperi*lperi); + return(larea * fill / lgeo); + }; + + /* find the best specific node(s) for object to be deleted from + * [ leaf node parent ] = _remove_subtree(rectangle, object, root) + * @private + */ + var _remove_subtree = function(rect, obj, root) { + var hit_stack = []; // Contains the elements that overlap + var count_stack = []; // Contains the elements that overlap + var ret_array = []; + var current_depth = 1; + + if(!rect || !RTree.Rectangle.overlap_rectangle(rect, root)) + return ret_array; + + var ret_obj = {x:rect.x, y:rect.y, w:rect.w, h:rect.h, target:obj}; + + count_stack.push(root.nodes.length); + hit_stack.push(root); + + do { + var tree = hit_stack.pop(); + var i = count_stack.pop()-1; + + if("target" in ret_obj) { // We are searching for a target + while(i >= 0) { + var ltree = tree.nodes[i]; + if(RTree.Rectangle.overlap_rectangle(ret_obj, ltree)) { + if( (ret_obj.target && "leaf" in ltree && ltree.leaf === ret_obj.target) + ||(!ret_obj.target && ("leaf" in ltree || RTree.Rectangle.contains_rectangle(ltree, ret_obj)))) { // A Match !! + // Yup we found a match... + // we can cancel search and start walking up the list + if("nodes" in ltree) {// If we are deleting a node not a leaf... + ret_array = _search_subtree(ltree, true, [], ltree); + tree.nodes.splice(i, 1); + } else { + ret_array = tree.nodes.splice(i, 1); + } + // Resize MBR down... + RTree.Rectangle.make_MBR(tree.nodes, tree); + delete ret_obj.target; + if(tree.nodes.length < _Min_Width) { // Underflow + ret_obj.nodes = _search_subtree(tree, true, [], tree); + } + break; + }/* else if("load" in ltree) { // A load + }*/ else if("nodes" in ltree) { // Not a Leaf + current_depth += 1; + count_stack.push(i); + hit_stack.push(tree); + tree = ltree; + i = ltree.nodes.length; + } + } + i -= 1; + } + } else if("nodes" in ret_obj) { // We are unsplitting + tree.nodes.splice(i+1, 1); // Remove unsplit node + // ret_obj.nodes contains a list of elements removed from the tree so far + if(tree.nodes.length > 0) + RTree.Rectangle.make_MBR(tree.nodes, tree); + for(var t = 0;t 0 && tree.nodes.length < _Min_Width) { // Underflow..AGAIN! + ret_obj.nodes = _search_subtree(tree, true, ret_obj.nodes, tree); + tree.nodes.length = 0; + }else { + delete ret_obj.nodes; // Just start resizing + } + } else { // we are just resizing + RTree.Rectangle.make_MBR(tree.nodes, tree); + } + current_depth -= 1; + }while(hit_stack.length > 0); + + return(ret_array); + }; + + /* choose the best damn node for rectangle to be inserted into + * [ leaf node parent ] = _choose_leaf_subtree(rectangle, root to start search at) + * @private + */ + var _choose_leaf_subtree = function(rect, root) { + var best_choice_index = -1; + var best_choice_stack = []; + var best_choice_area; + + var load_callback = function(local_tree, local_node){ + return(function(data) { + local_tree._attach_data(local_node, data); + }); + }; + + best_choice_stack.push(root); + var nodes = root.nodes; + + do { + if(best_choice_index != -1) { + best_choice_stack.push(nodes[best_choice_index]); + nodes = nodes[best_choice_index].nodes; + best_choice_index = -1; + } + + for(var i = nodes.length-1; i >= 0; i--) { + var ltree = nodes[i]; + if("leaf" in ltree) { + // Bail out of everything and start inserting + best_choice_index = -1; + break; + } /*else if(ltree.load) { + throw( "Can't insert into partially loaded tree ... yet!"); + //jQuery.getJSON(ltree.load, load_callback(this, ltree)); + //delete ltree.load; + }*/ + // Area of new enlarged rectangle + var old_lratio = RTree.Rectangle.squarified_ratio(ltree.w, ltree.h, ltree.nodes.length+1); + + // Enlarge rectangle to fit new rectangle + var nw = Math.max(ltree.x+ltree.w, rect.x+rect.w) - Math.min(ltree.x, rect.x); + var nh = Math.max(ltree.y+ltree.h, rect.y+rect.h) - Math.min(ltree.y, rect.y); + + // Area of new enlarged rectangle + var lratio = RTree.Rectangle.squarified_ratio(nw, nh, ltree.nodes.length+2); + + if(best_choice_index < 0 || Math.abs(lratio - old_lratio) < best_choice_area) { + best_choice_area = Math.abs(lratio - old_lratio); best_choice_index = i; + } + } + }while(best_choice_index != -1); + + return(best_choice_stack); + }; + + /* split a set of nodes into two roughly equally-filled nodes + * [ an array of two new arrays of nodes ] = linear_split(array of nodes) + * @private + */ + var _linear_split = function(nodes) { + var n = _pick_linear(nodes); + while(nodes.length > 0) { + _pick_next(nodes, n[0], n[1]); + } + return(n); + }; + + /* insert the best source rectangle into the best fitting parent node: a or b + * [] = pick_next(array of source nodes, target node array a, target node array b) + * @private + */ + var _pick_next = function(nodes, a, b) { + // Area of new enlarged rectangle + var area_a = RTree.Rectangle.squarified_ratio(a.w, a.h, a.nodes.length+1); + var area_b = RTree.Rectangle.squarified_ratio(b.w, b.h, b.nodes.length+1); + var high_area_delta; + var high_area_node; + var lowest_growth_group; + + for(var i = nodes.length-1; i>=0;i--) { + var l = nodes[i]; + var new_area_a = {}; + new_area_a.x = Math.min(a.x, l.x); new_area_a.y = Math.min(a.y, l.y); + new_area_a.w = Math.max(a.x+a.w, l.x+l.w) - new_area_a.x; new_area_a.h = Math.max(a.y+a.h, l.y+l.h) - new_area_a.y; + var change_new_area_a = Math.abs(RTree.Rectangle.squarified_ratio(new_area_a.w, new_area_a.h, a.nodes.length+2) - area_a); + + var new_area_b = {}; + new_area_b.x = Math.min(b.x, l.x); new_area_b.y = Math.min(b.y, l.y); + new_area_b.w = Math.max(b.x+b.w, l.x+l.w) - new_area_b.x; new_area_b.h = Math.max(b.y+b.h, l.y+l.h) - new_area_b.y; + var change_new_area_b = Math.abs(RTree.Rectangle.squarified_ratio(new_area_b.w, new_area_b.h, b.nodes.length+2) - area_b); + + if( !high_area_node || !high_area_delta || Math.abs( change_new_area_b - change_new_area_a ) < high_area_delta ) { + high_area_node = i; + high_area_delta = Math.abs(change_new_area_b-change_new_area_a); + lowest_growth_group = change_new_area_b < change_new_area_a ? b : a; + } + } + var temp_node = nodes.splice(high_area_node, 1)[0]; + if(a.nodes.length + nodes.length + 1 <= _Min_Width) { + a.nodes.push(temp_node); + RTree.Rectangle.expand_rectangle(a, temp_node); + } else if(b.nodes.length + nodes.length + 1 <= _Min_Width) { + b.nodes.push(temp_node); + RTree.Rectangle.expand_rectangle(b, temp_node); + } + else { + lowest_growth_group.nodes.push(temp_node); + RTree.Rectangle.expand_rectangle(lowest_growth_group, temp_node); + } + }; + + /* pick the "best" two starter nodes to use as seeds using the "linear" criteria + * [ an array of two new arrays of nodes ] = pick_linear(array of source nodes) + * @private + */ + var _pick_linear = function(nodes) { + var lowest_high_x = nodes.length-1; + var highest_low_x = 0; + var lowest_high_y = nodes.length-1; + var highest_low_y = 0; var t1, t2; - - for(var i = nodes.length-2; i>=0;i--) { - var l = nodes[i]; - if(l.x > nodes[highest_low_x].x ) highest_low_x = i; - else if(l.x+l.w < nodes[lowest_high_x].x+nodes[lowest_high_x].w) lowest_high_x = i; - if(l.y > nodes[highest_low_y].y ) highest_low_y = i; - else if(l.y+l.h < nodes[lowest_high_y].y+nodes[lowest_high_y].h) lowest_high_y = i; - } - var dx = Math.abs((nodes[lowest_high_x].x+nodes[lowest_high_x].w) - nodes[highest_low_x].x); - var dy = Math.abs((nodes[lowest_high_y].y+nodes[lowest_high_y].h) - nodes[highest_low_y].y); - if( dx > dy ) { - if(lowest_high_x > highest_low_x) { - t1 = nodes.splice(lowest_high_x, 1)[0]; - t2 = nodes.splice(highest_low_x, 1)[0]; - } else { - t2 = nodes.splice(highest_low_x, 1)[0]; - t1 = nodes.splice(lowest_high_x, 1)[0]; - } - } else { - if(lowest_high_y > highest_low_y) { - t1 = nodes.splice(lowest_high_y, 1)[0]; - t2 = nodes.splice(highest_low_y, 1)[0]; - } else { - t2 = nodes.splice(highest_low_y, 1)[0]; - t1 = nodes.splice(lowest_high_y, 1)[0]; - } - } - return([{x:t1.x, y:t1.y, w:t1.w, h:t1.h, nodes:[t1]}, - {x:t2.x, y:t2.y, w:t2.w, h:t2.h, nodes:[t2]} ]); - }; - - var _attach_data = function(node, more_tree){ - node.nodes = more_tree.nodes; - node.x = more_tree.x; node.y = more_tree.y; - node.w = more_tree.w; node.h = more_tree.h; - return(node); - }; - - /* non-recursive internal search function - * [ nodes | objects ] = _search_subtree(rectangle, [return node data], [array to fill], root to begin search at) - * @private - */ - var _search_subtree = function(rect, return_node, return_array, root) { - var hit_stack = []; // Contains the elements that overlap - - if(!RTree.Rectangle.overlap_rectangle(rect, root)) - return(return_array); - - var load_callback = function(local_tree, local_node){ - return(function(data) { - local_tree._attach_data(local_node, data); - }); - }; - - hit_stack.push(root.nodes); - - do { - var nodes = hit_stack.pop(); - - for(var i = nodes.length-1; i >= 0; i--) { - var ltree = nodes[i]; - if(RTree.Rectangle.overlap_rectangle(rect, ltree)) { - if("nodes" in ltree) { // Not a Leaf - hit_stack.push(ltree.nodes); - } else if("leaf" in ltree) { // A Leaf !! - if(!return_node) - return_array.push(ltree.leaf); - else - return_array.push(ltree); - }/* else if("load" in ltree) { // We need to fetch a URL for some more tree data - jQuery.getJSON(ltree.load, load_callback(this, ltree)); - delete ltree.load; - // i++; // Replay this entry - }*/ - } - } - }while(hit_stack.length > 0); - - return(return_array); - }; - - /* non-recursive internal insert function - * [] = _insert_subtree(rectangle, object to insert, root to begin insertion at) - * @private - */ - var _insert_subtree = function(node, root) { - var bc; // Best Current node - // Initial insertion is special because we resize the Tree and we don't - // care about any overflow (seriously, how can the first object overflow?) - if(root.nodes.length == 0) { - root.x = node.x; root.y = node.y; - root.w = node.w; root.h = node.h; - root.nodes.push(node); - return; - } - - // Find the best fitting leaf node - // choose_leaf returns an array of all tree levels (including root) - // that were traversed while trying to find the leaf - var tree_stack = _choose_leaf_subtree(node, root); - var ret_obj = node;//{x:rect.x,y:rect.y,w:rect.w,h:rect.h, leaf:obj}; - - // Walk back up the tree resizing and inserting as needed - do { - //handle the case of an empty node (from a split) - if(bc && "nodes" in bc && bc.nodes.length == 0) { - var pbc = bc; // Past bc - bc = tree_stack.pop(); - for(var t=0;t 0); - }; - - /* quick 'n' dirty function for plugins or manually drawing the tree - * [ tree ] = RTree.get_tree(): returns the raw tree data. useful for adding - * @public - * !! DEPRECATED !! - */ - this.get_tree = function() { - return _T; - }; - - /* quick 'n' dirty function for plugins or manually loading the tree - * [ tree ] = RTree.set_tree(sub-tree, where to attach): returns the raw tree data. useful for adding - * @public - * !! DEPRECATED !! - */ - this.set_tree = function(new_tree, where) { - if(!where) - where = _T; - return(_attach_data(where, new_tree)); - }; - - /* non-recursive search function - * [ nodes | objects ] = RTree.search(rectangle, [return node data], [array to fill]) - * @public - */ - this.search = function(rect, return_node, return_array) { - if(arguments.length < 1) - throw "Wrong number of arguments. RT.Search requires at least a bounding rectangle." - - switch(arguments.length) { - case 1: - arguments[1] = false;// Add an "return node" flag - may be removed in future - case 2: - arguments[2] = []; // Add an empty array to contain results - case 3: - arguments[3] = _T; // Add root node to end of argument list - default: - arguments.length = 4; - } - return(_search_subtree.apply(this, arguments)); - }; - - /* partially-recursive toJSON function - * [ string ] = RTree.toJSON([rectangle], [tree]) - * @public - */ - this.toJSON = function(rect, tree) { - var hit_stack = []; // Contains the elements that overlap - var count_stack = []; // Contains the elements that overlap - var return_stack = {}; // Contains the elements that overlap - var max_depth = 3; // This triggers recursion and tree-splitting - var current_depth = 1; - var return_string = ""; - - if(rect && !RTree.Rectangle.overlap_rectangle(rect, _T)) - return ""; - - if(!tree) { - count_stack.push(_T.nodes.length); - hit_stack.push(_T.nodes); - return_string += "var main_tree = {x:"+_T.x.toFixed()+",y:"+_T.y.toFixed()+",w:"+_T.w.toFixed()+",h:"+_T.h.toFixed()+",nodes:["; - } else { - max_depth += 4; - count_stack.push(tree.nodes.length); - hit_stack.push(tree.nodes); - return_string += "var main_tree = {x:"+tree.x.toFixed()+",y:"+tree.y.toFixed()+",w:"+tree.w.toFixed()+",h:"+tree.h.toFixed()+",nodes:["; - } - - do { - var nodes = hit_stack.pop(); - var i = count_stack.pop()-1; - - if(i >= 0 && i < nodes.length-1) - return_string += ","; - - while(i >= 0) { - var ltree = nodes[i]; - if(!rect || RTree.Rectangle.overlap_rectangle(rect, ltree)) { - if(ltree.nodes) { // Not a Leaf - if(current_depth >= max_depth) { - var len = return_stack.length; - var nam = _name_to_id("saved_subtree"); - return_string += "{x:"+ltree.x.toFixed()+",y:"+ltree.y.toFixed()+",w:"+ltree.w.toFixed()+",h:"+ltree.h.toFixed()+",load:'"+nam+".js'}"; - return_stack[nam] = this.toJSON(rect, ltree); - if(i > 0) - return_string += "," - } else { - return_string += "{x:"+ltree.x.toFixed()+",y:"+ltree.y.toFixed()+",w:"+ltree.w.toFixed()+",h:"+ltree.h.toFixed()+",nodes:["; - current_depth += 1; - count_stack.push(i); - hit_stack.push(nodes); - nodes = ltree.nodes; - i = ltree.nodes.length; - } - } else if(ltree.leaf) { // A Leaf !! - var data = ltree.leaf.toJSON ? ltree.leaf.toJSON() : JSON.stringify(ltree.leaf); - return_string += "{x:"+ltree.x.toFixed()+",y:"+ltree.y.toFixed()+",w:"+ltree.w.toFixed()+",h:"+ltree.h.toFixed()+",leaf:" + data + "}"; - if(i > 0) - return_string += "," - } else if(ltree.load) { // A load - return_string += "{x:"+ltree.x.toFixed()+",y:"+ltree.y.toFixed()+",w:"+ltree.w.toFixed()+",h:"+ltree.h.toFixed()+",load:'" + ltree.load + "'}"; - if(i > 0) - return_string += "," - } - } - i -= 1; - } - if(i < 0) { - return_string += "]}"; current_depth -= 1; - } - }while(hit_stack.length > 0); - - return_string+=";"; - - for(var my_key in return_stack) { - return_string += "\nvar " + my_key + " = function(){" + return_stack[my_key] + " return(main_tree);};"; - } - return(return_string); - }; - - /* non-recursive function that deletes a specific - * [ number ] = RTree.remove(rectangle, obj) - */ - this.remove = function(rect, obj) { - if(arguments.length < 1) - throw "Wrong number of arguments. RT.remove requires at least a bounding rectangle." - - switch(arguments.length) { - case 1: - arguments[1] = false; // obj == false for conditionals - case 2: - arguments[2] = _T; // Add root node to end of argument list - default: - arguments.length = 3; - } - if(arguments[1] === false) { // Do area-wide delete - var numberdeleted = 0; - var ret_array = []; - do { - numberdeleted=ret_array.length; - ret_array = ret_array.concat(_remove_subtree.apply(this, arguments)); - }while( numberdeleted != ret_array.length); - return ret_array; - } - else { // Delete a specific item - return(_remove_subtree.apply(this, arguments)); - } - }; - - /* non-recursive insert function - * [] = RTree.insert(rectangle, object to insert) - */ - this.insert = function(rect, obj) { - if(arguments.length < 2) - throw "Wrong number of arguments. RT.Insert requires at least a bounding rectangle and an object." - - return(_insert_subtree({x:rect.x,y:rect.y,w:rect.w,h:rect.h,leaf:obj}, _T)); - }; - - /* non-recursive delete function - * [deleted object] = RTree.remove(rectangle, [object to delete]) - */ + + for(var i = nodes.length-2; i>=0;i--) { + var l = nodes[i]; + if(l.x > nodes[highest_low_x].x ) highest_low_x = i; + else if(l.x+l.w < nodes[lowest_high_x].x+nodes[lowest_high_x].w) lowest_high_x = i; + if(l.y > nodes[highest_low_y].y ) highest_low_y = i; + else if(l.y+l.h < nodes[lowest_high_y].y+nodes[lowest_high_y].h) lowest_high_y = i; + } + var dx = Math.abs((nodes[lowest_high_x].x+nodes[lowest_high_x].w) - nodes[highest_low_x].x); + var dy = Math.abs((nodes[lowest_high_y].y+nodes[lowest_high_y].h) - nodes[highest_low_y].y); + if( dx > dy ) { + if(lowest_high_x > highest_low_x) { + t1 = nodes.splice(lowest_high_x, 1)[0]; + t2 = nodes.splice(highest_low_x, 1)[0]; + } else { + t2 = nodes.splice(highest_low_x, 1)[0]; + t1 = nodes.splice(lowest_high_x, 1)[0]; + } + } else { + if(lowest_high_y > highest_low_y) { + t1 = nodes.splice(lowest_high_y, 1)[0]; + t2 = nodes.splice(highest_low_y, 1)[0]; + } else { + t2 = nodes.splice(highest_low_y, 1)[0]; + t1 = nodes.splice(lowest_high_y, 1)[0]; + } + } + return([{x:t1.x, y:t1.y, w:t1.w, h:t1.h, nodes:[t1]}, + {x:t2.x, y:t2.y, w:t2.w, h:t2.h, nodes:[t2]} ]); + }; + + var _attach_data = function(node, more_tree){ + node.nodes = more_tree.nodes; + node.x = more_tree.x; node.y = more_tree.y; + node.w = more_tree.w; node.h = more_tree.h; + return(node); + }; + + /* non-recursive internal search function + * [ nodes | objects ] = _search_subtree(rectangle, [return node data], [array to fill], root to begin search at) + * @private + */ + var _search_subtree = function(rect, return_node, return_array, root) { + var hit_stack = []; // Contains the elements that overlap + + if(!RTree.Rectangle.overlap_rectangle(rect, root)) + return(return_array); + + var load_callback = function(local_tree, local_node){ + return(function(data) { + local_tree._attach_data(local_node, data); + }); + }; + + hit_stack.push(root.nodes); + + do { + var nodes = hit_stack.pop(); + + for(var i = nodes.length-1; i >= 0; i--) { + var ltree = nodes[i]; + if(RTree.Rectangle.overlap_rectangle(rect, ltree)) { + if("nodes" in ltree) { // Not a Leaf + hit_stack.push(ltree.nodes); + } else if("leaf" in ltree) { // A Leaf !! + if(!return_node) + return_array.push(ltree.leaf); + else + return_array.push(ltree); + }/* else if("load" in ltree) { // We need to fetch a URL for some more tree data + jQuery.getJSON(ltree.load, load_callback(this, ltree)); + delete ltree.load; + // i++; // Replay this entry + }*/ + } + } + }while(hit_stack.length > 0); + + return(return_array); + }; + + /* non-recursive internal insert function + * [] = _insert_subtree(rectangle, object to insert, root to begin insertion at) + * @private + */ + var _insert_subtree = function(node, root) { + var bc; // Best Current node + // Initial insertion is special because we resize the Tree and we don't + // care about any overflow (seriously, how can the first object overflow?) + if(root.nodes.length == 0) { + root.x = node.x; root.y = node.y; + root.w = node.w; root.h = node.h; + root.nodes.push(node); + return; + } + + // Find the best fitting leaf node + // choose_leaf returns an array of all tree levels (including root) + // that were traversed while trying to find the leaf + var tree_stack = _choose_leaf_subtree(node, root); + var ret_obj = node;//{x:rect.x,y:rect.y,w:rect.w,h:rect.h, leaf:obj}; + + // Walk back up the tree resizing and inserting as needed + do { + //handle the case of an empty node (from a split) + if(bc && "nodes" in bc && bc.nodes.length == 0) { + var pbc = bc; // Past bc + bc = tree_stack.pop(); + for(var t=0;t 0); + }; + + /* quick 'n' dirty function for plugins or manually drawing the tree + * [ tree ] = RTree.get_tree(): returns the raw tree data. useful for adding + * @public + * !! DEPRECATED !! + */ + this.get_tree = function() { + return _T; + }; + + /* quick 'n' dirty function for plugins or manually loading the tree + * [ tree ] = RTree.set_tree(sub-tree, where to attach): returns the raw tree data. useful for adding + * @public + * !! DEPRECATED !! + */ + this.set_tree = function(new_tree, where) { + if(!where) + where = _T; + return(_attach_data(where, new_tree)); + }; + + /* non-recursive search function + * [ nodes | objects ] = RTree.search(rectangle, [return node data], [array to fill]) + * @public + */ + this.search = function(rect, return_node, return_array) { + if(arguments.length < 1) + throw "Wrong number of arguments. RT.Search requires at least a bounding rectangle." + + switch(arguments.length) { + case 1: + arguments[1] = false;// Add an "return node" flag - may be removed in future + case 2: + arguments[2] = []; // Add an empty array to contain results + case 3: + arguments[3] = _T; // Add root node to end of argument list + default: + arguments.length = 4; + } + return(_search_subtree.apply(this, arguments)); + }; + + /* partially-recursive toJSON function + * [ string ] = RTree.toJSON([rectangle], [tree]) + * @public + */ + this.toJSON = function(rect, tree) { + var hit_stack = []; // Contains the elements that overlap + var count_stack = []; // Contains the elements that overlap + var return_stack = {}; // Contains the elements that overlap + var max_depth = 3; // This triggers recursion and tree-splitting + var current_depth = 1; + var return_string = ""; + + if(rect && !RTree.Rectangle.overlap_rectangle(rect, _T)) + return ""; + + if(!tree) { + count_stack.push(_T.nodes.length); + hit_stack.push(_T.nodes); + return_string += "var main_tree = {x:"+_T.x.toFixed()+",y:"+_T.y.toFixed()+",w:"+_T.w.toFixed()+",h:"+_T.h.toFixed()+",nodes:["; + } else { + max_depth += 4; + count_stack.push(tree.nodes.length); + hit_stack.push(tree.nodes); + return_string += "var main_tree = {x:"+tree.x.toFixed()+",y:"+tree.y.toFixed()+",w:"+tree.w.toFixed()+",h:"+tree.h.toFixed()+",nodes:["; + } + + do { + var nodes = hit_stack.pop(); + var i = count_stack.pop()-1; + + if(i >= 0 && i < nodes.length-1) + return_string += ","; + + while(i >= 0) { + var ltree = nodes[i]; + if(!rect || RTree.Rectangle.overlap_rectangle(rect, ltree)) { + if(ltree.nodes) { // Not a Leaf + if(current_depth >= max_depth) { + var len = return_stack.length; + var nam = _name_to_id("saved_subtree"); + return_string += "{x:"+ltree.x.toFixed()+",y:"+ltree.y.toFixed()+",w:"+ltree.w.toFixed()+",h:"+ltree.h.toFixed()+",load:'"+nam+".js'}"; + return_stack[nam] = this.toJSON(rect, ltree); + if(i > 0) + return_string += "," + } else { + return_string += "{x:"+ltree.x.toFixed()+",y:"+ltree.y.toFixed()+",w:"+ltree.w.toFixed()+",h:"+ltree.h.toFixed()+",nodes:["; + current_depth += 1; + count_stack.push(i); + hit_stack.push(nodes); + nodes = ltree.nodes; + i = ltree.nodes.length; + } + } else if(ltree.leaf) { // A Leaf !! + var data = ltree.leaf.toJSON ? ltree.leaf.toJSON() : JSON.stringify(ltree.leaf); + return_string += "{x:"+ltree.x.toFixed()+",y:"+ltree.y.toFixed()+",w:"+ltree.w.toFixed()+",h:"+ltree.h.toFixed()+",leaf:" + data + "}"; + if(i > 0) + return_string += "," + } else if(ltree.load) { // A load + return_string += "{x:"+ltree.x.toFixed()+",y:"+ltree.y.toFixed()+",w:"+ltree.w.toFixed()+",h:"+ltree.h.toFixed()+",load:'" + ltree.load + "'}"; + if(i > 0) + return_string += "," + } + } + i -= 1; + } + if(i < 0) { + return_string += "]}"; current_depth -= 1; + } + }while(hit_stack.length > 0); + + return_string+=";"; + + for(var my_key in return_stack) { + return_string += "\nvar " + my_key + " = function(){" + return_stack[my_key] + " return(main_tree);};"; + } + return(return_string); + }; + + /* non-recursive function that deletes a specific + * [ number ] = RTree.remove(rectangle, obj) + */ + this.remove = function(rect, obj) { + if(arguments.length < 1) + throw "Wrong number of arguments. RT.remove requires at least a bounding rectangle." + + switch(arguments.length) { + case 1: + arguments[1] = false; // obj == false for conditionals + case 2: + arguments[2] = _T; // Add root node to end of argument list + default: + arguments.length = 3; + } + if(arguments[1] === false) { // Do area-wide delete + var numberdeleted = 0; + var ret_array = []; + do { + numberdeleted=ret_array.length; + ret_array = ret_array.concat(_remove_subtree.apply(this, arguments)); + }while( numberdeleted != ret_array.length); + return ret_array; + } + else { // Delete a specific item + return(_remove_subtree.apply(this, arguments)); + } + }; + + /* non-recursive insert function + * [] = RTree.insert(rectangle, object to insert) + */ + this.insert = function(rect, obj) { + if(arguments.length < 2) + throw "Wrong number of arguments. RT.Insert requires at least a bounding rectangle and an object." + + return(_insert_subtree({x:rect.x,y:rect.y,w:rect.w,h:rect.h,leaf:obj}, _T)); + }; + + /* non-recursive delete function + * [deleted object] = RTree.remove(rectangle, [object to delete]) + */ //End of RTree }; @@ -602,60 +602,60 @@ var RTree = function(width){ /* Rectangle - Generic rectangle object - Not yet used */ RTree.Rectangle = function(ix, iy, iw, ih) { // new Rectangle(bounds) or new Rectangle(x, y, w, h) - var x, x2, y, y2, w, h; + var x, x2, y, y2, w, h; + + if(ix.x) { + x = ix.x; y = ix.y; + if(ix.w !== 0 && !ix.w && ix.x2){ + w = ix.x2-ix.x; h = ix.y2-ix.y; + } else { + w = ix.w; h = ix.h; + } + x2 = x + w; y2 = y + h; // For extra fastitude + } else { + x = ix; y = iy; w = iw; h = ih; + x2 = x + w; y2 = y + h; // For extra fastitude + } + + this.x1 = this.x = function(){return x;}; + this.y1 = this.y = function(){return y;}; + this.x2 = function(){return x2;}; + this.y2 = function(){return y2;}; + this.w = function(){return w;}; + this.h = function(){return h;}; + + this.toJSON = function() { + return('{"x":'+x.toString()+', "y":'+y.toString()+', "w":'+w.toString()+', "h":'+h.toString()+'}'); + }; + + this.overlap = function(a) { + return(this.x() < a.x2() && this.x2() > a.x() && this.y() < a.y2() && this.y2() > a.y()); + }; + this.expand = function(a) { + var nx = Math.min(this.x(), a.x()); + var ny = Math.min(this.y(), a.y()); + w = Math.max(this.x2(), a.x2()) - nx; + h = Math.max(this.y2(), a.y2()) - ny; + x = nx; y = ny; + return(this); + }; + + this.setRect = function(ix, iy, iw, ih) { + var x, x2, y, y2, w, h; if(ix.x) { - x = ix.x; y = ix.y; - if(ix.w !== 0 && !ix.w && ix.x2){ - w = ix.x2-ix.x; h = ix.y2-ix.y; - } else { - w = ix.w; h = ix.h; - } - x2 = x + w; y2 = y + h; // For extra fastitude - } else { - x = ix; y = iy; w = iw; h = ih; - x2 = x + w; y2 = y + h; // For extra fastitude - } - - this.x1 = this.x = function(){return x;}; - this.y1 = this.y = function(){return y;}; - this.x2 = function(){return x2;}; - this.y2 = function(){return y2;}; - this.w = function(){return w;}; - this.h = function(){return h;}; - - this.toJSON = function() { - return('{"x":'+x.toString()+', "y":'+y.toString()+', "w":'+w.toString()+', "h":'+h.toString()+'}'); - }; - - this.overlap = function(a) { - return(this.x() < a.x2() && this.x2() > a.x() && this.y() < a.y2() && this.y2() > a.y()); - }; - - this.expand = function(a) { - var nx = Math.min(this.x(), a.x()); - var ny = Math.min(this.y(), a.y()); - w = Math.max(this.x2(), a.x2()) - nx; - h = Math.max(this.y2(), a.y2()) - ny; - x = nx; y = ny; - return(this); - }; - - this.setRect = function(ix, iy, iw, ih) { - var x, x2, y, y2, w, h; - if(ix.x) { - x = ix.x; y = ix.y; - if(ix.w !== 0 && !ix.w && ix.x2) { - w = ix.x2-ix.x; h = ix.y2-ix.y; - } else { - w = ix.w; h = ix.h; - } - x2 = x + w; y2 = y + h; // For extra fastitude - } else { - x = ix; y = iy; w = iw; h = ih; - x2 = x + w; y2 = y + h; // For extra fastitude - } - }; + x = ix.x; y = ix.y; + if(ix.w !== 0 && !ix.w && ix.x2) { + w = ix.x2-ix.x; h = ix.y2-ix.y; + } else { + w = ix.w; h = ix.h; + } + x2 = x + w; y2 = y + h; // For extra fastitude + } else { + x = ix; y = iy; w = iw; h = ih; + x2 = x + w; y2 = y + h; // For extra fastitude + } + }; //End of RTree.Rectangle }; @@ -665,7 +665,7 @@ RTree.Rectangle = function(ix, iy, iw, ih) { // new Rectangle(bounds) or new Rec * @static function */ RTree.Rectangle.overlap_rectangle = function(a, b) { - return(a.x < (b.x+b.w) && (a.x+a.w) > b.x && a.y < (b.y+b.h) && (a.y+a.h) > b.y); + return(a.x < (b.x+b.w) && (a.x+a.w) > b.x && a.y < (b.y+b.h) && (a.y+a.h) > b.y); }; /* returns true if rectangle a is contained in rectangle b @@ -673,20 +673,20 @@ RTree.Rectangle.overlap_rectangle = function(a, b) { * @static function */ RTree.Rectangle.contains_rectangle = function(a, b) { - return((a.x+a.w) <= (b.x+b.w) && a.x >= b.x && (a.y+a.h) <= (b.y+b.h) && a.y >= b.y); + return((a.x+a.w) <= (b.x+b.w) && a.x >= b.x && (a.y+a.h) <= (b.y+b.h) && a.y >= b.y); }; /* expands rectangle A to include rectangle B, rectangle B is untouched * [ rectangle a ] = expand_rectangle(rectangle a, rectangle b) * @static function */ -RTree.Rectangle.expand_rectangle = function(a, b) { - var nx = Math.min(a.x, b.x); - var ny = Math.min(a.y, b.y); - a.w = Math.max(a.x+a.w, b.x+b.w) - nx; - a.h = Math.max(a.y+a.h, b.y+b.h) - ny; - a.x = nx; a.y = ny; - return(a); +RTree.Rectangle.expand_rectangle = function(a, b) { + var nx = Math.min(a.x, b.x); + var ny = Math.min(a.y, b.y); + a.w = Math.max(a.x+a.w, b.x+b.w) - nx; + a.h = Math.max(a.y+a.h, b.y+b.h) - ny; + a.x = nx; a.y = ny; + return(a); }; /* generates a minimally bounding rectangle for all rectangles in @@ -696,16 +696,16 @@ RTree.Rectangle.expand_rectangle = function(a, b) { * @static function */ RTree.Rectangle.make_MBR = function(nodes, rect) { - if(nodes.length < 1) - return({x:0, y:0, w:0, h:0}); - //throw "make_MBR: nodes must contain at least one rectangle!"; - if(!rect) - rect = {x:nodes[0].x, y:nodes[0].y, w:nodes[0].w, h:nodes[0].h}; - else - rect.x = nodes[0].x; rect.y = nodes[0].y; rect.w = nodes[0].w; rect.h = nodes[0].h; - - for(var i = nodes.length-1; i>0; i--) - RTree.Rectangle.expand_rectangle(rect, nodes[i]); - - return(rect); + if(nodes.length < 1) + return({x:0, y:0, w:0, h:0}); + //throw "make_MBR: nodes must contain at least one rectangle!"; + if(!rect) + rect = {x:nodes[0].x, y:nodes[0].y, w:nodes[0].w, h:nodes[0].h}; + else + rect.x = nodes[0].x; rect.y = nodes[0].y; rect.w = nodes[0].w; rect.h = nodes[0].h; + + for(var i = nodes.length-1; i>0; i--) + RTree.Rectangle.expand_rectangle(rect, nodes[i]); + + return(rect); }; \ No newline at end of file From ddeb11d464941aaa13203db6b9dd61c50edd47b9 Mon Sep 17 00:00:00 2001 From: Simon Brent Date: Tue, 23 Feb 2016 11:18:29 +0000 Subject: [PATCH 12/59] Added comment about line of code that causes horrible bugs --- js/Track.js | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/js/Track.js b/js/Track.js index d0fbeebe..fb3bb56d 100644 --- a/js/Track.js +++ b/js/Track.js @@ -113,6 +113,33 @@ Genoverse.Track = Base.extend({ } } + /* + * Abandon all hope! If you've tracked a bug to this line of code, be afraid. + * It will almost certainly be due to the wonderful way the javascript objects work. + * + * Consider the following: + * + * var Obj = function () {}; + * + * Obj.prototype = { + * scalar : 1, + * array : [ 1, 2, 3 ], + * hash : { a: 1, b : 2 } + * }; + * + * var x = new Obj(); + * + * x.scalar = 10; + * x.array[0] = 10; + * x.hash.a = 10; + * + * var y = new Obj(); + * + * y is now { scalar: 1, array: [ 10, 2, 3 ], hash: { a: 10, b : 2 } }, since memory locations of objects in prototypes are shared. + * + * This has been the cause of numerous Genoverse bugs in the past, due to property sharing between different tracks, models, views, and controllers. + * See also the line a bit further down: this[obj].constructor.extend(mvcSettings[obj].func); + */ this.extend(trackSettings); for (i = 0; i < 3; i++) { @@ -136,6 +163,7 @@ Genoverse.Track = Base.extend({ } } + // Abandon all hope! (see above) this[obj].constructor.extend(mvcSettings[obj].func); if (obj === 'model' && typeof test.url !== 'undefined') { From 699ff9e8428f2b8dad21ea14a28158b7e7c7022e Mon Sep 17 00:00:00 2001 From: Simon Brent Date: Tue, 23 Feb 2016 11:23:53 +0000 Subject: [PATCH 13/59] Improvements to constructor and destructor --- js/Genoverse.js | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/js/Genoverse.js b/js/Genoverse.js index 075b3248..7186b5c1 100644 --- a/js/Genoverse.js +++ b/js/Genoverse.js @@ -33,6 +33,8 @@ var Genoverse = Base.extend({ return this.die('Your browser does not support this functionality'); } + config = config || {}; + config.container = $(config.container); // Make sure container is a jquery object, jquery recognises itself automatically if (!(config.container && config.container.length)) { @@ -1334,6 +1336,11 @@ var Genoverse = Base.extend({ destroy: function () { this.onTracks('destructor'); (this.superContainer || this.container).empty(); + + if (this.zoomInHighlight) { + this.zoomInHighlight.add(this.zoomOutHighlight).remove(); + } + $(window).add(document).off(this.eventNamespace); for (var key in this) { From c8c54e295e7ee56a53991107b2d0acfc19b9954d Mon Sep 17 00:00:00 2001 From: Simon Brent Date: Tue, 23 Feb 2016 11:25:03 +0000 Subject: [PATCH 14/59] Added an interstitial menu when you click on more than one feature --- js/Genoverse.js | 105 +++++++++++++++++++------- js/Track/Controller/Sequence.js | 34 +++------ js/Track/library/HighlightRegion.js | 54 +++++++++++--- js/genoverse.combined.js | 110 ++++++++++++++++------------ js/genoverse.combined.nojquery.js | 110 ++++++++++++++++------------ 5 files changed, 261 insertions(+), 152 deletions(-) diff --git a/js/Genoverse.js b/js/Genoverse.js index 7186b5c1..39ca7fc6 100644 --- a/js/Genoverse.js +++ b/js/Genoverse.js @@ -1129,37 +1129,86 @@ var Genoverse = Base.extend({ } }), - makeMenu: function (feature, event, track) { - if (!feature.menuEl) { - var browser = this; - var menu = this.menuTemplate.clone(true).data({ browser: this, feature: feature }); - var content = $('.gv-menu-content', menu).remove(); - var loading = $('.gv-menu-loading', menu); - var getMenu = track ? track.controller.populateMenu(feature) : feature; - var isDeferred = typeof getMenu === 'object' && typeof getMenu.promise === 'function'; - var i, j, table, el, start, end, linkData, key, columns, colspan; + makeMenu: function (features, event, track) { + if (!features) { + return false; + } - function focus() { - var data = $(this).data(); - var length = data.end - data.start + 1; - var context = Math.max(Math.round(length / 4), 25); + if (!$.isArray(features)) { + features = [ features ]; + } - browser.moveTo(data.start - context, data.end + context, true); + if (features.length === 0) { + return false; + } else if (features.length === 1) { + return this.makeFeatureMenu(features[0], event, track); + } - return false; - } + var browser = this; + var menu = this.menuTemplate.clone(true).data({ browser: this }); + var table = $('.gv-menu-content', menu).addClass('gv-menu-content-first').find('table'); - function highlight() { - browser.addHighlight($(this).data()); + $('.gv-focus, .gv-highlight, .gv-menu-loading', menu).remove(); + $('.gv-title', menu).html(features.length + ' features'); + + $.each(features.sort(function (a, b) { return a.start - b.start; }), function (i, feature) { + var location = (feature.chr || browser.chr) + ':' + feature.start + (feature.end === feature.start ? '' : '-' + feature.end); + var title = feature.menuLabel || feature.name || ($.isArray(feature.label) ? feature.label.join(' ') : feature.label) || (feature.id + ''); + + $('').html(title.match(location) ? title : (location + ' ' + title)).on('click', function (e) { + browser.makeFeatureMenu(feature, e, track); return false; - } + }).appendTo($('').appendTo($('').appendTo(table))); + }); + + menu.appendTo(this.superContainer || this.container).show(); + + if (event) { + menu.css({ left: 0, top: 0 }).position({ of: event, my: 'left top', collision: 'flipfit' }); + } + + this.menus = this.menus.add(menu); + + if (track) { + track.prop('menus', track.prop('menus').add(menu)); + } + + return menu; + }, + + makeFeatureMenu: function (feature, e, track) { + var browser = this; + var container = this.superContainer || this.container; + var menu, content, loading, getMenu, isDeferred, i, j, el, start, end, linkData, key, columns, colspan; + + function focus() { + var data = $(this).data(); + var length = data.end - data.start + 1; + var context = Math.max(Math.round(length / 4), 25); + + browser.moveTo(data.start - context, data.end + context, true); + + return false; + } + + function highlight() { + browser.addHighlight($(this).data()); + return false; + } + + if (!feature.menuEl) { + menu = browser.menuTemplate.clone(true).data({ browser: browser, feature: feature }); + content = $('.gv-menu-content', menu).remove(); + loading = $('.gv-menu-loading', menu); + getMenu = track ? track.controller.populateMenu(feature) : feature; + isDeferred = typeof getMenu === 'object' && typeof getMenu.promise === 'function'; if (isDeferred) { loading.show(); } $.when(getMenu).done(function (properties) { - if (Object.prototype.toString.call(properties) !== '[object Array]') { + if (!$.isArray(properties)) { properties = [ properties ]; } @@ -1168,7 +1217,7 @@ var Genoverse = Base.extend({ el = content.clone().addClass(i ? '' : 'gv-menu-content-first').appendTo(menu); start = parseInt(typeof properties[i].start !== 'undefined' ? properties[i].start : feature.start, 10); end = parseInt(typeof properties[i].end !== 'undefined' ? properties[i].end : feature.end, 10); - columns = Math.max.apply(Math, $.map(properties[i], function (v) { return Object.prototype.toString.call(v) === '[object Array]' ? v.length : 1; })); + columns = Math.max.apply(Math, $.map(properties[i], function (v) { return $.isArray(v) ? v.length : 1; })); $('.gv-title', el)[properties[i].title ? 'html' : 'remove'](properties[i].title); @@ -1191,7 +1240,7 @@ var Genoverse = Base.extend({ table += '' + key + ''; if (!colspan) { - if (Object.prototype.toString.call(properties[i][key]) === '[object Array]') { + if ($.isArray(properties[i][key])) { for (j = 0; j < properties[i][key].length; j++) { table += '' + properties[i][key][j] + ''; } @@ -1206,7 +1255,7 @@ var Genoverse = Base.extend({ } } - $('table', el).html(table); + $('table', el)[table ? 'html' : 'remove'](table); } if (isDeferred) { @@ -1218,12 +1267,12 @@ var Genoverse = Base.extend({ menu.addClass(track.id).data('track', track); } - feature.menuEl = menu.appendTo(this.superContainer || this.container); + feature.menuEl = menu.appendTo(container); } else { - feature.menuEl.appendTo(this.superContainer || this.container); // Move the menu to the end of the container again, so that it will always be on top of other menus + feature.menuEl.appendTo(container); // Move the menu to the end of the container again, so that it will always be on top of other menus } - this.menus = this.menus.add(feature.menuEl); + browser.menus = browser.menus.add(feature.menuEl); if (track) { track.prop('menus', track.prop('menus').add(feature.menuEl)); @@ -1231,8 +1280,8 @@ var Genoverse = Base.extend({ feature.menuEl.show(); // Must show before positioning, else position will be wrong - if (event) { - feature.menuEl.css({ left: 0, top: 0 }).position({ of: event, my: 'left top', collision: 'flipfit' }); + if (e) { + feature.menuEl.css({ left: 0, top: 0 }).position({ of: e, my: 'left top', collision: 'flipfit' }); } return feature.menuEl; diff --git a/js/Track/Controller/Sequence.js b/js/Track/Controller/Sequence.js index a294139f..10a088d0 100644 --- a/js/Track/Controller/Sequence.js +++ b/js/Track/Controller/Sequence.js @@ -1,27 +1,15 @@ Genoverse.Track.Controller.Sequence = Genoverse.Track.Controller.extend({ - click: function (e) { - var x = e.pageX - this.container.parent().offset().left + this.browser.scaledStart; - var y = e.pageY - $(e.target).offset().top; - var features = this[e.target.className === 'gv-labels' ? 'labelPositions' : 'featurePositions'].search({ x: x, y: y, w: 1, h: 1 }).sort(function (a, b) { return a.sort - b.sort; }); - var seq; - - if (features.length) { - x = Math.floor(x / this.scale); - - for (var i = 0; i < features.length; i++) { - if (features[i].alt_allele) { - return this.browser.makeMenu(features[i], e, this.track); - } - - seq = features[i].sequence.charAt(x - features[i].start); - - if (seq) { - return this.browser.makeMenu({ - title : seq, - Location : this.browser.chr + ':' + x - }, e, this.track); - } - } + getClickedFeatures: function (x, y) { + return this.makeSeqFeatureMenu(this.base(x, y)[0], Math.floor(x / this.scale)); + }, + + makeSeqFeatureMenu: function (feature, pos) { + feature.featureMenus = feature.featureMenus || {}; + feature.featureMenus[pos] = feature.featureMenus[pos] || { + title : feature.sequence.charAt(pos - feature.start), + Location : this.browser.chr + ':' + pos } + + return feature.featureMenus[pos].title ? feature.featureMenus[pos] : undefined; } }); diff --git a/js/Track/library/HighlightRegion.js b/js/Track/library/HighlightRegion.js index 718276fc..9a4606db 100644 --- a/js/Track/library/HighlightRegion.js +++ b/js/Track/library/HighlightRegion.js @@ -103,18 +103,29 @@ Genoverse.Track.HighlightRegion = Genoverse.Track.extend({ img.height(this.browser.wrapper.outerHeight(true)); }, - populateMenu: function (feature) { - var location = feature.start + '-' + feature.end; - var menu = { - title: feature.label ? feature.label[0] : location, - start: false - }; + populateMenu: function (features) { + var menu = []; + var location, m; - menu[menu.title === location ? 'title' : 'Location'] = this.browser.chr + ':' + location; + if (features.length > 1) { + menu.push({ title: 'Highlights' }); + } + + for (var i = 0; i < features.length; i++) { + location = features[i].start + '-' + features[i].end; + m = { + title: features[i].label ? features[i].label[0] : location, + start: false + }; + + m[m.title === location ? 'title' : 'Location'] = this.browser.chr + ':' + location; - if (feature.removable !== false) { - menu['Remove this highlight'] = ''; - menu['Remove all highlights'] = ''; + if (features[i].removable !== false) { + m['Remove this highlight'] = ''; + m['Remove all highlights'] = ''; + } + + menu.push(m); } return menu; @@ -131,7 +142,8 @@ Genoverse.Track.HighlightRegion = Genoverse.Track.extend({ var track = this.track; menuEl.find('.gv-remove-highlight').on('click', function () { - track.removeHighlights([ menuEl.data('feature') ]); + var id = $(this).data('id'); + track.removeHighlights($.grep(menuEl.data('feature'), function (f) { return f.id === id; })); return false; }); @@ -142,6 +154,26 @@ Genoverse.Track.HighlightRegion = Genoverse.Track.extend({ menuEl.data('highlightEvents', true); } + }, + + getClickedFeatures: function (x, y, target) { + var seen = {}; + var scale = this.scale; + var features = $.grep( + // feature positions + this.featurePositions.search({ x: x, y: y, w: 1, h: 1 }).concat( + // plus label positions where the labels are visible + $.grep(this.labelPositions.search({ x: x, y: y, w: 1, h: 1 }), function (f) { + return f.position[scale].label.visible !== false; + }) + ), function (f) { + // with duplicates removed + var rtn = !seen[f.id]; + seen[f.id] = true; + return rtn; + }); + + return features.length ? [ this.model.sortFeatures(features) ] : false; } }), diff --git a/js/genoverse.combined.js b/js/genoverse.combined.js index 3c1808b3..645f5b11 100644 --- a/js/genoverse.combined.js +++ b/js/genoverse.combined.js @@ -4497,38 +4497,38 @@ Genoverse.Track.Static = Genoverse.Track.extend({ Genoverse.Track.Controller.Stranded = Genoverse.Track.Controller.extend({ constructor: function (properties) { this.base(properties); - + if (typeof this._makeImage === 'function') { return; } - + var strand = this.prop('strand'); var featureStrand = this.prop('featureStrand'); - + if (strand === -1) { this._makeImage = this.track.makeReverseImage ? $.proxy(this.track.makeReverseImage, this) : this.makeImage; this.makeImage = $.noop; } else { strand = this.prop('strand', 1); - + this._makeImage = this.makeImage; this.makeImage = this.makeForwardImage; this.reverseTrack = this.browser.addTrack(this.track.constructor.extend({ strand: -1, url: false, forwardTrack: this }), this.browser.tracks.length).controller; } - + if (!featureStrand) { this.prop('featureStrand', strand); } - + if (!(this.model instanceof Genoverse.Track.Model.Stranded)) { this.track.lengthMap.push([ -9e99, { model: Genoverse.Track.Model.Stranded }]); } }, - + makeForwardImage: function (params) { var reverseTrack = this.prop('reverseTrack'); var rtn = this._makeImage(params); - + if (rtn && typeof rtn.done === 'function') { rtn.done(function () { reverseTrack._makeImage(params, rtn); @@ -4537,14 +4537,14 @@ Genoverse.Track.Controller.Stranded = Genoverse.Track.Controller.extend({ reverseTrack._makeImage(params, rtn); } }, - + destroy: function () { if (this.removing) { return; } - + this.removing = true; - + this.browser.removeTrack((this.prop('forwardTrack') || this.prop('reverseTrack')).track); this.base(); } @@ -4576,30 +4576,18 @@ Genoverse.Track.Model.Stranded = Genoverse.Track.Model.extend({ Genoverse.Track.Controller.Sequence = Genoverse.Track.Controller.extend({ - click: function (e) { - var x = e.pageX - this.container.parent().offset().left + this.browser.scaledStart; - var y = e.pageY - $(e.target).offset().top; - var features = this[e.target.className === 'gv-labels' ? 'labelPositions' : 'featurePositions'].search({ x: x, y: y, w: 1, h: 1 }).sort(function (a, b) { return a.sort - b.sort; }); - var seq; - - if (features.length) { - x = Math.floor(x / this.scale); - - for (var i = 0; i < features.length; i++) { - if (features[i].alt_allele) { - return this.browser.makeMenu(features[i], e, this.track); - } - - seq = features[i].sequence.charAt(x - features[i].start); - - if (seq) { - return this.browser.makeMenu({ - title : seq, - Location : this.browser.chr + ':' + x - }, e, this.track); - } - } + getClickedFeatures: function (x, y) { + return this.makeSeqFeatureMenu(this.base(x, y)[0], Math.floor(x / this.scale)); + }, + + makeSeqFeatureMenu: function (feature, pos) { + feature.featureMenus = feature.featureMenus || {}; + feature.featureMenus[pos] = feature.featureMenus[pos] || { + title : feature.sequence.charAt(pos - feature.start), + Location : this.browser.chr + ':' + pos } + + return feature.featureMenus[pos].title ? feature.featureMenus[pos] : undefined; } }); @@ -6029,18 +6017,29 @@ Genoverse.Track.HighlightRegion = Genoverse.Track.extend({ img.height(this.browser.wrapper.outerHeight(true)); }, - populateMenu: function (feature) { - var location = feature.start + '-' + feature.end; - var menu = { - title: feature.label ? feature.label[0] : location, - start: false - }; + populateMenu: function (features) { + var menu = []; + var location, m; - menu[menu.title === location ? 'title' : 'Location'] = this.browser.chr + ':' + location; + if (features.length > 1) { + menu.push({ title: 'Highlights' }); + } + + for (var i = 0; i < features.length; i++) { + location = features[i].start + '-' + features[i].end; + m = { + title: features[i].label ? features[i].label[0] : location, + start: false + }; + + m[m.title === location ? 'title' : 'Location'] = this.browser.chr + ':' + location; - if (feature.removable !== false) { - menu['Remove this highlight'] = ''; - menu['Remove all highlights'] = ''; + if (features[i].removable !== false) { + m['Remove this highlight'] = ''; + m['Remove all highlights'] = ''; + } + + menu.push(m); } return menu; @@ -6057,7 +6056,8 @@ Genoverse.Track.HighlightRegion = Genoverse.Track.extend({ var track = this.track; menuEl.find('.gv-remove-highlight').on('click', function () { - track.removeHighlights([ menuEl.data('feature') ]); + var id = $(this).data('id'); + track.removeHighlights($.grep(menuEl.data('feature'), function (f) { return f.id === id; })); return false; }); @@ -6068,6 +6068,26 @@ Genoverse.Track.HighlightRegion = Genoverse.Track.extend({ menuEl.data('highlightEvents', true); } + }, + + getClickedFeatures: function (x, y, target) { + var seen = {}; + var scale = this.scale; + var features = $.grep( + // feature positions + this.featurePositions.search({ x: x, y: y, w: 1, h: 1 }).concat( + // plus label positions where the labels are visible + $.grep(this.labelPositions.search({ x: x, y: y, w: 1, h: 1 }), function (f) { + return f.position[scale].label.visible !== false; + }) + ), function (f) { + // with duplicates removed + var rtn = !seen[f.id]; + seen[f.id] = true; + return rtn; + }); + + return features.length ? [ this.model.sortFeatures(features) ] : false; } }), diff --git a/js/genoverse.combined.nojquery.js b/js/genoverse.combined.nojquery.js index 0ad12977..5a5acdf9 100644 --- a/js/genoverse.combined.nojquery.js +++ b/js/genoverse.combined.nojquery.js @@ -4492,38 +4492,38 @@ Genoverse.Track.Static = Genoverse.Track.extend({ Genoverse.Track.Controller.Stranded = Genoverse.Track.Controller.extend({ constructor: function (properties) { this.base(properties); - + if (typeof this._makeImage === 'function') { return; } - + var strand = this.prop('strand'); var featureStrand = this.prop('featureStrand'); - + if (strand === -1) { this._makeImage = this.track.makeReverseImage ? $.proxy(this.track.makeReverseImage, this) : this.makeImage; this.makeImage = $.noop; } else { strand = this.prop('strand', 1); - + this._makeImage = this.makeImage; this.makeImage = this.makeForwardImage; this.reverseTrack = this.browser.addTrack(this.track.constructor.extend({ strand: -1, url: false, forwardTrack: this }), this.browser.tracks.length).controller; } - + if (!featureStrand) { this.prop('featureStrand', strand); } - + if (!(this.model instanceof Genoverse.Track.Model.Stranded)) { this.track.lengthMap.push([ -9e99, { model: Genoverse.Track.Model.Stranded }]); } }, - + makeForwardImage: function (params) { var reverseTrack = this.prop('reverseTrack'); var rtn = this._makeImage(params); - + if (rtn && typeof rtn.done === 'function') { rtn.done(function () { reverseTrack._makeImage(params, rtn); @@ -4532,14 +4532,14 @@ Genoverse.Track.Controller.Stranded = Genoverse.Track.Controller.extend({ reverseTrack._makeImage(params, rtn); } }, - + destroy: function () { if (this.removing) { return; } - + this.removing = true; - + this.browser.removeTrack((this.prop('forwardTrack') || this.prop('reverseTrack')).track); this.base(); } @@ -4571,30 +4571,18 @@ Genoverse.Track.Model.Stranded = Genoverse.Track.Model.extend({ Genoverse.Track.Controller.Sequence = Genoverse.Track.Controller.extend({ - click: function (e) { - var x = e.pageX - this.container.parent().offset().left + this.browser.scaledStart; - var y = e.pageY - $(e.target).offset().top; - var features = this[e.target.className === 'gv-labels' ? 'labelPositions' : 'featurePositions'].search({ x: x, y: y, w: 1, h: 1 }).sort(function (a, b) { return a.sort - b.sort; }); - var seq; - - if (features.length) { - x = Math.floor(x / this.scale); - - for (var i = 0; i < features.length; i++) { - if (features[i].alt_allele) { - return this.browser.makeMenu(features[i], e, this.track); - } - - seq = features[i].sequence.charAt(x - features[i].start); - - if (seq) { - return this.browser.makeMenu({ - title : seq, - Location : this.browser.chr + ':' + x - }, e, this.track); - } - } + getClickedFeatures: function (x, y) { + return this.makeSeqFeatureMenu(this.base(x, y)[0], Math.floor(x / this.scale)); + }, + + makeSeqFeatureMenu: function (feature, pos) { + feature.featureMenus = feature.featureMenus || {}; + feature.featureMenus[pos] = feature.featureMenus[pos] || { + title : feature.sequence.charAt(pos - feature.start), + Location : this.browser.chr + ':' + pos } + + return feature.featureMenus[pos].title ? feature.featureMenus[pos] : undefined; } }); @@ -6024,18 +6012,29 @@ Genoverse.Track.HighlightRegion = Genoverse.Track.extend({ img.height(this.browser.wrapper.outerHeight(true)); }, - populateMenu: function (feature) { - var location = feature.start + '-' + feature.end; - var menu = { - title: feature.label ? feature.label[0] : location, - start: false - }; + populateMenu: function (features) { + var menu = []; + var location, m; - menu[menu.title === location ? 'title' : 'Location'] = this.browser.chr + ':' + location; + if (features.length > 1) { + menu.push({ title: 'Highlights' }); + } + + for (var i = 0; i < features.length; i++) { + location = features[i].start + '-' + features[i].end; + m = { + title: features[i].label ? features[i].label[0] : location, + start: false + }; + + m[m.title === location ? 'title' : 'Location'] = this.browser.chr + ':' + location; - if (feature.removable !== false) { - menu['Remove this highlight'] = ''; - menu['Remove all highlights'] = ''; + if (features[i].removable !== false) { + m['Remove this highlight'] = ''; + m['Remove all highlights'] = ''; + } + + menu.push(m); } return menu; @@ -6052,7 +6051,8 @@ Genoverse.Track.HighlightRegion = Genoverse.Track.extend({ var track = this.track; menuEl.find('.gv-remove-highlight').on('click', function () { - track.removeHighlights([ menuEl.data('feature') ]); + var id = $(this).data('id'); + track.removeHighlights($.grep(menuEl.data('feature'), function (f) { return f.id === id; })); return false; }); @@ -6063,6 +6063,26 @@ Genoverse.Track.HighlightRegion = Genoverse.Track.extend({ menuEl.data('highlightEvents', true); } + }, + + getClickedFeatures: function (x, y, target) { + var seen = {}; + var scale = this.scale; + var features = $.grep( + // feature positions + this.featurePositions.search({ x: x, y: y, w: 1, h: 1 }).concat( + // plus label positions where the labels are visible + $.grep(this.labelPositions.search({ x: x, y: y, w: 1, h: 1 }), function (f) { + return f.position[scale].label.visible !== false; + }) + ), function (f) { + // with duplicates removed + var rtn = !seen[f.id]; + seen[f.id] = true; + return rtn; + }); + + return features.length ? [ this.model.sortFeatures(features) ] : false; } }), From 95b701b41d02f4f63cf796feb73d2eea6cb4c2ac Mon Sep 17 00:00:00 2001 From: Simon Brent Date: Tue, 23 Feb 2016 11:32:23 +0000 Subject: [PATCH 15/59] Stop showing karyotype tooltip when dragging/resizing --- js/plugins/karyotype.js | 40 ++++++++++++++++++++++------------------ 1 file changed, 22 insertions(+), 18 deletions(-) diff --git a/js/plugins/karyotype.js b/js/plugins/karyotype.js index 983fe555..8185e3dc 100644 --- a/js/plugins/karyotype.js +++ b/js/plugins/karyotype.js @@ -31,18 +31,15 @@ Genoverse.Plugins.karyotype = function () { if (!this.browser.parent.isStatic) { this.browser.parent.moveTo(f.start, f.end, true); } - } else { - if (this.hoverFeature !== f) { - this.container.tipsy('hide'); - - if (f.label) { - var left = offset + f.position[this.scale].start + f.position[this.scale].width / 2; - - this.container.attr('title', f.label[0]).tipsy({ trigger: 'manual', container: 'body' }).tipsy('show').data('tipsy').$tip.css('left', function () { return left - $(this).width() / 2; }); - } + } else if (this.hoverFeature !== f && !this.browser.hideTooltip) { + this.container.tipsy('hide'); - this.hoverFeature = f; + if (f.label) { + var left = offset + f.position[this.scale].start + f.position[this.scale].width / 2; + this.container.attr('title', f.label[0]).tipsy({ trigger: 'manual', container: 'body' }).tipsy('show').data('tipsy').$tip.css('left', function () { return left - $(this).width() / 2; }); } + + this.hoverFeature = f; } } }, @@ -53,8 +50,8 @@ Genoverse.Plugins.karyotype = function () { this.base(); this.container.on({ - mousemove : function (e) { track.click(e); }, - mouseout : function (e) { + mousemove : function (e) { track.click(e); }, + mouseout : function (e) { if (track.browser.viewPoint.is(e.relatedTarget) || track.browser.viewPoint.find(e.relatedTarget).length) { return true; } @@ -94,10 +91,8 @@ Genoverse.Plugins.karyotype = function () { } this.viewPoint = $('
').appendTo(container).children().on({ - mousemove: function (e) { - karyotype.track.controller.click(e); - }, - mouseout: function (e) { + mousemove : function (e) { karyotype.track.controller.click(e); }, + mouseout : function (e) { var el = $(e.relatedTarget); if (karyotype.viewPoint.is(el) || karyotype.viewPoint.find(el).length || (el.prop('nodeName') === 'IMG' && el.parent().is(karyotype.track.prop('imgContainers')[0]))) { @@ -110,7 +105,14 @@ Genoverse.Plugins.karyotype = function () { }); if (!parent.isStatic) { + function hideTooltip() { + karyotype.hideTooltip = true; + karyotype.track.prop('container').tipsy('hide'); + } + function updateLocation(e, ui) { + karyotype.hideTooltip = false; + if (e.type === 'resizestop') { var axis = $(this).data('ui-resizable').axis; @@ -129,10 +131,12 @@ Genoverse.Plugins.karyotype = function () { this.viewPoint.draggable({ axis : 'x', containment : this.wrapper, + start : hideTooltip, stop : updateLocation }).resizable({ handles : 'e, w', containment : 'parent', + start : hideTooltip, stop : updateLocation, resize : function (e, ui) { ui.element.css('left', Math.max(0, ui.position.left)); @@ -148,8 +152,8 @@ Genoverse.Plugins.karyotype = function () { }, updatePosition: function () { - var left = this.width * this.parent.start / this.chromosomeSize; - var width = (this.width * this.parent.end / this.chromosomeSize) - left; + var left = this.parent.start * this.scale; + var width = (this.parent.end * this.scale) - left; this.viewPoint.css({ left: left, width: width }); } From b9e1002d9e5440ce02993c7bd9eebbc8050069a5 Mon Sep 17 00:00:00 2001 From: Simon Brent Date: Tue, 23 Feb 2016 11:35:06 +0000 Subject: [PATCH 16/59] Added clickTolerance when getting feature menus, to make tiny features easier to hit --- js/Track/Controller.js | 28 ++++++++++++++++++++------ js/genoverse.combined.js | 33 +++++++++++++++++++++++-------- js/genoverse.combined.nojquery.js | 33 +++++++++++++++++++++++-------- 3 files changed, 72 insertions(+), 22 deletions(-) diff --git a/js/Track/Controller.js b/js/Track/Controller.js index 5d56f1ae..27603b8c 100644 --- a/js/Track/Controller.js +++ b/js/Track/Controller.js @@ -1,7 +1,8 @@ Genoverse.Track.Controller = Base.extend({ - scrollBuffer : 1.2, // Number of widths, if left or right closer to the edges of viewpoint than the buffer, start making more images - threshold : Infinity, // Length above which the track is not drawn - messages : undefined, + scrollBuffer : 1.2, // Number of widths, if left or right closer to the edges of viewpoint than the buffer, start making more images + threshold : Infinity, // Length above which the track is not drawn + clickTolerance : 0, // pixels of tolerance added to a click position when finding features for popup menus, when scale < 1 + messages : undefined, constructor: function (properties) { $.extend(this, properties); @@ -122,10 +123,25 @@ Genoverse.Track.Controller = Base.extend({ y = target.height() - y; } - var f = this[e.target.className === 'gv-labels' ? 'labelPositions' : 'featurePositions'].search({ x: x, y: y, w: 1, h: 1 }).sort(function (a, b) { return a.sort - b.sort; })[0]; + return this.browser.makeMenu(this.getClickedFeatures(x, y, target), e, this.track); + }, + + getClickedFeatures: function (x, y, target) { + var bounds = { x: x, y: y, w: 1, h: 1 }; + var scale = this.scale; + var tolerance = scale < 1 ? this.clickTolerance : 0; + + if (tolerance) { + bounds.x -= tolerance / 2; + bounds.w += tolerance; + } + + var features = this[target && target.hasClass('gv-labels') ? 'labelPositions' : 'featurePositions'].search(bounds); - if (f) { - return this.browser.makeMenu(f, e, this.track); + if (tolerance) { + return features.sort(function (a, b) { return Math.abs(a.position[scale].start - x) - Math.abs(b.position[scale].start - x) }); + } else { + return this.model.sortFeatures(features); } }, diff --git a/js/genoverse.combined.js b/js/genoverse.combined.js index 645f5b11..a4997354 100644 --- a/js/genoverse.combined.js +++ b/js/genoverse.combined.js @@ -3266,9 +3266,10 @@ Genoverse.Track = Base.extend({ Genoverse.Track.Controller = Base.extend({ - scrollBuffer : 1.2, // Number of widths, if left or right closer to the edges of viewpoint than the buffer, start making more images - threshold : Infinity, // Length above which the track is not drawn - messages : undefined, + scrollBuffer : 1.2, // Number of widths, if left or right closer to the edges of viewpoint than the buffer, start making more images + threshold : Infinity, // Length above which the track is not drawn + clickTolerance : 0, // pixels of tolerance added to a click position when finding features for popup menus, when scale < 1 + messages : undefined, constructor: function (properties) { $.extend(this, properties); @@ -3389,10 +3390,25 @@ Genoverse.Track.Controller = Base.extend({ y = target.height() - y; } - var f = this[e.target.className === 'gv-labels' ? 'labelPositions' : 'featurePositions'].search({ x: x, y: y, w: 1, h: 1 }).sort(function (a, b) { return a.sort - b.sort; })[0]; + return this.browser.makeMenu(this.getClickedFeatures(x, y, target), e, this.track); + }, + + getClickedFeatures: function (x, y, target) { + var bounds = { x: x, y: y, w: 1, h: 1 }; + var scale = this.scale; + var tolerance = scale < 1 ? this.clickTolerance : 0; + + if (tolerance) { + bounds.x -= tolerance / 2; + bounds.w += tolerance; + } + + var features = this[target && target.hasClass('gv-labels') ? 'labelPositions' : 'featurePositions'].search(bounds); - if (f) { - return this.browser.makeMenu(f, e, this.track); + if (tolerance) { + return features.sort(function (a, b) { return Math.abs(a.position[scale].start - x) - Math.abs(b.position[scale].start - x) }); + } else { + return this.model.sortFeatures(features); } }, @@ -3851,7 +3867,7 @@ Genoverse.Track.Model = Base.extend({ end = this.browser.chromosomeSize; } - return (url || this.url).replace(/__CHR__/, this.browser.chr).replace(/__START__/, start).replace(/__END__/, end); + return (url || this.url).replace(/__ASSEMBLY__/, this.browser.assembly).replace(/__CHR__/, this.browser.chr).replace(/__START__/, start).replace(/__END__/, end); }, setLabelBuffer: function (buffer) { @@ -4305,7 +4321,7 @@ Genoverse.Track.View = Base.extend({ } var x = (original || feature).x; - var n = this.repeatLabels ? Math.ceil((width - Math.max(scale, 1) - (this.labels === 'overlay' ? feature.labelWidth : 0)) / this.width) : 1; + var n = this.repeatLabels ? Math.ceil((width - Math.max(scale, 1) - (this.labels === 'overlay' ? feature.labelWidth : 0)) / this.width) || 1 : 1; var spacing = width / n; var label, start, j, y, currentY, h; @@ -4349,6 +4365,7 @@ Genoverse.Track.View = Base.extend({ currentY = y + (j * h); if (context.labelPositions && context.labelPositions.search({ x: start, y: currentY, w: feature.labelWidth, h: h }).length) { + feature.position[scale].label.visible = false; continue; } diff --git a/js/genoverse.combined.nojquery.js b/js/genoverse.combined.nojquery.js index 5a5acdf9..b742c797 100644 --- a/js/genoverse.combined.nojquery.js +++ b/js/genoverse.combined.nojquery.js @@ -3261,9 +3261,10 @@ Genoverse.Track = Base.extend({ Genoverse.Track.Controller = Base.extend({ - scrollBuffer : 1.2, // Number of widths, if left or right closer to the edges of viewpoint than the buffer, start making more images - threshold : Infinity, // Length above which the track is not drawn - messages : undefined, + scrollBuffer : 1.2, // Number of widths, if left or right closer to the edges of viewpoint than the buffer, start making more images + threshold : Infinity, // Length above which the track is not drawn + clickTolerance : 0, // pixels of tolerance added to a click position when finding features for popup menus, when scale < 1 + messages : undefined, constructor: function (properties) { $.extend(this, properties); @@ -3384,10 +3385,25 @@ Genoverse.Track.Controller = Base.extend({ y = target.height() - y; } - var f = this[e.target.className === 'gv-labels' ? 'labelPositions' : 'featurePositions'].search({ x: x, y: y, w: 1, h: 1 }).sort(function (a, b) { return a.sort - b.sort; })[0]; + return this.browser.makeMenu(this.getClickedFeatures(x, y, target), e, this.track); + }, + + getClickedFeatures: function (x, y, target) { + var bounds = { x: x, y: y, w: 1, h: 1 }; + var scale = this.scale; + var tolerance = scale < 1 ? this.clickTolerance : 0; + + if (tolerance) { + bounds.x -= tolerance / 2; + bounds.w += tolerance; + } + + var features = this[target && target.hasClass('gv-labels') ? 'labelPositions' : 'featurePositions'].search(bounds); - if (f) { - return this.browser.makeMenu(f, e, this.track); + if (tolerance) { + return features.sort(function (a, b) { return Math.abs(a.position[scale].start - x) - Math.abs(b.position[scale].start - x) }); + } else { + return this.model.sortFeatures(features); } }, @@ -3846,7 +3862,7 @@ Genoverse.Track.Model = Base.extend({ end = this.browser.chromosomeSize; } - return (url || this.url).replace(/__CHR__/, this.browser.chr).replace(/__START__/, start).replace(/__END__/, end); + return (url || this.url).replace(/__ASSEMBLY__/, this.browser.assembly).replace(/__CHR__/, this.browser.chr).replace(/__START__/, start).replace(/__END__/, end); }, setLabelBuffer: function (buffer) { @@ -4300,7 +4316,7 @@ Genoverse.Track.View = Base.extend({ } var x = (original || feature).x; - var n = this.repeatLabels ? Math.ceil((width - Math.max(scale, 1) - (this.labels === 'overlay' ? feature.labelWidth : 0)) / this.width) : 1; + var n = this.repeatLabels ? Math.ceil((width - Math.max(scale, 1) - (this.labels === 'overlay' ? feature.labelWidth : 0)) / this.width) || 1 : 1; var spacing = width / n; var label, start, j, y, currentY, h; @@ -4344,6 +4360,7 @@ Genoverse.Track.View = Base.extend({ currentY = y + (j * h); if (context.labelPositions && context.labelPositions.search({ x: start, y: currentY, w: feature.labelWidth, h: h }).length) { + feature.position[scale].label.visible = false; continue; } From 28615c71a12b722008cfcbb8b91b6ecec372ef16 Mon Sep 17 00:00:00 2001 From: Simon Brent Date: Tue, 23 Feb 2016 11:35:32 +0000 Subject: [PATCH 17/59] Added __ASSEMBLY__ to URL parsing --- js/Track/Model.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/Track/Model.js b/js/Track/Model.js index a578e56b..509bb74b 100644 --- a/js/Track/Model.js +++ b/js/Track/Model.js @@ -63,7 +63,7 @@ Genoverse.Track.Model = Base.extend({ end = this.browser.chromosomeSize; } - return (url || this.url).replace(/__CHR__/, this.browser.chr).replace(/__START__/, start).replace(/__END__/, end); + return (url || this.url).replace(/__ASSEMBLY__/, this.browser.assembly).replace(/__CHR__/, this.browser.chr).replace(/__START__/, start).replace(/__END__/, end); }, setLabelBuffer: function (buffer) { From d022021dccc63d5f8703942dc828dfffa406c538 Mon Sep 17 00:00:00 2001 From: Simon Brent Date: Tue, 23 Feb 2016 11:35:52 +0000 Subject: [PATCH 18/59] Fixed bug with repeatLabels when label width = 1 --- js/Track/View.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/js/Track/View.js b/js/Track/View.js index 77d311db..956a3be5 100644 --- a/js/Track/View.js +++ b/js/Track/View.js @@ -265,7 +265,7 @@ Genoverse.Track.View = Base.extend({ } var x = (original || feature).x; - var n = this.repeatLabels ? Math.ceil((width - Math.max(scale, 1) - (this.labels === 'overlay' ? feature.labelWidth : 0)) / this.width) : 1; + var n = this.repeatLabels ? Math.ceil((width - Math.max(scale, 1) - (this.labels === 'overlay' ? feature.labelWidth : 0)) / this.width) || 1 : 1; var spacing = width / n; var label, start, j, y, currentY, h; @@ -309,6 +309,7 @@ Genoverse.Track.View = Base.extend({ currentY = y + (j * h); if (context.labelPositions && context.labelPositions.search({ x: start, y: currentY, w: feature.labelWidth, h: h }).length) { + feature.position[scale].label.visible = false; continue; } From 9125a4527e0f1e01a490867264028e1cdb7634d0 Mon Sep 17 00:00:00 2001 From: Simon Brent Date: Tue, 23 Feb 2016 11:40:24 +0000 Subject: [PATCH 19/59] Optimizatin for sequence track --- js/Track/View/Sequence.js | 12 +++++------- js/genoverse.combined.js | 12 +++++------- js/genoverse.combined.nojquery.js | 12 +++++------- 3 files changed, 15 insertions(+), 21 deletions(-) diff --git a/js/Track/View/Sequence.js b/js/Track/View/Sequence.js index d24a595a..c31c466b 100644 --- a/js/Track/View/Sequence.js +++ b/js/Track/View/Sequence.js @@ -4,14 +4,16 @@ Genoverse.Track.View.Sequence = Genoverse.Track.View.extend({ labelColors : { 'default': '#000000', T: '#FFFFFF', C: '#FFFFFF' }, labels : 'overlay', - constructor: function () { + setDefaults: function () { this.base.apply(this, arguments); var lowerCase = this.prop('lowerCase'); + this.labelYOffset = typeof this.labelYOffset === 'number' ? this.labelYOffset : (this.featureHeight + (lowerCase ? 0 : 1)) / 2; + this.widestLabel = typeof this.widestLabel === 'string' ? this.widestLabel : lowerCase ? 'g' : 'G'; this.labelWidth = {}; - this.widestLabel = lowerCase ? 'g' : 'G'; - this.labelYOffset = (this.featureHeight + (lowerCase ? 0 : 1)) / 2; + + this.labelWidth[this.widestLabel] = Math.ceil(this.context.measureText(this.widestLabel).width) + 1; if (lowerCase) { for (var key in this.colors) { @@ -28,10 +30,6 @@ Genoverse.Track.View.Sequence = Genoverse.Track.View.extend({ featureContext.textBaseline = 'middle'; featureContext.textAlign = 'left'; - if (!this.labelWidth[this.widestLabel]) { - this.labelWidth[this.widestLabel] = Math.ceil(this.context.measureText(this.widestLabel).width) + 1; - } - var width = Math.max(scale, this.minScaledWidth); for (var i = 0; i < features.length; i++) { diff --git a/js/genoverse.combined.js b/js/genoverse.combined.js index a4997354..dbfcb55c 100644 --- a/js/genoverse.combined.js +++ b/js/genoverse.combined.js @@ -4762,14 +4762,16 @@ Genoverse.Track.View.Sequence = Genoverse.Track.View.extend({ labelColors : { 'default': '#000000', T: '#FFFFFF', C: '#FFFFFF' }, labels : 'overlay', - constructor: function () { + setDefaults: function () { this.base.apply(this, arguments); var lowerCase = this.prop('lowerCase'); + this.labelYOffset = typeof this.labelYOffset === 'number' ? this.labelYOffset : (this.featureHeight + (lowerCase ? 0 : 1)) / 2; + this.widestLabel = typeof this.widestLabel === 'string' ? this.widestLabel : lowerCase ? 'g' : 'G'; this.labelWidth = {}; - this.widestLabel = lowerCase ? 'g' : 'G'; - this.labelYOffset = (this.featureHeight + (lowerCase ? 0 : 1)) / 2; + + this.labelWidth[this.widestLabel] = Math.ceil(this.context.measureText(this.widestLabel).width) + 1; if (lowerCase) { for (var key in this.colors) { @@ -4786,10 +4788,6 @@ Genoverse.Track.View.Sequence = Genoverse.Track.View.extend({ featureContext.textBaseline = 'middle'; featureContext.textAlign = 'left'; - if (!this.labelWidth[this.widestLabel]) { - this.labelWidth[this.widestLabel] = Math.ceil(this.context.measureText(this.widestLabel).width) + 1; - } - var width = Math.max(scale, this.minScaledWidth); for (var i = 0; i < features.length; i++) { diff --git a/js/genoverse.combined.nojquery.js b/js/genoverse.combined.nojquery.js index b742c797..874dc65e 100644 --- a/js/genoverse.combined.nojquery.js +++ b/js/genoverse.combined.nojquery.js @@ -4757,14 +4757,16 @@ Genoverse.Track.View.Sequence = Genoverse.Track.View.extend({ labelColors : { 'default': '#000000', T: '#FFFFFF', C: '#FFFFFF' }, labels : 'overlay', - constructor: function () { + setDefaults: function () { this.base.apply(this, arguments); var lowerCase = this.prop('lowerCase'); + this.labelYOffset = typeof this.labelYOffset === 'number' ? this.labelYOffset : (this.featureHeight + (lowerCase ? 0 : 1)) / 2; + this.widestLabel = typeof this.widestLabel === 'string' ? this.widestLabel : lowerCase ? 'g' : 'G'; this.labelWidth = {}; - this.widestLabel = lowerCase ? 'g' : 'G'; - this.labelYOffset = (this.featureHeight + (lowerCase ? 0 : 1)) / 2; + + this.labelWidth[this.widestLabel] = Math.ceil(this.context.measureText(this.widestLabel).width) + 1; if (lowerCase) { for (var key in this.colors) { @@ -4781,10 +4783,6 @@ Genoverse.Track.View.Sequence = Genoverse.Track.View.extend({ featureContext.textBaseline = 'middle'; featureContext.textAlign = 'left'; - if (!this.labelWidth[this.widestLabel]) { - this.labelWidth[this.widestLabel] = Math.ceil(this.context.measureText(this.widestLabel).width) + 1; - } - var width = Math.max(scale, this.minScaledWidth); for (var i = 0; i < features.length; i++) { From 65480869e5fa811cce43983dfccca89a9ca3341b Mon Sep 17 00:00:00 2001 From: Simon Brent Date: Tue, 23 Feb 2016 11:51:08 +0000 Subject: [PATCH 20/59] Fixed dbSNP feature menus --- js/Track/library/dbSNP.js | 8 ++++---- js/genoverse.combined.js | 10 +++++----- js/genoverse.combined.nojquery.js | 10 +++++----- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/js/Track/library/dbSNP.js b/js/Track/library/dbSNP.js index ea79ba24..13751425 100644 --- a/js/Track/library/dbSNP.js +++ b/js/Track/library/dbSNP.js @@ -81,10 +81,10 @@ Genoverse.Track.dbSNP = Genoverse.Track.extend({ populateMenu: function (feature) { var deferred = $.Deferred(); var menu = [{ - title : '' + feature.id + '', - Location : this.browser.chr + ':' + feature.start + '-' + feature.end, - Consequence : feature.consequence_type, - 'Alt alleles' : feature.alt_alleles.join(', ') + title : '' + feature.id + '', + Location : this.browser.chr + ':' + feature.start + '-' + feature.end, + Consequence : feature.consequence_type, + Alleles : feature.alleles.join(', ') }]; $.ajax({ diff --git a/js/genoverse.combined.js b/js/genoverse.combined.js index dbfcb55c..3dbd4680 100644 --- a/js/genoverse.combined.js +++ b/js/genoverse.combined.js @@ -2492,7 +2492,7 @@ var Genoverse = Base.extend({ $('.gv-title', menu).html(features.length + ' features'); $.each(features.sort(function (a, b) { return a.start - b.start; }), function (i, feature) { - var location = feature.chr + ':' + feature.start + (feature.end === feature.start ? '' : '-' + feature.end); + var location = (feature.chr || browser.chr) + ':' + feature.start + (feature.end === feature.start ? '' : '-' + feature.end); var title = feature.menuLabel || feature.name || ($.isArray(feature.label) ? feature.label.join(' ') : feature.label) || (feature.id + ''); $('').html(title.match(location) ? title : (location + ' ' + title)).on('click', function (e) { @@ -5661,10 +5661,10 @@ Genoverse.Track.dbSNP = Genoverse.Track.extend({ populateMenu: function (feature) { var deferred = $.Deferred(); var menu = [{ - title : '' + feature.id + '', - Location : this.browser.chr + ':' + feature.start + '-' + feature.end, - Consequence : feature.consequence_type, - 'Alt alleles' : feature.alt_alleles.join(', ') + title : '' + feature.id + '', + Location : this.browser.chr + ':' + feature.start + '-' + feature.end, + Consequence : feature.consequence_type, + Alleles : feature.alleles.join(', ') }]; $.ajax({ diff --git a/js/genoverse.combined.nojquery.js b/js/genoverse.combined.nojquery.js index 874dc65e..030d6609 100644 --- a/js/genoverse.combined.nojquery.js +++ b/js/genoverse.combined.nojquery.js @@ -2487,7 +2487,7 @@ var Genoverse = Base.extend({ $('.gv-title', menu).html(features.length + ' features'); $.each(features.sort(function (a, b) { return a.start - b.start; }), function (i, feature) { - var location = feature.chr + ':' + feature.start + (feature.end === feature.start ? '' : '-' + feature.end); + var location = (feature.chr || browser.chr) + ':' + feature.start + (feature.end === feature.start ? '' : '-' + feature.end); var title = feature.menuLabel || feature.name || ($.isArray(feature.label) ? feature.label.join(' ') : feature.label) || (feature.id + ''); $('').html(title.match(location) ? title : (location + ' ' + title)).on('click', function (e) { @@ -5656,10 +5656,10 @@ Genoverse.Track.dbSNP = Genoverse.Track.extend({ populateMenu: function (feature) { var deferred = $.Deferred(); var menu = [{ - title : '' + feature.id + '', - Location : this.browser.chr + ':' + feature.start + '-' + feature.end, - Consequence : feature.consequence_type, - 'Alt alleles' : feature.alt_alleles.join(', ') + title : '' + feature.id + '', + Location : this.browser.chr + ':' + feature.start + '-' + feature.end, + Consequence : feature.consequence_type, + Alleles : feature.alleles.join(', ') }]; $.ajax({ From 1b0dc5ca040359194472e268e222692f93acf8cf Mon Sep 17 00:00:00 2001 From: Simon Brent Date: Tue, 8 Mar 2016 15:08:59 +0000 Subject: [PATCH 21/59] Allow feature.marginTop --- js/Track/View.js | 4 ++-- js/genoverse.combined.js | 23 ++++++++++++++++++----- js/genoverse.combined.nojquery.js | 23 ++++++++++++++++++----- 3 files changed, 38 insertions(+), 12 deletions(-) diff --git a/js/Track/View.js b/js/Track/View.js index 956a3be5..48a3865c 100644 --- a/js/Track/View.js +++ b/js/Track/View.js @@ -107,8 +107,8 @@ Genoverse.Track.View = Base.extend({ if (!feature.position[scale].positioned) { feature.position[scale].H = feature.position[scale].height + this.featureMargin.bottom; - feature.position[scale].W = feature.position[scale].width + (feature.marginRight || this.featureMargin.right); - feature.position[scale].Y = (typeof feature.y === 'number' ? feature.y * feature.position[scale].H : 0) + this.featureMargin.top; + feature.position[scale].W = feature.position[scale].width + (feature.marginRight || this.featureMargin.right); + feature.position[scale].Y = (typeof feature.y === 'number' ? feature.y * feature.position[scale].H : 0) + (feature.marginTop || this.featureMargin.top); if (feature.label) { if (typeof feature.label === 'string') { diff --git a/js/genoverse.combined.js b/js/genoverse.combined.js index 3dbd4680..0a70451e 100644 --- a/js/genoverse.combined.js +++ b/js/genoverse.combined.js @@ -3242,7 +3242,7 @@ Genoverse.Track = Base.extend({ this.model.init(true); } - this.view.init(); + this.view.init.apply(this.view, arguments); this.setLengthMap(); this.controller.reset.apply(this.controller, arguments); }, @@ -3406,7 +3406,7 @@ Genoverse.Track.Controller = Base.extend({ var features = this[target && target.hasClass('gv-labels') ? 'labelPositions' : 'featurePositions'].search(bounds); if (tolerance) { - return features.sort(function (a, b) { return Math.abs(a.position[scale].start - x) - Math.abs(b.position[scale].start - x) }); + return features.sort(function (a, b) { return Math.abs(a.position[scale].start - x) - Math.abs(b.position[scale].start - x); }); } else { return this.model.sortFeatures(features); } @@ -3955,9 +3955,11 @@ Genoverse.Track.Model = Base.extend({ * and call this.insertFeature(feature) */ parseData: function (data, start, end) { + var feature; + // Example of parseData function when data is an array of hashes like { start: ..., end: ... } for (var i = 0; i < data.length; i++) { - var feature = data[i]; + feature = data[i]; feature.sort = start + i; @@ -4079,6 +4081,17 @@ Genoverse.Track.View = Base.extend({ init: function () { this.setDefaults(); this.scaleSettings = {}; + + if (arguments[0] === 'resizing') { + var features = this.prop('featuresById'); + var scale = this.prop('scale'); + + for (var i in features) { + if (features[i].position[scale]) { + features[i].position[scale].positioned = false; + } + } + } }, setDefaults: function () { @@ -4163,8 +4176,8 @@ Genoverse.Track.View = Base.extend({ if (!feature.position[scale].positioned) { feature.position[scale].H = feature.position[scale].height + this.featureMargin.bottom; - feature.position[scale].W = feature.position[scale].width + (feature.marginRight || this.featureMargin.right); - feature.position[scale].Y = (typeof feature.y === 'number' ? feature.y * feature.position[scale].H : 0) + this.featureMargin.top; + feature.position[scale].W = feature.position[scale].width + (feature.marginRight || this.featureMargin.right); + feature.position[scale].Y = (typeof feature.y === 'number' ? feature.y * feature.position[scale].H : 0) + (feature.marginTop || this.featureMargin.top); if (feature.label) { if (typeof feature.label === 'string') { diff --git a/js/genoverse.combined.nojquery.js b/js/genoverse.combined.nojquery.js index 030d6609..e606e340 100644 --- a/js/genoverse.combined.nojquery.js +++ b/js/genoverse.combined.nojquery.js @@ -3237,7 +3237,7 @@ Genoverse.Track = Base.extend({ this.model.init(true); } - this.view.init(); + this.view.init.apply(this.view, arguments); this.setLengthMap(); this.controller.reset.apply(this.controller, arguments); }, @@ -3401,7 +3401,7 @@ Genoverse.Track.Controller = Base.extend({ var features = this[target && target.hasClass('gv-labels') ? 'labelPositions' : 'featurePositions'].search(bounds); if (tolerance) { - return features.sort(function (a, b) { return Math.abs(a.position[scale].start - x) - Math.abs(b.position[scale].start - x) }); + return features.sort(function (a, b) { return Math.abs(a.position[scale].start - x) - Math.abs(b.position[scale].start - x); }); } else { return this.model.sortFeatures(features); } @@ -3950,9 +3950,11 @@ Genoverse.Track.Model = Base.extend({ * and call this.insertFeature(feature) */ parseData: function (data, start, end) { + var feature; + // Example of parseData function when data is an array of hashes like { start: ..., end: ... } for (var i = 0; i < data.length; i++) { - var feature = data[i]; + feature = data[i]; feature.sort = start + i; @@ -4074,6 +4076,17 @@ Genoverse.Track.View = Base.extend({ init: function () { this.setDefaults(); this.scaleSettings = {}; + + if (arguments[0] === 'resizing') { + var features = this.prop('featuresById'); + var scale = this.prop('scale'); + + for (var i in features) { + if (features[i].position[scale]) { + features[i].position[scale].positioned = false; + } + } + } }, setDefaults: function () { @@ -4158,8 +4171,8 @@ Genoverse.Track.View = Base.extend({ if (!feature.position[scale].positioned) { feature.position[scale].H = feature.position[scale].height + this.featureMargin.bottom; - feature.position[scale].W = feature.position[scale].width + (feature.marginRight || this.featureMargin.right); - feature.position[scale].Y = (typeof feature.y === 'number' ? feature.y * feature.position[scale].H : 0) + this.featureMargin.top; + feature.position[scale].W = feature.position[scale].width + (feature.marginRight || this.featureMargin.right); + feature.position[scale].Y = (typeof feature.y === 'number' ? feature.y * feature.position[scale].H : 0) + (feature.marginTop || this.featureMargin.top); if (feature.label) { if (typeof feature.label === 'string') { From 9bebbfc39fee0907ffd9ef04ed7ff025135ddedd Mon Sep 17 00:00:00 2001 From: Simon Brent Date: Tue, 8 Mar 2016 15:09:21 +0000 Subject: [PATCH 22/59] jshint --- js/Track/Controller.js | 2 +- js/Track/Model.js | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/js/Track/Controller.js b/js/Track/Controller.js index 27603b8c..91bb537d 100644 --- a/js/Track/Controller.js +++ b/js/Track/Controller.js @@ -139,7 +139,7 @@ Genoverse.Track.Controller = Base.extend({ var features = this[target && target.hasClass('gv-labels') ? 'labelPositions' : 'featurePositions'].search(bounds); if (tolerance) { - return features.sort(function (a, b) { return Math.abs(a.position[scale].start - x) - Math.abs(b.position[scale].start - x) }); + return features.sort(function (a, b) { return Math.abs(a.position[scale].start - x) - Math.abs(b.position[scale].start - x); }); } else { return this.model.sortFeatures(features); } diff --git a/js/Track/Model.js b/js/Track/Model.js index 509bb74b..da086bb5 100644 --- a/js/Track/Model.js +++ b/js/Track/Model.js @@ -151,9 +151,11 @@ Genoverse.Track.Model = Base.extend({ * and call this.insertFeature(feature) */ parseData: function (data, start, end) { + var feature; + // Example of parseData function when data is an array of hashes like { start: ..., end: ... } for (var i = 0; i < data.length; i++) { - var feature = data[i]; + feature = data[i]; feature.sort = start + i; From 2555e31eabb4923117dd3e8bd5a4501fbd308542 Mon Sep 17 00:00:00 2001 From: Simon Brent Date: Tue, 8 Mar 2016 16:15:30 +0000 Subject: [PATCH 23/59] Stop error when clicking beneath sequence --- js/Track/Controller/Sequence.js | 4 +- js/genoverse.combined.js | 72 +++++++++++++------------------ js/genoverse.combined.nojquery.js | 72 +++++++++++++------------------ 3 files changed, 63 insertions(+), 85 deletions(-) diff --git a/js/Track/Controller/Sequence.js b/js/Track/Controller/Sequence.js index 10a088d0..298d7b68 100644 --- a/js/Track/Controller/Sequence.js +++ b/js/Track/Controller/Sequence.js @@ -1,6 +1,8 @@ Genoverse.Track.Controller.Sequence = Genoverse.Track.Controller.extend({ getClickedFeatures: function (x, y) { - return this.makeSeqFeatureMenu(this.base(x, y)[0], Math.floor(x / this.scale)); + var feature = this.base(x, y)[0]; + + return feature ? this.makeSeqFeatureMenu(feature, Math.floor(x / this.scale)) : false; }, makeSeqFeatureMenu: function (feature, pos) { diff --git a/js/genoverse.combined.js b/js/genoverse.combined.js index 0a70451e..1204bd3b 100644 --- a/js/genoverse.combined.js +++ b/js/genoverse.combined.js @@ -3242,7 +3242,7 @@ Genoverse.Track = Base.extend({ this.model.init(true); } - this.view.init.apply(this.view, arguments); + this.view.init(); this.setLengthMap(); this.controller.reset.apply(this.controller, arguments); }, @@ -3652,11 +3652,8 @@ Genoverse.Track.Controller = Base.extend({ var controller = this; var tooLarge = this.browser.length > this.threshold; var div = this.imgContainer.clone().addClass((params.cls + ' gv-loading').replace('.', '_')).css({ left: params.left, display: params.cls === this.scrollStart ? 'block' : 'none' }); - var bgImage = params.background ? $('').hide().addClass(params.background).data(params).prependTo(div) : false; - var image = $('').hide().data(params).appendTo(div).on('load', function () { - $(this).fadeIn('fast').parent().removeClass('gv-loading'); - $(this).siblings('.gv-bg').show(); - }); + var bgCanvas = params.background ? $('').addClass(params.background).data(params).prependTo(div) : false; + var canvas = $('').data(params).appendTo(div); params.container = div; @@ -3678,11 +3675,14 @@ Genoverse.Track.Controller = Base.extend({ return deferred.done(function () { var features = tooLarge ? [] : controller.model.findFeatures(params.start, params.end); - controller.render(features, image); - if (bgImage) { - controller.renderBackground(features, bgImage); + controller.render(features, canvas); + + if (bgCanvas) { + controller.renderBackground(features, bgCanvas); } + + canvas.parent().removeClass('gv-loading'); }).fail(function (e) { controller.showError(e); }); @@ -3740,11 +3740,14 @@ Genoverse.Track.Controller = Base.extend({ } }, - render: function (features, img) { - var params = img.data(); - features = this.view.positionFeatures(this.view.scaleFeatures(features, params.scale), params); // positionFeatures alters params.featureHeight, so this must happen before the canvases are created - var featureCanvas = $('').attr({ width: params.width, height: params.featureHeight || 1 }); - var labelCanvas = this.prop('labels') === 'separate' && params.labelHeight ? featureCanvas.clone().attr('height', params.labelHeight) : featureCanvas; + render: function (features, featureCanvas) { + var params = featureCanvas.data(); + features = this.view.positionFeatures(this.view.scaleFeatures(features, params.scale), params); + + // positionFeatures alters params.featureHeight, so this must happen before the canvas height is set + featureCanvas.attr({ width: params.width, height: params.featureHeight || 1 }); + + var labelCanvas = this.prop('labels') === 'separate' && params.labelHeight ? featureCanvas.clone().attr({ 'class': 'gv-labels', height: params.labelHeight }).insertAfter(featureCanvas) : featureCanvas; var featureContext = featureCanvas[0].getContext('2d'); var labelContext = labelCanvas[0].getContext('2d'); @@ -3757,23 +3760,17 @@ Genoverse.Track.Controller = Base.extend({ } this.view.draw(features, featureContext, labelContext, params.scale); - - img.attr('src', featureCanvas[0].toDataURL()); - - if (labelContext !== featureContext) { - img.clone(true).attr({ 'class': 'gv-labels', src: labelCanvas[0].toDataURL() }).insertAfter(img); - } - this.checkHeight(); - featureCanvas = labelCanvas = img = null; + featureCanvas = labelCanvas = null; }, - renderBackground: function (features, img, height) { - var canvas = $('').attr({ width: this.width, height: height || 1 })[0]; - this.view.drawBackground(features, canvas.getContext('2d'), img.data()); - img.attr('src', canvas.toDataURL()); - canvas = img = null; + renderBackground: function (features, canvas, height) { + canvas.attr({ width: this.width, height: height || 1 }); + + this.view.drawBackground(features, canvas[0].getContext('2d'), canvas.data()); + + canvas = null; }, populateMenu: function (feature) { @@ -4081,17 +4078,6 @@ Genoverse.Track.View = Base.extend({ init: function () { this.setDefaults(); this.scaleSettings = {}; - - if (arguments[0] === 'resizing') { - var features = this.prop('featuresById'); - var scale = this.prop('scale'); - - for (var i in features) { - if (features[i].position[scale]) { - features[i].position[scale].positioned = false; - } - } - } }, setDefaults: function () { @@ -4447,7 +4433,7 @@ Genoverse.Track.Controller.Static = Genoverse.Track.Controller.extend({ addDomElements: function () { this.base(); - this.image = $('').appendTo(this.imgContainer); + this.canvas = $('').appendTo(this.imgContainer); this.container.toggleClass('gv-track-container gv-track-container-static').prepend(this.imgContainer); this.scrollContainer.add(this.messageContainer).remove(); @@ -4460,7 +4446,7 @@ Genoverse.Track.Controller.Static = Genoverse.Track.Controller.extend({ setWidth: function (width) { this.base(width); - this.image.width = this.width; + this.canvas.width = this.width; }, makeFirstImage: function () { @@ -4485,7 +4471,7 @@ Genoverse.Track.Controller.Static = Genoverse.Track.Controller.extend({ params.width = this.width; params.featureHeight = height; - this.render(features, this.image.data(params)); + this.render(features, this.canvas.data(params)); this.imgContainer.children(':last').show(); this.resize(height, undefined, false); @@ -4607,7 +4593,9 @@ Genoverse.Track.Model.Stranded = Genoverse.Track.Model.extend({ Genoverse.Track.Controller.Sequence = Genoverse.Track.Controller.extend({ getClickedFeatures: function (x, y) { - return this.makeSeqFeatureMenu(this.base(x, y)[0], Math.floor(x / this.scale)); + var feature = this.base(x, y)[0]; + + return feature ? this.makeSeqFeatureMenu(feature, Math.floor(x / this.scale)) : false; }, makeSeqFeatureMenu: function (feature, pos) { diff --git a/js/genoverse.combined.nojquery.js b/js/genoverse.combined.nojquery.js index e606e340..e7b43717 100644 --- a/js/genoverse.combined.nojquery.js +++ b/js/genoverse.combined.nojquery.js @@ -3237,7 +3237,7 @@ Genoverse.Track = Base.extend({ this.model.init(true); } - this.view.init.apply(this.view, arguments); + this.view.init(); this.setLengthMap(); this.controller.reset.apply(this.controller, arguments); }, @@ -3647,11 +3647,8 @@ Genoverse.Track.Controller = Base.extend({ var controller = this; var tooLarge = this.browser.length > this.threshold; var div = this.imgContainer.clone().addClass((params.cls + ' gv-loading').replace('.', '_')).css({ left: params.left, display: params.cls === this.scrollStart ? 'block' : 'none' }); - var bgImage = params.background ? $('').hide().addClass(params.background).data(params).prependTo(div) : false; - var image = $('').hide().data(params).appendTo(div).on('load', function () { - $(this).fadeIn('fast').parent().removeClass('gv-loading'); - $(this).siblings('.gv-bg').show(); - }); + var bgCanvas = params.background ? $('').addClass(params.background).data(params).prependTo(div) : false; + var canvas = $('').data(params).appendTo(div); params.container = div; @@ -3673,11 +3670,14 @@ Genoverse.Track.Controller = Base.extend({ return deferred.done(function () { var features = tooLarge ? [] : controller.model.findFeatures(params.start, params.end); - controller.render(features, image); - if (bgImage) { - controller.renderBackground(features, bgImage); + controller.render(features, canvas); + + if (bgCanvas) { + controller.renderBackground(features, bgCanvas); } + + canvas.parent().removeClass('gv-loading'); }).fail(function (e) { controller.showError(e); }); @@ -3735,11 +3735,14 @@ Genoverse.Track.Controller = Base.extend({ } }, - render: function (features, img) { - var params = img.data(); - features = this.view.positionFeatures(this.view.scaleFeatures(features, params.scale), params); // positionFeatures alters params.featureHeight, so this must happen before the canvases are created - var featureCanvas = $('').attr({ width: params.width, height: params.featureHeight || 1 }); - var labelCanvas = this.prop('labels') === 'separate' && params.labelHeight ? featureCanvas.clone().attr('height', params.labelHeight) : featureCanvas; + render: function (features, featureCanvas) { + var params = featureCanvas.data(); + features = this.view.positionFeatures(this.view.scaleFeatures(features, params.scale), params); + + // positionFeatures alters params.featureHeight, so this must happen before the canvas height is set + featureCanvas.attr({ width: params.width, height: params.featureHeight || 1 }); + + var labelCanvas = this.prop('labels') === 'separate' && params.labelHeight ? featureCanvas.clone().attr({ 'class': 'gv-labels', height: params.labelHeight }).insertAfter(featureCanvas) : featureCanvas; var featureContext = featureCanvas[0].getContext('2d'); var labelContext = labelCanvas[0].getContext('2d'); @@ -3752,23 +3755,17 @@ Genoverse.Track.Controller = Base.extend({ } this.view.draw(features, featureContext, labelContext, params.scale); - - img.attr('src', featureCanvas[0].toDataURL()); - - if (labelContext !== featureContext) { - img.clone(true).attr({ 'class': 'gv-labels', src: labelCanvas[0].toDataURL() }).insertAfter(img); - } - this.checkHeight(); - featureCanvas = labelCanvas = img = null; + featureCanvas = labelCanvas = null; }, - renderBackground: function (features, img, height) { - var canvas = $('').attr({ width: this.width, height: height || 1 })[0]; - this.view.drawBackground(features, canvas.getContext('2d'), img.data()); - img.attr('src', canvas.toDataURL()); - canvas = img = null; + renderBackground: function (features, canvas, height) { + canvas.attr({ width: this.width, height: height || 1 }); + + this.view.drawBackground(features, canvas[0].getContext('2d'), canvas.data()); + + canvas = null; }, populateMenu: function (feature) { @@ -4076,17 +4073,6 @@ Genoverse.Track.View = Base.extend({ init: function () { this.setDefaults(); this.scaleSettings = {}; - - if (arguments[0] === 'resizing') { - var features = this.prop('featuresById'); - var scale = this.prop('scale'); - - for (var i in features) { - if (features[i].position[scale]) { - features[i].position[scale].positioned = false; - } - } - } }, setDefaults: function () { @@ -4442,7 +4428,7 @@ Genoverse.Track.Controller.Static = Genoverse.Track.Controller.extend({ addDomElements: function () { this.base(); - this.image = $('').appendTo(this.imgContainer); + this.canvas = $('').appendTo(this.imgContainer); this.container.toggleClass('gv-track-container gv-track-container-static').prepend(this.imgContainer); this.scrollContainer.add(this.messageContainer).remove(); @@ -4455,7 +4441,7 @@ Genoverse.Track.Controller.Static = Genoverse.Track.Controller.extend({ setWidth: function (width) { this.base(width); - this.image.width = this.width; + this.canvas.width = this.width; }, makeFirstImage: function () { @@ -4480,7 +4466,7 @@ Genoverse.Track.Controller.Static = Genoverse.Track.Controller.extend({ params.width = this.width; params.featureHeight = height; - this.render(features, this.image.data(params)); + this.render(features, this.canvas.data(params)); this.imgContainer.children(':last').show(); this.resize(height, undefined, false); @@ -4602,7 +4588,9 @@ Genoverse.Track.Model.Stranded = Genoverse.Track.Model.extend({ Genoverse.Track.Controller.Sequence = Genoverse.Track.Controller.extend({ getClickedFeatures: function (x, y) { - return this.makeSeqFeatureMenu(this.base(x, y)[0], Math.floor(x / this.scale)); + var feature = this.base(x, y)[0]; + + return feature ? this.makeSeqFeatureMenu(feature, Math.floor(x / this.scale)) : false; }, makeSeqFeatureMenu: function (feature, pos) { From 2bf05f069960b53cf22ebce85b0d6fb14237f5d7 Mon Sep 17 00:00:00 2001 From: Simon Brent Date: Wed, 9 Mar 2016 11:47:43 +0000 Subject: [PATCH 24/59] Ensure intron hat/curves line up across images --- js/Track/View/Transcript.js | 4 +-- js/genoverse.combined.js | 59 ++++++++++++++++--------------- js/genoverse.combined.nojquery.js | 59 ++++++++++++++++--------------- 3 files changed, 64 insertions(+), 58 deletions(-) diff --git a/js/Track/View/Transcript.js b/js/Track/View/Transcript.js index b9524052..80bcabf6 100644 --- a/js/Track/View/Transcript.js +++ b/js/Track/View/Transcript.js @@ -30,13 +30,13 @@ Genoverse.Track.View.Transcript = Genoverse.Track.View.extend({ x = transcript.x + (cds[i].start - transcript.start) * scale; w = Math.max((cds[i].end - cds[i].start) * scale + add, this.minScaledWidth); + coding[cds[i].start + ':' + cds[i].end] = true; + if (x > this.width || x + w < 0) { continue; } featureContext.fillRect(x, transcript.y, w, transcript.height); - - coding[cds[i].start + ':' + cds[i].end] = true; } for (i = 0; i < exons.length; i++) { diff --git a/js/genoverse.combined.js b/js/genoverse.combined.js index 1204bd3b..d33d4010 100644 --- a/js/genoverse.combined.js +++ b/js/genoverse.combined.js @@ -3652,8 +3652,11 @@ Genoverse.Track.Controller = Base.extend({ var controller = this; var tooLarge = this.browser.length > this.threshold; var div = this.imgContainer.clone().addClass((params.cls + ' gv-loading').replace('.', '_')).css({ left: params.left, display: params.cls === this.scrollStart ? 'block' : 'none' }); - var bgCanvas = params.background ? $('').addClass(params.background).data(params).prependTo(div) : false; - var canvas = $('').data(params).appendTo(div); + var bgImage = params.background ? $('').hide().addClass(params.background).data(params).prependTo(div) : false; + var image = $('').hide().data(params).appendTo(div).on('load', function () { + $(this).fadeIn('fast').parent().removeClass('gv-loading'); + $(this).siblings('.gv-bg').show(); + }); params.container = div; @@ -3675,14 +3678,11 @@ Genoverse.Track.Controller = Base.extend({ return deferred.done(function () { var features = tooLarge ? [] : controller.model.findFeatures(params.start, params.end); + controller.render(features, image); - controller.render(features, canvas); - - if (bgCanvas) { - controller.renderBackground(features, bgCanvas); + if (bgImage) { + controller.renderBackground(features, bgImage); } - - canvas.parent().removeClass('gv-loading'); }).fail(function (e) { controller.showError(e); }); @@ -3740,14 +3740,11 @@ Genoverse.Track.Controller = Base.extend({ } }, - render: function (features, featureCanvas) { - var params = featureCanvas.data(); - features = this.view.positionFeatures(this.view.scaleFeatures(features, params.scale), params); - - // positionFeatures alters params.featureHeight, so this must happen before the canvas height is set - featureCanvas.attr({ width: params.width, height: params.featureHeight || 1 }); - - var labelCanvas = this.prop('labels') === 'separate' && params.labelHeight ? featureCanvas.clone().attr({ 'class': 'gv-labels', height: params.labelHeight }).insertAfter(featureCanvas) : featureCanvas; + render: function (features, img) { + var params = img.data(); + features = this.view.positionFeatures(this.view.scaleFeatures(features, params.scale), params); // positionFeatures alters params.featureHeight, so this must happen before the canvases are created + var featureCanvas = $('').attr({ width: params.width, height: params.featureHeight || 1 }); + var labelCanvas = this.prop('labels') === 'separate' && params.labelHeight ? featureCanvas.clone().attr('height', params.labelHeight) : featureCanvas; var featureContext = featureCanvas[0].getContext('2d'); var labelContext = labelCanvas[0].getContext('2d'); @@ -3760,17 +3757,23 @@ Genoverse.Track.Controller = Base.extend({ } this.view.draw(features, featureContext, labelContext, params.scale); - this.checkHeight(); - featureCanvas = labelCanvas = null; - }, + img.attr('src', featureCanvas[0].toDataURL()); - renderBackground: function (features, canvas, height) { - canvas.attr({ width: this.width, height: height || 1 }); + if (labelContext !== featureContext) { + img.clone(true).attr({ 'class': 'gv-labels', src: labelCanvas[0].toDataURL() }).insertAfter(img); + } - this.view.drawBackground(features, canvas[0].getContext('2d'), canvas.data()); + this.checkHeight(); + + featureCanvas = labelCanvas = img = null; + }, - canvas = null; + renderBackground: function (features, img, height) { + var canvas = $('').attr({ width: this.width, height: height || 1 })[0]; + this.view.drawBackground(features, canvas.getContext('2d'), img.data()); + img.attr('src', canvas.toDataURL()); + canvas = img = null; }, populateMenu: function (feature) { @@ -4433,7 +4436,7 @@ Genoverse.Track.Controller.Static = Genoverse.Track.Controller.extend({ addDomElements: function () { this.base(); - this.canvas = $('').appendTo(this.imgContainer); + this.image = $('').appendTo(this.imgContainer); this.container.toggleClass('gv-track-container gv-track-container-static').prepend(this.imgContainer); this.scrollContainer.add(this.messageContainer).remove(); @@ -4446,7 +4449,7 @@ Genoverse.Track.Controller.Static = Genoverse.Track.Controller.extend({ setWidth: function (width) { this.base(width); - this.canvas.width = this.width; + this.image.width = this.width; }, makeFirstImage: function () { @@ -4471,7 +4474,7 @@ Genoverse.Track.Controller.Static = Genoverse.Track.Controller.extend({ params.width = this.width; params.featureHeight = height; - this.render(features, this.canvas.data(params)); + this.render(features, this.image.data(params)); this.imgContainer.children(':last').show(); this.resize(height, undefined, false); @@ -5138,13 +5141,13 @@ Genoverse.Track.View.Transcript = Genoverse.Track.View.extend({ x = transcript.x + (cds[i].start - transcript.start) * scale; w = Math.max((cds[i].end - cds[i].start) * scale + add, this.minScaledWidth); + coding[cds[i].start + ':' + cds[i].end] = true; + if (x > this.width || x + w < 0) { continue; } featureContext.fillRect(x, transcript.y, w, transcript.height); - - coding[cds[i].start + ':' + cds[i].end] = true; } for (i = 0; i < exons.length; i++) { diff --git a/js/genoverse.combined.nojquery.js b/js/genoverse.combined.nojquery.js index e7b43717..9e8b2137 100644 --- a/js/genoverse.combined.nojquery.js +++ b/js/genoverse.combined.nojquery.js @@ -3647,8 +3647,11 @@ Genoverse.Track.Controller = Base.extend({ var controller = this; var tooLarge = this.browser.length > this.threshold; var div = this.imgContainer.clone().addClass((params.cls + ' gv-loading').replace('.', '_')).css({ left: params.left, display: params.cls === this.scrollStart ? 'block' : 'none' }); - var bgCanvas = params.background ? $('').addClass(params.background).data(params).prependTo(div) : false; - var canvas = $('').data(params).appendTo(div); + var bgImage = params.background ? $('').hide().addClass(params.background).data(params).prependTo(div) : false; + var image = $('').hide().data(params).appendTo(div).on('load', function () { + $(this).fadeIn('fast').parent().removeClass('gv-loading'); + $(this).siblings('.gv-bg').show(); + }); params.container = div; @@ -3670,14 +3673,11 @@ Genoverse.Track.Controller = Base.extend({ return deferred.done(function () { var features = tooLarge ? [] : controller.model.findFeatures(params.start, params.end); + controller.render(features, image); - controller.render(features, canvas); - - if (bgCanvas) { - controller.renderBackground(features, bgCanvas); + if (bgImage) { + controller.renderBackground(features, bgImage); } - - canvas.parent().removeClass('gv-loading'); }).fail(function (e) { controller.showError(e); }); @@ -3735,14 +3735,11 @@ Genoverse.Track.Controller = Base.extend({ } }, - render: function (features, featureCanvas) { - var params = featureCanvas.data(); - features = this.view.positionFeatures(this.view.scaleFeatures(features, params.scale), params); - - // positionFeatures alters params.featureHeight, so this must happen before the canvas height is set - featureCanvas.attr({ width: params.width, height: params.featureHeight || 1 }); - - var labelCanvas = this.prop('labels') === 'separate' && params.labelHeight ? featureCanvas.clone().attr({ 'class': 'gv-labels', height: params.labelHeight }).insertAfter(featureCanvas) : featureCanvas; + render: function (features, img) { + var params = img.data(); + features = this.view.positionFeatures(this.view.scaleFeatures(features, params.scale), params); // positionFeatures alters params.featureHeight, so this must happen before the canvases are created + var featureCanvas = $('').attr({ width: params.width, height: params.featureHeight || 1 }); + var labelCanvas = this.prop('labels') === 'separate' && params.labelHeight ? featureCanvas.clone().attr('height', params.labelHeight) : featureCanvas; var featureContext = featureCanvas[0].getContext('2d'); var labelContext = labelCanvas[0].getContext('2d'); @@ -3755,17 +3752,23 @@ Genoverse.Track.Controller = Base.extend({ } this.view.draw(features, featureContext, labelContext, params.scale); - this.checkHeight(); - featureCanvas = labelCanvas = null; - }, + img.attr('src', featureCanvas[0].toDataURL()); - renderBackground: function (features, canvas, height) { - canvas.attr({ width: this.width, height: height || 1 }); + if (labelContext !== featureContext) { + img.clone(true).attr({ 'class': 'gv-labels', src: labelCanvas[0].toDataURL() }).insertAfter(img); + } - this.view.drawBackground(features, canvas[0].getContext('2d'), canvas.data()); + this.checkHeight(); + + featureCanvas = labelCanvas = img = null; + }, - canvas = null; + renderBackground: function (features, img, height) { + var canvas = $('').attr({ width: this.width, height: height || 1 })[0]; + this.view.drawBackground(features, canvas.getContext('2d'), img.data()); + img.attr('src', canvas.toDataURL()); + canvas = img = null; }, populateMenu: function (feature) { @@ -4428,7 +4431,7 @@ Genoverse.Track.Controller.Static = Genoverse.Track.Controller.extend({ addDomElements: function () { this.base(); - this.canvas = $('').appendTo(this.imgContainer); + this.image = $('').appendTo(this.imgContainer); this.container.toggleClass('gv-track-container gv-track-container-static').prepend(this.imgContainer); this.scrollContainer.add(this.messageContainer).remove(); @@ -4441,7 +4444,7 @@ Genoverse.Track.Controller.Static = Genoverse.Track.Controller.extend({ setWidth: function (width) { this.base(width); - this.canvas.width = this.width; + this.image.width = this.width; }, makeFirstImage: function () { @@ -4466,7 +4469,7 @@ Genoverse.Track.Controller.Static = Genoverse.Track.Controller.extend({ params.width = this.width; params.featureHeight = height; - this.render(features, this.canvas.data(params)); + this.render(features, this.image.data(params)); this.imgContainer.children(':last').show(); this.resize(height, undefined, false); @@ -5133,13 +5136,13 @@ Genoverse.Track.View.Transcript = Genoverse.Track.View.extend({ x = transcript.x + (cds[i].start - transcript.start) * scale; w = Math.max((cds[i].end - cds[i].start) * scale + add, this.minScaledWidth); + coding[cds[i].start + ':' + cds[i].end] = true; + if (x > this.width || x + w < 0) { continue; } featureContext.fillRect(x, transcript.y, w, transcript.height); - - coding[cds[i].start + ':' + cds[i].end] = true; } for (i = 0; i < exons.length; i++) { From 00c2e612ae50f374ac73726a7d9811a308bc8940 Mon Sep 17 00:00:00 2001 From: Simon Brent Date: Sat, 12 Mar 2016 10:00:59 +0000 Subject: [PATCH 25/59] Added prepopulated tracks, where a data array is given to the track on creation --- expanded.html | 3 +++ js/Track/Model/Prepopulated.js | 20 ++++++++++++++++++++ js/Track/library/Prepopulated.js | 12 ++++++++++++ 3 files changed, 35 insertions(+) create mode 100644 js/Track/Model/Prepopulated.js create mode 100644 js/Track/library/Prepopulated.js diff --git a/expanded.html b/expanded.html index 7cd0a8bf..09b06f0f 100644 --- a/expanded.html +++ b/expanded.html @@ -31,6 +31,9 @@ + + + diff --git a/js/Track/Model/Prepopulated.js b/js/Track/Model/Prepopulated.js new file mode 100644 index 00000000..f35832fe --- /dev/null +++ b/js/Track/Model/Prepopulated.js @@ -0,0 +1,20 @@ +Genoverse.Track.Model.Prepopulated = Genoverse.Track.Model.extend({ + init: function () { + this.base(); // Don't pass reset argument in + }, + + setDefaults: function () { + this.data = this.prop('data') || []; + return this.base.apply(this, arguments); + }, + + getData: function (start, end) { + this.receiveData(this.data.sort(function (a, b) { return a.start - b.start; }), start, end); + return $.Deferred().resolveWith(this); + }, + + updateData: function (data) { + this.data = data; + this.track.reset(); + } +}); diff --git a/js/Track/library/Prepopulated.js b/js/Track/library/Prepopulated.js new file mode 100644 index 00000000..c48c25fd --- /dev/null +++ b/js/Track/library/Prepopulated.js @@ -0,0 +1,12 @@ +Genoverse.Track.Prepopulated = Genoverse.Track.extend({ + model: Genoverse.Track.Model.Prepopulated, + + setInterface: function () { + this.base(); + this._interface.data = 'model'; + }, + + updateData: function (data) { + this.model.updateData(data); + } +}); From a1d13255805f13b976392f14dfeee65c83224565 Mon Sep 17 00:00:00 2001 From: Simon Brent Date: Tue, 15 Mar 2016 17:04:09 +0000 Subject: [PATCH 26/59] Prepopulated models were annoying to use. Moved functionality into core model. --- expanded.html | 3 --- js/Track/Model.js | 20 ++++++++++++++++---- js/Track/Model/Prepopulated.js | 20 -------------------- js/Track/library/Prepopulated.js | 12 ------------ js/genoverse.combined.js | 20 ++++++++++++++++---- js/genoverse.combined.nojquery.js | 20 ++++++++++++++++---- 6 files changed, 48 insertions(+), 47 deletions(-) delete mode 100644 js/Track/Model/Prepopulated.js delete mode 100644 js/Track/library/Prepopulated.js diff --git a/expanded.html b/expanded.html index 09b06f0f..7cd0a8bf 100644 --- a/expanded.html +++ b/expanded.html @@ -31,9 +31,6 @@ - - - diff --git a/js/Track/Model.js b/js/Track/Model.js index da086bb5..647426f1 100644 --- a/js/Track/Model.js +++ b/js/Track/Model.js @@ -5,6 +5,7 @@ Genoverse.Track.Model = Base.extend({ xhrFields : undefined, url : undefined, urlParams : undefined, // hash of URL params + data : undefined, // is defined, will be used instead of fetching data from a source constructor: function (properties) { $.extend(this, properties); @@ -15,7 +16,7 @@ Genoverse.Track.Model = Base.extend({ init: function (reset) { this.setDefaults(reset); - if (reset) { + if (reset && !this.data) { for (var i in this.featuresById) { delete this.featuresById[i].position; } @@ -74,10 +75,16 @@ Genoverse.Track.Model = Base.extend({ start = Math.max(1, start); end = Math.min(this.browser.chromosomeSize, end); - var model = this; var deferred = $.Deferred(); - var bins = []; - var length = end - start + 1; + + if (typeof this.data !== 'undefined') { + this.receiveData(this.data.sort(function (a, b) { return a.start - b.start; }), start, end); + return deferred.resolveWith(this); + } + + var model = this; + var bins = []; + var length = end - start + 1; if (!this.url) { return deferred.resolveWith(this); @@ -163,6 +170,11 @@ Genoverse.Track.Model = Base.extend({ } }, + updateData: function (data) { + this.data = data; + this.track.reset(); + }, + setDataRange: function (start, end) { if (this.allData) { start = 1; diff --git a/js/Track/Model/Prepopulated.js b/js/Track/Model/Prepopulated.js deleted file mode 100644 index f35832fe..00000000 --- a/js/Track/Model/Prepopulated.js +++ /dev/null @@ -1,20 +0,0 @@ -Genoverse.Track.Model.Prepopulated = Genoverse.Track.Model.extend({ - init: function () { - this.base(); // Don't pass reset argument in - }, - - setDefaults: function () { - this.data = this.prop('data') || []; - return this.base.apply(this, arguments); - }, - - getData: function (start, end) { - this.receiveData(this.data.sort(function (a, b) { return a.start - b.start; }), start, end); - return $.Deferred().resolveWith(this); - }, - - updateData: function (data) { - this.data = data; - this.track.reset(); - } -}); diff --git a/js/Track/library/Prepopulated.js b/js/Track/library/Prepopulated.js deleted file mode 100644 index c48c25fd..00000000 --- a/js/Track/library/Prepopulated.js +++ /dev/null @@ -1,12 +0,0 @@ -Genoverse.Track.Prepopulated = Genoverse.Track.extend({ - model: Genoverse.Track.Model.Prepopulated, - - setInterface: function () { - this.base(); - this._interface.data = 'model'; - }, - - updateData: function (data) { - this.model.updateData(data); - } -}); diff --git a/js/genoverse.combined.js b/js/genoverse.combined.js index d33d4010..acaff122 100644 --- a/js/genoverse.combined.js +++ b/js/genoverse.combined.js @@ -3809,6 +3809,7 @@ Genoverse.Track.Model = Base.extend({ xhrFields : undefined, url : undefined, urlParams : undefined, // hash of URL params + data : undefined, // is defined, will be used instead of fetching data from a source constructor: function (properties) { $.extend(this, properties); @@ -3819,7 +3820,7 @@ Genoverse.Track.Model = Base.extend({ init: function (reset) { this.setDefaults(reset); - if (reset) { + if (reset && !this.data) { for (var i in this.featuresById) { delete this.featuresById[i].position; } @@ -3878,10 +3879,16 @@ Genoverse.Track.Model = Base.extend({ start = Math.max(1, start); end = Math.min(this.browser.chromosomeSize, end); - var model = this; var deferred = $.Deferred(); - var bins = []; - var length = end - start + 1; + + if (typeof this.data !== 'undefined') { + this.receiveData(this.data.sort(function (a, b) { return a.start - b.start; }), start, end); + return deferred.resolveWith(this); + } + + var model = this; + var bins = []; + var length = end - start + 1; if (!this.url) { return deferred.resolveWith(this); @@ -3967,6 +3974,11 @@ Genoverse.Track.Model = Base.extend({ } }, + updateData: function (data) { + this.data = data; + this.track.reset(); + }, + setDataRange: function (start, end) { if (this.allData) { start = 1; diff --git a/js/genoverse.combined.nojquery.js b/js/genoverse.combined.nojquery.js index 9e8b2137..632da1de 100644 --- a/js/genoverse.combined.nojquery.js +++ b/js/genoverse.combined.nojquery.js @@ -3804,6 +3804,7 @@ Genoverse.Track.Model = Base.extend({ xhrFields : undefined, url : undefined, urlParams : undefined, // hash of URL params + data : undefined, // is defined, will be used instead of fetching data from a source constructor: function (properties) { $.extend(this, properties); @@ -3814,7 +3815,7 @@ Genoverse.Track.Model = Base.extend({ init: function (reset) { this.setDefaults(reset); - if (reset) { + if (reset && !this.data) { for (var i in this.featuresById) { delete this.featuresById[i].position; } @@ -3873,10 +3874,16 @@ Genoverse.Track.Model = Base.extend({ start = Math.max(1, start); end = Math.min(this.browser.chromosomeSize, end); - var model = this; var deferred = $.Deferred(); - var bins = []; - var length = end - start + 1; + + if (typeof this.data !== 'undefined') { + this.receiveData(this.data.sort(function (a, b) { return a.start - b.start; }), start, end); + return deferred.resolveWith(this); + } + + var model = this; + var bins = []; + var length = end - start + 1; if (!this.url) { return deferred.resolveWith(this); @@ -3962,6 +3969,11 @@ Genoverse.Track.Model = Base.extend({ } }, + updateData: function (data) { + this.data = data; + this.track.reset(); + }, + setDataRange: function (start, end) { if (this.allData) { start = 1; From 0c58a19b5d735fca47cfba28dcbeb32471f4d9be Mon Sep 17 00:00:00 2001 From: Simon Brent Date: Wed, 16 Mar 2016 10:50:42 +0000 Subject: [PATCH 27/59] Make debug work more easily with models, views, and controllers --- js/Genoverse.js | 20 +++++++++++++++----- js/genoverse.combined.js | 20 +++++++++++++++----- js/genoverse.combined.nojquery.js | 20 +++++++++++++++----- 3 files changed, 45 insertions(+), 15 deletions(-) diff --git a/js/Genoverse.js b/js/Genoverse.js index 39ca7fc6..b3baffcf 100644 --- a/js/Genoverse.js +++ b/js/Genoverse.js @@ -1421,7 +1421,17 @@ var Genoverse = Base.extend({ var isBrowser = obj instanceof Genoverse; var mainObj = isBrowser || obj instanceof Genoverse.Track ? obj : obj.track; var events = isBrowser ? obj.events.browser : obj.browser.events.tracks; - var debug = (isBrowser ? 'Genoverse' : obj.id || obj.name || 'Track') + '.' + key; + var debug; + + if (mainObj.debug) { + debug = [ isBrowser ? 'Genoverse' : mainObj.id || mainObj.name || 'Track' ]; + + if (!isBrowser && obj !== mainObj) { + debug.push(obj instanceof Genoverse.Track.Controller ? 'Controller' : obj instanceof Genoverse.Track.Model ? 'Model' : 'View'); + } + + debug = debug.concat(key).join('.'); + } obj.functions[key] = obj[key]; @@ -1430,10 +1440,10 @@ var Genoverse = Base.extend({ var rtn; // Debugging functionality - // Enabled by "debug": true || { functionName: true, ...} option - if (obj.debug === true) { // if "debug": true, simply log function call + // Enabled by "debug": true || 'time' || { functionName: true, ...} option + if (mainObj.debug === true) { // if "debug": true, simply log function call console.log(debug); - } else if (typeof obj.debug === 'object' && obj.debug[key]) { // if debug: { functionName: true, ...}, log function time + } else if (mainObj.debug === 'time' || (typeof mainObj.debug === 'object' && mainObj.debug[key])) { // if debug: 'time' || { functionName: true, ...}, log function time console.time('time: ' + debug); } @@ -1454,7 +1464,7 @@ var Genoverse = Base.extend({ rtn = this.functions[key].apply(this, args); trigger.call(this, 'after'); - if (typeof obj.debug === 'object' && obj.debug[key]) { + if (mainObj.debug === 'time' || (typeof mainObj.debug === 'object' && mainObj.debug[key])) { console.timeEnd('time: ' + debug); } diff --git a/js/genoverse.combined.js b/js/genoverse.combined.js index acaff122..8224b20e 100644 --- a/js/genoverse.combined.js +++ b/js/genoverse.combined.js @@ -2761,7 +2761,17 @@ var Genoverse = Base.extend({ var isBrowser = obj instanceof Genoverse; var mainObj = isBrowser || obj instanceof Genoverse.Track ? obj : obj.track; var events = isBrowser ? obj.events.browser : obj.browser.events.tracks; - var debug = (isBrowser ? 'Genoverse' : obj.id || obj.name || 'Track') + '.' + key; + var debug; + + if (mainObj.debug) { + debug = [ isBrowser ? 'Genoverse' : mainObj.id || mainObj.name || 'Track' ]; + + if (!isBrowser && obj !== mainObj) { + debug.push(obj instanceof Genoverse.Track.Controller ? 'Controller' : obj instanceof Genoverse.Track.Model ? 'Model' : 'View'); + } + + debug = debug.concat(key).join('.'); + } obj.functions[key] = obj[key]; @@ -2770,10 +2780,10 @@ var Genoverse = Base.extend({ var rtn; // Debugging functionality - // Enabled by "debug": true || { functionName: true, ...} option - if (obj.debug === true) { // if "debug": true, simply log function call + // Enabled by "debug": true || 'time' || { functionName: true, ...} option + if (mainObj.debug === true) { // if "debug": true, simply log function call console.log(debug); - } else if (typeof obj.debug === 'object' && obj.debug[key]) { // if debug: { functionName: true, ...}, log function time + } else if (mainObj.debug === 'time' || (typeof mainObj.debug === 'object' && mainObj.debug[key])) { // if debug: 'time' || { functionName: true, ...}, log function time console.time('time: ' + debug); } @@ -2794,7 +2804,7 @@ var Genoverse = Base.extend({ rtn = this.functions[key].apply(this, args); trigger.call(this, 'after'); - if (typeof obj.debug === 'object' && obj.debug[key]) { + if (mainObj.debug === 'time' || (typeof mainObj.debug === 'object' && mainObj.debug[key])) { console.timeEnd('time: ' + debug); } diff --git a/js/genoverse.combined.nojquery.js b/js/genoverse.combined.nojquery.js index 632da1de..688cfe63 100644 --- a/js/genoverse.combined.nojquery.js +++ b/js/genoverse.combined.nojquery.js @@ -2756,7 +2756,17 @@ var Genoverse = Base.extend({ var isBrowser = obj instanceof Genoverse; var mainObj = isBrowser || obj instanceof Genoverse.Track ? obj : obj.track; var events = isBrowser ? obj.events.browser : obj.browser.events.tracks; - var debug = (isBrowser ? 'Genoverse' : obj.id || obj.name || 'Track') + '.' + key; + var debug; + + if (mainObj.debug) { + debug = [ isBrowser ? 'Genoverse' : mainObj.id || mainObj.name || 'Track' ]; + + if (!isBrowser && obj !== mainObj) { + debug.push(obj instanceof Genoverse.Track.Controller ? 'Controller' : obj instanceof Genoverse.Track.Model ? 'Model' : 'View'); + } + + debug = debug.concat(key).join('.'); + } obj.functions[key] = obj[key]; @@ -2765,10 +2775,10 @@ var Genoverse = Base.extend({ var rtn; // Debugging functionality - // Enabled by "debug": true || { functionName: true, ...} option - if (obj.debug === true) { // if "debug": true, simply log function call + // Enabled by "debug": true || 'time' || { functionName: true, ...} option + if (mainObj.debug === true) { // if "debug": true, simply log function call console.log(debug); - } else if (typeof obj.debug === 'object' && obj.debug[key]) { // if debug: { functionName: true, ...}, log function time + } else if (mainObj.debug === 'time' || (typeof mainObj.debug === 'object' && mainObj.debug[key])) { // if debug: 'time' || { functionName: true, ...}, log function time console.time('time: ' + debug); } @@ -2789,7 +2799,7 @@ var Genoverse = Base.extend({ rtn = this.functions[key].apply(this, args); trigger.call(this, 'after'); - if (typeof obj.debug === 'object' && obj.debug[key]) { + if (mainObj.debug === 'time' || (typeof mainObj.debug === 'object' && mainObj.debug[key])) { console.timeEnd('time: ' + debug); } From 715d0a3f2a2c57804b355d81af59128ef7172762 Mon Sep 17 00:00:00 2001 From: Simon Brent Date: Fri, 8 Apr 2016 15:55:52 +0100 Subject: [PATCH 28/59] Fixed VCF file rendering --- expanded.html | 3 +- js/Track/Model/SequenceVariation/VCF.js | 44 ----- js/Track/library/File/VCF.js | 2 +- js/genoverse.combined.js | 207 ++++++++++++++++++------ js/genoverse.combined.nojquery.js | 207 ++++++++++++++++++------ 5 files changed, 325 insertions(+), 138 deletions(-) delete mode 100644 js/Track/Model/SequenceVariation/VCF.js diff --git a/expanded.html b/expanded.html index 7cd0a8bf..fa4f6c34 100644 --- a/expanded.html +++ b/expanded.html @@ -42,9 +42,9 @@ + - @@ -61,6 +61,7 @@ + diff --git a/js/Track/Model/SequenceVariation/VCF.js b/js/Track/Model/SequenceVariation/VCF.js deleted file mode 100644 index e8355514..00000000 --- a/js/Track/Model/SequenceVariation/VCF.js +++ /dev/null @@ -1,44 +0,0 @@ -Genoverse.Track.Model.SequenceVariation.VCF = Genoverse.Track.Model.SequenceVariation.extend({ - dataType: 'text', - - parseData: function (text) { - var lines = text.split('\n'); - - for (var i = 0; i < lines.length; i++) { - if (!lines[i].length || lines[i].indexOf('#') === 0) { - continue; - } - - var fields = lines[i].split('\t'); - - if (fields.length < 5) { - continue; - } - - if (fields[0] === this.browser.chr || fields[0] === 'chr' + this.browser.chr) { - var id = fields.slice(0, 3).join('|'); - var start = parseInt(fields[1], 10); - var alleles = fields[4].split(','); - - alleles.unshift(fields[3]); - - for (var j = 0; j < alleles.length; j++) { - var end = start + alleles[j].length - 1; - - this.insertFeature({ - id : id + '|' + alleles[j], - sort : j, - start : start, - end : end, - width : end - start, - allele : j === 0 ? 'REF' : 'ALT', - sequence : alleles[j], - label : alleles[j], - labelColor : '#FFFFFF', - originalFeature : fields - }); - } - } - } - } -}); \ No newline at end of file diff --git a/js/Track/library/File/VCF.js b/js/Track/library/File/VCF.js index 6f440e68..1a57c6cb 100644 --- a/js/Track/library/File/VCF.js +++ b/js/Track/library/File/VCF.js @@ -1,6 +1,6 @@ Genoverse.Track.File.VCF = Genoverse.Track.File.extend({ name : 'VCF', - model : Genoverse.Track.Model.SequenceVariation.VCF, + model : Genoverse.Track.Model.File.VCF, autoHeight : false, populateMenu: function (feature) { diff --git a/js/genoverse.combined.js b/js/genoverse.combined.js index 8224b20e..85752316 100644 --- a/js/genoverse.combined.js +++ b/js/genoverse.combined.js @@ -4850,6 +4850,123 @@ Genoverse.Track.View.Sequence = Genoverse.Track.View.extend({ }); +Genoverse.Track.View.SequenceVariation = Genoverse.Track.View.Sequence.extend({ + featureHeight : 15, + featureMargin : { top: 0, right: 0, bottom: 4, left: 0 }, + bump : true, + showLegend : false, + + positionFeature: function (feature, params) { + var position = feature.position[params.scale]; + + if (feature.alt_allele) { + if (!position.positioned) { + position.reference = { end: position.start + feature.ref_allele.length * params.scale }; + } + + position.reference.x = position.reference.end - params.scaledStart; + } + + this.base(feature, params); + }, + + bumpFeature: function (bounds, feature) { + if (feature.alt_allele) { + this.base.apply(this, arguments); + } + }, + + draw: function (features, featureContext, labelContext, scale) { + var drawing = { seq: [], snv: [] }; + + for (var i = 0; i < features.length; i++) { + drawing[features[i].alt_allele ? 'snv' : 'seq'].push(features[i]); + } + + this.base(drawing.seq, featureContext, labelContext, scale); + this.highlightSNVs(drawing.snv, featureContext, scale); + this.base(drawing.snv, featureContext, labelContext, scale); + this.outlineSNVs(drawing.snv, featureContext, scale); // Redraw the outline for SNVs, since the feature will have been drawn on top of some of the outline created by highlightSNVs + }, + + highlightSNVs: function (features, context, scale) { + var position, positionX, positionY; + + for (var i = 0; i < features.length; i++) { + position = features[i].position[scale]; + positionX = [ position.X, position.reference.x, position.X + position.width ]; + + if (positionX[2] < 0 || positionX[0] > this.width) { + continue; + } + + if (positionX[0] < 0 || positionX[2] > this.width) { + this.truncateForDrawing(positionX); + } + + positionY = [ 0, position.Y - this.featureMargin.bottom / 2, position.Y, position.Y + this.featureHeight ]; + + if (!features[i].highlightColor) { + this.setHighlightColor(features[i]); + } + + context.strokeStyle = context.fillStyle = features[i].highlightColor; + context.lineWidth = 2; + + context.beginPath(); + context.moveTo(positionX[0], positionY[0]); + context.lineTo(positionX[1], positionY[0]); + context.lineTo(positionX[1], positionY[1]); + context.lineTo(positionX[2], positionY[2]); + context.lineTo(positionX[2], positionY[3]); + context.lineTo(positionX[0], positionY[3]); + context.closePath(); + context.stroke(); + + context.lineWidth = 1; + context.globalAlpha = 0.5; + + context.fill(); + + context.globalAlpha = 1; + } + }, + + outlineSNVs: function (features, context, scale) { + var position, positionX, positionY; + + for (var i = 0; i < features.length; i++) { + position = features[i].position[scale]; + positionX = [ position.X, position.X + position.width ]; + positionY = [ position.Y, position.Y + this.featureHeight ]; + + context.strokeStyle = features[i].highlightColor; + + context.lineWidth = 2; + + context.beginPath(); + context.moveTo(positionX[1], positionY[0]); + context.lineTo(positionX[1], positionY[1]); + context.lineTo(positionX[0], positionY[1]); + context.lineTo(positionX[0], positionY[0]); + context.stroke(); + + context.lineWidth = 1; + } + }, + + truncateForDrawing: function (positionX) { + for (var i in positionX) { + positionX[i] = Math.min(Math.max(positionX[i], -1), this.width + 1); + } + }, + + setHighlightColor: function (feature) { + feature.highlightColor = feature.alt_allele === '-' || feature.alt_allele.length < feature.ref_allele.length ? '#D31D00' : '#1DD300'; + } +}); + + Genoverse.Track.Model.SequenceVariation = Genoverse.Track.Model.extend({ seqModel: Genoverse.Track.Model.Sequence.Ensembl, @@ -4882,51 +4999,6 @@ Genoverse.Track.Model.SequenceVariation = Genoverse.Track.Model.extend({ } }); -Genoverse.Track.Model.SequenceVariation.VCF = Genoverse.Track.Model.SequenceVariation.extend({ - dataType: 'text', - - parseData: function (text) { - var lines = text.split('\n'); - - for (var i = 0; i < lines.length; i++) { - if (!lines[i].length || lines[i].indexOf('#') === 0) { - continue; - } - - var fields = lines[i].split('\t'); - - if (fields.length < 5) { - continue; - } - - if (fields[0] === this.browser.chr || fields[0] === 'chr' + this.browser.chr) { - var id = fields.slice(0, 3).join('|'); - var start = parseInt(fields[1], 10); - var alleles = fields[4].split(','); - - alleles.unshift(fields[3]); - - for (var j = 0; j < alleles.length; j++) { - var end = start + alleles[j].length - 1; - - this.insertFeature({ - id : id + '|' + alleles[j], - sort : j, - start : start, - end : end, - width : end - start, - allele : j === 0 ? 'REF' : 'ALT', - sequence : alleles[j], - label : alleles[j], - labelColor : '#FFFFFF', - originalFeature : fields - }); - } - } - } - } -}); - // Abstract Gene model // see sub-models for more specific examples Genoverse.Track.Model.Gene = Genoverse.Track.Model.extend({ @@ -5461,6 +5533,49 @@ Genoverse.Track.Model.File.GFF = Genoverse.Track.Model.File.extend({ Genoverse.Track.Model.File.GTF = Genoverse.Track.Model.File.GFF; +Genoverse.Track.Model.File.VCF = Genoverse.Track.Model.File.extend({ + parseData: function (text) { + var lines = text.split('\n'); + + for (var i = 0; i < lines.length; i++) { + if (!lines[i].length || lines[i].indexOf('#') === 0) { + continue; + } + + var fields = lines[i].split('\t'); + + if (fields.length < 5) { + continue; + } + + if (fields[0] === this.browser.chr || fields[0] === 'chr' + this.browser.chr) { + var id = fields.slice(0, 3).join('|'); + var start = parseInt(fields[1], 10); + var alleles = fields[4].split(','); + + alleles.unshift(fields[3]); + + for (var j = 0; j < alleles.length; j++) { + var end = start + alleles[j].length - 1; + + this.insertFeature({ + id : id + '|' + alleles[j], + sort : j, + start : start, + end : end, + width : end - start, + allele : j === 0 ? 'REF' : 'ALT', + sequence : alleles[j], + label : alleles[j], + labelColor : '#FFFFFF', + originalFeature : fields + }); + } + } + } + } +}); + Genoverse.Track.Chromosome = Genoverse.Track.extend({ id : 'chromosome', margin : 1, @@ -5844,7 +5959,7 @@ Genoverse.Track.File.GFF3 = Genoverse.Track.File.extend({ Genoverse.Track.File.VCF = Genoverse.Track.File.extend({ name : 'VCF', - model : Genoverse.Track.Model.SequenceVariation.VCF, + model : Genoverse.Track.Model.File.VCF, autoHeight : false, populateMenu: function (feature) { diff --git a/js/genoverse.combined.nojquery.js b/js/genoverse.combined.nojquery.js index 688cfe63..933c568d 100644 --- a/js/genoverse.combined.nojquery.js +++ b/js/genoverse.combined.nojquery.js @@ -4845,6 +4845,123 @@ Genoverse.Track.View.Sequence = Genoverse.Track.View.extend({ }); +Genoverse.Track.View.SequenceVariation = Genoverse.Track.View.Sequence.extend({ + featureHeight : 15, + featureMargin : { top: 0, right: 0, bottom: 4, left: 0 }, + bump : true, + showLegend : false, + + positionFeature: function (feature, params) { + var position = feature.position[params.scale]; + + if (feature.alt_allele) { + if (!position.positioned) { + position.reference = { end: position.start + feature.ref_allele.length * params.scale }; + } + + position.reference.x = position.reference.end - params.scaledStart; + } + + this.base(feature, params); + }, + + bumpFeature: function (bounds, feature) { + if (feature.alt_allele) { + this.base.apply(this, arguments); + } + }, + + draw: function (features, featureContext, labelContext, scale) { + var drawing = { seq: [], snv: [] }; + + for (var i = 0; i < features.length; i++) { + drawing[features[i].alt_allele ? 'snv' : 'seq'].push(features[i]); + } + + this.base(drawing.seq, featureContext, labelContext, scale); + this.highlightSNVs(drawing.snv, featureContext, scale); + this.base(drawing.snv, featureContext, labelContext, scale); + this.outlineSNVs(drawing.snv, featureContext, scale); // Redraw the outline for SNVs, since the feature will have been drawn on top of some of the outline created by highlightSNVs + }, + + highlightSNVs: function (features, context, scale) { + var position, positionX, positionY; + + for (var i = 0; i < features.length; i++) { + position = features[i].position[scale]; + positionX = [ position.X, position.reference.x, position.X + position.width ]; + + if (positionX[2] < 0 || positionX[0] > this.width) { + continue; + } + + if (positionX[0] < 0 || positionX[2] > this.width) { + this.truncateForDrawing(positionX); + } + + positionY = [ 0, position.Y - this.featureMargin.bottom / 2, position.Y, position.Y + this.featureHeight ]; + + if (!features[i].highlightColor) { + this.setHighlightColor(features[i]); + } + + context.strokeStyle = context.fillStyle = features[i].highlightColor; + context.lineWidth = 2; + + context.beginPath(); + context.moveTo(positionX[0], positionY[0]); + context.lineTo(positionX[1], positionY[0]); + context.lineTo(positionX[1], positionY[1]); + context.lineTo(positionX[2], positionY[2]); + context.lineTo(positionX[2], positionY[3]); + context.lineTo(positionX[0], positionY[3]); + context.closePath(); + context.stroke(); + + context.lineWidth = 1; + context.globalAlpha = 0.5; + + context.fill(); + + context.globalAlpha = 1; + } + }, + + outlineSNVs: function (features, context, scale) { + var position, positionX, positionY; + + for (var i = 0; i < features.length; i++) { + position = features[i].position[scale]; + positionX = [ position.X, position.X + position.width ]; + positionY = [ position.Y, position.Y + this.featureHeight ]; + + context.strokeStyle = features[i].highlightColor; + + context.lineWidth = 2; + + context.beginPath(); + context.moveTo(positionX[1], positionY[0]); + context.lineTo(positionX[1], positionY[1]); + context.lineTo(positionX[0], positionY[1]); + context.lineTo(positionX[0], positionY[0]); + context.stroke(); + + context.lineWidth = 1; + } + }, + + truncateForDrawing: function (positionX) { + for (var i in positionX) { + positionX[i] = Math.min(Math.max(positionX[i], -1), this.width + 1); + } + }, + + setHighlightColor: function (feature) { + feature.highlightColor = feature.alt_allele === '-' || feature.alt_allele.length < feature.ref_allele.length ? '#D31D00' : '#1DD300'; + } +}); + + Genoverse.Track.Model.SequenceVariation = Genoverse.Track.Model.extend({ seqModel: Genoverse.Track.Model.Sequence.Ensembl, @@ -4877,51 +4994,6 @@ Genoverse.Track.Model.SequenceVariation = Genoverse.Track.Model.extend({ } }); -Genoverse.Track.Model.SequenceVariation.VCF = Genoverse.Track.Model.SequenceVariation.extend({ - dataType: 'text', - - parseData: function (text) { - var lines = text.split('\n'); - - for (var i = 0; i < lines.length; i++) { - if (!lines[i].length || lines[i].indexOf('#') === 0) { - continue; - } - - var fields = lines[i].split('\t'); - - if (fields.length < 5) { - continue; - } - - if (fields[0] === this.browser.chr || fields[0] === 'chr' + this.browser.chr) { - var id = fields.slice(0, 3).join('|'); - var start = parseInt(fields[1], 10); - var alleles = fields[4].split(','); - - alleles.unshift(fields[3]); - - for (var j = 0; j < alleles.length; j++) { - var end = start + alleles[j].length - 1; - - this.insertFeature({ - id : id + '|' + alleles[j], - sort : j, - start : start, - end : end, - width : end - start, - allele : j === 0 ? 'REF' : 'ALT', - sequence : alleles[j], - label : alleles[j], - labelColor : '#FFFFFF', - originalFeature : fields - }); - } - } - } - } -}); - // Abstract Gene model // see sub-models for more specific examples Genoverse.Track.Model.Gene = Genoverse.Track.Model.extend({ @@ -5456,6 +5528,49 @@ Genoverse.Track.Model.File.GFF = Genoverse.Track.Model.File.extend({ Genoverse.Track.Model.File.GTF = Genoverse.Track.Model.File.GFF; +Genoverse.Track.Model.File.VCF = Genoverse.Track.Model.File.extend({ + parseData: function (text) { + var lines = text.split('\n'); + + for (var i = 0; i < lines.length; i++) { + if (!lines[i].length || lines[i].indexOf('#') === 0) { + continue; + } + + var fields = lines[i].split('\t'); + + if (fields.length < 5) { + continue; + } + + if (fields[0] === this.browser.chr || fields[0] === 'chr' + this.browser.chr) { + var id = fields.slice(0, 3).join('|'); + var start = parseInt(fields[1], 10); + var alleles = fields[4].split(','); + + alleles.unshift(fields[3]); + + for (var j = 0; j < alleles.length; j++) { + var end = start + alleles[j].length - 1; + + this.insertFeature({ + id : id + '|' + alleles[j], + sort : j, + start : start, + end : end, + width : end - start, + allele : j === 0 ? 'REF' : 'ALT', + sequence : alleles[j], + label : alleles[j], + labelColor : '#FFFFFF', + originalFeature : fields + }); + } + } + } + } +}); + Genoverse.Track.Chromosome = Genoverse.Track.extend({ id : 'chromosome', margin : 1, @@ -5839,7 +5954,7 @@ Genoverse.Track.File.GFF3 = Genoverse.Track.File.extend({ Genoverse.Track.File.VCF = Genoverse.Track.File.extend({ name : 'VCF', - model : Genoverse.Track.Model.SequenceVariation.VCF, + model : Genoverse.Track.Model.File.VCF, autoHeight : false, populateMenu: function (feature) { From 0eadae1187c83ec9dc868d66d7bb9930bda0b5fb Mon Sep 17 00:00:00 2001 From: Simon Brent Date: Fri, 22 Apr 2016 11:24:05 +0100 Subject: [PATCH 29/59] Removed import of script that no longer exists --- expanded.html | 1 - js/genoverse.combined.js | 43 ------------------------------- js/genoverse.combined.nojquery.js | 43 ------------------------------- 3 files changed, 87 deletions(-) diff --git a/expanded.html b/expanded.html index fa4f6c34..c98c0e28 100644 --- a/expanded.html +++ b/expanded.html @@ -61,7 +61,6 @@ - diff --git a/js/genoverse.combined.js b/js/genoverse.combined.js index 85752316..888f34ae 100644 --- a/js/genoverse.combined.js +++ b/js/genoverse.combined.js @@ -5533,49 +5533,6 @@ Genoverse.Track.Model.File.GFF = Genoverse.Track.Model.File.extend({ Genoverse.Track.Model.File.GTF = Genoverse.Track.Model.File.GFF; -Genoverse.Track.Model.File.VCF = Genoverse.Track.Model.File.extend({ - parseData: function (text) { - var lines = text.split('\n'); - - for (var i = 0; i < lines.length; i++) { - if (!lines[i].length || lines[i].indexOf('#') === 0) { - continue; - } - - var fields = lines[i].split('\t'); - - if (fields.length < 5) { - continue; - } - - if (fields[0] === this.browser.chr || fields[0] === 'chr' + this.browser.chr) { - var id = fields.slice(0, 3).join('|'); - var start = parseInt(fields[1], 10); - var alleles = fields[4].split(','); - - alleles.unshift(fields[3]); - - for (var j = 0; j < alleles.length; j++) { - var end = start + alleles[j].length - 1; - - this.insertFeature({ - id : id + '|' + alleles[j], - sort : j, - start : start, - end : end, - width : end - start, - allele : j === 0 ? 'REF' : 'ALT', - sequence : alleles[j], - label : alleles[j], - labelColor : '#FFFFFF', - originalFeature : fields - }); - } - } - } - } -}); - Genoverse.Track.Chromosome = Genoverse.Track.extend({ id : 'chromosome', margin : 1, diff --git a/js/genoverse.combined.nojquery.js b/js/genoverse.combined.nojquery.js index 933c568d..7ef6dd77 100644 --- a/js/genoverse.combined.nojquery.js +++ b/js/genoverse.combined.nojquery.js @@ -5528,49 +5528,6 @@ Genoverse.Track.Model.File.GFF = Genoverse.Track.Model.File.extend({ Genoverse.Track.Model.File.GTF = Genoverse.Track.Model.File.GFF; -Genoverse.Track.Model.File.VCF = Genoverse.Track.Model.File.extend({ - parseData: function (text) { - var lines = text.split('\n'); - - for (var i = 0; i < lines.length; i++) { - if (!lines[i].length || lines[i].indexOf('#') === 0) { - continue; - } - - var fields = lines[i].split('\t'); - - if (fields.length < 5) { - continue; - } - - if (fields[0] === this.browser.chr || fields[0] === 'chr' + this.browser.chr) { - var id = fields.slice(0, 3).join('|'); - var start = parseInt(fields[1], 10); - var alleles = fields[4].split(','); - - alleles.unshift(fields[3]); - - for (var j = 0; j < alleles.length; j++) { - var end = start + alleles[j].length - 1; - - this.insertFeature({ - id : id + '|' + alleles[j], - sort : j, - start : start, - end : end, - width : end - start, - allele : j === 0 ? 'REF' : 'ALT', - sequence : alleles[j], - label : alleles[j], - labelColor : '#FFFFFF', - originalFeature : fields - }); - } - } - } - } -}); - Genoverse.Track.Chromosome = Genoverse.Track.extend({ id : 'chromosome', margin : 1, From 12e3676af0e0be939d7588fbe6716a671eb9f133 Mon Sep 17 00:00:00 2001 From: Simon Brent Date: Fri, 22 Apr 2016 11:29:39 +0100 Subject: [PATCH 30/59] Revert last commit, and add the missing model --- expanded.html | 1 + js/Track/Model/File/VCF.js | 42 ++++++++++++++++++++++++++++++ js/genoverse.combined.js | 43 +++++++++++++++++++++++++++++++ js/genoverse.combined.nojquery.js | 43 +++++++++++++++++++++++++++++++ 4 files changed, 129 insertions(+) create mode 100644 js/Track/Model/File/VCF.js diff --git a/expanded.html b/expanded.html index c98c0e28..fa4f6c34 100644 --- a/expanded.html +++ b/expanded.html @@ -61,6 +61,7 @@ + diff --git a/js/Track/Model/File/VCF.js b/js/Track/Model/File/VCF.js new file mode 100644 index 00000000..f8eb1885 --- /dev/null +++ b/js/Track/Model/File/VCF.js @@ -0,0 +1,42 @@ +Genoverse.Track.Model.File.VCF = Genoverse.Track.Model.File.extend({ + parseData: function (text) { + var lines = text.split('\n'); + + for (var i = 0; i < lines.length; i++) { + if (!lines[i].length || lines[i].indexOf('#') === 0) { + continue; + } + + var fields = lines[i].split('\t'); + + if (fields.length < 5) { + continue; + } + + if (fields[0] === this.browser.chr || fields[0] === 'chr' + this.browser.chr) { + var id = fields.slice(0, 3).join('|'); + var start = parseInt(fields[1], 10); + var alleles = fields[4].split(','); + + alleles.unshift(fields[3]); + + for (var j = 0; j < alleles.length; j++) { + var end = start + alleles[j].length - 1; + + this.insertFeature({ + id : id + '|' + alleles[j], + sort : j, + start : start, + end : end, + width : end - start, + allele : j === 0 ? 'REF' : 'ALT', + sequence : alleles[j], + label : alleles[j], + labelColor : '#FFFFFF', + originalFeature : fields + }); + } + } + } + } +}); \ No newline at end of file diff --git a/js/genoverse.combined.js b/js/genoverse.combined.js index 888f34ae..85752316 100644 --- a/js/genoverse.combined.js +++ b/js/genoverse.combined.js @@ -5533,6 +5533,49 @@ Genoverse.Track.Model.File.GFF = Genoverse.Track.Model.File.extend({ Genoverse.Track.Model.File.GTF = Genoverse.Track.Model.File.GFF; +Genoverse.Track.Model.File.VCF = Genoverse.Track.Model.File.extend({ + parseData: function (text) { + var lines = text.split('\n'); + + for (var i = 0; i < lines.length; i++) { + if (!lines[i].length || lines[i].indexOf('#') === 0) { + continue; + } + + var fields = lines[i].split('\t'); + + if (fields.length < 5) { + continue; + } + + if (fields[0] === this.browser.chr || fields[0] === 'chr' + this.browser.chr) { + var id = fields.slice(0, 3).join('|'); + var start = parseInt(fields[1], 10); + var alleles = fields[4].split(','); + + alleles.unshift(fields[3]); + + for (var j = 0; j < alleles.length; j++) { + var end = start + alleles[j].length - 1; + + this.insertFeature({ + id : id + '|' + alleles[j], + sort : j, + start : start, + end : end, + width : end - start, + allele : j === 0 ? 'REF' : 'ALT', + sequence : alleles[j], + label : alleles[j], + labelColor : '#FFFFFF', + originalFeature : fields + }); + } + } + } + } +}); + Genoverse.Track.Chromosome = Genoverse.Track.extend({ id : 'chromosome', margin : 1, diff --git a/js/genoverse.combined.nojquery.js b/js/genoverse.combined.nojquery.js index 7ef6dd77..933c568d 100644 --- a/js/genoverse.combined.nojquery.js +++ b/js/genoverse.combined.nojquery.js @@ -5528,6 +5528,49 @@ Genoverse.Track.Model.File.GFF = Genoverse.Track.Model.File.extend({ Genoverse.Track.Model.File.GTF = Genoverse.Track.Model.File.GFF; +Genoverse.Track.Model.File.VCF = Genoverse.Track.Model.File.extend({ + parseData: function (text) { + var lines = text.split('\n'); + + for (var i = 0; i < lines.length; i++) { + if (!lines[i].length || lines[i].indexOf('#') === 0) { + continue; + } + + var fields = lines[i].split('\t'); + + if (fields.length < 5) { + continue; + } + + if (fields[0] === this.browser.chr || fields[0] === 'chr' + this.browser.chr) { + var id = fields.slice(0, 3).join('|'); + var start = parseInt(fields[1], 10); + var alleles = fields[4].split(','); + + alleles.unshift(fields[3]); + + for (var j = 0; j < alleles.length; j++) { + var end = start + alleles[j].length - 1; + + this.insertFeature({ + id : id + '|' + alleles[j], + sort : j, + start : start, + end : end, + width : end - start, + allele : j === 0 ? 'REF' : 'ALT', + sequence : alleles[j], + label : alleles[j], + labelColor : '#FFFFFF', + originalFeature : fields + }); + } + } + } + } +}); + Genoverse.Track.Chromosome = Genoverse.Track.extend({ id : 'chromosome', margin : 1, From b4f55f3513dfdc1553c1d71809cf646ff408a329 Mon Sep 17 00:00:00 2001 From: Simon Brent Date: Thu, 23 Jun 2016 09:11:07 +0100 Subject: [PATCH 31/59] Support partial featureMargin instead of featureMarginTop etc --- js/Track/View.js | 6 +++--- js/genoverse.combined.js | 14 +++++++++----- js/genoverse.combined.nojquery.js | 14 +++++++++----- 3 files changed, 21 insertions(+), 13 deletions(-) diff --git a/js/Track/View.js b/js/Track/View.js index 48a3865c..8f049cd5 100644 --- a/js/Track/View.js +++ b/js/Track/View.js @@ -28,11 +28,11 @@ Genoverse.Track.View = Base.extend({ setDefaults: function () { this.featureMargin = this.featureMargin || { top: 3, right: 1, bottom: 1, left: 0 }; - var margin = [ 'Top', 'Right', 'Bottom', 'Left' ]; + var margin = [ 'top', 'right', 'bottom', 'left' ]; for (var i = 0; i < margin.length; i++) { - if (typeof this['featureMargin' + margin[i]] === 'number') { - this.featureMargin[margin[i].toLowerCase()] = this['featureMargin' + margin[i]]; + if (typeof this.featureMargin[margin[i]] !== 'number') { + this.featureMargin[margin[i]] = 0; } } diff --git a/js/genoverse.combined.js b/js/genoverse.combined.js index 85752316..52bd38d1 100644 --- a/js/genoverse.combined.js +++ b/js/genoverse.combined.js @@ -2438,7 +2438,7 @@ var Genoverse = Base.extend({ if (el && el.length) { el.html(error); } else { - alert(error); + console.log(error); } this.failed = true; @@ -2842,7 +2842,7 @@ var Genoverse = Base.extend({ }); Genoverse.id = 0; -Genoverse.prototype.origin = ($('script[src]:last').attr('src').match(/(.*)js\/\w+/) || [])[1]; +Genoverse.prototype.origin = (($('script[src]:last').attr('src') || '').match(/(.*)js\/\w+/) || [])[1] || ''; $(function () { if (!$('link[href="' + Genoverse.prototype.origin + 'css/genoverse.css"]').length) { @@ -2852,6 +2852,10 @@ $(function () { window.Genoverse = Genoverse; +if (typeof module === 'object' && typeof module.exports === 'object') { + module.exports = Genoverse; +} + Genoverse.Track = Base.extend({ height : 12, // The height of the track_container div @@ -4108,11 +4112,11 @@ Genoverse.Track.View = Base.extend({ setDefaults: function () { this.featureMargin = this.featureMargin || { top: 3, right: 1, bottom: 1, left: 0 }; - var margin = [ 'Top', 'Right', 'Bottom', 'Left' ]; + var margin = [ 'top', 'right', 'bottom', 'left' ]; for (var i = 0; i < margin.length; i++) { - if (typeof this['featureMargin' + margin[i]] === 'number') { - this.featureMargin[margin[i].toLowerCase()] = this['featureMargin' + margin[i]]; + if (typeof this.featureMargin[margin[i]] !== 'number') { + this.featureMargin[margin[i]] = 0; } } diff --git a/js/genoverse.combined.nojquery.js b/js/genoverse.combined.nojquery.js index 933c568d..e6340a3a 100644 --- a/js/genoverse.combined.nojquery.js +++ b/js/genoverse.combined.nojquery.js @@ -2433,7 +2433,7 @@ var Genoverse = Base.extend({ if (el && el.length) { el.html(error); } else { - alert(error); + console.log(error); } this.failed = true; @@ -2837,7 +2837,7 @@ var Genoverse = Base.extend({ }); Genoverse.id = 0; -Genoverse.prototype.origin = ($('script[src]:last').attr('src').match(/(.*)js\/\w+/) || [])[1]; +Genoverse.prototype.origin = (($('script[src]:last').attr('src') || '').match(/(.*)js\/\w+/) || [])[1] || ''; $(function () { if (!$('link[href="' + Genoverse.prototype.origin + 'css/genoverse.css"]').length) { @@ -2847,6 +2847,10 @@ $(function () { window.Genoverse = Genoverse; +if (typeof module === 'object' && typeof module.exports === 'object') { + module.exports = Genoverse; +} + Genoverse.Track = Base.extend({ height : 12, // The height of the track_container div @@ -4103,11 +4107,11 @@ Genoverse.Track.View = Base.extend({ setDefaults: function () { this.featureMargin = this.featureMargin || { top: 3, right: 1, bottom: 1, left: 0 }; - var margin = [ 'Top', 'Right', 'Bottom', 'Left' ]; + var margin = [ 'top', 'right', 'bottom', 'left' ]; for (var i = 0; i < margin.length; i++) { - if (typeof this['featureMargin' + margin[i]] === 'number') { - this.featureMargin[margin[i].toLowerCase()] = this['featureMargin' + margin[i]]; + if (typeof this.featureMargin[margin[i]] !== 'number') { + this.featureMargin[margin[i]] = 0; } } From baef4407e66a51ff69beb740e3fdef2cce6e2ebb Mon Sep 17 00:00:00 2001 From: Simon Brent Date: Thu, 23 Jun 2016 16:59:12 +0100 Subject: [PATCH 32/59] When bumping features of variable height, bump based on height of features in place, not features being moved --- js/Track/View.js | 13 +++++++------ js/genoverse.combined.js | 13 +++++++------ js/genoverse.combined.nojquery.js | 13 +++++++------ 3 files changed, 21 insertions(+), 18 deletions(-) diff --git a/js/Track/View.js b/js/Track/View.js index 8f049cd5..b31a578e 100644 --- a/js/Track/View.js +++ b/js/Track/View.js @@ -137,7 +137,7 @@ Genoverse.Track.View = Base.extend({ x: feature.position[scale].start, y: feature.position[scale].Y, w: feature.position[scale].W, - h: feature.position[scale].H + this.featureMargin.top + h: feature.position[scale].H + (feature.marginTop || this.featureMargin.top) }; if (this.bump === true) { @@ -172,7 +172,7 @@ Genoverse.Track.View = Base.extend({ bumpFeature: function (bounds, feature, scale, tree) { var depth = 0; - var bump; + var bump, clash; do { if (this.depth && ++depth >= this.depth) { @@ -183,11 +183,12 @@ Genoverse.Track.View = Base.extend({ break; } - bump = false; + bump = false; + clash = tree.search(bounds)[0]; - if ((tree.search(bounds)[0] || feature).id !== feature.id) { - bounds.y += bounds.h; - bump = true; + if (clash && clash.id !== feature.id) { + bounds.y = clash.position[scale].Y + clash.position[scale].H + (clash.marginTop || this.featureMargin.top); + bump = true; } } while (bump); diff --git a/js/genoverse.combined.js b/js/genoverse.combined.js index 52bd38d1..66d7e9c3 100644 --- a/js/genoverse.combined.js +++ b/js/genoverse.combined.js @@ -4221,7 +4221,7 @@ Genoverse.Track.View = Base.extend({ x: feature.position[scale].start, y: feature.position[scale].Y, w: feature.position[scale].W, - h: feature.position[scale].H + this.featureMargin.top + h: feature.position[scale].H + (feature.marginTop || this.featureMargin.top) }; if (this.bump === true) { @@ -4256,7 +4256,7 @@ Genoverse.Track.View = Base.extend({ bumpFeature: function (bounds, feature, scale, tree) { var depth = 0; - var bump; + var bump, clash; do { if (this.depth && ++depth >= this.depth) { @@ -4267,11 +4267,12 @@ Genoverse.Track.View = Base.extend({ break; } - bump = false; + bump = false; + clash = tree.search(bounds)[0]; - if ((tree.search(bounds)[0] || feature).id !== feature.id) { - bounds.y += bounds.h; - bump = true; + if (clash && clash.id !== feature.id) { + bounds.y = clash.position[scale].Y + clash.position[scale].H + (clash.marginTop || this.featureMargin.top); + bump = true; } } while (bump); diff --git a/js/genoverse.combined.nojquery.js b/js/genoverse.combined.nojquery.js index e6340a3a..67d2256c 100644 --- a/js/genoverse.combined.nojquery.js +++ b/js/genoverse.combined.nojquery.js @@ -4216,7 +4216,7 @@ Genoverse.Track.View = Base.extend({ x: feature.position[scale].start, y: feature.position[scale].Y, w: feature.position[scale].W, - h: feature.position[scale].H + this.featureMargin.top + h: feature.position[scale].H + (feature.marginTop || this.featureMargin.top) }; if (this.bump === true) { @@ -4251,7 +4251,7 @@ Genoverse.Track.View = Base.extend({ bumpFeature: function (bounds, feature, scale, tree) { var depth = 0; - var bump; + var bump, clash; do { if (this.depth && ++depth >= this.depth) { @@ -4262,11 +4262,12 @@ Genoverse.Track.View = Base.extend({ break; } - bump = false; + bump = false; + clash = tree.search(bounds)[0]; - if ((tree.search(bounds)[0] || feature).id !== feature.id) { - bounds.y += bounds.h; - bump = true; + if (clash && clash.id !== feature.id) { + bounds.y = clash.position[scale].Y + clash.position[scale].H + (clash.marginTop || this.featureMargin.top); + bump = true; } } while (bump); From e15dff7bbdd2036e335878a23649aeab6f1e4a88 Mon Sep 17 00:00:00 2001 From: Simon Brent Date: Fri, 24 Jun 2016 13:29:46 +0100 Subject: [PATCH 33/59] Fixes for label bumping --- js/Track/View.js | 12 +++++++++--- js/genoverse.combined.js | 12 +++++++++--- js/genoverse.combined.nojquery.js | 12 +++++++++--- 3 files changed, 27 insertions(+), 9 deletions(-) diff --git a/js/Track/View.js b/js/Track/View.js index b31a578e..ad82377d 100644 --- a/js/Track/View.js +++ b/js/Track/View.js @@ -41,6 +41,8 @@ Genoverse.Track.View = Base.extend({ this.font = this.fontWeight + ' ' + this.fontHeight + 'px ' + this.fontFamily; this.labelUnits = [ 'bp', 'kb', 'Mb', 'Gb', 'Tb' ]; + this.context.font = this.font; + if (this.labels && this.labels !== 'overlay' && (this.depth || this.bump === 'labels')) { this.labels = 'separate'; } @@ -140,13 +142,15 @@ Genoverse.Track.View = Base.extend({ h: feature.position[scale].H + (feature.marginTop || this.featureMargin.top) }; + feature.position[scale].bounds = bounds; + if (this.bump === true) { this.bumpFeature(bounds, feature, scale, this.scaleSettings[scale].featurePositions); } this.scaleSettings[scale].featurePositions.insert(bounds, feature); - feature.position[scale].bottom = feature.position[scale].Y + feature.position[scale].H + params.margin; + feature.position[scale].bottom = feature.position[scale].Y + bounds.h + params.margin; if (feature.position[scale].label) { var f = $.extend(true, {}, feature); // FIXME: hack to avoid changing feature.position[scale].Y in bumpFeature @@ -170,8 +174,10 @@ Genoverse.Track.View = Base.extend({ params.height = Math.max(params.height, params.featureHeight + params.labelHeight); }, + // FIXME: should label bumping bounds be distinct from feature bumping bounds when label is smaller than feature? bumpFeature: function (bounds, feature, scale, tree) { - var depth = 0; + var depth = 0; + var labels = tree === this.scaleSettings[scale].labelPositions && tree !== this.scaleSettings[scale].featurePositions; var bump, clash; do { @@ -187,7 +193,7 @@ Genoverse.Track.View = Base.extend({ clash = tree.search(bounds)[0]; if (clash && clash.id !== feature.id) { - bounds.y = clash.position[scale].Y + clash.position[scale].H + (clash.marginTop || this.featureMargin.top); + bounds.y = clash.position[scale].bounds.y + clash.position[scale][labels ? 'label' : 'bounds'].h; bump = true; } } while (bump); diff --git a/js/genoverse.combined.js b/js/genoverse.combined.js index 66d7e9c3..173e203b 100644 --- a/js/genoverse.combined.js +++ b/js/genoverse.combined.js @@ -4125,6 +4125,8 @@ Genoverse.Track.View = Base.extend({ this.font = this.fontWeight + ' ' + this.fontHeight + 'px ' + this.fontFamily; this.labelUnits = [ 'bp', 'kb', 'Mb', 'Gb', 'Tb' ]; + this.context.font = this.font; + if (this.labels && this.labels !== 'overlay' && (this.depth || this.bump === 'labels')) { this.labels = 'separate'; } @@ -4224,13 +4226,15 @@ Genoverse.Track.View = Base.extend({ h: feature.position[scale].H + (feature.marginTop || this.featureMargin.top) }; + feature.position[scale].bounds = bounds; + if (this.bump === true) { this.bumpFeature(bounds, feature, scale, this.scaleSettings[scale].featurePositions); } this.scaleSettings[scale].featurePositions.insert(bounds, feature); - feature.position[scale].bottom = feature.position[scale].Y + feature.position[scale].H + params.margin; + feature.position[scale].bottom = feature.position[scale].Y + bounds.h + params.margin; if (feature.position[scale].label) { var f = $.extend(true, {}, feature); // FIXME: hack to avoid changing feature.position[scale].Y in bumpFeature @@ -4254,8 +4258,10 @@ Genoverse.Track.View = Base.extend({ params.height = Math.max(params.height, params.featureHeight + params.labelHeight); }, + // FIXME: should label bumping bounds be distinct from feature bumping bounds when label is smaller than feature? bumpFeature: function (bounds, feature, scale, tree) { - var depth = 0; + var depth = 0; + var labels = tree === this.scaleSettings[scale].labelPositions && tree !== this.scaleSettings[scale].featurePositions; var bump, clash; do { @@ -4271,7 +4277,7 @@ Genoverse.Track.View = Base.extend({ clash = tree.search(bounds)[0]; if (clash && clash.id !== feature.id) { - bounds.y = clash.position[scale].Y + clash.position[scale].H + (clash.marginTop || this.featureMargin.top); + bounds.y = clash.position[scale].bounds.y + clash.position[scale][labels ? 'label' : 'bounds'].h; bump = true; } } while (bump); diff --git a/js/genoverse.combined.nojquery.js b/js/genoverse.combined.nojquery.js index 67d2256c..6864b280 100644 --- a/js/genoverse.combined.nojquery.js +++ b/js/genoverse.combined.nojquery.js @@ -4120,6 +4120,8 @@ Genoverse.Track.View = Base.extend({ this.font = this.fontWeight + ' ' + this.fontHeight + 'px ' + this.fontFamily; this.labelUnits = [ 'bp', 'kb', 'Mb', 'Gb', 'Tb' ]; + this.context.font = this.font; + if (this.labels && this.labels !== 'overlay' && (this.depth || this.bump === 'labels')) { this.labels = 'separate'; } @@ -4219,13 +4221,15 @@ Genoverse.Track.View = Base.extend({ h: feature.position[scale].H + (feature.marginTop || this.featureMargin.top) }; + feature.position[scale].bounds = bounds; + if (this.bump === true) { this.bumpFeature(bounds, feature, scale, this.scaleSettings[scale].featurePositions); } this.scaleSettings[scale].featurePositions.insert(bounds, feature); - feature.position[scale].bottom = feature.position[scale].Y + feature.position[scale].H + params.margin; + feature.position[scale].bottom = feature.position[scale].Y + bounds.h + params.margin; if (feature.position[scale].label) { var f = $.extend(true, {}, feature); // FIXME: hack to avoid changing feature.position[scale].Y in bumpFeature @@ -4249,8 +4253,10 @@ Genoverse.Track.View = Base.extend({ params.height = Math.max(params.height, params.featureHeight + params.labelHeight); }, + // FIXME: should label bumping bounds be distinct from feature bumping bounds when label is smaller than feature? bumpFeature: function (bounds, feature, scale, tree) { - var depth = 0; + var depth = 0; + var labels = tree === this.scaleSettings[scale].labelPositions && tree !== this.scaleSettings[scale].featurePositions; var bump, clash; do { @@ -4266,7 +4272,7 @@ Genoverse.Track.View = Base.extend({ clash = tree.search(bounds)[0]; if (clash && clash.id !== feature.id) { - bounds.y = clash.position[scale].Y + clash.position[scale].H + (clash.marginTop || this.featureMargin.top); + bounds.y = clash.position[scale].bounds.y + clash.position[scale][labels ? 'label' : 'bounds'].h; bump = true; } } while (bump); From 7b292338de4cc8e95d03dbadbb598b0c736cae95 Mon Sep 17 00:00:00 2001 From: Simon Brent Date: Mon, 27 Jun 2016 16:34:13 +0100 Subject: [PATCH 34/59] Allow track.fontColor to take precedence over feature.color for labels --- js/Track/View.js | 4 ++-- js/genoverse.combined.js | 6 +++--- js/genoverse.combined.nojquery.js | 6 +++--- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/js/Track/View.js b/js/Track/View.js index ad82377d..f708c910 100644 --- a/js/Track/View.js +++ b/js/Track/View.js @@ -2,7 +2,7 @@ Genoverse.Track.View = Base.extend({ fontHeight : 10, fontFamily : 'sans-serif', fontWeight : 'normal', - fontColor : '#000000', + fontColor : undefined, // label color defaults to this, or feature color, or track.color (below), in that order of precedence color : '#000000', minScaledWidth : 0.5, widthCorrection : 1, // Pixels to add to the end of a feature when scale > 1 - ensures that 1bp features are always at least 1px wide @@ -335,7 +335,7 @@ Genoverse.Track.View = Base.extend({ }, setLabelColor: function (feature) { - feature.labelColor = feature.color || this.fontColor || this.color; + feature.labelColor = this.fontColor || feature.color || this.color; }, // Method to lighten a colour by an amount, adapted from http://stackoverflow.com/questions/5560248/programmatically-lighten-or-darken-a-hex-color-or-rgb-and-blend-colors diff --git a/js/genoverse.combined.js b/js/genoverse.combined.js index 173e203b..25b49887 100644 --- a/js/genoverse.combined.js +++ b/js/genoverse.combined.js @@ -4086,7 +4086,7 @@ Genoverse.Track.View = Base.extend({ fontHeight : 10, fontFamily : 'sans-serif', fontWeight : 'normal', - fontColor : '#000000', + fontColor : undefined, // label color defaults to this, or feature color, or track.color (below), in that order of precedence color : '#000000', minScaledWidth : 0.5, widthCorrection : 1, // Pixels to add to the end of a feature when scale > 1 - ensures that 1bp features are always at least 1px wide @@ -4360,7 +4360,7 @@ Genoverse.Track.View = Base.extend({ var spacing = width / n; var label, start, j, y, currentY, h; - if (this.repeatLabels && scale > 1) { + if (this.repeatLabels && (scale > 1 || this.labels !== 'overlay')) { // Ensure there's always a label in each image spacing = this.browser.length * scale; n = Math.ceil(width / spacing); } @@ -4419,7 +4419,7 @@ Genoverse.Track.View = Base.extend({ }, setLabelColor: function (feature) { - feature.labelColor = feature.color || this.fontColor || this.color; + feature.labelColor = this.fontColor || feature.color || this.color; }, // Method to lighten a colour by an amount, adapted from http://stackoverflow.com/questions/5560248/programmatically-lighten-or-darken-a-hex-color-or-rgb-and-blend-colors diff --git a/js/genoverse.combined.nojquery.js b/js/genoverse.combined.nojquery.js index 6864b280..da171720 100644 --- a/js/genoverse.combined.nojquery.js +++ b/js/genoverse.combined.nojquery.js @@ -4081,7 +4081,7 @@ Genoverse.Track.View = Base.extend({ fontHeight : 10, fontFamily : 'sans-serif', fontWeight : 'normal', - fontColor : '#000000', + fontColor : undefined, // label color defaults to this, or feature color, or track.color (below), in that order of precedence color : '#000000', minScaledWidth : 0.5, widthCorrection : 1, // Pixels to add to the end of a feature when scale > 1 - ensures that 1bp features are always at least 1px wide @@ -4355,7 +4355,7 @@ Genoverse.Track.View = Base.extend({ var spacing = width / n; var label, start, j, y, currentY, h; - if (this.repeatLabels && scale > 1) { + if (this.repeatLabels && (scale > 1 || this.labels !== 'overlay')) { // Ensure there's always a label in each image spacing = this.browser.length * scale; n = Math.ceil(width / spacing); } @@ -4414,7 +4414,7 @@ Genoverse.Track.View = Base.extend({ }, setLabelColor: function (feature) { - feature.labelColor = feature.color || this.fontColor || this.color; + feature.labelColor = this.fontColor || feature.color || this.color; }, // Method to lighten a colour by an amount, adapted from http://stackoverflow.com/questions/5560248/programmatically-lighten-or-darken-a-hex-color-or-rgb-and-blend-colors From af5e4a754794b3414177eed98dec1d50da96c39c Mon Sep 17 00:00:00 2001 From: Simon Brent Date: Mon, 27 Jun 2016 16:34:37 +0100 Subject: [PATCH 35/59] Don't repeat non overlaid labels more than necessary --- js/Track/View.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/Track/View.js b/js/Track/View.js index f708c910..33c9474c 100644 --- a/js/Track/View.js +++ b/js/Track/View.js @@ -276,7 +276,7 @@ Genoverse.Track.View = Base.extend({ var spacing = width / n; var label, start, j, y, currentY, h; - if (this.repeatLabels && scale > 1) { + if (this.repeatLabels && (scale > 1 || this.labels !== 'overlay')) { // Ensure there's always a label in each image spacing = this.browser.length * scale; n = Math.ceil(width / spacing); } From f8430ba4605e96650dc51e4dad389a1d9f8b0399 Mon Sep 17 00:00:00 2001 From: Simon Brent Date: Mon, 11 Jul 2016 11:03:54 +0100 Subject: [PATCH 36/59] Fixes for sequence and sequence variant tracks --- js/Track/Model.js | 2 +- js/Track/Model/SequenceVariation.js | 8 ++++++++ js/Track/View/Sequence.js | 4 ++-- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/js/Track/Model.js b/js/Track/Model.js index 647426f1..1b828ad6 100644 --- a/js/Track/Model.js +++ b/js/Track/Model.js @@ -78,7 +78,7 @@ Genoverse.Track.Model = Base.extend({ var deferred = $.Deferred(); if (typeof this.data !== 'undefined') { - this.receiveData(this.data.sort(function (a, b) { return a.start - b.start; }), start, end); + this.receiveData(typeof this.data.sort === 'function' ? this.data.sort(function (a, b) { return a.start - b.start; }) : this.data, start, end); return deferred.resolveWith(this); } diff --git a/js/Track/Model/SequenceVariation.js b/js/Track/Model/SequenceVariation.js index fcddf74a..eec9a317 100644 --- a/js/Track/Model/SequenceVariation.js +++ b/js/Track/Model/SequenceVariation.js @@ -21,6 +21,14 @@ Genoverse.Track.Model.SequenceVariation = Genoverse.Track.Model.extend({ return deferred; }, + insertFeature: function (feature) { + return this.base($.extend(feature, { + end : feature.start + feature.alt_allele.length - 1, + length : feature.alt_allele.length, + sequence : feature.alt_allele + })); + }, + checkDataRange: function (start, end) { return this.base(start, end) && this.getSeqModel().checkDataRange(start, end); }, diff --git a/js/Track/View/Sequence.js b/js/Track/View/Sequence.js index c31c466b..c8771452 100644 --- a/js/Track/View/Sequence.js +++ b/js/Track/View/Sequence.js @@ -9,7 +9,7 @@ Genoverse.Track.View.Sequence = Genoverse.Track.View.extend({ var lowerCase = this.prop('lowerCase'); - this.labelYOffset = typeof this.labelYOffset === 'number' ? this.labelYOffset : (this.featureHeight + (lowerCase ? 0 : 1)) / 2; + this.labelYOffset = typeof this.labelYOffset === 'number' ? this.labelYOffset : (this.featureHeight + 1) / 2; this.widestLabel = typeof this.widestLabel === 'string' ? this.widestLabel : lowerCase ? 'g' : 'G'; this.labelWidth = {}; @@ -21,7 +21,7 @@ Genoverse.Track.View.Sequence = Genoverse.Track.View.extend({ } for (key in this.labelColors) { - this.colors[key.toLowerCase()] = this.colors[key]; + this.labelColors[key.toLowerCase()] = this.labelColors[key]; } } }, From e1f925dfd2e79997b7a7c1f790885a69ddb1f378 Mon Sep 17 00:00:00 2001 From: Simon Brent Date: Thu, 30 Jun 2016 09:20:39 +0100 Subject: [PATCH 37/59] Fix intron heights --- js/Track/View/Transcript.js | 15 ++++++++++----- js/genoverse.combined.js | 15 ++++++++++----- js/genoverse.combined.nojquery.js | 15 ++++++++++----- 3 files changed, 30 insertions(+), 15 deletions(-) diff --git a/js/Track/View/Transcript.js b/js/Track/View/Transcript.js index 80bcabf6..8a14300a 100644 --- a/js/Track/View/Transcript.js +++ b/js/Track/View/Transcript.js @@ -9,10 +9,12 @@ Genoverse.Track.View.Transcript = Genoverse.Track.View.extend({ drawFeature: function (transcript, featureContext, labelContext, scale) { this.setFeatureColor(transcript); - var exons = ($.isArray(transcript.exons) ? $.extend(true, [], transcript.exons) : $.map($.extend(true, {}, transcript.exons || {}), function (e) { return e; })).sort(function (a, b) { return a.start - b.start; }); - var cds = ($.isArray(transcript.cds) ? $.extend(true, [], transcript.cds) : $.map($.extend(true, {}, transcript.cds || {}), function (c) { return c; })).sort(function (a, b) { return a.start - b.start; }); - var add = Math.max(scale, this.widthCorrection); - var coding = {}; + var exons = ($.isArray(transcript.exons) ? $.extend(true, [], transcript.exons) : $.map($.extend(true, {}, transcript.exons || {}), function (e) { return e; })).sort(function (a, b) { return a.start - b.start; }); + var cds = ($.isArray(transcript.cds) ? $.extend(true, [], transcript.cds) : $.map($.extend(true, {}, transcript.cds || {}), function (c) { return c; })).sort(function (a, b) { return a.start - b.start; }); + var add = Math.max(scale, this.widthCorrection); + var coding = {}; + var cdsStart = 9e99; + var cdsEnd = -9e99; var i, x, w; // Get intron lines to be drawn off the left and right edges of the image @@ -32,6 +34,9 @@ Genoverse.Track.View.Transcript = Genoverse.Track.View.extend({ coding[cds[i].start + ':' + cds[i].end] = true; + cdsStart = Math.min(cdsStart, cds[i].start); + cdsEnd = Math.max(cdsEnd, cds[i].end); + if (x > this.width || x + w < 0) { continue; } @@ -63,7 +68,7 @@ Genoverse.Track.View.Transcript = Genoverse.Track.View.extend({ x : x, y : transcript.y + transcript.height / 2, width : w, - height : (transcript.height - (coding[exons[i].start + ':' + exons[i].end] ? 0 : 3)) / 2 * (transcript.strand > 0 ? -1 : 1) + height : (transcript.height - (exons[i - 1].end >= cdsStart && exons[i].start <= cdsEnd ? 0 : 3)) / 2 * (transcript.strand > 0 ? -1 : 1) }, featureContext); } } diff --git a/js/genoverse.combined.js b/js/genoverse.combined.js index 25b49887..50b081c8 100644 --- a/js/genoverse.combined.js +++ b/js/genoverse.combined.js @@ -5225,10 +5225,12 @@ Genoverse.Track.View.Transcript = Genoverse.Track.View.extend({ drawFeature: function (transcript, featureContext, labelContext, scale) { this.setFeatureColor(transcript); - var exons = ($.isArray(transcript.exons) ? $.extend(true, [], transcript.exons) : $.map($.extend(true, {}, transcript.exons || {}), function (e) { return e; })).sort(function (a, b) { return a.start - b.start; }); - var cds = ($.isArray(transcript.cds) ? $.extend(true, [], transcript.cds) : $.map($.extend(true, {}, transcript.cds || {}), function (c) { return c; })).sort(function (a, b) { return a.start - b.start; }); - var add = Math.max(scale, this.widthCorrection); - var coding = {}; + var exons = ($.isArray(transcript.exons) ? $.extend(true, [], transcript.exons) : $.map($.extend(true, {}, transcript.exons || {}), function (e) { return e; })).sort(function (a, b) { return a.start - b.start; }); + var cds = ($.isArray(transcript.cds) ? $.extend(true, [], transcript.cds) : $.map($.extend(true, {}, transcript.cds || {}), function (c) { return c; })).sort(function (a, b) { return a.start - b.start; }); + var add = Math.max(scale, this.widthCorrection); + var coding = {}; + var cdsStart = 9e99; + var cdsEnd = -9e99; var i, x, w; // Get intron lines to be drawn off the left and right edges of the image @@ -5248,6 +5250,9 @@ Genoverse.Track.View.Transcript = Genoverse.Track.View.extend({ coding[cds[i].start + ':' + cds[i].end] = true; + cdsStart = Math.min(cdsStart, cds[i].start); + cdsEnd = Math.max(cdsEnd, cds[i].end); + if (x > this.width || x + w < 0) { continue; } @@ -5279,7 +5284,7 @@ Genoverse.Track.View.Transcript = Genoverse.Track.View.extend({ x : x, y : transcript.y + transcript.height / 2, width : w, - height : (transcript.height - (coding[exons[i].start + ':' + exons[i].end] ? 0 : 3)) / 2 * (transcript.strand > 0 ? -1 : 1) + height : (transcript.height - (exons[i - 1].end >= cdsStart && exons[i].start <= cdsEnd ? 0 : 3)) / 2 * (transcript.strand > 0 ? -1 : 1) }, featureContext); } } diff --git a/js/genoverse.combined.nojquery.js b/js/genoverse.combined.nojquery.js index da171720..e16601aa 100644 --- a/js/genoverse.combined.nojquery.js +++ b/js/genoverse.combined.nojquery.js @@ -5220,10 +5220,12 @@ Genoverse.Track.View.Transcript = Genoverse.Track.View.extend({ drawFeature: function (transcript, featureContext, labelContext, scale) { this.setFeatureColor(transcript); - var exons = ($.isArray(transcript.exons) ? $.extend(true, [], transcript.exons) : $.map($.extend(true, {}, transcript.exons || {}), function (e) { return e; })).sort(function (a, b) { return a.start - b.start; }); - var cds = ($.isArray(transcript.cds) ? $.extend(true, [], transcript.cds) : $.map($.extend(true, {}, transcript.cds || {}), function (c) { return c; })).sort(function (a, b) { return a.start - b.start; }); - var add = Math.max(scale, this.widthCorrection); - var coding = {}; + var exons = ($.isArray(transcript.exons) ? $.extend(true, [], transcript.exons) : $.map($.extend(true, {}, transcript.exons || {}), function (e) { return e; })).sort(function (a, b) { return a.start - b.start; }); + var cds = ($.isArray(transcript.cds) ? $.extend(true, [], transcript.cds) : $.map($.extend(true, {}, transcript.cds || {}), function (c) { return c; })).sort(function (a, b) { return a.start - b.start; }); + var add = Math.max(scale, this.widthCorrection); + var coding = {}; + var cdsStart = 9e99; + var cdsEnd = -9e99; var i, x, w; // Get intron lines to be drawn off the left and right edges of the image @@ -5243,6 +5245,9 @@ Genoverse.Track.View.Transcript = Genoverse.Track.View.extend({ coding[cds[i].start + ':' + cds[i].end] = true; + cdsStart = Math.min(cdsStart, cds[i].start); + cdsEnd = Math.max(cdsEnd, cds[i].end); + if (x > this.width || x + w < 0) { continue; } @@ -5274,7 +5279,7 @@ Genoverse.Track.View.Transcript = Genoverse.Track.View.extend({ x : x, y : transcript.y + transcript.height / 2, width : w, - height : (transcript.height - (coding[exons[i].start + ':' + exons[i].end] ? 0 : 3)) / 2 * (transcript.strand > 0 ? -1 : 1) + height : (transcript.height - (exons[i - 1].end >= cdsStart && exons[i].start <= cdsEnd ? 0 : 3)) / 2 * (transcript.strand > 0 ? -1 : 1) }, featureContext); } } From 0c7605f9c800db5502ea1a0237f39491989379b4 Mon Sep 17 00:00:00 2001 From: Simon Brent Date: Tue, 19 Jul 2016 12:53:15 +0100 Subject: [PATCH 38/59] Put genomes in the Genoverse namespace --- js/Genoverse.js | 8 ++++---- js/genomes/grch37.js | 2 +- js/genomes/grch38.js | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/js/Genoverse.js b/js/Genoverse.js index b3baffcf..23808bb0 100644 --- a/js/Genoverse.js +++ b/js/Genoverse.js @@ -63,10 +63,9 @@ var Genoverse = Base.extend({ dataType : 'script', context : this, success : function () { - try { - this.genome = eval(genomeName); - } catch (e) { - console.log(e); + this.genome = Genoverse.Genomes[genomeName]; + + if (!this.genome) { this.die('Unable to load genome ' + genomeName); } } @@ -1397,6 +1396,7 @@ var Genoverse = Base.extend({ } } }, { + Genomes: {}, Plugins: {}, wrapFunctions: function (obj) { diff --git a/js/genomes/grch37.js b/js/genomes/grch37.js index a0a79f78..dbc044e7 100644 --- a/js/genomes/grch37.js +++ b/js/genomes/grch37.js @@ -1,4 +1,4 @@ -window.grch37 = { +Genoverse.Genomes.grch37 = { "1": { "size" : 249250621, "bands" : [ diff --git a/js/genomes/grch38.js b/js/genomes/grch38.js index ac530789..dcfb2a59 100644 --- a/js/genomes/grch38.js +++ b/js/genomes/grch38.js @@ -1,4 +1,4 @@ -window.grch38 = { +Genoverse.Genomes.grch38 = { "1": { "size" : 248956422, "bands" : [ From 6c04ec70b5a56b9e5557c88963d5cfbe5b6f42cb Mon Sep 17 00:00:00 2001 From: Simon Brent Date: Tue, 19 Jul 2016 15:02:28 +0100 Subject: [PATCH 39/59] Remove old stuff --- bam.html | 190 ------------------------ combined.html | 28 ---- examples/genoverse.org/styles.css | 45 ------ examples/tomato/SequenceVariation.js | 62 -------- examples/tomato/index.html | 75 ---------- index.html | 81 +++++----- ion.html | 214 --------------------------- js/genomes/node.js | 63 -------- js/genomes/tomato.js | 51 ------- js/genoverse.combined.js | 34 +++-- js/genoverse.combined.nojquery.js | 25 ++-- 11 files changed, 84 insertions(+), 784 deletions(-) delete mode 100644 bam.html delete mode 100644 combined.html delete mode 100644 examples/genoverse.org/styles.css delete mode 100644 examples/tomato/SequenceVariation.js delete mode 100644 examples/tomato/index.html delete mode 100644 ion.html delete mode 100644 js/genomes/node.js delete mode 100644 js/genomes/tomato.js diff --git a/bam.html b/bam.html deleted file mode 100644 index 99f0a146..00000000 --- a/bam.html +++ /dev/null @@ -1,190 +0,0 @@ - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/combined.html b/combined.html deleted file mode 100644 index 22a0a06f..00000000 --- a/combined.html +++ /dev/null @@ -1,28 +0,0 @@ - diff --git a/examples/genoverse.org/styles.css b/examples/genoverse.org/styles.css deleted file mode 100644 index 13af9fb1..00000000 --- a/examples/genoverse.org/styles.css +++ /dev/null @@ -1,45 +0,0 @@ -body { - background: #2A313A; - font-family: Verdana; - font-size: 14px; - margin: 0; -} - -.container { - background: white; - position: relative; - width: 1020px; - top: 10px; - left: 50%; - margin-left: -510px; - padding-bottom: 1px; - border-radius: 5px; -} - -.head { - background: #5F8CB0; - width: 100%; - height: 40px; - border-bottom: 1px solid black; - border-radius: 5px 5px 0 0; -} - -.head h1 { - color: white; - font-size: 30px; - text-shadow: 0 2px 0 rgba(0, 0, 0, 0.75); - margin-left: 10px; -} - -.wrap { - margin: 10px auto; - width: 1000px; -} - -.info p { - padding: 0 16px; -} - -.gv-tracks-menu { - margin-left: -445px!important; -} \ No newline at end of file diff --git a/examples/tomato/SequenceVariation.js b/examples/tomato/SequenceVariation.js deleted file mode 100644 index de3092d4..00000000 --- a/examples/tomato/SequenceVariation.js +++ /dev/null @@ -1,62 +0,0 @@ -Genoverse.Track.SequenceVariation = Genoverse.Track.extend({ - model: Genoverse.Track.Model.SequenceVariation.VCF, - - populateMenu: function (feature) { - return { - 'title' : 'This is the title', - 'Location' : feature.originalFeature[0] + ':' + feature.start + '-' + feature.end, - 'Ref allele' : feature.originalFeature[3], - 'Alt allele(s)' : feature.originalFeature[4], - 'Qual' : feature.originalFeature[5] - }; - }, - - 1: { - view: Genoverse.Track.View.Sequence.extend({ - bump : true, - labels : false, - bumpSpacing : 0, - featureSpacing : 0, - autoHeight : false, - - draw: function (features, featureContext, labelContext, scale) { - this.base.apply(this, arguments); - this.highlightRef(features, featureContext, scale); - }, - - highlightRef: function (features, context, scale) { - context.strokeStyle = 'black'; - - for (var i = 0; i < features.length; i++) { - if (features[i].allele === 'REF') { - context.strokeRect(features[i].position[scale].X, features[i].position[scale].Y, features[i].position[scale].width, features[i].position[scale].height); - } - } - } - }) - }, - - 1000: { - view: Genoverse.Track.View.extend({ - bump : false, - labels : false, - autoHeight : false, - - setFeatureColor: function (feature) { - var QUAL = feature.originalFeature[5]; - - if (QUAL > 0) { - var heat = Math.min(255, Math.floor(255 * QUAL / this.maxQUAL)) - 127; - var red = heat > 0 ? 255 : 127 + heat; - var green = heat < 0 ? 255 : 127 - heat; - - feature.color = 'rgb(' + red + ',' + green + ',0)'; - } else { - feature.color = 'rgb(0,0,0)'; - } - } - }) - }, - - 100000: false -}); \ No newline at end of file diff --git a/examples/tomato/index.html b/examples/tomato/index.html deleted file mode 100644 index b15fa738..00000000 --- a/examples/tomato/index.html +++ /dev/null @@ -1,75 +0,0 @@ - - - - - - -
- - - - - - diff --git a/index.html b/index.html index 46173de7..3632e26d 100644 --- a/index.html +++ b/index.html @@ -2,10 +2,20 @@ - + - Fork me on GitHub + Fork me on GitHub

Genoverse - interactive HTML5 genome browser

@@ -17,41 +27,44 @@

Genoverse works with a variety of formats, such as XML, JSON, GFF, GFF3, BED (try drag-n-drop one), and can be customized to parse and display any data source as required.

For more information on how to use Genoverse please refer to this tutorial.

-

If you have any questions or need help, please contact us info@genoverse.org

+

If you have any questions or need help, please contact us info@genoverse.org

- + diff --git a/ion.html b/ion.html deleted file mode 100644 index fd071583..00000000 --- a/ion.html +++ /dev/null @@ -1,214 +0,0 @@ - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/js/genomes/node.js b/js/genomes/node.js deleted file mode 100644 index 75cdd668..00000000 --- a/js/genomes/node.js +++ /dev/null @@ -1,63 +0,0 @@ -var karyotype = { }; -var i = 22; -var autosomes = []; -while (i > 0) autosomes.unshift((i--) + ''); -var chromosomes = autosomes.concat(["X", "Y"]); - - -var http = require('http'); -var parser = require('xml2json'); -var options = { - host: 'www.ensembl.org', - path: '/das/Homo_sapiens.GRCh37.karyotype/features?segment=1' -}; - -callback = function(response, chr) { - var str = ''; - - //another chunk of data has been recieved, so append it to `str` - response.on('data', function (chunk) { - str += chunk; - }); - - //the whole response has been recieved, so we just print it out here - response.on('end', function () { - var json = parser.toJson(str, {object : true}); - - var chromosome = {}; - chromosome.size = json.DASGFF.GFF.SEGMENT.stop; - chromosome.bands = []; - for (var i=0; ia?this[a+this.length]:this[a]:d.call(this)},pushStack:function(a){var b=n.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a,b){return n.each(this,a,b)},map:function(a){return this.pushStack(n.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(d.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(0>a?b:0);return this.pushStack(c>=0&&b>c?[this[c]]:[])},end:function(){return this.prevObject||this.constructor(null)},push:f,sort:c.sort,splice:c.splice},n.extend=n.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||n.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(a=arguments[h]))for(b in a)c=g[b],d=a[b],g!==d&&(j&&d&&(n.isPlainObject(d)||(e=n.isArray(d)))?(e?(e=!1,f=c&&n.isArray(c)?c:[]):f=c&&n.isPlainObject(c)?c:{},g[b]=n.extend(j,f,d)):void 0!==d&&(g[b]=d));return g},n.extend({expando:"jQuery"+(m+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===n.type(a)},isArray:Array.isArray,isWindow:function(a){return null!=a&&a===a.window},isNumeric:function(a){return!n.isArray(a)&&a-parseFloat(a)+1>=0},isPlainObject:function(a){return"object"!==n.type(a)||a.nodeType||n.isWindow(a)?!1:a.constructor&&!j.call(a.constructor.prototype,"isPrototypeOf")?!1:!0},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?h[i.call(a)]||"object":typeof a},globalEval:function(a){var b,c=eval;a=n.trim(a),a&&(1===a.indexOf("use strict")?(b=l.createElement("script"),b.text=a,l.head.appendChild(b).parentNode.removeChild(b)):c(a))},camelCase:function(a){return a.replace(p,"ms-").replace(q,r)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b,c){var d,e=0,f=a.length,g=s(a);if(c){if(g){for(;f>e;e++)if(d=b.apply(a[e],c),d===!1)break}else for(e in a)if(d=b.apply(a[e],c),d===!1)break}else if(g){for(;f>e;e++)if(d=b.call(a[e],e,a[e]),d===!1)break}else for(e in a)if(d=b.call(a[e],e,a[e]),d===!1)break;return a},trim:function(a){return null==a?"":(a+"").replace(o,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(s(Object(a))?n.merge(c,"string"==typeof a?[a]:a):f.call(c,a)),c},inArray:function(a,b,c){return null==b?-1:g.call(b,a,c)},merge:function(a,b){for(var c=+b.length,d=0,e=a.length;c>d;d++)a[e++]=b[d];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;g>f;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,f=0,g=a.length,h=s(a),i=[];if(h)for(;g>f;f++)d=b(a[f],f,c),null!=d&&i.push(d);else for(f in a)d=b(a[f],f,c),null!=d&&i.push(d);return e.apply([],i)},guid:1,proxy:function(a,b){var c,e,f;return"string"==typeof b&&(c=a[b],b=a,a=c),n.isFunction(a)?(e=d.call(arguments,2),f=function(){return a.apply(b||this,e.concat(d.call(arguments)))},f.guid=a.guid=a.guid||n.guid++,f):void 0},now:Date.now,support:k}),n.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),function(a,b){h["[object "+b+"]"]=b.toLowerCase()});function s(a){var b=a.length,c=n.type(a);return"function"===c||n.isWindow(a)?!1:1===a.nodeType&&b?!0:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a}var t=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+1*new Date,v=a.document,w=0,x=0,y=hb(),z=hb(),A=hb(),B=function(a,b){return a===b&&(l=!0),0},C=1<<31,D={}.hasOwnProperty,E=[],F=E.pop,G=E.push,H=E.push,I=E.slice,J=function(a,b){for(var c=0,d=a.length;d>c;c++)if(a[c]===b)return c;return-1},K="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",L="[\\x20\\t\\r\\n\\f]",M="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",N=M.replace("w","w#"),O="\\["+L+"*("+M+")(?:"+L+"*([*^$|!~]?=)"+L+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+N+"))|)"+L+"*\\]",P=":("+M+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+O+")*)|.*)\\)|)",Q=new RegExp(L+"+","g"),R=new RegExp("^"+L+"+|((?:^|[^\\\\])(?:\\\\.)*)"+L+"+$","g"),S=new RegExp("^"+L+"*,"+L+"*"),T=new RegExp("^"+L+"*([>+~]|"+L+")"+L+"*"),U=new RegExp("="+L+"*([^\\]'\"]*?)"+L+"*\\]","g"),V=new RegExp(P),W=new RegExp("^"+N+"$"),X={ID:new RegExp("^#("+M+")"),CLASS:new RegExp("^\\.("+M+")"),TAG:new RegExp("^("+M.replace("w","w*")+")"),ATTR:new RegExp("^"+O),PSEUDO:new RegExp("^"+P),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+L+"*(even|odd|(([+-]|)(\\d*)n|)"+L+"*(?:([+-]|)"+L+"*(\\d+)|))"+L+"*\\)|)","i"),bool:new RegExp("^(?:"+K+")$","i"),needsContext:new RegExp("^"+L+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+L+"*((?:-\\d)?\\d*)"+L+"*\\)|)(?=[^-]|$)","i")},Y=/^(?:input|select|textarea|button)$/i,Z=/^h\d$/i,$=/^[^{]+\{\s*\[native \w/,_=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ab=/[+~]/,bb=/'|\\/g,cb=new RegExp("\\\\([\\da-f]{1,6}"+L+"?|("+L+")|.)","ig"),db=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:0>d?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)},eb=function(){m()};try{H.apply(E=I.call(v.childNodes),v.childNodes),E[v.childNodes.length].nodeType}catch(fb){H={apply:E.length?function(a,b){G.apply(a,I.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function gb(a,b,d,e){var f,h,j,k,l,o,r,s,w,x;if((b?b.ownerDocument||b:v)!==n&&m(b),b=b||n,d=d||[],k=b.nodeType,"string"!=typeof a||!a||1!==k&&9!==k&&11!==k)return d;if(!e&&p){if(11!==k&&(f=_.exec(a)))if(j=f[1]){if(9===k){if(h=b.getElementById(j),!h||!h.parentNode)return d;if(h.id===j)return d.push(h),d}else if(b.ownerDocument&&(h=b.ownerDocument.getElementById(j))&&t(b,h)&&h.id===j)return d.push(h),d}else{if(f[2])return H.apply(d,b.getElementsByTagName(a)),d;if((j=f[3])&&c.getElementsByClassName)return H.apply(d,b.getElementsByClassName(j)),d}if(c.qsa&&(!q||!q.test(a))){if(s=r=u,w=b,x=1!==k&&a,1===k&&"object"!==b.nodeName.toLowerCase()){o=g(a),(r=b.getAttribute("id"))?s=r.replace(bb,"\\$&"):b.setAttribute("id",s),s="[id='"+s+"'] ",l=o.length;while(l--)o[l]=s+rb(o[l]);w=ab.test(a)&&pb(b.parentNode)||b,x=o.join(",")}if(x)try{return H.apply(d,w.querySelectorAll(x)),d}catch(y){}finally{r||b.removeAttribute("id")}}}return i(a.replace(R,"$1"),b,d,e)}function hb(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function ib(a){return a[u]=!0,a}function jb(a){var b=n.createElement("div");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function kb(a,b){var c=a.split("|"),e=a.length;while(e--)d.attrHandle[c[e]]=b}function lb(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&(~b.sourceIndex||C)-(~a.sourceIndex||C);if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function mb(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function nb(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function ob(a){return ib(function(b){return b=+b,ib(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function pb(a){return a&&"undefined"!=typeof a.getElementsByTagName&&a}c=gb.support={},f=gb.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?"HTML"!==b.nodeName:!1},m=gb.setDocument=function(a){var b,e,g=a?a.ownerDocument||a:v;return g!==n&&9===g.nodeType&&g.documentElement?(n=g,o=g.documentElement,e=g.defaultView,e&&e!==e.top&&(e.addEventListener?e.addEventListener("unload",eb,!1):e.attachEvent&&e.attachEvent("onunload",eb)),p=!f(g),c.attributes=jb(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=jb(function(a){return a.appendChild(g.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=$.test(g.getElementsByClassName),c.getById=jb(function(a){return o.appendChild(a).id=u,!g.getElementsByName||!g.getElementsByName(u).length}),c.getById?(d.find.ID=function(a,b){if("undefined"!=typeof b.getElementById&&p){var c=b.getElementById(a);return c&&c.parentNode?[c]:[]}},d.filter.ID=function(a){var b=a.replace(cb,db);return function(a){return a.getAttribute("id")===b}}):(delete d.find.ID,d.filter.ID=function(a){var b=a.replace(cb,db);return function(a){var c="undefined"!=typeof a.getAttributeNode&&a.getAttributeNode("id");return c&&c.value===b}}),d.find.TAG=c.getElementsByTagName?function(a,b){return"undefined"!=typeof b.getElementsByTagName?b.getElementsByTagName(a):c.qsa?b.querySelectorAll(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){return p?b.getElementsByClassName(a):void 0},r=[],q=[],(c.qsa=$.test(g.querySelectorAll))&&(jb(function(a){o.appendChild(a).innerHTML="",a.querySelectorAll("[msallowcapture^='']").length&&q.push("[*^$]="+L+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||q.push("\\["+L+"*(?:value|"+K+")"),a.querySelectorAll("[id~="+u+"-]").length||q.push("~="),a.querySelectorAll(":checked").length||q.push(":checked"),a.querySelectorAll("a#"+u+"+*").length||q.push(".#.+[+~]")}),jb(function(a){var b=g.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&q.push("name"+L+"*[*^$|!~]?="),a.querySelectorAll(":enabled").length||q.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),q.push(",.*:")})),(c.matchesSelector=$.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&jb(function(a){c.disconnectedMatch=s.call(a,"div"),s.call(a,"[s!='']:x"),r.push("!=",P)}),q=q.length&&new RegExp(q.join("|")),r=r.length&&new RegExp(r.join("|")),b=$.test(o.compareDocumentPosition),t=b||$.test(o.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},B=b?function(a,b){if(a===b)return l=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===g||a.ownerDocument===v&&t(v,a)?-1:b===g||b.ownerDocument===v&&t(v,b)?1:k?J(k,a)-J(k,b):0:4&d?-1:1)}:function(a,b){if(a===b)return l=!0,0;var c,d=0,e=a.parentNode,f=b.parentNode,h=[a],i=[b];if(!e||!f)return a===g?-1:b===g?1:e?-1:f?1:k?J(k,a)-J(k,b):0;if(e===f)return lb(a,b);c=a;while(c=c.parentNode)h.unshift(c);c=b;while(c=c.parentNode)i.unshift(c);while(h[d]===i[d])d++;return d?lb(h[d],i[d]):h[d]===v?-1:i[d]===v?1:0},g):n},gb.matches=function(a,b){return gb(a,null,null,b)},gb.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(U,"='$1']"),!(!c.matchesSelector||!p||r&&r.test(b)||q&&q.test(b)))try{var d=s.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return gb(b,n,null,[a]).length>0},gb.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},gb.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&D.call(d.attrHandle,b.toLowerCase())?e(a,b,!p):void 0;return void 0!==f?f:c.attributes||!p?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},gb.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},gb.uniqueSort=function(a){var b,d=[],e=0,f=0;if(l=!c.detectDuplicates,k=!c.sortStable&&a.slice(0),a.sort(B),l){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return k=null,a},e=gb.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=gb.selectors={cacheLength:50,createPseudo:ib,match:X,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(cb,db),a[3]=(a[3]||a[4]||a[5]||"").replace(cb,db),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||gb.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&gb.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return X.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||"":c&&V.test(c)&&(b=g(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(cb,db).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=y[a+" "];return b||(b=new RegExp("(^|"+L+")"+a+"("+L+"|$)"))&&y(a,function(a){return b.test("string"==typeof a.className&&a.className||"undefined"!=typeof a.getAttribute&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=gb.attr(d,a);return null==e?"!="===b:b?(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e.replace(Q," ")+" ").indexOf(c)>-1:"|="===b?e===c||e.slice(0,c.length+1)===c+"-":!1):!0}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),s=!i&&!h;if(q){if(f){while(p){l=b;while(l=l[p])if(h?l.nodeName.toLowerCase()===r:1===l.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){k=q[u]||(q[u]={}),j=k[a]||[],n=j[0]===w&&j[1],m=j[0]===w&&j[2],l=n&&q.childNodes[n];while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if(1===l.nodeType&&++m&&l===b){k[a]=[w,n,m];break}}else if(s&&(j=(b[u]||(b[u]={}))[a])&&j[0]===w)m=j[1];else while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if((h?l.nodeName.toLowerCase()===r:1===l.nodeType)&&++m&&(s&&((l[u]||(l[u]={}))[a]=[w,m]),l===b))break;return m-=e,m===d||m%d===0&&m/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||gb.error("unsupported pseudo: "+a);return e[u]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?ib(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=J(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:ib(function(a){var b=[],c=[],d=h(a.replace(R,"$1"));return d[u]?ib(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),b[0]=null,!c.pop()}}),has:ib(function(a){return function(b){return gb(a,b).length>0}}),contains:ib(function(a){return a=a.replace(cb,db),function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:ib(function(a){return W.test(a||"")||gb.error("unsupported lang: "+a),a=a.replace(cb,db).toLowerCase(),function(b){var c;do if(c=p?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===o},focus:function(a){return a===n.activeElement&&(!n.hasFocus||n.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:function(a){return a.disabled===!1},disabled:function(a){return a.disabled===!0},checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return Z.test(a.nodeName)},input:function(a){return Y.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:ob(function(){return[0]}),last:ob(function(a,b){return[b-1]}),eq:ob(function(a,b,c){return[0>c?c+b:c]}),even:ob(function(a,b){for(var c=0;b>c;c+=2)a.push(c);return a}),odd:ob(function(a,b){for(var c=1;b>c;c+=2)a.push(c);return a}),lt:ob(function(a,b,c){for(var d=0>c?c+b:c;--d>=0;)a.push(d);return a}),gt:ob(function(a,b,c){for(var d=0>c?c+b:c;++db;b++)d+=a[b].value;return d}function sb(a,b,c){var d=b.dir,e=c&&"parentNode"===d,f=x++;return b.first?function(b,c,f){while(b=b[d])if(1===b.nodeType||e)return a(b,c,f)}:function(b,c,g){var h,i,j=[w,f];if(g){while(b=b[d])if((1===b.nodeType||e)&&a(b,c,g))return!0}else while(b=b[d])if(1===b.nodeType||e){if(i=b[u]||(b[u]={}),(h=i[d])&&h[0]===w&&h[1]===f)return j[2]=h[2];if(i[d]=j,j[2]=a(b,c,g))return!0}}}function tb(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function ub(a,b,c){for(var d=0,e=b.length;e>d;d++)gb(a,b[d],c);return c}function vb(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;i>h;h++)(f=a[h])&&(!c||c(f,d,e))&&(g.push(f),j&&b.push(h));return g}function wb(a,b,c,d,e,f){return d&&!d[u]&&(d=wb(d)),e&&!e[u]&&(e=wb(e,f)),ib(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||ub(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:vb(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=vb(r,n),d(j,[],h,i),k=j.length;while(k--)(l=j[k])&&(r[n[k]]=!(q[n[k]]=l))}if(f){if(e||a){if(e){j=[],k=r.length;while(k--)(l=r[k])&&j.push(q[k]=l);e(null,r=[],j,i)}k=r.length;while(k--)(l=r[k])&&(j=e?J(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=vb(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):H.apply(g,r)})}function xb(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[" "],i=g?1:0,k=sb(function(a){return a===b},h,!0),l=sb(function(a){return J(b,a)>-1},h,!0),m=[function(a,c,d){var e=!g&&(d||c!==j)||((b=c).nodeType?k(a,c,d):l(a,c,d));return b=null,e}];f>i;i++)if(c=d.relative[a[i].type])m=[sb(tb(m),c)];else{if(c=d.filter[a[i].type].apply(null,a[i].matches),c[u]){for(e=++i;f>e;e++)if(d.relative[a[e].type])break;return wb(i>1&&tb(m),i>1&&rb(a.slice(0,i-1).concat({value:" "===a[i-2].type?"*":""})).replace(R,"$1"),c,e>i&&xb(a.slice(i,e)),f>e&&xb(a=a.slice(e)),f>e&&rb(a))}m.push(c)}return tb(m)}function yb(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,h,i,k){var l,m,o,p=0,q="0",r=f&&[],s=[],t=j,u=f||e&&d.find.TAG("*",k),v=w+=null==t?1:Math.random()||.1,x=u.length;for(k&&(j=g!==n&&g);q!==x&&null!=(l=u[q]);q++){if(e&&l){m=0;while(o=a[m++])if(o(l,g,h)){i.push(l);break}k&&(w=v)}c&&((l=!o&&l)&&p--,f&&r.push(l))}if(p+=q,c&&q!==p){m=0;while(o=b[m++])o(r,s,g,h);if(f){if(p>0)while(q--)r[q]||s[q]||(s[q]=F.call(i));s=vb(s)}H.apply(i,s),k&&!f&&s.length>0&&p+b.length>1&&gb.uniqueSort(i)}return k&&(w=v,j=t),r};return c?ib(f):f}return h=gb.compile=function(a,b){var c,d=[],e=[],f=A[a+" "];if(!f){b||(b=g(a)),c=b.length;while(c--)f=xb(b[c]),f[u]?d.push(f):e.push(f);f=A(a,yb(e,d)),f.selector=a}return f},i=gb.select=function(a,b,e,f){var i,j,k,l,m,n="function"==typeof a&&a,o=!f&&g(a=n.selector||a);if(e=e||[],1===o.length){if(j=o[0]=o[0].slice(0),j.length>2&&"ID"===(k=j[0]).type&&c.getById&&9===b.nodeType&&p&&d.relative[j[1].type]){if(b=(d.find.ID(k.matches[0].replace(cb,db),b)||[])[0],!b)return e;n&&(b=b.parentNode),a=a.slice(j.shift().value.length)}i=X.needsContext.test(a)?0:j.length;while(i--){if(k=j[i],d.relative[l=k.type])break;if((m=d.find[l])&&(f=m(k.matches[0].replace(cb,db),ab.test(j[0].type)&&pb(b.parentNode)||b))){if(j.splice(i,1),a=f.length&&rb(j),!a)return H.apply(e,f),e;break}}}return(n||h(a,o))(f,b,!p,e,ab.test(a)&&pb(b.parentNode)||b),e},c.sortStable=u.split("").sort(B).join("")===u,c.detectDuplicates=!!l,m(),c.sortDetached=jb(function(a){return 1&a.compareDocumentPosition(n.createElement("div"))}),jb(function(a){return a.innerHTML="","#"===a.firstChild.getAttribute("href")})||kb("type|href|height|width",function(a,b,c){return c?void 0:a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&jb(function(a){return a.innerHTML="",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||kb("value",function(a,b,c){return c||"input"!==a.nodeName.toLowerCase()?void 0:a.defaultValue}),jb(function(a){return null==a.getAttribute("disabled")})||kb(K,function(a,b,c){var d;return c?void 0:a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),gb}(a);n.find=t,n.expr=t.selectors,n.expr[":"]=n.expr.pseudos,n.unique=t.uniqueSort,n.text=t.getText,n.isXMLDoc=t.isXML,n.contains=t.contains;var u=n.expr.match.needsContext,v=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,w=/^.[^:#\[\.,]*$/;function x(a,b,c){if(n.isFunction(b))return n.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return n.grep(a,function(a){return a===b!==c});if("string"==typeof b){if(w.test(b))return n.filter(b,a,c);b=n.filter(b,a)}return n.grep(a,function(a){return g.call(b,a)>=0!==c})}n.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?n.find.matchesSelector(d,a)?[d]:[]:n.find.matches(a,n.grep(b,function(a){return 1===a.nodeType}))},n.fn.extend({find:function(a){var b,c=this.length,d=[],e=this;if("string"!=typeof a)return this.pushStack(n(a).filter(function(){for(b=0;c>b;b++)if(n.contains(e[b],this))return!0}));for(b=0;c>b;b++)n.find(a,e[b],d);return d=this.pushStack(c>1?n.unique(d):d),d.selector=this.selector?this.selector+" "+a:a,d},filter:function(a){return this.pushStack(x(this,a||[],!1))},not:function(a){return this.pushStack(x(this,a||[],!0))},is:function(a){return!!x(this,"string"==typeof a&&u.test(a)?n(a):a||[],!1).length}});var y,z=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,A=n.fn.init=function(a,b){var c,d;if(!a)return this;if("string"==typeof a){if(c="<"===a[0]&&">"===a[a.length-1]&&a.length>=3?[null,a,null]:z.exec(a),!c||!c[1]&&b)return!b||b.jquery?(b||y).find(a):this.constructor(b).find(a);if(c[1]){if(b=b instanceof n?b[0]:b,n.merge(this,n.parseHTML(c[1],b&&b.nodeType?b.ownerDocument||b:l,!0)),v.test(c[1])&&n.isPlainObject(b))for(c in b)n.isFunction(this[c])?this[c](b[c]):this.attr(c,b[c]);return this}return d=l.getElementById(c[2]),d&&d.parentNode&&(this.length=1,this[0]=d),this.context=l,this.selector=a,this}return a.nodeType?(this.context=this[0]=a,this.length=1,this):n.isFunction(a)?"undefined"!=typeof y.ready?y.ready(a):a(n):(void 0!==a.selector&&(this.selector=a.selector,this.context=a.context),n.makeArray(a,this))};A.prototype=n.fn,y=n(l);var B=/^(?:parents|prev(?:Until|All))/,C={children:!0,contents:!0,next:!0,prev:!0};n.extend({dir:function(a,b,c){var d=[],e=void 0!==c;while((a=a[b])&&9!==a.nodeType)if(1===a.nodeType){if(e&&n(a).is(c))break;d.push(a)}return d},sibling:function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c}}),n.fn.extend({has:function(a){var b=n(a,this),c=b.length;return this.filter(function(){for(var a=0;c>a;a++)if(n.contains(this,b[a]))return!0})},closest:function(a,b){for(var c,d=0,e=this.length,f=[],g=u.test(a)||"string"!=typeof a?n(a,b||this.context):0;e>d;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&n.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?n.unique(f):f)},index:function(a){return a?"string"==typeof a?g.call(n(a),this[0]):g.call(this,a.jquery?a[0]:a):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(n.unique(n.merge(this.get(),n(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function D(a,b){while((a=a[b])&&1!==a.nodeType);return a}n.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return n.dir(a,"parentNode")},parentsUntil:function(a,b,c){return n.dir(a,"parentNode",c)},next:function(a){return D(a,"nextSibling")},prev:function(a){return D(a,"previousSibling")},nextAll:function(a){return n.dir(a,"nextSibling")},prevAll:function(a){return n.dir(a,"previousSibling")},nextUntil:function(a,b,c){return n.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return n.dir(a,"previousSibling",c)},siblings:function(a){return n.sibling((a.parentNode||{}).firstChild,a)},children:function(a){return n.sibling(a.firstChild)},contents:function(a){return a.contentDocument||n.merge([],a.childNodes)}},function(a,b){n.fn[a]=function(c,d){var e=n.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=n.filter(d,e)),this.length>1&&(C[a]||n.unique(e),B.test(a)&&e.reverse()),this.pushStack(e)}});var E=/\S+/g,F={};function G(a){var b=F[a]={};return n.each(a.match(E)||[],function(a,c){b[c]=!0}),b}n.Callbacks=function(a){a="string"==typeof a?F[a]||G(a):n.extend({},a);var b,c,d,e,f,g,h=[],i=!a.once&&[],j=function(l){for(b=a.memory&&l,c=!0,g=e||0,e=0,f=h.length,d=!0;h&&f>g;g++)if(h[g].apply(l[0],l[1])===!1&&a.stopOnFalse){b=!1;break}d=!1,h&&(i?i.length&&j(i.shift()):b?h=[]:k.disable())},k={add:function(){if(h){var c=h.length;!function g(b){n.each(b,function(b,c){var d=n.type(c);"function"===d?a.unique&&k.has(c)||h.push(c):c&&c.length&&"string"!==d&&g(c)})}(arguments),d?f=h.length:b&&(e=c,j(b))}return this},remove:function(){return h&&n.each(arguments,function(a,b){var c;while((c=n.inArray(b,h,c))>-1)h.splice(c,1),d&&(f>=c&&f--,g>=c&&g--)}),this},has:function(a){return a?n.inArray(a,h)>-1:!(!h||!h.length)},empty:function(){return h=[],f=0,this},disable:function(){return h=i=b=void 0,this},disabled:function(){return!h},lock:function(){return i=void 0,b||k.disable(),this},locked:function(){return!i},fireWith:function(a,b){return!h||c&&!i||(b=b||[],b=[a,b.slice?b.slice():b],d?i.push(b):j(b)),this},fire:function(){return k.fireWith(this,arguments),this},fired:function(){return!!c}};return k},n.extend({Deferred:function(a){var b=[["resolve","done",n.Callbacks("once memory"),"resolved"],["reject","fail",n.Callbacks("once memory"),"rejected"],["notify","progress",n.Callbacks("memory")]],c="pending",d={state:function(){return c},always:function(){return e.done(arguments).fail(arguments),this},then:function(){var a=arguments;return n.Deferred(function(c){n.each(b,function(b,f){var g=n.isFunction(a[b])&&a[b];e[f[1]](function(){var a=g&&g.apply(this,arguments);a&&n.isFunction(a.promise)?a.promise().done(c.resolve).fail(c.reject).progress(c.notify):c[f[0]+"With"](this===d?c.promise():this,g?[a]:arguments)})}),a=null}).promise()},promise:function(a){return null!=a?n.extend(a,d):d}},e={};return d.pipe=d.then,n.each(b,function(a,f){var g=f[2],h=f[3];d[f[1]]=g.add,h&&g.add(function(){c=h},b[1^a][2].disable,b[2][2].lock),e[f[0]]=function(){return e[f[0]+"With"](this===e?d:this,arguments),this},e[f[0]+"With"]=g.fireWith}),d.promise(e),a&&a.call(e,e),e},when:function(a){var b=0,c=d.call(arguments),e=c.length,f=1!==e||a&&n.isFunction(a.promise)?e:0,g=1===f?a:n.Deferred(),h=function(a,b,c){return function(e){b[a]=this,c[a]=arguments.length>1?d.call(arguments):e,c===i?g.notifyWith(b,c):--f||g.resolveWith(b,c)}},i,j,k;if(e>1)for(i=new Array(e),j=new Array(e),k=new Array(e);e>b;b++)c[b]&&n.isFunction(c[b].promise)?c[b].promise().done(h(b,k,c)).fail(g.reject).progress(h(b,j,i)):--f;return f||g.resolveWith(k,c),g.promise()}});var H;n.fn.ready=function(a){return n.ready.promise().done(a),this},n.extend({isReady:!1,readyWait:1,holdReady:function(a){a?n.readyWait++:n.ready(!0)},ready:function(a){(a===!0?--n.readyWait:n.isReady)||(n.isReady=!0,a!==!0&&--n.readyWait>0||(H.resolveWith(l,[n]),n.fn.triggerHandler&&(n(l).triggerHandler("ready"),n(l).off("ready"))))}});function I(){l.removeEventListener("DOMContentLoaded",I,!1),a.removeEventListener("load",I,!1),n.ready()}n.ready.promise=function(b){return H||(H=n.Deferred(),"complete"===l.readyState?setTimeout(n.ready):(l.addEventListener("DOMContentLoaded",I,!1),a.addEventListener("load",I,!1))),H.promise(b)},n.ready.promise();var J=n.access=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if("object"===n.type(c)){e=!0;for(h in c)n.access(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,n.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){return j.call(n(a),c)})),b))for(;i>h;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f};n.acceptData=function(a){return 1===a.nodeType||9===a.nodeType||!+a.nodeType};function K(){Object.defineProperty(this.cache={},0,{get:function(){return{}}}),this.expando=n.expando+K.uid++}K.uid=1,K.accepts=n.acceptData,K.prototype={key:function(a){if(!K.accepts(a))return 0;var b={},c=a[this.expando];if(!c){c=K.uid++;try{b[this.expando]={value:c},Object.defineProperties(a,b)}catch(d){b[this.expando]=c,n.extend(a,b)}}return this.cache[c]||(this.cache[c]={}),c},set:function(a,b,c){var d,e=this.key(a),f=this.cache[e];if("string"==typeof b)f[b]=c;else if(n.isEmptyObject(f))n.extend(this.cache[e],b);else for(d in b)f[d]=b[d];return f},get:function(a,b){var c=this.cache[this.key(a)];return void 0===b?c:c[b]},access:function(a,b,c){var d;return void 0===b||b&&"string"==typeof b&&void 0===c?(d=this.get(a,b),void 0!==d?d:this.get(a,n.camelCase(b))):(this.set(a,b,c),void 0!==c?c:b)},remove:function(a,b){var c,d,e,f=this.key(a),g=this.cache[f];if(void 0===b)this.cache[f]={};else{n.isArray(b)?d=b.concat(b.map(n.camelCase)):(e=n.camelCase(b),b in g?d=[b,e]:(d=e,d=d in g?[d]:d.match(E)||[])),c=d.length;while(c--)delete g[d[c]]}},hasData:function(a){return!n.isEmptyObject(this.cache[a[this.expando]]||{})},discard:function(a){a[this.expando]&&delete this.cache[a[this.expando]]}};var L=new K,M=new K,N=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,O=/([A-Z])/g;function P(a,b,c){var d;if(void 0===c&&1===a.nodeType)if(d="data-"+b.replace(O,"-$1").toLowerCase(),c=a.getAttribute(d),"string"==typeof c){try{c="true"===c?!0:"false"===c?!1:"null"===c?null:+c+""===c?+c:N.test(c)?n.parseJSON(c):c}catch(e){}M.set(a,b,c)}else c=void 0;return c}n.extend({hasData:function(a){return M.hasData(a)||L.hasData(a)},data:function(a,b,c){return M.access(a,b,c) -},removeData:function(a,b){M.remove(a,b)},_data:function(a,b,c){return L.access(a,b,c)},_removeData:function(a,b){L.remove(a,b)}}),n.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=M.get(f),1===f.nodeType&&!L.get(f,"hasDataAttrs"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf("data-")&&(d=n.camelCase(d.slice(5)),P(f,d,e[d])));L.set(f,"hasDataAttrs",!0)}return e}return"object"==typeof a?this.each(function(){M.set(this,a)}):J(this,function(b){var c,d=n.camelCase(a);if(f&&void 0===b){if(c=M.get(f,a),void 0!==c)return c;if(c=M.get(f,d),void 0!==c)return c;if(c=P(f,d,void 0),void 0!==c)return c}else this.each(function(){var c=M.get(this,d);M.set(this,d,b),-1!==a.indexOf("-")&&void 0!==c&&M.set(this,a,b)})},null,b,arguments.length>1,null,!0)},removeData:function(a){return this.each(function(){M.remove(this,a)})}}),n.extend({queue:function(a,b,c){var d;return a?(b=(b||"fx")+"queue",d=L.get(a,b),c&&(!d||n.isArray(c)?d=L.access(a,b,n.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||"fx";var c=n.queue(a,b),d=c.length,e=c.shift(),f=n._queueHooks(a,b),g=function(){n.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return L.get(a,c)||L.access(a,c,{empty:n.Callbacks("once memory").add(function(){L.remove(a,[b+"queue",c])})})}}),n.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.lengthx",k.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue}();var U="undefined";k.focusinBubbles="onfocusin"in a;var V=/^key/,W=/^(?:mouse|pointer|contextmenu)|click/,X=/^(?:focusinfocus|focusoutblur)$/,Y=/^([^.]*)(?:\.(.+)|)$/;function Z(){return!0}function $(){return!1}function _(){try{return l.activeElement}catch(a){}}n.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=L.get(a);if(r){c.handler&&(f=c,c=f.handler,e=f.selector),c.guid||(c.guid=n.guid++),(i=r.events)||(i=r.events={}),(g=r.handle)||(g=r.handle=function(b){return typeof n!==U&&n.event.triggered!==b.type?n.event.dispatch.apply(a,arguments):void 0}),b=(b||"").match(E)||[""],j=b.length;while(j--)h=Y.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o&&(l=n.event.special[o]||{},o=(e?l.delegateType:l.bindType)||o,l=n.event.special[o]||{},k=n.extend({type:o,origType:q,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&n.expr.match.needsContext.test(e),namespace:p.join(".")},f),(m=i[o])||(m=i[o]=[],m.delegateCount=0,l.setup&&l.setup.call(a,d,p,g)!==!1||a.addEventListener&&a.addEventListener(o,g,!1)),l.add&&(l.add.call(a,k),k.handler.guid||(k.handler.guid=c.guid)),e?m.splice(m.delegateCount++,0,k):m.push(k),n.event.global[o]=!0)}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=L.hasData(a)&&L.get(a);if(r&&(i=r.events)){b=(b||"").match(E)||[""],j=b.length;while(j--)if(h=Y.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o){l=n.event.special[o]||{},o=(d?l.delegateType:l.bindType)||o,m=i[o]||[],h=h[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),g=f=m.length;while(f--)k=m[f],!e&&q!==k.origType||c&&c.guid!==k.guid||h&&!h.test(k.namespace)||d&&d!==k.selector&&("**"!==d||!k.selector)||(m.splice(f,1),k.selector&&m.delegateCount--,l.remove&&l.remove.call(a,k));g&&!m.length&&(l.teardown&&l.teardown.call(a,p,r.handle)!==!1||n.removeEvent(a,o,r.handle),delete i[o])}else for(o in i)n.event.remove(a,o+b[j],c,d,!0);n.isEmptyObject(i)&&(delete r.handle,L.remove(a,"events"))}},trigger:function(b,c,d,e){var f,g,h,i,k,m,o,p=[d||l],q=j.call(b,"type")?b.type:b,r=j.call(b,"namespace")?b.namespace.split("."):[];if(g=h=d=d||l,3!==d.nodeType&&8!==d.nodeType&&!X.test(q+n.event.triggered)&&(q.indexOf(".")>=0&&(r=q.split("."),q=r.shift(),r.sort()),k=q.indexOf(":")<0&&"on"+q,b=b[n.expando]?b:new n.Event(q,"object"==typeof b&&b),b.isTrigger=e?2:3,b.namespace=r.join("."),b.namespace_re=b.namespace?new RegExp("(^|\\.)"+r.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=d),c=null==c?[b]:n.makeArray(c,[b]),o=n.event.special[q]||{},e||!o.trigger||o.trigger.apply(d,c)!==!1)){if(!e&&!o.noBubble&&!n.isWindow(d)){for(i=o.delegateType||q,X.test(i+q)||(g=g.parentNode);g;g=g.parentNode)p.push(g),h=g;h===(d.ownerDocument||l)&&p.push(h.defaultView||h.parentWindow||a)}f=0;while((g=p[f++])&&!b.isPropagationStopped())b.type=f>1?i:o.bindType||q,m=(L.get(g,"events")||{})[b.type]&&L.get(g,"handle"),m&&m.apply(g,c),m=k&&g[k],m&&m.apply&&n.acceptData(g)&&(b.result=m.apply(g,c),b.result===!1&&b.preventDefault());return b.type=q,e||b.isDefaultPrevented()||o._default&&o._default.apply(p.pop(),c)!==!1||!n.acceptData(d)||k&&n.isFunction(d[q])&&!n.isWindow(d)&&(h=d[k],h&&(d[k]=null),n.event.triggered=q,d[q](),n.event.triggered=void 0,h&&(d[k]=h)),b.result}},dispatch:function(a){a=n.event.fix(a);var b,c,e,f,g,h=[],i=d.call(arguments),j=(L.get(this,"events")||{})[a.type]||[],k=n.event.special[a.type]||{};if(i[0]=a,a.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,a)!==!1){h=n.event.handlers.call(this,a,j),b=0;while((f=h[b++])&&!a.isPropagationStopped()){a.currentTarget=f.elem,c=0;while((g=f.handlers[c++])&&!a.isImmediatePropagationStopped())(!a.namespace_re||a.namespace_re.test(g.namespace))&&(a.handleObj=g,a.data=g.data,e=((n.event.special[g.origType]||{}).handle||g.handler).apply(f.elem,i),void 0!==e&&(a.result=e)===!1&&(a.preventDefault(),a.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,a),a.result}},handlers:function(a,b){var c,d,e,f,g=[],h=b.delegateCount,i=a.target;if(h&&i.nodeType&&(!a.button||"click"!==a.type))for(;i!==this;i=i.parentNode||this)if(i.disabled!==!0||"click"!==a.type){for(d=[],c=0;h>c;c++)f=b[c],e=f.selector+" ",void 0===d[e]&&(d[e]=f.needsContext?n(e,this).index(i)>=0:n.find(e,this,null,[i]).length),d[e]&&d.push(f);d.length&&g.push({elem:i,handlers:d})}return h]*)\/>/gi,bb=/<([\w:]+)/,cb=/<|&#?\w+;/,db=/<(?:script|style|link)/i,eb=/checked\s*(?:[^=]|=\s*.checked.)/i,fb=/^$|\/(?:java|ecma)script/i,gb=/^true\/(.*)/,hb=/^\s*\s*$/g,ib={option:[1,""],thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};ib.optgroup=ib.option,ib.tbody=ib.tfoot=ib.colgroup=ib.caption=ib.thead,ib.th=ib.td;function jb(a,b){return n.nodeName(a,"table")&&n.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function kb(a){return a.type=(null!==a.getAttribute("type"))+"/"+a.type,a}function lb(a){var b=gb.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function mb(a,b){for(var c=0,d=a.length;d>c;c++)L.set(a[c],"globalEval",!b||L.get(b[c],"globalEval"))}function nb(a,b){var c,d,e,f,g,h,i,j;if(1===b.nodeType){if(L.hasData(a)&&(f=L.access(a),g=L.set(b,f),j=f.events)){delete g.handle,g.events={};for(e in j)for(c=0,d=j[e].length;d>c;c++)n.event.add(b,e,j[e][c])}M.hasData(a)&&(h=M.access(a),i=n.extend({},h),M.set(b,i))}}function ob(a,b){var c=a.getElementsByTagName?a.getElementsByTagName(b||"*"):a.querySelectorAll?a.querySelectorAll(b||"*"):[];return void 0===b||b&&n.nodeName(a,b)?n.merge([a],c):c}function pb(a,b){var c=b.nodeName.toLowerCase();"input"===c&&T.test(a.type)?b.checked=a.checked:("input"===c||"textarea"===c)&&(b.defaultValue=a.defaultValue)}n.extend({clone:function(a,b,c){var d,e,f,g,h=a.cloneNode(!0),i=n.contains(a.ownerDocument,a);if(!(k.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||n.isXMLDoc(a)))for(g=ob(h),f=ob(a),d=0,e=f.length;e>d;d++)pb(f[d],g[d]);if(b)if(c)for(f=f||ob(a),g=g||ob(h),d=0,e=f.length;e>d;d++)nb(f[d],g[d]);else nb(a,h);return g=ob(h,"script"),g.length>0&&mb(g,!i&&ob(a,"script")),h},buildFragment:function(a,b,c,d){for(var e,f,g,h,i,j,k=b.createDocumentFragment(),l=[],m=0,o=a.length;o>m;m++)if(e=a[m],e||0===e)if("object"===n.type(e))n.merge(l,e.nodeType?[e]:e);else if(cb.test(e)){f=f||k.appendChild(b.createElement("div")),g=(bb.exec(e)||["",""])[1].toLowerCase(),h=ib[g]||ib._default,f.innerHTML=h[1]+e.replace(ab,"<$1>")+h[2],j=h[0];while(j--)f=f.lastChild;n.merge(l,f.childNodes),f=k.firstChild,f.textContent=""}else l.push(b.createTextNode(e));k.textContent="",m=0;while(e=l[m++])if((!d||-1===n.inArray(e,d))&&(i=n.contains(e.ownerDocument,e),f=ob(k.appendChild(e),"script"),i&&mb(f),c)){j=0;while(e=f[j++])fb.test(e.type||"")&&c.push(e)}return k},cleanData:function(a){for(var b,c,d,e,f=n.event.special,g=0;void 0!==(c=a[g]);g++){if(n.acceptData(c)&&(e=c[L.expando],e&&(b=L.cache[e]))){if(b.events)for(d in b.events)f[d]?n.event.remove(c,d):n.removeEvent(c,d,b.handle);L.cache[e]&&delete L.cache[e]}delete M.cache[c[M.expando]]}}}),n.fn.extend({text:function(a){return J(this,function(a){return void 0===a?n.text(this):this.empty().each(function(){(1===this.nodeType||11===this.nodeType||9===this.nodeType)&&(this.textContent=a)})},null,a,arguments.length)},append:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=jb(this,a);b.appendChild(a)}})},prepend:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=jb(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},remove:function(a,b){for(var c,d=a?n.filter(a,this):this,e=0;null!=(c=d[e]);e++)b||1!==c.nodeType||n.cleanData(ob(c)),c.parentNode&&(b&&n.contains(c.ownerDocument,c)&&mb(ob(c,"script")),c.parentNode.removeChild(c));return this},empty:function(){for(var a,b=0;null!=(a=this[b]);b++)1===a.nodeType&&(n.cleanData(ob(a,!1)),a.textContent="");return this},clone:function(a,b){return a=null==a?!1:a,b=null==b?a:b,this.map(function(){return n.clone(this,a,b)})},html:function(a){return J(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a&&1===b.nodeType)return b.innerHTML;if("string"==typeof a&&!db.test(a)&&!ib[(bb.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(ab,"<$1>");try{for(;d>c;c++)b=this[c]||{},1===b.nodeType&&(n.cleanData(ob(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=arguments[0];return this.domManip(arguments,function(b){a=this.parentNode,n.cleanData(ob(this)),a&&a.replaceChild(b,this)}),a&&(a.length||a.nodeType)?this:this.remove()},detach:function(a){return this.remove(a,!0)},domManip:function(a,b){a=e.apply([],a);var c,d,f,g,h,i,j=0,l=this.length,m=this,o=l-1,p=a[0],q=n.isFunction(p);if(q||l>1&&"string"==typeof p&&!k.checkClone&&eb.test(p))return this.each(function(c){var d=m.eq(c);q&&(a[0]=p.call(this,c,d.html())),d.domManip(a,b)});if(l&&(c=n.buildFragment(a,this[0].ownerDocument,!1,this),d=c.firstChild,1===c.childNodes.length&&(c=d),d)){for(f=n.map(ob(c,"script"),kb),g=f.length;l>j;j++)h=c,j!==o&&(h=n.clone(h,!0,!0),g&&n.merge(f,ob(h,"script"))),b.call(this[j],h,j);if(g)for(i=f[f.length-1].ownerDocument,n.map(f,lb),j=0;g>j;j++)h=f[j],fb.test(h.type||"")&&!L.access(h,"globalEval")&&n.contains(i,h)&&(h.src?n._evalUrl&&n._evalUrl(h.src):n.globalEval(h.textContent.replace(hb,"")))}return this}}),n.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){n.fn[a]=function(a){for(var c,d=[],e=n(a),g=e.length-1,h=0;g>=h;h++)c=h===g?this:this.clone(!0),n(e[h])[b](c),f.apply(d,c.get());return this.pushStack(d)}});var qb,rb={};function sb(b,c){var d,e=n(c.createElement(b)).appendTo(c.body),f=a.getDefaultComputedStyle&&(d=a.getDefaultComputedStyle(e[0]))?d.display:n.css(e[0],"display");return e.detach(),f}function tb(a){var b=l,c=rb[a];return c||(c=sb(a,b),"none"!==c&&c||(qb=(qb||n("