import {
  spliceevent_exonskip_getdefault_default
} from "./chunk-O3JB4PIX.js";
import {
  spliceevent_phrase_default
} from "./chunk-WSDUD52Y.js";
import {
  legend_newrow
} from "./chunk-UJKW42DI.js";
import "./chunk-V2OJLJSK.js";
import "./chunk-VGYTAYFK.js";
import {
  appear2 as appear,
  axisstyle,
  category2legend,
  export_data,
  font,
  gmmode,
  keyupEnter,
  sayerror,
  tkt
} from "./chunk-SA7APTJR.js";
import "./chunk-HJ6L54YS.js";
import "./chunk-LSEFWW72.js";
import "./chunk-SKREEF3H.js";
import {
  Menu
} from "./chunk-HYOEWQ5P.js";
import "./chunk-HBW42TDT.js";
import "./chunk-G6O3URDN.js";
import "./chunk-FN5XPUPH.js";
import "./chunk-IIT367QZ.js";
import "./chunk-RZGEKL77.js";
import "./chunk-UI7OCM2A.js";
import "./chunk-YZK37YCC.js";
import {
  dofetch2,
  dofetch3
} from "./chunk-7EMWHCVW.js";
import "./chunk-7IYJZZQI.js";
import "./chunk-M3J4MINX.js";
import "./chunk-PF4DSFDR.js";
import "./chunk-QH6W3NVF.js";
import "./chunk-NOEAT6CX.js";
import {
  IN_frame,
  OUT_frame,
  bplen,
  defaultcolor,
  spliceeventchangegmexon
} from "./chunk-4UWS5Y3N.js";
import "./chunk-DD4R5P6W.js";
import "./chunk-JNITUVXP.js";
import {
  category10_default
} from "./chunk-KSGA62R2.js";
import {
  axisRight
} from "./chunk-LOZEKOES.js";
import "./chunk-TOU7EVFQ.js";
import {
  linear,
  log,
  ordinal
} from "./chunk-OAWQ6LOO.js";
import "./chunk-TLT4YIG3.js";
import "./chunk-KYBIQBXE.js";
import {
  select_default
} from "./chunk-I6Y4O3RR.js";
import "./chunk-OMR2DT66.js";
import "./chunk-DQC5FFGV.js";
import {
  __commonJS,
  __toESM
} from "./chunk-HFNDKYVF.js";

// ../node_modules/d3-beeswarm/build/d3-beeswarm.js
var require_d3_beeswarm = __commonJS({
  "../node_modules/d3-beeswarm/build/d3-beeswarm.js"(exports, module) {
    (function(global, factory) {
      typeof exports === "object" && typeof module !== "undefined" ? factory(exports) : typeof define === "function" && define.amd ? define(["exports"], factory) : factory(global.d3 = global.d3 || {});
    })(exports, function(exports2) {
      "use strict";
      function beeswarm2() {
        var data = [];
        var radius = 4;
        var orientation = "horizontal";
        var side = "symetric";
        var distributeOn = (
          // accessor to the x value
          function(datum) {
            return datum.x;
          }
        );
        var minDistanceBetweenCircles;
        var minSquareDistanceBetweenCircles;
        var xBasedDataManager;
        var xBasedColliderManager;
        var yBasedColliderManager;
        var arrangement;
        var totalPossibleColliders, maxPossibleColliders, totalTestedPlacements, visitedColliderCount, totalVisitedColliders, maxVisitedColliders;
        function _beeswarm() {
        }
        _beeswarm.data = function(_) {
          if (!arguments.length) {
            return data;
          }
          data = _;
          return _beeswarm;
        };
        _beeswarm.radius = function(_) {
          if (!arguments.length) {
            return radius;
          }
          radius = _;
          return _beeswarm;
        };
        _beeswarm.orientation = function(_) {
          if (!arguments.length) {
            return orientation;
          }
          if (_ === "horizontal" || _ === "vertical") {
            orientation = _;
          }
          return _beeswarm;
        };
        _beeswarm.side = function(_) {
          if (!arguments.length) {
            return side;
          }
          if (_ === "symetric" || _ === "positive" || _ === "negative") {
            side = _;
          }
          return _beeswarm;
        };
        _beeswarm.distributeOn = function(_) {
          if (!arguments.length) {
            return distributeOn;
          }
          distributeOn = _;
          return _beeswarm;
        };
        _beeswarm.arrange = function() {
          initArrangement();
          arrangement.forEach(function(d) {
            var bestYPosition = -Infinity, relativeYPos, xBasedPossibleColliders = gatherXBasedPossibleColliders(d);
            if (xBasedPossibleColliders.length === 0) {
              bestYPosition = 0;
            } else {
              yBasedColliderManager.clear();
              yBasedColliderManager.addMany(xBasedPossibleColliders);
              d.free = 0;
              if (!collidesWithOther(d, yBasedColliderManager.closestTo0())) {
                bestYPosition = 0;
                totalVisitedColliders += visitedColliderCount;
                if (visitedColliderCount > maxVisitedColliders) {
                  maxVisitedColliders = visitedColliderCount;
                }
                visitedColliderCount = 0;
                totalTestedPlacements += 1;
              } else {
                xBasedPossibleColliders.forEach(function(xbpc) {
                  relativeYPos = yPosRelativeToXbpc(xbpc, d);
                  placeBelow(d, xbpc, relativeYPos);
                  if (isAuthorizedPlacement(d) && isBetterPlacement(d, bestYPosition) && !collidesWithOther(d, yBasedColliderManager.dln(xbpc))) {
                    bestYPosition = d.free;
                  }
                  totalVisitedColliders += visitedColliderCount;
                  if (visitedColliderCount > maxVisitedColliders) {
                    maxVisitedColliders = visitedColliderCount;
                  }
                  visitedColliderCount = 0;
                  totalTestedPlacements += 1;
                  placeAbove(d, xbpc, relativeYPos);
                  if (isAuthorizedPlacement(d) && isBetterPlacement(d, bestYPosition) && !collidesWithOther(d, yBasedColliderManager.dln(xbpc))) {
                    bestYPosition = d.free;
                  }
                  totalVisitedColliders += visitedColliderCount;
                  if (visitedColliderCount > maxVisitedColliders) {
                    maxVisitedColliders = visitedColliderCount;
                  }
                  visitedColliderCount = 0;
                  totalTestedPlacements += 1;
                });
              }
            }
            ;
            d.free = bestYPosition;
            if (orientation === "horizontal") {
              d.x = d.fixed;
              d.y = bestYPosition;
            } else {
              d.x = bestYPosition;
              d.y = d.fixed;
            }
            xBasedColliderManager.add(d);
          });
          return arrangement;
        };
        _beeswarm.metrics = function() {
          return {
            totalPossibleColliders,
            maxPossibleColliders,
            totalTestedPlacements,
            visitedColliderCount,
            totalVisitedColliders,
            maxVisitedColliders
          };
        };
        function initArrangement() {
          arrangement = data.map(function(d, i) {
            return {
              datum: d,
              id: i,
              fixed: distributeOn(d),
              free: -Infinity
            };
          });
          minDistanceBetweenCircles = 2 * radius;
          minSquareDistanceBetweenCircles = Math.pow(minDistanceBetweenCircles, 2);
          xBasedDataManager = new SortedDirectAccessDoublyLinkedList().valueAccessor(function(d) {
            return d.fixed;
          }).addMany(arrangement);
          xBasedColliderManager = new SortedDirectAccessDoublyLinkedList().valueAccessor(function(d) {
            return d.fixed;
          });
          yBasedColliderManager = new SortedDirectAccessDoublyLinkedList().valueAccessor(function(d) {
            return d.free;
          });
          totalPossibleColliders = maxPossibleColliders = 0;
          totalTestedPlacements = 0;
          visitedColliderCount = totalVisitedColliders = maxVisitedColliders = 0;
        }
        function findNearestPossibleCollider(dln, visitedDln, direction) {
          if (visitedDln === null) {
            return null;
          } else if (direction === "prev" ? dln.value - visitedDln.value > minDistanceBetweenCircles : visitedDln.value - dln.value > minDistanceBetweenCircles) {
            return null;
          } else {
            if (isFinite(visitedDln.datum.free)) {
              return visitedDln.datum;
            }
            return findNearestPossibleCollider(dln, visitedDln[direction], direction);
          }
        }
        function visitToGatherXBasedPossibleColliders(dln, visitedDln, direction, xBasedPossibleColliders) {
          if (visitedDln === null) {
            return;
          } else if (direction === "prev" ? dln.value - visitedDln.value > minDistanceBetweenCircles : visitedDln.value - dln.value > minDistanceBetweenCircles) {
            return;
          } else {
            xBasedPossibleColliders.push(visitedDln.datum);
            visitToGatherXBasedPossibleColliders(dln, visitedDln[direction], direction, xBasedPossibleColliders);
          }
        }
        function gatherXBasedPossibleColliders(datum) {
          var xBasedPossibleColliders = [];
          var dln = xBasedDataManager.dln(datum);
          var nearestXPrevAlreadyArrangedData = findNearestPossibleCollider(dln, dln.prev, "prev");
          var nearestXNextAlreadyArrangedData = findNearestPossibleCollider(dln, dln.next, "next");
          if (nearestXPrevAlreadyArrangedData != null) {
            dln = xBasedColliderManager.dln(nearestXPrevAlreadyArrangedData);
            visitToGatherXBasedPossibleColliders(dln, dln, "prev", xBasedPossibleColliders);
          }
          if (nearestXNextAlreadyArrangedData != null) {
            dln = xBasedColliderManager.dln(nearestXNextAlreadyArrangedData);
            visitToGatherXBasedPossibleColliders(dln, dln, "next", xBasedPossibleColliders);
          }
          totalPossibleColliders += xBasedPossibleColliders.length;
          if (xBasedPossibleColliders.length > maxPossibleColliders) {
            maxPossibleColliders = xBasedPossibleColliders.length;
          }
          return xBasedPossibleColliders;
        }
        function isAuthorizedPlacement(datum) {
          if (side === "symetric") {
            return true;
          } else if (side === "positive") {
            return datum.free >= 0;
          } else {
            return datum.free <= 0;
          }
        }
        function isBetterPlacement(datum, bestYPosition) {
          return Math.abs(datum.free) < Math.abs(bestYPosition);
        }
        function yPosRelativeToXbpc(xbpc, d) {
          return Math.sqrt(minSquareDistanceBetweenCircles - Math.pow(d.fixed - xbpc.fixed, 2)) + 1e-6;
        }
        function placeBelow(d, aad, relativeYPos) {
          d.free = aad.free - relativeYPos;
        }
        function placeAbove(d, aad, relativeYPos) {
          d.free = aad.free + relativeYPos;
        }
        function areCirclesColliding(d0, d1) {
          visitedColliderCount++;
          return Math.pow(d1.free - d0.free, 2) + Math.pow(d1.fixed - d0.fixed, 2) < minSquareDistanceBetweenCircles;
        }
        function visitToDetectCollisionWithOther(datum, visitedDln, direction, visitCount) {
          if (visitedDln === null) {
            return false;
          } else if (direction === "prev" ? datum.free - visitedDln.datum.free > minDistanceBetweenCircles : visitedDln.datum.free - datum.free > minDistanceBetweenCircles) {
            return false;
          } else if (areCirclesColliding(datum, visitedDln.datum)) {
            return true;
          } else {
            return visitToDetectCollisionWithOther(datum, visitedDln[direction], direction, visitCount++);
          }
        }
        function collidesWithOther(datum, visitedDln) {
          var visitCount = 0;
          if (visitToDetectCollisionWithOther(datum, visitedDln, "prev", visitCount++)) {
            return true;
          } else {
            return visitToDetectCollisionWithOther(datum, visitedDln, "next", visitCount++);
          }
        }
        function SortedDirectAccessDoublyLinkedList() {
          this._valueAccesor = // accessor to the value to sort on
          function(obj) {
            return obj.value;
          };
          this._min = null;
          this._max = null;
          this._closestTo0 = null;
          this.size = 0;
          this._idToNode = {};
        }
        SortedDirectAccessDoublyLinkedList.prototype.valueAccessor = function(_) {
          if (!arguments.length) {
            return this._valueAccesor;
          }
          this._valueAccesor = _;
          return this;
        };
        SortedDirectAccessDoublyLinkedList.prototype.closestTo0 = function() {
          return this._closestTo0;
        };
        SortedDirectAccessDoublyLinkedList.prototype.clear = function() {
          this._min = null;
          this._max = null;
          this._closestTo0 = null;
          this.size = 0;
          this._idToNode = {};
          return this;
        };
        SortedDirectAccessDoublyLinkedList.prototype.dln = function(datum) {
          return this._idToNode[datum.id];
        };
        SortedDirectAccessDoublyLinkedList.prototype.addMany = function(data2) {
          data2.forEach(function(datum, item) {
            this.add(datum);
          }, this);
          return this;
        };
        SortedDirectAccessDoublyLinkedList.prototype.add = function(datum) {
          var dln = {
            datum,
            // original datum
            value: this._valueAccesor(datum),
            prev: null,
            // previous value-based node
            next: null
            // next value-based node
          };
          if (this.size === 0) {
            this._min = this._max = this._closestTo0 = dln;
          } else {
            if (dln.value <= this._min.value) {
              dln.next = this._min;
              dln.next.prev = dln;
              this._min = dln;
            } else if (dln.value >= this._max.value) {
              dln.prev = this._max;
              dln.prev.next = dln;
              this._max = dln;
            } else {
              var current = this._max;
              while (current.value > dln.value) {
                current = current.prev;
              }
              dln.prev = current;
              dln.next = current.next;
              dln.next.prev = dln;
              dln.prev.next = dln;
            }
            if (Math.abs(dln.value) < Math.abs(this._closestTo0.value)) {
              this._closestTo0 = dln;
            }
          }
          this._idToNode[dln.datum.id] = dln;
          this.size++;
          return this;
        };
        SortedDirectAccessDoublyLinkedList.prototype.remove = function(datum) {
          var dln = this.dln(datum);
          if (this.size === 1) {
            this._min = this._max = this._closestTo0 = null;
          } else {
            if (dln === this._closestTo0) {
              if (this._closestTo0.next === null) {
                this._closestTo0 = dln.prev;
              } else if (this.closestToZero.prev === null) {
                this._closestTo0 = dln.prev;
              } else {
                var prevAbsValue = Math.abs(this._closestTo0.prev.value);
                var nextAbsValue = Math.abs(this._closestTo0.next.value);
                if (prevAbsValue < nextAbsValue) {
                  this._closestTo0 = this._closestTo0.prev;
                } else {
                  this._closestTo0 = this._closestTo0.next;
                }
              }
            }
            if (dln === this._min) {
              this._min = this._min.next;
              this._min.prev = null;
            } else if (dln === this._max) {
              this._max = this._max.prev;
              this._max.next = null;
            } else {
              dln.next.prev = dln.prev;
              dln.prev.next = dln.next;
            }
          }
          dln = null;
          delete this._idToNode[datum.id];
          this.size--;
          return this;
        };
        return _beeswarm;
      }
      ;
      exports2.beeswarm = beeswarm2;
      Object.defineProperty(exports2, "__esModule", { value: true });
    });
  }
});

// src/spliceevent.prep.js
function mapjunctiontoexons(junctions, genes) {
  for (const j of junctions) {
    j.exonleft = [];
    j.exonright = [];
    j.exonleftin = [];
    j.exonrightin = [];
    j.intronleft = [];
    j.intronright = [];
    j.leftout = [];
    j.rightout = [];
    j.matchisoform = [];
  }
  const usegenes = [];
  for (const gene of genes) {
    let use = false;
    for (const j of junctions) {
      if (gene.chr == j.chr && Math.max(gene.start, j.start) < Math.min(gene.stop, j.stop)) {
        use = true;
        break;
      }
    }
    if (use) {
      usegenes.push(gene);
    }
  }
  if (usegenes.length == 0) {
    return;
  }
  const leftpos = /* @__PURE__ */ new Map();
  const rightpos = /* @__PURE__ */ new Map();
  for (const j of junctions) {
    if (!leftpos.has(j.start)) {
      leftpos.set(j.start, []);
    }
    leftpos.get(j.start).push(j);
    if (!rightpos.has(j.stop)) {
      rightpos.set(j.stop, []);
    }
    rightpos.get(j.stop).push(j);
  }
  for (const [pos, jlst] of leftpos) {
    for (const gm of usegenes) {
      if (!gm.exon) continue;
      for (let i = 0; i < gm.exon.length; i++) {
        if (gm.exon[i][1] - 1 == pos) {
          for (const j of jlst) {
            j.exonleft.push({
              gm,
              exonidx: i
            });
          }
        }
        if (gm.exon[i][0] <= pos && gm.exon[i][1] - 1 > pos) {
          for (const j of jlst) {
            j.exonleftin.push({
              gm,
              exonidx: i
            });
          }
        }
      }
      if (gm.intron) {
        for (let i = 0; i < gm.intron.length; i++) {
          if (gm.intron[i][0] <= pos && gm.intron[i][1] > pos) {
            for (const j of jlst) {
              j.intronleft.push({
                gm,
                intronidx: i
              });
            }
          }
        }
      }
    }
  }
  for (const [pos, jlst] of rightpos) {
    for (const gm of usegenes) {
      if (!gm.exon) continue;
      for (let i = 0; i < gm.exon.length; i++) {
        if (gm.exon[i][0] == pos) {
          for (const j of jlst) {
            j.exonright.push({
              gm,
              exonidx: i
            });
          }
        }
        if (gm.exon[i][0] < pos && gm.exon[i][1] > pos) {
          for (const j of jlst) {
            j.exonrightin.push({
              gm,
              exonidx: i
            });
          }
        }
      }
      if (gm.intron) {
        for (let i = 0; i < gm.intron.length; i++) {
          if (gm.intron[i][0] <= pos && gm.intron[i][1] > pos) {
            for (const j of jlst) {
              j.intronright.push({
                gm,
                intronidx: i
              });
            }
          }
        }
      }
    }
  }
  for (const j of junctions) {
    {
      const isoforms = /* @__PURE__ */ new Set();
      for (const q of j.exonleft) isoforms.add(q.gm.isoform);
      for (const q of j.exonleftin) isoforms.add(q.gm.isoform);
      for (const q of j.intronleft) isoforms.add(q.gm.isoform);
      if (isoforms.size) {
        for (const gm of usegenes) {
          if (!isoforms.has(gm.isoform)) continue;
          if (gm.stop <= j.stop) {
            j.rightout.push({
              gm
            });
          }
        }
      }
    }
    {
      const isoforms = /* @__PURE__ */ new Set();
      for (const q of j.exonright) isoforms.add(q.gm.isoform);
      for (const q of j.exonrightin) isoforms.add(q.gm.isoform);
      for (const q of j.intronright) isoforms.add(q.gm.isoform);
      if (isoforms.size) {
        for (const gm of usegenes) {
          if (!isoforms.has(gm.isoform)) continue;
          if (gm.start > j.start) {
            j.leftout.push({
              gm
            });
          }
        }
      }
    }
  }
  for (const j of junctions) {
    if (j.exonleft.length == 0 || j.exonright.length == 0) continue;
    for (const el of j.exonleft) {
      for (const er of j.exonright) {
        if (el.gm.isoform == er.gm.isoform) {
          j.matchisoform.push({
            gm: el.gm,
            leftexonidx: el.exonidx,
            rightexonidx: er.exonidx
          });
        }
      }
    }
  }
}

// src/spliceevent.exonskip.js
var exonskipcolor = "#99004d";
var exonaltcolor = "#004d99";
function findexonskipping(multisample, junctions, gmdata) {
  const allevents = [];
  for (const j0 of junctions) {
    if (!j0.matchisoform || j0.matchisoform.length == 0) {
      continue;
    }
    for (const j0isoform of j0.matchisoform) {
      const j0exonbegin = Math.min(j0isoform.leftexonidx, j0isoform.rightexonidx);
      const j0exonend = Math.max(j0isoform.leftexonidx, j0isoform.rightexonidx);
      if (j0exonend - j0exonbegin <= 1) {
        continue;
      }
      const jB = j0;
      const thisevent = {
        skippedexon: [],
        junctionB: jB,
        junctionAlst: []
      };
      for (let i = j0exonbegin + 1; i < j0exonend; i++) {
        thisevent.skippedexon.push(i);
      }
      let gmB = null;
      for (const gm of gmdata) {
        if (!gm.intron) continue;
        for (const i of gm.intron) {
          if (i[0] - 1 == jB.start && i[1] == jB.stop) {
            gmB = gm;
            break;
          }
        }
        if (gmB) {
          break;
        }
      }
      if (gmB) {
        thisevent.isaltexon = true;
        thisevent.color = exonaltcolor;
        thisevent.gmA = j0isoform.gm;
        thisevent.gmB = gmB;
      } else {
        thisevent.isskipexon = true;
        thisevent.color = exonskipcolor;
        thisevent.gm = j0isoform.gm;
        const [utr3, utr5, coding] = checkexoncodingutr(thisevent.skippedexon, thisevent.gm);
        if (utr3) thisevent.utr3 = true;
        if (utr5) thisevent.utr5 = true;
        if (coding) thisevent.coding = true;
      }
      {
        const jAlst = findjunctionAlst(junctions, j0isoform.gm, j0exonbegin, j0exonend);
        for (const ja of jAlst) {
          thisevent.junctionAlst.push(ja);
        }
      }
      if (thisevent.isskipexon) {
        findupdown1junction4exonskip(thisevent, j0isoform.gm, junctions);
      }
      if (multisample) {
        if (!jB.data) {
          console.error("exonskip: jB.data missing when it is multi-sample");
          continue;
        }
        if (jB.data.length == 0) {
          console.error("exonskip: jB.data.length==0");
          continue;
        }
        let percentagesamplesum = 0;
        for (const sampleBdata of jB.data) {
          const bcount = sampleBdata.v;
          let acountsum = 0;
          for (const junctionA of thisevent.junctionAlst) {
            if (!junctionA) {
              continue;
            }
            if (!junctionA.data) {
              console.log("exonskip: jA.data missing when multi-sample");
              continue;
            }
            for (const sampleAdata of junctionA.data) {
              if (sampleAdata.tkid == sampleBdata.tkid) {
                acountsum += sampleAdata.v;
                break;
              }
            }
          }
          percentagesamplesum += 100 * bcount / (bcount + acountsum / thisevent.junctionAlst.length);
        }
        thisevent.percentage = Math.ceil(percentagesamplesum / jB.data.length);
      } else {
        let asum = 0;
        for (const _j of thisevent.junctionAlst) {
          asum += _j ? _j.data[0].v : 0;
        }
        thisevent.percentage = Math.ceil(
          100 * thisevent.junctionB.data[0].v / (thisevent.junctionB.data[0].v + asum / thisevent.junctionAlst.length)
        );
      }
      allevents.push(thisevent);
    }
  }
  const exoncoords = /* @__PURE__ */ new Map();
  for (const evt of allevents) {
    const positionlst = [];
    for (const eid of evt.skippedexon) {
      let thisexon;
      if (evt.isskipexon) {
        thisexon = evt.gm.exon[eid];
      } else {
        thisexon = evt.gmA.exon[eid];
      }
      positionlst.push(thisexon[0]);
      positionlst.push(thisexon[1]);
    }
    if (positionlst.length == 0) {
      console.error("not possible: no skipped exon position for exon-skip");
      console.log(evt);
      continue;
    }
    positionlst.sort();
    const posstr = positionlst.join(".") + "|" + evt.junctionB.start + "." + evt.junctionB.stop;
    if (!exoncoords.has(posstr)) {
      exoncoords.set(posstr, []);
    }
    exoncoords.get(posstr).push(evt);
  }
  const eventsetlst = [];
  for (const eventlst of exoncoords.values()) {
    const thisset = {
      eventlst,
      exonlst: []
      // each exon: {start:, stop:}
    };
    eventsetlst.push(thisset);
    const firstevent = eventlst[0];
    for (const eid of firstevent.skippedexon) {
      const gm = firstevent.isskipexon ? firstevent.gm : firstevent.gmA;
      const thisexon = gm.exon[eid];
      thisset.exonlst.push({
        chr: gm.chr,
        start: thisexon[0],
        stop: thisexon[1]
      });
    }
    let eventcount_skip = 0, eventcount_alt = 0;
    for (const evt of eventlst) {
      if (evt.isskipexon) {
        eventcount_skip++;
      } else {
        eventcount_alt++;
      }
    }
    thisset.color = eventcount_skip > 0 ? exonskipcolor : exonaltcolor;
    const exonnumberset = /* @__PURE__ */ new Set();
    for (const evt of eventlst) {
      const thisexonnumbers = [];
      for (const eid of evt.skippedexon) {
        thisexonnumbers.push(eid + 1);
      }
      exonnumberset.add(thisexonnumbers.join(","));
    }
    if (exonnumberset.size == 1) {
      thisset.toplabelsays = "exon " + [...exonnumberset][0] + " ";
    } else {
      thisset.toplabelsays = "exon ";
    }
    thisset.toplabelsays += eventcount_skip ? "skip" + (eventcount_alt ? "|alt" : "") : "alt";
    if (multisample) {
      let samplecount = 0;
      for (const evt of eventlst) {
        samplecount = Math.max(samplecount, evt.junctionB.data.length);
      }
      thisset.middlelabelsays = samplecount + " sample" + (samplecount > 1 ? "s" : "");
    }
    thisset.bottomlabelsays = firstevent.percentage + "%";
  }
  return eventsetlst;
}
function findjunctionbystartstop(lst, p1, p2) {
  const start = Math.min(p1, p2);
  const stop = Math.max(p1, p2);
  for (const j of lst) {
    if (j.start == start && j.stop == stop) return j;
  }
  return null;
}
function findjunctionAlst(junctions, gm, exonbegin, exonend) {
  const lst = [];
  const exonstart = Math.min(exonbegin, exonend);
  const exonstop = Math.max(exonbegin, exonend);
  if (gm.strand == "+") {
    for (let i = exonstart; i < exonstop; i++) {
      const p1 = gm.exon[i][1] - 1;
      const p2 = gm.exon[i + 1][0];
      lst.push(findjunctionbystartstop(junctions, p1, p2));
    }
  } else {
    for (let i = exonstop; i > exonstart; i--) {
      const p1 = gm.exon[i][1] - 1;
      const p2 = gm.exon[i - 1][0];
      lst.unshift(findjunctionbystartstop(junctions, p1, p2));
    }
  }
  return lst;
}
function findupdown1junction4exonskip(evt, gm, junctions) {
  let exonidx = evt.skippedexon[0];
  if (exonidx > 1) {
    let p1, p2;
    if (gm.strand == "+") {
      p1 = gm.exon[exonidx - 2][1] - 1;
      p2 = gm.exon[exonidx - 1][0];
    } else {
      p1 = gm.exon[exonidx - 1][1] - 1;
      p2 = gm.exon[exonidx - 2][0];
    }
    evt.up1junction = findjunctionbystartstop(junctions, p1, p2);
  }
  exonidx = evt.skippedexon[evt.skippedexon.length - 1];
  if (exonidx < gm.exon.length - 2) {
    let p1, p2;
    if (gm.strand == "+") {
      p1 = gm.exon[exonidx + 1][1] - 1;
      p2 = gm.exon[exonidx + 2][0];
    } else {
      p1 = gm.exon[exonidx + 2][1] - 1;
      p2 = gm.exon[exonidx + 1][0];
    }
    evt.down1junction = findjunctionbystartstop(junctions, p1, p2);
  }
}
function checkexoncodingutr(exonidlst, gm) {
  if (!gm.coding) {
    return [false, false, false];
  }
  let exonstart = gm.exon[exonidlst[0]][0];
  let exonstop = gm.exon[exonidlst[0]][1];
  for (const idx of exonidlst) {
    exonstart = Math.min(gm.exon[idx][0], exonstart);
    exonstop = Math.max(gm.exon[idx][1], exonstop);
  }
  const forward = gm.strand == "+";
  let utr3 = false, utr5 = false, coding = false;
  if (exonstop <= gm.codingstart) {
    if (forward) {
      utr5 = true;
    } else {
      utr3 = true;
    }
  } else if (exonstart >= gm.codingstop) {
    if (forward) {
      utr3 = true;
    } else {
      utr5 = true;
    }
  } else {
    coding = true;
  }
  return [utr3, utr5, coding];
}

// src/block.tk.junction.spliceevent.js
function spliceeventanalyze(tk, block) {
  if (tk.eventsg) {
    tk.eventsg.selectAll("*").remove();
  }
  if (tk.type != tkt.junction) {
    return;
  }
  if (!tk.data) {
    return;
  }
  if (tk.data.length == 0) {
    return;
  }
  const [gmdataerr, gmdata] = getgmdata(block);
  if (gmdataerr) {
    const fontsize = 12;
    const pad = 2;
    tk.eventsg.append("rect").attr("width", block.width).attr("height", pad * 2 + fontsize).attr("fill", "#f1f1f1");
    tk.eventsg.append("text").text(gmdataerr).attr("font-family", font).attr("font-size", fontsize).attr("fill", "#858585").attr("text-anchor", "middle").attr("x", block.width / 2).attr("y", pad + fontsize / 2).attr("dominant-baseline", "central");
    tk.height_main += pad * 2 + fontsize;
    block.block_setheight();
    return;
  }
  if (!gmdata) {
    return;
  }
  for (const junction of tk.data) {
    delete junction.spliceevents;
  }
  mapjunctiontoexons(tk.data, gmdata);
  const allevents = [];
  const exonskipalt = findexonskipping(tk.totalsamplecount > 1, tk.data, gmdata);
  if (exonskipalt.length > 0) {
    for (const exonset of exonskipalt) {
      if (exonlstoutofrange(exonset.exonlst, block)) {
        continue;
      }
      allevents.push(exonset);
      for (const thisevt of exonset.eventlst) {
        if (!thisevt.junctionB.spliceevents) {
          thisevt.junctionB.spliceevents = [];
        }
        thisevt.junctionB.spliceevents.push(thisevt);
      }
    }
  }
  if (allevents.length) {
    rendereventsintrack(allevents, tk, block);
  }
}
function rendereventsintrack(allevents, tk, block) {
  const labelfontsize = 10;
  const stackspace = 1;
  const boxlabelspacing = 2;
  let stackheight;
  if (tk.totalsamplecount > 1) {
    stackheight = labelfontsize * 3 + stackspace * 2;
  } else {
    stackheight = labelfontsize * 2 + stackspace;
  }
  for (const eventset of allevents) {
    eventset.g = tk.eventsg.append("g");
    const junctionB = eventset.eventlst[0].junctionB;
    const jbstr = junctionB.chr + "-" + junctionB.start + "-" + junctionB.stop;
    eventset.toplabel = eventset.g.append("text").text(eventset.toplabelsays).attr("font-size", labelfontsize).attr("font-family", font).attr("fill", eventset.color).attr("y", labelfontsize / 2).attr("dominant-baseline", "central");
    if (tk.totalsamplecount > 1) {
      eventset.middlelabel = eventset.g.append("text").text(eventset.middlelabelsays).attr("font-size", labelfontsize).attr("font-family", font).attr("fill", eventset.color).attr("y", labelfontsize * 1.5).attr("dominant-baseline", "central");
    }
    let willshowframe = false;
    let thiseventframe = null;
    for (const evt of eventset.eventlst) {
      if (evt.isaltexon) {
        evt.framenocheck = true;
        continue;
      }
      if (evt.isskipexon) {
        if (!evt.gm.coding) {
          evt.framenocheck = true;
          continue;
        }
        if (evt.utr3 || evt.utr5) {
          evt.framenocheck = true;
          continue;
        }
      }
      willshowframe = true;
      if (block.genome.junctionframecache.has(jbstr)) {
        let isoform;
        if (evt.isskipexon) {
          isoform = evt.gm.isoform;
        }
        const thisframe = block.genome.junctionframecache.get(jbstr).get(isoform);
        if (thisframe == void 0) {
        } else {
          evt.frame = thisframe;
          if (thiseventframe == null) {
            thiseventframe = thisframe;
          } else {
            if (thisframe == IN_frame) {
              thiseventframe = IN_frame;
            }
          }
        }
      } else {
      }
    }
    eventset.bottomlabel = eventset.g.append("text").text(
      eventset.bottomlabelsays + (willshowframe ? ", " + (thiseventframe == null ? "checking" : thiseventframe == IN_frame ? "IN" : "OUT") : "")
    ).attr("font-size", labelfontsize).attr("font-family", font).attr("fill", eventset.color).attr("y", stackheight - labelfontsize / 2).attr("dominant-baseline", "central");
    if (willshowframe && thiseventframe == null) {
      for (const evt of eventset.eventlst) {
        let gm;
        if (evt.isaltexon) {
          gm = evt.gmB;
        } else if (evt.isskipexon) {
          gm = evt.gm;
        }
        if (!block.genome.junctionframecache.has(jbstr)) {
          checkjunctionframe({
            jbstr,
            evt,
            gm,
            block,
            eventset
          });
          continue;
        }
        if (!block.genome.junctionframecache.get(jbstr).has(gm.isoform)) {
          checkjunctionframe({
            jbstr,
            evt,
            gm,
            block,
            eventset
          });
        }
      }
    }
    const exonobjlst = [];
    let boxstart = null, boxstop;
    for (const exon of eventset.exonlst) {
      const pointa = block.seekcoord(exon.chr, exon.start)[0];
      if (!pointa) {
        console.log("skipped exon start position not mapped: " + exon.start);
        return;
      }
      const pointb = block.seekcoord(exon.chr, exon.stop - 1)[0];
      if (!pointb) {
        console.log("skipped exon stop position not mapped: " + exon.stop);
        return;
      }
      const exonobj = {
        x: Math.min(pointa.x, pointb.x),
        w: Math.max(1, Math.abs(pointa.x - pointb.x))
      };
      exonobj.rect = eventset.g.append("rect").attr("fill", eventset.color).attr("width", exonobj.w).attr("height", stackheight).attr("shape-rendering", "crispEdges").on("click", () => {
        console.log(eventset);
      });
      if (boxstart == null) {
        boxstart = exonobj.x;
        boxstop = exonobj.x + exonobj.w;
      } else {
        boxstart = Math.min(boxstart, exonobj.x);
        boxstop = Math.max(boxstop, exonobj.x + exonobj.w);
      }
      exonobjlst.push(exonobj);
    }
    for (const exon of exonobjlst) {
      exon.rect.attr("x", exon.x - boxstart);
    }
    eventset.boxstart = boxstart;
    eventset.boxwidth = boxstop - boxstart;
    if (eventset.exonlst.length > 1) {
      eventset.g.append("line").attr("stroke", eventset.color).attr("stroke-opacity", 0.2).attr("stroke-width", 2).attr("shape-rendering", "crispEdges").attr("x1", 0).attr("x2", eventset.boxwidth).attr("y1", stackheight / 2 - 0.5).attr("y2", stackheight / 2 - 0.5);
    }
    eventset.toplabel.each(function() {
      eventset.labelwidth = this.getBBox().width;
    });
    if (eventset.middlelabel) {
      eventset.middlelabel.each(function() {
        eventset.labelwidth = this.getBBox().width;
      });
    }
    eventset.bottomlabel.each(function() {
      eventset.labelwidth = Math.max(eventset.labelwidth, this.getBBox().width);
    });
    if (eventset.labelwidth > eventset.boxstart) {
      eventset.labelonright = true;
      eventset.toplabel.attr("x", eventset.boxwidth + boxlabelspacing);
      eventset.bottomlabel.attr("x", eventset.boxwidth + boxlabelspacing);
      if (eventset.middlelabel) {
        eventset.middlelabel.attr("x", eventset.boxwidth + boxlabelspacing);
      }
    } else {
      eventset.toplabel.attr("text-anchor", "end").attr("x", -boxlabelspacing);
      eventset.bottomlabel.attr("text-anchor", "end").attr("x", -boxlabelspacing);
      if (eventset.middlelabel) {
        eventset.middlelabel.attr("text-anchor", "end").attr("x", -boxlabelspacing);
      }
    }
    eventset.cover = eventset.g.append("rect").attr("x", eventset.labelonright ? 0 : -eventset.labelwidth - boxlabelspacing).attr("width", eventset.labelwidth + boxlabelspacing + eventset.boxwidth).attr("height", stackheight).attr("fill", "#858585").attr("fill-opacity", 0).on("mouseover", () => {
      eventset.cover.attr("fill-opacity", 0.1);
    }).on("mouseout", () => {
      eventset.cover.attr("fill-opacity", 0);
    }).on("click", () => {
      tk.tktip.clear();
      displayspliceevents(eventset.eventlst, tk.tktip.d);
      tk.tktip.showunder(eventset.cover.node());
    });
  }
  const stacks = [0];
  for (const eventset of allevents) {
    let x1 = eventset.boxstart - (eventset.labelonright ? 0 : boxlabelspacing + eventset.labelwidth);
    let x2 = eventset.boxstart + eventset.boxwidth + (eventset.labelonright ? boxlabelspacing + eventset.labelwidth : 0);
    for (let stackidx = 0; stackidx < stacks.length; stackidx++) {
      if (x1 > stacks[stackidx]) {
        eventset.stackidx = stackidx;
        stacks[stackidx] = x2;
        break;
      }
      if (!eventset.labelonright) {
        const newx1 = eventset.boxstart;
        const newx2 = eventset.boxstart + eventset.boxwidth + boxlabelspacing + eventset.labelwidth;
        if (newx1 > stacks[stackidx] && newx2 <= block.width) {
          eventset.labelonright = true;
          eventset.stackidx = stackidx;
          stacks[stackidx] = newx2;
          eventset.toplabel.attr("x", eventset.boxwidth + boxlabelspacing).attr("text-anchor", "start");
          eventset.bottomlabel.attr("x", eventset.boxwidth + boxlabelspacing).attr("text-anchor", "start");
          if (eventset.middlelabel) {
            eventset.middlelabel.attr("x", eventset.boxwidth + boxlabelspacing).attr("text-anchor", "start");
          }
          eventset.cover.attr("x", 0);
          break;
        }
      }
    }
    if (eventset.stackidx == void 0) {
      eventset.stackidx = stacks.length;
      stacks.push(x2);
    }
    eventset.g.attr(
      "transform",
      "translate(" + eventset.boxstart + "," + eventset.stackidx * (stackheight + stackspace) + ")"
    );
  }
  tk.height_main += stacks.length * (stackheight + stackspace) + tk.bottompad;
  block.block_setheight();
}
function checkjunctionframe(arg) {
  if (!arg.block.genome.junctionframecache.has(arg.jbstr)) {
    arg.block.genome.junctionframecache.set(arg.jbstr, /* @__PURE__ */ new Map());
  }
  if (!arg.gm.coding) {
    arg.block.genome.junctionframecache.get(arg.jbstr).set(arg.gm.isoform, false);
    mayupdateeventsetlabel(arg);
    return;
  }
  const gm2 = spliceeventchangegmexon(arg.gm, arg.evt);
  dofetch2("translategm", { method: "POST", body: JSON.stringify({ genome: arg.block.genome.name, gm: gm2 }) }).then((data) => {
    if (!data) {
      console.log("server error");
      return;
    }
    if (data.error) {
      console.log(data.error);
      return;
    }
    if (typeof data.frame != "boolean") {
      console.log("invalid result from translategm: " + data.frame);
      return;
    }
    arg.evt.frame = data.frame;
    arg.block.genome.junctionframecache.get(arg.jbstr).set(arg.gm.isoform, data.frame);
    mayupdateeventsetlabel(arg);
  });
}
function mayupdateeventsetlabel(arg) {
  if (!arg.block.genome.junctionframecache.has(arg.jbstr)) {
    return;
  }
  let frame = OUT_frame;
  for (const evt of arg.eventset.eventlst) {
    if (evt.framenocheck) {
      continue;
    }
    let isoform;
    if (evt.isskipexon) {
      isoform = evt.gm.isoform;
    }
    const thisframe = arg.block.genome.junctionframecache.get(arg.jbstr).get(isoform);
    if (thisframe == void 0) {
      return;
    }
    if (thisframe == IN_frame) {
      frame = IN_frame;
    }
  }
  arg.eventset.bottomlabel.text(arg.eventset.bottomlabelsays + ", " + (frame == IN_frame ? "IN" : "OUT"));
}
function displayspliceevents(events, holder) {
  const evt2showidx = spliceevent_exonskip_getdefault_default(events);
  if (events.length > 1) {
    holder.append("div").style("margin", "3px 0px").style("color", "#858585").text("Additional interpretations:");
    const name = Math.random().toString();
    for (const [idx, evt] of events.entries()) {
      const id = name + idx;
      const row = holder.append("div").style("margin-top", "3px");
      row.append("input").attr("type", "radio").property("checked", idx == evt2showidx).attr("name", name).attr("id", id).on("change", () => {
        displayspliceevents_show(events, idx, showdiv);
      });
      row.append("label").attr("for", id).html("&nbsp;" + spliceevent_phrase_default(evt));
    }
  }
  const showdiv = holder.append("div");
  displayspliceevents_show(events, evt2showidx, showdiv);
}
function displayspliceevents_show(events, idx, div) {
  div.selectAll("*").remove();
  import("./spliceevent.exonskip.diagram-LAOIOIST.js").then((p) => {
    p.default({
      event: events[idx],
      holder: div,
      nophrase: events.length > 1
    });
  });
}
function exonlstoutofrange(lst, block) {
  const chr = lst[0].chr;
  let start = lst[0].start;
  let stop = lst[0].stop;
  for (const e of lst) {
    start = Math.min(start, e.start);
    stop = Math.max(stop, e.stop);
  }
  const starthit = block.seekcoord(chr, start)[0];
  const stophit = block.seekcoord(chr, stop)[0];
  if (!starthit || !stophit) {
    return true;
  }
  let startoutleft = false;
  let startoutright = false;
  if (starthit.x <= 0) {
    startoutleft = true;
  } else if (starthit.x >= block.width) {
    startoutright = true;
  }
  let stopoutleft = false;
  let stopoutright = false;
  if (stophit.x <= 0) {
    stopoutleft = true;
  } else if (stophit.x >= block.width) {
    stopoutright = true;
  }
  if (startoutleft && stopoutleft) return true;
  if (startoutright && stopoutright) return true;
  return false;
}
function getgmdata(block) {
  if (!block.gmmode || block.gmmode == gmmode.genomic) {
    const genetk = [];
    for (const t of block.tklst) {
      if (t.__isgene) {
        genetk.push(t);
      }
    }
    if (genetk.length == 0) {
      return ["Add a gene track to analyze splice junctions."];
    }
    const gmdatalst = [];
    for (const t of genetk) {
      if (t.gmdata) {
        for (const m of t.gmdata) {
          gmdatalst.push(m);
        }
      }
    }
    if (gmdatalst.length == 0) {
      return [null];
    }
    const regions = [];
    for (const m of gmdatalst) {
      let overlap = false;
      for (const r of regions) {
        if (Math.max(r.start, m.start) < Math.min(r.stop, m.stop)) {
          overlap = true;
          r.start = Math.min(r.start, m.start);
          r.stop = Math.max(r.stop, m.stop);
          break;
        }
      }
      if (!overlap) {
        regions.push({ start: m.start, stop: m.stop });
      }
    }
    if (regions.length >= 3) {
      return ["Zoom in on a single gene to analyze splice junctions."];
    }
    return [null, gmdatalst];
  }
  if (block.gmmode == gmmode.gmsum) {
    if (!block.allgm) {
      return ["Error: block.allgm[] is missing"];
    }
    return [null, block.allgm];
  }
  if (!block.usegm) {
    return ["Error: block.usegm is missing"];
  }
  return [null, [block.usegm]];
}

// src/block.tk.junction.renderjunctions.js
var import_d3_beeswarm = __toESM(require_d3_beeswarm(), 1);
var colorfunc = ordinal(category10_default);
var minfontsize = 12;
function rendertk(junctions, tk, block) {
  if (tk.data) {
    const map = /* @__PURE__ */ new Map();
    for (const j of tk.data) {
      map.set(j.chr + "." + j.start + "." + j.stop, j);
    }
    const pannedpx = Number.isInteger(block.pannedpx) ? block.pannedpx : 0;
    for (const i of junctions) {
      const j = map.get(i.chr + "." + i.start + "." + i.stop);
      if (j) {
        i.x = j.x + pannedpx;
        i.mode = j.mode;
        i.modefix = j.modefix;
        if (i.mode == modesample) {
          i.mode = moderaise;
        }
      }
    }
  }
  tk.data = junctions;
  tk.glider.selectAll("*").remove();
  tk.leftaxis.selectAll("*").remove();
  if (tk.readcountcutoff) {
    const newj = [];
    for (const j of tk.data) {
      if (j.data) {
        const newsamples = [];
        for (const s of j.data) {
          if (s.v >= tk.readcountcutoff) {
            newsamples.push(s);
          }
        }
        if (newsamples.length == 0) {
          continue;
        }
        j.data = newsamples;
        newj.push(j);
      } else {
        if (j.v >= tk.readcountcutoff) {
          newj.push(j);
        }
      }
    }
    tk.data = newj;
  }
  if (tk.data.length == 0) {
    tk.height_main = 50;
    block.tkcloakoff(tk, { error: tk.name + ": No junction in view range" });
    tk.label_mcount.text("");
    if (tk.label_samplecount) {
      tk.label_samplecount.text("");
    }
    get_leftLabelMaxwidth(tk);
    block.setllabel();
    block.block_setheight();
    return;
  }
  tk.label_mcount.text(tk.data.length + " junction" + (tk.data.length > 1 ? "s" : ""));
  get_leftLabelMaxwidth(tk);
  block.setllabel();
  junctiontype2color(tk, block);
  const mg = tk.glider.append("g");
  tk.data.sort((a, b) => {
    return a._x - b._x;
  });
  let maxsamplecount = 0;
  if (tk.totalsamplecount > 1) {
    maxsamplecount = tk.data.reduce((max, j) => Math.max(max, j.data.length), 0);
    const radius = 5;
    let mrd = 0;
    const w = Math.pow(radius, 2) * Math.PI;
    if (maxsamplecount <= 10) {
      mrd = w * maxsamplecount * 0.9;
    } else if (maxsamplecount <= 100) {
      mrd = w * 10;
    } else if (maxsamplecount <= 1e3) {
      mrd = w * 14;
    } else {
      mrd = w * 20;
    }
    const sf_discradius = linear().domain([
      1,
      maxsamplecount * 0.5 + 0.1,
      maxsamplecount * 0.6 + 0.1,
      maxsamplecount * 0.7 + 0.1,
      maxsamplecount * 0.8 + 0.1,
      maxsamplecount
    ]).range([w, w + (mrd - w) * 0.8, w + (mrd - w) * 0.85, w + (mrd - w) * 0.9, w + (mrd - w) * 0.95, mrd]);
    let maxradius = 0;
    for (const j of tk.data) {
      j.radius = Math.sqrt(sf_discradius(j.data.length) / Math.PI);
      if (j.data.length > 1) {
        mg.append("text").attr("font-family", font).attr("font-size", Math.max(minfontsize, j.radius)).text(j.data.length).each(function() {
          const b = this.getBBox();
          const newrad = Math.sqrt(Math.pow(b.width, 2) + Math.pow(b.height, 2)) / 2;
          j.radius = Math.max(j.radius, newrad);
        }).remove();
      }
      j.rimwidth = j.rimcount ? Math.max(2, j.radius / 6) : 0;
      j.radius2 = j.radius + j.rimwidth + (j.rimwidth > 0 ? 1 : 0);
      maxradius = Math.max(maxradius, j.radius2);
    }
    tk.maxradius = maxradius;
  } else {
    maxsamplecount = tk.data.reduce((max, j) => Math.max(max, j.data[0].v), 0);
    const radius = 5;
    let mrd = 0;
    const w = Math.pow(radius, 2) * Math.PI;
    if (maxsamplecount <= 10) {
      mrd = w * maxsamplecount * 0.9;
    } else if (maxsamplecount <= 100) {
      mrd = w * 5;
    } else if (maxsamplecount <= 1e3) {
      mrd = w * 7;
    } else {
      mrd = w * 10;
    }
    const sf_discradius = linear().domain([
      1,
      maxsamplecount * 0.5 + 0.1,
      maxsamplecount * 0.6 + 0.1,
      maxsamplecount * 0.7 + 0.1,
      maxsamplecount * 0.8 + 0.1,
      maxsamplecount
    ]).range([w, w + (mrd - w) * 0.8, w + (mrd - w) * 0.85, w + (mrd - w) * 0.9, w + (mrd - w) * 0.95, mrd]);
    let maxradius = 0;
    for (const j of tk.data) {
      j.radius = Math.sqrt(sf_discradius(j.data[0].v) / Math.PI);
      j.rimwidth = j.rimcount ? Math.max(2, j.radius / 6) : 0;
      j.radius2 = j.radius + j.rimwidth + (j.rimwidth > 0 ? 1 : 0);
      maxradius = Math.max(maxradius, j.radius2);
    }
    tk.maxradius = maxradius;
  }
  let maxread = 0, maxmedian = 0, maxmedianradius = 0;
  for (const j of tk.data) {
    for (const s of j.data) {
      maxread = Math.max(s.v, maxread);
    }
    if (j.data.length == 1) {
      j.median = j.data[0].v;
    } else {
      const readlst = j.data.map((s) => s.v);
      readlst.sort((a, b) => a - b);
      j.median = readlst[Math.floor(j.data.length / 2)];
    }
    if (j.median > maxmedian) {
      maxmedian = j.median;
      maxmedianradius = j.radius;
    }
  }
  tk.yscale = log().domain([tk.readcountcutoff || 1, maxread]).range([tk.axisheight, 0]);
  axisstyle({
    axis: tk.leftaxis.call(axisRight().scale(tk.yscale).ticks(6, ".0f")),
    color: "black",
    showline: true
  });
  tk.height_main = tk.toppad + tk.axisheight + tk.maxradius * 4 + tk.padheight + tk.lowpad + tk.legheight + tk.bottompad;
  tk.eventsg = tk.glider.append("g").attr("transform", "translate(0," + (tk.height_main - tk.toppad) + ")");
  automode(tk, null, block.width);
  mg.attr("transform", "translate(0," + (tk.height_main - tk.toppad - tk.bottompad) + ")");
  {
    const topy = -tk.legheight - tk.lowpad - tk.maxradius * 4 - tk.padheight - tk.axisheight;
    mg.append("line").attr("x1", 0).attr("y1", topy).attr("y2", topy).attr("x2", block.width).attr("stroke", "#858585").attr("stroke-opacity", 0.2).attr("shape-rendering", "crispEdges");
    mg.append("line").attr("x1", 0).attr("y1", topy + tk.axisheight).attr("y2", topy + tk.axisheight).attr("x2", block.width).attr("stroke", "#858585").attr("stroke-opacity", 0.2).attr("shape-rendering", "crispEdges");
    let v = 10;
    while (v <= maxread) {
      mg.append("line").attr("x1", 0).attr("y1", topy + tk.yscale(v)).attr("y2", topy + tk.yscale(v)).attr("x2", block.width).attr("stroke", "#858585").attr("stroke-opacity", 0.2).attr("stroke-dasharray", "4,4").attr("shape-rendering", "crispEdges");
      v *= 10;
    }
  }
  const jug = mg.selectAll().data(tk.data).enter().append("g").attr("transform", (d) => set_jug(d)).each(function(j) {
    j.jugg = this;
  });
  tk.jug = jug;
  if (tk.hljunctions) {
    jug.attr("class", (d) => {
      for (const j of tk.hljunctions) {
        if (d.chr == j.chr && d.start == j.start && d.stop == j.stop) {
          return "sja_pulse";
        }
      }
      return null;
    });
  }
  jug.append("line").attr("stroke", (d) => d.color).attr("x1", (d) => set_leg_x1(d)).attr("y2", (d) => set_leg_y(d, tk)).attr("stroke-opacity", (d) => set_lineopacity(d)).each(function(d) {
    d.leg1 = this;
  }).classed("sja_jug_leg1", true);
  jug.append("line").attr("stroke", (d) => d.color).attr("x2", (d) => set_leg_x2(d)).attr("y1", (d) => set_leg_y(d, tk)).attr("stroke-opacity", (d) => set_lineopacity(d)).classed("sja_jug_leg2", true).each(function(d) {
    d.leg2 = this;
  });
  const jug2 = jug.append("g").attr("class", "sja_jug_jug2").attr("transform", (d) => set_jug2(d, tk));
  jug2.append("line").attr("stroke", (d) => d.color).classed("sja_jug_stem", true).attr("stroke-dasharray", "2,2").attr("shape-rendering", "crispEdges").attr("y1", (d) => set_stem_y1(d)).attr("y2", (d) => set_stem_y2(d, tk)).attr("stroke-opacity", (d) => set_lineopacity(d)).each(function(d) {
    d.stem = this;
  });
  jug2.append("circle").attr("r", (d) => d.radius).attr("fill", (d) => d.color).attr("stroke", "white").attr("fill-opacity", 0.5);
  jug2.filter((d) => d.data.length > 1).append("text").text((d) => d.data.length).attr("font-size", (d) => Math.max(minfontsize, d.radius)).attr("fill-opacity", (d) => set_discnum(d)).classed("sja_jug_discnum", true).attr("fill", "white").attr("font-family", font).attr("text-anchor", "middle").attr("dominant-baseline", "central");
  jug2.append("circle").attr("r", (d) => d.radius).attr("stroke", (d) => d.color).classed("sja_aa_disckick", true).attr("fill", "white").attr("fill-opacity", 0).attr("stroke-opacity", 0).on("mouseover", (event, d) => {
    jug.selectAll(".sja_jug_leg1").attr("stroke-opacity", 0.2);
    jug.selectAll(".sja_jug_leg2").attr("stroke-opacity", 0.2);
    jug.selectAll(".sja_jug_stem").attr("stroke-opacity", 0.2);
    select_default(d.leg1).attr("stroke-opacity", 1);
    select_default(d.leg2).attr("stroke-opacity", 1);
    select_default(d.stem).attr("stroke-opacity", 1);
    if (d.mode == modefold) {
      foldedjunctioninfo(d, tk);
      return;
    }
    const circle = event.target.getBoundingClientRect();
    expandedjunctioninfo(d, tk, circle);
  }).on("mouseout", () => {
    tk.pica.g.selectAll("*").remove();
    tk.tktip.hide();
    jug.selectAll(".sja_jug_leg1").attr("stroke-opacity", (d) => set_lineopacity(d));
    jug.selectAll(".sja_jug_leg2").attr("stroke-opacity", (d) => set_lineopacity(d));
    jug.selectAll(".sja_jug_stem").attr("stroke-opacity", (d) => set_lineopacity(d));
  }).on("mousedown", (event) => {
    event.stopPropagation();
  }).on("click", (event, d) => {
    if (d.mode == modefold) {
      d.mode = moderaise;
    } else if (d.mode == moderaise) {
      if (d.data.length == 1) {
        d.mode = modefold;
      } else {
        d.mode = modesample;
        junctionsamplespread(d, tk, block);
      }
    } else {
      d.mode = modefold;
    }
    d.modefix = true;
    horiplace(tk.data, block.width, tk);
  });
  horiplace(tk.data, block.width, tk);
  function set_lineopacity(d) {
    return 0.5;
  }
  block.onloadalltk.push(() => {
    spliceeventanalyze(tk, block);
  });
  block.tkcloakoff(tk, {});
  block.block_setheight();
}
function horiplace(lst, width, tk) {
  const todo = [];
  for (const i of lst) {
    if (i.x0 < 0) {
      i.tox = i.x1 - i.radius2 * 2;
    } else if (i.x1 > width) {
      i.tox = i.x0 + i.radius2 * 2;
    } else {
      i.tox = i._x;
    }
    if (i.mode == modefold) {
      i.x = i.tox;
    } else {
      todo.push(i);
    }
  }
  for (const i of lst) {
    i.x = i.tox;
  }
  set_all(tk);
  return;
}
function automode(tk, usemode, blockwidth) {
  for (const i of tk.data) {
    if (!i.mode) i.mode = moderaise;
  }
  return;
  const samplecountlst = [];
  for (let i = 0; i < tk.data.length; i++) {
    samplecountlst.push({
      idx: i,
      count: tk.data[i].data ? tk.data[i].data.length : tk.data[i].v
    });
  }
  samplecountlst.sort((a, b) => b.count - a.count);
  let cumx = 0;
  for (const cc of samplecountlst) {
    const d = tk.data[cc.idx];
    if (!d.mode) {
      cumx += d.radius2 * 2;
      d.mode = cumx >= blockwidth ? modefold : moderaise;
    } else {
      if (d.modefix) {
        if (d.mode != modefold) {
          cumx += d.radius2 * 2;
        }
      } else {
        if (usemode) {
          d.mode = usemode;
          if (d.mode != modefold) {
            cumx += d.radius2 * 2;
          }
        } else {
          cumx += d.radius2 * 2;
          d.mode = cumx >= blockwidth ? modefold : moderaise;
        }
      }
    }
  }
}
function set_jug(d) {
  return "translate(" + d.x + ",0)";
}
function set_leg_x1(d) {
  return d.x0 - d.x;
}
function set_leg_x2(d) {
  return d.x1 - d.x;
}
function set_discnum(d) {
  return d.mode == modefold ? 0 : 1;
}
function set_stem_y1(d) {
  if (d.mode == modefold) return d.radius;
  return d.radius2;
}
function set_qmg(d, tk) {
  if (d.mode == modesample)
    return "translate(0,-" + (tk.legheight + tk.maxradius * 4 + tk.lowpad + tk.padheight) + ") scale(1)";
  return "translate(0,0) scale(0)";
}
function set_leg_y(d, tk) {
  if (d.mode == modefold) return -tk.legheight;
  return -tk.legheight - tk.lowpad - tk.maxradius * 2;
}
function set_jug2(d, tk) {
  if (d.mode == modefold) return "translate(0,-" + (tk.legheight + tk.lowpad + d.radius) + ")";
  if (d.mode == moderaise)
    return "translate(0,-" + (tk.legheight + tk.lowpad + tk.maxradius * 4 + tk.padheight + tk.axisheight - tk.yscale(d.median)) + ")";
  return "translate(0,-" + (tk.legheight + tk.lowpad + tk.maxradius * 3 + tk.padheight) + ")";
}
function set_stem_y2(d, tk) {
  if (d.mode == modefold) return d.radius + tk.lowpad;
  if (d.mode == moderaise) return tk.padheight + tk.maxradius * 2 + tk.axisheight - tk.yscale(d.median);
  return tk.maxradius + tk.padheight;
}
function set_all(tk) {
  const dur = 500;
  if (tk.totalsamplecount > 1) {
    tk.jug.selectAll(".sja_jug_qmg").transition().duration(dur).attr("transform", (d) => set_qmg(d, tk));
    tk.jug.selectAll(".sja_jug_discnum").transition().duration(dur).attr("fill-opacity", (d) => set_discnum(d));
  }
  tk.jug.selectAll(".sja_jug_leg1").transition().duration(dur).attr("y2", (d) => set_leg_y(d, tk)).attr("x1", (d) => set_leg_x1(d));
  tk.jug.selectAll(".sja_jug_leg2").transition().duration(dur).attr("y1", (d) => set_leg_y(d, tk)).attr("x2", (d) => set_leg_x2(d));
  tk.jug.selectAll(".sja_jug_jug2").transition().duration(dur).attr("transform", (d) => set_jug2(d, tk));
  tk.jug.selectAll(".sja_jug_stem").transition().duration(dur).attr("y2", (d) => set_stem_y2(d, tk)).attr("y1", (d) => set_stem_y1(d));
  tk.jug.transition().duration(dur).attr("transform", (d) => set_jug(d));
}
function junctiontype2color(tk, block) {
  for (const j of tk.data) {
    j.color = defaultcolor;
  }
  if (tk.nocatepreconfig) {
    let categories = {};
    if (tk.categories) {
      categories = tk.categories;
    }
    let hasnewtype = false;
    for (const j of tk.data) {
      if (j.type) {
        if (!categories[j.type]) {
          hasnewtype = true;
          categories[j.type] = {
            label: j.type
          };
          if (j.type.toLowerCase() == "known") {
            categories[j.type].color = "#0C72A8";
          } else if (j.type.toLowerCase() == "novel") {
            categories[j.type].color = "#A80C33";
          } else {
            categories[j.type].color = colorfunc(j.type);
          }
        }
      }
    }
    if (hasnewtype) {
      tk.categories = categories;
      if (!tk.tr_legend) {
        const [tr, td] = legend_newrow(block, tk.name);
        tk.tr_legend = tr;
        tk.td_legend = td;
        tr.style("display", "none");
        appear(tr, "table-row");
      }
      category2legend(tk.categories, tk.td_legend);
    }
  }
  if (tk.categories) {
    for (const j of tk.data) {
      if (j.type && tk.categories[j.type]) {
        j.color = tk.categories[j.type].color;
      }
    }
  }
}
function foldedjunctioninfo(d, tk) {
  const fontsize = 15;
  let pad = 5, y = pad, width = 0;
  const bg = tk.pica.g.append("rect").attr("stroke", d.color).attr("shape-rendering", "crispEdges").attr("fill", "white").attr("fill-opacity", 0.8);
  if (d.type) {
    tk.pica.g.append("text").text(d.type).attr("fill", d.color).attr("font-size", fontsize - 2).attr("font-family", font).attr("x", pad).attr("y", y + fontsize / 2).attr("dominant-baseline", "central").each(function() {
      width = this.getBBox().width;
    });
    y += fontsize;
  }
  if (d.data) {
    tk.pica.g.append("text").text(d.data.length + " sample" + (d.data.length > 1 ? "s" : "")).attr("fill", "#858585").attr("font-size", fontsize - 2).attr("font-family", font).attr("x", pad).attr("y", y + fontsize / 2).attr("dominant-baseline", "central").each(function() {
      width = Math.max(width, this.getBBox().width);
    });
    y += fontsize;
    tk.pica.g.append("text").text(d.median + " median").attr("fill", "#858585").attr("font-size", fontsize - 2).attr("font-family", font).attr("x", pad).attr("y", y + fontsize / 2).attr("dominant-baseline", "central").each(function() {
      width = Math.max(width, this.getBBox().width);
    });
    y += fontsize;
  } else {
    tk.pica.g.append("text").text(d.v + " reads").attr("fill", "#858585").attr("font-size", fontsize - 2).attr("font-family", font).attr("x", pad).attr("y", y + fontsize / 2).attr("dominant-baseline", "central").each(function() {
      width = Math.max(width, this.getBBox().width);
    });
    y += fontsize;
  }
  y += pad;
  bg.attr("width", pad * 2 + width).attr("height", y);
  tk.pica.g.append("line").attr("stroke", d.color).attr("shape-rendering", "crispEdges").attr("x1", 30).attr("x2", 30).attr("y1", y).attr("y2", y + 15);
  y += 15;
  tk.pica.g.attr(
    "transform",
    "translate(" + (d.x - 30) + "," + (tk.toppad + tk.axisheight + tk.maxradius * 4 + tk.padheight - d.radius * 2 - y) + ")"
  );
}
function expandedjunctioninfo(d, tk, circle) {
  tk.tktip.clear();
  const holder = tk.tktip.d;
  if (d.type) {
    holder.append("div").style("display", "inline-block").text(d.type).classed("sja_mcdot", true).style("background-color", d.color).style("padding", "1px 8px").style("margin-bottom", "3px");
  }
  holder.append("div").html(
    bplen(d.stop - d.start) + ' <span style="font-size:.8em;">' + d.chr + ":" + (d.start + 1) + "-" + (d.stop + 1) + "</span>"
  );
  if (d.data) {
    if (d.data.length > 1) {
      holder.append("div").html(d.data.length + ' <span style="font-size:.8em;color:#858585">samples</span>');
      if (d.rimcount) {
        holder.append("div").html(d.rimcount + ' <span style="font-size:.8em;color:#858585">show ' + tk.rimwhat + "</span>");
      }
      holder.append("div").html(d.median + ' <span style="font-size:.8em;color:#858585">median read count</span>');
    } else if (d.data.length == 1) {
      samplejunctiontooltip(d, d.data[0], tk, holder);
    }
  } else {
    holder.append("div").html(d.v + ' <span style="font-size:.8em;color:#858585">read count</span>');
  }
  if (d.spliceevents && d.spliceevents.length > 0) {
    const renderdiv = holder.append("div").style("margin", "10px 0px");
    displayspliceevents(d.spliceevents, renderdiv);
  }
  tk.tktip.show(circle.left + circle.width, circle.top - 50);
}
function junctionsamplespread(j, tk, block) {
  if (j.qmg) {
    j.qmg.remove();
  }
  if (tk.cohortsetting && tk.cohortsetting.uselevelidx != void 0) {
    for (const d of j.data) {
      if (!d[tk.cohortsetting.cohort.levels[0].k]) {
        d.color = "gray";
        continue;
      }
      const levelkeys = [];
      for (let lidx = 0; lidx <= tk.cohortsetting.uselevelidx; lidx++) {
        const levelvalue = d[tk.cohortsetting.cohort.levels[lidx].k];
        if (levelvalue) {
          levelkeys.push(levelvalue);
        }
      }
      const str = levelkeys.join(tk.cohortsetting.levelseparator);
      d.color = tk.cohortsetting.colorfunc(str);
    }
  }
  j.swarm = (0, import_d3_beeswarm.beeswarm)().data(j.data).distributeOn((d) => tk.axisheight - tk.yscale(d.v)).radius(tk.qmradius).orientation("vertical").side("symetric").arrange();
  const jugg = select_default(j.jugg);
  j.qmg = jugg.append("g").attr("class", "sja_jug_qmg").attr("transform", set_qmg(j, tk));
  const opacity = 0.8;
  j.qmg.selectAll().data(j.swarm).enter().append("circle").attr("cx", 0).attr("cy", (bee) => -bee.y).attr("r", tk.qmradius).attr("fill", (bee) => {
    return bee.datum.color || "green";
  }).attr("fill-opacity", opacity).on("mousedown", (event) => event.stopPropagation()).on("mousemove", (event) => event.stopPropagation()).on("mouseover", (event, bee) => {
    select_default(event.target).attr("fill-opacity", 1);
    const p = event.target.getBoundingClientRect();
    tk.tktip.clear();
    tk.tktip.show(p.left + 20, p.top - 40);
    samplejunctiontooltip(j, bee.datum, tk, tk.tktip.d);
  }).on("mouseout", (event) => select_default(event.target).attr("fill-opacity", opacity)).on("click", (event, bee) => {
    if (tk.tracks) {
      return;
    }
  }).transition().attr("cx", (bee) => bee.x);
}
function samplejunctiontooltip(j, sample, tk, holder) {
  if (sample.sample) {
    holder.append("div").html(sample.sample);
  } else if (sample.name) {
    holder.append("div").html(sample.name);
  } else if (sample.patient || sample.sampletype) {
    if (sample.patient) {
      holder.append("div").html(sample.patient + ' <span style="font-size:.7em;color:#858585">patient</span>');
    }
    if (sample.sampletype) {
      holder.append("div").html(sample.sampletype + ' <span style="font-size:.7em;color:#858585">sample type</span>');
    }
  } else if (sample.tkid) {
    for (const t of tk.tracks) {
      if (t.tkid == sample.tkid) {
        holder.append("div").text(t.name || "unnamed member");
        break;
      }
    }
  }
  if (tk.cohortsetting && tk.cohortsetting.cohort && tk.cohortsetting.cohort.levels) {
    for (const lev of tk.cohortsetting.cohort.levels) {
      if (sample[lev.k]) {
        holder.append("div").html(sample[lev.k] + ' <span style="font-size:.7em;color:#858585">' + lev.label + "</span>");
      }
    }
  }
  holder.append("div").html(sample.v + ' <span style="font-size:.7em;color:#858585">read count</span>');
  if (sample.metadata) {
    holder.append("div").html(
      '<span style="background-color:' + sample.metadata.color + '" class=sja_mcdot>&nbsp;</span> ' + sample.metadata.value + ' <span style="font-size:.7em;color:#858585">' + tk.metadata.m.label + "</span>"
    );
  }
  if (sample.hasrim) {
    holder.append("div").text(tk.rimwhat);
  }
  if (j.spliceevents) {
    const evtidx = spliceevent_exonskip_getdefault_default(j.spliceevents);
    const evt = j.spliceevents[evtidx];
    const skipwhichexon = "exon " + evt.skippedexon.map((i) => i + 1).join(",") + " " + (evt.isskipexon ? "skip" : "alt. use");
    let jbcount = 0;
    if (evt.junctionB && evt.junctionB.data) {
      for (const d of evt.junctionB.data) {
        if (d.tkid == sample.tkid) {
          jbcount = d.v;
          break;
        }
      }
    }
    let acountsum = 0;
    if (evt.junctionAlst) {
      for (const ja of evt.junctionAlst) {
        if (ja && ja.data) {
          for (const d of ja.data) {
            if (d.tkid == sample.tkid) {
              acountsum += d.v;
              break;
            }
          }
        }
      }
    }
    let percent;
    if (jbcount == 0) {
      percent = 0;
    } else {
      percent = Math.ceil(100 * jbcount / (jbcount + acountsum / evt.junctionAlst.length));
    }
    holder.append("div").html(percent + '% <span style="font-size:.7em;color:#858585;">' + skipwhichexon + "</span>");
  }
}
function get_leftLabelMaxwidth(tk) {
  const collectlabw = [];
  tk.tklabel.each(function() {
    collectlabw.push(this.getBBox().width);
  });
  if (tk.label_mcount) {
    tk.label_mcount.each(function() {
      collectlabw.push(this.getBBox().width);
    });
  }
  tk.leftLabelMaxwidth = Math.max(...collectlabw);
}

// src/block.tk.junction.js
var binpxw = 5;
var modefold = 1;
var moderaise = 2;
var modesample = 3;
var labyspace = 5;
function makeTk(tk, block) {
  tk.leftaxis = tk.gleft.append("g");
  let laby = labyspace + block.labelfontsize;
  const thistip = new Menu({ padding: "none" });
  tk.label_mcount = block.maketklefthandle(tk, laby).on("click", (event) => {
    label_mcount_fillpane(tk, block, thistip);
  });
  laby += labyspace + block.labelfontsize;
  tk.totalsamplecount = 0;
  tk.height_main = 100;
  tk.config_handle = block.maketkconfighandle(tk).on("click", (event) => configpanel(tk, block));
  if (tk.categories || tk.cohortsetting) {
    const [tr, td] = legend_newrow(block, tk.name);
    tk.tr_legend = tr;
    tk.td_legend = td;
  }
  if (tk.categories) {
    category2legend(tk.categories, tk.td_legend);
  }
  if (tk.cohortsetting) {
    tk.cohortsetting.holder = tk.td_legend.append("div").style("margin-top", "10px");
    tk.cohortsetting.legendholder = tk.cohortsetting.holder.append("div");
  }
}
function junctionload(tk, block) {
  if (tk.uninitialized) {
    makeTk(tk, block);
    delete tk.uninitialized;
  }
  if ((block.zoomedin || block.resized) && tk.data) {
    const junc = [];
    for (const i of tk.data) {
      const oldx = i.x;
      const e = j2block(i, block);
      if (e) {
        continue;
      }
      if (i.x0 >= 0 && i.x0 <= block.width || i.x1 >= 0 && i.x1 <= block.width) {
        i.x = oldx;
        junc.push(i);
      }
    }
    rendertk(junc, tk, block);
    return;
  }
  if (tk.fixeddata) {
    block.tkcloakon(tk);
    const junc2 = [];
    for (const j of tk.fixeddata) {
      const j2 = {
        chr: j.chr,
        start: j.start,
        stop: j.stop,
        data: j.data,
        type: j.type
      };
      const e = j2block(j2, block);
      if (e) {
        continue;
      }
      junc2.push(j2);
    }
    tk.totalsamplecount = tk.tracks[0].samplecount;
    tk.axisheight = 200;
    tk.legheight = 50;
    tk.bottompad = 0;
    tk.qmradius = 2;
    tk.lowpad = 15;
    tk.padheight = 10;
    rendertk(junc2, tk, block);
    return;
  }
  if (!tk.tracks) {
    block.tkcloakoff(tk, { error: "neither .tracks[] or .fixeddata[] are available" });
    tk.height_main = 50;
    block.block_setheight();
    return;
  }
  block.block_setheight();
  block.tkcloakon(tk);
  const bincount = Math.ceil(block.width / binpxw);
  let bins = null;
  let donenum = 0;
  const tasks = [];
  const allfiledata = [];
  for (const t of tk.tracks) {
    const getheader = new Promise((resolve, reject) => {
      if (t.rnapegfile) {
        t.samplecount = 1;
        return resolve();
      }
      if (t.samplecount != void 0 && t.checkedheader) return resolve();
      const par = {};
      if (t.file) {
        par.file = t.file;
      } else {
        par.url = t.url;
        if (t.indexURL) par.indexURL = t.indexURL;
      }
      dofetch3("tabixheader", { body: par }).then((data) => {
        if (data.error) return reject("cannot load header for member track " + t.name + ": " + data.error);
        t.checkedheader = true;
        const str = data.lines.join("");
        if (!str) {
        } else {
          const l = str.trim().split("	");
          t.headersamples = [];
          for (let i = 5; i < l.length; i++) {
            const str2 = l[i];
            let j = null;
            if (str2[0] == "{" && str2[str2.length - 1] == "}") {
              try {
                j = JSON.parse(str2);
              } catch (e) {
                console.error("header line field [" + i + "] is broken json: " + str2);
              }
            }
            if (j) {
              j.tkid = Math.random().toString();
              t.headersamples.push(j);
            } else {
              t.headersamples.push({
                name: l[i],
                tkid: Math.random().toString()
              });
            }
          }
          t.samplecount = t.headersamples.length;
          tk.totalsamplecount += t.samplecount;
        }
        resolve();
      });
    });
    const getdata = new Promise((resolve, reject) => {
      getheader.then(() => {
        const par = {
          genome: block.genome.name,
          rglst: block.tkarg_maygm(t)
        };
        if (bincount) par.bincount = bincount;
        if (t.file || t.rnapegfile) {
          par.file = t.file || t.rnapegfile;
        } else {
          par.url = t.url;
          if (t.indexURL) par.indexURL = t.indexURL;
        }
        if (t.rnapegfile) {
          par.isrnapeg = 1;
        }
        dofetch3("junction", { body: par }).then((data) => {
          donenum++;
          if (tk.tracks.length > 1) {
            block.tkprogress(tk, donenum / tk.tracks.length);
          }
          if (!data) reject("server error for getting member track " + t.name);
          if (data.error) reject("Cannot get data: " + data.error);
          if (!data.lst && !data.bins) reject("wrong response when getting data for " + t.name);
          if (data.lst) {
            if (data.lst[0] && data.lst[0].rawdata && t.samplecount == void 0) {
              t.samplecount = data.lst[0].rawdata.length;
              tk.totalsamplecount += t.samplecount;
            }
            if (bins) {
            } else {
              const thisfilejunctions = [];
              for (const k of data.lst) {
                k.data = [];
                for (let i = 0; i < k.rawdata.length; i++) {
                  const v = k.rawdata[i];
                  if (!Number.isInteger(v) || v <= 0) {
                    continue;
                  }
                  const s = { v };
                  if (t.headersamples) {
                    const s0 = t.headersamples[i];
                    if (s0) {
                      for (const _k in s0) {
                        s[_k] = s0[_k];
                      }
                    }
                  } else {
                    if (t.name) s.name = t.name;
                    if (t.sample) s.sample = t.sample;
                    if (t.patient) s.patient = t.patient;
                    if (t.sampeltype) s.sampletype = t.sampletype;
                    if (t.tkid) s.tkid = t.tkid;
                    if (t.file) s.file = t.file;
                    if (t.url) s.url = t.url;
                    if (t.indexURL) s.indexURL = t.indexURL;
                  }
                  k.data.push(s);
                }
                delete k.rawdata;
                thisfilejunctions.push(k);
              }
              resolve(thisfilejunctions);
            }
          } else {
          }
        });
      }).catch((err) => reject(err));
    });
    tasks.push(getdata);
  }
  Promise.all(tasks).then((data) => {
    const junc = [];
    data.forEach((dat) => {
      if (!dat) return;
      dat.forEach((k) => {
        let notfound = true;
        for (const j of junc) {
          if (j.start == k.start && j.stop == k.stop) {
            j.data = j.data.concat(k.data);
            notfound = false;
            break;
          }
        }
        if (notfound) {
          junc.push(k);
        }
      });
    });
    for (const j of junc) {
      j2block(j, block);
    }
    for (const j of junc) {
      smuggleattributes(j);
    }
    if (!tk.axisheight) {
      if (tk.totalsamplecount > 1) {
        tk.axisheight = 200;
        tk.legheight = 50;
        tk.bottompad = 0;
        tk.qmradius = 2;
        tk.lowpad = 15;
        tk.padheight = 10;
      } else {
        tk.axisheight = 100;
        tk.legheight = 20;
        tk.bottompad = 0;
        tk.lowpad = 10;
        tk.padheight = 10;
      }
      if (tk.cohortsetting) {
        initcohortsetting(tk, block);
      }
    }
    rendertk(junc, tk, block);
  }).catch((err) => {
    tk.glider.selectAll("*").remove();
    block.tkcloakoff(tk, { error: err });
    block.block_setheight();
  });
}
function j2block(j, block) {
  const starthit = block.seekcoord(j.chr, j.start)[0];
  if (!starthit) {
    return true;
  }
  const stophit = block.seekcoord(j.chr, j.stop)[0];
  if (!stophit) {
    return true;
  }
  const startout = starthit.x < 0 || starthit.x > block.width;
  const stopout = stophit.x < 0 || stophit.x > block.width;
  if (startout && stopout) {
    return true;
  }
  j.x0 = starthit.x;
  j.x1 = stophit.x;
  j.x = (j.x0 + j.x1) / 2;
  j._x = j.x;
  if (!j.modefix) {
    j.mode = moderaise;
  }
  return false;
}
function smuggleattributes(j) {
}
function label_mcount_fillpane(tk, block, tip) {
  tip.clear();
  const holder = tip.d;
  const types = /* @__PURE__ */ new Map();
  for (const j of tk.data) {
    if (!j.type) continue;
    if (!types.has(j.type)) {
      types.set(j.type, []);
    }
    if (j.data) {
      types.get(j.type).push(j.data.map((i) => i.v));
    } else {
      types.get(j.type).push(j.v);
    }
  }
  if (types.size) {
    const d = holder.append("div").style("margin", "8px");
    for (const [type, valuelst] of types) {
      d.append("div").style("margin", "2px").html(
        valuelst.length + ' <span style="font-size:.8em;color:' + tk.categories[type].color + '">' + type + " junction" + (valuelst.length > 1 ? "s" : "") + "</span>"
      );
      let vlst = valuelst;
      if (tk.tracks) {
        vlst = [];
        for (const l of valuelst) {
          vlst.push(...l);
        }
      }
      if (vlst.length == 1) {
      } else {
        d.append("table").style("margin-left", "20px").html(
          '<tr><td style="text-align:right;">' + Math.max(...vlst) + '</td><td style="color:#858585;font-size:.7em">max read count</td></tr><tr><td style="text-align:right;">' + Math.min(...vlst) + '</td><td style="color:#858585;font-size:.7em">min</td></tr><tr><td style="text-align:right;">' + Math.ceil(vlst.reduce((i, j) => j + i, 0) / vlst.length) + '</td><td style="color:#858585;font-size:.7em">mean</td></tr>'
        );
      }
    }
  } else {
    let vlst = [];
    if (tk.tracks) {
      for (const j of tk.data) {
        vlst.push(...j.data.map((i) => i.v));
      }
    } else {
      vlst = tk.data.map((j) => j.v);
    }
    if (vlst.length > 1) {
      holder.append("table").html(
        '<tr><td style="text-align:right;">' + Math.max(...vlst) + '</td><td style="color:#858585;font-size:.7em">max read count</td></tr><tr><td style="text-align:right;">' + Math.min(...vlst) + '</td><td style="color:#858585;font-size:.7em">min</td></tr><tr><td style="text-align:right;">' + Math.ceil(vlst.reduce((i, j) => j + i, 0) / vlst.length) + '</td><td style="color:#858585;font-size:.7em">mean</td></tr>'
      );
    }
  }
  holder.append("div").text("Fold").classed("sja_menuoption", true).on("click", (event) => {
    tip.hide();
    for (const j of tk.data) {
      j.mode = modefold;
      j.modefix = true;
    }
    horiplace(tk.data, block.width, tk);
  });
  holder.append("div").text("Expand").classed("sja_menuoption", true).on("click", (event) => {
    tip.hide();
    for (const j of tk.data) {
      j.modefix = false;
    }
    automode(tk, null, block.width);
    for (const j of tk.data) {
      j.modefix = true;
    }
    horiplace(tk.data, block.width, tk);
  });
  holder.append("div").text("Download").classed("sja_menuoption", true).on("click", (event) => {
    tip.hide();
    downloadjunctions(tk);
  });
  tip.showunder(tk.label_mcount.node());
}
function downloadjunctions(tk) {
  const txt = [];
  if (tk.file || tk.url) {
    if (tk.data) {
      txt.push("chromosome	start	stop	read_count" + (tk.categories ? "	type" : ""));
      for (const j of tk.data) {
        txt.push(j.chr + "	" + j.start + "	" + j.stop + "	" + j.v + (tk.categories ? "	" + j.type : ""));
      }
    }
  } else if (tk.tracks) {
    if (tk.data) {
      const header = ["chromosome	start	stop" + (tk.categories ? "	type" : "")];
      for (const t of tk.tracks) {
        const lst = [];
        if (t.patient) lst.push(t.patient);
        if (t.sampletype) lst.push(t.sampletype);
        if (lst.length == 0) {
          lst.push(t.name);
        }
        header.push(lst.join(", "));
      }
      txt.push(header.join("	"));
      for (const j of tk.data) {
        const lst = [j.chr + "	" + j.start + "	" + j.stop + (tk.categories ? "	" + j.type : "")];
        const hash = /* @__PURE__ */ new Map();
        for (const jsample of j.data) {
          hash.set(jsample.tkid, jsample.v);
        }
        for (const t of tk.tracks) {
          lst.push(hash.has(t.tkid) ? hash.get(t.tkid) : "");
        }
        txt.push(lst.join("	"));
      }
    }
  }
  export_data(tk.name, [{ label: "Splice junction", text: txt.join("\n") }]);
}
function configpanel(tk, block) {
  tk.tkconfigtip.clear().showunder(tk.config_handle.node());
  const holder = tk.tkconfigtip.d;
  {
    const row = holder.append("div").style("margin-bottom", "10px");
    row.append("span").html("Read count cutoff&nbsp;");
    row.append("input").property("value", tk.readcountcutoff || 0).attr("type", "number").style("width", "50px").on("keyup", (event) => {
      if (!keyupEnter(event)) return;
      const v = Number.parseFloat(event.target.value);
      if (v == 0) {
        if (tk.readcountcutoff) {
          tk.readcountcutoff = 0;
          junctionload(tk, block);
        } else {
        }
        return;
      }
      if (!v || v < 0) {
        return;
      }
      if (tk.readcountcutoff) {
        if (tk.readcountcutoff == v) {
        } else if (tk.readcountcutoff > v) {
          tk.readcountcutoff = v;
          junctionload(tk, block);
        } else {
          tk.readcountcutoff = v;
          rendertk(tk.data, tk, block);
        }
      } else {
        tk.readcountcutoff = v;
        junctionload(tk, block);
      }
    });
    const note = row.append("div").style("font-size", ".7em").style("color", "#858585");
    if (tk.totalsamplecount > 1) {
      note.text("For a junction, samples with read count lower than cutoff will not be shown.");
    } else {
      note.text("Junctions with read count lower than cutoff will not be shown.");
    }
  }
}
function initcohortsetting(tk, block) {
  if (!tk.cohortsetting.cohort) {
    sayerror(tk.cohortsetting.holder, ".cohort missing from tk.cohortsetting");
    return;
  }
  if (!tk.cohortsetting.cohort.levels) {
    sayerror(tk.cohortsetting.holder, ".levels missing from tk.cohortsetting.cohort");
    return;
  }
  if (!tk.cohortsetting.cohort.levels[0]) {
    sayerror(tk.cohortsetting.holder, "tk.cohortsetting.cohort.levels[0] is invalid");
    return;
  }
  tk.cohortsetting.levelseperator = ".";
  tk.cohortsetting.uselevelidx = 0;
  setcohortlegend_usecohortlevel(tk, block);
}
function setcohortlegend_usecohortlevel(tk, block) {
  tk.cohortsetting.legendholder.selectAll("*").remove();
  tk.cohortsetting.colorfunc = ordinal(category10_default);
  const stratkey2count = /* @__PURE__ */ new Map();
  for (const t of tk.tracks) {
    for (const s of t.headersamples) {
      if (!s[tk.cohortsetting.cohort.levels[0].k]) {
        continue;
      }
      const thissamplekeys = [];
      for (let lidx = 0; lidx <= tk.cohortsetting.uselevelidx; lidx++) {
        const thislevelkey = s[tk.cohortsetting.cohort.levels[lidx].k];
        if (thislevelkey) {
          thissamplekeys.push(thislevelkey);
        }
      }
      const str = thissamplekeys.join(tk.cohortsetting.levelseperator);
      if (!stratkey2count.has(str)) {
        stratkey2count.set(str, {
          count: 0,
          label: s[tk.cohortsetting.cohort.levels[tk.cohortsetting.uselevelidx].full]
        });
      }
      stratkey2count.get(str).count++;
    }
  }
  const sorteditems = [...stratkey2count].sort((a, b) => b[1].count - a[1].count);
  for (const item of sorteditems) {
    const color = tk.cohortsetting.colorfunc(item[0]);
    const label = item[1].label;
    const row = tk.cohortsetting.legendholder.append("div").style("margin-top", "5px");
    row.append("div").style("display", "inline-block").attr("class", "sja_mcdot").style("background-color", color).style("margin-right", "10px").html("&nbsp;&nbsp;");
    row.append("div").style("display", "inline-block").text(label);
  }
}
export {
  junctionload,
  modefold,
  moderaise,
  modesample
};
//# sourceMappingURL=block.tk.junction-AJYML4AW.js.map
