@jbrowse/plugin-alignments 1.6.5 → 1.6.6

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.
Files changed (34) hide show
  1. package/dist/AlignmentsFeatureDetail/index.d.ts +1 -1
  2. package/dist/BamAdapter/BamSlightlyLazyFeature.d.ts +3 -2
  3. package/dist/BamAdapter/configSchema.d.ts +1 -1
  4. package/dist/CramAdapter/configSchema.d.ts +1 -1
  5. package/dist/HtsgetBamAdapter/configSchema.d.ts +1 -1
  6. package/dist/LinearAlignmentsDisplay/models/configSchema.d.ts +1 -1
  7. package/dist/LinearAlignmentsDisplay/models/model.d.ts +1 -1
  8. package/dist/LinearPileupDisplay/configSchema.d.ts +1 -1
  9. package/dist/LinearSNPCoverageDisplay/components/Tooltip.d.ts +1 -1
  10. package/dist/LinearSNPCoverageDisplay/models/configSchema.d.ts +1 -1
  11. package/dist/PileupRenderer/configSchema.d.ts +1 -1
  12. package/dist/SNPCoverageAdapter/configSchema.d.ts +1 -1
  13. package/dist/SNPCoverageRenderer/SNPCoverageRenderer.d.ts +1 -1
  14. package/dist/SNPCoverageRenderer/configSchema.d.ts +1 -1
  15. package/dist/SNPCoverageRenderer/index.d.ts +1 -1
  16. package/dist/plugin-alignments.cjs.development.js +254 -180
  17. package/dist/plugin-alignments.cjs.development.js.map +1 -1
  18. package/dist/plugin-alignments.cjs.production.min.js +1 -1
  19. package/dist/plugin-alignments.cjs.production.min.js.map +1 -1
  20. package/dist/plugin-alignments.esm.js +254 -180
  21. package/dist/plugin-alignments.esm.js.map +1 -1
  22. package/package.json +4 -4
  23. package/src/AlignmentsFeatureDetail/AlignmentsFeatureDetail.tsx +23 -14
  24. package/src/BamAdapter/BamSlightlyLazyFeature.ts +8 -4
  25. package/src/LinearAlignmentsDisplay/components/AlignmentsDisplay.tsx +38 -30
  26. package/src/LinearAlignmentsDisplay/models/model.tsx +6 -3
  27. package/src/LinearPileupDisplay/model.ts +6 -6
  28. package/src/LinearSNPCoverageDisplay/components/Tooltip.tsx +5 -3
  29. package/src/LinearSNPCoverageDisplay/models/configSchema.ts +4 -5
  30. package/src/PileupRenderer/PileupRenderer.tsx +28 -17
  31. package/src/PileupRenderer/components/PileupRendering.tsx +5 -3
  32. package/src/SNPCoverageAdapter/SNPCoverageAdapter.ts +28 -24
  33. package/src/SNPCoverageRenderer/SNPCoverageRenderer.ts +86 -56
  34. package/src/SNPCoverageRenderer/configSchema.js +1 -1
@@ -21,6 +21,7 @@ import DisplayType from '@jbrowse/core/pluggableElementTypes/DisplayType';
21
21
  import { baseLinearDisplayConfigSchema, linearBasicDisplayConfigSchemaFactory, BaseLinearDisplay, BaseLinearDisplayComponent } from '@jbrowse/plugin-linear-genome-view';
22
22
  import { BaseDisplay, createBaseTrackConfig, createBaseTrackModel } from '@jbrowse/core/pluggableElementTypes/models';
23
23
  import { autorun, when, observable } from 'mobx';
24
+ import { makeStyles, Dialog, DialogTitle, IconButton, DialogContent, Typography as Typography$1, TextField, Button, Link, Paper, FormControlLabel, Checkbox, CircularProgress, FormGroup } from '@material-ui/core';
24
25
  import SerializableFilterChain from '@jbrowse/core/pluggableElementTypes/renderers/util/serializableFilterChain';
25
26
  import { getRpcSessionId, getFileName, makeIndex, makeIndexType } from '@jbrowse/core/util/tracks';
26
27
  import VisibilityIcon from '@material-ui/icons/Visibility';
@@ -38,7 +39,6 @@ import RpcMethodType from '@jbrowse/core/pluggableElementTypes/RpcMethodType';
38
39
  import { IndexedCramFile, CraiIndex } from '@gmod/cram';
39
40
  import { openLocation } from '@jbrowse/core/util/io';
40
41
  import { BamFile, HtsgetFile } from '@gmod/bam';
41
- import { Dialog, DialogTitle, IconButton, DialogContent, Typography as Typography$1, TextField, Button, makeStyles, Link, Paper, FormControlLabel, Checkbox, CircularProgress, FormGroup } from '@material-ui/core';
42
42
  import CloseIcon from '@material-ui/icons/Close';
43
43
  import { FeatureDetails, BaseCard, SimpleValue } from '@jbrowse/core/BaseFeatureWidget/BaseFeatureDetail';
44
44
 
@@ -1941,18 +1941,16 @@ var SNPCoverageAdapter = /*#__PURE__*/function (_BaseFeatureDataAdapt) {
1941
1941
  bins = _yield$_this$generate.bins;
1942
1942
  skipmap = _yield$_this$generate.skipmap;
1943
1943
  bins.forEach(function (bin, index) {
1944
- if (bin.total) {
1945
- observer.next(new SimpleFeature({
1946
- id: "".concat(_this.id, "-").concat(region.start, "-").concat(index),
1947
- data: {
1948
- score: bin.total,
1949
- snpinfo: bin,
1950
- start: region.start + index,
1951
- end: region.start + index + 1,
1952
- refName: region.refName
1953
- }
1954
- }));
1955
- }
1944
+ observer.next(new SimpleFeature({
1945
+ id: "".concat(_this.id, "-").concat(region.start, "-").concat(index),
1946
+ data: {
1947
+ score: bin.total,
1948
+ snpinfo: bin,
1949
+ start: region.start + index,
1950
+ end: region.start + index + 1,
1951
+ refName: region.refName
1952
+ }
1953
+ }));
1956
1954
  }); // make fake features from the coverage
1957
1955
 
1958
1956
  Object.entries(skipmap).forEach(function (_ref2) {
@@ -2118,7 +2116,7 @@ var SNPCoverageAdapter = /*#__PURE__*/function (_BaseFeatureDataAdapt) {
2118
2116
  var fstrand = feature.get('strand');
2119
2117
  var cigarOps = parseCigar(cigar);
2120
2118
 
2121
- for (var j = fstart; j < fend; j++) {
2119
+ for (var j = fstart; j < fend + 1; j++) {
2122
2120
  var i = j - region.start;
2123
2121
 
2124
2122
  if (i >= 0 && i < binMax) {
@@ -2130,8 +2128,12 @@ var SNPCoverageAdapter = /*#__PURE__*/function (_BaseFeatureDataAdapt) {
2130
2128
  noncov: {},
2131
2129
  ref: {}
2132
2130
  };
2133
- bin.total++;
2134
- inc(bin, fstrand, 'ref', 'ref');
2131
+
2132
+ if (j !== fend) {
2133
+ bin.total++;
2134
+ inc(bin, fstrand, 'ref', 'ref');
2135
+ }
2136
+
2135
2137
  bins[i] = bin;
2136
2138
  }
2137
2139
  }
@@ -2164,7 +2166,14 @@ var SNPCoverageAdapter = /*#__PURE__*/function (_BaseFeatureDataAdapt) {
2164
2166
  var epos = pos + fstart - region.start;
2165
2167
 
2166
2168
  if (epos >= 0 && epos < bins.length && pos + fstart < fend) {
2167
- var _bin = bins[epos];
2169
+ var _bin = bins[epos] || {
2170
+ total: 0,
2171
+ lowqual: {},
2172
+ cov: {},
2173
+ delskips: {},
2174
+ noncov: {},
2175
+ ref: {}
2176
+ };
2168
2177
 
2169
2178
  if (probabilities[probIndex] > 0.5) {
2170
2179
  inc(_bin, fstrand, 'cov', mod);
@@ -2253,9 +2262,9 @@ var SNPCoverageAdapter = /*#__PURE__*/function (_BaseFeatureDataAdapt) {
2253
2262
  if (mismatches) {
2254
2263
  for (var _i2 = 0; _i2 < mismatches.length; _i2++) {
2255
2264
  var mismatch = mismatches[_i2];
2256
- var mstart = fstart + mismatch.start;
2265
+ var ms = fstart + mismatch.start;
2257
2266
 
2258
- for (var _j2 = mstart; _j2 < mstart + mismatchLen(mismatch); _j2++) {
2267
+ for (var _j2 = ms; _j2 < ms + mismatchLen(mismatch); _j2++) {
2259
2268
  var epos = _j2 - region.start;
2260
2269
 
2261
2270
  if (epos >= 0 && epos < bins.length) {
@@ -2371,7 +2380,7 @@ var ConfigSchema = /*#__PURE__*/ConfigurationSchema('SNPCoverageRenderer', {
2371
2380
  indicatorThreshold: {
2372
2381
  type: 'number',
2373
2382
  description: 'the proportion of reads containing a insertion/clip indicator',
2374
- defaultValue: 0.3
2383
+ defaultValue: 0.4
2375
2384
  },
2376
2385
  drawArcs: {
2377
2386
  type: 'boolean',
@@ -2412,12 +2421,13 @@ var SNPCoverageRenderer = /*#__PURE__*/function (_WiggleBaseRenderer) {
2412
2421
  regions = props.regions,
2413
2422
  bpPerPx = props.bpPerPx,
2414
2423
  displayCrossHatches = props.displayCrossHatches,
2415
- modificationTagMap = props.modificationTagMap,
2424
+ _props$modificationTa = props.modificationTagMap,
2425
+ modificationTagMap = _props$modificationTa === void 0 ? {} : _props$modificationTa,
2416
2426
  scaleOpts = props.scaleOpts,
2417
2427
  unadjustedHeight = props.height,
2418
2428
  configTheme = props.theme,
2419
2429
  cfg = props.config,
2420
- values = props.ticks.values;
2430
+ ticks = props.ticks;
2421
2431
  var theme = createJBrowseTheme(configTheme);
2422
2432
 
2423
2433
  var _regions = _slicedToArray(regions, 1),
@@ -2429,6 +2439,11 @@ var SNPCoverageRenderer = /*#__PURE__*/function (_WiggleBaseRenderer) {
2429
2439
 
2430
2440
  var offset = YSCALEBAR_LABEL_OFFSET;
2431
2441
  var height = unadjustedHeight - offset * 2;
2442
+ var domain = scaleOpts.domain;
2443
+
2444
+ if (!domain) {
2445
+ return;
2446
+ }
2432
2447
 
2433
2448
  var opts = _objectSpread2(_objectSpread2({}, scaleOpts), {}, {
2434
2449
  range: [0, height]
@@ -2436,6 +2451,12 @@ var SNPCoverageRenderer = /*#__PURE__*/function (_WiggleBaseRenderer) {
2436
2451
 
2437
2452
  var viewScale = getScale(opts);
2438
2453
  var snpViewScale = getScale(_objectSpread2(_objectSpread2({}, opts), {}, {
2454
+ range: [0, height],
2455
+ scaleType: 'linear'
2456
+ })); // clipping and insertion indicators, uses a smaller height/2 scale
2457
+
2458
+ var indicatorViewScale = getScale(_objectSpread2(_objectSpread2({}, opts), {}, {
2459
+ range: [0, height / 2],
2439
2460
  scaleType: 'linear'
2440
2461
  }));
2441
2462
  var originY = getOrigin(scaleOpts.scaleType);
@@ -2458,10 +2479,18 @@ var SNPCoverageRenderer = /*#__PURE__*/function (_WiggleBaseRenderer) {
2458
2479
  return height - (snpViewScale(n) || 0) + offset;
2459
2480
  };
2460
2481
 
2482
+ var indicatorToY = function indicatorToY(n) {
2483
+ return height - (indicatorViewScale(n) || 0) + offset;
2484
+ };
2485
+
2461
2486
  var snpToHeight = function snpToHeight(n) {
2462
2487
  return snpToY(snpOriginY) - snpToY(n);
2463
2488
  };
2464
2489
 
2490
+ var indicatorToHeight = function indicatorToHeight(n) {
2491
+ return indicatorToY(snpOriginY) - indicatorToY(n);
2492
+ };
2493
+
2465
2494
  var colorForBase = {
2466
2495
  A: theme.palette.bases.A.main,
2467
2496
  C: theme.palette.bases.C.main,
@@ -2487,7 +2516,10 @@ var SNPCoverageRenderer = /*#__PURE__*/function (_WiggleBaseRenderer) {
2487
2516
  // bpPerPx First pass: draw the gray background
2488
2517
 
2489
2518
  ctx.fillStyle = colorForBase.total;
2490
- coverage.forEach(function (feature) {
2519
+
2520
+ for (var i = 0; i < coverage.length; i++) {
2521
+ var feature = coverage[i];
2522
+
2491
2523
  var _featureSpanPx = featureSpanPx(feature, region, bpPerPx),
2492
2524
  _featureSpanPx2 = _slicedToArray(_featureSpanPx, 2),
2493
2525
  leftPx = _featureSpanPx2[0],
@@ -2496,96 +2528,97 @@ var SNPCoverageRenderer = /*#__PURE__*/function (_WiggleBaseRenderer) {
2496
2528
  var w = rightPx - leftPx + 0.3;
2497
2529
  var score = feature.get('score');
2498
2530
  ctx.fillRect(leftPx, toY(score), w, toHeight(score));
2499
- });
2500
- ctx.fillStyle = 'grey';
2501
- ctx.beginPath();
2502
- ctx.lineTo(0, 0);
2503
- ctx.moveTo(0, width);
2504
- ctx.stroke(); // Second pass: draw the SNP data, and add a minimum feature width of 1px
2531
+ } // Keep track of previous total which we will use it to draw the interbase
2532
+ // indicator (if there is a sudden clip, there will be no read coverage but
2533
+ // there will be "clip" coverage) at that position beyond the read. if the
2534
+ // clip is right at a block boundary then prevTotal will not be available,
2535
+ // so this is a best attempt to plot interbase indicator at the "cliffs"
2536
+
2537
+
2538
+ var prevTotal = 0; // extraHorizontallyFlippedOffset is used to draw interbase items, which
2539
+ // are located to the left when forward and right when reversed
2540
+
2541
+ var extraHorizontallyFlippedOffset = region.reversed ? 1 / bpPerPx : 0; // Second pass: draw the SNP data, and add a minimum feature width of 1px
2505
2542
  // which can be wider than the actual bpPerPx This reduces overdrawing of
2506
2543
  // the grey background over the SNPs
2507
2544
 
2508
- coverage.forEach(function (feature) {
2509
- var _featureSpanPx3 = featureSpanPx(feature, region, bpPerPx),
2545
+ for (var _i = 0; _i < coverage.length; _i++) {
2546
+ var _feature = coverage[_i];
2547
+
2548
+ var _featureSpanPx3 = featureSpanPx(_feature, region, bpPerPx),
2510
2549
  _featureSpanPx4 = _slicedToArray(_featureSpanPx3, 2),
2511
- leftPx = _featureSpanPx4[0],
2512
- rightPx = _featureSpanPx4[1];
2550
+ _leftPx = _featureSpanPx4[0],
2551
+ _rightPx = _featureSpanPx4[1];
2513
2552
 
2514
- var snpinfo = feature.get('snpinfo');
2515
- var w = Math.max(rightPx - leftPx + 0.3, 1);
2516
- var totalScore = snpinfo.total;
2517
- Object.entries(snpinfo.cov).sort(function (_ref, _ref2) {
2518
- var _ref3 = _slicedToArray(_ref, 1),
2519
- a = _ref3[0];
2553
+ var snpinfo = _feature.get('snpinfo');
2520
2554
 
2521
- var _ref4 = _slicedToArray(_ref2, 1),
2522
- b = _ref4[0];
2555
+ var _w = Math.max(_rightPx - _leftPx + 0.3, 1);
2523
2556
 
2524
- if (a < b) {
2525
- return -1;
2526
- }
2527
-
2528
- if (a > b) {
2529
- return 1;
2530
- }
2557
+ var totalScore = snpinfo.total;
2558
+ var keys = Object.keys(snpinfo.cov).sort();
2559
+ var curr = 0;
2560
+
2561
+ for (var _i2 = 0; _i2 < keys.length; _i2++) {
2562
+ var base = keys[_i2];
2563
+ var total = snpinfo.cov[base].total;
2564
+ ctx.fillStyle = colorForBase[base] || modificationTagMap[base.replace('mod_', '')] || '#888';
2565
+ ctx.fillRect(_leftPx, snpToY(total + curr), _w, snpToHeight(total));
2566
+ curr += total;
2567
+ }
2531
2568
 
2532
- return 0;
2533
- }).reduce(function (curr, _ref5) {
2534
- var _ref6 = _slicedToArray(_ref5, 2),
2535
- base = _ref6[0],
2536
- total = _ref6[1].total;
2537
-
2538
- ctx.fillStyle = colorForBase[base] || modificationTagMap[base.replace('mod_', '')] || 'red';
2539
- ctx.fillRect(leftPx, snpToY(total + curr), w, snpToHeight(total));
2540
- return curr + total;
2541
- }, 0);
2542
- var interbaseEvents = Object.entries(snpinfo.noncov);
2569
+ var interbaseEvents = Object.keys(snpinfo.noncov);
2543
2570
  var indicatorHeight = 4.5;
2544
2571
 
2545
2572
  if (drawInterbaseCounts) {
2546
- interbaseEvents.reduce(function (curr, _ref7) {
2547
- var _ref8 = _slicedToArray(_ref7, 2),
2548
- base = _ref8[0],
2549
- total = _ref8[1].total;
2550
-
2551
- ctx.fillStyle = colorForBase[base];
2552
- ctx.fillRect(leftPx - 0.6, indicatorHeight + snpToHeight(curr), 1.2, snpToHeight(total));
2553
- return curr + total;
2554
- }, 0);
2573
+ var _curr = 0;
2574
+
2575
+ for (var _i3 = 0; _i3 < interbaseEvents.length; _i3++) {
2576
+ var _base = interbaseEvents[_i3];
2577
+ var _total = snpinfo.noncov[_base].total;
2578
+ ctx.fillStyle = colorForBase[_base];
2579
+ ctx.fillRect(_leftPx - 0.6 + extraHorizontallyFlippedOffset, indicatorHeight + indicatorToHeight(_curr), 1.2, indicatorToHeight(_total));
2580
+ _curr += _total;
2581
+ }
2555
2582
  }
2556
2583
 
2557
2584
  if (drawIndicators) {
2558
2585
  var accum = 0;
2559
2586
  var max = 0;
2560
2587
  var maxBase = '';
2561
- interbaseEvents.forEach(function (_ref9) {
2562
- var _ref10 = _slicedToArray(_ref9, 2),
2563
- base = _ref10[0],
2564
- total = _ref10[1].total;
2565
2588
 
2566
- accum += total;
2589
+ for (var _i4 = 0; _i4 < interbaseEvents.length; _i4++) {
2590
+ var _base2 = interbaseEvents[_i4];
2591
+ var _total2 = snpinfo.noncov[_base2].total;
2592
+ accum += _total2;
2567
2593
 
2568
- if (total > max) {
2569
- max = total;
2570
- maxBase = base;
2594
+ if (_total2 > max) {
2595
+ max = _total2;
2596
+ maxBase = _base2;
2571
2597
  }
2572
- }); // avoid drawing a bunch of indicators if coverage is very low e.g.
2573
- // less than 7
2598
+ } // avoid drawing a bunch of indicators if coverage is very low e.g.
2599
+ // less than 7, uses the prev total in the case of the "cliff"
2600
+
2601
+
2602
+ var indicatorComparatorScore = Math.max(totalScore, prevTotal);
2574
2603
 
2575
- if (accum > totalScore * indicatorThreshold && totalScore > 7) {
2604
+ if (accum > indicatorComparatorScore * indicatorThreshold && indicatorComparatorScore > 7) {
2576
2605
  ctx.fillStyle = colorForBase[maxBase];
2577
2606
  ctx.beginPath();
2578
- ctx.moveTo(leftPx - 3, 0);
2579
- ctx.lineTo(leftPx + 3, 0);
2580
- ctx.lineTo(leftPx, indicatorHeight);
2607
+ var l = _leftPx + extraHorizontallyFlippedOffset;
2608
+ ctx.moveTo(l - 3.5, 0);
2609
+ ctx.lineTo(l + 3.5, 0);
2610
+ ctx.lineTo(l, indicatorHeight);
2581
2611
  ctx.fill();
2582
2612
  }
2583
2613
  }
2584
- });
2585
- ctx.globalAlpha = 0.7;
2614
+
2615
+ prevTotal = totalScore;
2616
+ }
2586
2617
 
2587
2618
  if (drawArcs) {
2588
- skips.forEach(function (f) {
2619
+ for (var _i5 = 0; _i5 < skips.length; _i5++) {
2620
+ var f = skips[_i5];
2621
+
2589
2622
  var _bpSpanPx = bpSpanPx(f.get('start'), f.get('end'), region, bpPerPx),
2590
2623
  _bpSpanPx2 = _slicedToArray(_bpSpanPx, 2),
2591
2624
  left = _bpSpanPx2[0],
@@ -2594,9 +2627,9 @@ var SNPCoverageRenderer = /*#__PURE__*/function (_WiggleBaseRenderer) {
2594
2627
  ctx.beginPath();
2595
2628
  var str = f.get('strand');
2596
2629
  var xs = f.get('xs');
2597
- var pos = 'rgb(255,200,200)';
2598
- var neg = 'rgb(200,200,255)';
2599
- var neutral = 'rgb(200,200,200)';
2630
+ var pos = 'rgba(255,200,200,0.7)';
2631
+ var neg = 'rgba(200,200,255,0.7)';
2632
+ var neutral = 'rgba(200,200,200,0.7)';
2600
2633
 
2601
2634
  if (xs === '+') {
2602
2635
  ctx.strokeStyle = pos;
@@ -2614,13 +2647,13 @@ var SNPCoverageRenderer = /*#__PURE__*/function (_WiggleBaseRenderer) {
2614
2647
  ctx.moveTo(left, height - offset * 2);
2615
2648
  ctx.bezierCurveTo(left, 0, right, 0, right, height - offset * 2);
2616
2649
  ctx.stroke();
2617
- });
2650
+ }
2618
2651
  }
2619
2652
 
2620
2653
  if (displayCrossHatches) {
2621
2654
  ctx.lineWidth = 1;
2622
2655
  ctx.strokeStyle = 'rgba(140,140,140,0.8)';
2623
- values.forEach(function (tick) {
2656
+ ticks.values.forEach(function (tick) {
2624
2657
  ctx.beginPath();
2625
2658
  ctx.moveTo(0, Math.round(toY(tick)));
2626
2659
  ctx.lineTo(width, Math.round(toY(tick)));
@@ -3057,9 +3090,11 @@ var PileupRenderer = /*#__PURE__*/function (_BoxRendererType) {
3057
3090
  var modifications = getModificationPositions(mm, seq, strand); // probIndex applies across multiple modifications e.g.
3058
3091
 
3059
3092
  var probIndex = 0;
3060
- modifications.forEach(function (_ref2) {
3061
- var type = _ref2.type,
3062
- positions = _ref2.positions;
3093
+
3094
+ for (var i = 0; i < modifications.length; i++) {
3095
+ var _modifications$i = modifications[i],
3096
+ type = _modifications$i.type,
3097
+ positions = _modifications$i.positions;
3063
3098
  var col = modificationTagMap[type] || 'black';
3064
3099
  var base = Color(col);
3065
3100
 
@@ -3089,7 +3124,7 @@ var PileupRenderer = /*#__PURE__*/function (_BoxRendererType) {
3089
3124
  } finally {
3090
3125
  _iterator.f();
3091
3126
  }
3092
- });
3127
+ }
3093
3128
  } // Color by methylation is slightly modified version of color by
3094
3129
  // modifications
3095
3130
  //
@@ -3116,9 +3151,12 @@ var PileupRenderer = /*#__PURE__*/function (_BoxRendererType) {
3116
3151
  var rstart = region.start,
3117
3152
  rend = region.end;
3118
3153
  var methBins = new Array(rend - rstart).fill(0);
3119
- getModificationPositions(mm, seq, strand).forEach(function (_ref3) {
3120
- var type = _ref3.type,
3121
- positions = _ref3.positions;
3154
+ var modifications = getModificationPositions(mm, seq, strand);
3155
+
3156
+ for (var i = 0; i < modifications.length; i++) {
3157
+ var _modifications$i2 = modifications[i],
3158
+ type = _modifications$i2.type,
3159
+ positions = _modifications$i2.positions;
3122
3160
 
3123
3161
  if (type === 'm' && positions) {
3124
3162
  var _iterator2 = _createForOfIteratorHelper(getNextRefPos(cigarOps, positions)),
@@ -3139,25 +3177,27 @@ var PileupRenderer = /*#__PURE__*/function (_BoxRendererType) {
3139
3177
  _iterator2.f();
3140
3178
  }
3141
3179
  }
3142
- });
3180
+ }
3143
3181
 
3144
3182
  for (var j = fstart; j < fend; j++) {
3145
- var i = j - rstart;
3183
+ var _i = j - rstart;
3184
+
3185
+ if (_i >= 0 && _i < methBins.length) {
3186
+ var l1 = regionSequence[_i].toLowerCase();
3187
+
3188
+ var l2 = regionSequence[_i + 1].toLowerCase(); // if we are zoomed out, display just a block over the cpg
3146
3189
 
3147
- if (i >= 0 && i < methBins.length) {
3148
- var l1 = regionSequence[i].toLowerCase();
3149
- var l2 = regionSequence[i + 1].toLowerCase(); // if we are zoomed out, display just a block over the cpg
3150
3190
 
3151
3191
  if (bpPerPx > 2) {
3152
3192
  if (l1 === 'c' && l2 === 'g') {
3153
- var s = rstart + i;
3193
+ var s = rstart + _i;
3154
3194
 
3155
3195
  var _bpSpanPx7 = bpSpanPx(s, s + 2, region, bpPerPx),
3156
3196
  _bpSpanPx8 = _slicedToArray(_bpSpanPx7, 2),
3157
3197
  leftPx = _bpSpanPx8[0],
3158
3198
  rightPx = _bpSpanPx8[1];
3159
3199
 
3160
- if (methBins[i] || methBins[i + 1]) {
3200
+ if (methBins[_i] || methBins[_i + 1]) {
3161
3201
  ctx.fillStyle = 'red';
3162
3202
  } else {
3163
3203
  ctx.fillStyle = 'blue';
@@ -3169,14 +3209,14 @@ var PileupRenderer = /*#__PURE__*/function (_BoxRendererType) {
3169
3209
  else {
3170
3210
  // color
3171
3211
  if (l1 === 'c' && l2 === 'g') {
3172
- var _s = rstart + i;
3212
+ var _s = rstart + _i;
3173
3213
 
3174
3214
  var _bpSpanPx9 = bpSpanPx(_s, _s + 1, region, bpPerPx),
3175
3215
  _bpSpanPx10 = _slicedToArray(_bpSpanPx9, 2),
3176
3216
  _leftPx = _bpSpanPx10[0],
3177
3217
  _rightPx = _bpSpanPx10[1];
3178
3218
 
3179
- if (methBins[i]) {
3219
+ if (methBins[_i]) {
3180
3220
  ctx.fillStyle = 'red';
3181
3221
  } else {
3182
3222
  ctx.fillStyle = 'blue';
@@ -3189,7 +3229,7 @@ var PileupRenderer = /*#__PURE__*/function (_BoxRendererType) {
3189
3229
  leftPx2 = _bpSpanPx12[0],
3190
3230
  rightPx2 = _bpSpanPx12[1];
3191
3231
 
3192
- if (methBins[i + 1]) {
3232
+ if (methBins[_i + 1]) {
3193
3233
  ctx.fillStyle = 'red';
3194
3234
  } else {
3195
3235
  ctx.fillStyle = 'blue';
@@ -3256,11 +3296,11 @@ var PileupRenderer = /*#__PURE__*/function (_BoxRendererType) {
3256
3296
  _props$colorTagMap = props.colorTagMap,
3257
3297
  colorTagMap = _props$colorTagMap === void 0 ? {} : _props$colorTagMap;
3258
3298
 
3259
- var _ref4 = colorBy || {},
3260
- _ref4$tag = _ref4.tag,
3261
- tag = _ref4$tag === void 0 ? '' : _ref4$tag,
3262
- _ref4$type = _ref4.type,
3263
- colorType = _ref4$type === void 0 ? '' : _ref4$type;
3299
+ var _ref2 = colorBy || {},
3300
+ _ref2$tag = _ref2.tag,
3301
+ tag = _ref2$tag === void 0 ? '' : _ref2$tag,
3302
+ _ref2$type = _ref2.type,
3303
+ colorType = _ref2$type === void 0 ? '' : _ref2$type;
3264
3304
 
3265
3305
  var feature = feat.feature;
3266
3306
  var region = regions[0]; // first pass for simple color changes that change the color of the
@@ -3387,9 +3427,12 @@ var PileupRenderer = /*#__PURE__*/function (_BoxRendererType) {
3387
3427
  }
3388
3428
 
3389
3429
  return color;
3390
- } // two pass rendering: first pass, draw all the mismatches except wide
3391
- // insertion markers
3430
+ } // extraHorizontallyFlippedOffset is used to draw interbase items, which
3431
+ // are located to the left when forward and right when reversed
3432
+
3392
3433
 
3434
+ var extraHorizontallyFlippedOffset = region.reversed ? 1 / bpPerPx + 1 : -1; // two pass rendering: first pass, draw all the mismatches except wide
3435
+ // insertion markers
3393
3436
 
3394
3437
  for (var i = 0; i < mismatches.length; i += 1) {
3395
3438
  var mismatch = mismatches[i];
@@ -3427,32 +3470,36 @@ var PileupRenderer = /*#__PURE__*/function (_BoxRendererType) {
3427
3470
  }
3428
3471
  } else if (mismatch.type === 'insertion' && drawIndels) {
3429
3472
  ctx.fillStyle = 'purple';
3430
- var pos = leftPx - 1;
3473
+ var pos = leftPx + extraHorizontallyFlippedOffset;
3431
3474
  var len = +mismatch.base || mismatch.length;
3475
+ var insW = Math.max(minWidth, Math.min(1.2, 1 / bpPerPx));
3432
3476
 
3433
3477
  if (len < 10) {
3434
- ctx.fillRect(pos, topPx, w, heightPx);
3478
+ ctx.fillRect(pos, topPx, insW, heightPx);
3435
3479
 
3436
3480
  if (1 / bpPerPx >= charWidth) {
3437
- ctx.fillRect(pos - w, topPx, w * 3, 1);
3438
- ctx.fillRect(pos - w, topPx + heightPx - 1, w * 3, 1);
3481
+ ctx.fillRect(pos - insW, topPx, insW * 3, 1);
3482
+ ctx.fillRect(pos - insW, topPx + heightPx - 1, insW * 3, 1);
3439
3483
  }
3440
3484
 
3441
3485
  if (1 / bpPerPx >= charWidth && heightPx >= heightLim) {
3442
- ctx.fillText("(".concat(mismatch.base, ")"), leftPx + 2, topPx + heightPx);
3486
+ ctx.fillText("(".concat(mismatch.base, ")"), pos + 3, topPx + heightPx);
3443
3487
  }
3444
3488
  }
3445
3489
  } else if (mismatch.type === 'hardclip' || mismatch.type === 'softclip') {
3446
3490
  ctx.fillStyle = mismatch.type === 'hardclip' ? 'red' : 'blue';
3447
3491
 
3448
- var _pos = leftPx - 1;
3492
+ var _pos = leftPx + extraHorizontallyFlippedOffset;
3449
3493
 
3450
- ctx.fillRect(_pos, topPx + 1, w, heightPx - 2);
3451
- ctx.fillRect(_pos - w, topPx, w * 3, 1);
3452
- ctx.fillRect(_pos - w, topPx + heightPx - 1, w * 3, 1);
3494
+ ctx.fillRect(_pos, topPx, w, heightPx);
3495
+
3496
+ if (1 / bpPerPx >= charWidth) {
3497
+ ctx.fillRect(_pos - w, topPx, w * 3, 1);
3498
+ ctx.fillRect(_pos - w, topPx + heightPx - 1, w * 3, 1);
3499
+ }
3453
3500
 
3454
3501
  if (widthPx >= charWidth && heightPx >= heightLim) {
3455
- ctx.fillText("(".concat(mismatch.base, ")"), leftPx + 2, topPx + heightPx);
3502
+ ctx.fillText("(".concat(mismatch.base, ")"), _pos + 3, topPx + heightPx);
3456
3503
  }
3457
3504
  } else if (mismatch.type === 'skip') {
3458
3505
  // fix to avoid bad rendering note that this was also related to chrome
@@ -3470,8 +3517,8 @@ var PileupRenderer = /*#__PURE__*/function (_BoxRendererType) {
3470
3517
 
3471
3518
 
3472
3519
  if (drawIndels) {
3473
- for (var _i = 0; _i < mismatches.length; _i += 1) {
3474
- var _mismatch = mismatches[_i];
3520
+ for (var _i2 = 0; _i2 < mismatches.length; _i2 += 1) {
3521
+ var _mismatch = mismatches[_i2];
3475
3522
 
3476
3523
  var _mstart = start + _mismatch.start;
3477
3524
 
@@ -3539,7 +3586,8 @@ var PileupRenderer = /*#__PURE__*/function (_BoxRendererType) {
3539
3586
  return mismatch.type === 'softclip';
3540
3587
  }).forEach(function (mismatch) {
3541
3588
  var softClipLength = mismatch.cliplen || 0;
3542
- var softClipStart = mismatch.start === 0 ? feature.get('start') - softClipLength : feature.get('start') + mismatch.start;
3589
+ var s = feature.get('start');
3590
+ var softClipStart = mismatch.start === 0 ? s - softClipLength : s + mismatch.start;
3543
3591
 
3544
3592
  for (var k = 0; k < softClipLength; k += 1) {
3545
3593
  var base = seq.charAt(k + mismatch.start); // If softclip length+start is longer than sequence, no need to
@@ -3935,10 +3983,15 @@ function PileupRendering(props) {
3935
3983
 
3936
3984
  var offsetX = 0;
3937
3985
  var offsetY = 0;
3986
+ var canvas = highlightOverlayCanvas.current;
3987
+
3988
+ if (canvas) {
3989
+ var _canvas$getBoundingCl = canvas.getBoundingClientRect(),
3990
+ left = _canvas$getBoundingCl.left,
3991
+ top = _canvas$getBoundingCl.top;
3938
3992
 
3939
- if (highlightOverlayCanvas.current) {
3940
- offsetX = highlightOverlayCanvas.current.getBoundingClientRect().left;
3941
- offsetY = highlightOverlayCanvas.current.getBoundingClientRect().top;
3993
+ offsetX = left;
3994
+ offsetY = top;
3942
3995
  }
3943
3996
 
3944
3997
  offsetX = event.clientX - offsetX;
@@ -4322,45 +4375,51 @@ var stateModelFactory = function stateModelFactory(pluginManager, configSchema)
4322
4375
  });
4323
4376
  };
4324
4377
 
4378
+ var useStyles = /*#__PURE__*/makeStyles(function () {
4379
+ return {
4380
+ resizeHandle: {
4381
+ height: 2,
4382
+ position: 'absolute',
4383
+ zIndex: 2
4384
+ }
4385
+ };
4386
+ });
4387
+
4325
4388
  function AlignmentsDisplay(_ref) {
4326
4389
  var model = _ref.model;
4327
4390
  var PileupDisplay = model.PileupDisplay,
4328
4391
  SNPCoverageDisplay = model.SNPCoverageDisplay,
4329
4392
  showPileup = model.showPileup,
4330
4393
  showCoverage = model.showCoverage;
4394
+ var classes = useStyles();
4395
+ var top = SNPCoverageDisplay.height;
4331
4396
  return /*#__PURE__*/React.createElement("div", {
4332
4397
  "data-testid": "display-".concat(getConf(model, 'displayId')),
4333
4398
  style: {
4334
4399
  position: 'relative'
4335
4400
  }
4336
- }, /*#__PURE__*/React.createElement("div", {
4401
+ }, showCoverage ? /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", {
4337
4402
  "data-testid": "Blockset-snpcoverage"
4338
- }, showCoverage ? /*#__PURE__*/React.createElement(SNPCoverageDisplay.RenderingComponent, {
4403
+ }, /*#__PURE__*/React.createElement(SNPCoverageDisplay.RenderingComponent, {
4339
4404
  model: SNPCoverageDisplay
4340
- }) : null), /*#__PURE__*/React.createElement(ResizeHandle, {
4405
+ })), /*#__PURE__*/React.createElement(ResizeHandle, {
4341
4406
  onDrag: function onDrag(delta) {
4342
- if (SNPCoverageDisplay) {
4343
- SNPCoverageDisplay.setHeight(SNPCoverageDisplay.height + delta);
4344
- return delta;
4345
- }
4346
-
4347
- return 0;
4407
+ SNPCoverageDisplay.setHeight(SNPCoverageDisplay.height + delta);
4408
+ return delta;
4348
4409
  },
4410
+ className: classes.resizeHandle,
4349
4411
  style: {
4350
- position: 'absolute',
4351
- top: showCoverage ? SNPCoverageDisplay.height + 2 : 0,
4352
- height: 3
4412
+ top: top
4353
4413
  }
4354
- }), /*#__PURE__*/React.createElement("div", {
4414
+ })) : null, showPileup ? /*#__PURE__*/React.createElement("div", {
4355
4415
  "data-testid": "Blockset-pileup",
4356
4416
  style: {
4357
4417
  position: 'absolute',
4358
- top: showCoverage ? SNPCoverageDisplay.height + 5 : 0,
4359
- height: 3
4418
+ top: showCoverage ? SNPCoverageDisplay.height : 0
4360
4419
  }
4361
- }, showPileup ? /*#__PURE__*/React.createElement(PileupDisplay.RenderingComponent, {
4420
+ }, /*#__PURE__*/React.createElement(PileupDisplay.RenderingComponent, {
4362
4421
  model: PileupDisplay
4363
- }) : null));
4422
+ })) : null);
4364
4423
  }
4365
4424
 
4366
4425
  var ReactComponent$1 = /*#__PURE__*/observer(AlignmentsDisplay);
@@ -4409,10 +4468,10 @@ function SNPCoverageConfigFactory(pluginManager) {
4409
4468
  description: 'draw upside down',
4410
4469
  defaultValue: false
4411
4470
  },
4412
- headroom: {
4413
- type: 'number',
4414
- description: 'round the upper value of the domain scale to the nearest N',
4415
- defaultValue: 0
4471
+ multiTicks: {
4472
+ type: 'boolean',
4473
+ description: 'Display multiple values for the ticks',
4474
+ defaultValue: false
4416
4475
  },
4417
4476
  renderers: ConfigurationSchema('RenderersConfiguration', {
4418
4477
  SNPCoverageRenderer: SNPCoverageRendererConfigSchema
@@ -4432,10 +4491,10 @@ var TooltipContents = /*#__PURE__*/React.forwardRef(function (_ref, ref) {
4432
4491
  var start = feature.get('start');
4433
4492
  var end = feature.get('end');
4434
4493
  var name = feature.get('refName');
4494
+ var info = feature.get('snpinfo');
4435
4495
  var loc = [name, start === end ? en(start) : "".concat(en(start), "..").concat(en(end))].filter(function (f) {
4436
4496
  return !!f;
4437
4497
  }).join(':');
4438
- var info = feature.get('snpinfo');
4439
4498
  var total = info === null || info === void 0 ? void 0 : info.total;
4440
4499
  return /*#__PURE__*/React.createElement("div", {
4441
4500
  ref: ref
@@ -4452,7 +4511,7 @@ var TooltipContents = /*#__PURE__*/React.forwardRef(function (_ref, ref) {
4452
4511
  var strands = score.strands;
4453
4512
  return /*#__PURE__*/React.createElement("tr", {
4454
4513
  key: base
4455
- }, /*#__PURE__*/React.createElement("td", null, base.toUpperCase()), /*#__PURE__*/React.createElement("td", null, score.total), /*#__PURE__*/React.createElement("td", null, base === 'total' || base === 'skip' ? '---' : "".concat(Math.floor(score.total / total * 100), "%")), /*#__PURE__*/React.createElement("td", null, strands['-1'] ? "".concat(strands['-1'], "(-)") : '', strands['1'] ? "".concat(strands['1'], "(+)") : ''), /*#__PURE__*/React.createElement("td", null, key));
4514
+ }, /*#__PURE__*/React.createElement("td", null, base.toUpperCase()), /*#__PURE__*/React.createElement("td", null, score.total), /*#__PURE__*/React.createElement("td", null, base === 'total' || base === 'skip' ? '---' : "".concat(Math.floor(score.total / (total || score.total || 1) * 100), "%")), /*#__PURE__*/React.createElement("td", null, strands['-1'] ? "".concat(strands['-1'], "(-)") : '', strands['1'] ? "".concat(strands['1'], "(+)") : ''), /*#__PURE__*/React.createElement("td", null, key));
4456
4515
  });
4457
4516
  }))));
4458
4517
  });
@@ -6772,6 +6831,7 @@ var BamSlightlyLazyFeature = /*#__PURE__*/function () {
6772
6831
  this.record = record;
6773
6832
  this.adapter = adapter;
6774
6833
  this.ref = ref;
6834
+ this.cachedMD = '';
6775
6835
  }
6776
6836
 
6777
6837
  _createClass(BamSlightlyLazyFeature, [{
@@ -6835,11 +6895,15 @@ var BamSlightlyLazyFeature = /*#__PURE__*/function () {
6835
6895
  }, {
6836
6896
  key: "_get_MD",
6837
6897
  value: function _get_MD() {
6838
- var md = this.record.get('MD');
6839
- var seq = this.get('seq');
6898
+ var md = this.record.get('MD') || this.cachedMD;
6899
+
6900
+ if (!md) {
6901
+ var seq = this.get('seq');
6840
6902
 
6841
- if (!md && seq && this.ref) {
6842
- return generateMD(this.ref, this.record.getReadBases(), this.get('CIGAR'));
6903
+ if (seq && this.ref) {
6904
+ this.cachedMD = generateMD(this.ref, this.get('seq'), this.get('CIGAR'));
6905
+ return this.cachedMD;
6906
+ }
6843
6907
  }
6844
6908
 
6845
6909
  return md;
@@ -7552,7 +7616,7 @@ var HtsgetBamAdapter$1 = {
7552
7616
  'default': HtsgetBamAdapter
7553
7617
  };
7554
7618
 
7555
- var useStyles = /*#__PURE__*/makeStyles(function (theme) {
7619
+ var useStyles$1 = /*#__PURE__*/makeStyles(function (theme) {
7556
7620
  return {
7557
7621
  root: {
7558
7622
  width: 300
@@ -7567,7 +7631,7 @@ var useStyles = /*#__PURE__*/makeStyles(function (theme) {
7567
7631
  });
7568
7632
 
7569
7633
  function ColorByTagDlg$1(props) {
7570
- var classes = useStyles();
7634
+ var classes = useStyles$1();
7571
7635
  var model = props.model,
7572
7636
  handleClose = props.handleClose;
7573
7637
 
@@ -7630,7 +7694,7 @@ var ColorByTag$1 = {
7630
7694
  'default': ColorByTag
7631
7695
  };
7632
7696
 
7633
- var useStyles$1 = /*#__PURE__*/makeStyles(function (theme) {
7697
+ var useStyles$2 = /*#__PURE__*/makeStyles(function (theme) {
7634
7698
  return {
7635
7699
  root: {
7636
7700
  width: 500
@@ -7688,7 +7752,7 @@ function FilterByTagDlg$1(props) {
7688
7752
 
7689
7753
  var model = props.model,
7690
7754
  handleClose = props.handleClose;
7691
- var classes = useStyles$1();
7755
+ var classes = useStyles$2();
7692
7756
  var filterBy = model.filterBy;
7693
7757
 
7694
7758
  var _useState = useState(filterBy === null || filterBy === void 0 ? void 0 : filterBy.flagInclude),
@@ -7809,7 +7873,7 @@ var FilterByTag$1 = {
7809
7873
  'default': FilterByTag
7810
7874
  };
7811
7875
 
7812
- var useStyles$2 = /*#__PURE__*/makeStyles(function (theme) {
7876
+ var useStyles$3 = /*#__PURE__*/makeStyles(function (theme) {
7813
7877
  return {
7814
7878
  root: {
7815
7879
  margin: 0,
@@ -7825,7 +7889,7 @@ var useStyles$2 = /*#__PURE__*/makeStyles(function (theme) {
7825
7889
  });
7826
7890
 
7827
7891
  function SortByTagDlg$1(props) {
7828
- var classes = useStyles$2();
7892
+ var classes = useStyles$3();
7829
7893
  var model = props.model,
7830
7894
  handleClose = props.handleClose;
7831
7895
 
@@ -7875,7 +7939,7 @@ var SortByTag$1 = {
7875
7939
  'default': SortByTag
7876
7940
  };
7877
7941
 
7878
- var useStyles$3 = /*#__PURE__*/makeStyles(function (theme) {
7942
+ var useStyles$4 = /*#__PURE__*/makeStyles(function (theme) {
7879
7943
  return {
7880
7944
  root: {
7881
7945
  margin: theme.spacing(4)
@@ -7890,7 +7954,7 @@ var useStyles$3 = /*#__PURE__*/makeStyles(function (theme) {
7890
7954
  });
7891
7955
 
7892
7956
  function SetFeatureHeightDlg$1(props) {
7893
- var classes = useStyles$3();
7957
+ var classes = useStyles$4();
7894
7958
  var model = props.model,
7895
7959
  handleClose = props.handleClose;
7896
7960
  var featureHeightSetting = model.featureHeightSetting,
@@ -7953,7 +8017,7 @@ var SetFeatureHeight$1 = {
7953
8017
  'default': SetFeatureHeight
7954
8018
  };
7955
8019
 
7956
- var useStyles$4 = /*#__PURE__*/makeStyles(function (theme) {
8020
+ var useStyles$5 = /*#__PURE__*/makeStyles(function (theme) {
7957
8021
  return {
7958
8022
  root: {
7959
8023
  width: 500
@@ -7973,7 +8037,7 @@ var useStyles$4 = /*#__PURE__*/makeStyles(function (theme) {
7973
8037
  function SetMaxHeightDlg$1(props) {
7974
8038
  var model = props.model,
7975
8039
  handleClose = props.handleClose;
7976
- var classes = useStyles$4();
8040
+ var classes = useStyles$5();
7977
8041
  var _model$maxHeight = model.maxHeight,
7978
8042
  maxHeight = _model$maxHeight === void 0 ? '' : _model$maxHeight;
7979
8043
 
@@ -8020,7 +8084,7 @@ var SetMaxHeight$1 = {
8020
8084
  'default': SetMaxHeight
8021
8085
  };
8022
8086
 
8023
- var useStyles$5 = /*#__PURE__*/makeStyles(function (theme) {
8087
+ var useStyles$6 = /*#__PURE__*/makeStyles(function (theme) {
8024
8088
  return {
8025
8089
  root: {},
8026
8090
  closeButton: {
@@ -8041,7 +8105,7 @@ var useStyles$5 = /*#__PURE__*/makeStyles(function (theme) {
8041
8105
 
8042
8106
  function ModificationTable(_ref) {
8043
8107
  var modifications = _ref.modifications;
8044
- var classes = useStyles$5();
8108
+ var classes = useStyles$6();
8045
8109
  return /*#__PURE__*/React.createElement("table", {
8046
8110
  className: classes.table
8047
8111
  }, /*#__PURE__*/React.createElement("tbody", null, modifications.map(function (_ref2) {
@@ -8061,7 +8125,7 @@ function ModificationTable(_ref) {
8061
8125
  }
8062
8126
 
8063
8127
  function ColorByTagDlg$2(props) {
8064
- var classes = useStyles$5();
8128
+ var classes = useStyles$6();
8065
8129
  var model = props.model,
8066
8130
  handleClose = props.handleClose;
8067
8131
  var colorBy = model.colorBy,
@@ -8135,7 +8199,7 @@ var ColorByModifications$1 = {
8135
8199
  'default': ColorByModifications
8136
8200
  };
8137
8201
 
8138
- var useStyles$6 = /*#__PURE__*/makeStyles(function () {
8202
+ var useStyles$7 = /*#__PURE__*/makeStyles(function () {
8139
8203
  return {
8140
8204
  compact: {
8141
8205
  paddingRight: 0,
@@ -8147,7 +8211,7 @@ var useStyles$6 = /*#__PURE__*/makeStyles(function () {
8147
8211
  var omit = ['clipPos', 'flags']; // eslint-disable-next-line @typescript-eslint/no-explicit-any
8148
8212
 
8149
8213
  function AlignmentFlags(props) {
8150
- var classes = useStyles$6();
8214
+ var classes = useStyles$7();
8151
8215
  var feature = props.feature;
8152
8216
  var flags = feature.flags;
8153
8217
  var flagNames = ['read paired', 'read mapped in proper pair', 'read unmapped', 'mate unmapped', 'read reverse strand', 'mate reverse strand', 'first in pair', 'second in pair', 'not primary alignment', 'read fails platform/vendor quality checks', 'read is PCR or optical duplicate', 'supplementary alignment'];
@@ -8249,10 +8313,15 @@ function SupplementaryAlignments(props) {
8249
8313
  onClick: function onClick() {
8250
8314
  var view = model.view;
8251
8315
 
8252
- if (view) {
8253
- view.navToLocString(locString);
8254
- } else {
8255
- session.notify('No view associated with this feature detail panel anymore', 'warning');
8316
+ try {
8317
+ if (view) {
8318
+ view.navToLocString(locString);
8319
+ } else {
8320
+ throw new Error('No view associated with this view anymore');
8321
+ }
8322
+ } catch (e) {
8323
+ console.error(e);
8324
+ session.notify("".concat(e));
8256
8325
  }
8257
8326
  },
8258
8327
  href: "#"
@@ -8269,10 +8338,15 @@ function PairLink(_ref2) {
8269
8338
  onClick: function onClick() {
8270
8339
  var view = model.view;
8271
8340
 
8272
- if (view) {
8273
- view.navToLocString(locString);
8274
- } else {
8275
- session.notify('No view associated with this feature detail panel anymore', 'warning');
8341
+ try {
8342
+ if (view) {
8343
+ view.navToLocString(locString);
8344
+ } else {
8345
+ session.notify('No view associated with this feature detail panel anymore', 'warning');
8346
+ }
8347
+ } catch (e) {
8348
+ console.error(e);
8349
+ session.notify("".concat(e));
8276
8350
  }
8277
8351
  },
8278
8352
  href: "#"