import {
  urlmap_default
} from "./chunk-WKNI3HRQ.js";
import {
  axisstyle,
  make_one_checkbox,
  make_radios,
  sayerror,
  table2col
} 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 {
  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 "./chunk-4UWS5Y3N.js";
import "./chunk-DD4R5P6W.js";
import "./chunk-JNITUVXP.js";
import "./chunk-KSGA62R2.js";
import {
  axisRight
} from "./chunk-LOZEKOES.js";
import "./chunk-TOU7EVFQ.js";
import {
  linear
} from "./chunk-OAWQ6LOO.js";
import "./chunk-TLT4YIG3.js";
import "./chunk-KYBIQBXE.js";
import {
  pointer_default,
  select_default
} from "./chunk-I6Y4O3RR.js";
import "./chunk-OMR2DT66.js";
import "./chunk-DQC5FFGV.js";
import "./chunk-HFNDKYVF.js";

// src/block.tk.bam.js
var stackpagesize = 60;
var slider_rail_color = "#eee";
var slider_color = "#c7edc5";
var slider_color_dark = "#9ed19b";
var slider_color_dark_line = "#36a32f";
var messagerowheight = 15;
var stackheight_min = 7;
async function loadTk(tk, block) {
  block.tkcloakon(tk);
  block.block_setheight();
  if (tk.uninitialized) {
    makeTk(tk, block);
  }
  const regions = [];
  let xoff = 0;
  for (let i = block.startidx; i <= block.stopidx; i++) {
    const r = block.rglst[i];
    regions.push({
      chr: r.chr,
      start: r.start,
      stop: r.stop,
      width: r.width,
      x: xoff
    });
    xoff += r.width + block.regionspace;
  }
  for (const [idx, r] of block.subpanels.entries()) {
    xoff += r.leftpad;
    regions.push({
      chr: r.chr,
      start: r.start,
      stop: r.stop,
      width: r.width,
      exonsf: r.exonsf,
      subpanelidx: idx,
      x: xoff
    });
    xoff += r.width;
  }
  tk.regions = regions;
  try {
    if (tk.groups) {
      for (const g of tk.groups) {
        delete g.partstack;
        delete g.dom.rightg.vslider.boxy;
      }
    }
    const data = await getData(tk, block);
    if (data.error) throw data.error;
    if (data.colorscale) {
      tk.colorscale = data.colorscale;
    }
    if (tk.variants) {
      for (let var_idx = 0; var_idx < tk.variants.length; var_idx++) {
        if (tk.variants[var_idx].pos != data.allele_positions[var_idx]) {
          tk.variants[var_idx].pos = data.allele_positions[var_idx];
          tk.variants[var_idx].ref = data.ref_alleles[var_idx];
          tk.variants[var_idx].alt = data.alt_alleles[var_idx];
        }
      }
    }
    renderTk(data, tk, block);
    block.tkcloakoff(tk, {});
  } catch (e) {
    if (e.stack) console.log(e.stack);
    if (tk.pileup_shown) {
      tk.dom.pileup_axis.selectAll("*").remove();
      tk.dom.pileup_img.attr("width", 0);
    }
    if (tk.groups) {
      for (const g of tk.groups) {
        g.dom.img_fullstack.attr("width", 0).attr("height", 0);
        g.dom.img_partstack.attr("width", 0).attr("height", 0);
        g.dom.img_cover.attr("width", 0).attr("height", 0);
      }
    }
    tk.height_main = tk.height = 100;
    if (typeof e == "string" && e.startsWith("No reads in view range")) {
      tk.leftlabel_count.text("");
      tk.leftlabel_skip.text("");
    }
    block.tkcloakoff(tk, { error: e.message || e });
  }
  setLeftlabelWidth(tk, block);
  block.block_setheight();
}
async function getData(tk, block, additional = {}) {
  const body = {
    genome: block.genome.name,
    regions: tk.regions,
    nucleotide_length: block.exonsf,
    pileupheight: tk.pileupheight,
    ...additional
  };
  if (tk.gdcFile) {
    body.gdcFileUUID = tk.gdcFile.uuid;
    body.gdcFilePosition = tk.gdcFile.position;
  }
  if (tk.variants) {
    body.variant = tk.variants.map((m) => m.chr + "." + m.pos + "." + m.ref + "." + m.alt).join(".");
    body.strictness = tk.strictness;
    body.diff_score_plotwidth = tk.dom.diff_score_plotwidth;
    if (Number.isFinite(tk.max_diff_score)) {
      body.max_diff_score = tk.max_diff_score;
      body.min_diff_score = tk.min_diff_score;
    }
  } else if (tk.sv) {
    if (tk.sv[0].strandA == "+") {
      tk.sv[0].strandA = "positive";
    } else if (tk.sv[0].strandA == "-") {
      tk.sv[0].strandA = "negative";
    }
    if (tk.sv[0].strandB == "+") {
      tk.sv[0].strandB = "positive";
    } else if (tk.sv[0].strandB == "-") {
      tk.sv[0].strandB = "negative";
    }
    body.sv = tk.sv.map((m) => m.chrA + "." + m.startA + "." + m.strandA + "." + m.chrB + "." + m.startB + "." + m.strandB).join(".");
  }
  if (tk.variants && tk.alleleAlreadyUpdated) {
    body.alleleAlreadyUpdated = 1;
    body.refseqs = tk.variants.refseqs;
    body.altseqs = tk.variants.altseqs;
    body.leftflankseqs = tk.variants.leftflankseqs;
    body.rightflankseqs = tk.variants.rightflankseqs;
    body.ref_positions = tk.variants.ref_positions;
    body.refalleles = tk.variants.refalleles;
    body.altalleles = tk.variants.altalleles;
  }
  if (tk.uninitialized) {
    body.getcolorscale = 1;
    delete tk.uninitialized;
  }
  if (tk.asPaired) body.asPaired = 1;
  if ("nochr" in tk) body.nochr = tk.nochr;
  if (tk.file) body.file = tk.file;
  if (tk.url) body.url = tk.url;
  if (tk.indexURL) body.indexURL = tk.indexURL;
  if (tk.drop_pcrduplicates) body.drop_pcrduplicates = 1;
  if (tk.drop_supplementary_alignments) body.drop_supplementary_alignments = 1;
  if (window.devicePixelRatio > 1) body.devicePixelRatio = window.devicePixelRatio;
  const data = await dofetch3("tkbam", { headers: getHeaders(tk), body });
  if (tk.variants && !tk.alleleAlreadyUpdated) {
    tk.variants.refseqs = data.refseqs;
    tk.variants.altseqs = data.altseqs;
    tk.variants.refalleles = data.refalleles;
    tk.variants.altalleles = data.altalleles;
    tk.variants.leftflankseqs = data.leftflankseqs;
    tk.variants.rightflankseqs = data.rightflankseqs;
    tk.variants.ref_positions = data.ref_positions;
    tk.alleleAlreadyUpdated = true;
  }
  if (data.error) throw data.error;
  return data;
}
function renderTk(data, tk, block) {
  if ("nochr" in data) tk.nochr = data.nochr;
  if (data.pileup_data) {
    tk.pileup_shown = true;
    tk.dom.pileup_img.attr("xlink:href", data.pileup_data.src).attr("width", data.pileup_data.width).attr("height", tk.pileupheight);
    tk.dom.pileup_axis.selectAll("*").remove();
    const scale = linear().domain([0, data.pileup_data.maxValue]).range([tk.pileupheight, 0]);
    axisstyle({
      axis: tk.dom.pileup_axis.call(axisRight().scale(scale).ticks(5)),
      // at most 5 ticks
      color: "black",
      showline: true
    });
  } else {
    tk.pileup_shown = false;
    tk.dom.pileup_axis.selectAll("*").remove();
    tk.dom.pileup_img.attr("width", 0);
  }
  if (data.count.read_limit_reached) {
    tk.toomanyreads = true;
    tk.dom.read_limit_text.text(
      `Downsampled to ${data.groups.reduce((i, j) => i + j.count.r, 0)} from ${data.count.read_limit_reached} reads. Try zooming into a smaller region.`
    ).attr("x", data.pileup_data.width / 2).attr("transform", "scale(1)");
  } else {
    tk.toomanyreads = false;
    tk.dom.read_limit_text.attr("transform", "scale(0)");
  }
  if (!tk.groups) {
    tk.groups = [];
    for (const g of data.groups) {
      const gd = makeGroup(g, tk, block, data);
      tk.groups.push(gd);
    }
  } else {
    updateExistingGroups(data, tk, block);
  }
  may_render_variant(data, tk, block);
  for (const g of tk.groups) {
    g.dom.message_rowg.selectAll("*").remove();
    let y = 0;
    for (const m of g.data.messages) {
      const msg = g.dom.message_rowg.append("text").attr("x", block.width / 2).attr("y", y + messagerowheight - 1).attr("font-size", messagerowheight).attr("text-anchor", "middle").text(m.t);
      if (m.isheader && !tk.gdcFile) {
        msg.attr("class", "sja_clbtext2").on("click", () => {
          click_groupheader(tk, g, block);
        });
      }
      y += messagerowheight;
    }
  }
  setTkHeight(tk);
  let countr = 0, countt = 0;
  for (const g of tk.groups) {
    countr += g.data.count.r;
    if (tk.asPaired) {
      countt += g.data.count.t;
    }
  }
  tk.leftlabel_count.text(
    (countr ? countr + " read" + (countr > 1 ? "s" : "") : "") + (countt ? ", " + countt + " template" + (countt > 1 ? "s" : "") : "")
  );
  if (data.count.skipped) {
    tk.leftlabel_skip.text(`${data.count.skipped} read${data.count.skipped > 1 ? "s" : ""} skipped`);
  } else {
    tk.leftlabel_skip.text("");
  }
  tk.read_alignment_diff_scores_asc = data.read_alignment_diff_scores_asc;
}
function setLeftlabelWidth(tk, block) {
  const lst = [
    tk.tklabel.node().getBBox().width,
    tk.leftlabel_count.node().getBBox().width,
    tk.leftlabel_skip.node().getBBox().width,
    tk.leftlabel_about ? tk.leftlabel_about.node().getBBox().width : 0
  ];
  if (tk.show_readnames) {
    for (const g of tk.groups) lst.push(g.ReadNameMaxwidth);
  }
  tk.leftLabelMaxwidth = Math.max(...lst);
  block.setllabel();
}
function may_render_variant(data, tk, block) {
  if (!tk.dom.variantg || tk.sv) return;
  let var_idx = 0;
  for (const g of tk.groups) {
    if (g.data.type.includes("support_alt")) {
      if (g.variantg) {
        g.variantg.selectAll("*").remove();
      } else {
        g.variantg = tk.glider.append("g");
      }
      let x1, x2;
      {
        const hits = block.seekcoord(tk.variants[0].chr, tk.variants[var_idx].pos);
        if (hits[0]) {
          x1 = hits[0].x - block.exonsf / 2;
        }
      }
      {
        const hits = block.seekcoord(tk.variants[0].chr, tk.variants[var_idx].pos + tk.variants[var_idx].ref.length);
        if (hits[0]) {
          x2 = hits[0].x - block.exonsf / 2;
        }
      }
      if (x1 === void 0 || x2 === void 0 || x1 >= block.width || x2 <= 0) return;
      let variant_box_width = x2 - x1;
      if (x2 > data.pileup_data.width) {
        variant_box_width = data.pileup_data.width - x1;
      } else if (x1 < 0) {
        variant_box_width = x2;
      }
      if (tk.variants.length == 1) {
        g.variantg.append("rect").attr("x", Math.max(0, x1)).attr("width", variant_box_width).attr("height", tk.dom.variantrowheight).attr("fill", "grey");
      } else {
        g.variantg.append("rect").attr("x", Math.max(0, x1)).attr("width", variant_box_width).attr("height", tk.dom.variantrowheight).attr("fill", g.data.group_color);
      }
      const variant_string = tk.variants[0].chr + "." + (data.allele_positions[var_idx] + 1).toString() + "." + data.ref_alleles[var_idx] + "." + data.alt_alleles[var_idx];
      let variant_start_text_pos = 0;
      const space_param = 10;
      const pad_param = 15;
      const var_str = g.variantg.append("text").attr("y", tk.dom.variantrowheight - 2).attr("font-size", tk.dom.variantrowheight).text(variant_string);
      const var_str_bbox = var_str.node().getBBox();
      if (var_str_bbox.width + space_param < x1) {
        variant_start_text_pos = x1 - var_str_bbox.width - space_param;
      } else if (var_str_bbox.width < variant_box_width) {
        variant_start_text_pos = Math.max(0, x1) + (variant_box_width - var_str_bbox.width) / 2;
      } else if (x2 + var_str_bbox.width < data.pileup_data.width) {
        variant_start_text_pos = x2 + space_param;
      }
      var_str.attr("x", variant_start_text_pos);
      if (data.refalleleerror == true) {
        let text_start_pos = 0;
        const incorrect_string = g.variantg.append("text").attr("x", text_start_pos).attr("y", tk.dom.variantrowheight).style("fill", "red").attr("font-size", tk.dom.variantrowheight).text("Incorrect reference allele");
        const incorrect_ref_bbox = incorrect_string.node().getBBox();
        if (variant_start_text_pos == 0 && incorrect_ref_bbox.width + space_param < x1 - var_str_bbox.width - space_param) {
          text_start_pos = var_str_bbox.width + space_param;
        } else if (variant_start_text_pos == 0 && incorrect_ref_bbox.width + space_param > x1 - var_str_bbox.width - space_param) {
          text_start_pos = x2 + space_param;
        } else if (var_str_bbox.width + space_param < x1 && x2 + incorrect_ref_bbox.width + space_param < data.pileup_data.width) {
          text_start_pos = x2 + space_param;
        } else if (var_str_bbox.width + space_param < x1 && x2 + incorrect_ref_bbox.width + space_param >= data.pileup_data.width && incorrect_ref_bbox.width + space_param < variant_box_width) {
          text_start_pos = Math.max(0, x1);
        } else if (var_str_bbox.width + space_param < x1 && x2 + incorrect_ref_bbox.width + space_param >= data.pileup_data.width) {
          text_start_pos = x1 - var_str_bbox.width - space_param * 2 - incorrect_ref_bbox.width;
        } else if (var_str_bbox.width < variant_box_width && incorrect_ref_bbox.width + space_param < x1) {
          text_start_pos = x1 - incorrect_ref_bbox.width - space_param;
        } else if (var_str_bbox.width < variant_box_width && incorrect_ref_bbox.width + space_param >= x1) {
          text_start_pos = x2 + space_param;
        } else if (x2 + var_str_bbox.width < data.pileup_data.width && incorrect_ref_bbox.width + space_param < x1) {
          text_start_pos = x1 - incorrect_ref_bbox.width - space_param;
        } else if (x2 + var_str_bbox.width < data.pileup_data.width && incorrect_ref_bbox.width + space_param >= x1) {
          text_start_pos = x2 + var_str_bbox.width + 2 * space_param;
        } else if (x2 + var_str_bbox.width < data.pileup_data.width && incorrect_ref_bbox.width < variant_box_width) {
          text_start_pos = Math.max(0, x1);
        }
        incorrect_string.attr("x", text_start_pos);
      }
      var_idx += 1;
    }
  }
  if (tk.variants.length == 1) {
    tk.fs_string.text("FS = " + data.strand_probability);
    if (data.strand_significance) {
      tk.fs_string.style("fill", "red");
    } else {
      tk.fs_string.style("fill", "black");
    }
    tk.fs_string.on("click", (event) => {
      tk.tktip.clear().showunder(event.target);
      tk.tktip.d.append("div").style("width", "350px").html(
        `Fisher strand (FS) analysis score containing p-values in phred scale (-10*log(p-value)). If <a href='https://gatk.broadinstitute.org/hc/en-us/articles/360035890471' target='_blank'>FS>60</a>, the variant maybe a sequencing artifact and highlighted in red.
					</br></br>
					To compute the p-value, Fisher's exact test is used for variants with a sequencing depth <= 300. If depth > 300 and each individual category > 150, chi-squared test is used. Following table displays read counts in each category.`
      );
      const table = tk.tktip.d.append("table").style("margin-top", "20px").style("border-spacing", "5px");
      {
        const tr = table.append("tr").style("font-weight", "bold");
        tr.append("td");
        tr.append("td").text("Alternative");
        tr.append("td").text("Reference");
      }
      {
        const tr = table.append("tr");
        tr.append("td").text("Forward").style("font-weight", "bold");
        tr.append("td").text(data.alternate_forward_count);
        tr.append("td").text(data.reference_forward_count);
      }
      {
        const tr = table.append("tr");
        tr.append("td").text("Reverse").style("font-weight", "bold");
        tr.append("td").text(data.alternate_reverse_count);
        tr.append("td").text(data.reference_reverse_count);
      }
    });
  }
  if (Number.isFinite(data.max_diff_score) && !tk.dom.alleleSimilarityHeaderLabel) {
    tk.dom.alleleSimilarityHeaderLabel = tk.dom.alleleSimilarityHeaderG.append("text").attr("y", 2 * tk.dom.variantrowheight).attr("font-size", tk.dom.variantrowheight).attr("class", "sja_clbtext2").text("Allele similarity");
    const html_text = [
      "Allele similarity: This chart shows the allele to which the read has maximum sequence similarity. In case of alternative and reference alleles, all reads in the same group have same color. In case of none category, color representing allele with maximum sequence color is displayed. In case of ambiguous category, for each read colors representing each alleles having equal similarity to each other are displayed."
    ];
    let var_idx2 = 0;
    html_text.push("<br>Allele color codes:");
    let old_pos = tk.variants[0].pos;
    let old_ref_length = tk.variants[0].ref.length;
    tk.is_same_ref = true;
    let ref_color;
    for (const g of tk.groups) {
      if (g.data.type.includes("support_alt")) {
        let test_text = '<svg width="10" height="10" style = "display:inline-block;"><rect width="10" height="10" style="fill:' + g.data.group_color + ';" /> </svg> ' + tk.variants[var_idx2].alt;
        html_text.push(test_text);
        if (tk.variants[var_idx2].pos != old_pos || tk.variants[var_idx2].ref.length != old_ref_length) {
          tk.is_same_ref = false;
        }
        var_idx2 += 1;
      } else if (g.data.type == "support_ref") {
        ref_color = g.data.group_color;
      }
    }
    if (!ref_color) {
      ref_color = "#47C8FF";
    }
    if (tk.is_same_ref == true) {
      html_text.push(
        '<svg width="10" height="10" style = "display:inline-block;"><rect width="10" height="10" style="fill:' + ref_color + ';" /> </svg> ' + tk.variants[0].ref
      );
    } else {
      html_text.push(
        '<svg width="10" height="10" style = "display:inline-block;"><rect width="10" height="10" style="fill:' + ref_color + ';" /> </svg> Combined reference allele'
      );
    }
    if (!tk.gdcFile) {
      html_text.push(
        "<br><a href='https://proteinpaint.stjude.org/bam' target='_blank'>Click here to view details of this method</a>."
      );
    }
    tk.dom.alleleSimilarityHeaderLabel.on("click", (event) => {
      const b = event.target.getBoundingClientRect();
      tk.tktip.clear().show(b.x - 250, b.y);
      tk.tktip.d.append("div").style("width", "300px").html(html_text.join("<br>"));
    });
  }
}
function setTkHeight(tk) {
  let h = 0;
  if (tk.pileup_shown) h += tk.pileupheight + tk.pileupbottompad;
  if (tk.toomanyreads) {
    h += tk.dom.read_limit_height;
    tk.dom.read_limit_text.attr("y", h);
    h += tk.dom.read_limit_bottompad;
  }
  if (tk.dom.variantg) {
    tk.dom.variantg.attr("transform", "translate(0," + h + ")");
  }
  if (tk.dom.alleleSimilarityHeaderG) {
    tk.dom.alleleSimilarityHeaderG.attr("transform", "translate(0," + (tk.pileupheight - tk.pileupbottompad * 2) + ")");
  }
  let var_idx = 0;
  for (const g of tk.groups) {
    if (g.data.type.includes("support_alt")) {
      g.variantg.attr("transform", "translate(0," + h + ")");
      h += tk.dom.variantrowheight + tk.dom.variantrowbottompad;
      var_idx += 1;
    }
    g.dom.groupg.transition().attr("transform", "translate(0," + h + ")");
    g.dom.rightg.transition().attr("transform", "translate(0," + h + ")");
    g.msgheight = messagerowheight * g.data.messages.length;
    g.dom.leftg.transition().attr("transform", "translate(0," + (h + g.msgheight) + ")");
    g.dom.imgg.transition().attr("transform", "translate(0," + g.msgheight + ")");
    if (tk.variants) {
      g.dom.diff_score_barplot_fullstack.transition().attr("transform", "translate(0," + g.msgheight + ")");
    }
    if (g.partstack) {
      if (tk.variants) {
        g.dom.diff_score_barplot_partstack.transition().attr("transform", "translate(0," + g.msgheight + ")");
        g.dom.rightg.vslider.g.transition().attr("transform", "translate(" + tk.dom.diff_score_plotwidth * 1.1 + "," + g.msgheight + ") scale(1)");
      } else {
        g.dom.rightg.vslider.g.transition().attr("transform", "translate(0,0) scale(1)");
      }
    }
    h += g.data.height + g.msgheight;
    if (g.data.type.includes("support_alt") && var_idx < tk.variants.length) {
      h += tk.dom.variantrowheight;
    }
  }
  tk.height_main = tk.height = h;
  tk.height_main += tk.toppad + tk.bottompad;
}
function updateExistingGroups(data, tk, block) {
  for (let i = 0; i < tk.groups.length; i++) {
    const group = data.groups.find((g) => g.type == tk.groups[i].data.type);
    if (!group) {
      deleteGroupDom(tk.groups[i]);
      tk.groups.splice(i, 1);
    }
  }
  for (const gd of data.groups) {
    const group = tk.groups.find((g) => g.data.type == gd.type);
    if (!group) {
      const g = makeGroup(gd, tk, block, data);
      tk.groups.push(g);
    } else {
      group.data = gd;
      update_boxes(group, tk, block);
      group.dom.img_fullstack.attr("xlink:href", group.data.src).attr("width", group.data.width).attr("height", group.data.height);
      if (tk.variants) {
        group.ReadNameMaxwidth = 0;
        if (tk.show_readnames) {
          if (group.data.templatebox) {
            group.dom.read_names_g.selectAll("*").remove();
            let read_count = 1;
            for (const read of group.data.templatebox) {
              const read_name_bbox = group.dom.read_names_g.append("text").attr("x", 0).attr("y", group.data.height * read_count / group.data.templatebox.length).attr("text-anchor", "end").style("fill", "black").attr("font-size", group.data.height / group.data.templatebox.length).text(read.qname);
              group.ReadNameMaxwidth = Math.max(group.ReadNameMaxwidth, read_name_bbox.node().getBBox().width);
              read_count += 1;
            }
          }
        } else {
          group.dom.read_names_g.selectAll("*").remove();
          group.ReadNameMaxwidth = 0;
        }
        if (group.my_partstack) {
          if (group.data.allowpartstack) {
            enter_partstack(group, tk, block, group.my_partstack, data);
          }
        } else {
          group.dom.diff_score_barplot_fullstack.attr("xlink:href", gd.diff_scores_img.src).attr("width", gd.diff_scores_img.width).attr("height", gd.diff_scores_img.height);
        }
      }
      group.dom.img_partstack.attr("width", 0).attr("height", 0);
      if (tk.variants) {
        group.dom.diff_score_barplot_partstack.attr("width", 0).attr("height", 0);
      }
      group.dom.rightg.vslider.g.transition().attr("transform", "scale(0)");
      group.dom.img_cover.attr("width", group.data.width).attr("height", group.data.height);
    }
  }
}
function update_boxes(group, tk, block) {
  group.dom.box_move.attr("width", 0);
  update_box_stay(group, tk, block);
}
function update_box_stay(group, tk, block) {
  if (!group.data.templatebox) {
    group.dom.box_stay.attr("width", 0);
    return;
  }
  if (!group.clickedtemplate) {
    group.dom.box_stay.attr("width", 0);
    return;
  }
  for (const t of group.data.templatebox) {
    if (t.qname == group.clickedtemplate.qname) {
      if (tk.asPaired || t.isfirst && group.clickedtemplate.isfirst || t.islast && group.clickedtemplate.islast) {
        const bx1 = Math.max(0, t.x1);
        const bx2 = Math.min(block.width, t.x2);
        group.dom.box_stay.attr("width", bx2 - bx1).attr("height", t.y2 - t.y1).attr("transform", "translate(" + bx1 + "," + t.y1 + ")");
        return;
      }
    }
  }
  group.dom.box_stay.attr("width", 0);
}
function deleteGroupDom(g) {
  g.dom.message_rowg.remove();
  g.dom.img_fullstack.remove();
  g.dom.img_partstack.remove();
  g.dom.diff_score_barplot_fullstack?.remove();
  g.dom.diff_score_barplot_partstack?.remove();
  g.dom.read_names_g?.remove();
  g.dom.leftg.remove();
  g.dom.box_stay?.remove();
  g.dom.box_move?.remove();
  g.dom.rightg.remove();
}
function makeTk(tk, block) {
  if (tk.gdcFile) {
    block.gdcBamSliceDownloadBtn.style("display", "inline-block");
  }
  may_add_urlparameter(tk, block);
  if (tk.drop_pcrduplicates == void 0) {
    tk.drop_pcrduplicates = true;
  }
  tk.drop_supplementary_alignments = false;
  if (tk.show_readnames == void 0) {
    tk.show_readnames = false;
  }
  tk.config_handle = block.maketkconfighandle(tk).attr("y", 10 + block.labelfontsize).on("click", () => {
    configPanel(tk, block);
  });
  tk.readMenu = new Menu();
  tk.readMenu.d.style("max-width", "90vw").style("max-height", "65vh").attr("class", "sjpp_show_scrollbar");
  tk.multiAlignMenu = new Menu();
  tk.multiAlignMenu.d.style("max-width", "90vw").style("max-height", "65vh").attr("class", "sjpp_show_scrollbar");
  tk.pileupheight = 100;
  tk.pileupbottompad = 6;
  tk.dom = {
    pileup_g: tk.glider.append("g"),
    pileup_axis: tk.glider.append("g"),
    read_limit_height: 15,
    read_limit_bottompad: 6,
    read_limit_g: tk.glider.append("g")
  };
  tk.dom.pileup_img = tk.dom.pileup_g.append("image");
  tk.dom.read_limit_text = tk.dom.read_limit_g.append("text").style("fill", "red").attr("text-anchor", "middle").attr("font-size", tk.dom.read_limit_height).attr("transform", "scale(0)");
  if (tk.variants) {
    tk.dom.variantg = tk.glider.append("g");
    tk.dom.alleleSimilarityHeaderG = tk.gright.append("g");
    tk.dom.variantrowheight = 15;
    tk.dom.variantrowbottompad = 5;
    tk.dom.diff_score_plotwidth = 20;
    tk.fs_string = block.maketklefthandle(tk, tk.pileupheight + tk.dom.variantrowheight / 2);
  } else if (tk.sv) {
    tk.dom.variantg = tk.glider.append("g");
    tk.dom.variantrowheight = 15;
    tk.dom.variantrowbottompad = 5;
  }
  tk.asPaired = false;
  let laby = block.labelfontsize + 5;
  tk.leftlabel_count = block.maketklefthandle(tk, laby);
  laby += block.labelfontsize;
  tk.leftlabel_skip = block.maketklefthandle(tk, laby).text("");
  if (tk.aboutThisFile) {
    laby += block.labelfontsize;
    tk.leftlabel_about = block.maketklefthandle(tk, laby).text("About the BAM file").on("mouseover", (event) => {
      tk.tktip.showunder(event.target).clear();
      const t = table2col({ holder: tk.tktip.d });
      for (const r of tk.aboutThisFile) t.addRow(r.k, r.v);
    }).on("mouseout", () => {
      tk.tktip.hide();
    });
  }
  delete tk.alleleAlreadyUpdated;
  if (tk.groups) {
    for (const g of tk.groups) deleteGroupDom(g);
    delete tk.groups;
  }
}
function may_add_urlparameter(tk, block) {
  const u2p = urlmap_default();
  if (u2p.has("variant")) {
    tk.variants = [];
    if (typeof u2p.get("variant") == "string") {
      const tmp = u2p.get("variant").split(".");
      if (tmp.length == 4) {
        const pos = Number(tmp[1]);
        if (!Number.isInteger(pos)) throw "urlparam variant pos is not integer";
        if (!tmp[2]) throw "ref allele missing";
        if (!tmp[3]) throw "alt allele missing";
        tk.variants.push({ chr: tmp[0], pos: pos - 1, ref: tmp[2], alt: tmp[3], strictness: 1 });
      }
    } else {
      const variant_json = u2p.get("variant");
      for (const item of variant_json.variants) {
        if (!Number.isInteger(item.pos)) throw "urlparam variant pos is not integer";
        if (!item.ref) throw "ref allele missing";
        if (!item.alt) throw "alt allele missing";
        tk.variants.push({ chr: variant_json.chr, pos: Number(item.pos) - 1, ref: item.ref, alt: item.alt });
      }
    }
    if (u2p.has("strictness")) {
      const tmp = u2p.get("strictness");
      if (!Number.isInteger(Number(tmp))) throw "strictness must be an integer";
      tk.strictness = Number(tmp);
      if (tk.strictness != 1 && tk.strictness != 0) {
        throw "strictness must be 0 or 1";
      }
    } else {
      tk.strictness = 1;
    }
  } else if (u2p.has("sv")) {
    const tmp = u2p.get("sv").split(".");
    tk.sv = [];
    if (tmp.length == 7) {
      tk.sv.push({
        chrA: tmp[0],
        startA: tmp[1],
        strandA: tmp[2],
        chrB: tmp[3],
        startB: tmp[4],
        strandB: tmp[5],
        contig: tmp[6]
      });
    } else if (tmp.length == 6) {
      tk.sv.push({
        chrA: tmp[0],
        startA: tmp[1],
        strandA: tmp[2],
        chrB: tmp[3],
        startB: tmp[4],
        strandB: tmp[5]
      });
    }
  }
}
function makeGroup(gd, tk, block, data) {
  const group = {
    data: gd,
    dom: {
      groupg: tk.glider.append("g"),
      rightg: tk.gright.append("g"),
      leftg: tk.gleft.append("g")
    }
  };
  group.dom.message_rowg = group.dom.groupg.append("g");
  group.dom.imgg = group.dom.groupg.append("g");
  group.dom.rightg.vslider = group.dom.rightg.append("g");
  group.dom.rightg.vslider.g = group.dom.rightg.vslider.append("g").attr("transform", "scale(0)");
  if (tk.variants) {
    group.dom.diff_score_g = group.dom.rightg.append("g");
    group.dom.read_names_g = group.dom.leftg.append("g");
    group.dom.diff_score_barplot_fullstack = group.dom.diff_score_g.append("image").attr("xlink:href", gd.diff_scores_img.src).attr("width", gd.diff_scores_img.width).attr("height", gd.diff_scores_img.height);
    group.dom.diff_score_barplot_partstack = group.dom.diff_score_g.append("image").attr("xlink:href", gd.diff_scores_img.src).attr("width", 0).attr("height", 0);
    if (!group.allowpartstack && !Number.isFinite(tk.max_diff_score) && tk.variants) {
      tk.max_diff_score = data.max_diff_score;
      tk.min_diff_score = data.min_diff_score;
    }
    let diff_score_height = tk.pileupheight + tk.dom.variantrowheight * 2;
    if (tk.toomanyreads) {
      diff_score_height = tk.pileupheight + tk.dom.variantrowheight * 3;
    }
  }
  group.dom.img_fullstack = group.dom.imgg.append("image").attr("xlink:href", group.data.src).attr("width", group.data.width).attr("height", group.data.height);
  group.dom.img_partstack = group.dom.imgg.append("image").attr("width", 0).attr("height", 0);
  group.dom.box_move = group.dom.imgg.append("rect").attr("stroke", "black").attr("fill", "none");
  group.dom.box_stay = group.dom.imgg.append("rect").attr("stroke", "magenta").attr("fill", "none");
  let mousedownx;
  const left_margin = tk.regions[0].x;
  const right_margin = tk.regions[tk.regions.length - 1].x + tk.regions[tk.regions.length - 1].width;
  group.dom.img_cover = group.dom.imgg.append("rect").attr("fill", "white").attr("fill-opacity", 0).attr("width", group.data.width).attr("height", group.data.height).on("mousedown", (event) => {
    mousedownx = event.clientX;
  }).on("mousemove", (event) => {
    if (group.data.allowpartstack) {
      return;
    }
    if (!group.data.templatebox) return;
    const [mx, my] = pointer_default(event, group.dom.img_cover.node());
    let read_number = 0;
    for (const t of group.data.templatebox) {
      read_number += 1;
      const bx1 = Math.max(t.x1, left_margin);
      const bx2 = Math.min(t.x2, right_margin);
      if (mx > bx1 && mx < bx2 && my > t.y1 && my < t.y2) {
        group.dom.box_move.attr("width", bx2 - bx1).attr("height", t.y2 - t.y1).attr("transform", "translate(" + bx1 + "," + t.y1 + ")");
        if (tk.readAlignmentTable && tk.readAlignmentTableGroup == group.data.type) {
          updateExistingMultiReadAligInfo(tk, read_number);
        } else if (tk.readAlignmentTable && tk.readAlignmentTableGroup != group.data.type) {
          updateExistingMultiReadAligInfo(tk, group.data.templatebox.length + 10);
        }
        return;
      }
    }
  }).on("click", (event) => {
    if (mousedownx != event.clientX) return;
    const [mx, my] = pointer_default(event, group.dom.img_cover.node());
    group.my_partstack = my;
    if (group.data.allowpartstack) {
      enter_partstack(group, tk, block, my, data);
      return;
    }
    if (!group.data.templatebox) return;
    tk.readMenu.clear().show(50, event.clientY);
    let readNotShown = true;
    for (let region_idx = 0; region_idx < tk.regions.length; region_idx += 1) {
      for (const t of group.data.templatebox) {
        const cx1 = Math.max(t.x1, left_margin);
        const cx2 = Math.min(t.x2, right_margin);
        const bx1 = Math.max(tk.regions[region_idx].x, t.x1);
        const bx2 = Math.min(tk.regions[region_idx].x + tk.regions[region_idx].width, t.x2);
        if (mx > bx1 && mx < bx2 && my > t.y1 && my < t.y2) {
          if (group.clickedtemplate && group.clickedtemplate.qname == t.qname) {
            if (tk.asPaired || t.isfirst && group.clickedtemplate.isfirst || t.islast && group.clickedtemplate.islast) {
              delete group.clickedtemplate;
              group.dom.box_stay.attr("width", 0);
              break;
            }
          }
          group.clickedtemplate = {
            qname: t.qname
          };
          if (tk.asPaired) {
            group.clickedtemplate.isfirst = true;
          } else {
            if (t.isfirst) group.clickedtemplate.isfirst = true;
            if (t.islast) group.clickedtemplate.islast = true;
          }
          group.dom.box_stay.attr("width", cx2 - cx1).attr("height", t.y2 - t.y1).attr("transform", "translate(" + cx1 + "," + t.y1 + ")");
          getReadInfo(tk, block, t, region_idx);
          readNotShown = false;
        }
      }
    }
    if (readNotShown) tk.readMenu.hide();
  });
  group.dom.rightg.vslider.bar = group.dom.rightg.vslider.g.append("rect").attr("fill", slider_rail_color).attr("x", 10).attr("width", 20).on("mouseover", () => group.dom.rightg.vslider.bar.attr("fill", "#fae8e8")).on("mouseout", () => group.dom.rightg.vslider.bar.attr("fill", slider_rail_color)).on("click", () => {
    delete group.dom.rightg.vslider.boxy;
    delete group.partstack;
    if (group.my_partstack) {
      delete group.my_partstack;
    }
    group.ReadNameMaxwidth = 0;
    group.data = group.data_fullstack;
    renderGroup(group, tk, block);
    setTkHeight(tk);
    block.block_setheight();
  });
  group.dom.rightg.vslider.boxg = group.dom.rightg.vslider.g.append("g");
  group.dom.rightg.vslider.box = group.dom.rightg.vslider.boxg.append("rect").attr("fill", slider_color).attr("width", 40).on("mousedown", (event) => {
    event.preventDefault();
    group.dom.rightg.vslider.box.attr("fill", slider_color_dark);
    const scrollableheight = group.data.height;
    const y0 = event.clientY;
    let deltay = 0;
    const b = select_default(document.body);
    b.on("mousemove", (event2) => {
      const y1 = event2.clientY;
      const d = y1 - y0;
      if (d < 0) {
        if (group.dom.rightg.vslider.boxy + d <= 0) return;
      } else {
        if (group.dom.rightg.vslider.boxy + d >= scrollableheight - group.dom.rightg.vslider.boxh) return;
      }
      deltay = d;
      if (tk.variants) {
        group.dom.diff_score_barplot_partstack.attr(
          "transform",
          "translate(0," + (-1 * deltay * group.data_fullstack.stackcount * group.data.stackheight / scrollableheight + group.msgheight) + ")"
        );
        group.dom.read_names_g.attr(
          "transform",
          "translate(0," + -1 * deltay * group.data_fullstack.stackcount * group.data.stackheight / scrollableheight + ")"
        );
      }
      group.dom.rightg.vslider.boxg.attr("transform", "translate(0," + (group.dom.rightg.vslider.boxy + deltay) + ")");
      group.dom.img_partstack.attr(
        "y",
        -(deltay * group.data_fullstack.stackcount * group.data.stackheight / scrollableheight)
      );
      group.dom.box_move.attr("width", 0);
      group.dom.box_stay.attr("width", 0);
    });
    b.on("mouseup", async () => {
      group.dom.rightg.vslider.box.attr("fill", slider_color);
      b.on("mousemove", null).on("mouseup", null);
      if (deltay == 0) return;
      group.dom.rightg.vslider.boxy += deltay;
      const delta = Math.ceil(group.data_fullstack.stackcount * deltay / scrollableheight);
      group.partstack.start += delta;
      group.partstack.stop += delta;
      block.tkcloakon(tk);
      const _d = await getData(tk, block, {
        stackstart: group.partstack.start,
        stackstop: group.partstack.stop,
        grouptype: group.data.type
      });
      group.data = _d.groups[0];
      renderGroup(group, tk, block);
      setTkHeight(tk);
      block.tkcloakoff(tk, {});
      block.block_setheight();
    });
  });
  group.dom.rightg.vslider.boxtopline = group.dom.rightg.vslider.boxg.append("line").attr("stroke", slider_color_dark).attr("stroke-width", 3).attr("x2", 40).on("mouseover", () => group.dom.rightg.vslider.boxtopline.attr("stroke", slider_color_dark_line)).on("mouseout", () => group.dom.rightg.vslider.boxtopline.attr("stroke", slider_color_dark)).on("mousedown", (event) => {
    event.preventDefault();
    const scrollableheight = group.data.height;
    const y0 = event.clientY;
    let deltay = 0;
    const b = select_default(document.body);
    b.on("mousemove", (event2) => {
      const y1 = event2.clientY;
      const d = y1 - y0;
      if (d < 0) {
        if (group.dom.rightg.vslider.boxy + d <= 0) return;
      } else {
        if (group.dom.rightg.vslider.boxh - d <= stackpagesize * scrollableheight / group.data_fullstack.stackcount)
          return;
      }
      deltay = d;
      group.dom.rightg.vslider.boxg.attr("transform", "translate(0," + (group.dom.rightg.vslider.boxy + deltay) + ")");
      group.dom.rightg.vslider.box.attr("height", group.dom.rightg.vslider.boxh - deltay);
      group.dom.rightg.vslider.boxbotline.attr("y1", group.dom.rightg.vslider.boxh - deltay).attr("y2", group.dom.rightg.vslider.boxh - deltay);
    });
    b.on("mouseup", async () => {
      b.on("mousemove", null).on("mouseup", null);
      if (deltay == 0) return;
      group.dom.rightg.vslider.boxy += deltay;
      group.partstack.start += Math.ceil(group.data_fullstack.stackcount * deltay / scrollableheight);
      block.tkcloakon(tk);
      const _d = await getData(tk, block, {
        stackstart: group.partstack.start,
        stackstop: group.partstack.stop,
        grouptype: group.data.type
      });
      group.data = _d.groups[0];
      renderGroup(group, tk, block);
      block.tkcloakoff(tk, {});
      setTkHeight(tk);
      block.block_setheight();
    });
  });
  group.dom.rightg.vslider.boxbotline = group.dom.rightg.vslider.boxg.append("line").attr("stroke", slider_color_dark).attr("stroke-width", 3).attr("x2", 40).on("mouseover", () => group.dom.rightg.vslider.boxbotline.attr("stroke", slider_color_dark_line)).on("mouseout", () => group.dom.rightg.vslider.boxbotline.attr("stroke", slider_color_dark)).on("mousedown", (event) => {
    event.preventDefault();
    const scrollableheight = group.data.height;
    const y0 = event.clientY;
    let deltay = 0;
    const b = select_default(document.body);
    b.on("mousemove", (event2) => {
      const y1 = event2.clientY;
      const d = y1 - y0;
      if (d < 0) {
        if (group.dom.rightg.vslider.boxh + d <= stackpagesize * scrollableheight / group.data_fullstack.stackcount)
          return;
      } else {
        if (group.dom.rightg.vslider.boxy + d >= scrollableheight - group.dom.rightg.vslider.boxh) return;
      }
      deltay = d;
      group.dom.rightg.vslider.box.attr("height", group.dom.rightg.vslider.boxh + deltay);
      group.dom.rightg.vslider.boxbotline.attr("y1", group.dom.rightg.vslider.boxh + deltay).attr("y2", group.dom.rightg.vslider.boxh + deltay);
    });
    b.on("mouseup", async () => {
      b.on("mousemove", null).on("mouseup", null);
      if (deltay == 0) return;
      group.dom.rightg.vslider.boxh += deltay;
      group.partstack.stop += Math.ceil(group.data_fullstack.stackcount * deltay / scrollableheight);
      block.tkcloakon(tk);
      const _d = await getData(tk, block, {
        stackstart: group.partstack.start,
        stackstop: group.partstack.stop,
        grouptype: group.data.type
      });
      group.data = _d.groups[0];
      renderGroup(group, tk, block);
      setTkHeight(tk);
      block.tkcloakoff(tk, {});
      block.block_setheight();
    });
  });
  return group;
}
async function align_reads_to_allele(tk, group, block) {
  const body = {
    alignOneGroup: group.data.type,
    genome: block.genome.name,
    regions: tk.regions,
    variant: tk.variants.map((m) => m.chr + "." + m.pos + "." + m.ref + "." + m.alt).join(".")
  };
  if (tk.file) body.file = tk.file;
  if (tk.url) body.url = tk.url;
  if (tk.indexURL) body.indexURL = tk.indexURL;
  if (tk.gdcFile) {
    body.gdcFileUUID = tk.gdcFile.uuid;
    body.gdcFilePosition = tk.gdcFile.position;
  }
  if (tk.alleleAlreadyUpdated) {
    body.alleleAlreadyUpdated = 1;
    body.refseqs = tk.variants.refseqs;
    body.altseqs = tk.variants.altseqs;
    body.refalleles = tk.variants.refalleles;
    body.altalleles = tk.variants.altalleles;
    body.leftflankseqs = tk.variants.leftflankseqs;
    body.rightflankseqs = tk.variants.rightflankseqs;
    body.ref_positions = tk.variants.ref_positions;
    body.strictness = tk.strictness;
  }
  if (tk.asPaired) body.asPaired = 1;
  if ("nochr" in tk) body.nochr = tk.nochr;
  if (tk.drop_pcrduplicates) body.drop_pcrduplicates = 1;
  if (tk.drop_supplementary_alignments) body.drop_supplementary_alignments = 1;
  if (group.partstack) {
    body.stackstart = group.partstack.start;
    body.stackstop = group.partstack.stop;
    body.grouptype = group.data.type;
  }
  return await dofetch3("tkbam", { headers: getHeaders(tk), body });
}
function getHeaders(tk) {
  const headers = { "Content-Type": "application/json", Accept: "application/json" };
  if (tk.gdcToken) headers["X-Auth-Token"] = tk.gdcToken;
  return headers;
}
function configPanel(tk, block) {
  {
    const b = tk.config_handle.node().getBoundingClientRect();
    tk.tkconfigtip.clear().show(b.x - 300, b.y);
  }
  const d = tk.tkconfigtip.d.append("div").style("max-width", "50vw");
  {
    const row = d.append("div");
    row.append("span").html("Show reads as:&nbsp;").style("opacity", 0.5).style("margin", "10px 5px");
    make_radios({
      holder: row,
      options: [
        { label: "Single", value: false, checked: !tk.asPaired },
        { label: "Paired", value: true, checked: tk.asPaired }
      ],
      styles: { margin: "10px 5px" },
      callback: (v) => {
        tk.asPaired = v;
        loadTk(tk, block);
      }
    });
  }
  {
    make_one_checkbox({
      holder: d.append("div"),
      labeltext: "Drop PCR or optical duplicates",
      checked: tk.drop_pcrduplicates,
      divstyle: { display: "block", margin: "10px 5px", height: "10px", "margin-left": "6.5px" },
      callback: () => {
        tk.drop_pcrduplicates = !tk.drop_pcrduplicates;
        loadTk(tk, block);
      }
    });
  }
  if (tk.variants) {
    make_one_checkbox({
      holder: d.append("div"),
      labeltext: "Show read names",
      checked: tk.show_readnames,
      divstyle: { display: "block", margin: "10px 5px", height: "10px", "margin-left": "6.5px" },
      callback: () => {
        tk.show_readnames = !tk.show_readnames;
        loadTk(tk, block);
      }
    });
    if (tk.variants[0].strictness == 0) {
    } else if (!tk.variants[0].strictness) {
      tk.variants[0].strictness = 1;
    }
    const row = d.append("div");
    row.append("span").html("Strictness: ").style("display", "block").style("height", "10px").style("opacity", 0.5).style("margin", "10px 5px").style("margin-top", "20px");
    make_radios({
      holder: row,
      options: [
        {
          label: 'Lenient: "None group" is not generated.',
          value: 0,
          checked: tk.strictness == 0
        },
        {
          label: 'Strict: "None group" is generated for reads with imperfect match to both reference and alternative alleles.',
          value: 1,
          checked: tk.strictness == 1
        }
      ],
      styles: { display: "block", margin: "10px 5px", height: "10px", "margin-left": "30px" },
      callback: (v) => {
        tk.strictness = v;
        loadTk(tk, block);
      }
    });
  }
  d.append("div").style("display", "inline-block").style("height", "10px").style("margin-top", "20px").style("font-size", ".8em").html(`
	<ul style="padding-left:15px">
	  <li><b>Matches</b> are rendered as gray boxes aligned to the reference.</li>
	  <li><b>Mismatches</b> will be checked when 1 bp is wider than 1 pixel, and are rendered as red boxes aligned to the reference.</li>
	  <li><b>Softclips</b> are rendered as blue boxes not aligned to the reference.</li>
	  <li><b>Base qualities</b> are rendered when 1 bp is wider than 2 pixels. See color scale below. When base quality is not used or is unavailable, full colors are used.</li>
	  <li><b>Sequences</b> from mismatch and softclip will be printed when 1 bp is wider than 7 pixels.</li>
	  <li>An <b>insertion</b> with on-screen size wider than 1 pixel will be rendered as cyan text between aligned bases, in either a letter or the number of inserted bp. Text color scales by average base quality when that is in use.</li>
	  <li><b>Deletions</b> are gaps joined by black horizontal lines.</li>
	  <li><b>Split reads</b> and splice junctions are indicated by solid gray lines.</li>
	  <li><b>Read pairs</b> are joined by dashed gray lines.</li>
          <li><b>Discordant reads</b> Discordant reads are colored based on their respective features as described below:<ul style="list-style-type:none;"> <li> <svg width="10" height="10" style = "display:inline-block;"> <rect width="10" height="10" style="fill:#3B7A57;" /> </svg> Read pair has wrong insert size </li> <li> <svg width="10" height="10" style = "display:inline-block;"> <rect width="10" height="10" style="fill:#6B4423;" /> </svg> Mate is unmapped </li> <li> <svg width="10" height="10" style = "display:inline-block;"> <rect width="10" height="10" style="fill:#fc6df3;" /> </svg> Wrong orientation </li> <li> <svg width="10" height="10" style = "display:inline-block;"> <rect width="10" height="10" style="fill:#d48b37;" /> </svg> Mate mapped to different chromosome </li> </ul>
          </li>  
	</ul>`);
  d.append("div").style("margin-top", "10px").append("img").attr("width", tk.colorscale.width).attr("height", tk.colorscale.height).attr("src", tk.colorscale.src);
  d.append("div").style("font-size", ".8em").html(`
`);
}
function click_groupheader(tk, group, block) {
  if (tk.variants) {
    click_groupheader_showMultiReadAlign(tk, group, block);
  }
}
function updateExistingMultiReadAligInfo(tk, read_number) {
  const rows = tk.readAlignmentTable._groups[0][0].querySelectorAll("tr");
  rows.forEach((row) => {
    if (row.rowIndex == read_number + 1 && !tk.is_align_gene) {
      row.style.setProperty("font-weight", "bold");
      const cols = row.querySelectorAll("td");
      cols.forEach((col) => {
        if (col.style.backgroundColor.toString() == "rgb(255, 255, 255)") {
          col.style.setProperty("background-color", "yellow");
        }
      });
    } else if (row.rowIndex == read_number + 2 && tk.is_align_gene) {
      row.style.setProperty("font-weight", "bold");
      const cols = row.querySelectorAll("td");
      cols.forEach((col) => {
        if (col.style.backgroundColor.toString() == "rgb(255, 255, 255)") {
          col.style.setProperty("background-color", "yellow");
        }
      });
    } else {
      row.style.setProperty("font-weight", "normal");
      const cols = row.querySelectorAll("td");
      cols.forEach((col) => {
        if (col.style.backgroundColor.toString() == "yellow") {
          col.style.setProperty("background-color", "rgb(255, 255, 255)");
        }
      });
    }
  });
}
async function create_gene_models_refalt(tk, block, multi_read_alig_data, group, alt_var_idx) {
  const gene_model_images = [];
  const break_points = [];
  const gene_model_order = [];
  let refalt_seq = multi_read_alig_data.alignmentData.final_read_align[0];
  let left_most_pos = tk.variants[0].pos - tk.variants.leftflankseqs[0].length;
  let right_most_pos = tk.variants[0].pos + tk.variants.rightflankseqs[0].length;
  if (group.data.type == "support_alt" + alt_var_idx.toString()) {
    left_most_pos = tk.variants[alt_var_idx].pos - tk.variants.leftflankseqs[alt_var_idx].length;
    right_most_pos = tk.variants[alt_var_idx].pos + tk.variants.rightflankseqs[alt_var_idx].length;
  }
  let segstart = left_most_pos;
  let segstop = left_most_pos;
  let local_alignment_width = 0;
  let first_row = tk.readAlignmentTable.node().children[0];
  let gm_nuc_count = 0;
  let prev_nclt_not_blank = false;
  let nclt_count = 0;
  for (const nclt of refalt_seq) {
    if (nclt == "-") {
      if (prev_nclt_not_blank == true) {
        break_points.push(1);
        gene_model_order.push("break");
        segstart += 1;
        segstop += 1;
      } else {
        const gene_model_image = await get_gene_models_refalt(block, tk, segstart, segstop - 1, local_alignment_width);
        const gm = {
          src: gene_model_image.src,
          width: local_alignment_width,
          height: gene_model_image.height,
          colspan: gm_nuc_count
        };
        gene_model_images.push(gm);
        gene_model_order.push("gene_model");
        gm_nuc_count = 0;
        segstart = left_most_pos + nclt_count + 1;
        segstop = left_most_pos + nclt_count + 1;
        local_alignment_width = 0;
        prev_nclt_not_blank = true;
        break_points.push(1);
        gene_model_order.push("break");
      }
      gm_nuc_count += 1;
      local_alignment_width += first_row.children[nclt_count].getBoundingClientRect().width;
    } else if (group.data.type == "support_alt" + alt_var_idx.toString() && tk.variants[alt_var_idx].alt.length > tk.variants[alt_var_idx].ref.length && // Insertion case
    tk.variants[alt_var_idx].pos < left_most_pos + nclt_count && tk.variants[alt_var_idx].pos + tk.variants[alt_var_idx].alt.length - 1 >= left_most_pos + nclt_count) {
    } else if (tk.variants[0].pos == left_most_pos + nclt_count && group.data.type == "support_alt" + alt_var_idx.toString()) {
      if (tk.variants[alt_var_idx].ref.length == 1 && tk.variants[alt_var_idx].alt.length == 1) {
        continue;
      }
      if (tk.variants[alt_var_idx].ref.length >= tk.variants[alt_var_idx].alt.length) {
        segstop += 1;
        gm_nuc_count += 1;
        local_alignment_width += first_row.children[nclt_count + 1].getBoundingClientRect().width;
      }
      const gene_model_image = await get_gene_models_refalt(block, tk, segstart, segstop, local_alignment_width);
      const gm = {
        src: gene_model_image.src,
        width: local_alignment_width,
        height: gene_model_image.height,
        colspan: gm_nuc_count
      };
      gene_model_images.push(gm);
      gene_model_order.push("gene_model");
      gm_nuc_count = 0;
      segstart = left_most_pos + nclt_count + tk.variants[alt_var_idx].ref.length;
      segstop = left_most_pos + nclt_count + tk.variants[alt_var_idx].ref.length;
      if (tk.variants[alt_var_idx].ref.length < tk.variants[alt_var_idx].alt.length) {
        break_points.push(tk.variants[0].alt.length);
        gene_model_order.push("break");
      }
      local_alignment_width = 0;
      prev_nclt_not_blank = false;
    } else if (nclt_count == refalt_seq.length - 1) {
      segstop += 1;
      gm_nuc_count += 1;
      local_alignment_width += first_row.children[nclt_count].getBoundingClientRect().width;
      const gene_model_image = await get_gene_models_refalt(block, tk, segstart, segstop, local_alignment_width);
      const gm = {
        src: gene_model_image.src,
        width: local_alignment_width,
        height: gene_model_image.height,
        colspan: gm_nuc_count
      };
      gene_model_images.push(gm);
      gene_model_order.push("gene_model");
    } else {
      segstop += 1;
      gm_nuc_count += 1;
      local_alignment_width += first_row.children[nclt_count].getBoundingClientRect().width;
      prev_nclt_not_blank = false;
    }
    nclt_count += 1;
  }
  let j = 0;
  let k = 0;
  const gene_model_tr = tk.readAlignmentTable.node().insertRow();
  if (tk.readAlignmentTable.node().children.length >= 3) {
    const first_read = tk.readAlignmentTable.node().children[2];
    tk.readAlignmentTable.node().insertBefore(gene_model_tr, first_read);
  } else {
    console.log("Possible problem in placing gene model in table. Please check");
  }
  for (let i = 0; i < gene_model_order.length; i++) {
    const gene_models_cell = gene_model_tr.insertCell();
    if (gene_model_order[i] == "gene_model") {
      const img = document.createElement("img");
      img.src = gene_model_images[k].src;
      img.width = gene_model_images[k].width;
      img.height = gene_model_images[k].height;
      gene_models_cell.appendChild(img);
      gene_models_cell.colSpan = gene_model_images[k].colspan;
      k += 1;
    } else if (gene_model_order[i] == "break") {
      gene_models_cell.colSpan = break_points[j];
      j += 1;
    }
  }
}
async function click_groupheader_showMultiReadAlign(tk, group, block) {
  tk.multiAlignMenu.clear().show(50, 100);
  const wait = tk.multiAlignMenu.d.append("div").text("Loading...");
  try {
    const data = await align_reads_to_allele(tk, group, block);
    if (data.error) {
      wait.remove();
      sayerror(tk.multiAlignMenu.d, "Realignment of reads in ambiguous group is not currently implemented.");
      setTimeout(() => tk.multiAlignMenu.d.remove(), 3e3);
      return;
    }
    wait.remove();
    let alt_var_idx = 0;
    let ref_start_stops = [];
    let highlight_regions_in_refallele = [];
    if (group.data.type.includes("support_alt")) {
      for (let var_idx = 0; var_idx < tk.variants.length; var_idx++) {
        if (group.data.type == "support_alt" + var_idx.toString()) {
          alt_var_idx = var_idx;
        }
      }
    } else if (group.data.type == "support_ref") {
      for (let var_idx = 0; var_idx < tk.variants.length; var_idx++) {
        ref_start_stops.push({
          start: tk.variants[var_idx].pos,
          stop: tk.variants[var_idx].pos + tk.variants[var_idx].ref.length
        });
      }
      ref_start_stops.sort((i, j) => i.start - j.start);
      let old_variant = { start: ref_start_stops[0].start, stop: ref_start_stops[0].stop };
      highlight_regions_in_refallele.push(ref_start_stops[0].start);
      let break_point = false;
      for (let var_idx = 1; var_idx < ref_start_stops.length; var_idx++) {
        if (ref_start_stops[var_idx].start <= old_variant.stop && old_variant.stop <= ref_start_stops[var_idx].stop) {
          old_variant = ref_start_stops[var_idx];
        } else if (old_variant.stop > ref_start_stops[var_idx].stop) {
          continue;
        } else {
          highlight_regions_in_refallele.push(old_variant.stop);
          highlight_regions_in_refallele.push(ref_start_stops[var_idx].start);
        }
      }
      highlight_regions_in_refallele.push(Math.max(old_variant.stop, ref_start_stops[ref_start_stops.length - 1].stop));
    }
    if (data.alignmentData.final_read_align.length > 0 && (group.data.type.includes("support_alt") || group.data.type == "support_ref")) {
      const gene_button = tk.multiAlignMenu.d.append("button").style("margin-left", "10px").text("Show gene model").on("click", async () => {
        tk.is_align_gene = true;
        gene_button.property("disabled", true);
        await create_gene_models_refalt(tk, block, data, group, alt_var_idx);
      });
    }
    create_multi_alignment_table(tk, data, group, alt_var_idx, highlight_regions_in_refallele);
  } catch (e) {
    wait.remove();
    sayerror(tk.multiAlignMenu.d, e);
  }
}
function create_multi_alignment_table(tk, multi_read_alig_data, group, alt_var_idx, highlight_regions_in_refallele) {
  let num_read_div;
  if (!multi_read_alig_data.alignmentData.read_count) {
    multi_read_alig_data.alignmentData.read_count = 0;
  }
  if (group.data.type == "support_ref") {
    num_read_div = tk.multiAlignMenu.d.append("div").text("Number of reads aligned to reference allele = " + multi_read_alig_data.alignmentData.read_count).style("text-align", "center");
  } else if (group.data.type == "support_no" || group.data.type == "support_amb") {
    num_read_div = tk.multiAlignMenu.d.append("div").text("Number of reads aligned = " + multi_read_alig_data.alignmentData.read_count).style("text-align", "center");
  } else if (group.data.type.includes("support_alt")) {
    let hit = 0;
    for (let var_idx = 0; var_idx < tk.variants.length; var_idx++) {
      if (group.data.type == "support_alt" + var_idx.toString()) {
        hit = 1;
        alt_var_idx = var_idx;
        num_read_div = tk.multiAlignMenu.d.append("div").text(
          "Number of reads aligned to alternative allele " + tk.variants[var_idx].alt + " = " + multi_read_alig_data.alignmentData.read_count
        ).style("text-align", "center");
      }
    }
    if (hit == 0) {
      console.log("group.data.type:", group.data.type);
      console.log("Alternate allele not found");
    }
  }
  if (multi_read_alig_data.alignmentData.partstack_start) {
    const partstack_div = tk.multiAlignMenu.d.append("div").text(
      "Reads aligned from " + multi_read_alig_data.alignmentData.partstack_start + " to " + multi_read_alig_data.alignmentData.partstack_stop
    ).style("text-align", "center");
  }
  const div = tk.multiAlignMenu.d.append("div").style("margin", "20px");
  tk.readAlignmentTable = div.append("table").style("font-family", "Courier").style("font-size", "0.8em").style("color", "#303030").style("margin", "5px 5px 20px 5px").style("border-spacing", 0).style("border-collapse", "separate").style("text-align", "center").style("empty-cells", "show");
  let refallele_tr = tk.readAlignmentTable.append("tr").style("color", "white").style("background-color", "white");
  refallele_tr.attr("id", "RefAltBar");
  let variant_string;
  let nclt_count = 0;
  let allele_start = 0;
  let variant_string_count = 0;
  let inside_variant_box = 1;
  if (group.data.type == "support_alt" + alt_var_idx.toString()) {
    if (tk.variants.length == 1) {
      variant_string = "Alternative allele";
      if (variant_string.length < tk.variants[alt_var_idx].alt.length) {
        inside_variant_box = 0;
      } else {
        variant_string = " Alternative allele";
      }
    } else {
      if (group.data.type == "support_alt" + alt_var_idx.toString()) {
        variant_string = "Alternative allele = " + tk.variants[alt_var_idx].alt;
        if (variant_string.length < tk.variants[alt_var_idx].alt.length) {
          inside_variant_box = 0;
        } else {
          variant_string = " Alternative allele = " + tk.variants[alt_var_idx].alt;
        }
      }
    }
  } else if (group.data.type == "support_ref") {
    if (tk.is_same_ref == false) {
      variant_string = "Combined reference allele";
    } else {
      variant_string = "Reference allele";
    }
    if (variant_string.length < highlight_regions_in_refallele[1] - highlight_regions_in_refallele[0]) {
      inside_variant_box = 0;
    } else {
      if (tk.is_same_ref == false) {
        variant_string = " Combined reference allele";
      } else {
        variant_string = " Reference allele";
      }
    }
  }
  tk.readAlignmentTableGroup = group.data.type;
  if (multi_read_alig_data.alignmentData.final_read_align.length > 0) {
    for (const nclt of multi_read_alig_data.alignmentData.final_read_align[0]) {
      nclt_count += 1;
      const refallele_td = refallele_tr.append("td");
      if (group.data.type == "support_alt" + alt_var_idx.toString() && nclt_count > tk.variants.leftflankseqs[alt_var_idx].length + multi_read_alig_data.alignmentData.gaps_before_variant && nclt_count <= tk.variants.leftflankseqs[alt_var_idx].length + tk.variants[alt_var_idx].alt.length + multi_read_alig_data.alignmentData.gaps_before_variant) {
        if (inside_variant_box == 1) {
          allele_start = 1;
          refallele_td.text(" ").style("text-align", "right").style("font-weight", "550").style("margin", "5px 5px 10px 5px").style("color", "black").style("background-color", "black");
        } else {
          if (variant_string_count < variant_string.length) {
            refallele_td.text(variant_string[variant_string_count]).style("text-align", "right").style("font-weight", "550").style("margin", "5px 5px 10px 5px").style("color", "white").style("background-color", "black");
            variant_string_count += 1;
          } else {
            refallele_td.text(" ").style("text-align", "right").style("font-weight", "550").style("margin", "5px 5px 10px 5px").style("color", "black").style("background-color", "black");
          }
        }
      } else if (group.data.type == "support_ref" && nclt_count > tk.variants.leftflankseqs[0].length + multi_read_alig_data.alignmentData.gaps_before_variant && nclt_count <= tk.variants.leftflankseqs[0].length + highlight_regions_in_refallele[1] - // For now assuming there are no breaks within ref alleles on the reference sequence.
      highlight_regions_in_refallele[0] + multi_read_alig_data.alignmentData.gaps_before_variant) {
        if (inside_variant_box == 1) {
          allele_start = 1;
          refallele_td.text("").style("text-align", "right").style("font-weight", "550").style("margin", "5px 5px 10px 5px").style("color", "black").style("background-color", "black");
        } else {
          if (variant_string_count < variant_string.length) {
            refallele_td.text(variant_string[variant_string_count]).style("text-align", "right").style("font-weight", "550").style("margin", "5px 5px 10px 5px").style("color", "white").style("background-color", "black");
            variant_string_count += 1;
          } else {
            refallele_td.text("").style("text-align", "right").style("font-weight", "550").style("margin", "5px 5px 10px 5px").style("color", "black").style("background-color", "black");
          }
        }
      } else if (allele_start == 1 && inside_variant_box == 1) {
        refallele_td.text(variant_string[variant_string_count]).style("text-align", "right").style("font-weight", "550").style("margin", "5px 5px 10px 5px").style("color", "black").style("background-color", "white");
        variant_string_count += 1;
        if (variant_string_count == variant_string.length) {
          allele_start = 0;
        }
      } else {
        refallele_td.text("").style("text-align", "right").style("font-weight", "550").style("margin", "5px 5px 10px 5px").style("color", "white").style("background-color", "white");
      }
    }
    let read_count = 0;
    for (const read of multi_read_alig_data.alignmentData.final_read_align) {
      let nclt_count2 = 0;
      const read_tr = tk.readAlignmentTable.append("tr").style("color", "white").style("background-color", "white");
      if (read_count == 0 && (group.data.type == "support_ref" || group.data.type == "support_alt")) {
        read_tr.attr("id", "RefAltSeq");
      } else {
        read_tr.attr("id", read_count.toString());
      }
      const r_colors = multi_read_alig_data.alignmentData.qual_r[read_count].split(",");
      const g_colors = multi_read_alig_data.alignmentData.qual_g[read_count].split(",");
      const b_colors = multi_read_alig_data.alignmentData.qual_b[read_count].split(",");
      for (const nclt of read) {
        nclt_count2 += 1;
        let nclt_td;
        if (read_count == 0 && (group.data.type == "support_ref" || group.data.type.includes("support_alt"))) {
          nclt_td = read_tr.append("td").text(nclt).style("background-color", "white").style("color", "black").style("font-weight", "550");
        } else {
          nclt_td = read_tr.append("td").text(nclt).style(
            "background-color",
            "rgb(" + r_colors[nclt_count2 - 1] + "," + g_colors[nclt_count2 - 1] + "," + b_colors[nclt_count2 - 1] + ")"
          );
          if (nclt != "-") {
            nclt_td.style("color", "white");
          } else {
            nclt_td.style("color", "black");
          }
        }
        if (group.data.type == "support_alt" + alt_var_idx.toString() && nclt_count2 > tk.variants.leftflankseqs[alt_var_idx].length + multi_read_alig_data.alignmentData.gaps_before_variant && nclt_count2 <= tk.variants.leftflankseqs[alt_var_idx].length + tk.variants[alt_var_idx].alt.length + multi_read_alig_data.alignmentData.gaps_before_variant) {
          nclt_td.style("color", "black");
        } else if (group.data.type == "support_ref" && nclt_count2 > tk.variants.leftflankseqs[0].length + multi_read_alig_data.alignmentData.gaps_before_variant && nclt_count2 <= tk.variants.leftflankseqs[0].length + highlight_regions_in_refallele[1] - // For now assuming there are no breaks within ref alleles on the reference sequence.
        highlight_regions_in_refallele[0] + multi_read_alig_data.alignmentData.gaps_before_variant) {
          nclt_td.style("color", "black");
        }
      }
      read_count += 1;
    }
  }
}
async function getReadInfo(tk, block, box, ridx) {
  const wait = tk.readMenu.d.append("div").text("Loading...");
  const param = getparam(
    tk.variants ? {
      refseqs: tk.variants.refseqs,
      altseqs: tk.variants.altseqs,
      chrom: tk.variants[0].chr,
      ref_positions: tk.variants.ref_positions,
      refalleles: tk.variants.refalleles,
      altalleles: tk.variants.altalleles,
      start: box.start,
      stop: box.stop,
      paired: tk.asPaired
    } : { start: box.start, stop: box.stop, paired: tk.asPaired }
  );
  const data = await dofetch3("tkbam", param);
  if (data.error) {
    sayerror(wait, data.error);
    return;
  }
  wait.remove();
  for (const r of data.lst) {
    const div = tk.readMenu.d.append("div").style("margin", "10px");
    const read_reference_div = div.append("div").html(r.alignment);
    const row = div.append("div").style("margin-top", "10px");
    row.append("button").text("Copy read sequence").on("click", function() {
      navigator.clipboard.writeText(r.seq).then(() => {
      }, console.warn);
      select_default(this).html("Copy read sequence&nbsp;&check;");
    });
    if (data.lst[0].alignments) {
      select_default(this).append("span").html("&nbsp;");
      const alignment_button = row.append("button").style("margin-left", "10px").text("Align read to variant alleles");
      let first = true;
      alignment_button.on("click", () => {
        if (first) {
          first = false;
          for (let var_idx = 0; var_idx < tk.variants.length; var_idx++) {
            makeReadAlignmentTable(variantAlignmentTable, "Ref", tk, data.lst[0].start_readpos - 1, var_idx);
            makeReadAlignmentTable(variantAlignmentTable, "Alt", tk, data.lst[0].start_readpos - 1, var_idx);
          }
        }
        if (variantAlignmentTable.style("display") == "none") {
          variantAlignmentTable.style("display", "block");
        } else {
          variantAlignmentTable.style("display", "none");
        }
      });
    }
    if (r.unmapped_mate && !tk.asPaired) {
      const mate_button = row.append("button").style("margin-left", "10px").text("Show unmapped mate").on("click", async () => {
        mate_button.property("disabled", true);
        const wait2 = tk.readMenu.d.append("div").text("Loading...");
        const data2 = await dofetch3("tkbam", getparam({ show_unmapped: 1 }));
        if (data2.error) {
          wait2.text("");
          sayerror(wait2, data2.error);
          mate_button.property("disabled", false);
          return;
        }
        wait2.remove();
        mate_button.remove();
        const r2 = data2.lst[0];
        div.append("div").html(r2.alignment);
        const row2 = div.append("div").style("margin-top", "10px");
        row2.append("button").text("Copy read sequence").on("click", function() {
          navigator.clipboard.writeText(r2.seq).then(() => {
          }, console.warn);
          select_default(this).html("Copy read sequence&nbsp;&check;");
        });
        mayshow_blatbutton(r2, row2, tk, block);
        div.append("div").html(r2.info);
      });
    }
    const gene_button = row.append("button").style("margin-left", "10px").text("Show gene model").property("disabled", !r.seq || r.seq == "*").on("click", async () => {
      gene_button.property("disabled", true);
      let i = 0;
      let nuc_count = 0;
      let gm_nuc_count = 0;
      let segstart = data.lst[0].boxes[0].start;
      let segstop;
      let local_alignment_width = 0;
      const tbodyRef = read_reference_div.node().children[0].getElementsByTagName("tbody")[0];
      const gene_model_tr = tbodyRef.insertRow();
      const heading_gene_cell = gene_model_tr.insertCell();
      const heading_gene_text = document.createTextNode("");
      heading_gene_cell.appendChild(heading_gene_text);
      const gene_models = [];
      const break_points = [];
      let num_break_points = 0;
      let gene_model_td;
      const refseq_row = read_reference_div.node().children[0].children[0].children[0];
      for (const item of data.lst[0].boxes) {
        if (item.opr == "H") {
          continue;
        } else if (item.opr == "M" || item.opr == "S" || item.opr == "N" && item.len < data.lst[0].readpanel_DN_maxlength || item.opr == "D" && item.len < data.lst[0].readpanel_DN_maxlength) {
          for (let j2 = 0; j2 < item.len; j2++) {
            local_alignment_width += refseq_row.children[nuc_count + 1].getBoundingClientRect().width;
            nuc_count += 1;
          }
          gm_nuc_count += item.len;
        } else if (item.opr == "I" || item.opr == "N" && item.len >= data.lst[0].readpanel_DN_maxlength || item.opr == "D" && item.len >= data.lst[0].readpanel_DN_maxlength) {
          segstop = item.start;
          const gene_model = await get_gene_models_reads(block, ridx, segstart, segstop, local_alignment_width);
          const gm = {
            src: gene_model.src,
            width: local_alignment_width,
            height: gene_model.height,
            colspan: gm_nuc_count
          };
          gene_models.push(gm);
          if (item.opr == "I") {
            break_points.push(item.len);
          } else if (item.opr == "N" || item.opr == "D") {
            break_points.push(1);
          }
          if (item.opr == "D" || item.opr == "N") {
            segstart = item.start + item.len;
          } else if (item.opr == "I") {
            segstart = item.start;
          }
          local_alignment_width = 0;
          gm_nuc_count = 0;
          num_break_points += 1;
        }
        if (i == data.lst[0].boxes.length - 1) {
          segstop = item.start + item.len;
          const gene_model = await get_gene_models_reads(block, ridx, segstart, segstop, local_alignment_width);
          const gm = {
            src: gene_model.src,
            width: local_alignment_width,
            height: gene_model.height,
            colspan: gm_nuc_count
          };
          gene_models.push(gm);
        }
        i += 1;
      }
      const num_gene_cells = num_break_points + gene_models.length;
      let j = 0;
      let k = 0;
      for (let i2 = 0; i2 < num_gene_cells; i2++) {
        const gene_model_cell = gene_model_tr.insertCell();
        if (i2 % 2 == 0) {
          const img = document.createElement("img");
          img.src = gene_models[k].src;
          img.width = gene_models[k].width;
          img.height = gene_models[k].height;
          gene_model_cell.appendChild(img);
          gene_model_cell.colSpan = gene_models[k].colspan;
          k += 1;
        } else {
          gene_model_cell.colSpan = break_points[j];
          j += 1;
        }
      }
    });
    mayshow_blatbutton(r, row, tk, block);
    div.append("div").html(r.info);
    const variantAlignmentTable = div.append("div").style("display", "none");
  }
  function getparam(extra = {}) {
    const r = tk.regions[ridx];
    const body = {
      getread: 1,
      qname: encodeURIComponent(box.qname),
      // convert + to %2B, so it can be kept the same but not a space instead
      genome: block.genome.name,
      chr: r.chr,
      start: r.start,
      stop: r.stop,
      ...extra
    };
    if (tk.gdcFile) {
      body.gdcFileUUID = tk.gdcFile.uuid;
      body.gdcFilePosition = tk.gdcFile.position;
    }
    if (tk.nochr) body.nochr = 1;
    if (tk.file) body.file = tk.file;
    if (tk.url) body.url = tk.url;
    if (tk.indexURL) body.indexURL = tk.indexURL;
    if (tk.asPaired) {
      body.getpair = 1;
    } else {
      if (box.isfirst) {
        body.getfirst = 1;
      } else if (box.islast) {
        body.getlast = 1;
      } else {
        body.unknownorder = 1;
        body.readstart = box.start;
        body.readstop = box.stop;
      }
    }
    return { headers: getHeaders(tk), body };
  }
  function makeReadAlignmentTable(div, type, tk2, read_start_pos, var_idx) {
    let q_align, align_wrt, r_align;
    if (type == "Ref") {
      q_align = data.lst[0].alignments[var_idx].q_seq_ref;
      align_wrt = data.lst[0].alignments[var_idx].align_ref;
      r_align = data.lst[0].alignments[var_idx].r_seq_ref;
    }
    if (type == "Alt") {
      q_align = data.lst[0].alignments[var_idx].q_seq_alt;
      align_wrt = data.lst[0].alignments[var_idx].align_alt;
      r_align = data.lst[0].alignments[var_idx].r_seq_alt;
    }
    if (data.lst[0].alignments.length == 1) {
      div.append("span").text(type + " alignment").style("font-family", "Courier").style("font-size", "15px").style("color", "#303030").style("margin", "5px 5px 10px 5px");
    } else {
      if (type == "Alt") {
        div.append("span").text("Alignment with Alt allele: " + tk2.variants[var_idx].alt).style("font-family", "Courier").style("font-size", "15px").style("color", "#303030").style("margin", "5px 5px 10px 5px");
      } else if (type == "Ref") {
        div.append("span").text("Alignment with Ref allele: " + tk2.variants[var_idx].ref).style("font-family", "Courier").style("font-size", "15px").style("color", "#303030").style("margin", "5px 5px 10px 5px");
      } else {
        console.log("Unknown allele, please check");
      }
    }
    const table = div.append("table").style("font-family", "Courier").style("font-size", "0.8em").style("color", "#303030").style("margin", "5px 5px 20px 5px");
    let nclt_count = 0;
    const refAlt_tr = table.append("tr");
    refAlt_tr.append("td").text(type + " allele").style("text-align", "right").style("font-weight", "550").style("white-space", "nowrap");
    for (const nclt of r_align) {
      nclt_count += 1;
      if (type == "Ref" && nclt_count > data.lst[0].alignments[var_idx].red_region_start_ref && nclt_count <= data.lst[0].alignments[var_idx].red_region_stop_ref) {
        refAlt_tr.append("td").text(nclt).style("color", "red");
      } else if (type == "Alt" && nclt_count > data.lst[0].alignments[var_idx].red_region_start_alt && nclt_count <= data.lst[0].alignments[var_idx].red_region_stop_alt) {
        refAlt_tr.append("td").text(nclt).style("color", "red");
      } else {
        refAlt_tr.append("td").text(nclt);
      }
    }
    const alignment_tr = table.append("tr");
    alignment_tr.append("td");
    nclt_count = 0;
    for (const align_str of align_wrt) {
      nclt_count += 1;
      if (type == "Ref" && nclt_count > data.lst[0].alignments[var_idx].red_region_start_ref && nclt_count <= data.lst[0].alignments[var_idx].red_region_stop_ref) {
        alignment_tr.append("td").text(align_str).style("color", "red");
      } else if (type == "Alt" && nclt_count > data.lst[0].alignments[var_idx].red_region_start_alt && nclt_count <= data.lst[0].alignments[var_idx].red_region_stop_alt) {
        alignment_tr.append("td").text(align_str).style("color", "red");
      } else {
        alignment_tr.append("td").text(align_str);
      }
    }
    const query_tr = table.append("tr");
    query_tr.append("td").text("Read").style("text-align", "right").style("font-weight", "550");
    nclt_count = 0;
    for (const nclt of q_align) {
      nclt_count += 1;
      if (type == "Ref" && nclt_count > data.lst[0].alignments[var_idx].red_region_start_ref && nclt_count <= data.lst[0].alignments[var_idx].red_region_stop_ref) {
        query_tr.append("td").text(nclt).style("color", "red");
      } else if (type == "Alt" && nclt_count > data.lst[0].alignments[var_idx].red_region_start_alt && nclt_count <= data.lst[0].alignments[var_idx].red_region_stop_alt) {
        query_tr.append("td").text(nclt).style("color", "red");
      } else {
        query_tr.append("td").text(nclt);
      }
    }
  }
}
async function get_gene_models_refalt(block, tk, segstart, segstop, local_alignment_width) {
  const genetk = block.genome.tracks.find((i) => i.__isgene);
  const args = {
    name: genetk.name,
    genome: block.genome.name,
    rglst: [
      {
        chr: tk.variants[0].chr,
        start: segstart,
        stop: segstop,
        width: local_alignment_width
      }
    ],
    width: local_alignment_width,
    stackheight: 16,
    stackspace: 1,
    regionspace: 0,
    file: genetk.file,
    devicePixelRatio: window.devicePixelRatio > 1 ? window.devicePixelRatio : 1,
    color: genetk.color,
    translatecoding: 1,
    __isgene: true,
    noNameHover: true
  };
  {
    const tk2 = block.tklst.find((i) => i.name == args.name && i.type == "bedj");
    if (tk2 && tk2.filterByName) {
      args.filterByName = tk2.filterByName;
    }
  }
  return await dofetch3("tkbedj", { method: "POST", body: JSON.stringify(args) });
}
async function get_gene_models_reads(block, ridx, segstart, segstop, local_alignment_width) {
  const genetk = block.genome.tracks.find((i) => i.__isgene);
  const args = {
    name: genetk.name,
    genome: block.genome.name,
    rglst: [
      {
        chr: block.rglst[ridx].chr,
        start: segstart,
        stop: segstop,
        width: local_alignment_width
      }
    ],
    width: local_alignment_width,
    stackheight: 16,
    stackspace: 1,
    regionspace: 0,
    file: genetk.file,
    devicePixelRatio: window.devicePixelRatio > 1 ? window.devicePixelRatio : 1,
    color: genetk.color,
    translatecoding: 1,
    __isgene: true,
    noNameHover: true
  };
  {
    const tk = block.tklst.find((i) => i.name == args.name && i.type == "bedj");
    if (tk && tk.filterByName) {
      args.filterByName = tk.filterByName;
    }
  }
  return await dofetch3("tkbedj", { method: "POST", body: JSON.stringify(args) });
}
function mayshow_blatbutton(read, div, tk, block) {
  if (!block.genome.blat) {
    return;
  }
  const button = div.append("button").style("margin-left", "10px").text("BLAT").on("click", async () => {
    button.property("disabled", true);
    blatdiv.selectAll("*").remove();
    const wait = blatdiv.append("div").text("Loading...");
    try {
      const data = await dofetch3("blat", {
        body: {
          genome: block.genome.name,
          seq: read.seq,
          soft_starts: read.soft_starts,
          soft_stops: read.soft_stops
        }
      });
      if (data.error) throw data.error;
      if (data.nohit) throw "No hit";
      if (!data.hits) throw ".hits[] missing";
      wait.remove();
      show_blatresult(data.hits, blatdiv, tk, block);
    } catch (e) {
      wait.text(e.message || e);
      if (e.stack) console.log(e.stack);
    }
    button.property("disabled", false);
  });
  const blatdiv = div.append("div");
}
async function enter_partstack(group, tk, block, y, data) {
  group.data_fullstack = group.data;
  const clickstackidx = (group.partstack ? group.partstack.start : 0) + Math.floor(y / group.data.stackheight);
  if (clickstackidx < stackpagesize / 2) {
    group.partstack = {
      start: 0,
      stop: stackpagesize
    };
  } else if (clickstackidx > group.data_fullstack.stackcount - stackpagesize / 2) {
    group.partstack = {
      start: group.data_fullstack.stackcount - stackpagesize,
      stop: group.data_fullstack.stackcount
    };
  } else {
    group.partstack = {
      start: clickstackidx - stackpagesize / 2,
      stop: clickstackidx + stackpagesize / 2
    };
  }
  block.tkcloakon(tk);
  const _d = await getData(tk, block, {
    stackstart: group.partstack.start,
    stackstop: group.partstack.stop,
    grouptype: group.data.type
  });
  group.data = _d.groups[0];
  renderGroup(group, tk, block);
  setTkHeight(tk);
  block.tkcloakoff(tk, {});
  block.block_setheight();
}
function show_blatresult(hits, div, tk, block) {
  const table = div.append("table");
  const tr = table.append("tr").style("opacity", 0.5).style("font-size", ".8em");
  tr.append("td").text("QScore");
  tr.append("td").text("QStart");
  tr.append("td").text("QStop");
  tr.append("td").text("QStrand");
  tr.append("td").text("QAlignLen");
  tr.append("td").text("RChr");
  tr.append("td").text("RStart");
  tr.append("td").text("RStop");
  tr.append("td").text("RAlignLen");
  for (const h of hits) {
    let tr2 = table.append("tr").style("font-size", ".8em");
    tr2.append("td").text(h.query_match);
    tr2.append("td").text(h.query_startpos);
    tr2.append("td").text(h.query_stoppos);
    tr2.append("td").text(h.query_strand);
    tr2.append("td").text(h.query_alignlen);
    tr2.append("td").text(h.ref_chr);
    tr2.append("td").text(h.ref_startpos);
    tr2.append("td").text(h.ref_stoppos);
    tr2.append("td").text(h.ref_alignlen);
  }
}
function renderGroup(group, tk, block) {
  update_boxes(group, tk, block);
  if (group.partstack) {
    if (tk.variants) {
      group.dom.diff_score_barplot_partstack.attr("xlink:href", group.data.diff_scores_img.src).attr("width", group.data.diff_scores_img.width).attr("height", group.data.diff_scores_img.height);
      group.ReadNameMaxwidth = 0;
      if (tk.show_readnames) {
        group.dom.read_names_g.attr("transform", "translate(0,0)");
        group.dom.read_names_g.selectAll("*").remove();
        if (group.data.templatebox && group.data.stackheight >= stackheight_min) {
          let read_count = 1;
          for (const read of group.data.templatebox) {
            const read_name_bbox = group.dom.read_names_g.append("text").attr("x", 0).attr("y", group.data.height * read_count / group.data.templatebox.length).attr("text-anchor", "end").style("fill", "black").attr("font-size", group.data.height / group.data.templatebox.length).text(read.qname);
            group.ReadNameMaxwidth = Math.max(group.ReadNameMaxwidth, read_name_bbox.node().getBBox().width);
            read_count += 1;
          }
        }
      } else {
        group.dom.read_names_g.selectAll("*").remove();
        group.ReadNameMaxwidth = 0;
      }
    }
    group.dom.img_partstack.attr("xlink:href", group.data.src).attr("width", group.data.width).attr("height", group.data.height).attr("y", 0);
    group.dom.img_fullstack.attr("width", 0).attr("height", 0);
    if (tk.variants) {
      group.dom.diff_score_barplot_fullstack.attr("width", 0).attr("height", 0);
    }
    const scrollableheight = group.data.height;
    group.dom.rightg.vslider.bar.transition().attr("height", scrollableheight);
    group.dom.rightg.vslider.boxy = scrollableheight * group.partstack.start / group.data_fullstack.stackcount;
    group.dom.rightg.vslider.boxh = scrollableheight * (group.partstack.stop - group.partstack.start) / group.data_fullstack.stackcount;
    group.dom.rightg.vslider.box.transition().attr("height", group.dom.rightg.vslider.boxh);
    group.dom.rightg.vslider.boxbotline.transition().attr("y1", group.dom.rightg.vslider.boxh).attr("y2", group.dom.rightg.vslider.boxh);
    group.dom.rightg.vslider.boxg.transition().attr("transform", "translate(0," + group.dom.rightg.vslider.boxy + ")");
  } else {
    group.dom.img_fullstack.attr("xlink:href", group.data.src).attr("width", group.data.width).attr("height", group.data.height);
    group.dom.img_partstack.attr("width", 0).attr("height", 0);
    if (tk.variants) {
      if (group.dom.diff_score_barplot_partstack) {
        group.dom.diff_score_barplot_partstack.attr("width", 0).attr("height", 0);
      }
      group.dom.diff_score_barplot_fullstack.attr("width", group.data.diff_scores_img.width).attr("height", group.data.diff_scores_img.height);
      if (tk.show_readnames) {
        group.dom.read_names_g.selectAll("*").remove();
      }
    }
    group.dom.rightg.vslider.g.transition().attr("transform", "scale(0)");
  }
  group.dom.img_cover.attr("width", group.data.width).attr("height", group.data.height);
}
export {
  loadTk
};
//# sourceMappingURL=block.tk.bam-XNZFHSDQ.js.map
