igv 2.15.6 → 2.15.8

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.js CHANGED
@@ -9681,6 +9681,7 @@
9681
9681
  menuItems.push(unsetColorMenuItem({trackView, label: "Unset track color"}));
9682
9682
  if(trackView.track.config.type === 'wig' || trackView.track.config.type === 'annotation') {
9683
9683
  menuItems.push(colorPickerMenuItem({trackView, label: "Set alt color", option: "altColor"}));
9684
+ menuItems.push(unsetAltColorMenuItem({trackView, label: "Unset alt color"}));
9684
9685
  }
9685
9686
  }
9686
9687
 
@@ -9882,6 +9883,20 @@
9882
9883
  }
9883
9884
  }
9884
9885
 
9886
+ function unsetAltColorMenuItem({trackView, label}) {
9887
+
9888
+ const $e = $$1('<div>');
9889
+ $e.text(label);
9890
+
9891
+ return {
9892
+ object: $e,
9893
+ click: () => {
9894
+ trackView.track.altColor = undefined;
9895
+ trackView.repaintViews();
9896
+ }
9897
+ }
9898
+ }
9899
+
9885
9900
  function trackRenameMenuItem(trackView) {
9886
9901
 
9887
9902
  const click = e => {
@@ -18665,7 +18680,6 @@
18665
18680
 
18666
18681
  const self = this;
18667
18682
 
18668
- //console.log(`${Date.now()} ${url}`)
18669
18683
  url = mapUrl$1(url);
18670
18684
 
18671
18685
  options = options || {};
@@ -18715,7 +18729,10 @@
18715
18729
  }
18716
18730
 
18717
18731
  if (range) {
18718
- var rangeEnd = range.size ? range.start + range.size - 1 : "";
18732
+ let rangeEnd = "";
18733
+ if (range.size) {
18734
+ rangeEnd = range.start + range.size - 1;
18735
+ }
18719
18736
  xhr.setRequestHeader("Range", "bytes=" + range.start + "-" + rangeEnd);
18720
18737
  // xhr.setRequestHeader("Cache-Control", "no-cache"); <= This can cause CORS issues, disabled for now
18721
18738
  }
@@ -18741,20 +18758,34 @@
18741
18758
  }
18742
18759
 
18743
18760
  xhr.onload = async function (event) {
18744
- // when the url points to a local file, the status is 0 but that is not an error
18761
+
18762
+ // when the url points to a local file, the status is 0
18745
18763
  if (xhr.status === 0 || (xhr.status >= 200 && xhr.status <= 300)) {
18746
- if (range && xhr.status !== 206 && range.start !== 0) {
18747
- // For small files a range starting at 0 can return the whole file => 200
18748
- // Provide just the slice we asked for, throw out the rest quietly
18749
- // If file is large warn user
18750
- if (xhr.response.length > 100000 && !self.RANGE_WARNING_GIVEN) {
18751
- alert(`Warning: Range header ignored for URL: ${url}. This can have severe performance impacts.`);
18764
+ if ("HEAD" === options.method) {
18765
+ // Support fetching specific headers. Attempting to fetch all headers can be problematic with CORS
18766
+ const headers = options.requestedHeaders || ['content-length'];
18767
+ const headerMap = {};
18768
+ for (let h of headers) {
18769
+ headerMap[h] = xhr.getResponseHeader(h);
18752
18770
  }
18753
- resolve(xhr.response.slice(range.start, range.start + range.size));
18754
-
18771
+ resolve(headerMap);
18755
18772
  } else {
18756
- resolve(xhr.response);
18773
+ // Assume "GET" or "POST"
18774
+ if (range && xhr.status !== 206 && range.start !== 0) {
18775
+
18776
+ // For small files a range starting at 0 can return the whole file => 200
18777
+ // Provide just the slice we asked for, throw out the rest quietly
18778
+ // If file is large warn user
18779
+ if (xhr.response.length > 100000 && !self.RANGE_WARNING_GIVEN) {
18780
+ alert(`Warning: Range header ignored for URL: ${url}. This can have severe performance impacts.`);
18781
+ }
18782
+ resolve(xhr.response.slice(range.start, range.start + range.size));
18783
+ } else {
18784
+ resolve(xhr.response);
18785
+ }
18757
18786
  }
18787
+ } else if (xhr.status === 416) {
18788
+ handleError(Error(`416 Unsatisfiable Range`));
18758
18789
  } else if ((typeof gapi !== "undefined") &&
18759
18790
  ((xhr.status === 404 || xhr.status === 401 || xhr.status === 403) &&
18760
18791
  isGoogleURL(url)) &&
@@ -18764,9 +18795,6 @@
18764
18795
  } else {
18765
18796
  if (xhr.status === 403) {
18766
18797
  handleError("Access forbidden: " + url);
18767
- } else if (xhr.status === 416) {
18768
- // Tried to read off the end of the file. This shouldn't happen, but if it does return an
18769
- handleError("Unsatisfiable range");
18770
18798
  } else {
18771
18799
  handleError(xhr.status);
18772
18800
  }
@@ -18898,6 +18926,24 @@
18898
18926
  }
18899
18927
  }
18900
18928
  }
18929
+
18930
+ /**
18931
+ * This method should only be called when it is known the server supports HEAD requests. It is used to recover
18932
+ * from 416 errors from out-of-spec WRT range request servers. Notably Globus.
18933
+ * * *
18934
+ * @param url
18935
+ * @param options
18936
+ * @returns {Promise<unknown>}
18937
+ */
18938
+ async getContentLength(url, options) {
18939
+ options = options || {};
18940
+ options.method = 'HEAD';
18941
+ options.requestedHeaders = ['content-length'];
18942
+ const headerMap = await this._loadURL(url, options);
18943
+ const contentLengthString = headerMap['content-length'];
18944
+ return contentLengthString ? Number.parseInt(contentLengthString) : 0
18945
+ }
18946
+
18901
18947
  }
18902
18948
 
18903
18949
  function isGoogleStorageSigned(url) {
@@ -21107,6 +21153,10 @@
21107
21153
 
21108
21154
  }
21109
21155
 
21156
+ function registerFileFormats(name, fields) {
21157
+ FileFormats[name] = {fields: fields};
21158
+ }
21159
+
21110
21160
  var TrackUtils = /*#__PURE__*/Object.freeze({
21111
21161
  __proto__: null,
21112
21162
  knownFileExtensions: knownFileExtensions,
@@ -21114,7 +21164,8 @@
21114
21164
  inferFileFormat: inferFileFormat,
21115
21165
  inferFileFormatFromHeader: inferFileFormatFromHeader,
21116
21166
  inferTrackType: inferTrackType,
21117
- inferIndexPath: inferIndexPath
21167
+ inferIndexPath: inferIndexPath,
21168
+ registerFileFormats: registerFileFormats
21118
21169
  });
21119
21170
 
21120
21171
  const pairs =
@@ -23944,7 +23995,7 @@
23944
23995
  }
23945
23996
  };
23946
23997
 
23947
- const _version = "2.15.6";
23998
+ const _version = "2.15.8";
23948
23999
  function version() {
23949
24000
  return _version
23950
24001
  }
@@ -27083,10 +27134,10 @@
27083
27134
 
27084
27135
  static defaults = {
27085
27136
  height: 50,
27086
- color: 'rgb(0, 0, 150)',
27087
- altColor: 'rgb(0, 0, 150)',
27088
27137
  autoHeight: false,
27089
- visibilityWindow: undefined,
27138
+ visibilityWindow: undefined, // Identifies property that should be copied from config
27139
+ color: undefined, // Identifies property that should be copied from config
27140
+ altColor: undefined, // Identifies property that should be copied from config
27090
27141
  supportHiDPI: true
27091
27142
  }
27092
27143
 
@@ -31956,6 +32007,7 @@
31956
32007
  this.queryable = true;
31957
32008
  } else if ("htsget" === config.sourceType) {
31958
32009
  this.reader = new HtsgetVariantReader(config, genome);
32010
+ this.queryable = true;
31959
32011
  } else if (config.sourceType === 'ucscservice') {
31960
32012
  this.reader = new UCSCServiceReader(config.source);
31961
32013
  this.queryable = true;
@@ -32169,30 +32221,45 @@
32169
32221
  * @param fulfill - function to receive result
32170
32222
  * @param asUint8 - optional flag to return result as an UInt8Array
32171
32223
  */
32172
- async dataViewForRange(requestedRange, asUint8) {
32224
+ async dataViewForRange(requestedRange, asUint8, retries = 0) {
32225
+ try {
32173
32226
 
32174
- const hasData = (this.data && (this.range.start <= requestedRange.start) &&
32175
- ((this.range.start + this.range.size) >= (requestedRange.start + requestedRange.size)));
32227
+ const hasData = (this.data && (this.range.start <= requestedRange.start) &&
32228
+ ((this.range.start + this.range.size) >= (requestedRange.start + requestedRange.size)));
32176
32229
 
32177
- if (!hasData) {
32178
- let bufferSize;
32179
- // If requested range size is specified, potentially expand buffer size
32180
- if (requestedRange.size) {
32181
- bufferSize = Math.max(this.bufferSize, requestedRange.size);
32182
- } else {
32183
- bufferSize = this.bufferSize;
32230
+ if (!hasData) {
32231
+ let bufferSize;
32232
+ // If requested range size is specified, potentially expand buffer size
32233
+ if (requestedRange.size) {
32234
+ bufferSize = Math.max(this.bufferSize, requestedRange.size);
32235
+ } else {
32236
+ bufferSize = this.bufferSize;
32237
+ }
32238
+ if (this.contentLength) {
32239
+ bufferSize = Math.min(bufferSize, this.contentLength - requestedRange.start);
32240
+ }
32241
+ const loadRange = {start: requestedRange.start, size: bufferSize};
32242
+ const arrayBuffer = await igvxhr.loadArrayBuffer(this.path, buildOptions(this.config, {range: loadRange}));
32243
+ this.data = arrayBuffer;
32244
+ this.range = loadRange;
32184
32245
  }
32185
- const loadRange = {start: requestedRange.start, size: bufferSize};
32186
- const arrayBuffer = await igvxhr.loadArrayBuffer(this.path, buildOptions(this.config, {range: loadRange}));
32187
- this.data = arrayBuffer;
32188
- this.range = loadRange;
32189
- }
32190
32246
 
32191
- const len = this.data.byteLength;
32192
- const bufferStart = requestedRange.start - this.range.start;
32193
- return asUint8 ?
32194
- new Uint8Array(this.data, bufferStart, len - bufferStart) :
32195
- new DataView(this.data, bufferStart, len - bufferStart)
32247
+ const len = this.data.byteLength;
32248
+ const bufferStart = requestedRange.start - this.range.start;
32249
+ return asUint8 ?
32250
+ new Uint8Array(this.data, bufferStart, len - bufferStart) :
32251
+ new DataView(this.data, bufferStart, len - bufferStart)
32252
+ } catch (e) {
32253
+ if (retries === 0 && e.message && e.message.startsWith("416")) {
32254
+ try {
32255
+ this.contentLength = await igvxhr.getContentLength(this.path, buildOptions(this.config));
32256
+ return this.dataViewForRange(requestedRange, asUint8, ++retries)
32257
+ } catch (e1) {
32258
+ console.error(e1);
32259
+ }
32260
+ throw e
32261
+ }
32262
+ }
32196
32263
  }
32197
32264
  }
32198
32265
 
@@ -40401,6 +40468,9 @@
40401
40468
  }
40402
40469
  }
40403
40470
 
40471
+ const DEFAULT_COLOR$2 = 'rgb(0, 0, 150)';
40472
+
40473
+
40404
40474
  class FeatureTrack extends TrackBase {
40405
40475
 
40406
40476
  static defaults = {
@@ -40832,8 +40902,11 @@
40832
40902
  color = this.colorTable.getColor(value);
40833
40903
  } else if (feature.color) {
40834
40904
  color = feature.color; // Explicit color for feature
40835
- } else {
40836
- color = this.color; // Track default
40905
+ }
40906
+
40907
+ // If no explicit setting use the default
40908
+ if (!color) {
40909
+ color = DEFAULT_COLOR$2; // Track default
40837
40910
  }
40838
40911
 
40839
40912
  if (feature.alpha && feature.alpha !== 1) {
@@ -41418,8 +41491,6 @@
41418
41491
  showAllBases: false,
41419
41492
  showInsertions: true,
41420
41493
  showMismatches: true,
41421
- color: DEFAULT_ALIGNMENT_COLOR,
41422
- coverageColor: DEFAULT_COVERAGE_COLOR,
41423
41494
  height: 300,
41424
41495
  coverageTrackHeight: 50
41425
41496
  }
@@ -41439,6 +41510,10 @@
41439
41510
 
41440
41511
  this.alignmentTrack.setTop(this.coverageTrack, this.showCoverage);
41441
41512
 
41513
+ if(!this.showAlignments) {
41514
+ this._height = this.coverageTrackHeight;
41515
+ }
41516
+
41442
41517
  // The sort object can be an array in the case of multi-locus view, however if multiple sort positions
41443
41518
  // are present for a given reference frame the last one will take precedence
41444
41519
  if (config.sort) {
@@ -41915,15 +41990,6 @@
41915
41990
  }
41916
41991
  const chords = makePairedAlignmentChords(inView);
41917
41992
  sendChords(chords, this, refFrame, 0.02);
41918
-
41919
- // const chordSetColor = IGVColor.addAlpha("all" === refFrame.chr ? this.color : getChrColor(refFrame.chr), 0.02)
41920
- // const trackColor = IGVColor.addAlpha(this.color || 'rgb(0,0,255)', 0.02)
41921
- //
41922
- // // name the chord set to include track name and locus
41923
- // const encodedName = this.name.replaceAll(' ', '%20')
41924
- // const chordSetName = "all" === refFrame.chr ? encodedName :
41925
- // `${encodedName} (${refFrame.chr}:${refFrame.start}-${refFrame.end}`
41926
- // this.browser.circularView.addChords(chords, {name: chordSetName, color: chordSetColor, trackColor: trackColor})
41927
41993
  }
41928
41994
 
41929
41995
  addSplitChordsForViewport(viewport) {
@@ -41940,15 +42006,6 @@
41940
42006
 
41941
42007
  const chords = makeSupplementalAlignmentChords(inView);
41942
42008
  sendChords(chords, this, refFrame, 0.02);
41943
-
41944
- // const chordSetColor = IGVColor.addAlpha("all" === refFrame.chr ? this.color : getChrColor(refFrame.chr), 0.02)
41945
- // const trackColor = IGVColor.addAlpha(this.color || 'rgb(0,0,255)', 0.02)
41946
- //
41947
- // // name the chord set to include track name and locus
41948
- // const encodedName = this.name.replaceAll(' ', '%20')
41949
- // const chordSetName = "all" === refFrame.chr ? encodedName :
41950
- // `${encodedName} (${refFrame.chr}:${refFrame.start}-${refFrame.end}`
41951
- // this.browser.circularView.addChords(chords, {name: chordSetName, color: chordSetColor, trackColor: trackColor})
41952
42009
  }
41953
42010
  }
41954
42011
 
@@ -42005,7 +42062,7 @@
42005
42062
  let color;
42006
42063
  if (this.parent.coverageColor) {
42007
42064
  color = this.parent.coverageColor;
42008
- } else if (this.parent.color !== undefined && typeof this.parent.color !== "function") {
42065
+ } else if (this.parent.color && typeof this.parent.color !== "function") {
42009
42066
  color = IGVColor.darkenLighten(this.parent.color, -35);
42010
42067
  } else {
42011
42068
  color = DEFAULT_COVERAGE_COLOR;
@@ -42846,8 +42903,9 @@
42846
42903
  case "tag":
42847
42904
  if (this.parent.color) {
42848
42905
  return (typeof this.parent.color === "function") ? this.parent.color(alignment) : this.parent.color
42906
+ } else {
42907
+ return DEFAULT_CONNECTOR_COLOR
42849
42908
  }
42850
- return DEFAULT_CONNECTOR_COLOR
42851
42909
  default:
42852
42910
  return this.getAlignmentColor(alignment)
42853
42911
 
@@ -42859,6 +42917,8 @@
42859
42917
  let color = DEFAULT_ALIGNMENT_COLOR; // The default color if nothing else applies
42860
42918
  if (this.parent.color) {
42861
42919
  color = (typeof this.parent.color === "function") ? this.parent.color(alignment) : this.parent.color;
42920
+ } else {
42921
+ color = DEFAULT_ALIGNMENT_COLOR;
42862
42922
  }
42863
42923
  const option = this.colorBy;
42864
42924
  switch (option) {
@@ -44670,12 +44730,12 @@
44670
44730
  * THE SOFTWARE.
44671
44731
  */
44672
44732
 
44733
+ const DEFAULT_COLOR$1 = 'rgb(150, 150, 150)';
44734
+
44673
44735
  class WigTrack extends TrackBase {
44674
44736
 
44675
44737
  static defaults = {
44676
44738
  height: 50,
44677
- color: 'rgb(150, 150, 150)',
44678
- altColor: 'rgb(150, 150, 150)',
44679
44739
  flipAxis: false,
44680
44740
  logScale: false,
44681
44741
  windowFunction: 'mean',
@@ -44808,7 +44868,7 @@
44808
44868
  const pixelWidth = options.pixelWidth;
44809
44869
  options.pixelHeight;
44810
44870
  const bpEnd = bpStart + pixelWidth * bpPerPixel + 1;
44811
- const posColor = this.color || WigTrack.defaults.color;
44871
+ const posColor = this.color || DEFAULT_COLOR$1;
44812
44872
 
44813
44873
  let baselineColor;
44814
44874
  if (typeof posColor === "string" && posColor.startsWith("rgb(")) {
@@ -44952,7 +45012,7 @@
44952
45012
  */
44953
45013
 
44954
45014
  getColorForFeature(f) {
44955
- let c = (f.value < 0 && this.altColor) ? this.altColor : this.color || WigTrack.defaults.color;
45015
+ let c = (f.value < 0 && this.altColor) ? this.altColor : this.color || DEFAULT_COLOR$1;
44956
45016
  return (typeof c === "function") ? c(f.value) : c
44957
45017
  }
44958
45018
 
@@ -46680,7 +46740,7 @@
46680
46740
 
46681
46741
  const isString = isString$2;
46682
46742
 
46683
-
46743
+ const DEFAULT_COLOR = "rgb(0,0,150)";
46684
46744
  const DEFAULT_VISIBILITY_WINDOW = 1000000;
46685
46745
  const TOP_MARGIN = 10;
46686
46746
  const STANDARD_FIELDS = new Map([["REF", "referenceBases"], ["ALT", "alternateBases"], ["QUAL", "quality"], ["FILTER", "filter"]]);
@@ -46730,6 +46790,7 @@
46730
46790
  this.colorTables = new Map();
46731
46791
  this.colorTables.set(config.colorBy, new ColorTable(config.colorTable));
46732
46792
  }
46793
+ this._color = config.color;
46733
46794
  this._strokecolor = config.strokecolor;
46734
46795
  this._context_hook = config.context_hook;
46735
46796
 
@@ -46762,7 +46823,7 @@
46762
46823
  }
46763
46824
 
46764
46825
  get color() {
46765
- return this._color
46826
+ return this._color || DEFAULT_COLOR
46766
46827
  }
46767
46828
 
46768
46829
  set color(c) {
@@ -62103,7 +62164,8 @@
62103
62164
  setOauthToken,
62104
62165
  oauth,
62105
62166
  version,
62106
- setApiKey
62167
+ setApiKey,
62168
+ registerFileFormats
62107
62169
  };
62108
62170
 
62109
62171
  return index;