igv 2.13.2 → 2.13.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/igv.esm.js CHANGED
@@ -8239,7 +8239,7 @@ function attachDialogCloseHandlerWithParent$1(parent, closeHandler) {
8239
8239
  * @param x
8240
8240
  * @returns {boolean}
8241
8241
  */
8242
- function isString$3(x) {
8242
+ function isString$2(x) {
8243
8243
  return typeof x === "string" || x instanceof String
8244
8244
  }
8245
8245
 
@@ -8301,13 +8301,6 @@ function stripQuotes$1(str) {
8301
8301
  return str;
8302
8302
  }
8303
8303
 
8304
- function hashCode$1(s) {
8305
- return s.split("").reduce(function (a, b) {
8306
- a = ((a << 5) - a) + b.charCodeAt(0);
8307
- return a & a
8308
- }, 0);
8309
- }
8310
-
8311
8304
  function capitalize(str) {
8312
8305
  return str.length > 0 ? str.charAt(0).toUpperCase() + str.slice(1) : str;
8313
8306
  }
@@ -8744,7 +8737,7 @@ function getFilename$1(urlOrFile) {
8744
8737
 
8745
8738
  if (urlOrFile.name !== undefined) {
8746
8739
  return urlOrFile.name
8747
- } else if (isString$3(urlOrFile)) {
8740
+ } else if (isString$2(urlOrFile)) {
8748
8741
 
8749
8742
  let index = urlOrFile.lastIndexOf("/");
8750
8743
  let filename = index < 0 ? urlOrFile : urlOrFile.substr(index + 1);
@@ -20595,7 +20588,7 @@ const isNumber = function (num) {
20595
20588
  };
20596
20589
 
20597
20590
  async function getFilename(url) {
20598
- if (isString$3(url) && url.startsWith("https://drive.google.com")) {
20591
+ if (isString$2(url) && url.startsWith("https://drive.google.com")) {
20599
20592
  // This will fail if Google API key is not defined
20600
20593
  if (getApiKey() === undefined) {
20601
20594
  throw Error("Google drive is referenced, but API key is not defined. An API key is required for Google Drive access")
@@ -20637,7 +20630,7 @@ function prettyBasePairNumber(raw) {
20637
20630
 
20638
20631
 
20639
20632
  function isDataURL(obj) {
20640
- return (isString$3(obj) && obj.startsWith("data:"))
20633
+ return (isString$2(obj) && obj.startsWith("data:"))
20641
20634
  }
20642
20635
 
20643
20636
  function createColumn(columnContainer, className) {
@@ -20988,7 +20981,7 @@ function inferFileFormat(fn) {
20988
20981
 
20989
20982
  function inferIndexPath(url, extension) {
20990
20983
 
20991
- if (isString$3(url)) {
20984
+ if (isString$2(url)) {
20992
20985
  if (url.includes("?")) {
20993
20986
  const idx = url.indexOf("?");
20994
20987
  return url.substring(0, idx) + "." + extension + url.substring(idx)
@@ -21395,7 +21388,6 @@ class SequenceTrack {
21395
21388
 
21396
21389
  let sequence = options.features.sequence;
21397
21390
  if(!sequence) {
21398
- console.error("No sequence");
21399
21391
  return
21400
21392
  }
21401
21393
 
@@ -21562,17 +21554,9 @@ class Viewport {
21562
21554
  this.alert = new AlertDialog(this.$viewport.get(0));
21563
21555
  }
21564
21556
 
21565
- this.$content = $$1("<div>", {class: 'igv-viewport-content'});
21566
- this.$viewport.append(this.$content);
21567
-
21568
- this.$content.height(this.$viewport.height());
21569
- this.contentDiv = this.$content.get(0);
21557
+ this.contentTop = 0;
21558
+ this.contentHeight = this.$viewport.height();
21570
21559
 
21571
- // this.$canvas = $('<canvas>')
21572
- // this.$content.append(this.$canvas)
21573
- //
21574
- // this.canvas = this.$canvas.get(0)
21575
- // this.ctx = this.canvas.getContext("2d")
21576
21560
 
21577
21561
  this.$viewport.width(width);
21578
21562
 
@@ -21588,7 +21572,8 @@ class Viewport {
21588
21572
  if (!this.messageDiv) {
21589
21573
  this.messageDiv = document.createElement('div');
21590
21574
  this.messageDiv.className = 'igv-viewport-message';
21591
- this.contentDiv.append(this.messageDiv);
21575
+ //this.contentDiv.append(this.messageDiv)
21576
+ this.$viewport.append($$1(this.messageDiv));
21592
21577
  }
21593
21578
  this.messageDiv.textContent = message;
21594
21579
  this.messageDiv.style.display = 'inline-block';
@@ -21617,15 +21602,15 @@ class Viewport {
21617
21602
 
21618
21603
  setTop(contentTop) {
21619
21604
 
21620
- const viewportHeight = this.$viewport.height();
21621
- const viewTop = -contentTop;
21622
- const viewBottom = viewTop + viewportHeight;
21623
-
21624
- this.$content.css('top', `${contentTop}px`);
21605
+ this.contentTop = contentTop;
21606
+ this.$viewport.height();
21625
21607
 
21626
- if (undefined === this.canvasVerticalRange || this.canvasVerticalRange.bottom < viewBottom || this.canvasVerticalRange.top > viewTop) {
21627
- this.repaint();
21628
- }
21608
+ //this.$content.css('top', `${contentTop}px`)
21609
+ //
21610
+ // if (undefined === this.canvasVerticalRange || this.canvasVerticalRange.bottom < viewBottom || this.canvasVerticalRange.top > viewTop) {
21611
+ // console.log("Repaint " + this.canvasVerticalRange)
21612
+ // this.repaint()
21613
+ // }
21629
21614
 
21630
21615
  }
21631
21616
 
@@ -21653,7 +21638,8 @@ class Viewport {
21653
21638
  } else if (typeof track.computePixelHeight === 'function') {
21654
21639
  if (features && features.length > 0) {
21655
21640
  let requiredContentHeight = track.computePixelHeight(features);
21656
- let currentContentHeight = this.$content.height();
21641
+ //let currentContentHeight = this.$content.height()
21642
+ let currentContentHeight = this.contentHeight;
21657
21643
  if (requiredContentHeight !== currentContentHeight) {
21658
21644
  this.setContentHeight(requiredContentHeight);
21659
21645
  }
@@ -21662,14 +21648,12 @@ class Viewport {
21662
21648
  }
21663
21649
 
21664
21650
  getContentHeight() {
21665
- return this.$content.height()
21651
+ //return this.$content.height()
21652
+ return this.contentHeight
21666
21653
  }
21667
21654
 
21668
21655
  setContentHeight(contentHeight) {
21669
-
21670
- // Maximum height of a canvas is ~32,000 pixels on Chrome, possibly smaller on other platforms
21671
- contentHeight = Math.min(contentHeight, 32000);
21672
- this.$content.height(contentHeight);
21656
+ this.contentHeight = contentHeight;
21673
21657
  }
21674
21658
 
21675
21659
  isLoading() {
@@ -21693,7 +21677,7 @@ class Viewport {
21693
21677
  }
21694
21678
 
21695
21679
  getContentTop() {
21696
- return this.contentDiv.offsetTop
21680
+ return this.contentTop
21697
21681
  }
21698
21682
 
21699
21683
  containsPosition(chr, position) {
@@ -23859,7 +23843,7 @@ const Cytoband = function (start, end, name, typestain) {
23859
23843
  }
23860
23844
  };
23861
23845
 
23862
- const _version = "2.13.2";
23846
+ const _version = "2.13.4";
23863
23847
  function version() {
23864
23848
  return _version
23865
23849
  }
@@ -23972,7 +23956,7 @@ const GenomeUtils = {
23972
23956
  expandReference: function (alert, idOrConfig) {
23973
23957
 
23974
23958
  // idOrConfig might be json
23975
- if (isString$3(idOrConfig) && idOrConfig.startsWith("{")) {
23959
+ if (isString$2(idOrConfig) && idOrConfig.startsWith("{")) {
23976
23960
  try {
23977
23961
  idOrConfig = JSON.parse(idOrConfig);
23978
23962
  } catch (e) {
@@ -23981,7 +23965,7 @@ const GenomeUtils = {
23981
23965
  }
23982
23966
 
23983
23967
  let genomeID;
23984
- if (isString$3(idOrConfig)) {
23968
+ if (isString$2(idOrConfig)) {
23985
23969
  genomeID = idOrConfig;
23986
23970
  } else if (idOrConfig.genome) {
23987
23971
  genomeID = idOrConfig.genome;
@@ -24333,7 +24317,7 @@ function constructWG(genome, config) {
24333
24317
  function generateGenomeID(config) {
24334
24318
  if (config.id !== undefined) {
24335
24319
  return config.id
24336
- } else if (config.fastaURL && isString$3(config.fastaURL)) {
24320
+ } else if (config.fastaURL && isString$2(config.fastaURL)) {
24337
24321
  return config.fastaURL
24338
24322
  } else if (config.fastaURL && config.fastaURL.name) {
24339
24323
  return config.fastaURL.name
@@ -24365,7 +24349,7 @@ class TrackViewport extends Viewport {
24365
24349
 
24366
24350
  const track = this.trackView.track;
24367
24351
  if ('sequence' !== track.type) {
24368
- this.$zoomInNotice = this.createZoomInNotice(this.$content);
24352
+ this.$zoomInNotice = this.createZoomInNotice(this.$viewport);
24369
24353
  }
24370
24354
 
24371
24355
  if (track.name && "sequence" !== track.id) {
@@ -24476,6 +24460,34 @@ class TrackViewport extends Viewport {
24476
24460
  }
24477
24461
  }
24478
24462
 
24463
+ /**
24464
+ * Set the content top of the current view. This is triggered by scrolling. If the current canvas extent is not
24465
+ * sufficient to cover the new vertical range repaint.
24466
+ *
24467
+ * @param contentTop - the "top" property of the virtual content div, 0 unless track is scrolled vertically
24468
+ *
24469
+ *
24470
+ */
24471
+ setTop(contentTop) {
24472
+ super.setTop(contentTop);
24473
+
24474
+ if (!this.canvas) {
24475
+ this.repaint();
24476
+ } else {
24477
+ // See if currently painted canvas covers the vertical range of the viewport. If not repaint
24478
+ const h = this.$viewport.height();
24479
+ const vt = contentTop + this.canvas._data.canvasTop;
24480
+ const vb = contentTop + this.canvas._data.canvasBottom;
24481
+ if (vt > 0 || vb < h) {
24482
+ this.repaint();
24483
+ }
24484
+ }
24485
+
24486
+ // Now offset backing canvas to align with the contentTop visual offset.
24487
+ let offset = contentTop + this.canvas._data.canvasTop;
24488
+ this.canvas.style.top = `${offset}px`;
24489
+ }
24490
+
24479
24491
  async loadFeatures() {
24480
24492
 
24481
24493
  const referenceFrame = this.referenceFrame;
@@ -24483,7 +24495,7 @@ class TrackViewport extends Viewport {
24483
24495
 
24484
24496
  // Expand the requested range so we can pan a bit without reloading. But not beyond chromosome bounds
24485
24497
  const chrLength = this.browser.genome.getChromosome(chr).bpLength;
24486
- const pixelWidth = this.$content.width();// * 3;
24498
+ const pixelWidth = this.$viewport.width();// * 3;
24487
24499
  const bpWidth = pixelWidth * referenceFrame.bpPerPixel;
24488
24500
  const bpStart = Math.floor(Math.max(0, referenceFrame.start - bpWidth));
24489
24501
  const bpEnd = Math.ceil(Math.min(chrLength, referenceFrame.start + bpWidth + bpWidth)); // Add one screen width to end
@@ -24524,6 +24536,12 @@ class TrackViewport extends Viewport {
24524
24536
  }
24525
24537
  }
24526
24538
 
24539
+ /**
24540
+ * Compute the genomic extent and needed pixelWidth to repaint the canvas for the current genomic state.
24541
+ * Normally the canvas is size 3X the width of the viewport, however there is no left-right panning for WGV so
24542
+ * canvas width is viewport width.
24543
+ * @returns {{bpEnd: *, pixelWidth: (*|number), bpStart: number}}
24544
+ */
24527
24545
  repaintDimensions() {
24528
24546
  const isWGV = GenomeUtils.isWholeGenomeView(this.referenceFrame.chr);
24529
24547
  const pixelWidth = isWGV ? this.$viewport.width() : 3 * this.$viewport.width();
@@ -24546,12 +24564,8 @@ class TrackViewport extends Viewport {
24546
24564
  }
24547
24565
 
24548
24566
  const {features, roiFeatures} = this.featureCache;
24549
- //this.tile.bpPerPixel = this.referenceFrame.bpPerPixel
24550
24567
 
24551
- // const isWGV = GenomeUtils.isWholeGenomeView(this.browser.referenceFrameList[0].chr)
24552
- GenomeUtils.isWholeGenomeView(this.referenceFrame.chr);
24553
-
24554
- // Canvas dimensions. There is no left-right panning for WGV so canvas width is viewport width.
24568
+ // Canvas dimensions.
24555
24569
  // For deep tracks we paint a canvas == 3*viewportHeight centered on the current vertical scroll position
24556
24570
  const {bpStart, bpEnd, pixelWidth} = this.repaintDimensions();
24557
24571
  const viewportHeight = this.$viewport.height();
@@ -24564,14 +24578,15 @@ class TrackViewport extends Viewport {
24564
24578
  }
24565
24579
  return
24566
24580
  }
24567
- const canvasTop = Math.max(0, -(this.$content.position().top) - viewportHeight);
24581
+ const canvasTop = Math.max(0, -this.contentTop - viewportHeight);
24582
+
24568
24583
 
24569
24584
  const bpPerPixel = this.referenceFrame.bpPerPixel;
24570
- //const bpStart = this.referenceFrame.start - (isWGV ? 0 : pixelWidth / 3 * bpPerPixel)
24571
- //const bpEnd = this.referenceFrame.end + (isWGV ? 0 : pixelWidth / 3 * bpPerPixel)
24572
24585
  const pixelXOffset = Math.round((bpStart - this.referenceFrame.start) / bpPerPixel);
24573
24586
 
24574
- const newCanvas = $$1('<canvas class="igv-canvas">').get(0);
24587
+ const newCanvas = document.createElement('canvas');// $('<canvas class="igv-canvas">').get(0)
24588
+ newCanvas.style.position = 'relative';
24589
+ newCanvas.style.display = 'block';
24575
24590
  newCanvas.style.width = pixelWidth + "px";
24576
24591
  newCanvas.style.height = pixelHeight + "px";
24577
24592
  newCanvas.style.left = pixelXOffset + "px";
@@ -24597,6 +24612,8 @@ class TrackViewport extends Viewport {
24597
24612
  bpStart: bpStart,
24598
24613
  bpEnd: bpEnd,
24599
24614
  bpPerPixel,
24615
+ canvasTop,
24616
+ canvasBottom: canvasTop + pixelHeight,
24600
24617
  referenceFrame: this.referenceFrame,
24601
24618
  selection: this.selection,
24602
24619
  viewport: this,
@@ -24610,7 +24627,7 @@ class TrackViewport extends Viewport {
24610
24627
  }
24611
24628
  newCanvas._data = drawConfiguration;
24612
24629
  this.canvas = newCanvas;
24613
- this.$content.append($$1(newCanvas));
24630
+ this.$viewport.append($$1(newCanvas));
24614
24631
 
24615
24632
  }
24616
24633
 
@@ -24632,13 +24649,11 @@ class TrackViewport extends Viewport {
24632
24649
  */
24633
24650
  draw(drawConfiguration, features, roiFeatures) {
24634
24651
 
24635
- // console.log(`${ Date.now() } viewport draw(). track ${ this.trackView.track.type }. content-css-top ${ this.$content.css('top') }. canvas-top ${ drawConfiguration.pixelTop }.`)
24636
-
24637
24652
  if (features) {
24638
24653
  drawConfiguration.features = features;
24639
24654
  this.trackView.track.draw(drawConfiguration);
24640
24655
  }
24641
- if (roiFeatures) {
24656
+ if (roiFeatures && roiFeatures.length > 0) {
24642
24657
  for (let r of roiFeatures) {
24643
24658
  drawConfiguration.features = r.features;
24644
24659
  r.track.draw(drawConfiguration);
@@ -24662,13 +24677,13 @@ class TrackViewport extends Viewport {
24662
24677
 
24663
24678
  if (!this.canvas) return
24664
24679
 
24665
- const canvasMetadata = this.featureCache;
24680
+ const canvasMetadata = this.canvas._data;
24666
24681
  const canvasTop = canvasMetadata ? canvasMetadata.canvasTop : 0;
24667
24682
  const devicePixelRatio = window.devicePixelRatio;
24668
24683
  const w = this.$viewport.width() * devicePixelRatio;
24669
24684
  const h = this.$viewport.height() * devicePixelRatio;
24670
24685
  const x = -$$1(this.canvas).position().left * devicePixelRatio;
24671
- const y = (-this.$content.position().top - canvasTop) * devicePixelRatio;
24686
+ const y = (-this.contentTop - canvasTop) * devicePixelRatio;
24672
24687
 
24673
24688
  const ctx = this.canvas.getContext("2d");
24674
24689
  const imageData = ctx.getImageData(x, y, w, h);
@@ -24686,57 +24701,82 @@ class TrackViewport extends Viewport {
24686
24701
 
24687
24702
  saveSVG() {
24688
24703
 
24689
- const {width, height} = this.$viewport.get(0).getBoundingClientRect();
24704
+ const marginTop = 32;
24705
+ const marginLeft = 32;
24706
+
24707
+ let {width, height} = this.browser.columnContainer.getBoundingClientRect();
24708
+
24709
+ const h_render = 8000;
24690
24710
 
24691
24711
  const config =
24692
24712
  {
24713
+
24693
24714
  width,
24694
- height,
24715
+ height: h_render,
24716
+
24717
+ backdropColor: 'white',
24718
+
24719
+ multiLocusGap: 0,
24720
+
24695
24721
  viewbox:
24696
24722
  {
24697
24723
  x: 0,
24698
- y: -this.$content.position().top,
24724
+ y: 0,
24699
24725
  width,
24700
- height
24726
+ height: h_render
24701
24727
  }
24702
24728
 
24703
24729
  };
24704
24730
 
24705
24731
  const context = new ctx(config);
24706
24732
 
24707
- const str = (this.trackView.track.name || this.trackView.track.id).replace(/\W/g, '');
24733
+ const delta =
24734
+ {
24735
+ deltaX: marginLeft,
24736
+ deltaY: marginTop
24737
+ };
24708
24738
 
24709
- const index = this.browser.referenceFrameList.indexOf(this.referenceFrame);
24710
- const id = `${str}_referenceFrame_${index}_guid_${guid$2()}`;
24739
+ this.renderViewportToSVG(context, delta);
24740
+
24741
+ // reset height to trim away unneeded svg canvas real estate. Yes, a bit of a hack.
24742
+ context.setHeight(height);
24711
24743
 
24712
- this.drawSVGWithContext(context, width, height, id, 0, 0, 0);
24744
+ const str = (this.trackView.track.name || this.trackView.track.id).replace(/\W/g, '');
24745
+ const index = this.browser.referenceFrameList.indexOf(this.referenceFrame);
24713
24746
 
24714
24747
  const svg = context.getSerializedSvg(true);
24715
24748
  const data = URL.createObjectURL(new Blob([svg], {type: "application/octet-stream"}));
24716
24749
 
24750
+ const id = `${str}_referenceFrame_${index}_guid_${guid$2()}`;
24717
24751
  download(`${id}.svg`, data);
24752
+
24718
24753
  }
24719
24754
 
24720
24755
  // called by trackView.renderSVGContext() when rendering
24721
24756
  // entire browser as SVG
24722
24757
 
24723
- renderSVGContext(context, {deltaX, deltaY}) {
24758
+ renderViewportToSVG(context, {deltaX, deltaY}) {
24724
24759
 
24725
- // Nothing to do if zoomInNotice is active
24726
24760
  if (this.$zoomInNotice && this.$zoomInNotice.is(":visible")) {
24727
24761
  return
24728
24762
  }
24729
24763
 
24730
- const str = (this.trackView.track.name || this.trackView.track.id).replace(/\W/g, '');
24764
+ const {width, height} = this.$viewport.get(0).getBoundingClientRect();
24731
24765
 
24766
+ const str = (this.trackView.track.name || this.trackView.track.id).replace(/\W/g, '');
24732
24767
  const index = this.browser.referenceFrameList.indexOf(this.referenceFrame);
24733
24768
  const id = `${str}_referenceFrame_${index}_guid_${guid$2()}`;
24769
+ this.drawSVGWithContext(context, width, height, id, deltaX, deltaY + this.contentTop, -this.contentTop);
24734
24770
 
24735
- const {top: yScrollDelta} = this.$content.position();
24771
+ }
24736
24772
 
24737
- const {width, height} = this.$viewport.get(0).getBoundingClientRect();
24773
+ renderSVGContext(context, {deltaX, deltaY}) {
24774
+
24775
+ this.renderViewportToSVG(context, {deltaX, deltaY});
24738
24776
 
24739
- this.drawSVGWithContext(context, width, height, id, deltaX, deltaY + yScrollDelta, -yScrollDelta);
24777
+ if (this.$zoomInNotice && this.$zoomInNotice.is(":visible")) {
24778
+ return
24779
+ }
24740
24780
 
24741
24781
  if (this.$trackLabel && true === this.browser.trackLabelsVisible) {
24742
24782
  const {x, y, width, height} = relativeDOMBBox(this.$viewport.get(0), this.$trackLabel.get(0));
@@ -24794,7 +24834,7 @@ class TrackViewport extends Viewport {
24794
24834
  selection: this.selection
24795
24835
  };
24796
24836
 
24797
- const features = this.featureCache ? this.featureCache.features : [];
24837
+ const features = this.featureCache ? this.featureCache.features : undefined;
24798
24838
  const roiFeatures = this.featureCache ? this.featureCache.roiFeatures : undefined;
24799
24839
  this.draw(config, features, roiFeatures);
24800
24840
 
@@ -24894,22 +24934,21 @@ class TrackViewport extends Viewport {
24894
24934
  viewport.addEventListener('touchend', mu);
24895
24935
 
24896
24936
  // Mouse move
24897
- if (typeof this.trackView.track._hoverText === 'function') {
24937
+ if (typeof this.trackView.track.hoverText === 'function') {
24898
24938
  viewport.addEventListener('mousemove', (event => {
24899
- if (Date.now() - lastHoverUpdateTime > 100) {
24939
+ if (event.buttons === 0 && (Date.now() - lastHoverUpdateTime > 100)) {
24900
24940
  lastHoverUpdateTime = Date.now();
24901
- const clickState = createClickState(event, this);
24941
+ const clickState = this.createClickState(event);
24902
24942
  if (clickState) {
24903
- const hoverText = this.trackView.track._hoverText(clickState);
24904
- if (hoverText) {
24905
- this.$viewport[0].setAttribute("title", hoverText);
24943
+ const tooltip = this.trackView.track.hoverText(clickState);
24944
+ if (tooltip) {
24945
+ this.$viewport[0].setAttribute("title", tooltip);
24906
24946
  } else {
24907
24947
  this.$viewport[0].removeAttribute("title");
24908
24948
  }
24909
24949
  }
24910
24950
  }
24911
24951
  }));
24912
-
24913
24952
  }
24914
24953
 
24915
24954
  this.addViewportClickHandler(this.$viewport.get(0));
@@ -24929,7 +24968,7 @@ class TrackViewport extends Viewport {
24929
24968
  return false
24930
24969
  }
24931
24970
 
24932
- const clickState = createClickState(event, this);
24971
+ const clickState = this.createClickState(event);
24933
24972
 
24934
24973
  if (undefined === clickState) {
24935
24974
  return false
@@ -25031,7 +25070,7 @@ class TrackViewport extends Viewport {
25031
25070
 
25032
25071
  popupTimerID = setTimeout(() => {
25033
25072
 
25034
- const content = getPopupContent(event, this);
25073
+ const content = this.getPopupContent(event);
25035
25074
  if (content) {
25036
25075
  if (this.popover) this.popover.dispose();
25037
25076
  this.popover = new Popover(this.browser.columnContainer);
@@ -25075,57 +25114,58 @@ class TrackViewport extends Viewport {
25075
25114
  });
25076
25115
  }
25077
25116
 
25078
- }
25117
+ createClickState(event) {
25079
25118
 
25080
- function createClickState(event, viewport) {
25119
+ if (!this.canvas) return // Can happen during initialization
25081
25120
 
25082
- if (!viewport.contentDiv || !viewport.canvas) return // Can happen during initialization
25121
+ const referenceFrame = this.referenceFrame;
25122
+ const viewportCoords = translateMouseCoordinates$1(event, this.$viewport.get(0));
25123
+ const canvasCoords = translateMouseCoordinates$1(event, this.canvas);
25124
+ const genomicLocation = ((referenceFrame.start) + referenceFrame.toBP(viewportCoords.x));
25083
25125
 
25084
- const referenceFrame = viewport.referenceFrame;
25085
- const viewportCoords = translateMouseCoordinates$1(event, viewport.contentDiv);
25086
- const canvasCoords = translateMouseCoordinates$1(event, viewport.canvas);
25087
- const genomicLocation = ((referenceFrame.start) + referenceFrame.toBP(viewportCoords.x));
25126
+ return {
25127
+ event,
25128
+ viewport: this,
25129
+ referenceFrame,
25130
+ genomicLocation,
25131
+ y: viewportCoords.y - this.contentTop,
25132
+ canvasX: canvasCoords.x,
25133
+ canvasY: canvasCoords.y
25134
+ }
25088
25135
 
25089
- return {
25090
- event,
25091
- viewport,
25092
- referenceFrame,
25093
- genomicLocation,
25094
- x: viewportCoords.x,
25095
- y: viewportCoords.y,
25096
- canvasX: canvasCoords.x,
25097
- canvasY: canvasCoords.y
25098
25136
  }
25099
25137
 
25100
- }
25138
+ getPopupContent(event) {
25101
25139
 
25102
- function getPopupContent(event, viewport) {
25140
+ const clickState = this.createClickState(event);
25103
25141
 
25104
- const clickState = createClickState(event, viewport);
25142
+ if (undefined === clickState) {
25143
+ return
25144
+ }
25105
25145
 
25106
- if (undefined === clickState) {
25107
- return
25108
- }
25146
+ let track = this.trackView.track;
25147
+ const dataList = track.popupData(clickState);
25109
25148
 
25110
- let track = viewport.trackView.track;
25111
- const dataList = track.popupData(clickState);
25149
+ const popupClickHandlerResult = this.browser.fireEvent('trackclick', [track, dataList]);
25112
25150
 
25113
- const popupClickHandlerResult = viewport.browser.fireEvent('trackclick', [track, dataList]);
25151
+ let content;
25152
+ if (undefined === popupClickHandlerResult || true === popupClickHandlerResult) {
25153
+ // Indicates handler did not handle the result, or the handler wishes default behavior to occur
25154
+ if (dataList && dataList.length > 0) {
25155
+ content = formatPopoverText(dataList);
25156
+ }
25114
25157
 
25115
- let content;
25116
- if (undefined === popupClickHandlerResult || true === popupClickHandlerResult) {
25117
- // Indicates handler did not handle the result, or the handler wishes default behavior to occur
25118
- if (dataList && dataList.length > 0) {
25119
- content = formatPopoverText(dataList);
25158
+ } else if (typeof popupClickHandlerResult === 'string') {
25159
+ content = popupClickHandlerResult;
25120
25160
  }
25121
25161
 
25122
- } else if (typeof popupClickHandlerResult === 'string') {
25123
- content = popupClickHandlerResult;
25162
+ return content
25124
25163
  }
25125
25164
 
25126
- return content
25165
+
25127
25166
  }
25128
25167
 
25168
+
25129
25169
  function formatPopoverText(nameValues) {
25130
25170
 
25131
25171
  const rows = nameValues.map(nameValue => {
@@ -26695,8 +26735,8 @@ function parseVariableStep(line) {
26695
26735
  */
26696
26736
 
26697
26737
  const fixColor = (colorString) => {
26698
- if (isString$3(colorString)) {
26699
- return (colorString.indexOf(",") > 0 && !colorString.startsWith("rgb(")) ?
26738
+ if (isString$2(colorString)) {
26739
+ return (colorString.indexOf(",") > 0 && !(colorString.startsWith("rgb(") || colorString.startsWith("rgba("))) ?
26700
26740
  `rgb(${colorString})` : colorString
26701
26741
  } else {
26702
26742
  return colorString
@@ -26724,6 +26764,7 @@ class TrackBase {
26724
26764
  * @param config
26725
26765
  */
26726
26766
  init(config) {
26767
+
26727
26768
  if (config.displayMode) {
26728
26769
  config.displayMode = config.displayMode.toUpperCase();
26729
26770
  }
@@ -26738,7 +26779,7 @@ class TrackBase {
26738
26779
  this.name = config.name || config.label;
26739
26780
  } else if (isFile(config.url)) {
26740
26781
  this.name = config.url.name;
26741
- } else if (isString$3(config.url) && !config.url.startsWith("data:")) {
26782
+ } else if (isString$2(config.url) && !config.url.startsWith("data:")) {
26742
26783
  this.name = getFilename$1(config.url);
26743
26784
  }
26744
26785
 
@@ -26779,8 +26820,12 @@ class TrackBase {
26779
26820
  }
26780
26821
  }
26781
26822
 
26782
- if(config.hoverTextFields) {
26783
- this.hoverTextFields = config.hoverTextFields;
26823
+ // Support for mouse hover text. This can be expensive, off by default.
26824
+ // this.hoverText = function(clickState) => return tool tip text
26825
+ if (config.hoverTextFields) {
26826
+ this.hoverText = hoverText.bind(this);
26827
+ } else if (typeof this.config.hoverText === 'function') {
26828
+ this.hoverText = this.config.hoverText;
26784
26829
  }
26785
26830
  }
26786
26831
 
@@ -26895,7 +26940,7 @@ class TrackBase {
26895
26940
  */
26896
26941
  setTrackProperties(properties) {
26897
26942
 
26898
- if(this.disposed) return; // This track was removed during async load
26943
+ if (this.disposed) return // This track was removed during async load
26899
26944
 
26900
26945
  const tracklineConfg = {};
26901
26946
  let tokens;
@@ -26998,20 +27043,20 @@ class TrackBase {
26998
27043
  }
26999
27044
 
27000
27045
  /**
27001
- * Return the features clicked over. Default implementation assumes a single row of features and only considers
27046
+ * Return the features clicked over. Default implementation assumes an array of features and only considers
27002
27047
  * the genomic location. Overriden by most subclasses.
27003
27048
  *
27004
27049
  * @param clickState
27005
27050
  * @param features
27006
27051
  * @returns {[]|*[]}
27007
27052
  */
27008
- clickedFeatures(clickState, features) {
27053
+ clickedFeatures(clickState) {
27009
27054
 
27010
27055
  // We use the cached features rather than method to avoid async load. If the
27011
27056
  // feature is not already loaded this won't work, but the user wouldn't be mousing over it either.
27012
- if (!features) features = clickState.viewport.cachedFeatures;
27057
+ const features = clickState.viewport.cachedFeatures;
27013
27058
 
27014
- if (!features || features.length === 0) {
27059
+ if (!features || !Array.isArray(features) || features.length === 0) {
27015
27060
  return []
27016
27061
  }
27017
27062
 
@@ -27109,65 +27154,6 @@ class TrackBase {
27109
27154
 
27110
27155
  }
27111
27156
 
27112
- /**
27113
- * Return a plain string for descriptive text given the list of features. The string is used to set a "title"
27114
- * attribute and cannot contain any html.
27115
- *
27116
- * @returns {undefined}
27117
- */
27118
- _hoverText(clickState) {
27119
-
27120
- const features = this.clickedFeatures(clickState);
27121
-
27122
- if (features && features.length > 0) {
27123
- let str = "";
27124
- for (let i = 0; i < features.length; i++) {
27125
- if (i === 10) {
27126
- str += "; ...";
27127
- break
27128
- }
27129
- if (!features[i]) continue
27130
-
27131
- const f = features[i]._f || features[i];
27132
- if (str.length > 0) str += "\n";
27133
-
27134
- if(this.hoverTextFields) {
27135
- str = "";
27136
- for(let field of this.hoverTextFields) {
27137
- if(str.length > 0) str += "\n";
27138
- if(f.hasOwnProperty(field)) {
27139
- str += f[field];
27140
- } else if(typeof f.getAttribute === "function") {
27141
- str += f.getAttribute(field);
27142
- }
27143
- }
27144
- }
27145
- else if (typeof this.config.hoverText === 'function') {
27146
- str += this.config.hoverText(f);
27147
- } else if (typeof f.hoverText === 'function') {
27148
- str += f.hoverText();
27149
- } else {
27150
- str += this.hoverText(f);
27151
- }
27152
- }
27153
- return str
27154
- }
27155
- }
27156
-
27157
- /**
27158
- * Default hoverText function. Can be overridden in track configuration or subclasses
27159
- *
27160
- * @param f - feature hovered over
27161
- */
27162
- hoverText(f) {
27163
- let str = "";
27164
- if (f.name) {
27165
- str += f.name;
27166
- if (f.value) str += ": ";
27167
- }
27168
- if (f.value) str += f.value; // TODO format value if number
27169
- return str;
27170
- }
27171
27157
 
27172
27158
  /**
27173
27159
  * Default track description -- displayed on click of track label. This can be overriden in the track
@@ -27240,6 +27226,38 @@ class TrackBase {
27240
27226
  }
27241
27227
  }
27242
27228
 
27229
+ function hoverText(clickState) {
27230
+
27231
+ if (!this.hoverTextFields) return
27232
+
27233
+ const features = this.clickedFeatures(clickState);
27234
+
27235
+ if (features && features.length > 0) {
27236
+ let str = "";
27237
+ for (let i = 0; i < features.length; i++) {
27238
+ if (i === 10) {
27239
+ str += "; ...";
27240
+ break
27241
+ }
27242
+ if (!features[i]) continue
27243
+
27244
+ const f = features[i]._f || features[i];
27245
+ if (str.length > 0) str += "\n";
27246
+
27247
+ str = "";
27248
+ for (let field of this.hoverTextFields) {
27249
+ if (str.length > 0) str += "\n";
27250
+ if (f.hasOwnProperty(field)) {
27251
+ str += f[field];
27252
+ } else if (typeof f.getAttribute === "function") {
27253
+ str += f.getAttribute(field);
27254
+ }
27255
+ }
27256
+
27257
+ }
27258
+ return str
27259
+ }
27260
+ }
27243
27261
 
27244
27262
  /**
27245
27263
  * Map UCSC track line "type" setting to file format. In igv.js "type" refers to the track type, not the input file format
@@ -27438,12 +27456,6 @@ class SegFeature {
27438
27456
  return pd
27439
27457
  }
27440
27458
 
27441
- hoverText() {
27442
-
27443
- return `${this.sample}: ${this.value}`
27444
- }
27445
-
27446
-
27447
27459
  extractCravatLink(genomeId) {
27448
27460
 
27449
27461
  let ref, alt;
@@ -27727,10 +27739,6 @@ class Variant {
27727
27739
  return fields
27728
27740
  }
27729
27741
 
27730
- hoverText() {
27731
- return `${this.names} ${this.referenceBases}->${this.alternateBases}`
27732
- }
27733
-
27734
27742
  getInfo(tag) {
27735
27743
  return this.info ? this.info[tag] : undefined;
27736
27744
  }
@@ -28949,10 +28957,9 @@ class CSIIndex {
28949
28957
  for (let bin = binRange[0]; bin <= binRange[1]; bin++) {
28950
28958
  if (ba.binIndex[bin]) {
28951
28959
  const binChunks = ba.binIndex[bin];
28952
- const nchnk = binChunks.length;
28953
- for (let c = 0; c < nchnk; ++c) {
28954
- const cs = binChunks[c][0];
28955
- const ce = binChunks[c][1];
28960
+ for (let c of binChunks) {
28961
+ const cs = c[0];
28962
+ const ce = c[1];
28956
28963
  chunks.push({minv: cs, maxv: ce, bin: bin});
28957
28964
  }
28958
28965
  }
@@ -28970,7 +28977,7 @@ class CSIIndex {
28970
28977
  reg2bins(beg, end) {
28971
28978
  beg -= 1; // < convert to 1-based closed
28972
28979
  if (beg < 1) beg = 1;
28973
- if (end > 2 ** 50) end = 2 ** 34; // 17 GiB ought to be enough for anybody
28980
+ if (end > 2 ** 34) end = 2 ** 34; // 17 GiB ought to be enough for anybody
28974
28981
  end -= 1;
28975
28982
  let l = 0;
28976
28983
  let t = 0;
@@ -28979,25 +28986,18 @@ class CSIIndex {
28979
28986
  for (; l <= this.depth; s -= 3, t += (1 << l * 3), l += 1) {
28980
28987
  const b = t + (beg >> s);
28981
28988
  const e = t + (end >> s);
28982
- if (e - b + bins.length > this.maxBinNumber)
28983
- throw new Error(
28984
- `query ${beg}-${end} is too large for current binning scheme (shift ${this.minShift}, depth ${this.depth}), try a smaller query or a coarser index binning scheme`,
28985
- )
28986
- //for (let i = b; i <= e; i += 1) bins.push(i)
28989
+ //
28990
+ // ITS NOT CLEAR WHERE THIS TEST CAME FROM, but maxBinNumber is never set, and its not clear what it represents.
28991
+ // if (e - b + bins.length > this.maxBinNumber)
28992
+ // throw new Error(
28993
+ // `query ${beg}-${end} is too large for current binning scheme (shift ${this.minShift}, depth ${this.depth}), try a smaller query or a coarser index binning scheme`,
28994
+ // )
28995
+ //
28987
28996
  bins.push([b, e]);
28988
28997
  }
28989
28998
  return bins
28990
28999
  }
28991
29000
 
28992
- // function reg2bins(beg, end, min_shift, depth) {
28993
- // let l, t, n, s = min_shift + depth * 3;
28994
- // const bins = [];
28995
- // for (--end, l = n = t = 0; l <= depth; s -= 3, t += 1 << l * 3, ++l) {
28996
- // let b = t + (beg >> s), e = t + (end >> s), i;
28997
- // for (i = b; i <= e; ++i) bins[n++] = i;
28998
- // }
28999
- // return bins;
29000
- // }
29001
29001
 
29002
29002
  bin_limit() {
29003
29003
  return ((1 << (this.depth + 1) * 3) - 1) / 7
@@ -29200,11 +29200,10 @@ class BamIndex {
29200
29200
  for (let binRange of overlappingBins) {
29201
29201
  for (let bin = binRange[0]; bin <= binRange[1]; bin++) {
29202
29202
  if (ba.binIndex[bin]) {
29203
- const binChunks = ba.binIndex[bin],
29204
- nchnk = binChunks.length;
29205
- for (let c = 0; c < nchnk; ++c) {
29206
- const cs = binChunks[c][0];
29207
- const ce = binChunks[c][1];
29203
+ const binChunks = ba.binIndex[bin];
29204
+ for (let c of binChunks) {
29205
+ const cs = c[0];
29206
+ const ce = c[1];
29208
29207
  chunks.push({minv: cs, maxv: ce, bin: bin});
29209
29208
  }
29210
29209
  }
@@ -29216,7 +29215,7 @@ class BamIndex {
29216
29215
  let lowest = null;
29217
29216
  const minLin = Math.min(min >> 14, nintv - 1);
29218
29217
  const maxLin = Math.min(max >> 14, nintv - 1);
29219
- for (let i = minLin; i <= maxLin; ++i) {
29218
+ for (let i = minLin; i < maxLin; i++) {
29220
29219
  const vp = ba.linearIndex[i];
29221
29220
  if (vp) {
29222
29221
  // todo -- I think, but am not sure, that the values in the linear index have to be in increasing order. So the first non-null should be minimum
@@ -30006,7 +30005,7 @@ class FeatureFileReader {
30006
30005
  * THE SOFTWARE.
30007
30006
  */
30008
30007
 
30009
- const isString$2 = isString$3;
30008
+ const isString$1 = isString$2;
30010
30009
 
30011
30010
 
30012
30011
  class CustomServiceReader {
@@ -30045,7 +30044,7 @@ class CustomServiceReader {
30045
30044
  if (data) {
30046
30045
  if (typeof this.config.parser === "function") {
30047
30046
  features = this.config.parser(data);
30048
- } else if (isString$2(data)) {
30047
+ } else if (isString$1(data)) {
30049
30048
  features = JSON.parse(data);
30050
30049
  } else {
30051
30050
  features = data;
@@ -33748,7 +33747,7 @@ class ROISet {
33748
33747
  this.name = config.name;
33749
33748
  } else if (config.url && isFile(config.url)) {
33750
33749
  this.name = config.url.name;
33751
- } else if (config.url && isString$3(config.url) && !config.url.startsWith("data:")) {
33750
+ } else if (config.url && isString$2(config.url) && !config.url.startsWith("data:")) {
33752
33751
  this.name = getFilename$1(config.url);
33753
33752
  }
33754
33753
 
@@ -33857,10 +33856,14 @@ class DynamicFeatureSource {
33857
33856
  this.genome = genome;
33858
33857
 
33859
33858
  for (let feature of features) {
33860
- let featureList = this.featureMap[feature.chr];
33859
+
33860
+ // Store as canonical chr name (i.e. translate aliases)
33861
+ const chrKey = genome ? genome.getChromosomeName(feature.chr) : feature.chr;
33862
+
33863
+ let featureList = this.featureMap[chrKey];
33861
33864
  if (!featureList) {
33862
33865
  featureList = [];
33863
- this.featureMap[feature.chr] = featureList;
33866
+ this.featureMap[chrKey] = featureList;
33864
33867
  }
33865
33868
  featureList.push(feature);
33866
33869
  }
@@ -34261,9 +34264,6 @@ class PairedAlignment {
34261
34264
  * THE SOFTWARE.
34262
34265
  */
34263
34266
 
34264
- const isString$1 = isString$3;
34265
- const hashCode = hashCode$1;
34266
-
34267
34267
  class BamAlignmentRow {
34268
34268
 
34269
34269
  constructor() {
@@ -34300,20 +34300,15 @@ class BamAlignmentRow {
34300
34300
 
34301
34301
  }
34302
34302
 
34303
- updateScore(options, alignmentContainer) {
34304
- this.score = this.calculateScore(options, alignmentContainer);
34305
- }
34306
-
34307
- calculateScore({position, option, direction, tag}, alignmentContainer) {
34303
+ getSortValue({position, option, tag}, alignmentContainer) {
34308
34304
 
34309
34305
  if (!option) option = "BASE";
34310
34306
 
34311
34307
  const alignment = this.findAlignment(position);
34312
- if (undefined === alignment) {
34313
- return Number.MAX_VALUE * (direction ? 1 : -1)
34308
+ if (undefined === alignment) { // This condition should never occur
34309
+ return Number.MAX_VALUE
34314
34310
  }
34315
34311
 
34316
- let mate;
34317
34312
  switch (option) {
34318
34313
  case "NUCLEOTIDE":
34319
34314
  case "BASE": {
@@ -34324,31 +34319,16 @@ class BamAlignmentRow {
34324
34319
  case "START":
34325
34320
  return alignment.start
34326
34321
  case "TAG": {
34327
-
34328
- const tagValue = alignment.tags()[tag];
34329
- if (tagValue !== undefined) {
34330
- return isString$1(tagValue) ? hashCode(tagValue) : tagValue
34331
- } else {
34332
- return Number.MAX_VALUE
34333
- }
34322
+ return alignment.tags()[tag]
34334
34323
  }
34335
34324
  case "READ_NAME":
34336
- return hashCode(alignment.readName)
34325
+ return alignment.readName
34337
34326
  case "INSERT_SIZE":
34338
34327
  return -Math.abs(alignment.fragmentLength)
34339
34328
  case "GAP_SIZE":
34340
34329
  return -alignment.gapSizeAt(position)
34341
34330
  case "MATE_CHR":
34342
- mate = alignment.mate;
34343
- if (!mate) {
34344
- return Number.MAX_VALUE
34345
- } else {
34346
- if (mate.chr === alignment.chr) {
34347
- return Number.MAX_VALUE - 1
34348
- } else {
34349
- return hashCode(mate.chr)
34350
- }
34351
- }
34331
+ return alignment.mate
34352
34332
  case "MQ":
34353
34333
  return alignment.mq === undefined ? Number.MAX_VALUE : -alignment.mq
34354
34334
  case "ALIGNED_READ_LENGTH":
@@ -34411,6 +34391,8 @@ class BamAlignmentRow {
34411
34391
  return baseScore
34412
34392
  }
34413
34393
  }
34394
+
34395
+
34414
34396
  }
34415
34397
 
34416
34398
  function canBePaired(alignment) {
@@ -34692,6 +34674,39 @@ class AlignmentContainer {
34692
34674
  getMax(start, end) {
34693
34675
  return this.coverageMap.getMax(start, end)
34694
34676
  }
34677
+
34678
+ sortRows(options) {
34679
+
34680
+ const newRows = [];
34681
+ const undefinedRow = [];
34682
+ for (let row of this.packedAlignmentRows) {
34683
+ const alignment = row.findAlignment(options.position);
34684
+ if (undefined !== alignment) {
34685
+ newRows.push(row);
34686
+ } else {
34687
+ undefinedRow.push(row);
34688
+ }
34689
+ }
34690
+
34691
+ newRows.sort((rowA, rowB) => {
34692
+ const direction = options.direction;
34693
+ const rowAValue = rowA.getSortValue(options, this);
34694
+ const rowBValue = rowB.getSortValue(options, this);
34695
+
34696
+ if (rowBValue === undefined && rowBValue !== undefined) return 1
34697
+ else if (rowAValue !== undefined && rowBValue === undefined) return -1
34698
+
34699
+ const i = rowAValue > rowBValue ? 1 : (rowAValue < rowBValue ? -1 : 0);
34700
+ return true === direction ? i : -i
34701
+ });
34702
+
34703
+ for (let row of undefinedRow) {
34704
+ newRows.push(row);
34705
+ }
34706
+
34707
+ this.packedAlignmentRows = newRows;
34708
+ }
34709
+
34695
34710
  }
34696
34711
 
34697
34712
 
@@ -34920,7 +34935,7 @@ class Coverage {
34920
34935
  hoverText() {
34921
34936
  const pos = this.posA + this.posT + this.posC + this.posG + this.posN;
34922
34937
  const neg = this.negA + this.negT + this.negC + this.negG + this.negN;
34923
- return `${this.total } (${pos}+, ${neg}-)`
34938
+ return `${this.total} (${pos}+, ${neg}-)`
34924
34939
  }
34925
34940
 
34926
34941
  isMismatch(refBase) {
@@ -35120,10 +35135,6 @@ class BamAlignment {
35120
35135
  return (genomicLocation >= s && genomicLocation <= (s + l))
35121
35136
  }
35122
35137
 
35123
- hoverText() {
35124
- return this.readName;
35125
- }
35126
-
35127
35138
  popupData(genomicLocation) {
35128
35139
 
35129
35140
  // if the user clicks on a base next to an insertion, show just the
@@ -37568,9 +37579,6 @@ class BamSource {
37568
37579
  this.genome = genome;
37569
37580
 
37570
37581
  if (isDataURL(config.url)) {
37571
- if ("cram" === config.format) {
37572
- throw "CRAM data uris are not supported"
37573
- }
37574
37582
  this.config.indexed = false;
37575
37583
  }
37576
37584
 
@@ -37586,7 +37594,7 @@ class BamSource {
37586
37594
  this.bamReader = new CramReader(config, genome, browser);
37587
37595
  } else {
37588
37596
  if (!this.config.indexURL && config.indexed !== false) {
37589
- if (isString$3(this.config.url)) {
37597
+ if (isString$2(this.config.url)) {
37590
37598
  const inferIndexPath$1 = inferIndexPath(this.config.url, "bai");
37591
37599
  if (inferIndexPath$1) {
37592
37600
  console.error(`Warning: no indexURL specified for ${this.config.url}. Guessing ${this.baiPath}`);
@@ -39857,7 +39865,7 @@ class BAMTrack extends TrackBase {
39857
39865
  if (vp.containsPosition(options.chr, options.position)) {
39858
39866
  const alignmentContainer = vp.cachedFeatures;
39859
39867
  if (alignmentContainer) {
39860
- sortAlignmentRows(options, alignmentContainer);
39868
+ alignmentContainer.sortRows(options);
39861
39869
  vp.repaint();
39862
39870
  }
39863
39871
  }
@@ -39901,7 +39909,7 @@ class BAMTrack extends TrackBase {
39901
39909
  const sort = this.sortObject;
39902
39910
  if (sort) {
39903
39911
  if (sort.chr === chr && sort.position >= bpStart && sort.position <= bpEnd) {
39904
- sortAlignmentRows(sort, alignmentContainer);
39912
+ alignmentContainer.sortRows(sort);
39905
39913
  }
39906
39914
  }
39907
39915
 
@@ -39978,6 +39986,14 @@ class BAMTrack extends TrackBase {
39978
39986
  return clickedObject ? [clickedObject] : undefined
39979
39987
  }
39980
39988
 
39989
+ hoverText(clickState) {
39990
+ if (true === this.showCoverage && clickState.y >= this.coverageTrack.top && clickState.y < this.coverageTrack.height) {
39991
+ const clickedObject = this.coverageTrack.getClickedObject(clickState);
39992
+ return clickedObject.hoverText()
39993
+ }
39994
+
39995
+ }
39996
+
39981
39997
  menuItemList() {
39982
39998
 
39983
39999
 
@@ -40981,7 +40997,7 @@ class AlignmentTrack {
40981
40997
  direction: direction
40982
40998
  };
40983
40999
  this.parent.sortObject = newSortObject;
40984
- sortAlignmentRows(newSortObject, viewport.cachedFeatures);
41000
+ viewport.cachedFeatures.sortRows(newSortObject);
40985
41001
  viewport.repaint();
40986
41002
  };
40987
41003
  list.push('<b>Sort by...</b>');
@@ -41012,7 +41028,7 @@ class AlignmentTrack {
41012
41028
  };
41013
41029
  this.sortByTag = tag;
41014
41030
  this.parent.sortObject = newSortObject;
41015
- sortAlignmentRows(newSortObject, viewport.cachedFeatures);
41031
+ viewport.cachedFeatures.sortRows(newSortObject);
41016
41032
  viewport.repaint();
41017
41033
  }
41018
41034
  }
@@ -41255,21 +41271,6 @@ class AlignmentTrack {
41255
41271
  }
41256
41272
  }
41257
41273
 
41258
- function sortAlignmentRows(options, alignmentContainer) {
41259
-
41260
- const direction = options.direction;
41261
-
41262
- for (let row of alignmentContainer.packedAlignmentRows) {
41263
- row.updateScore(options, alignmentContainer);
41264
- }
41265
-
41266
- alignmentContainer.packedAlignmentRows.sort(function (rowA, rowB) {
41267
- const i = rowA.score > rowB.score ? 1 : (rowA.score < rowB.score ? -1 : 0);
41268
- return true === direction ? i : -i
41269
- });
41270
-
41271
- }
41272
-
41273
41274
  function shadedBaseColor(qual, baseColor) {
41274
41275
 
41275
41276
  const minQ = 5; //prefs.getAsInt(PreferenceManager.SAM_BASE_QUALITY_MIN),
@@ -41410,6 +41411,10 @@ class RulerViewport extends TrackViewport {
41410
41411
  super(trackView, $viewportColumn, referenceFrame, width);
41411
41412
  }
41412
41413
 
41414
+ get contentDiv() {
41415
+ return this.$viewport.get(0)
41416
+ }
41417
+
41413
41418
  initializationHelper() {
41414
41419
 
41415
41420
  this.$multiLocusCloseButton = $$1('<div>', {class: 'igv-multi-locus-close-button'});
@@ -41637,7 +41642,8 @@ class IdeogramViewport extends TrackViewport {
41637
41642
 
41638
41643
  this.canvas = document.createElement('canvas');
41639
41644
  this.canvas.className = 'igv-ideogram-canvas';
41640
- this.$content.append($$1(this.canvas));
41645
+ //this.$content.append($(this.canvas))
41646
+ this.$viewport.append($$1(this.canvas));
41641
41647
  this.ideogram_ctx = this.canvas.getContext('2d');
41642
41648
 
41643
41649
  this.addMouseHandlers();
@@ -42211,7 +42217,7 @@ const hideAllMenuPopups = () => {
42211
42217
  * THE SOFTWARE.
42212
42218
  */
42213
42219
 
42214
- const scrollbarExclusionTypes = new Set(['ruler', 'sequence', 'ideogram']);
42220
+ const scrollbarExclusionTypes = new Set(['ruler', 'ideogram']);
42215
42221
  const colorPickerExclusionTypes = new Set(['ruler', 'sequence', 'ideogram']);
42216
42222
 
42217
42223
  class TrackView {
@@ -42383,10 +42389,10 @@ class TrackView {
42383
42389
 
42384
42390
  const trackColors = [];
42385
42391
  const color = this.track.color || this.track.defaultColor;
42386
- if (isString$3(color)) {
42392
+ if (isString$2(color)) {
42387
42393
  trackColors.push(color);
42388
42394
  }
42389
- if (this.track.altColor && isString$3(this.track.altColor)) {
42395
+ if (this.track.altColor && isString$2(this.track.altColor)) {
42390
42396
  trackColors.push(this.track.altColor);
42391
42397
  }
42392
42398
  const defaultColors = trackColors.map(c => c.startsWith("#") ? c : c.startsWith("rgb(") ? IGVColor.rgbToHex(c) : IGVColor.colorNameToHex(c));
@@ -42591,17 +42597,18 @@ class TrackView {
42591
42597
  }
42592
42598
 
42593
42599
  if (this.track.autoscale) {
42594
- let allFeatures = [];
42600
+ let allFeatures;
42595
42601
  for (let visibleViewport of visibleViewports) {
42596
42602
  const referenceFrame = visibleViewport.referenceFrame;
42597
42603
  const start = referenceFrame.start;
42598
- const end = start + referenceFrame.toBP($$1(visibleViewport.contentDiv).width());
42604
+ const end = start + referenceFrame.toBP(visibleViewport.getWidth());
42599
42605
  if (visibleViewport.featureCache && visibleViewport.featureCache.features) {
42606
+ // If the "features" object has a getMax function use it. Currently only alignmentContainer implements this, for coverage.
42600
42607
  if (typeof visibleViewport.featureCache.features.getMax === 'function') {
42601
42608
  const max = visibleViewport.featureCache.features.getMax(start, end);
42602
- allFeatures.push({value: max});
42609
+ allFeatures = [{value: max}];
42603
42610
  } else {
42604
- allFeatures = allFeatures.concat(FeatureUtils.findOverlapping(visibleViewport.featureCache.features, start, end));
42611
+ allFeatures = FeatureUtils.findOverlapping(visibleViewport.featureCache.features, start, end);
42605
42612
  }
42606
42613
  }
42607
42614
  }
@@ -42666,7 +42673,7 @@ class TrackView {
42666
42673
 
42667
42674
  const referenceFrame = vp.referenceFrame;
42668
42675
  const {chr, start, bpPerPixel} = vp.referenceFrame;
42669
- const end = start + referenceFrame.toBP($$1(vp.contentDiv).width());
42676
+ const end = start + referenceFrame.toBP(vp.getWidth());
42670
42677
  const needsReload = !vp.featureCache || !vp.featureCache.containsRange(chr, start, end, bpPerPixel);
42671
42678
 
42672
42679
  if (needsReload) {
@@ -43558,7 +43565,7 @@ class FeatureTrack extends TrackBase {
43558
43565
 
43559
43566
  if (typeof this.featureSource.getHeader === "function") {
43560
43567
  this.header = await this.featureSource.getHeader();
43561
- if(this.disposed) return; // This track was removed during async load
43568
+ if (this.disposed) return // This track was removed during async load
43562
43569
  }
43563
43570
 
43564
43571
  // Set properties from track line
@@ -43651,7 +43658,7 @@ class FeatureTrack extends TrackBase {
43651
43658
  options.rowLastLabelX[row] = -Number.MAX_SAFE_INTEGER;
43652
43659
  }
43653
43660
  }
43654
- const maxFeatureCount = Math.max(1, Math.max(...rowFeatureCount));
43661
+ const maxFeatureCount = Math.max(1, Math.max(...rowFeatureCount));
43655
43662
  const pixelsPerFeature = pixelWidth / maxFeatureCount;
43656
43663
 
43657
43664
  let lastPxEnd = [];
@@ -43682,10 +43689,10 @@ class FeatureTrack extends TrackBase {
43682
43689
 
43683
43690
  };
43684
43691
 
43685
- clickedFeatures(clickState, features) {
43692
+ clickedFeatures(clickState) {
43686
43693
 
43687
43694
  const y = clickState.y - this.margin;
43688
- const allFeatures = super.clickedFeatures(clickState, features);
43695
+ const allFeatures = super.clickedFeatures(clickState);
43689
43696
 
43690
43697
  let row;
43691
43698
  switch (this.displayMode) {
@@ -43709,9 +43716,8 @@ class FeatureTrack extends TrackBase {
43709
43716
  */
43710
43717
  popupData(clickState, features) {
43711
43718
 
43712
- features = this.clickedFeatures(clickState, features);
43719
+ if (features === undefined) features = this.clickedFeatures(clickState);
43713
43720
  const genomicLocation = clickState.genomicLocation;
43714
-
43715
43721
  const data = [];
43716
43722
  for (let feature of features) {
43717
43723
 
@@ -43738,7 +43744,7 @@ class FeatureTrack extends TrackBase {
43738
43744
  fd.name &&
43739
43745
  fd.name.toLowerCase() === "name" &&
43740
43746
  fd.value &&
43741
- isString$3(fd.value) &&
43747
+ isString$2(fd.value) &&
43742
43748
  !fd.value.startsWith("<")) {
43743
43749
  const href = infoURL.replace("$$", feature.name);
43744
43750
  fd.value = `<a target=_blank href=${href}>${fd.value}</a>`;
@@ -43836,8 +43842,7 @@ class FeatureTrack extends TrackBase {
43836
43842
  let seq = await this.browser.genome.getSequence(f.chr, f.start, f.end);
43837
43843
  if (!seq) {
43838
43844
  seq = "Unknown sequence";
43839
- }
43840
- else if (f.strand === '-') {
43845
+ } else if (f.strand === '-') {
43841
43846
  seq = reverseComplementSequence(seq);
43842
43847
  }
43843
43848
  this.browser.alert.present(seq);
@@ -43853,8 +43858,7 @@ class FeatureTrack extends TrackBase {
43853
43858
  let seq = await this.browser.genome.getSequence(f.chr, f.start, f.end);
43854
43859
  if (!seq) {
43855
43860
  seq = "Unknown sequence";
43856
- }
43857
- else if (f.strand === '-') {
43861
+ } else if (f.strand === '-') {
43858
43862
  seq = reverseComplementSequence(seq);
43859
43863
  }
43860
43864
  try {
@@ -44171,10 +44175,7 @@ class WigTrack extends TrackBase {
44171
44175
 
44172
44176
  popupData(clickState, features) {
44173
44177
 
44174
- // We use the featureCache property rather than method to avoid async load. If the
44175
- // feature is not already loaded this won't work, but the user wouldn't be mousing over it either.
44176
-
44177
- features = this.clickedFeatures(clickState, features);
44178
+ if(features === undefined) features = this.clickedFeatures(clickState);
44178
44179
 
44179
44180
  if (features && features.length > 0) {
44180
44181
 
@@ -44492,7 +44493,7 @@ class SegTrack extends TrackBase {
44492
44493
 
44493
44494
  draw({context, renderSVG, pixelTop, pixelWidth, pixelHeight, features, bpPerPixel, bpStart}) {
44494
44495
 
44495
- IGVGraphics.fillRect(context, 0, 0, pixelWidth, pixelHeight, {'fillStyle': "rgb(255, 255, 255)"});
44496
+ IGVGraphics.fillRect(context, 0, pixelTop, pixelWidth, pixelHeight, {'fillStyle': "rgb(255, 255, 255)"});
44496
44497
 
44497
44498
  if (features && features.length > 0) {
44498
44499
 
@@ -44716,9 +44717,9 @@ class SegTrack extends TrackBase {
44716
44717
 
44717
44718
  }
44718
44719
 
44719
- clickedFeatures(clickState, features) {
44720
+ clickedFeatures(clickState) {
44720
44721
 
44721
- const allFeatures = super.clickedFeatures(clickState, features);
44722
+ const allFeatures = super.clickedFeatures(clickState);
44722
44723
  const y = clickState.y;
44723
44724
  return allFeatures.filter(function (feature) {
44724
44725
  const rect = feature.pixelRect;
@@ -44727,13 +44728,16 @@ class SegTrack extends TrackBase {
44727
44728
 
44728
44729
  }
44729
44730
 
44730
- hoverText(feature) {
44731
- return `${feature.sample}: ${feature.value}`
44731
+ hoverText(clickState) {
44732
+ const features = this.clickedFeatures(clickState);
44733
+ if(features && features.length > 0) {
44734
+ return `${features[0].sample}: ${features[0].value}`
44735
+ }
44732
44736
  }
44733
44737
 
44734
44738
  popupData(clickState, featureList) {
44735
44739
 
44736
- featureList = this.clickedFeatures(clickState);
44740
+ if(featureList === undefined) featureList = this.clickedFeatures(clickState);
44737
44741
 
44738
44742
  const items = [];
44739
44743
 
@@ -44889,6 +44893,7 @@ const MUT_COLORS = {
44889
44893
  * THE SOFTWARE.
44890
44894
  */
44891
44895
 
44896
+
44892
44897
  /**
44893
44898
  * Represents 2 or more wig tracks overlaid on a common viewport.
44894
44899
  */
@@ -44899,6 +44904,7 @@ class MergedTrack extends TrackBase {
44899
44904
  this.type = "merged";
44900
44905
  this.featureType = 'numeric';
44901
44906
  this.paintAxis = paintAxis;
44907
+ this.graphType = config.graphType;
44902
44908
  }
44903
44909
 
44904
44910
  init(config) {
@@ -44978,68 +44984,111 @@ class MergedTrack extends TrackBase {
44978
44984
  return items
44979
44985
  }
44980
44986
 
44987
+ /**
44988
+ * Returns a MergedFeatureCollection containing an array of features for the specified range, 1 for each track.
44989
+ */
44981
44990
  async getFeatures(chr, bpStart, bpEnd, bpPerPixel) {
44982
44991
 
44983
44992
  const promises = this.tracks.map((t) => t.getFeatures(chr, bpStart, bpEnd, bpPerPixel));
44984
- return Promise.all(promises)
44993
+ const featureArrays = await Promise.all(promises);
44994
+ return new MergedFeatureCollection(featureArrays)
44985
44995
  }
44986
44996
 
44987
44997
  draw(options) {
44988
44998
 
44989
- const mergedFeatures = options.features; // Array of feature arrays, 1 for each track
44990
-
44991
- if (this.autoscale) {
44992
- this.dataRange = autoscale(options.referenceFrame.chr, mergedFeatures);
44993
- }
44999
+ const mergedFeatures = options.features; // A MergedFeatureCollection
44994
45000
 
44995
45001
  for (let i = 0, len = this.tracks.length; i < len; i++) {
44996
45002
  const trackOptions = Object.assign({}, options);
44997
- trackOptions.features = mergedFeatures[i];
45003
+ trackOptions.features = mergedFeatures.featureArrays[i];
44998
45004
  this.tracks[i].dataRange = this.dataRange;
44999
45005
  this.tracks[i].flipAxis = this.flipAxis;
45000
45006
  this.tracks[i].logScale = this.logScale;
45001
- this.tracks[i].graphType = this.graphType;
45007
+ if (this.graphType) {
45008
+ this.tracks[i].graphType = this.graphType;
45009
+ }
45002
45010
  this.tracks[i].draw(trackOptions);
45003
45011
  }
45004
45012
  }
45005
45013
 
45006
- popupData(clickState, features) {
45014
+ popupData(clickState) {
45007
45015
 
45008
- const featuresArray = features || clickState.viewport.cachedFeatures;
45016
+ if(clickState.viewport && clickState.viewport.cachedFeatures) {
45009
45017
 
45010
- if (featuresArray && featuresArray.length === this.tracks.length) {
45011
- // Array of feature arrays, 1 for each track
45012
- const popupData = [];
45013
- for (let i = 0; i < this.tracks.length; i++) {
45014
- if (i > 0) popupData.push('<hr/>');
45015
- popupData.push(`<div style=background-color:rgb(245,245,245);border-bottom-style:dashed;border-bottom-width:1px;padding-bottom:5px;padding-top:10px;font-weight:bold;font-size:larger >${this.tracks[i].name}</div>`);
45016
- const trackPopupData = this.tracks[i].popupData(clickState, featuresArray[i]);
45017
- popupData.push(...trackPopupData);
45018
+ const featuresArray = clickState.viewport.cachedFeatures.featureArrays;
45019
+
45020
+ if (featuresArray && featuresArray.length === this.tracks.length) {
45021
+ // Array of feature arrays, 1 for each track
45022
+ const popupData = [];
45023
+ for (let i = 0; i < this.tracks.length; i++) {
45024
+ if (i > 0) popupData.push('<hr/>');
45025
+ popupData.push(`<div style=background-color:rgb(245,245,245);border-bottom-style:dashed;border-bottom-width:1px;padding-bottom:5px;padding-top:10px;font-weight:bold;font-size:larger >${this.tracks[i].name}</div>`);
45026
+ const trackPopupData = this.tracks[i].popupData(clickState, featuresArray[i]);
45027
+ popupData.push(...trackPopupData);
45018
45028
 
45029
+ }
45030
+ return popupData
45019
45031
  }
45020
- return popupData
45021
45032
  }
45022
45033
  }
45023
45034
 
45035
+ clickedFeatures(clickState) {
45036
+
45037
+
45038
+ // We use the cached features rather than method to avoid async load. If the
45039
+ // feature is not already loaded this won't work, but the user wouldn't be mousing over it either.
45040
+ const mergedFeaturesCollection = clickState.viewport.cachedFeatures;
45041
+
45042
+ if(!mergedFeaturesCollection) {
45043
+ return [];
45044
+ }
45045
+
45046
+ const genomicLocation = clickState.genomicLocation;
45047
+ const clickedFeatures = [];
45048
+ for(let features of mergedFeaturesCollection.featureArrays) {
45049
+ // When zoomed out we need some tolerance around genomicLocation
45050
+ const tolerance = (clickState.referenceFrame.bpPerPixel > 0.2) ? 3 * clickState.referenceFrame.bpPerPixel : 0.2;
45051
+ const ss = genomicLocation - tolerance;
45052
+ const ee = genomicLocation + tolerance;
45053
+ const tmp = (FeatureUtils.findOverlapping(features, ss, ee));
45054
+ for(let f of tmp) {
45055
+ clickedFeatures.push(f);
45056
+ }
45057
+ }
45058
+ return clickedFeatures;
45059
+ }
45060
+
45024
45061
 
45025
45062
  get supportsWholeGenome() {
45026
- return this.tracks.every(track => track.supportsWholeGenome())
45063
+ return this.tracks.every(track => track.supportsWholeGenome)
45027
45064
  }
45028
45065
  }
45029
45066
 
45030
- function autoscale(chr, featureArrays) {
45031
45067
 
45032
- let min = 0;
45033
- let max = -Number.MAX_VALUE;
45034
- for(let features of featureArrays) {
45035
- for(let f of features) {
45036
- if (typeof f.value !== 'undefined' && !Number.isNaN(f.value)) {
45037
- min = Math.min(min, f.value);
45038
- max = Math.max(max, f.value);
45068
+ class MergedFeatureCollection {
45069
+
45070
+ constructor(featureArrays) {
45071
+ this.featureArrays = featureArrays;
45072
+ }
45073
+
45074
+ getMax(start, end) {
45075
+ let max = -Number.MAX_VALUE;
45076
+ for (let a of this.featureArrays) {
45077
+ for (let f of a) {
45078
+ if (typeof f.value !== 'undefined' && !Number.isNaN(f.value)) {
45079
+ if (f.end < start) {
45080
+ continue
45081
+ }
45082
+ if (f.start > end) {
45083
+ break
45084
+ }
45085
+ max = Math.max(max, f.value);
45086
+ }
45039
45087
  }
45040
45088
  }
45089
+ return max
45041
45090
  }
45042
- return {min: min, max: max}
45091
+
45043
45092
  }
45044
45093
 
45045
45094
  /*
@@ -45622,7 +45671,7 @@ class InteractionTrack extends TrackBase {
45622
45671
 
45623
45672
  popupData(clickState, features) {
45624
45673
 
45625
- features = this.clickedFeatures(clickState);
45674
+ if(features === undefined) features = this.clickedFeatures(clickState);
45626
45675
 
45627
45676
  const data = [];
45628
45677
  for (let feature of features) {
@@ -45664,11 +45713,11 @@ class InteractionTrack extends TrackBase {
45664
45713
  return data
45665
45714
  }
45666
45715
 
45667
- clickedFeatures(clickState, features) {
45716
+ clickedFeatures(clickState) {
45668
45717
 
45669
45718
  // We use the cached features rather than method to avoid async load. If the
45670
45719
  // feature is not already loaded this won't work, but the user wouldn't be mousing over it either.
45671
- const featureList = features || clickState.viewport.cachedFeatures;
45720
+ const featureList = clickState.viewport.cachedFeatures;
45672
45721
  const candidates = [];
45673
45722
  if (featureList) {
45674
45723
  const proportional = (this.arcType === "proportional" || this.arcType === "inView" || this.arcType === "partialInView");
@@ -45930,7 +45979,7 @@ function extractInfoColumn(data, str) {
45930
45979
  * THE SOFTWARE.
45931
45980
  */
45932
45981
 
45933
- const isString = isString$3;
45982
+ const isString = isString$2;
45934
45983
 
45935
45984
 
45936
45985
  const DEFAULT_VISIBILITY_WINDOW = 1000000;
@@ -46258,9 +46307,9 @@ class VariantTrack extends TrackBase {
46258
46307
  }
46259
46308
  }
46260
46309
 
46261
- clickedFeatures(clickState, features) {
46310
+ clickedFeatures(clickState) {
46262
46311
 
46263
- let featureList = super.clickedFeatures(clickState, features);
46312
+ let featureList = super.clickedFeatures(clickState);
46264
46313
 
46265
46314
  const vGap = (this.displayMode === 'EXPANDED') ? this.expandedVGap : this.squishedVGap;
46266
46315
  const callHeight = vGap + ("SQUISHED" === this.displayMode ? this.squishedCallHeight : this.expandedCallHeight);
@@ -46296,9 +46345,9 @@ class VariantTrack extends TrackBase {
46296
46345
  /**
46297
46346
  * Return "popup data" for feature @ genomic location. Data is an array of key-value pairs
46298
46347
  */
46299
- popupData(clickState, features) {
46348
+ popupData(clickState, featureList) {
46300
46349
 
46301
- const featureList = this.clickedFeatures(clickState, features);
46350
+ if(featureList === undefined) featureList = this.clickedFeatures(clickState);
46302
46351
  const genomicLocation = clickState.genomicLocation;
46303
46352
  const genomeID = this.browser.genome.id;
46304
46353
  const sampleInformation = this.browser.sampleInformation;
@@ -46826,9 +46875,9 @@ class EqtlTrack extends TrackBase {
46826
46875
  /**
46827
46876
  * Return "popup data" for feature @ genomic location. Data is an array of key-value pairs
46828
46877
  */
46829
- popupData(clickState) {
46878
+ popupData(clickState, features) {
46830
46879
 
46831
- let features = clickState.viewport.cachedFeatures;
46880
+ if(features === undefined) features = clickState.viewport.cachedFeatures;
46832
46881
  if (!features || features.length === 0) return []
46833
46882
 
46834
46883
  const tolerance = 3;
@@ -47155,11 +47204,12 @@ class GWASTrack extends TrackBase {
47155
47204
  }
47156
47205
  }
47157
47206
 
47158
- popupData(clickState) {
47207
+ popupData(clickState, features) {
47208
+
47209
+ if(features === undefined) features = clickState.viewport.cachedFeatures;
47159
47210
 
47160
47211
  let data = [];
47161
47212
  const track = clickState.viewport.trackView.track;
47162
- const features = clickState.viewport.cachedFeatures;
47163
47213
 
47164
47214
  if (features) {
47165
47215
  let count = 0;
@@ -47547,12 +47597,12 @@ class GCNVTrack extends TrackBase {
47547
47597
  return []
47548
47598
  }
47549
47599
 
47550
- popupData(clickState, featureList) {
47600
+ popupData(clickState, features) {
47551
47601
 
47552
- featureList = this.clickedFeatures(clickState, featureList);
47602
+ if(features === undefined) features = this.clickedFeatures(clickState);
47553
47603
 
47554
47604
  const items = [];
47555
- featureList.forEach(function (f) {
47605
+ features.forEach(function (f) {
47556
47606
  for (let property of Object.keys(f)) {
47557
47607
  if (isSimpleType(f[property])) {
47558
47608
  items.push({name: property, value: f[property]});
@@ -47738,9 +47788,9 @@ class RnaStructTrack extends TrackBase {
47738
47788
  }
47739
47789
  }
47740
47790
 
47741
- clickedFeatures(clickState, features) {
47791
+ clickedFeatures(clickState) {
47742
47792
 
47743
- features = super.clickedFeatures(clickState, features);
47793
+ const features = super.clickedFeatures(clickState);
47744
47794
 
47745
47795
  const clicked = [];
47746
47796
 
@@ -47782,10 +47832,7 @@ class RnaStructTrack extends TrackBase {
47782
47832
 
47783
47833
  popupData(clickState, features) {
47784
47834
 
47785
- // We use the featureCache property rather than method to avoid async load. If the
47786
- // feature is not already loaded this won't work, but the user wouldn't be mousing over it either.
47787
-
47788
- features = this.clickedFeatures(clickState, features);
47835
+ if(features === undefined) features = this.clickedFeatures(clickState);
47789
47836
 
47790
47837
  if (features && features.length > 0) {
47791
47838
 
@@ -48213,7 +48260,7 @@ class SpliceJunctionTrack extends TrackBase {
48213
48260
 
48214
48261
  if (typeof this.featureSource.getHeader === "function") {
48215
48262
  this.header = await this.featureSource.getHeader();
48216
- if(this.disposed) return; // This track was removed during async load
48263
+ if (this.disposed) return // This track was removed during async load
48217
48264
  }
48218
48265
 
48219
48266
  // Set properties from track line
@@ -48270,7 +48317,8 @@ class SpliceJunctionTrack extends TrackBase {
48270
48317
 
48271
48318
  junctionRenderingContext.referenceFrame = options.viewport.referenceFrame;
48272
48319
  junctionRenderingContext.referenceFrameStart = junctionRenderingContext.referenceFrame.start;
48273
- junctionRenderingContext.referenceFrameEnd = junctionRenderingContext.referenceFrameStart + junctionRenderingContext.referenceFrame.toBP($$1(options.viewport.contentDiv).width());
48320
+ junctionRenderingContext.referenceFrameEnd = junctionRenderingContext.referenceFrameStart +
48321
+ junctionRenderingContext.referenceFrame.toBP(options.viewport.getWidth());
48274
48322
 
48275
48323
  // For a given viewport, records where features that are < 2px in width have been rendered already.
48276
48324
  // This prevents wasteful rendering of multiple such features onto the same pixels.
@@ -48518,9 +48566,9 @@ class SpliceJunctionTrack extends TrackBase {
48518
48566
  ctx.fillText(label, junctionMiddlePx - ctx.measureText(label).width / 2, (7 * topY + cy) / 8);
48519
48567
  }
48520
48568
 
48521
- clickedFeatures(clickState, features) {
48569
+ clickedFeatures(clickState) {
48522
48570
 
48523
- const allFeatures = super.clickedFeatures(clickState, features);
48571
+ const allFeatures = super.clickedFeatures(clickState);
48524
48572
 
48525
48573
  return allFeatures.filter(function (feature) {
48526
48574
  return (feature.isVisible && feature.attributes)
@@ -48532,7 +48580,7 @@ class SpliceJunctionTrack extends TrackBase {
48532
48580
  */
48533
48581
  popupData(clickState, features) {
48534
48582
 
48535
- features = this.clickedFeatures(clickState, features);
48583
+ if (features === undefined) features = this.clickedFeatures(clickState);
48536
48584
  const genomicLocation = clickState.genomicLocation;
48537
48585
 
48538
48586
  const data = [];
@@ -51976,11 +52024,11 @@ class Browser {
51976
52024
  */
51977
52025
  toSVG() {
51978
52026
 
51979
- let {x, y, width, height} = this.columnContainer.getBoundingClientRect();
52027
+ const {y, width, height} = this.columnContainer.getBoundingClientRect();
51980
52028
 
51981
52029
  const h_render = 8000;
51982
52030
 
51983
- let context = new ctx(
52031
+ const config =
51984
52032
  {
51985
52033
 
51986
52034
  width,
@@ -51998,13 +52046,14 @@ class Browser {
51998
52046
  height: h_render
51999
52047
  }
52000
52048
 
52001
- });
52049
+ };
52050
+
52051
+ const context = new ctx(config);
52002
52052
 
52003
52053
  // tracks -> SVG
52004
52054
  for (let trackView of this.trackViews) {
52005
52055
  trackView.renderSVGContext(context, {deltaX: 0, deltaY: -y});
52006
52056
  }
52007
-
52008
52057
  // reset height to trim away unneeded svg canvas real estate. Yes, a bit of a hack.
52009
52058
  context.setHeight(height);
52010
52059
 
@@ -52436,7 +52485,7 @@ class Browser {
52436
52485
  async _loadTrack(config) {
52437
52486
 
52438
52487
  // config might be json
52439
- if (isString$3(config)) {
52488
+ if (isString$2(config)) {
52440
52489
  config = JSON.parse(config);
52441
52490
  }
52442
52491
 
@@ -52559,7 +52608,7 @@ class Browser {
52559
52608
 
52560
52609
  // Resolve function and promise urls
52561
52610
  let url = await resolveURL(config.url);
52562
- if (isString$3(url)) {
52611
+ if (isString$2(url)) {
52563
52612
  url = url.trim();
52564
52613
  }
52565
52614
 
@@ -53989,7 +54038,7 @@ async function createTrack(config, browser) {
53989
54038
 
53990
54039
  function embedCSS() {
53991
54040
 
53992
- var css = '.igv-navbar {\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: space-between;\n align-items: center;\n box-sizing: border-box;\n width: 100%;\n color: #444;\n font-size: 12px;\n font-family: \"Open Sans\", sans-serif;\n font-weight: 400;\n line-height: 32px;\n padding-left: 8px;\n padding-right: 8px;\n margin-top: 2px;\n margin-bottom: 6px;\n height: 32px;\n border-style: solid;\n border-radius: 3px;\n border-width: thin;\n border-color: #bfbfbf;\n background-color: #f3f3f3;\n}\n.igv-navbar .igv-navbar-left-container {\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: space-between;\n align-items: center;\n height: 32px;\n line-height: 32px;\n}\n.igv-navbar .igv-navbar-left-container .igv-logo {\n width: 34px;\n height: 32px;\n margin-right: 8px;\n}\n.igv-navbar .igv-navbar-left-container .igv-current-genome {\n height: 32px;\n margin-left: 4px;\n margin-right: 4px;\n user-select: none;\n line-height: 32px;\n vertical-align: middle;\n text-align: center;\n}\n.igv-navbar .igv-navbar-left-container .igv-navbar-genomic-location {\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: space-between;\n align-items: center;\n height: 100%;\n}\n.igv-navbar .igv-navbar-left-container .igv-navbar-genomic-location .igv-chromosome-select-widget-container {\n display: flex;\n flex-flow: column;\n flex-wrap: nowrap;\n justify-content: space-around;\n align-items: center;\n height: 100%;\n width: 125px;\n margin-right: 4px;\n}\n.igv-navbar .igv-navbar-left-container .igv-navbar-genomic-location .igv-chromosome-select-widget-container select {\n display: block;\n cursor: pointer;\n width: 100px;\n height: 75%;\n outline: none;\n font-size: 12px;\n font-family: \"Open Sans\", sans-serif;\n font-weight: 400;\n}\n.igv-navbar .igv-navbar-left-container .igv-navbar-genomic-location .igv-locus-size-group {\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: space-between;\n align-items: center;\n margin-left: 8px;\n height: 22px;\n}\n.igv-navbar .igv-navbar-left-container .igv-navbar-genomic-location .igv-locus-size-group .igv-search-container {\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: center;\n width: 210px;\n height: 22px;\n line-height: 22px;\n}\n.igv-navbar .igv-navbar-left-container .igv-navbar-genomic-location .igv-locus-size-group .igv-search-container input.igv-search-input {\n cursor: text;\n width: 85%;\n height: 22px;\n line-height: 22px;\n font-size: 12px;\n font-family: \"Open Sans\", sans-serif;\n font-weight: 400;\n text-align: left;\n padding-left: 8px;\n margin-right: 8px;\n outline: none;\n border-style: solid;\n border-radius: 3px;\n border-width: thin;\n border-color: #bfbfbf;\n background-color: white;\n}\n.igv-navbar .igv-navbar-left-container .igv-navbar-genomic-location .igv-locus-size-group .igv-search-container .igv-search-icon-container {\n cursor: pointer;\n height: 16px;\n width: 16px;\n}\n.igv-navbar .igv-navbar-left-container .igv-navbar-genomic-location .igv-locus-size-group .igv-windowsize-panel-container {\n margin-left: 4px;\n user-select: none;\n}\n.igv-navbar .igv-navbar-right-container {\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: space-between;\n align-items: center;\n height: 32px;\n line-height: 32px;\n}\n.igv-navbar .igv-navbar-right-container .igv-navbar-toggle-button-container {\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: space-between;\n align-items: center;\n height: 100%;\n}\n.igv-navbar .igv-navbar-right-container .igv-navbar-toggle-button-container div {\n margin-left: 0;\n margin-right: 4px;\n}\n.igv-navbar .igv-navbar-right-container .igv-navbar-toggle-button-container div:last-child {\n margin-left: 0;\n margin-right: 0;\n}\n.igv-navbar .igv-navbar-right-container .igv-navbar-toggle-button-container-750 {\n display: none;\n}\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget {\n color: #737373;\n font-size: 18px;\n height: 32px;\n line-height: 32px;\n margin-left: 8px;\n user-select: none;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: flex-end;\n align-items: center;\n}\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget div {\n cursor: pointer;\n margin-left: unset;\n margin-right: unset;\n}\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget div:first-child {\n height: 24px;\n width: 24px;\n margin-left: unset;\n margin-right: 8px;\n}\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget div:last-child {\n height: 24px;\n width: 24px;\n margin-left: 8px;\n margin-right: unset;\n}\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget div:nth-child(even) {\n display: block;\n height: fit-content;\n}\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget input {\n display: block;\n width: 125px;\n}\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget svg {\n display: block;\n}\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget-900 {\n color: #737373;\n font-size: 18px;\n height: 32px;\n line-height: 32px;\n margin-left: 8px;\n user-select: none;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: flex-end;\n align-items: center;\n}\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget-900 div {\n cursor: pointer;\n margin-left: unset;\n margin-right: unset;\n}\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget-900 div:first-child {\n height: 24px;\n width: 24px;\n margin-left: unset;\n margin-right: 8px;\n}\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget-900 div:last-child {\n height: 24px;\n width: 24px;\n margin-left: 8px;\n margin-right: unset;\n}\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget-900 div:nth-child(even) {\n width: 0;\n height: 0;\n display: none;\n}\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget-900 input {\n width: 0;\n height: 0;\n display: none;\n}\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget-900 svg {\n display: block;\n}\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget-hidden {\n display: none;\n}\n\n.igv-navbar-button {\n display: block;\n box-sizing: unset;\n padding-left: 6px;\n padding-right: 6px;\n height: 18px;\n text-transform: capitalize;\n user-select: none;\n line-height: 18px;\n text-align: center;\n vertical-align: middle;\n font-family: \"Open Sans\", sans-serif;\n font-size: 11px;\n font-weight: 200;\n color: #737373;\n background-color: #f3f3f3;\n border-color: #737373;\n border-style: solid;\n border-width: thin;\n border-radius: 6px;\n}\n\n.igv-navbar-button-clicked {\n color: white;\n background-color: #737373;\n}\n\n.igv-navbar-button:hover {\n cursor: pointer;\n}\n\n.igv-zoom-in-notice-container {\n z-index: 1024;\n position: absolute;\n top: 8px;\n left: 50%;\n transform: translate(-50%, 0%);\n display: flex;\n flex-direction: row;\n flex-wrap: nowrap;\n justify-content: center;\n align-items: center;\n background-color: white;\n}\n.igv-zoom-in-notice-container > div {\n padding-left: 4px;\n padding-right: 4px;\n padding-top: 2px;\n padding-bottom: 2px;\n width: 100%;\n height: 100%;\n font-family: \"Open Sans\", sans-serif;\n font-size: 14px;\n font-weight: 400;\n color: #3f3f3f;\n}\n\n.igv-zoom-in-notice {\n position: absolute;\n top: 10px;\n left: 50%;\n}\n.igv-zoom-in-notice div {\n position: relative;\n left: -50%;\n font-family: \"Open Sans\", sans-serif;\n font-size: medium;\n font-weight: 400;\n color: #3f3f3f;\n background-color: rgba(255, 255, 255, 0.51);\n z-index: 64;\n}\n\n.igv-container-spinner {\n position: absolute;\n top: 90%;\n left: 50%;\n transform: translate(-50%, -50%);\n z-index: 1024;\n width: 24px;\n height: 24px;\n pointer-events: none;\n color: #737373;\n}\n\n.igv-multi-locus-close-button {\n position: absolute;\n top: 2px;\n right: 0;\n padding-left: 2px;\n padding-right: 2px;\n width: 18px;\n height: 18px;\n color: #666666;\n background-color: white;\n z-index: 1000;\n}\n.igv-multi-locus-close-button > svg {\n vertical-align: top;\n}\n\n.igv-multi-locus-close-button:hover {\n cursor: pointer;\n color: #434343;\n}\n\n.igv-multi-locus-ruler-label {\n z-index: 64;\n position: absolute;\n top: 2px;\n left: 0;\n width: 100%;\n height: 14px;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: center;\n align-items: center;\n}\n.igv-multi-locus-ruler-label div {\n font-family: \"Open Sans\", sans-serif;\n font-size: 14px;\n font-weight: 400;\n color: rgb(16, 16, 16);\n background-color: white;\n}\n\n.igv-multi-locus-ruler-label-square-dot {\n z-index: 64;\n position: absolute;\n left: 50%;\n top: 5%;\n transform: translate(-50%, 0%);\n background-color: white;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: center;\n}\n.igv-multi-locus-ruler-label-square-dot > div:first-child {\n width: 14px;\n height: 14px;\n}\n.igv-multi-locus-ruler-label-square-dot > div:last-child {\n margin-left: 16px;\n font-family: \"Open Sans\", sans-serif;\n font-size: 14px;\n font-weight: 400;\n color: rgb(16, 16, 16);\n}\n\n.igv-multi-locus-ruler-label:hover {\n cursor: pointer;\n}\n\n.igv-ruler-sweeper {\n display: none;\n pointer-events: none;\n position: absolute;\n top: 26px;\n bottom: 0;\n left: 0;\n width: 0;\n z-index: 99999;\n background-color: rgba(68, 134, 247, 0.25);\n}\n\n.igv-ruler-tooltip {\n pointer-events: none;\n z-index: 128;\n position: absolute;\n top: 0;\n left: 0;\n width: 1px;\n height: 32px;\n background-color: transparent;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: center;\n}\n.igv-ruler-tooltip > div {\n pointer-events: none;\n width: 128px;\n height: auto;\n padding: 1px;\n color: #373737;\n font-size: 10px;\n font-family: \"Open Sans\", sans-serif;\n font-weight: 400;\n background-color: white;\n border-style: solid;\n border-width: thin;\n border-color: #373737;\n}\n\n.igv-track-label {\n position: absolute;\n left: 8px;\n top: 8px;\n width: auto;\n height: auto;\n max-width: 200px;\n padding-left: 4px;\n padding-right: 4px;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n font-family: \"Open Sans\", sans-serif;\n font-size: small;\n font-weight: 400;\n text-align: center;\n user-select: none;\n -moz-user-select: none;\n -webkit-user-select: none;\n border-color: #444;\n border-radius: 2px;\n border-style: solid;\n border-width: thin;\n background-color: white;\n z-index: 128;\n cursor: pointer;\n}\n\n.igv-track-label:hover,\n.igv-track-label:focus,\n.igv-track-label:active {\n background-color: #e8e8e8;\n}\n\n.igv-track-label-popup-shim {\n padding-left: 8px;\n padding-right: 8px;\n padding-top: 4px;\n}\n\n.igv-center-line {\n display: none;\n pointer-events: none;\n position: absolute;\n top: 0;\n bottom: 0;\n left: 50%;\n transform: translateX(-50%);\n z-index: 8;\n user-select: none;\n -moz-user-select: none;\n -webkit-user-select: none;\n border-left-style: dashed;\n border-left-width: thin;\n border-right-style: dashed;\n border-right-width: thin;\n}\n\n.igv-center-line-wide {\n background-color: rgba(0, 0, 0, 0);\n border-left-color: rgba(127, 127, 127, 0.51);\n border-right-color: rgba(127, 127, 127, 0.51);\n}\n\n.igv-center-line-thin {\n background-color: rgba(0, 0, 0, 0);\n border-left-color: rgba(127, 127, 127, 0.51);\n border-right-color: rgba(0, 0, 0, 0);\n}\n\n.igv-cursor-guide-horizontal {\n display: none;\n pointer-events: none;\n user-select: none;\n -moz-user-select: none;\n -webkit-user-select: none;\n position: absolute;\n left: 0;\n right: 0;\n top: 50%;\n height: 1px;\n z-index: 1;\n margin-left: 50px;\n margin-right: 54px;\n border-top-style: dotted;\n border-top-width: thin;\n border-top-color: rgba(127, 127, 127, 0.76);\n}\n\n.igv-cursor-guide-vertical {\n pointer-events: none;\n user-select: none;\n -moz-user-select: none;\n -webkit-user-select: none;\n position: absolute;\n top: 0;\n bottom: 0;\n left: 50%;\n width: 1px;\n z-index: 1;\n border-left-style: dotted;\n border-left-width: thin;\n border-left-color: rgba(127, 127, 127, 0.76);\n display: none;\n}\n\n.igv-user-feedback {\n position: fixed;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n width: 512px;\n height: 360px;\n z-index: 2048;\n background-color: white;\n border-color: #a2a2a2;\n border-style: solid;\n border-width: thin;\n font-family: \"Open Sans\", sans-serif;\n font-size: medium;\n font-weight: 400;\n color: #444;\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: center;\n}\n.igv-user-feedback div:first-child {\n position: relative;\n height: 24px;\n width: 100%;\n background-color: white;\n border-bottom-color: #a2a2a2;\n border-bottom-style: solid;\n border-bottom-width: thin;\n}\n.igv-user-feedback div:first-child div {\n position: absolute;\n top: 2px;\n width: 16px;\n height: 16px;\n background-color: transparent;\n}\n.igv-user-feedback div:first-child div:first-child {\n left: 8px;\n}\n.igv-user-feedback div:first-child div:last-child {\n cursor: pointer;\n right: 8px;\n}\n.igv-user-feedback div:last-child {\n width: 100%;\n height: calc(100% - 24px);\n border-width: 0;\n}\n.igv-user-feedback div:last-child div {\n width: auto;\n height: auto;\n margin: 8px;\n}\n\n.igv-generic-dialog-container {\n position: absolute;\n top: 0;\n left: 0;\n width: 300px;\n height: 200px;\n border-color: #7F7F7F;\n border-radius: 4px;\n border-style: solid;\n border-width: thin;\n font-family: \"Open Sans\", sans-serif;\n font-size: medium;\n font-weight: 400;\n z-index: 2048;\n background-color: white;\n display: flex;\n flex-flow: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: center;\n}\n.igv-generic-dialog-container .igv-generic-dialog-header {\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: flex-end;\n align-items: center;\n width: 100%;\n height: 24px;\n cursor: move;\n border-top-left-radius: 4px;\n border-top-right-radius: 4px;\n border-bottom-color: #7F7F7F;\n border-bottom-style: solid;\n border-bottom-width: thin;\n background-color: #eee;\n}\n.igv-generic-dialog-container .igv-generic-dialog-header div {\n margin-right: 4px;\n margin-bottom: 2px;\n height: 12px;\n width: 12px;\n color: #7F7F7F;\n}\n.igv-generic-dialog-container .igv-generic-dialog-header div:hover {\n cursor: pointer;\n color: #444;\n}\n.igv-generic-dialog-container .igv-generic-dialog-one-liner {\n color: #373737;\n width: 95%;\n height: 24px;\n line-height: 24px;\n text-align: left;\n margin-top: 8px;\n padding-left: 8px;\n overflow-wrap: break-word;\n background-color: white;\n}\n.igv-generic-dialog-container .igv-generic-dialog-label-input {\n margin-top: 8px;\n width: 95%;\n height: 24px;\n color: #373737;\n line-height: 24px;\n padding-left: 8px;\n background-color: white;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: center;\n}\n.igv-generic-dialog-container .igv-generic-dialog-label-input div {\n width: 30%;\n height: 100%;\n font-size: 16px;\n text-align: right;\n padding-right: 8px;\n background-color: white;\n}\n.igv-generic-dialog-container .igv-generic-dialog-label-input input {\n display: block;\n height: 100%;\n width: 100%;\n padding-left: 4px;\n font-family: \"Open Sans\", sans-serif;\n font-weight: 400;\n color: #373737;\n text-align: left;\n outline: none;\n border-style: solid;\n border-width: thin;\n border-color: #7F7F7F;\n background-color: white;\n}\n.igv-generic-dialog-container .igv-generic-dialog-label-input input {\n width: 50%;\n font-size: 16px;\n}\n.igv-generic-dialog-container .igv-generic-dialog-input {\n margin-top: 8px;\n width: calc(100% - 16px);\n height: 24px;\n color: #373737;\n line-height: 24px;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: space-around;\n align-items: center;\n}\n.igv-generic-dialog-container .igv-generic-dialog-input input {\n display: block;\n height: 100%;\n width: 100%;\n padding-left: 4px;\n font-family: \"Open Sans\", sans-serif;\n font-weight: 400;\n color: #373737;\n text-align: left;\n outline: none;\n border-style: solid;\n border-width: thin;\n border-color: #7F7F7F;\n background-color: white;\n}\n.igv-generic-dialog-container .igv-generic-dialog-input input {\n font-size: 16px;\n}\n.igv-generic-dialog-container .igv-generic-dialog-ok-cancel {\n width: 100%;\n height: 28px;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: space-around;\n align-items: center;\n}\n.igv-generic-dialog-container .igv-generic-dialog-ok-cancel div {\n margin-top: 32px;\n color: white;\n font-family: \"Open Sans\", sans-serif;\n font-size: 14px;\n font-weight: 400;\n width: 75px;\n height: 28px;\n line-height: 28px;\n text-align: center;\n border-color: transparent;\n border-style: solid;\n border-width: thin;\n border-radius: 2px;\n}\n.igv-generic-dialog-container .igv-generic-dialog-ok-cancel div:first-child {\n margin-left: 32px;\n margin-right: 0;\n background-color: #5ea4e0;\n}\n.igv-generic-dialog-container .igv-generic-dialog-ok-cancel div:last-child {\n margin-left: 0;\n margin-right: 32px;\n background-color: #c4c4c4;\n}\n.igv-generic-dialog-container .igv-generic-dialog-ok-cancel div:first-child:hover {\n cursor: pointer;\n background-color: #3b5c7f;\n}\n.igv-generic-dialog-container .igv-generic-dialog-ok-cancel div:last-child:hover {\n cursor: pointer;\n background-color: #7f7f7f;\n}\n.igv-generic-dialog-container .igv-generic-dialog-ok {\n width: 100%;\n height: 36px;\n margin-top: 32px;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: space-around;\n align-items: center;\n}\n.igv-generic-dialog-container .igv-generic-dialog-ok div {\n width: 98px;\n height: 36px;\n line-height: 36px;\n text-align: center;\n color: white;\n font-family: \"Open Sans\", sans-serif;\n font-size: medium;\n font-weight: 400;\n border-color: white;\n border-style: solid;\n border-width: thin;\n border-radius: 4px;\n background-color: #2B81AF;\n}\n.igv-generic-dialog-container .igv-generic-dialog-ok div:hover {\n cursor: pointer;\n background-color: #25597f;\n}\n\n.igv-generic-container {\n position: absolute;\n top: 0;\n left: 0;\n z-index: 2048;\n background-color: white;\n cursor: pointer;\n display: flex;\n flex-direction: row;\n flex-wrap: wrap;\n justify-content: flex-start;\n align-items: center;\n}\n.igv-generic-container div:first-child {\n cursor: move;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: flex-end;\n align-items: center;\n height: 24px;\n width: 100%;\n background-color: #dddddd;\n}\n.igv-generic-container div:first-child i {\n display: block;\n color: #5f5f5f;\n cursor: pointer;\n width: 14px;\n height: 14px;\n margin-right: 8px;\n margin-bottom: 4px;\n}\n\n.igv-menu-popup {\n position: absolute;\n top: 0;\n left: 0;\n width: max-content;\n z-index: 4096;\n cursor: pointer;\n font-family: \"Open Sans\", sans-serif;\n font-size: small;\n font-weight: 400;\n color: #4b4b4b;\n background: white;\n border-radius: 4px;\n border-color: #7F7F7F;\n border-style: solid;\n border-width: thin;\n display: flex;\n flex-flow: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: flex-end;\n text-align: left;\n}\n.igv-menu-popup > div:not(:first-child) {\n width: 100%;\n}\n.igv-menu-popup > div:not(:first-child) > div {\n background: white;\n}\n.igv-menu-popup > div:not(:first-child) > div.context-menu {\n padding-left: 4px;\n padding-right: 4px;\n}\n.igv-menu-popup > div:not(:first-child) > div:last-child {\n border-bottom-left-radius: 4px;\n border-bottom-right-radius: 4px;\n border-bottom-color: transparent;\n border-bottom-style: solid;\n border-bottom-width: thin;\n}\n.igv-menu-popup > div:not(:first-child) > div:hover {\n background: #efefef;\n}\n\n.igv-menu-popup-shim {\n padding-left: 8px;\n padding-right: 8px;\n padding-bottom: 1px;\n padding-top: 1px;\n}\n\n.igv-menu-popup-header {\n position: relative;\n width: 100%;\n height: 24px;\n cursor: move;\n border-top-color: transparent;\n border-top-left-radius: 4px;\n border-top-right-radius: 4px;\n border-bottom-color: #7F7F7F;\n border-bottom-style: solid;\n border-bottom-width: thin;\n background-color: #eee;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: flex-end;\n align-items: center;\n}\n.igv-menu-popup-header div {\n margin-right: 4px;\n height: 12px;\n width: 12px;\n color: #7F7F7F;\n}\n.igv-menu-popup-header div:hover {\n cursor: pointer;\n color: #444;\n}\n\n.igv-menu-popup-check-container {\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: center;\n width: 100%;\n height: 20px;\n margin-right: 4px;\n background-color: transparent;\n}\n.igv-menu-popup-check-container div {\n padding-top: 2px;\n padding-left: 8px;\n}\n.igv-menu-popup-check-container div:first-child {\n position: relative;\n width: 12px;\n height: 12px;\n}\n.igv-menu-popup-check-container div:first-child svg {\n position: absolute;\n width: 12px;\n height: 12px;\n}\n\n.igv-user-feedback {\n position: fixed;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n width: 512px;\n height: 360px;\n z-index: 2048;\n background-color: white;\n border-color: #a2a2a2;\n border-style: solid;\n border-width: thin;\n font-family: \"Open Sans\", sans-serif;\n font-size: medium;\n font-weight: 400;\n color: #444;\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: center;\n}\n.igv-user-feedback div:first-child {\n position: relative;\n height: 24px;\n width: 100%;\n background-color: white;\n border-bottom-color: #a2a2a2;\n border-bottom-style: solid;\n border-bottom-width: thin;\n}\n.igv-user-feedback div:first-child div {\n position: absolute;\n top: 2px;\n width: 16px;\n height: 16px;\n background-color: transparent;\n}\n.igv-user-feedback div:first-child div:first-child {\n left: 8px;\n}\n.igv-user-feedback div:first-child div:last-child {\n cursor: pointer;\n right: 8px;\n}\n.igv-user-feedback div:last-child {\n width: 100%;\n height: calc(100% - 24px);\n border-width: 0;\n}\n.igv-user-feedback div:last-child div {\n width: auto;\n height: auto;\n margin: 8px;\n}\n\n.igv-loading-spinner-container {\n z-index: 1024;\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n width: 32px;\n height: 32px;\n display: flex;\n flex-direction: row;\n flex-wrap: nowrap;\n justify-content: center;\n align-items: center;\n}\n.igv-loading-spinner-container > div {\n box-sizing: border-box;\n width: 100%;\n height: 100%;\n border-radius: 50%;\n border: 4px solid rgba(128, 128, 128, 0.5);\n border-top-color: rgb(255, 255, 255);\n animation: spin 1s ease-in-out infinite;\n -webkit-animation: spin 1s ease-in-out infinite;\n}\n\n@keyframes spin {\n to {\n -webkit-transform: rotate(360deg);\n transform: rotate(360deg);\n }\n}\n@-webkit-keyframes spin {\n to {\n -webkit-transform: rotate(360deg);\n\n transform: rotate(360deg); } }\n.igv-roi-menu-next-gen {\n position: absolute;\n z-index: 512;\n font-family: \"Open Sans\", sans-serif;\n font-size: small;\n font-weight: 400;\n color: #4b4b4b;\n background-color: white;\n width: 192px;\n border-radius: 4px;\n border-color: #7F7F7F;\n border-style: solid;\n border-width: thin;\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: stretch; }\n .igv-roi-menu-next-gen > div:first-child {\n height: 24px;\n border-top-color: transparent;\n border-top-left-radius: 4px;\n border-top-right-radius: 4px;\n border-bottom-color: #7F7F7F;\n border-bottom-style: solid;\n border-bottom-width: thin;\n background-color: #eee;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: flex-end;\n align-items: center; }\n .igv-roi-menu-next-gen > div:first-child > div {\n margin-right: 4px;\n height: 12px;\n width: 12px;\n color: #7F7F7F; }\n .igv-roi-menu-next-gen > div:first-child > div:hover {\n cursor: pointer;\n color: #444; }\n .igv-roi-menu-next-gen > div:last-child {\n background-color: white;\n border-bottom-left-radius: 4px;\n border-bottom-right-radius: 4px;\n border-bottom-color: transparent;\n border-bottom-style: solid;\n border-bottom-width: 0;\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: stretch;\n text-align: start;\n vertical-align: middle;\n cursor: pointer; }\n .igv-roi-menu-next-gen > div:last-child > div {\n height: 24px;\n padding-left: 4px;\n border-bottom-style: solid;\n border-bottom-width: thin;\n border-bottom-color: #7f7f7f; }\n .igv-roi-menu-next-gen > div:last-child > div:not(:first-child):hover {\n background-color: rgba(127, 127, 127, 0.1); }\n .igv-roi-menu-next-gen > div:last-child div:first-child {\n cursor: default;\n font-style: italic;\n text-align: center;\n padding-right: 4px;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis; }\n .igv-roi-menu-next-gen > div:last-child > div:last-child {\n border-bottom-width: 0;\n border-bottom-color: transparent; }\n\n.igv-roi-placeholder {\n font-style: normal;\n color: rgba(75, 75, 75, 0.6); }\n\n\n.igv-roi-table {\n position: absolute;\n z-index: 1024;\n width: fit-content;\n border-color: #7f7f7f;\n border-radius: 4px;\n border-style: solid;\n border-width: thin;\n font-family: \"Open Sans\", sans-serif;\n font-size: 12px;\n font-weight: 400;\n background-color: white;\n display: flex;\n flex-flow: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: stretch;\n}\n.igv-roi-table > div {\n height: 24px;\n font-size: 14px;\n text-align: start;\n vertical-align: middle;\n line-height: 24px;\n}\n.igv-roi-table > div:first-child {\n border-color: transparent;\n border-top-left-radius: 4px;\n border-top-right-radius: 4px;\n border-top-width: 0;\n border-bottom-color: #7f7f7f;\n border-bottom-style: solid;\n border-bottom-width: thin;\n background-color: #eee;\n cursor: move;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: space-between;\n align-items: center;\n}\n.igv-roi-table > div:first-child > div:first-child {\n text-align: center;\n width: calc(100% - 4px - 12px);\n}\n.igv-roi-table > div:first-child > div:last-child {\n margin-right: 4px;\n margin-bottom: 2px;\n height: 12px;\n width: 12px;\n color: #7f7f7f;\n}\n.igv-roi-table > div:first-child > div:last-child > svg {\n display: block;\n}\n.igv-roi-table > div:first-child > div:last-child:hover {\n cursor: pointer;\n color: #444;\n}\n.igv-roi-table > .igv-roi-table-column-titles {\n height: 24px;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: stretch;\n align-items: stretch;\n padding-right: 16px;\n background-color: white;\n border-bottom-color: #7f7f7f;\n border-bottom-style: solid;\n border-bottom-width: thin;\n}\n.igv-roi-table > .igv-roi-table-column-titles > div {\n font-size: 14px;\n vertical-align: middle;\n line-height: 24px;\n text-align: center;\n margin-left: 4px;\n margin-right: 4px;\n height: 24px;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n.igv-roi-table > .igv-roi-table-column-titles > div:nth-child(1) {\n width: 20%;\n}\n.igv-roi-table > .igv-roi-table-column-titles > div:nth-child(2) {\n width: 15%;\n}\n.igv-roi-table > .igv-roi-table-column-titles > div:nth-child(3) {\n width: 15%;\n}\n.igv-roi-table > .igv-roi-table-column-titles > div:nth-child(4) {\n width: 30%;\n}\n.igv-roi-table > .igv-roi-table-column-titles > div:nth-child(5) {\n width: 20%;\n}\n.igv-roi-table > .igv-roi-table-row-container {\n resize: both;\n overflow: scroll;\n min-width: 512px;\n min-height: 72px;\n height: 144px;\n max-height: 480px;\n background-color: white;\n display: flex;\n flex-flow: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: stretch;\n}\n.igv-roi-table > .igv-roi-table-row-container > .igv-roi-table-row {\n height: 24px;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: stretch;\n align-items: stretch;\n}\n.igv-roi-table > .igv-roi-table-row-container > .igv-roi-table-row > div {\n font-size: 14px;\n vertical-align: middle;\n line-height: 24px;\n text-align: center;\n margin-left: 4px;\n margin-right: 4px;\n height: 24px;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n.igv-roi-table > .igv-roi-table-row-container > .igv-roi-table-row > div:nth-child(1) {\n width: 20%;\n}\n.igv-roi-table > .igv-roi-table-row-container > .igv-roi-table-row > div:nth-child(2) {\n width: 15%;\n}\n.igv-roi-table > .igv-roi-table-row-container > .igv-roi-table-row > div:nth-child(3) {\n width: 15%;\n}\n.igv-roi-table > .igv-roi-table-row-container > .igv-roi-table-row > div:nth-child(4) {\n width: 30%;\n}\n.igv-roi-table > .igv-roi-table-row-container > .igv-roi-table-row > div:nth-child(5) {\n width: 20%;\n}\n.igv-roi-table > .igv-roi-table-row-container > .igv-roi-table-row-hover {\n background-color: rgba(0, 0, 0, 0.04);\n}\n.igv-roi-table > div:last-child {\n height: 32px;\n line-height: 32px;\n border-top-color: #7f7f7f;\n border-top-style: solid;\n border-top-width: thin;\n border-bottom-color: transparent;\n border-bottom-left-radius: 4px;\n border-bottom-right-radius: 4px;\n border-bottom-width: 0;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: space-around;\n align-items: center;\n}\n\n.igv-roi-table-four-column {\n position: absolute;\n z-index: 1024;\n width: fit-content;\n border-color: #7f7f7f;\n border-radius: 4px;\n border-style: solid;\n border-width: thin;\n font-family: \"Open Sans\", sans-serif;\n font-size: 12px;\n font-weight: 400;\n background-color: white;\n display: flex;\n flex-flow: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: stretch;\n}\n.igv-roi-table-four-column > div {\n height: 24px;\n font-size: 14px;\n text-align: start;\n vertical-align: middle;\n line-height: 24px;\n}\n.igv-roi-table-four-column > div:first-child {\n border-color: transparent;\n border-top-left-radius: 4px;\n border-top-right-radius: 4px;\n border-top-width: 0;\n border-bottom-color: #7f7f7f;\n border-bottom-style: solid;\n border-bottom-width: thin;\n background-color: #eee;\n cursor: move;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: space-between;\n align-items: center;\n}\n.igv-roi-table-four-column > div:first-child > div:first-child {\n text-align: center;\n width: calc(100% - 4px - 12px);\n}\n.igv-roi-table-four-column > div:first-child > div:last-child {\n margin-right: 4px;\n margin-bottom: 2px;\n height: 12px;\n width: 12px;\n color: #7f7f7f;\n}\n.igv-roi-table-four-column > div:first-child > div:last-child > svg {\n display: block;\n}\n.igv-roi-table-four-column > div:first-child > div:last-child:hover {\n cursor: pointer;\n color: #444;\n}\n.igv-roi-table-four-column > .igv-roi-table-column-titles {\n height: 24px;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: stretch;\n align-items: stretch;\n padding-right: 16px;\n background-color: white;\n border-bottom-color: #7f7f7f;\n border-bottom-style: solid;\n border-bottom-width: thin;\n}\n.igv-roi-table-four-column > .igv-roi-table-column-titles > div {\n font-size: 14px;\n vertical-align: middle;\n line-height: 24px;\n text-align: center;\n margin-left: 4px;\n margin-right: 4px;\n height: 24px;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n.igv-roi-table-four-column > .igv-roi-table-column-titles > div:nth-child(1) {\n width: 25%;\n}\n.igv-roi-table-four-column > .igv-roi-table-column-titles > div:nth-child(2) {\n width: 20%;\n}\n.igv-roi-table-four-column > .igv-roi-table-column-titles > div:nth-child(3) {\n width: 20%;\n}\n.igv-roi-table-four-column > .igv-roi-table-column-titles > div:nth-child(4) {\n width: 35%;\n}\n.igv-roi-table-four-column > .igv-roi-table-row-container {\n resize: both;\n overflow: scroll;\n min-width: 512px;\n min-height: 72px;\n height: 144px;\n max-height: 480px;\n background-color: white;\n display: flex;\n flex-flow: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: stretch;\n}\n.igv-roi-table-four-column > .igv-roi-table-row-container > .igv-roi-table-row {\n height: 24px;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: stretch;\n align-items: stretch;\n}\n.igv-roi-table-four-column > .igv-roi-table-row-container > .igv-roi-table-row > div {\n font-size: 14px;\n vertical-align: middle;\n line-height: 24px;\n text-align: center;\n margin-left: 4px;\n margin-right: 4px;\n height: 24px;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n.igv-roi-table-four-column > .igv-roi-table-row-container > .igv-roi-table-row > div:nth-child(1) {\n width: 25%;\n}\n.igv-roi-table-four-column > .igv-roi-table-row-container > .igv-roi-table-row > div:nth-child(2) {\n width: 20%;\n}\n.igv-roi-table-four-column > .igv-roi-table-row-container > .igv-roi-table-row > div:nth-child(3) {\n width: 20%;\n}\n.igv-roi-table-four-column > .igv-roi-table-row-container > .igv-roi-table-row > div:nth-child(4) {\n width: 35%;\n}\n.igv-roi-table-four-column > .igv-roi-table-row-container > .igv-roi-table-row-hover {\n background-color: rgba(0, 0, 0, 0.04);\n}\n.igv-roi-table-four-column > div:last-child {\n height: 32px;\n line-height: 32px;\n border-top-color: #7f7f7f;\n border-top-style: solid;\n border-top-width: thin;\n border-bottom-color: transparent;\n border-bottom-left-radius: 4px;\n border-bottom-right-radius: 4px;\n border-bottom-width: 0;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: space-around;\n align-items: center;\n}\n\n.igv-roi-table-row-selected {\n background-color: rgba(0, 0, 0, 0.125);\n}\n\n.igv-roi-table-button {\n height: 20px;\n user-select: none;\n line-height: 20px;\n text-align: center;\n vertical-align: middle;\n font-family: \"Open Sans\", sans-serif;\n font-size: 13px;\n font-weight: 400;\n color: black;\n padding-left: 6px;\n padding-right: 6px;\n background-color: rgb(239, 239, 239);\n border-color: black;\n border-style: solid;\n border-width: thin;\n border-radius: 3px;\n}\n\n.igv-roi-table-button:hover {\n cursor: pointer;\n font-weight: 400;\n background-color: rgba(0, 0, 0, 0.13);\n}\n\n.igv-roi-region {\n z-index: 64;\n position: absolute;\n top: 0;\n bottom: 0;\n pointer-events: none;\n overflow: visible;\n margin-top: 44px;\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: stretch;\n}\n.igv-roi-region > div {\n position: relative;\n width: 100%;\n height: 8px;\n cursor: pointer;\n pointer-events: auto;\n}\n\n.igv-roi-menu {\n position: absolute;\n z-index: 1024;\n width: 144px;\n border-color: #7f7f7f;\n border-radius: 4px;\n border-style: solid;\n border-width: thin;\n font-family: \"Open Sans\", sans-serif;\n background-color: white;\n display: flex;\n flex-flow: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: stretch;\n}\n.igv-roi-menu > div:not(:last-child) {\n border-bottom-color: rgba(128, 128, 128, 0.5);\n border-bottom-style: solid;\n border-bottom-width: thin;\n}\n.igv-roi-menu > div:first-child {\n border-top-left-radius: 4px;\n border-top-right-radius: 4px;\n border-top-color: transparent;\n border-top-style: solid;\n border-top-width: 0;\n}\n.igv-roi-menu > div:last-child {\n border-bottom-left-radius: 4px;\n border-bottom-right-radius: 4px;\n border-bottom-color: transparent;\n border-bottom-style: solid;\n border-bottom-width: 0;\n}\n\n.igv-roi-menu-row {\n height: 24px;\n padding-left: 8px;\n font-size: small;\n text-align: start;\n vertical-align: middle;\n line-height: 24px;\n background-color: white;\n}\n\n.igv-roi-menu-row-edit-description {\n width: -webkit-fill-available;\n font-size: small;\n text-align: start;\n vertical-align: middle;\n background-color: white;\n padding-left: 4px;\n padding-right: 4px;\n padding-bottom: 4px;\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n justify-content: stretch;\n align-items: stretch;\n}\n.igv-roi-menu-row-edit-description > label {\n margin-left: 2px;\n margin-bottom: 0;\n display: block;\n width: -webkit-fill-available;\n}\n.igv-roi-menu-row-edit-description > input {\n display: block;\n margin-left: 2px;\n margin-right: 2px;\n margin-bottom: 1px;\n width: -webkit-fill-available;\n}\n\n.igv-container {\n position: relative;\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: flex-start;\n padding-top: 4px;\n user-select: none;\n -webkit-user-select: none;\n -ms-user-select: none;\n}\n\n.igv-viewport {\n position: relative;\n margin-top: 5px;\n overflow-x: hidden;\n overflow-y: hidden;\n}\n\n.igv-viewport-content {\n position: relative;\n width: 100%;\n}\n.igv-viewport-content > canvas {\n position: relative;\n display: block;\n}\n\n.igv-column-container {\n position: relative;\n display: flex;\n flex-direction: row;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: stretch;\n width: 100%;\n}\n\n.igv-column-shim {\n width: 1px;\n margin-left: 2px;\n margin-right: 2px;\n background-color: #545453;\n}\n\n.igv-column {\n position: relative;\n position: relative;\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: flex-start;\n box-sizing: border-box;\n height: 100%;\n}\n\n.igv-axis-column {\n position: relative;\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: flex-start;\n box-sizing: border-box;\n height: 100%;\n width: 50px;\n}\n.igv-axis-column > div {\n margin-top: 5px;\n width: 100%;\n}\n\n.igv-sample-name-column {\n position: relative;\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: flex-start;\n box-sizing: border-box;\n height: 100%;\n}\n\n.igv-scrollbar-column {\n position: relative;\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: flex-start;\n box-sizing: border-box;\n height: 100%;\n width: 14px;\n}\n.igv-scrollbar-column > div {\n position: relative;\n margin-top: 5px;\n width: 14px;\n}\n.igv-scrollbar-column > div > div {\n cursor: pointer;\n position: absolute;\n top: 0;\n left: 2px;\n width: 8px;\n border-width: 1px;\n border-style: solid;\n border-color: #c4c4c4;\n border-top-left-radius: 4px;\n border-top-right-radius: 4px;\n border-bottom-left-radius: 4px;\n border-bottom-right-radius: 4px;\n}\n.igv-scrollbar-column > div > div:hover {\n background-color: #c4c4c4;\n}\n\n.igv-track-drag-column {\n position: relative;\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: flex-start;\n box-sizing: border-box;\n height: 100%;\n width: 12px;\n background-color: white;\n}\n.igv-track-drag-column > .igv-track-drag-handle {\n z-index: 512;\n position: relative;\n cursor: pointer;\n margin-top: 5px;\n width: 100%;\n border-style: solid;\n border-width: 0;\n border-top-right-radius: 6px;\n border-bottom-right-radius: 6px;\n background-color: #c4c4c4;\n}\n.igv-track-drag-column .igv-track-drag-handle-hover {\n background-color: #787878;\n}\n.igv-track-drag-column > .igv-track-drag-shim {\n position: relative;\n margin-top: 5px;\n width: 100%;\n border-style: solid;\n border-width: 0;\n}\n\n.igv-gear-menu-column {\n position: relative;\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: flex-start;\n box-sizing: border-box;\n height: 100%;\n width: 28px;\n}\n.igv-gear-menu-column > div {\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: center;\n margin-top: 5px;\n width: 100%;\n background: white;\n}\n.igv-gear-menu-column > div > div {\n position: relative;\n margin-top: 4px;\n width: 16px;\n height: 16px;\n color: #7F7F7F;\n}\n.igv-gear-menu-column > div > div:hover {\n cursor: pointer;\n color: #444;\n}\n\n/*# sourceMappingURL=dom.css.map */\n';
54041
+ var css = '.igv-navbar {\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: space-between;\n align-items: center;\n box-sizing: border-box;\n width: 100%;\n color: #444;\n font-size: 12px;\n font-family: \"Open Sans\", sans-serif;\n font-weight: 400;\n line-height: 32px;\n padding-left: 8px;\n padding-right: 8px;\n margin-top: 2px;\n margin-bottom: 6px;\n height: 32px;\n border-style: solid;\n border-radius: 3px;\n border-width: thin;\n border-color: #bfbfbf;\n background-color: #f3f3f3;\n}\n.igv-navbar .igv-navbar-left-container {\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: space-between;\n align-items: center;\n height: 32px;\n line-height: 32px;\n}\n.igv-navbar .igv-navbar-left-container .igv-logo {\n width: 34px;\n height: 32px;\n margin-right: 8px;\n}\n.igv-navbar .igv-navbar-left-container .igv-current-genome {\n height: 32px;\n margin-left: 4px;\n margin-right: 4px;\n user-select: none;\n line-height: 32px;\n vertical-align: middle;\n text-align: center;\n}\n.igv-navbar .igv-navbar-left-container .igv-navbar-genomic-location {\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: space-between;\n align-items: center;\n height: 100%;\n}\n.igv-navbar .igv-navbar-left-container .igv-navbar-genomic-location .igv-chromosome-select-widget-container {\n display: flex;\n flex-flow: column;\n flex-wrap: nowrap;\n justify-content: space-around;\n align-items: center;\n height: 100%;\n width: 125px;\n margin-right: 4px;\n}\n.igv-navbar .igv-navbar-left-container .igv-navbar-genomic-location .igv-chromosome-select-widget-container select {\n display: block;\n cursor: pointer;\n width: 100px;\n height: 75%;\n outline: none;\n font-size: 12px;\n font-family: \"Open Sans\", sans-serif;\n font-weight: 400;\n}\n.igv-navbar .igv-navbar-left-container .igv-navbar-genomic-location .igv-locus-size-group {\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: space-between;\n align-items: center;\n margin-left: 8px;\n height: 22px;\n}\n.igv-navbar .igv-navbar-left-container .igv-navbar-genomic-location .igv-locus-size-group .igv-search-container {\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: center;\n width: 210px;\n height: 22px;\n line-height: 22px;\n}\n.igv-navbar .igv-navbar-left-container .igv-navbar-genomic-location .igv-locus-size-group .igv-search-container input.igv-search-input {\n cursor: text;\n width: 85%;\n height: 22px;\n line-height: 22px;\n font-size: 12px;\n font-family: \"Open Sans\", sans-serif;\n font-weight: 400;\n text-align: left;\n padding-left: 8px;\n margin-right: 8px;\n outline: none;\n border-style: solid;\n border-radius: 3px;\n border-width: thin;\n border-color: #bfbfbf;\n background-color: white;\n}\n.igv-navbar .igv-navbar-left-container .igv-navbar-genomic-location .igv-locus-size-group .igv-search-container .igv-search-icon-container {\n cursor: pointer;\n height: 16px;\n width: 16px;\n}\n.igv-navbar .igv-navbar-left-container .igv-navbar-genomic-location .igv-locus-size-group .igv-windowsize-panel-container {\n margin-left: 4px;\n user-select: none;\n}\n.igv-navbar .igv-navbar-right-container {\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: space-between;\n align-items: center;\n height: 32px;\n line-height: 32px;\n}\n.igv-navbar .igv-navbar-right-container .igv-navbar-toggle-button-container {\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: space-between;\n align-items: center;\n height: 100%;\n}\n.igv-navbar .igv-navbar-right-container .igv-navbar-toggle-button-container div {\n margin-left: 0;\n margin-right: 4px;\n}\n.igv-navbar .igv-navbar-right-container .igv-navbar-toggle-button-container div:last-child {\n margin-left: 0;\n margin-right: 0;\n}\n.igv-navbar .igv-navbar-right-container .igv-navbar-toggle-button-container-750 {\n display: none;\n}\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget {\n color: #737373;\n font-size: 18px;\n height: 32px;\n line-height: 32px;\n margin-left: 8px;\n user-select: none;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: flex-end;\n align-items: center;\n}\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget div {\n cursor: pointer;\n margin-left: unset;\n margin-right: unset;\n}\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget div:first-child {\n height: 24px;\n width: 24px;\n margin-left: unset;\n margin-right: 8px;\n}\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget div:last-child {\n height: 24px;\n width: 24px;\n margin-left: 8px;\n margin-right: unset;\n}\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget div:nth-child(even) {\n display: block;\n height: fit-content;\n}\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget input {\n display: block;\n width: 125px;\n}\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget svg {\n display: block;\n}\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget-900 {\n color: #737373;\n font-size: 18px;\n height: 32px;\n line-height: 32px;\n margin-left: 8px;\n user-select: none;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: flex-end;\n align-items: center;\n}\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget-900 div {\n cursor: pointer;\n margin-left: unset;\n margin-right: unset;\n}\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget-900 div:first-child {\n height: 24px;\n width: 24px;\n margin-left: unset;\n margin-right: 8px;\n}\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget-900 div:last-child {\n height: 24px;\n width: 24px;\n margin-left: 8px;\n margin-right: unset;\n}\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget-900 div:nth-child(even) {\n width: 0;\n height: 0;\n display: none;\n}\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget-900 input {\n width: 0;\n height: 0;\n display: none;\n}\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget-900 svg {\n display: block;\n}\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget-hidden {\n display: none;\n}\n\n.igv-navbar-button {\n display: block;\n box-sizing: unset;\n padding-left: 6px;\n padding-right: 6px;\n height: 18px;\n text-transform: capitalize;\n user-select: none;\n line-height: 18px;\n text-align: center;\n vertical-align: middle;\n font-family: \"Open Sans\", sans-serif;\n font-size: 11px;\n font-weight: 200;\n color: #737373;\n background-color: #f3f3f3;\n border-color: #737373;\n border-style: solid;\n border-width: thin;\n border-radius: 6px;\n}\n\n.igv-navbar-button-clicked {\n color: white;\n background-color: #737373;\n}\n\n.igv-navbar-button:hover {\n cursor: pointer;\n}\n\n.igv-zoom-in-notice-container {\n z-index: 1024;\n position: absolute;\n top: 8px;\n left: 50%;\n transform: translate(-50%, 0%);\n display: flex;\n flex-direction: row;\n flex-wrap: nowrap;\n justify-content: center;\n align-items: center;\n background-color: white;\n}\n.igv-zoom-in-notice-container > div {\n padding-left: 4px;\n padding-right: 4px;\n padding-top: 2px;\n padding-bottom: 2px;\n width: 100%;\n height: 100%;\n font-family: \"Open Sans\", sans-serif;\n font-size: 14px;\n font-weight: 400;\n color: #3f3f3f;\n}\n\n.igv-zoom-in-notice {\n position: absolute;\n top: 10px;\n left: 50%;\n}\n.igv-zoom-in-notice div {\n position: relative;\n left: -50%;\n font-family: \"Open Sans\", sans-serif;\n font-size: medium;\n font-weight: 400;\n color: #3f3f3f;\n background-color: rgba(255, 255, 255, 0.51);\n z-index: 64;\n}\n\n.igv-container-spinner {\n position: absolute;\n top: 90%;\n left: 50%;\n transform: translate(-50%, -50%);\n z-index: 1024;\n width: 24px;\n height: 24px;\n pointer-events: none;\n color: #737373;\n}\n\n.igv-multi-locus-close-button {\n position: absolute;\n top: 2px;\n right: 0;\n padding-left: 2px;\n padding-right: 2px;\n width: 18px;\n height: 18px;\n color: #666666;\n background-color: white;\n z-index: 1000;\n}\n.igv-multi-locus-close-button > svg {\n vertical-align: top;\n}\n\n.igv-multi-locus-close-button:hover {\n cursor: pointer;\n color: #434343;\n}\n\n.igv-multi-locus-ruler-label {\n z-index: 64;\n position: absolute;\n top: 2px;\n left: 0;\n width: 100%;\n height: 14px;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: center;\n align-items: center;\n}\n.igv-multi-locus-ruler-label div {\n font-family: \"Open Sans\", sans-serif;\n font-size: 14px;\n font-weight: 400;\n color: rgb(16, 16, 16);\n background-color: white;\n}\n\n.igv-multi-locus-ruler-label-square-dot {\n z-index: 64;\n position: absolute;\n left: 50%;\n top: 5%;\n transform: translate(-50%, 0%);\n background-color: white;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: center;\n}\n.igv-multi-locus-ruler-label-square-dot > div:first-child {\n width: 14px;\n height: 14px;\n}\n.igv-multi-locus-ruler-label-square-dot > div:last-child {\n margin-left: 16px;\n font-family: \"Open Sans\", sans-serif;\n font-size: 14px;\n font-weight: 400;\n color: rgb(16, 16, 16);\n}\n\n.igv-multi-locus-ruler-label:hover {\n cursor: pointer;\n}\n\n.igv-ruler-sweeper {\n display: none;\n pointer-events: none;\n position: absolute;\n top: 26px;\n bottom: 0;\n left: 0;\n width: 0;\n z-index: 99999;\n background-color: rgba(68, 134, 247, 0.25);\n}\n\n.igv-ruler-tooltip {\n pointer-events: none;\n z-index: 128;\n position: absolute;\n top: 0;\n left: 0;\n width: 1px;\n height: 32px;\n background-color: transparent;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: center;\n}\n.igv-ruler-tooltip > div {\n pointer-events: none;\n width: 128px;\n height: auto;\n padding: 1px;\n color: #373737;\n font-size: 10px;\n font-family: \"Open Sans\", sans-serif;\n font-weight: 400;\n background-color: white;\n border-style: solid;\n border-width: thin;\n border-color: #373737;\n}\n\n.igv-track-label {\n position: absolute;\n left: 8px;\n top: 8px;\n width: auto;\n height: auto;\n max-width: 200px;\n padding-left: 4px;\n padding-right: 4px;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n font-family: \"Open Sans\", sans-serif;\n font-size: small;\n font-weight: 400;\n text-align: center;\n user-select: none;\n -moz-user-select: none;\n -webkit-user-select: none;\n border-color: #444;\n border-radius: 2px;\n border-style: solid;\n border-width: thin;\n background-color: white;\n z-index: 128;\n cursor: pointer;\n}\n\n.igv-track-label:hover,\n.igv-track-label:focus,\n.igv-track-label:active {\n background-color: #e8e8e8;\n}\n\n.igv-track-label-popup-shim {\n padding-left: 8px;\n padding-right: 8px;\n padding-top: 4px;\n}\n\n.igv-center-line {\n display: none;\n pointer-events: none;\n position: absolute;\n top: 0;\n bottom: 0;\n left: 50%;\n transform: translateX(-50%);\n z-index: 8;\n user-select: none;\n -moz-user-select: none;\n -webkit-user-select: none;\n border-left-style: dashed;\n border-left-width: thin;\n border-right-style: dashed;\n border-right-width: thin;\n}\n\n.igv-center-line-wide {\n background-color: rgba(0, 0, 0, 0);\n border-left-color: rgba(127, 127, 127, 0.51);\n border-right-color: rgba(127, 127, 127, 0.51);\n}\n\n.igv-center-line-thin {\n background-color: rgba(0, 0, 0, 0);\n border-left-color: rgba(127, 127, 127, 0.51);\n border-right-color: rgba(0, 0, 0, 0);\n}\n\n.igv-cursor-guide-horizontal {\n display: none;\n pointer-events: none;\n user-select: none;\n -moz-user-select: none;\n -webkit-user-select: none;\n position: absolute;\n left: 0;\n right: 0;\n top: 50%;\n height: 1px;\n z-index: 1;\n margin-left: 50px;\n margin-right: 54px;\n border-top-style: dotted;\n border-top-width: thin;\n border-top-color: rgba(127, 127, 127, 0.76);\n}\n\n.igv-cursor-guide-vertical {\n pointer-events: none;\n user-select: none;\n -moz-user-select: none;\n -webkit-user-select: none;\n position: absolute;\n top: 0;\n bottom: 0;\n left: 50%;\n width: 1px;\n z-index: 1;\n border-left-style: dotted;\n border-left-width: thin;\n border-left-color: rgba(127, 127, 127, 0.76);\n display: none;\n}\n\n.igv-user-feedback {\n position: fixed;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n width: 512px;\n height: 360px;\n z-index: 2048;\n background-color: white;\n border-color: #a2a2a2;\n border-style: solid;\n border-width: thin;\n font-family: \"Open Sans\", sans-serif;\n font-size: medium;\n font-weight: 400;\n color: #444;\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: center;\n}\n.igv-user-feedback div:first-child {\n position: relative;\n height: 24px;\n width: 100%;\n background-color: white;\n border-bottom-color: #a2a2a2;\n border-bottom-style: solid;\n border-bottom-width: thin;\n}\n.igv-user-feedback div:first-child div {\n position: absolute;\n top: 2px;\n width: 16px;\n height: 16px;\n background-color: transparent;\n}\n.igv-user-feedback div:first-child div:first-child {\n left: 8px;\n}\n.igv-user-feedback div:first-child div:last-child {\n cursor: pointer;\n right: 8px;\n}\n.igv-user-feedback div:last-child {\n width: 100%;\n height: calc(100% - 24px);\n border-width: 0;\n}\n.igv-user-feedback div:last-child div {\n width: auto;\n height: auto;\n margin: 8px;\n}\n\n.igv-generic-dialog-container {\n position: absolute;\n top: 0;\n left: 0;\n width: 300px;\n height: 200px;\n border-color: #7F7F7F;\n border-radius: 4px;\n border-style: solid;\n border-width: thin;\n font-family: \"Open Sans\", sans-serif;\n font-size: medium;\n font-weight: 400;\n z-index: 2048;\n background-color: white;\n display: flex;\n flex-flow: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: center;\n}\n.igv-generic-dialog-container .igv-generic-dialog-header {\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: flex-end;\n align-items: center;\n width: 100%;\n height: 24px;\n cursor: move;\n border-top-left-radius: 4px;\n border-top-right-radius: 4px;\n border-bottom-color: #7F7F7F;\n border-bottom-style: solid;\n border-bottom-width: thin;\n background-color: #eee;\n}\n.igv-generic-dialog-container .igv-generic-dialog-header div {\n margin-right: 4px;\n margin-bottom: 2px;\n height: 12px;\n width: 12px;\n color: #7F7F7F;\n}\n.igv-generic-dialog-container .igv-generic-dialog-header div:hover {\n cursor: pointer;\n color: #444;\n}\n.igv-generic-dialog-container .igv-generic-dialog-one-liner {\n color: #373737;\n width: 95%;\n height: 24px;\n line-height: 24px;\n text-align: left;\n margin-top: 8px;\n padding-left: 8px;\n overflow-wrap: break-word;\n background-color: white;\n}\n.igv-generic-dialog-container .igv-generic-dialog-label-input {\n margin-top: 8px;\n width: 95%;\n height: 24px;\n color: #373737;\n line-height: 24px;\n padding-left: 8px;\n background-color: white;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: center;\n}\n.igv-generic-dialog-container .igv-generic-dialog-label-input div {\n width: 30%;\n height: 100%;\n font-size: 16px;\n text-align: right;\n padding-right: 8px;\n background-color: white;\n}\n.igv-generic-dialog-container .igv-generic-dialog-label-input input {\n display: block;\n height: 100%;\n width: 100%;\n padding-left: 4px;\n font-family: \"Open Sans\", sans-serif;\n font-weight: 400;\n color: #373737;\n text-align: left;\n outline: none;\n border-style: solid;\n border-width: thin;\n border-color: #7F7F7F;\n background-color: white;\n}\n.igv-generic-dialog-container .igv-generic-dialog-label-input input {\n width: 50%;\n font-size: 16px;\n}\n.igv-generic-dialog-container .igv-generic-dialog-input {\n margin-top: 8px;\n width: calc(100% - 16px);\n height: 24px;\n color: #373737;\n line-height: 24px;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: space-around;\n align-items: center;\n}\n.igv-generic-dialog-container .igv-generic-dialog-input input {\n display: block;\n height: 100%;\n width: 100%;\n padding-left: 4px;\n font-family: \"Open Sans\", sans-serif;\n font-weight: 400;\n color: #373737;\n text-align: left;\n outline: none;\n border-style: solid;\n border-width: thin;\n border-color: #7F7F7F;\n background-color: white;\n}\n.igv-generic-dialog-container .igv-generic-dialog-input input {\n font-size: 16px;\n}\n.igv-generic-dialog-container .igv-generic-dialog-ok-cancel {\n width: 100%;\n height: 28px;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: space-around;\n align-items: center;\n}\n.igv-generic-dialog-container .igv-generic-dialog-ok-cancel div {\n margin-top: 32px;\n color: white;\n font-family: \"Open Sans\", sans-serif;\n font-size: 14px;\n font-weight: 400;\n width: 75px;\n height: 28px;\n line-height: 28px;\n text-align: center;\n border-color: transparent;\n border-style: solid;\n border-width: thin;\n border-radius: 2px;\n}\n.igv-generic-dialog-container .igv-generic-dialog-ok-cancel div:first-child {\n margin-left: 32px;\n margin-right: 0;\n background-color: #5ea4e0;\n}\n.igv-generic-dialog-container .igv-generic-dialog-ok-cancel div:last-child {\n margin-left: 0;\n margin-right: 32px;\n background-color: #c4c4c4;\n}\n.igv-generic-dialog-container .igv-generic-dialog-ok-cancel div:first-child:hover {\n cursor: pointer;\n background-color: #3b5c7f;\n}\n.igv-generic-dialog-container .igv-generic-dialog-ok-cancel div:last-child:hover {\n cursor: pointer;\n background-color: #7f7f7f;\n}\n.igv-generic-dialog-container .igv-generic-dialog-ok {\n width: 100%;\n height: 36px;\n margin-top: 32px;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: space-around;\n align-items: center;\n}\n.igv-generic-dialog-container .igv-generic-dialog-ok div {\n width: 98px;\n height: 36px;\n line-height: 36px;\n text-align: center;\n color: white;\n font-family: \"Open Sans\", sans-serif;\n font-size: medium;\n font-weight: 400;\n border-color: white;\n border-style: solid;\n border-width: thin;\n border-radius: 4px;\n background-color: #2B81AF;\n}\n.igv-generic-dialog-container .igv-generic-dialog-ok div:hover {\n cursor: pointer;\n background-color: #25597f;\n}\n\n.igv-generic-container {\n position: absolute;\n top: 0;\n left: 0;\n z-index: 2048;\n background-color: white;\n cursor: pointer;\n display: flex;\n flex-direction: row;\n flex-wrap: wrap;\n justify-content: flex-start;\n align-items: center;\n}\n.igv-generic-container div:first-child {\n cursor: move;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: flex-end;\n align-items: center;\n height: 24px;\n width: 100%;\n background-color: #dddddd;\n}\n.igv-generic-container div:first-child i {\n display: block;\n color: #5f5f5f;\n cursor: pointer;\n width: 14px;\n height: 14px;\n margin-right: 8px;\n margin-bottom: 4px;\n}\n\n.igv-menu-popup {\n position: absolute;\n top: 0;\n left: 0;\n width: max-content;\n z-index: 4096;\n cursor: pointer;\n font-family: \"Open Sans\", sans-serif;\n font-size: small;\n font-weight: 400;\n color: #4b4b4b;\n background: white;\n border-radius: 4px;\n border-color: #7F7F7F;\n border-style: solid;\n border-width: thin;\n display: flex;\n flex-flow: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: flex-end;\n text-align: left;\n}\n.igv-menu-popup > div:not(:first-child) {\n width: 100%;\n}\n.igv-menu-popup > div:not(:first-child) > div {\n background: white;\n}\n.igv-menu-popup > div:not(:first-child) > div.context-menu {\n padding-left: 4px;\n padding-right: 4px;\n}\n.igv-menu-popup > div:not(:first-child) > div:last-child {\n border-bottom-left-radius: 4px;\n border-bottom-right-radius: 4px;\n border-bottom-color: transparent;\n border-bottom-style: solid;\n border-bottom-width: thin;\n}\n.igv-menu-popup > div:not(:first-child) > div:hover {\n background: #efefef;\n}\n\n.igv-menu-popup-shim {\n padding-left: 8px;\n padding-right: 8px;\n padding-bottom: 1px;\n padding-top: 1px;\n}\n\n.igv-menu-popup-header {\n position: relative;\n width: 100%;\n height: 24px;\n cursor: move;\n border-top-color: transparent;\n border-top-left-radius: 4px;\n border-top-right-radius: 4px;\n border-bottom-color: #7F7F7F;\n border-bottom-style: solid;\n border-bottom-width: thin;\n background-color: #eee;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: flex-end;\n align-items: center;\n}\n.igv-menu-popup-header div {\n margin-right: 4px;\n height: 12px;\n width: 12px;\n color: #7F7F7F;\n}\n.igv-menu-popup-header div:hover {\n cursor: pointer;\n color: #444;\n}\n\n.igv-menu-popup-check-container {\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: center;\n width: 100%;\n height: 20px;\n margin-right: 4px;\n background-color: transparent;\n}\n.igv-menu-popup-check-container div {\n padding-top: 2px;\n padding-left: 8px;\n}\n.igv-menu-popup-check-container div:first-child {\n position: relative;\n width: 12px;\n height: 12px;\n}\n.igv-menu-popup-check-container div:first-child svg {\n position: absolute;\n width: 12px;\n height: 12px;\n}\n\n.igv-user-feedback {\n position: fixed;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n width: 512px;\n height: 360px;\n z-index: 2048;\n background-color: white;\n border-color: #a2a2a2;\n border-style: solid;\n border-width: thin;\n font-family: \"Open Sans\", sans-serif;\n font-size: medium;\n font-weight: 400;\n color: #444;\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: center;\n}\n.igv-user-feedback div:first-child {\n position: relative;\n height: 24px;\n width: 100%;\n background-color: white;\n border-bottom-color: #a2a2a2;\n border-bottom-style: solid;\n border-bottom-width: thin;\n}\n.igv-user-feedback div:first-child div {\n position: absolute;\n top: 2px;\n width: 16px;\n height: 16px;\n background-color: transparent;\n}\n.igv-user-feedback div:first-child div:first-child {\n left: 8px;\n}\n.igv-user-feedback div:first-child div:last-child {\n cursor: pointer;\n right: 8px;\n}\n.igv-user-feedback div:last-child {\n width: 100%;\n height: calc(100% - 24px);\n border-width: 0;\n}\n.igv-user-feedback div:last-child div {\n width: auto;\n height: auto;\n margin: 8px;\n}\n\n.igv-loading-spinner-container {\n z-index: 1024;\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n width: 32px;\n height: 32px;\n display: flex;\n flex-direction: row;\n flex-wrap: nowrap;\n justify-content: center;\n align-items: center;\n}\n.igv-loading-spinner-container > div {\n box-sizing: border-box;\n width: 100%;\n height: 100%;\n border-radius: 50%;\n border: 4px solid rgba(128, 128, 128, 0.5);\n border-top-color: rgb(255, 255, 255);\n animation: spin 1s ease-in-out infinite;\n -webkit-animation: spin 1s ease-in-out infinite;\n}\n\n@keyframes spin {\n to {\n -webkit-transform: rotate(360deg);\n transform: rotate(360deg);\n }\n}\n@-webkit-keyframes spin {\n to {\n -webkit-transform: rotate(360deg);\n transform: rotate(360deg);\n }\n}\n.igv-roi-menu-next-gen {\n position: absolute;\n z-index: 512;\n font-family: \"Open Sans\", sans-serif;\n font-size: small;\n font-weight: 400;\n color: #4b4b4b;\n background-color: white;\n width: 192px;\n border-radius: 4px;\n border-color: #7F7F7F;\n border-style: solid;\n border-width: thin;\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: stretch;\n}\n.igv-roi-menu-next-gen > div:first-child {\n height: 24px;\n border-top-color: transparent;\n border-top-left-radius: 4px;\n border-top-right-radius: 4px;\n border-bottom-color: #7F7F7F;\n border-bottom-style: solid;\n border-bottom-width: thin;\n background-color: #eee;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: flex-end;\n align-items: center;\n}\n.igv-roi-menu-next-gen > div:first-child > div {\n margin-right: 4px;\n height: 12px;\n width: 12px;\n color: #7F7F7F;\n}\n.igv-roi-menu-next-gen > div:first-child > div:hover {\n cursor: pointer;\n color: #444;\n}\n.igv-roi-menu-next-gen > div:last-child {\n background-color: white;\n border-bottom-left-radius: 4px;\n border-bottom-right-radius: 4px;\n border-bottom-color: transparent;\n border-bottom-style: solid;\n border-bottom-width: 0;\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: stretch;\n text-align: start;\n vertical-align: middle;\n cursor: pointer;\n}\n.igv-roi-menu-next-gen > div:last-child > div {\n height: 24px;\n padding-left: 4px;\n border-bottom-style: solid;\n border-bottom-width: thin;\n border-bottom-color: #7f7f7f;\n}\n.igv-roi-menu-next-gen > div:last-child > div:not(:first-child):hover {\n background-color: rgba(127, 127, 127, 0.1);\n}\n.igv-roi-menu-next-gen > div:last-child div:first-child {\n cursor: default;\n font-style: italic;\n text-align: center;\n padding-right: 4px;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n.igv-roi-menu-next-gen > div:last-child > div:last-child {\n border-bottom-width: 0;\n border-bottom-color: transparent;\n}\n\n.igv-roi-placeholder {\n font-style: normal;\n color: rgba(75, 75, 75, 0.6);\n}\n\n.igv-roi-table {\n position: absolute;\n z-index: 1024;\n width: fit-content;\n border-color: #7f7f7f;\n border-radius: 4px;\n border-style: solid;\n border-width: thin;\n font-family: \"Open Sans\", sans-serif;\n font-size: 12px;\n font-weight: 400;\n background-color: white;\n display: flex;\n flex-flow: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: stretch;\n}\n.igv-roi-table > div {\n height: 24px;\n font-size: 14px;\n text-align: start;\n vertical-align: middle;\n line-height: 24px;\n}\n.igv-roi-table > div:first-child {\n border-color: transparent;\n border-top-left-radius: 4px;\n border-top-right-radius: 4px;\n border-top-width: 0;\n border-bottom-color: #7f7f7f;\n border-bottom-style: solid;\n border-bottom-width: thin;\n background-color: #eee;\n cursor: move;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: space-between;\n align-items: center;\n}\n.igv-roi-table > div:first-child > div:first-child {\n text-align: center;\n width: calc(100% - 4px - 12px);\n}\n.igv-roi-table > div:first-child > div:last-child {\n margin-right: 4px;\n margin-bottom: 2px;\n height: 12px;\n width: 12px;\n color: #7f7f7f;\n}\n.igv-roi-table > div:first-child > div:last-child > svg {\n display: block;\n}\n.igv-roi-table > div:first-child > div:last-child:hover {\n cursor: pointer;\n color: #444;\n}\n.igv-roi-table > .igv-roi-table-column-titles {\n height: 24px;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: stretch;\n align-items: stretch;\n padding-right: 16px;\n background-color: white;\n border-bottom-color: #7f7f7f;\n border-bottom-style: solid;\n border-bottom-width: thin;\n}\n.igv-roi-table > .igv-roi-table-column-titles > div {\n font-size: 14px;\n vertical-align: middle;\n line-height: 24px;\n text-align: center;\n margin-left: 4px;\n margin-right: 4px;\n height: 24px;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n.igv-roi-table > .igv-roi-table-column-titles > div:nth-child(1) {\n width: 20%;\n}\n.igv-roi-table > .igv-roi-table-column-titles > div:nth-child(2) {\n width: 15%;\n}\n.igv-roi-table > .igv-roi-table-column-titles > div:nth-child(3) {\n width: 15%;\n}\n.igv-roi-table > .igv-roi-table-column-titles > div:nth-child(4) {\n width: 30%;\n}\n.igv-roi-table > .igv-roi-table-column-titles > div:nth-child(5) {\n width: 20%;\n}\n.igv-roi-table > .igv-roi-table-row-container {\n resize: both;\n overflow: scroll;\n min-width: 512px;\n min-height: 72px;\n height: 144px;\n max-height: 480px;\n background-color: white;\n display: flex;\n flex-flow: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: stretch;\n}\n.igv-roi-table > .igv-roi-table-row-container > .igv-roi-table-row {\n height: 24px;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: stretch;\n align-items: stretch;\n}\n.igv-roi-table > .igv-roi-table-row-container > .igv-roi-table-row > div {\n font-size: 14px;\n vertical-align: middle;\n line-height: 24px;\n text-align: center;\n margin-left: 4px;\n margin-right: 4px;\n height: 24px;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n.igv-roi-table > .igv-roi-table-row-container > .igv-roi-table-row > div:nth-child(1) {\n width: 20%;\n}\n.igv-roi-table > .igv-roi-table-row-container > .igv-roi-table-row > div:nth-child(2) {\n width: 15%;\n}\n.igv-roi-table > .igv-roi-table-row-container > .igv-roi-table-row > div:nth-child(3) {\n width: 15%;\n}\n.igv-roi-table > .igv-roi-table-row-container > .igv-roi-table-row > div:nth-child(4) {\n width: 30%;\n}\n.igv-roi-table > .igv-roi-table-row-container > .igv-roi-table-row > div:nth-child(5) {\n width: 20%;\n}\n.igv-roi-table > .igv-roi-table-row-container > .igv-roi-table-row-hover {\n background-color: rgba(0, 0, 0, 0.04);\n}\n.igv-roi-table > div:last-child {\n height: 32px;\n line-height: 32px;\n border-top-color: #7f7f7f;\n border-top-style: solid;\n border-top-width: thin;\n border-bottom-color: transparent;\n border-bottom-left-radius: 4px;\n border-bottom-right-radius: 4px;\n border-bottom-width: 0;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: space-around;\n align-items: center;\n}\n\n.igv-roi-table-four-column {\n position: absolute;\n z-index: 1024;\n width: fit-content;\n border-color: #7f7f7f;\n border-radius: 4px;\n border-style: solid;\n border-width: thin;\n font-family: \"Open Sans\", sans-serif;\n font-size: 12px;\n font-weight: 400;\n background-color: white;\n display: flex;\n flex-flow: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: stretch;\n}\n.igv-roi-table-four-column > div {\n height: 24px;\n font-size: 14px;\n text-align: start;\n vertical-align: middle;\n line-height: 24px;\n}\n.igv-roi-table-four-column > div:first-child {\n border-color: transparent;\n border-top-left-radius: 4px;\n border-top-right-radius: 4px;\n border-top-width: 0;\n border-bottom-color: #7f7f7f;\n border-bottom-style: solid;\n border-bottom-width: thin;\n background-color: #eee;\n cursor: move;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: space-between;\n align-items: center;\n}\n.igv-roi-table-four-column > div:first-child > div:first-child {\n text-align: center;\n width: calc(100% - 4px - 12px);\n}\n.igv-roi-table-four-column > div:first-child > div:last-child {\n margin-right: 4px;\n margin-bottom: 2px;\n height: 12px;\n width: 12px;\n color: #7f7f7f;\n}\n.igv-roi-table-four-column > div:first-child > div:last-child > svg {\n display: block;\n}\n.igv-roi-table-four-column > div:first-child > div:last-child:hover {\n cursor: pointer;\n color: #444;\n}\n.igv-roi-table-four-column > .igv-roi-table-column-titles {\n height: 24px;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: stretch;\n align-items: stretch;\n padding-right: 16px;\n background-color: white;\n border-bottom-color: #7f7f7f;\n border-bottom-style: solid;\n border-bottom-width: thin;\n}\n.igv-roi-table-four-column > .igv-roi-table-column-titles > div {\n font-size: 14px;\n vertical-align: middle;\n line-height: 24px;\n text-align: center;\n margin-left: 4px;\n margin-right: 4px;\n height: 24px;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n.igv-roi-table-four-column > .igv-roi-table-column-titles > div:nth-child(1) {\n width: 25%;\n}\n.igv-roi-table-four-column > .igv-roi-table-column-titles > div:nth-child(2) {\n width: 20%;\n}\n.igv-roi-table-four-column > .igv-roi-table-column-titles > div:nth-child(3) {\n width: 20%;\n}\n.igv-roi-table-four-column > .igv-roi-table-column-titles > div:nth-child(4) {\n width: 35%;\n}\n.igv-roi-table-four-column > .igv-roi-table-row-container {\n resize: both;\n overflow: scroll;\n min-width: 512px;\n min-height: 72px;\n height: 144px;\n max-height: 480px;\n background-color: white;\n display: flex;\n flex-flow: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: stretch;\n}\n.igv-roi-table-four-column > .igv-roi-table-row-container > .igv-roi-table-row {\n height: 24px;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: stretch;\n align-items: stretch;\n}\n.igv-roi-table-four-column > .igv-roi-table-row-container > .igv-roi-table-row > div {\n font-size: 14px;\n vertical-align: middle;\n line-height: 24px;\n text-align: center;\n margin-left: 4px;\n margin-right: 4px;\n height: 24px;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n.igv-roi-table-four-column > .igv-roi-table-row-container > .igv-roi-table-row > div:nth-child(1) {\n width: 25%;\n}\n.igv-roi-table-four-column > .igv-roi-table-row-container > .igv-roi-table-row > div:nth-child(2) {\n width: 20%;\n}\n.igv-roi-table-four-column > .igv-roi-table-row-container > .igv-roi-table-row > div:nth-child(3) {\n width: 20%;\n}\n.igv-roi-table-four-column > .igv-roi-table-row-container > .igv-roi-table-row > div:nth-child(4) {\n width: 35%;\n}\n.igv-roi-table-four-column > .igv-roi-table-row-container > .igv-roi-table-row-hover {\n background-color: rgba(0, 0, 0, 0.04);\n}\n.igv-roi-table-four-column > div:last-child {\n height: 32px;\n line-height: 32px;\n border-top-color: #7f7f7f;\n border-top-style: solid;\n border-top-width: thin;\n border-bottom-color: transparent;\n border-bottom-left-radius: 4px;\n border-bottom-right-radius: 4px;\n border-bottom-width: 0;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: space-around;\n align-items: center;\n}\n\n.igv-roi-table-row-selected {\n background-color: rgba(0, 0, 0, 0.125);\n}\n\n.igv-roi-table-button {\n height: 20px;\n user-select: none;\n line-height: 20px;\n text-align: center;\n vertical-align: middle;\n font-family: \"Open Sans\", sans-serif;\n font-size: 13px;\n font-weight: 400;\n color: black;\n padding-left: 6px;\n padding-right: 6px;\n background-color: rgb(239, 239, 239);\n border-color: black;\n border-style: solid;\n border-width: thin;\n border-radius: 3px;\n}\n\n.igv-roi-table-button:hover {\n cursor: pointer;\n font-weight: 400;\n background-color: rgba(0, 0, 0, 0.13);\n}\n\n.igv-roi-region {\n z-index: 64;\n position: absolute;\n top: 0;\n bottom: 0;\n pointer-events: none;\n overflow: visible;\n margin-top: 44px;\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: stretch;\n}\n.igv-roi-region > div {\n position: relative;\n width: 100%;\n height: 8px;\n cursor: pointer;\n pointer-events: auto;\n}\n\n.igv-roi-menu {\n position: absolute;\n z-index: 1024;\n width: 144px;\n border-color: #7f7f7f;\n border-radius: 4px;\n border-style: solid;\n border-width: thin;\n font-family: \"Open Sans\", sans-serif;\n background-color: white;\n display: flex;\n flex-flow: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: stretch;\n}\n.igv-roi-menu > div:not(:last-child) {\n border-bottom-color: rgba(128, 128, 128, 0.5);\n border-bottom-style: solid;\n border-bottom-width: thin;\n}\n.igv-roi-menu > div:first-child {\n border-top-left-radius: 4px;\n border-top-right-radius: 4px;\n border-top-color: transparent;\n border-top-style: solid;\n border-top-width: 0;\n}\n.igv-roi-menu > div:last-child {\n border-bottom-left-radius: 4px;\n border-bottom-right-radius: 4px;\n border-bottom-color: transparent;\n border-bottom-style: solid;\n border-bottom-width: 0;\n}\n\n.igv-roi-menu-row {\n height: 24px;\n padding-left: 8px;\n font-size: small;\n text-align: start;\n vertical-align: middle;\n line-height: 24px;\n background-color: white;\n}\n\n.igv-roi-menu-row-edit-description {\n width: -webkit-fill-available;\n font-size: small;\n text-align: start;\n vertical-align: middle;\n background-color: white;\n padding-left: 4px;\n padding-right: 4px;\n padding-bottom: 4px;\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n justify-content: stretch;\n align-items: stretch;\n}\n.igv-roi-menu-row-edit-description > label {\n margin-left: 2px;\n margin-bottom: 0;\n display: block;\n width: -webkit-fill-available;\n}\n.igv-roi-menu-row-edit-description > input {\n display: block;\n margin-left: 2px;\n margin-right: 2px;\n margin-bottom: 1px;\n width: -webkit-fill-available;\n}\n\n.igv-container {\n position: relative;\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: flex-start;\n padding-top: 4px;\n user-select: none;\n -webkit-user-select: none;\n -ms-user-select: none;\n}\n\n.igv-viewport {\n position: relative;\n margin-top: 5px;\n overflow-x: hidden;\n overflow-y: hidden;\n}\n\n.igv-viewport-content {\n position: relative;\n width: 100%;\n}\n.igv-viewport-content > canvas {\n position: relative;\n display: block;\n}\n\n.igv-column-container {\n position: relative;\n display: flex;\n flex-direction: row;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: stretch;\n width: 100%;\n}\n\n.igv-column-shim {\n width: 1px;\n margin-left: 2px;\n margin-right: 2px;\n background-color: #545453;\n}\n\n.igv-column {\n position: relative;\n position: relative;\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: flex-start;\n box-sizing: border-box;\n height: 100%;\n}\n\n.igv-axis-column {\n position: relative;\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: flex-start;\n box-sizing: border-box;\n height: 100%;\n width: 50px;\n}\n.igv-axis-column > div {\n margin-top: 5px;\n width: 100%;\n}\n\n.igv-sample-name-column {\n position: relative;\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: flex-start;\n box-sizing: border-box;\n height: 100%;\n}\n\n.igv-scrollbar-column {\n position: relative;\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: flex-start;\n box-sizing: border-box;\n height: 100%;\n width: 14px;\n}\n.igv-scrollbar-column > div {\n position: relative;\n margin-top: 5px;\n width: 14px;\n}\n.igv-scrollbar-column > div > div {\n cursor: pointer;\n position: absolute;\n top: 0;\n left: 2px;\n width: 8px;\n border-width: 1px;\n border-style: solid;\n border-color: #c4c4c4;\n border-top-left-radius: 4px;\n border-top-right-radius: 4px;\n border-bottom-left-radius: 4px;\n border-bottom-right-radius: 4px;\n}\n.igv-scrollbar-column > div > div:hover {\n background-color: #c4c4c4;\n}\n\n.igv-track-drag-column {\n position: relative;\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: flex-start;\n box-sizing: border-box;\n height: 100%;\n width: 12px;\n background-color: white;\n}\n.igv-track-drag-column > .igv-track-drag-handle {\n z-index: 512;\n position: relative;\n cursor: pointer;\n margin-top: 5px;\n width: 100%;\n border-style: solid;\n border-width: 0;\n border-top-right-radius: 6px;\n border-bottom-right-radius: 6px;\n background-color: #c4c4c4;\n}\n.igv-track-drag-column .igv-track-drag-handle-hover {\n background-color: #787878;\n}\n.igv-track-drag-column > .igv-track-drag-shim {\n position: relative;\n margin-top: 5px;\n width: 100%;\n border-style: solid;\n border-width: 0;\n}\n\n.igv-gear-menu-column {\n position: relative;\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: flex-start;\n box-sizing: border-box;\n height: 100%;\n width: 28px;\n}\n.igv-gear-menu-column > div {\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: center;\n margin-top: 5px;\n width: 100%;\n background: white;\n}\n.igv-gear-menu-column > div > div {\n position: relative;\n margin-top: 4px;\n width: 16px;\n height: 16px;\n color: #7F7F7F;\n}\n.igv-gear-menu-column > div > div:hover {\n cursor: pointer;\n color: #444;\n}\n\n/*# sourceMappingURL=dom.css.map */\n';
53993
54042
 
53994
54043
  var style = document.createElement('style');
53995
54044
  style.setAttribute('type', 'text/css');