igv 2.15.1 → 2.15.3

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
@@ -18366,7 +18366,7 @@
18366
18366
 
18367
18367
  function getScopeForURL(url) {
18368
18368
  if (isGoogleDriveURL(url)) {
18369
- return "https://www.googleapis.com/auth/drive.file"
18369
+ return "https://www.googleapis.com/auth/drive.readonly"
18370
18370
  } else if (isGoogleStorageURL(url)) {
18371
18371
  return "https://www.googleapis.com/auth/devstorage.read_only"
18372
18372
  } else {
@@ -18395,7 +18395,8 @@
18395
18395
  const response = await fetch(endPoint);
18396
18396
  let json = await response.json();
18397
18397
  if (json.error && json.error.code === 404) {
18398
- const access_token = await getAccessToken("https://www.googleapis.com/auth/drive.readonly");
18398
+ let scope = "https://www.googleapis.com/auth/drive.readonly";
18399
+ const access_token = await getAccessToken(scope);
18399
18400
  if (access_token) {
18400
18401
  const response = await fetch(endPoint, {
18401
18402
  headers: {
@@ -18662,6 +18663,8 @@
18662
18663
 
18663
18664
  async _loadURL(url, options) {
18664
18665
 
18666
+ const self = this;
18667
+
18665
18668
  //console.log(`${Date.now()} ${url}`)
18666
18669
  url = mapUrl$1(url);
18667
18670
 
@@ -18751,7 +18754,7 @@
18751
18754
  // For small files a range starting at 0 can return the whole file => 200
18752
18755
  // Provide just the slice we asked for, throw out the rest quietly
18753
18756
  // If file is large warn user
18754
- if (xhr.response.length > 100000 && !this.RANGE_WARNING_GIVEN) {
18757
+ if (xhr.response.length > 100000 && !self.RANGE_WARNING_GIVEN) {
18755
18758
  alert(`Warning: Range header ignored for URL: ${url}. This can have severe performance impacts.`);
18756
18759
  }
18757
18760
  resolve(xhr.response.slice(range.start, range.start + range.size));
@@ -18780,8 +18783,9 @@
18780
18783
  xhr.onerror = function (event) {
18781
18784
  if (isGoogleURL(url) && !options.retries) {
18782
18785
  tryGoogleAuth();
18786
+ } else {
18787
+ handleError("Error accessing resource: " + url + " Status: " + xhr.status);
18783
18788
  }
18784
- handleError("Error accessing resource: " + url + " Status: " + xhr.status);
18785
18789
  };
18786
18790
 
18787
18791
  xhr.ontimeout = function (event) {
@@ -18796,7 +18800,11 @@
18796
18800
  try {
18797
18801
  xhr.send(sendData);
18798
18802
  } catch (e) {
18799
- reject(e);
18803
+ if (isGoogleURL(url) && !options.retries) {
18804
+ tryGoogleAuth();
18805
+ } else {
18806
+ handleError(e);
18807
+ }
18800
18808
  }
18801
18809
 
18802
18810
 
@@ -18813,7 +18821,7 @@
18813
18821
  const accessToken = await fetchGoogleAccessToken(url);
18814
18822
  options.retries = 1;
18815
18823
  options.oauthToken = accessToken;
18816
- const response = await this._load(url, options);
18824
+ const response = await self.load(url, options);
18817
18825
  resolve(response);
18818
18826
  } catch (e) {
18819
18827
  if (e.error) {
@@ -18869,29 +18877,41 @@
18869
18877
  this.oauth.setToken(token, host);
18870
18878
  }
18871
18879
 
18880
+ /**
18881
+ * Return an oauth token for the URL if we have one. This method does not force sign-in, and the token may
18882
+ * or may not be valid. Sign-in is triggered on request failure.
18883
+ * *
18884
+ * @param url
18885
+ * @returns {*}
18886
+ */
18872
18887
  getOauthToken(url) {
18873
18888
 
18874
18889
  // Google is the default provider, don't try to parse host for google URLs
18875
18890
  const host = isGoogleURL(url) ?
18876
18891
  undefined :
18877
18892
  parseUri(url).host;
18893
+
18894
+ // First check the explicit settings (i.e. token set through the API)
18878
18895
  let token = this.oauth.getToken(host);
18879
18896
  if (token) {
18880
18897
  return token
18881
18898
  } else if (host === undefined) {
18899
+ // Now try Google oauth tokens previously obtained. This will return undefined if google oauth is not
18900
+ // configured.
18882
18901
  const googleToken = getCurrentGoogleAccessToken();
18883
18902
  if (googleToken && googleToken.expires_at > Date.now()) {
18884
18903
  return googleToken.access_token
18885
18904
  }
18886
18905
  }
18887
18906
  }
18888
-
18889
18907
  }
18890
18908
 
18891
18909
  function isGoogleStorageSigned(url) {
18892
18910
  return url.indexOf("X-Goog-Signature") > -1
18893
18911
  }
18894
18912
 
18913
+
18914
+
18895
18915
  /**
18896
18916
  * Return a Google oAuth token, triggering a sign in if required. This method should not be called until we know
18897
18917
  * a token is required, that is until we've tried the url and received a 401, 403, or 404.
@@ -18959,14 +18979,16 @@
18959
18979
  */
18960
18980
  function mapUrl$1(url) {
18961
18981
 
18962
- if (url.includes("//www.dropbox.com")) {
18982
+ if (url.startsWith("https://www.dropbox.com")) {
18963
18983
  return url.replace("//www.dropbox.com", "//dl.dropboxusercontent.com")
18964
- } else if (url.includes("//drive.google.com")) {
18984
+ } else if (url.startsWith("https://drive.google.com")) {
18965
18985
  return getDriveDownloadURL(url)
18966
18986
  } else if (url.includes("//www.broadinstitute.org/igvdata")) {
18967
18987
  return url.replace("//www.broadinstitute.org/igvdata", "//data.broadinstitute.org/igvdata")
18968
18988
  } else if (url.includes("//igvdata.broadinstitute.org")) {
18969
- return url.replace("//igvdata.broadinstitute.org", "https://dn7ywbm9isq8j.cloudfront.net")
18989
+ return url.replace("//igvdata.broadinstitute.org", "//s3.amazonaws.com/igv.broadinstitute.org")
18990
+ } else if (url.includes("//igv.genepattern.org")) {
18991
+ return url.replace("//igv.genepattern.org", "//igv-genepattern-org.s3.amazonaws.com")
18970
18992
  } else if (url.startsWith("ftp://ftp.ncbi.nlm.nih.gov/geo")) {
18971
18993
  return url.replace("ftp://", "https://")
18972
18994
  } else {
@@ -23928,7 +23950,7 @@
23928
23950
  }
23929
23951
  };
23930
23952
 
23931
- const _version = "2.15.1";
23953
+ const _version = "2.15.3";
23932
23954
  function version() {
23933
23955
  return _version
23934
23956
  }
@@ -25765,15 +25787,15 @@
25765
25787
  * @param keyValueDelim
25766
25788
  * @returns {[]}
25767
25789
  */
25768
- function parseAttributeString(attributeString, keyValueDelim) {
25790
+ function parseAttributeString(attributeString, keyValueDelim, relaxed = false) {
25769
25791
  // parse 'attributes' string (see column 9 docs in https://github.com/The-Sequence-Ontology/Specifications/blob/master/gff3.md)
25770
25792
  var attributes = [];
25771
25793
  for (let kv of attributeString.split(';')) {
25772
25794
  kv = kv.trim();
25773
25795
  const idx = kv.indexOf(keyValueDelim);
25774
25796
  if (idx > 0 && idx < kv.length - 1) {
25775
- const key = kv.substring(0, idx);
25776
- let value = stripQuotes(decodeGFFAttribute(kv.substring(idx + 1).trim()));
25797
+ const key = stripQuotes(decodeGFFAttribute(kv.substring(0, idx).trim(), relaxed));
25798
+ let value = stripQuotes(decodeGFFAttribute(kv.substring(idx + 1).trim(), relaxed));
25777
25799
  attributes.push([key, value]);
25778
25800
  }
25779
25801
  }
@@ -25812,11 +25834,14 @@
25812
25834
  ["%2C", ","]
25813
25835
  ]);
25814
25836
 
25815
- function decodeGFFAttribute(str) {
25837
+ function decodeGFFAttribute(str, relaxed = false) {
25816
25838
 
25817
25839
  if (!str.includes("%")) {
25818
25840
  return str
25819
25841
  }
25842
+ if (relaxed) {
25843
+ return decodeURIComponent(str);
25844
+ }
25820
25845
  let decoded = "";
25821
25846
  for (let i = 0; i < str.length; i++) {
25822
25847
 
@@ -25874,7 +25899,7 @@
25874
25899
 
25875
25900
  // Potentially parse name field as GFF column 9 style streng.
25876
25901
  if (tokens[3].indexOf(';') > 0 && tokens[3].indexOf('=') > 0) {
25877
- const attributeKVs = parseAttributeString(tokens[3], '=');
25902
+ const attributeKVs = parseAttributeString(tokens[3], '=', true);
25878
25903
  feature.attributes = {};
25879
25904
  for (let kv of attributeKVs) {
25880
25905
  feature.attributes[kv[0]] = kv[1];
@@ -27275,6 +27300,8 @@
27275
27300
  }
27276
27301
  tracklineConfg.autoscale = false;
27277
27302
  tracklineConfg.dataRange = {min, max};
27303
+ this.viewLimitMin = min;
27304
+ this.viewLimitMax = max;
27278
27305
  }
27279
27306
  case "name":
27280
27307
  tracklineConfg[key] = properties[key];
@@ -29173,9 +29200,9 @@
29173
29200
  * @returns {boolean|boolean}
29174
29201
  */
29175
29202
  function canMerge(chunk1, chunk2) {
29176
- const gap = chunk2.minv.block - chunk1.maxv.block;
29203
+ chunk2.minv.block - chunk1.maxv.block;
29177
29204
  const sizeEstimate = chunk1.maxv.block - chunk1.minv.block;
29178
- return gap < 65000 && sizeEstimate < 5000000
29205
+ return sizeEstimate < 5000000
29179
29206
  }
29180
29207
 
29181
29208
  // Represents a CSI Bam or Tabix index
@@ -40798,8 +40825,8 @@
40798
40825
  color = IGVColor.addAlpha(color, feature.alpha);
40799
40826
  } else if (this.useScore && feature.score && !Number.isNaN(feature.score)) {
40800
40827
  // UCSC useScore option, for scores between 0-1000. See https://genome.ucsc.edu/goldenPath/help/customTrack.html#TRACK
40801
- const min = this.config.min ? this.config.min : 0; //getViewLimitMin(track);
40802
- const max = this.config.max ? this.config.max : 1000; //getViewLimitMax(track);
40828
+ const min = this.config.min ? this.config.min : this.viewLimitMin ? this.viewLimitMin : 0;
40829
+ const max = this.config.max ? this.config.max : this.viewLimitMax ? this.viewLimitMax : 1000;
40803
40830
  const alpha = getAlpha(min, max, feature.score);
40804
40831
  feature.alpha = alpha; // Avoid computing again
40805
40832
  color = IGVColor.addAlpha(color, alpha);
@@ -40858,6 +40885,10 @@
40858
40885
  this.browser = config.browser;
40859
40886
 
40860
40887
  this.container = domUtils.div({ class: 'igv-roi-table' });
40888
+ if(config.width) {
40889
+ this.container.style.width = config.width;
40890
+
40891
+ }
40861
40892
 
40862
40893
  config.parent.appendChild(this.container);
40863
40894
 
@@ -41039,6 +41070,7 @@
41039
41070
  set columnTitleDOM(columnFormat) {
41040
41071
 
41041
41072
  const dom = domUtils.div({ class: 'igv-roi-table-column-titles' });
41073
+ this.columnTitlesDiv = dom;
41042
41074
  this.container.appendChild(dom);
41043
41075
 
41044
41076
  for (const format of columnFormat) {
@@ -41056,13 +41088,16 @@
41056
41088
 
41057
41089
  let dom;
41058
41090
 
41059
- const found = this.container.querySelector('.igv-roi-table-column-titles');
41060
41091
  dom = domUtils.div({ class: 'igv-roi-table-description' });
41061
- this.container.insertBefore(dom, found);
41092
+ this.container.insertBefore(dom, this.columnTitlesDiv);
41093
+ dom.innerHTML = `BLAT result for query sequence:`;
41094
+
41095
+ dom = domUtils.div({ class: 'igv-roi-table-description' });
41096
+ this.container.insertBefore(dom, this.columnTitlesDiv);
41062
41097
  dom.innerHTML = config.description;
41063
41098
 
41064
41099
  dom = domUtils.div({ class: 'igv-roi-table-goto-explainer' });
41065
- this.container.insertBefore(dom, found);
41100
+ this.container.insertBefore(dom, this.columnTitlesDiv);
41066
41101
  dom.innerHTML = `Select one or more rows and click Go To to view the regions`;
41067
41102
 
41068
41103
  }
@@ -41180,16 +41215,16 @@
41180
41215
  &output=json
41181
41216
  */
41182
41217
 
41183
-
41184
41218
  //const blatServer = "https://genome.ucsc.edu/cgi-bin/hgBlat"
41185
- const blatServer = "https://igv.org/services/blat.php";
41219
+ const defaultBlatServer = "https://igv.org/services/blatUCSC.php";
41220
+ //const blatServer = "http://localhost:8000/blatUCSC.php"
41186
41221
 
41187
41222
 
41188
- async function blat(userSeq, db) {
41223
+ async function blat({url, userSeq, db}) {
41189
41224
 
41190
- const url = `${blatServer}?userSeq=${userSeq}&type=DNA&db=${db}&output=json`;
41225
+ url = url || defaultBlatServer;
41191
41226
 
41192
- const results = await igvxhr.loadJson(url, {});
41227
+ const results = await postData(url, userSeq, db);
41193
41228
 
41194
41229
  results.fields;
41195
41230
 
@@ -41198,8 +41233,19 @@
41198
41233
  return features
41199
41234
  }
41200
41235
 
41201
- class BlatTrack extends FeatureTrack {
41236
+ async function postData(url = "", userSeq, db) {
41237
+
41238
+ const data = new URLSearchParams();
41239
+ data.append("userSeq", userSeq);
41240
+ data.append("db", db);
41202
41241
 
41242
+ const response = await fetch(url, { method: "post", body: data });
41243
+ return response.json(); // parses JSON response into native JavaScript objects
41244
+ }
41245
+
41246
+ const maxSequenceSize = 25000;
41247
+
41248
+ class BlatTrack extends FeatureTrack {
41203
41249
 
41204
41250
  constructor(config, browser) {
41205
41251
  super(config, browser);
@@ -41235,7 +41281,7 @@
41235
41281
  browser: this.browser,
41236
41282
  parent: this.browser.parent,
41237
41283
  headerTitle: this.config.title,
41238
- description: `BLAT result for query sequence:<br>${ this.sequence }`,
41284
+ description: this.sequence,
41239
41285
  dismissHandler: () => {
41240
41286
  this.table.dismiss();
41241
41287
  this.table.dispose();
@@ -41284,21 +41330,34 @@
41284
41330
 
41285
41331
  async function createBlatTrack({sequence, browser, name, title}) {
41286
41332
 
41333
+ if (sequence.length > maxSequenceSize) {
41334
+ browser.alert.present(`Sequence size exceeds maximum allowed length (${sequence.length} > ${maxSequenceSize})`);
41335
+ return
41336
+ }
41337
+
41287
41338
  const db = browser.genome.id; // TODO -- blat specific property
41288
41339
 
41289
- const features = await blat(sequence, db);
41340
+ const url = browser.config["blatServerURL"];
41290
41341
 
41291
- const trackConfig = {
41292
- type: 'blat',
41293
- name: name || 'blat results',
41294
- title: title || 'blat results',
41295
- sequence: sequence,
41296
- features: features
41297
- };
41342
+ try {
41343
+
41344
+ const features = await blat({url, userSeq: sequence, db});
41345
+ const trackConfig = {
41346
+ type: 'blat',
41347
+ name: name || 'blat results',
41348
+ title: title || 'blat results',
41349
+ sequence: sequence,
41350
+ altColor: 'rgb(176, 176, 236)',
41351
+ color: 'rgb(236, 176, 176)',
41352
+ features: features
41353
+ };
41298
41354
 
41299
- const track = await browser.loadTrack(trackConfig);
41355
+ const track = await browser.loadTrack(trackConfig);
41356
+ track.openTableView();
41300
41357
 
41301
- track.openTableView();
41358
+ } catch (e) {
41359
+ browser.alert.present(`Error performing blat search: ${e}`);
41360
+ }
41302
41361
 
41303
41362
  }
41304
41363
 
@@ -42651,18 +42710,21 @@
42651
42710
  // TODO if genome supports blat
42652
42711
  const seqstring = clickedAlignment.seq;
42653
42712
  if (seqstring && "*" != seqstring) {
42654
- list.push({
42655
- label: 'BLAT read sequence',
42656
- click: () => {
42657
- const sequence = clickedAlignment.isNegativeStrand() ? reverseComplementSequence(seqstring) : seqstring;
42658
- const name = `${clickedAlignment.readName} - blat`;
42659
- const title = `${this.parent.name} - ${name}`;
42660
- createBlatTrack({sequence, browser: this.browser, name, title});
42661
- }
42662
- });
42713
+
42714
+ if(seqstring.length < maxSequenceSize) {
42715
+ list.push({
42716
+ label: 'BLAT read sequence',
42717
+ click: () => {
42718
+ const sequence = clickedAlignment.isNegativeStrand() ? reverseComplementSequence(seqstring) : seqstring;
42719
+ const name = `${clickedAlignment.readName} - blat`;
42720
+ const title = `${this.parent.name} - ${name}`;
42721
+ createBlatTrack({sequence, browser: this.browser, name, title});
42722
+ }
42723
+ });
42724
+ }
42663
42725
 
42664
42726
  const softClips = clickedAlignment.softClippedBlocks();
42665
- if (softClips.left && softClips.left.len > MINIMUM_BLAT_LENGTH) {
42727
+ if (softClips.left && softClips.left.len > MINIMUM_BLAT_LENGTH && softClips.left.len < maxSequenceSize) {
42666
42728
  list.push({
42667
42729
  label: 'BLAT left soft-clipped sequence',
42668
42730
  click: () => {
@@ -42674,7 +42736,7 @@
42674
42736
  }
42675
42737
  });
42676
42738
  }
42677
- if (softClips.right && softClips.right.length > MINIMUM_BLAT_LENGTH) {
42739
+ if (softClips.right && softClips.right.len > MINIMUM_BLAT_LENGTH && softClips.right.len < maxSequenceSize) {
42678
42740
  list.push({
42679
42741
  label: 'BLAT right soft-clipped sequence',
42680
42742
  click: () => {
@@ -54168,11 +54230,13 @@
54168
54230
 
54169
54231
  // console.log(h5_obj_keys)
54170
54232
  let signal_bin = new ParseSignals(h5_obj_keys);
54171
- this.rd_bins = signal_bin.get_rd_bins();
54233
+ let rd_bins = signal_bin.get_rd_bins();
54234
+ let snp_bins = signal_bin.get_snp_bins();
54235
+ this.available_bins = [...new Set(rd_bins, snp_bins)];
54172
54236
 
54173
54237
  // let bin_size = this.bin_size
54174
- if(! this.rd_bins.includes(bin_size)){
54175
- bin_size = this.rd_bins[rd_bins.length-1];
54238
+ if(! this.available_bins.includes(bin_size)){
54239
+ bin_size = this.available_bins.at(-1);
54176
54240
  }
54177
54241
 
54178
54242
  const chr_ds = await h5_obj.get("rd_chromosomes");
@@ -54216,6 +54280,9 @@
54216
54280
  let signal_baf_1 = `snp_likelihood_${chrom}_${bin_size}_mask`;
54217
54281
  let chr_wig_bafs = await this.get_baf_signals(h5_obj, h5_obj_keys, chrom, bin_size, signal_baf_1);
54218
54282
 
54283
+ // let signal_baf_1 = `snp_i1_${chrom}_${bin_size}_mask`
54284
+ // let chr_wig_bafs = await this.get_baf_signals_v2(h5_obj, h5_obj_keys, chrom, bin_size, signal_baf_1)
54285
+
54219
54286
  wigFeatures_baf1 = wigFeatures_baf1.concat(chr_wig_bafs[0]);
54220
54287
  wigFeatures_baf2 = wigFeatures_baf2.concat(chr_wig_bafs[1]);
54221
54288
  // this.rd_call_combined(h5_obj, h5_obj_keys, chrom, bin_size, rd_stat)
@@ -54340,6 +54407,28 @@
54340
54407
  }
54341
54408
  return [chr_wig_1, chr_wig_2]
54342
54409
  }
54410
+
54411
+ async get_baf_signals_v2(h5_obj, h5_obj_keys, chrom, bin_size, signal_name){
54412
+
54413
+ /* return two list of dictionary*/
54414
+ let chr_wig_1 = [];
54415
+ let chr_wig_2 = [];
54416
+ if (h5_obj_keys.includes(signal_name)){
54417
+ let chrom_dataset = await h5_obj.get(signal_name);
54418
+ let chrom_data = await chrom_dataset.to_array(); //create_nested_array(value, shape)
54419
+ chrom_data.forEach((lh, bin_idx) => {
54420
+ if (!isNaN(lh)){
54421
+ chr_wig_1.push({chr:chrom, start: bin_idx*bin_size, end: (bin_idx+1) * bin_size, value: -2 * ( 0.5 - lh )});
54422
+ if(lh != 0.5){
54423
+ chr_wig_2.push({chr:chrom, start: bin_idx*bin_size, end: (bin_idx+1) * bin_size, value: -2 * ( 0.5 + lh )});
54424
+ }
54425
+ }
54426
+ });
54427
+ }
54428
+ console.log(chrom, chr_wig_1, chr_wig_2);
54429
+ return [chr_wig_1, chr_wig_2]
54430
+
54431
+ }
54343
54432
  }
54344
54433
 
54345
54434
  class ParseSignals{
@@ -54380,6 +54469,53 @@
54380
54469
  }
54381
54470
  }
54382
54471
 
54472
+ class GetFit {
54473
+ constructor(allBins) {
54474
+ this.allBins = allBins;
54475
+ }
54476
+ getValues() {
54477
+ const bins = Object.values(this.allBins).reduce(
54478
+ (binResult, bin) => { return binResult.concat(bin.filter(a => a.binScore > 0).map(a => a.binScore)) }, []);
54479
+ return bins
54480
+ }
54481
+ getMean(data) {
54482
+ return (data.reduce(function (a, b) { return a + b; }) / data.length);
54483
+ }
54484
+ fit_data() {
54485
+ let rd_list = this.getValues();
54486
+ let distParmas = getDistParams(rd_list);
54487
+ return distParmas
54488
+ }
54489
+
54490
+ histogram(data, bins) {
54491
+ const step = bins[1] - bins[0];
54492
+ const hist_bins = [];
54493
+
54494
+ data.forEach((value, index) => {
54495
+ bins.forEach((bin_value, bin_index) => {
54496
+ if (!hist_bins[bin_value]) {
54497
+ hist_bins[bin_value] = { count: 0 };
54498
+ }
54499
+ if (bin_value <= value && value < bin_value + step) {
54500
+ hist_bins[bin_value].count++;
54501
+ return false;
54502
+ }
54503
+ });
54504
+ });
54505
+ const dist_p = [];
54506
+ hist_bins.forEach((bin, index) => { dist_p.push(bin.count); });
54507
+ return dist_p
54508
+ }
54509
+
54510
+ }
54511
+
54512
+ function range_function(start, stop, step) {
54513
+ const data_array = Array(Math.ceil((stop - start) / step))
54514
+ .fill(start)
54515
+ .map((x, y) => x + y * step);
54516
+ return data_array;
54517
+ }
54518
+
54383
54519
  function filterOutliers(someArray) {
54384
54520
 
54385
54521
  if (someArray.length < 4)
@@ -54412,6 +54548,21 @@
54412
54548
  return [mean, std]
54413
54549
  }
54414
54550
 
54551
+ function linspace(a, b, n) {
54552
+ if (typeof n === "undefined") n = Math.max(Math.round(b - a) + 1, 1);
54553
+ if (n < 2) {
54554
+ return n === 1 ? [a] : [];
54555
+ }
54556
+ var ret = Array(n);
54557
+ n--;
54558
+ for (let i = n; i >= 0; i--) {
54559
+ ret[i] = (i * b + (n - i) * a) / n;
54560
+ }
54561
+ return ret;
54562
+ }
54563
+
54564
+ var g_utils = { range_function, getDistParams, linspace, GetFit};
54565
+
54415
54566
  /**
54416
54567
  * Evaluates the cumulative distribution function (CDF) for a Student's t distribution with degrees of freedom `v` at a value `t`.
54417
54568
  *
@@ -54556,48 +54707,507 @@
54556
54707
  return Math.log(gamma(xg))
54557
54708
  }
54558
54709
 
54559
- var t_dist = {TdistributionCDF, gamma};
54710
+ function t_test_1_sample$1(mean, m, s, n) {
54711
+ if (s == 0) s = 1;
54712
+ var t = ((mean - m) / s) * Math.sqrt(n);
54713
+ var p = 1.0 - TdistributionCDF(Math.abs(t), (n - 1));
54714
+ return p
54715
+ }
54560
54716
 
54561
- class GetFit {
54562
- constructor(allBins) {
54563
- this.allBins = allBins;
54564
- }
54565
- getValues() {
54566
- const bins = Object.values(this.allBins).reduce(
54567
- (binResult, bin) => { return binResult.concat(bin.filter(a => a.binScore > 0).map(a => a.binScore)) }, []);
54568
- return bins
54717
+ function t_test_2_samples$1(m1, s1, n1, m2, s2, n2) {
54718
+ if (s1 == 0) s1 = 1;
54719
+ if (s2 == 0) s2 = 1;
54720
+ var t = (m1 - m2) / Math.sqrt(s1 ** 2 / n1 + s2 ** 2 / n2);
54721
+ var df = ((s1 ** 2 / n1 + s2 ** 2 / n2) ** 2 * (n1 - 1) * (n2 - 1)) /
54722
+ ((s1 ** 4 * (n2 - 1)) / n1 ** 2 + (s2 ** 4 * (n1 - 1)) / n2 ** 2);
54723
+
54724
+ var p = 1.0 - TdistributionCDF(Math.abs(t), parseInt(df + 0.5));
54725
+
54726
+ return p
54727
+ }
54728
+
54729
+ var t_dist = {TdistributionCDF, gamma, t_test_1_sample: t_test_1_sample$1, t_test_2_samples: t_test_2_samples$1};
54730
+
54731
+ class CombinedCaller{
54732
+ constructor(wigFeatures, binSize) {
54733
+ this.wigFeatures = wigFeatures;
54734
+ this.binSize = binSize;
54735
+ // let fit_obj = this.get_fit()
54736
+ // this.globalMean = fit_obj.globalMean
54737
+ // this.globalStd = fit_obj.globalStd
54569
54738
  }
54570
- getMean(data) {
54571
- return (data.reduce(function (a, b) { return a + b; }) / data.length);
54739
+ get_fit(){
54740
+ var fit_info = new g_utils.GetFit(this.wigFeatures);
54741
+ var [globalMean, globalStd] = fit_info.fit_data();
54742
+
54743
+ return {globalMean:globalMean, globalStd:globalStd}
54744
+
54572
54745
  }
54573
- fit_data() {
54574
- let rd_list = this.getValues();
54575
- let distParmas = getDistParams(rd_list);
54576
- return distParmas
54746
+ async call_2d(omin=null, mcount=null, event_type="both", max_distance=0.1, baf_threshold=0, max_copy_number=10, min_cell_fraction=0.0){
54747
+
54748
+ let fit_obj = this.get_fit();
54749
+ this.globalMean = fit_obj.globalMean;
54750
+ this.globalStd = fit_obj.globalStd;
54751
+
54752
+ let overlap_min = omin==null ? 0.05 * this.binSize / 3e9: omin ;
54753
+ let min_count = mcount == null ? parseInt(this.binSize / 10000) : mcount ;
54754
+
54755
+ let gstat_rd0 = [];
54756
+ let gstat_rd_all = [];
54757
+ let gstat_rd = [];
54758
+ let gstat_error = [];
54759
+ let gstat_lh = [];
54760
+ let gstat_n = [];
54761
+
54762
+ for (const [chr, wig] of Object.entries(this.wigFeatures)) {
54763
+ let segments = [];
54764
+ let levels = [];
54765
+ let likelihoods = [];
54766
+
54767
+ wig.forEach((bin, bin_idx) => {
54768
+ if (bin.hets_count > 4 ){
54769
+
54770
+ if( bin.dp_count > min_count ){
54771
+ segments.push([bin_idx]);
54772
+ levels.push(bin.binScore);
54773
+ likelihoods.push(bin.likelihood_score);
54774
+ delete bin.likelihood_score;
54775
+
54776
+ }
54777
+ }
54778
+ });
54779
+
54780
+ let diff_level = [];
54781
+ for(let i=1; i<levels.length; i++){
54782
+ diff_level.push(Math.abs(levels[i] - levels[i-1]));
54783
+ }
54784
+ let min_flank = [0];
54785
+ for(let i=1; i<diff_level.length; i++){
54786
+ min_flank.push(Math.min(diff_level[i-1], diff_level[i]));
54787
+ }
54788
+ min_flank.push(0);
54789
+
54790
+ let error = levels.map((x, x_idx) => {return Math.sqrt(Math.sqrt(x) ** 2 + this.globalStd ** 2 + Math.pow(min_flank[x_idx]/2, 2));});
54791
+
54792
+ let overlaps = [];
54793
+
54794
+ for(let i=0; i< segments.length-1; i++){
54795
+
54796
+ let lh_overlap = 0;
54797
+ try{
54798
+ lh_overlap = likelihood_overlap(likelihoods[i], likelihoods[i+1]);
54799
+ }catch{
54800
+ console.log("Overlap failed: ", i, likelihoods[i], segments[i+1], likelihoods[i+1]);
54801
+ }
54802
+
54803
+ let rd_overlap = normal_overlap_approx(levels[i], error[i], levels[i+1], error[i+1]);
54804
+ overlaps.push(rd_overlap * lh_overlap);
54805
+
54806
+ }
54807
+
54808
+ while(overlaps.length >0) {
54809
+ overlaps = overlaps.filter(num => typeof num === "number");
54810
+
54811
+ let max_overlap = arrayMax(overlaps);
54812
+ if(isNaN(max_overlap)){
54813
+ console.log('NaN value', overlaps);
54814
+ }
54815
+ if(max_overlap < overlap_min){
54816
+ // console.log("maxoverlap ",max_overlap, "is smaller than overlap min")
54817
+ break
54818
+ }
54819
+ let i = overlaps.indexOf(max_overlap);
54820
+
54821
+ let merge_level = normal_merge(levels[i], error[i], levels[i + 1], error[i + 1]);
54822
+
54823
+ let nlh;
54824
+ let nlh_sum;
54825
+ try{
54826
+ nlh = likelihoods[i].map((l_value, l_idx) => { return l_value * likelihoods[i+1][l_idx]});
54827
+
54828
+ nlh_sum = nlh.reduce((a, c_value) => {return a + c_value});
54829
+
54830
+ }catch{
54831
+ console.log(likelihoods);
54832
+ console.log('max_overlap:', max_overlap, i, overlaps.length);
54833
+ console.log('likelihood: ', i ,likelihoods[i], likelihoods[i+1]);
54834
+ console.log('nlh: ', nlh_sum);
54835
+ }
54836
+ // nlh_sum = nlh.reduce((a, c_value) => {return a + c_value});
54837
+
54838
+ levels[i] = merge_level.nl;
54839
+ error[i] = merge_level.ne;
54840
+
54841
+ likelihoods[i] = nlh.map(function(item) { return item/nlh_sum } );
54842
+
54843
+ segments[i].push(...segments[i+1]);
54844
+
54845
+ levels.splice(i + 1, 1);
54846
+ error.splice(i + 1, 1);
54847
+ segments.splice(i + 1, 1);
54848
+ likelihoods.splice(i + 1, 1);
54849
+ overlaps.splice(i, 1);
54850
+
54851
+ if(i < overlaps.length){
54852
+
54853
+ let rd_overlap = normal_overlap_approx(levels[i], error[i], levels[i+1], error[i+1]);
54854
+ let new_overlap = rd_overlap * likelihood_overlap(likelihoods[i], likelihoods[i + 1]);
54855
+
54856
+ overlaps[i] = new_overlap;
54857
+ }
54858
+ if(i > 0){
54859
+ let new_overlap = normal_overlap_approx(levels[i - 1], error[i - 1], levels[i], error[i])
54860
+ * likelihood_overlap(likelihoods[i - 1], likelihoods[i]);
54861
+ overlaps[i - 1] = new_overlap;
54862
+ }
54863
+
54864
+ }
54865
+ let ons = -1;
54866
+ while(true){
54867
+ overlaps = [];
54868
+ for(let i=0; i< levels.length; i++){
54869
+ for(let j=i; j<levels.length; j++){
54870
+ if(segments[j][0] - segments[i].at(-1) < max_distance * (segments[i].length + segments[j].length)){
54871
+ overlaps.push(normal_overlap_approx(levels[i], error[i], levels[j], error[j]) * likelihood_overlap(likelihoods[i], likelihoods[j]));
54872
+ }
54873
+ }
54874
+ }
54875
+
54876
+ if(overlaps.length == 0){
54877
+ break
54878
+ }
54879
+ let max_overlap = arrayMax(overlaps);
54880
+ if(max_overlap < overlap_min){
54881
+ break
54882
+ }
54883
+ let i = 0;
54884
+ let j = 1;
54885
+ while (i < segments.length - 1){
54886
+ let overlap_value = normal_overlap_approx(levels[i], error[i], levels[j], error[j]) * likelihood_overlap(likelihoods[i], likelihoods[j]);
54887
+
54888
+ if((segments[j][0] - segments[i].at(-1)) < max_distance * (segments[i].length + segments[j].length) && overlap_value == max_overlap){
54889
+ let merge_level = normal_merge(levels[i], error[i], levels[i + 1], error[i + 1]);
54890
+
54891
+ levels[i] = merge_level.nl;
54892
+ error[i] = merge_level.ne;
54893
+ let nlh = likelihoods[i].map((l_value, l_idx) => { return l_value * likelihoods[i+1][l_idx]});
54894
+ let nlh_sum = nlh.reduce((a, c_value) => {return a + c_value});
54895
+ likelihoods[i] = nlh.map(function(item) { return item/nlh_sum } );
54896
+
54897
+
54898
+ segments[i].push(...segments[i+1]);
54899
+ segments[i] = segments[i].sort((a,b) => a-b);
54900
+
54901
+ levels.splice(j, 1);
54902
+ error.splice(j, 1);
54903
+ segments.splice(j, 1);
54904
+ likelihoods.splice(j, 1);
54905
+
54906
+ if(j >= segments.length){
54907
+ i += 1;
54908
+ j = i + 1;
54909
+ }
54910
+
54911
+ }else {
54912
+ j += 1;
54913
+ if(j >= segments.length){
54914
+ i += 1;
54915
+ j = i + 1;
54916
+ }
54917
+ }
54918
+ }
54919
+ if(ons == segments.length){
54920
+ break
54921
+ }
54922
+ ons = segments.length;
54923
+ }
54924
+ // console.log('final segments', segments)
54925
+
54926
+ segments.forEach((seg_value, seg_idx) => {
54927
+ let baf_info = likelihood_baf_pval(likelihoods[seg_idx]);
54928
+ if(seg_value.length > 1){
54929
+
54930
+ seg_value.forEach((bin, bin_idx) =>{
54931
+ gstat_rd_all.push(wig[bin]);
54932
+ if(baf_info.mean <= baf_threshold){
54933
+ gstat_rd0.push(wig[bin]);
54934
+ }
54935
+ wig[bin].segment_score = levels[seg_idx];
54936
+ });
54937
+ gstat_rd.push(levels[seg_idx]);
54938
+ gstat_error.push(error[seg_idx]);
54939
+ gstat_lh.push(likelihoods[seg_idx]);
54940
+
54941
+ }
54942
+
54943
+ });
54944
+
54945
+ continue
54946
+ }
54947
+
54948
+ // Third stage for call
54949
+
54950
+ // let data = gstat_rd0.lengthn == 0 ? gstat_rd_all: gstat_rd0 ;
54951
+
54952
+ let points = parseInt(1000 * (1 - min_cell_fraction));
54953
+ if(points == 0){
54954
+ points = 1;
54955
+ }
54956
+ let x = g_utils.linspace(min_cell_fraction, 1, points);
54957
+ let master_lh = {};
54958
+ let germline_lh = {};
54959
+ for(let cn=10; cn > -1; cn--){
54960
+ for(let h1=0; h1 < (cn/2+1); h1++){
54961
+ let h2 = cn - h1;
54962
+ let mrd = x.map((v, idx) => {return 1-v +v*cn/2});
54963
+ let g_mrd = cn / 2;
54964
+ let g_mbaf;
54965
+ let mbaf;
54966
+ if(cn > 0){
54967
+ g_mbaf = 0.5 - (h1 / (h1 + h2));
54968
+ mbaf = x.map((v, idx) => {return 0.5 - (1 - v + v * h1) / (2 - 2 * v + (h1 + h2) * v)});
54969
+
54970
+ }else {
54971
+ g_mbaf = 0;
54972
+ mbaf = x.map((v, idx) => {return 0*v});
54973
+ }
54974
+
54975
+ for( let ei=0; ei < gstat_rd.length; ei++){
54976
+
54977
+ let g_lh = normal(g_mrd * this.globalMean, 1, gstat_rd[ei], gstat_error[ei]) * likelihood_of_baf(gstat_lh[ei], 0.5 + g_mbaf);
54978
+ if(ei in germline_lh){
54979
+ germline_lh[ei].push([cn, h1, h2, g_lh, 1.0]);
54980
+ }else {
54981
+ germline_lh[ei] = [cn, h1, h2, g_lh, 1.0];
54982
+ }
54983
+ let slh = 0;
54984
+ let max_lh = 0;
54985
+ let max_x = 0;
54986
+ mrd.forEach((mi, idx) => {
54987
+ if(!isNaN(mbaf[idx])){
54988
+ let tmpl = normal(mi * this.globalMean, 1, gstat_rd[ei], gstat_error[ei]) * likelihood_of_baf(gstat_lh[ei], 0.5 + mbaf[idx]);
54989
+ slh += tmpl;
54990
+ if(tmpl > max_lh){
54991
+ max_lh = tmpl;
54992
+ max_x = x[idx];
54993
+ }
54994
+ }
54995
+ });
54996
+ if(ei in master_lh){
54997
+ master_lh[ei].push([cn, h1, h2, slh / x.length, max_x]);
54998
+ }else {
54999
+ master_lh[ei] = [cn, h1, h2, slh / x.length, max_x];
55000
+ }
55001
+ }
55002
+
55003
+ for( let ei=0; ei < gstat_rd.length; ei++){
55004
+ if(event_type == "germline"){
55005
+ master_lh[ei].sort((a, b) => a[3] - b[3]);
55006
+ }
55007
+ else {
55008
+ master_lh[ei].sort((a, b) => a[3] - b[3]);
55009
+ if(event_type == "both"){
55010
+
55011
+ germline_lh[ei].sort((a, b) => a[3] - b[3]);
55012
+ if(germline_lh[ei][0][3] > master_lh[ei][0][3]){
55013
+ //let tmp_list = list(filter( lambda x: x[0] != germline_lh[ei][0][0] and x[1] != germline_lh[ei][0][1], master_lh[ei]))
55014
+ let tmp_list = master_lh[ei].filter((x) => (x[0] != germline_lh[ei][0][0]) && (x[1] <= germline_lh[ei][0][1]));
55015
+ // console.log('tmp_list', tmp_list)
55016
+ // master_lh[ei] = [germline_lh[ei][0]] + tmp_list
55017
+ master_lh[ei] = [germline_lh[ei][0]].push(...tmp_list);
55018
+ }
55019
+ }
55020
+ }
55021
+ }
55022
+ for( let ei=0; ei < gstat_rd.length; ei++){
55023
+ if(master_lh[ei][0][0] > 2);
55024
+ if(master_lh[ei][0][0] < 2);
55025
+ gstat_rd[ei] / this.globalMean;
55026
+ t_dist.t_test_1_sample(this.globalMean, gstat_rd[ei], gstat_error[ei], gstat_n[ei]);
55027
+ // console.log(etype)
55028
+
55029
+ }
55030
+
55031
+
55032
+ // break
55033
+ }
55034
+
55035
+ }
55036
+
55037
+ var rawbinScore = this.formatDataStructure(this.wigFeatures, 'binScore', this.globalMean);
55038
+ var callScore = this.formatDataStructure(this.wigFeatures, 'segment_score', this.globalMean);
55039
+
55040
+ return {binScore: rawbinScore, segment_score: callScore}
55041
+
54577
55042
  }
54578
55043
 
54579
- histogram(data, bins) {
54580
- const step = bins[1] - bins[0];
54581
- const hist_bins = [];
55044
+ formatDataStructure(wigFeatures, feature_column, scaling_factor = 1) {
55045
+ const results = [];
55046
+ for (const [chr, wig] of Object.entries(wigFeatures)) {
54582
55047
 
54583
- data.forEach((value, index) => {
54584
- bins.forEach((bin_value, bin_index) => {
54585
- if (!hist_bins[bin_value]) {
54586
- hist_bins[bin_value] = { count: 0 };
55048
+ wig.forEach(sample => {
55049
+ var new_sample = { ...sample };
55050
+ if (scaling_factor != 1) {
55051
+ new_sample.value = sample[feature_column] / scaling_factor * 2;
54587
55052
  }
54588
- if (bin_value <= value && value < bin_value + step) {
54589
- hist_bins[bin_value].count++;
54590
- return false;
55053
+ results.push(new_sample);
55054
+ });
55055
+ }
55056
+
55057
+ return results
55058
+ }
55059
+
55060
+ formatDataStructure_BAF(feature_column, scaling_factor = 2) {
55061
+ const baf1 = [];
55062
+ const baf2 = [];
55063
+ for (const [chr, wig] of Object.entries(this.wigFeatures)) {
55064
+
55065
+ wig.forEach(sample => {
55066
+
55067
+ var baf1_value = { ...sample };
55068
+ var baf2_value = { ...sample };
55069
+
55070
+ let value = sample[feature_column];
55071
+ if (value != 0.5){
55072
+ baf2_value.value = -2 * (1 - value);
55073
+ baf2.push(baf2_value);
54591
55074
  }
55075
+ baf1_value.value = -2 * value;
55076
+ baf1.push(baf1_value);
55077
+
54592
55078
  });
54593
- });
54594
- const dist_p = [];
54595
- hist_bins.forEach((bin, index) => { dist_p.push(bin.count); });
54596
- return dist_p
55079
+ }
55080
+
55081
+
55082
+ return [baf1, baf2]
55083
+ }
55084
+ }
55085
+
55086
+ function arrayMax(arr) {
55087
+ return arr.reduce(function (p, v) {
55088
+ return ( p > v ? p : v );
55089
+ });
55090
+ }
55091
+
55092
+ /**
55093
+ * Normal distribution.
55094
+ *
55095
+ * @param {float} x - Variable.
55096
+ * @param {float} a - area
55097
+ * @param {float} x0 - Mean value
55098
+ * @param {float} sigma - Sigma
55099
+ * @returns {float} - Value of distribution in x.
55100
+ */
55101
+ function normal(x, a, x0, sigma){
55102
+
55103
+ return a * Math.exp(-1* (x - x0) ** 2 / (2 * sigma ** 2)) / Math.sqrt(2 * Math.PI) / sigma
55104
+
55105
+ }
55106
+
55107
+ /**
55108
+ * Calculates two normal distributions overlap area.
55109
+ *
55110
+ * @param {float} m1 - Mean value of the first distribution
55111
+ * @param {float} s1 - Sigma of the first distribution
55112
+ * @param {float} m2 - Mean value for second distribution
55113
+ * @param {float} s2 - Sigma of the second distribution
55114
+ *
55115
+ * @returns {float} area - Area of overlap
55116
+ */
55117
+ function normal_overlap_approx(m1, s1, m2, s2){
55118
+
55119
+ return Math.exp(-1* (m1-m2)**2/ (s1**2+s2**2))
55120
+ }
55121
+
55122
+
55123
+ /**
55124
+ * Returns overlap area of two likelihood functions.
55125
+ *
55126
+ * @param {*} lk1 - First likelihood function.
55127
+ * @param {*} lk2 - Second likelihood function.
55128
+ *
55129
+ * @returns {float} - Overlap area.
55130
+ */
55131
+ function likelihood_overlap(likelihood_1, likelihood_2){
55132
+ let sum;
55133
+ try{
55134
+ sum = likelihood_1.reduce((accumulator, currentValue, currentIndex) => {return accumulator + Math.min(currentValue, likelihood_2[currentIndex])});
55135
+ }catch{
55136
+ console.log("Failed to find likelihood overlap: ", likelihood_1, likelihood_2);
55137
+ return 0
55138
+ }
55139
+
55140
+ return sum
55141
+ }
55142
+
55143
+ /**
55144
+ * Calculates normal distribution that is product of two given normal distributions.
55145
+ *
55146
+ * @param {float} m1 - Mean value of the first distribution
55147
+ * @param {float} s1 - Sigma of the first distribution
55148
+ * @param {float} m2 - Mean value for second distribution
55149
+ * @param {float} s2 - Sigma of the second distribution
55150
+ * @returns {Object} An object representing the first distribution
55151
+ * @property {float} nl - Mean value of the first distribution
55152
+ * @property {float} ne - Sigma of the first distribution
55153
+ */
55154
+ function normal_merge(m1, s1, m2, s2){
55155
+
55156
+ if((s1 == 0) && (s2 == 0)){
55157
+ return {nl: 0.5 * (m1 + m2), ne: 0}
54597
55158
  }
55159
+ else {
55160
+ return {nl: (m1 * s2 * s2 + m2 * s1 * s1) / (s1 * s1 + s2 * s2), ne: Math.sqrt(s1 * s1 * s2 * s2 / (s1 * s1 + s2 * s2))}
55161
+ }
55162
+ }
54598
55163
 
55164
+ /**
55165
+ * Calculates likelihood for given baf
55166
+ * @param {*} likelihood
55167
+ * @param {*} baf
55168
+ * @returns {float} likelihood value
55169
+ */
55170
+ function likelihood_of_baf(likelihood, baf){
55171
+
55172
+ let bin = parseInt(baf * (likelihood.length - 1));
55173
+ let fr = baf * (likelihood.length - 1) - bin;
55174
+ if(bin < likelihood.length - 1){
55175
+ return likelihood[bin] * (1 - fr) + likelihood[bin + 1] * fr
55176
+ }
55177
+ else {
55178
+ return likelihood[bin]
55179
+ }
54599
55180
  }
54600
55181
 
55182
+ /**
55183
+ *
55184
+ * Calculates baf level and p-value for given likelihood function.
55185
+ *
55186
+ * @param {*} likelihood
55187
+ * @returns {Object} An object representing BAF
55188
+ * @property {float} mean BAF level (difference from 1/2)
55189
+ * @property {float} p p-value for event different than 1/2
55190
+ */
55191
+ function likelihood_baf_pval(likelihood) {
55192
+ const res = likelihood.length;
55193
+ const max_lh = Math.max(...likelihood);
55194
+ let ix = likelihood.indexOf(max_lh);
55195
+ if (ix > Math.floor(res / 2)) {
55196
+ ix = res - 1 - ix;
55197
+ }
55198
+ const b = (res / 2 - ix) / (res + 1);
55199
+
55200
+ const ix1 = Math.floor((res / 2 + ix) / 2);
55201
+ const ix2 = res - 1 - ix1;
55202
+ let p = likelihood.slice(ix1, ix2 + 1).reduce((acc, val) => acc + val, 0) / likelihood.reduce((acc, val) => acc + val, 0);
55203
+ if (ix === Math.floor(res / 2)) {
55204
+ p = 1.0;
55205
+ }
55206
+ return {mean:b, p:p};
55207
+ }
55208
+
55209
+ var combined_caller = {CombinedCaller};
55210
+
54601
55211
  function erf(x) {
54602
55212
  var m = 1.0, s = 1.0, sum = x * 1.0;
54603
55213
  for (var i = 1; i < 50; i++) {
@@ -55245,6 +55855,10 @@
55245
55855
  }
55246
55856
  }
55247
55857
 
55858
+
55859
+
55860
+ var read_depth_caller = { Partition };
55861
+
55248
55862
  class CNVpytorVCF {
55249
55863
  constructor(allVariants, binSize) {
55250
55864
  this.allVariants = allVariants;
@@ -55372,13 +55986,11 @@
55372
55986
  readDepthMeanshift(wigFeatures) {
55373
55987
 
55374
55988
  // Get global mean and standrad deviation
55375
- var fit_info = new GetFit(wigFeatures);
55989
+ var fit_info = new g_utils.GetFit(wigFeatures);
55376
55990
  var [globamMean, globalStd] = fit_info.fit_data();
55377
- // console.log('Fitter', globamMean, globalStd)
55378
-
55379
55991
 
55380
55992
  // Apply partition method
55381
- var partition = new Partition(wigFeatures, globamMean, globalStd);
55993
+ var partition = new read_depth_caller.Partition(wigFeatures, globamMean, globalStd);
55382
55994
  var partition_array = partition.meanShiftCaller();
55383
55995
  var caller_array = partition.cnv_calling();
55384
55996
 
@@ -55409,86 +56021,10 @@
55409
56021
  results.push(new_sample);
55410
56022
  });
55411
56023
  }
55412
- // console.log(feature_column, results)
55413
56024
 
55414
56025
  return results
55415
56026
  }
55416
56027
 
55417
- // function for baf likelihood calculations
55418
- async computeBAF() {
55419
- const chromosomes = Object.keys(this.allVariants);
55420
- const wigFeatures = {};
55421
- const results = [];
55422
-
55423
- for (let chr of chromosomes) {
55424
- const variants = this.allVariants[chr];
55425
- if (variants.length === 0) continue
55426
- var featureBin;
55427
- for (let snp of variants) {
55428
- featureBin = Math.max(Math.floor(snp.start / this.binSize), 0);
55429
-
55430
- if (!wigFeatures[chr]) {
55431
- wigFeatures[chr] = [];
55432
- }
55433
- if (!wigFeatures[chr][featureBin]) {
55434
- if (featureBin > 0) {
55435
- // calculating the BAF likelihood for previous bin
55436
- let previous_featureBin = featureBin - 1;
55437
- if (wigFeatures[chr][previous_featureBin]) {
55438
-
55439
- const updated_bin = this.get_max_min_score(wigFeatures[chr][previous_featureBin]);
55440
- wigFeatures[chr][previous_featureBin] = updated_bin;
55441
- results.push(wigFeatures[chr][previous_featureBin]);
55442
- }
55443
- }
55444
- wigFeatures[chr][featureBin] = {
55445
- chr,
55446
- start: featureBin * this.binSize,
55447
- end: (featureBin + 1) * this.binSize,
55448
- value: 0,
55449
- count: 0,
55450
- likelihood_score: [],
55451
- min_score: 0,
55452
- };
55453
- }
55454
- const calls = snp.calls[9];
55455
- let genotype = calls.genotype;
55456
- let ad_score = calls.info["AD"].split(',');
55457
- let ad_a = ad_score[0], ad_b = ad_score[1];
55458
-
55459
- if ((genotype[0] == 0 && genotype[1] == 1) || (genotype[0] == 1 && genotype[1] == 0)) {
55460
- //apply the beta function
55461
- if (wigFeatures[chr][featureBin].likelihood_score.length == 0) {
55462
- wigFeatures[chr][featureBin].likelihood_score = linspace(0, 1, 200).map((value, index) => {
55463
- return beta(ad_a, ad_b, value);
55464
- });
55465
- } else {
55466
- var sum = 0;
55467
-
55468
- wigFeatures[chr][featureBin].likelihood_score = linspace(0, 1, 200).map((value, index) => {
55469
- var likelihood_value = wigFeatures[chr][featureBin].likelihood_score[index] * beta(ad_a, ad_b, value);
55470
- sum = sum + likelihood_value;
55471
- return likelihood_value;
55472
- });
55473
-
55474
- wigFeatures[chr][featureBin].likelihood_score = linspace(0, 1, 200).map((value, index) => {
55475
- return wigFeatures[chr][featureBin].likelihood_score[index] / sum;
55476
- });
55477
- }
55478
- wigFeatures[chr][featureBin].count++;
55479
- }
55480
- }
55481
-
55482
- // last feature bin
55483
- const updated_bin = this.get_max_min_score(wigFeatures[chr][featureBin]);
55484
- wigFeatures[chr][featureBin] = updated_bin;
55485
- results.push(wigFeatures[chr][featureBin]);
55486
- }
55487
-
55488
- const baf2_result = this.format_BAF_likelihood(wigFeatures);
55489
- return [results, baf2_result]
55490
-
55491
- }
55492
56028
  async computeBAF_v2() {
55493
56029
 
55494
56030
  const chromosomes = Object.keys(this.allVariants);
@@ -55543,19 +56079,19 @@
55543
56079
  if ((genotype[0] == 0 && genotype[1] == 1) || (genotype[0] == 1 && genotype[1] == 0)) {
55544
56080
  //apply the beta function
55545
56081
  if (wigFeatures[chr][featureBin].likelihood_score.length == 0) {
55546
- wigFeatures[chr][featureBin].likelihood_score = linspace(0, 1, 100).map((value, index) => {
56082
+ wigFeatures[chr][featureBin].likelihood_score = g_utils.linspace(0, 1, 100).map((value, index) => {
55547
56083
  return beta(ad_a, ad_b, value);
55548
56084
  });
55549
56085
  } else {
55550
56086
  var sum = 0;
55551
56087
 
55552
- wigFeatures[chr][featureBin].likelihood_score = linspace(0, 1, 100).map((value, index) => {
56088
+ wigFeatures[chr][featureBin].likelihood_score = g_utils.linspace(0, 1, 100).map((value, index) => {
55553
56089
  var likelihood_value = wigFeatures[chr][featureBin].likelihood_score[index] * beta(ad_a, ad_b, value);
55554
56090
  sum = sum + likelihood_value;
55555
56091
  return likelihood_value;
55556
56092
  });
55557
56093
 
55558
- wigFeatures[chr][featureBin].likelihood_score = linspace(0, 1, 100).map((value, index) => {
56094
+ wigFeatures[chr][featureBin].likelihood_score = g_utils.linspace(0, 1, 100).map((value, index) => {
55559
56095
  return wigFeatures[chr][featureBin].likelihood_score[index] / sum;
55560
56096
  });
55561
56097
  }
@@ -55601,7 +56137,6 @@
55601
56137
  if (sample.likelihood_score.length > 0) {
55602
56138
  const max = Math.max(...sample.likelihood_score);
55603
56139
  const res = sample.likelihood_score.indexOf(max);
55604
- sample.likelihood_score = [];
55605
56140
  sample.value = Math.max(res / 100, 1 - res / 100);
55606
56141
  sample.min_score = Math.min(res / 100, 1 - res / 100);
55607
56142
 
@@ -55617,7 +56152,7 @@
55617
56152
 
55618
56153
  //console.log('getAllbins', bins["value"])
55619
56154
 
55620
- const fitter = new GetFit(bins);
56155
+ const fitter = new g_utils.GetFit(bins);
55621
56156
 
55622
56157
  fitter.fit_data();
55623
56158
  // dconsole.log('rd list', distParams)
@@ -55625,7 +56160,7 @@
55625
56160
  return bins
55626
56161
  }
55627
56162
 
55628
- async read_rd_baf(){
56163
+ async read_rd_baf(caller='ReadDepth'){
55629
56164
 
55630
56165
  const chromosomes = Object.keys(this.allVariants);
55631
56166
  var wigFeatures = {};
@@ -55671,13 +56206,22 @@
55671
56206
  }
55672
56207
 
55673
56208
  }
55674
-
56209
+
55675
56210
  var avgbin = this.adjust_bin_size(wigFeatures);
56211
+ var finalFeatureSet;
56212
+ if(caller == 'ReadDepth'){
56213
+ finalFeatureSet = this.readDepthMeanshift(avgbin);
56214
+ var baf = this.formatDataStructure_BAF(avgbin, 'max_likelihood');
56215
+ }else if(caller=='2D'){
56216
+
56217
+ let caller_obj = new combined_caller.CombinedCaller(avgbin, this.binSize);
56218
+ let processed_bins = await caller_obj.call_2d();
56219
+
56220
+ finalFeatureSet = [processed_bins.binScore, [], processed_bins.segment_score];
56221
+
56222
+ var baf = caller_obj.formatDataStructure_BAF('max_likelihood');
56223
+ }
55676
56224
 
55677
- let finalFeatureSet = this.readDepthMeanshift(avgbin);
55678
-
55679
- //var rawbinScore = this.formatDataStructure(avgbin, 'binScore', globamMean)
55680
- var baf = this.formatDataStructure_BAF(avgbin, 'max_likelihood');
55681
56225
 
55682
56226
  return [finalFeatureSet, baf]
55683
56227
  }
@@ -55740,19 +56284,19 @@
55740
56284
 
55741
56285
  wigFeatures[chr][j].hets.forEach((hets, hets_idx) => {
55742
56286
  if(avgbin[chr][k].likelihood_score.length == 0){
55743
- avgbin[chr][k].likelihood_score = linspace(0, 1, 100).map((value, index) => {
56287
+ avgbin[chr][k].likelihood_score = g_utils.linspace(0, 1, 100).map((value, index) => {
55744
56288
  return beta(hets.ref, hets.alt, value);
55745
56289
  });
55746
56290
  }
55747
56291
  else {
55748
56292
  var likelihood_sum = 0;
55749
- avgbin[chr][k].likelihood_score = linspace(0, 1, 100).map((value, index) => {
56293
+ avgbin[chr][k].likelihood_score = g_utils.linspace(0, 1, 100).map((value, index) => {
55750
56294
  var likelihood_value = avgbin[chr][k].likelihood_score[index] * beta(hets.ref, hets.alt, value);
55751
56295
  likelihood_sum += likelihood_value;
55752
56296
  return likelihood_value;
55753
56297
  });
55754
56298
 
55755
- avgbin[chr][k].likelihood_score = linspace(0, 1, 100).map((value, index) => {
56299
+ avgbin[chr][k].likelihood_score = g_utils.linspace(0, 1, 100).map((value, index) => {
55756
56300
  return avgbin[chr][k].likelihood_score[index] / likelihood_sum;
55757
56301
  });
55758
56302
 
@@ -55777,19 +56321,6 @@
55777
56321
  return p ** a * (1 - p) ** b + p ** b * (1 - p) ** a;
55778
56322
  }
55779
56323
 
55780
- function linspace(a, b, n) {
55781
- if (typeof n === "undefined") n = Math.max(Math.round(b - a) + 1, 1);
55782
- if (n < 2) {
55783
- return n === 1 ? [a] : [];
55784
- }
55785
- var ret = Array(n);
55786
- n--;
55787
- for (let i = n; i >= 0; i--) {
55788
- ret[i] = (i * b + (n - i) * a) / n;
55789
- }
55790
- return ret;
55791
- }
55792
-
55793
56324
  /*
55794
56325
  * The MIT License (MIT)
55795
56326
  *
@@ -55900,29 +56431,43 @@
55900
56431
  }, Object.create(null));
55901
56432
 
55902
56433
  const cnvpytor_obj = new CNVpytorVCF(allVariants, this.bin_size);
55903
- //const wigFeatures = await cnvpytor_obj.computeReadDepth()
55904
- //const bafFeatures = await cnvpytor_obj.computeBAF_v2()
55905
- const dataWigs = await cnvpytor_obj.read_rd_baf();
55906
- const wigFeatures = dataWigs[0];
55907
- const bafFeatures = dataWigs[1];
55908
56434
 
56435
+ let wigFeatures;
56436
+ let bafFeatures;
55909
56437
  this.wigFeatures_obj = {};
55910
- this.wigFeatures_obj[this.bin_size] = {
55911
- "RD_Raw": wigFeatures[0],
55912
- "RD_Raw_gc_coor": wigFeatures[1],
55913
- "ReadDepth": wigFeatures[2],
55914
- "2D": [],
55915
- "BAF1": bafFeatures[0],
55916
- "BAF2": bafFeatures[1]
55917
- };
55918
- this.rd_bins = [this.bin_size];
55919
- this.available_callers = ["ReadDepth"];
56438
+ this.wigFeatures_obj[this.bin_size] = {};
56439
+
56440
+ let dataWigs;
56441
+ if(this.config.cnv_caller == '2D'){
56442
+
56443
+ dataWigs = await cnvpytor_obj.read_rd_baf('2D');
56444
+
56445
+ wigFeatures = dataWigs[0];
56446
+ bafFeatures = dataWigs[1];
56447
+ this.wigFeatures_obj[this.bin_size]['2D'] = wigFeatures[2];
56448
+
56449
+ this.available_callers = ['2D'];
56450
+ }else {
56451
+ dataWigs = await cnvpytor_obj.read_rd_baf();
56452
+ wigFeatures = dataWigs[0];
56453
+ bafFeatures = dataWigs[1];
56454
+ this.wigFeatures_obj[this.bin_size]['ReadDepth'] = wigFeatures[2];
56455
+ this.available_callers = ['ReadDepth'];
56456
+ }
56457
+
56458
+ this.wigFeatures_obj[this.bin_size]['RD_Raw'] = wigFeatures[0];
56459
+ this.wigFeatures_obj[this.bin_size]['RD_Raw_gc_coor'] = wigFeatures[1];
56460
+ this.wigFeatures_obj[this.bin_size]['BAF1'] = bafFeatures[0];
56461
+ this.wigFeatures_obj[this.bin_size]['BAF2'] = bafFeatures[1];
56462
+
56463
+ this.available_bins = [this.bin_size];
56464
+
55920
56465
  this.set_available_callers();
55921
56466
 
55922
56467
  } else {
55923
56468
  this.cnvpytor_obj = new HDF5Reader(this.config.url, this.bin_size);
55924
56469
  this.wigFeatures_obj = await this.cnvpytor_obj.get_rd_signal(this.bin_size);
55925
- this.rd_bins = this.cnvpytor_obj.rd_bins;
56470
+ this.available_bins = this.cnvpytor_obj.available_bins;
55926
56471
  this.available_callers = this.cnvpytor_obj.callers;
55927
56472
  this.set_available_callers();
55928
56473
  }
@@ -56035,7 +56580,7 @@
56035
56580
 
56036
56581
  items.push('<hr/>');
56037
56582
  items.push("Bin Sizes");
56038
- for (let rd_bin of this.rd_bins) {
56583
+ for (let rd_bin of this.available_bins) {
56039
56584
  const checkBox = createCheckbox(rd_bin, rd_bin === this.bin_size);
56040
56585
  items.push({
56041
56586
  object: $$1(checkBox),
@@ -60432,6 +60977,7 @@
60432
60977
 
60433
60978
  updateLocusSearchWidget() {
60434
60979
 
60980
+ if(!this.referenceFrameList) return
60435
60981
  const referenceFrameList = this.referenceFrameList;
60436
60982
 
60437
60983
  // Update end position of reference frames based on pixel widths. This is hacky, but its been done here
@@ -60485,6 +61031,8 @@
60485
61031
 
60486
61032
  async zoomWithScaleFactor(scaleFactor, centerBPOrUndefined, referenceFrameOrUndefined) {
60487
61033
 
61034
+ if(!this.referenceFrameList) return
61035
+
60488
61036
  const viewportWidth = this.calculateViewportWidth(this.referenceFrameList.length);
60489
61037
 
60490
61038
  let referenceFrames = referenceFrameOrUndefined ? [referenceFrameOrUndefined] : this.referenceFrameList;
@@ -60503,6 +61051,8 @@
60503
61051
  */
60504
61052
  async addMultiLocusPanel(chr, start, end, referenceFrameLeft) {
60505
61053
 
61054
+ if(!this.referenceFrameList) return
61055
+
60506
61056
  // account for reduced viewport width as a result of adding right mate pair panel
60507
61057
  const viewportWidth = this.calculateViewportWidth(1 + this.referenceFrameList.length);
60508
61058
  const scaleFactor = this.calculateViewportWidth(this.referenceFrameList.length) / this.calculateViewportWidth(1 + this.referenceFrameList.length);
@@ -61116,6 +61666,8 @@
61116
61666
  */
61117
61667
  async function resize() {
61118
61668
 
61669
+ if(!this.referenceFrameList) return
61670
+
61119
61671
  const viewportWidth = this.calculateViewportWidth(this.referenceFrameList.length);
61120
61672
 
61121
61673
  for (let referenceFrame of this.referenceFrameList) {
@@ -61520,7 +62072,7 @@
61520
62072
 
61521
62073
  function embedCSS() {
61522
62074
 
61523
- 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: 12px;\n height: 12px;\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: 12px;\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: 12px;\n color: rgb(16, 16, 16);\n background-color: white;\n}\n.igv-multi-locus-ruler-label > div {\n cursor: pointer;\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-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: 50%;\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}\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 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 cursor: default;\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-description {\n height: fit-content;\n padding: 4px;\n margin-left: 4px;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: center;\n}\n.igv-roi-table > .igv-roi-table-goto-explainer {\n margin-left: 4px;\n color: #7F7F7F;\n font-style: italic;\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-top-color: #7f7f7f;\n border-top-style: solid;\n border-top-width: thin;\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: left;\n margin-left: 4px;\n height: 24px;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n border-right-color: #7f7f7f;\n border-right-style: solid;\n border-right-width: thin;\n}\n.igv-roi-table > .igv-roi-table-column-titles > div:last-child {\n border-right: unset;\n}\n.igv-roi-table > .igv-roi-table-row-container {\n resize: both;\n overflow: scroll;\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: left;\n margin-left: 4px;\n height: 24px;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n border-right-color: transparent;\n border-right-style: solid;\n border-right-width: thin;\n}\n.igv-roi-table > .igv-roi-table-row-container > .igv-roi-table-row > div:last-child {\n border-right: unset;\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-row-selected {\n background-color: rgba(0, 0, 0, 0.125);\n}\n\n.igv-roi-table-button {\n cursor: pointer;\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 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 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 line-height: 1;\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';
62075
+ 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: 12px;\n height: 12px;\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: 12px;\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: 12px;\n color: rgb(16, 16, 16);\n background-color: white;\n}\n.igv-multi-locus-ruler-label > div {\n cursor: pointer;\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-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: 50%;\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}\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 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 cursor: default;\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-description {\n height: fit-content;\n padding: 4px;\n margin-left: 4px;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n word-break: break-all;\n max-height: 300px;\n overflow-y: auto;\n}\n.igv-roi-table > .igv-roi-table-goto-explainer {\n margin-left: 4px;\n color: #7F7F7F;\n font-style: italic;\n border-top: solid lightgray;\n margin-top: 5px;\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-top-color: #7f7f7f;\n border-top-style: solid;\n border-top-width: thin;\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: left;\n margin-left: 4px;\n height: 24px;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n border-right-color: #7f7f7f;\n border-right-style: solid;\n border-right-width: thin;\n}\n.igv-roi-table > .igv-roi-table-column-titles > div:last-child {\n border-right: unset;\n}\n.igv-roi-table > .igv-roi-table-row-container {\n overflow: scroll;\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: left;\n margin-left: 4px;\n height: 24px;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n border-right-color: transparent;\n border-right-style: solid;\n border-right-width: thin;\n}\n.igv-roi-table > .igv-roi-table-row-container > .igv-roi-table-row > div:last-child {\n border-right: unset;\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 background-color: #eee;\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 cursor: pointer;\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 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 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 line-height: 1;\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';
61524
62076
 
61525
62077
  var style = document.createElement('style');
61526
62078
  style.setAttribute('type', 'text/css');