import {
  appear2 as appear,
  disappear2 as disappear,
  gmmode,
  newpane,
  tkexists,
  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 "./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 {
  category10_default
} from "./chunk-KSGA62R2.js";
import "./chunk-LOZEKOES.js";
import "./chunk-TOU7EVFQ.js";
import {
  ordinal
} from "./chunk-OAWQ6LOO.js";
import "./chunk-TLT4YIG3.js";
import "./chunk-KYBIQBXE.js";
import "./chunk-I6Y4O3RR.js";
import "./chunk-OMR2DT66.js";
import "./chunk-DQC5FFGV.js";
import "./chunk-HFNDKYVF.js";

// src/block.tk.menu.js
var colorfunc = ordinal(category10_default);
function block_tk_menu_default(block, tip, x, y, button) {
  tip.clear();
  const div = tip.d;
  onesearchui(block, div);
  facettrigger(block, div, tip);
  for (const s of block.genome.tkset) {
    if (s.facetlst) {
      for (const f of s.facetlst) {
        if (f.facetpane) {
          disappear(f.facetpane.pane);
        }
      }
    }
    if (s.facetpane) {
      disappear(s.facetpane.pane);
    }
  }
  hardlist4block(block, div);
  if (!JSON.parse(sessionStorage.getItem("optionalFeatures")).disableCustomTrackUI) {
    div.append("div").html("Add custom track &raquo;").style("padding", "15px").style("text-align", "center").attr("class", "sja_menuoption").on("click", () => {
      customtracktypeui(block, div);
    });
  }
  tip.show2(x, y, { elem: button });
}
function onesearchui(block, div) {
  let count = 0;
  for (const s of block.genome.tkset) {
    count += s.tklst.length;
  }
  if (count == 0) {
    return;
  }
  const searchrow = div.append("div").style("margin", count == 0 ? "0px" : "15px 15px 5px 15px");
  const input = searchrow.append("input").attr("size", 15).attr("placeholder", "Search " + count + " tracks");
  const searchsays = searchrow.append("span").style("font-size", ".8em").style("padding-left", "10px");
  input.on("keyup", (event) => {
    founddiv.selectAll("*").remove();
    searchsays.text("");
    const v = event.target.value;
    if (v.length < 2) {
      return;
    }
    const vv = v.toLowerCase();
    let foundnum = 0;
    for (const set of block.genome.tkset) {
      const hits = [];
      for (const t of set.tklst) {
        if (t.name && t.name.toLowerCase().indexOf(vv) != -1) {
          hits.push(t);
          continue;
        }
        if (t.patient && t.patient.toLowerCase().indexOf(vv) != -1) {
          hits.push(t);
          continue;
        }
        if (t.sampletype && t.sampletype.toLowerCase().indexOf(vv) != -1) {
          hits.push(t);
          continue;
        }
        if (t.assayname && t.assayname.toLowerCase().indexOf(vv) != -1) {
          hits.push(t);
          continue;
        }
      }
      foundnum += hits.length;
      if (hits.length == 0) continue;
      const color = colorfunc(set.name);
      const tr = founddiv.append("table").style("border-spacing", "0px").append("tr");
      const thisscroll = tr.append("td").style("padding", "0px 10px 0px 20px").append("div").style("border", "solid 1px " + color);
      if (hits.length > 13) {
        thisscroll.style("padding", "10px 10px 10px 0px").style("height", "300px").style("overflow-y", "scroll").style("resize", "vertical");
      }
      const tktable = thisscroll.append("table").style("border-spacing", "1px");
      tr.append("td").style("color", color).style("font-size", ".8em").style("font-weight", "bold").text(set.name);
      for (const cold of hits) {
        let hot = null;
        for (const t of block.tklst) {
          if (t.id == cold.id && t.file == cold.file && t.url == cold.url) {
            hot = t;
            break;
          }
        }
        const tr2 = tktable.append("tr");
        const td1 = tr2.append("td").style("color", "#555").style("font-size", ".7em");
        if (hot) {
          td1.text("SHOWN");
        }
        const handle = tr2.append("td").classed("sja_menuoption", true).text(tkhtmllabel(cold, block));
        if (hot) {
          handle.on("click", () => tkhandleclick(block, hot, td1));
        } else {
          handle.on("click", () => tkhandleclick(block, cold, td1));
        }
      }
    }
    searchsays.text(foundnum == 0 ? "No tracks found" : "Found " + foundnum + " track" + (foundnum > 1 ? "s" : ""));
  });
  const founddiv = div.append("div").style("margin-top", "3px");
}
function hardlist4block(block, div) {
  const harddiv = div.append("div").style("margin", "20px");
  {
    const set = /* @__PURE__ */ new Set();
    for (const t of block.tklst) {
      set.add(t.name);
    }
    for (const t of block.genome.tracks) {
      set.add(t.name);
    }
    if (set.size > 13) {
      harddiv.style("border-top", "solid 1px #eee").style("border-bottom", "solid 1px #eee").style("padding", "10px 10px 10px 0px").style("height", "300px").style("overflow-y", "scroll").style("resize", "vertical");
    }
  }
  const hardtable = harddiv.append("table");
  for (const tk of block.tklst) {
    const tr = hardtable.append("tr");
    const td1 = tr.append("td");
    td1.text("SHOWN").style("color", "#555").style("font-size", ".7em");
    const handle = tr.append("td").text(tkhtmllabel(tk, block));
    if (notAllowedToHideThisTrack(tk)) {
      handle.style("padding", "5px 10px");
    } else {
      handle.attr("class", "sja_menuoption").on("click", () => {
        tkhandleclick(block, tk, td1);
      });
    }
  }
  for (const tk of block.genome.tracks) {
    let ishot = false;
    for (const t of block.tklst) {
      if (t.tkid == tk.tkid) {
        ishot = true;
        break;
      }
    }
    if (ishot) {
      continue;
    }
    const tr = hardtable.append("tr");
    const td1 = tr.append("td").style("color", "#555").style("font-size", ".7em");
    const handle = tr.append("td").attr("class", "sja_menuoption").text(tkhtmllabel(tk, block));
    handle.on("click", () => {
      tkhandleclick(block, tk, td1);
    });
  }
}
function customtracktypeui(block, div) {
  div.selectAll("*").remove();
  div.append("div").style("margin", "30px").style("text-align", "center").style("color", "#858585").text("Add track for " + block.genome.name + " genome");
  const d1 = div.append("div").style("margin", "20px");
  d1.append("div").attr("class", "sja_menuoption").html('bigWig <span style="opacity:.5;font-size:.8em">numerical data</span>').on("click", () => newtk_bw(block, div));
  d1.append("div").attr("class", "sja_menuoption").html('JSON-BED <span style="opacity:.5;font-size:.8em">positional annotations</span>').on("click", () => newtk_bedj(block, div));
  d1.append("div").attr("class", "sja_menuoption").text("Splice junction").on("click", () => newtk_junction(block, div));
  d1.append("div").attr("class", "sja_menuoption").html('VCF <span style="opacity:.5;font-size:.8em">SNV/indel</span>').on("click", () => newtk_vcf(block, div));
  d1.append("div").attr("class", "sja_menuoption").html('Interaction <span style="opacity:.5;font-size:.8em">pairs of genomic regions</span>').on("click", () => newtk_interaction(block, div));
  const d2 = div.append("div").style("margin", "20px");
  d2.append("p").style("color", "#858585").text("Declare tracks as JSON text:");
  const ta = d2.append("textarea").attr("rows", 5).attr("cols", "30").attr("placeholder", "Enter JSON text");
  const row = d2.append("div").style("margin-top", "3px");
  row.append("button").text("Submit").on("click", () => {
    const v = ta.property("value");
    if (v == "") return;
    let j;
    try {
      j = JSON.parse(v);
    } catch (e) {
      alert("Invalid JSON: " + e);
      return;
    }
    if (!Array.isArray(j)) {
      j = [j];
    }
    for (const t of j) {
      if (t.hidden) {
        delete t.hidden;
        block.genome.tracks.push(t);
      } else {
        const tt = block.block_addtk_template(t);
        if (tt) {
          block.tk_load(tt);
        }
      }
    }
  });
  row.append("button").text("Clear").on("click", () => ta.property("value", ""));
  row.append("span").style("padding-left", "10px").html("<a href=https://github.com/stjude/proteinpaint/wiki/Tracks target=_blank>Track format</a>");
  row.append("span").style("padding-left", "10px").html("<a href=https://jsonlint.com/ target=_blank>debug</a>");
}
function may_add_customtk(tk, block, div) {
  const tk_reg = tkexists(tk, block.genome.tracks);
  if (tk_reg) {
    if (tkexists(tk, block.tklst)) {
      window.alert("The track is already shown");
    } else {
      const tk2 = block.block_addtk_template(tk_reg);
      block.tk_load(tk2);
      customtracktypeui(block, div);
    }
  } else {
    tk.tkid = Math.random().toString();
    block.genome.tracks.push(tk);
    const tk2 = block.block_addtk_template(tk);
    block.tk_load(tk2);
    customtracktypeui(block, div);
  }
}
function newtk_bw(block, div) {
  div.selectAll("*").remove();
  div.append("div").style("margin", "20px").style("display", "inline-block").html("\u226A Go back").attr("class", "sja_menuoption").on("click", () => customtracktypeui(block, div));
  {
    const box = div.append("div").style("margin", "0px 20px 20px 20px");
    box.append("p").text("Add a single track").style("color", "#858585").style("font-size", ".7em");
    const iname = box.append("p").append("input").attr("type", "text").attr("placeholder", "bigWig track name").attr("size", 20);
    const iurl = box.append("p").append("input").attr("type", "text").attr("placeholder", "URL or server-side file path").attr("size", 40);
    const p2 = box.append("p");
    p2.append("button").text("Add bigWig track").on("click", () => {
      const text = iurl.property("value").trim();
      if (text == "") return;
      let file, url;
      if (stringisurl(text)) {
        url = text;
      } else {
        file = text;
      }
      const tk = {
        type: tkt.bigwig,
        name: iname.property("value").trim() || "bigwig track",
        scale: {
          auto: 1
        },
        file,
        url,
        iscustom: true
      };
      may_add_customtk(tk, block, div);
    });
    p2.append("button").text("Clear").on("click", () => iurl.node().value = iname.node().value = "");
  }
  {
    const box = div.append("div").style("margin", "0px 20px 20px 20px");
    box.append("p").text("Add multiple tracks").style("color", "#858585").style("font-size", ".7em");
    const input = box.append("p").append("textarea").attr("placeholder", "one track per line: [track name],[path/to/file.bw or URL]").attr("rows", 2).attr("cols", 50);
    const p2 = box.append("p");
    p2.append("button").text("Add tracks").on("click", () => {
      const text = input.property("value").trim();
      if (text == "") return;
      for (const s of text.split(/[\r\n]/)) {
        const l = s.split(",");
        if (l[0] && l[1]) {
          const t = {
            type: tkt.bigwig,
            name: l[0].trim(),
            scale: { auto: 1 },
            iscustom: true
          };
          const tmp = l[1].trim();
          if (stringisurl(tmp)) t.url = tmp;
          else t.file = tmp;
          const t2 = block.block_addtk_template(t);
          block.tk_load(t2);
        }
      }
    });
    p2.append("button").text("Clear").on("click", () => input.node().value = "");
  }
  div.append("div").style("margin", "20px").html("<a href=https://genome.ucsc.edu/goldenpath/help/bigWig.html target=_blank>bigWig file format</a>");
}
function newtk_bedj(block, div) {
  div.selectAll("*").remove();
  div.append("div").style("margin", "20px").style("display", "inline-block").html("&lt; go back").attr("class", "sja_menuoption").on("click", () => customtracktypeui(block, div));
  const box = div.append("div").style("margin", "20px");
  const nta = box.append("p").append("input").attr("type", "text").attr("placeholder", "JSON-BED track name").attr("size", 20);
  const ta = box.append("p").append("input").attr("type", "text").attr("placeholder", "URL or server-side file path").attr("size", 40);
  const p = box.append("p");
  p.append("button").text("Add JSON-BED track").on("click", () => {
    const text = ta.property("value").trim();
    if (text == "") return;
    let file, url;
    if (stringisurl(text)) {
      url = text;
    } else {
      file = text;
    }
    const tk = {
      type: tkt.bedj,
      name: nta.property("value").trim() || "JSON-BED",
      file,
      url,
      iscustom: true
    };
    may_add_customtk(tk, block, div);
  });
  p.append("button").text("Clear").on("click", () => ta.node().value = nta.node().value = "");
  box.append("p").html(
    "<a href=https://github.com/stjude/proteinpaint/wiki/Tracks#Track-JSON-BED-track-format target=_blank>JSON-BED format</a>"
  );
}
function newtk_junction(block, div) {
  div.selectAll("*").remove();
  div.append("div").style("margin", "20px").style("display", "inline-block").html("&lt; go back").attr("class", "sja_menuoption").on("click", () => customtracktypeui(block, div));
  const box = div.append("div").style("margin", "20px");
  const nta = box.append("p").append("input").attr("type", "text").attr("placeholder", "Junction track name").attr("size", 20);
  const ta = box.append("p").append("input").attr("type", "text").attr("placeholder", "URL or server-side file path").attr("size", 40);
  const p = box.append("p");
  p.append("button").text("Add junction track").on("click", () => {
    const text = ta.property("value").trim();
    if (text == "") return;
    let file, url;
    if (stringisurl(text)) {
      url = text;
    } else {
      file = text;
    }
    const tk = {
      type: tkt.junction,
      name: nta.property("value").trim() || "junction",
      tracks: [
        {
          file,
          url
        }
      ],
      iscustom: true
    };
    may_add_customtk(tk, block, div);
  });
  p.append("button").text("Clear").on("click", () => ta.node().value = nta.node().value = "");
  box.append("p").html(
    "<a href=https://github.com/stjude/proteinpaint/wiki/Tracks#Track-splice-junction target=_blank>Junction track format</a>"
  );
}
function newtk_vcf(block, div) {
  div.selectAll("*").remove();
  div.append("div").style("margin", "20px").style("display", "inline-block").html("&lt; go back").attr("class", "sja_menuoption").on("click", () => customtracktypeui(block, div));
  const box = div.append("div").style("margin", "20px");
  const nta = box.append("p").append("input").attr("type", "text").attr("placeholder", "VCF track name").attr("size", 20);
  const ta = box.append("p").append("input").attr("type", "text").attr("placeholder", "URL or server-side file path").attr("size", 40);
  const p = box.append("p");
  p.append("button").text("Add VCF track").on("click", () => {
    const text = ta.property("value").trim();
    if (text == "") return;
    let file, url;
    if (stringisurl(text)) {
      url = text;
    } else {
      file = text;
    }
    const vcfid = Math.random().toString();
    const ds = {
      label: nta.property("value").trim() || "VCF",
      id2vcf: {}
    };
    ds.id2vcf[vcfid] = {
      vcfid,
      file,
      url,
      headernotloaded: true
    };
    const tk = {
      type: tkt.ds,
      ds,
      isvcf: true,
      // trigger
      iscustom: true
    };
    may_add_customtk(tk, block, div);
  });
  p.append("button").text("Clear").on("click", () => ta.node().value = nta.node().value = "");
  box.append("p").html("<a href=https://en.wikipedia.org/wiki/Variant_Call_Format target=_blank>VCF format</a>");
  box.append("p").style("color", "#858585").style("font-size", ".8em").text("SNV/indel data only");
}
function newtk_interaction(block, div) {
  div.selectAll("*").remove();
  div.append("div").style("margin", "20px").style("display", "inline-block").html("&lt; go back").attr("class", "sja_menuoption").on("click", () => customtracktypeui(block, div));
  const box = div.append("div").style("margin", "20px");
  const tknameinput = box.append("p").append("input").attr("type", "text").attr("placeholder", "Interaction track name").attr("size", 20);
  const tr = box.append("table").append("tr");
  tr.append("td").text("Data source").style("opacity", 0.5).style("vertical-align", "top").style("padding-right", "10px");
  const td = tr.append("td");
  const id = Math.random().toString();
  {
    const row = td.append("div");
    row.append("input").attr("type", "radio").attr("name", id).attr("id", id + 1).property("checked", 1).on("change", () => change(1));
    row.append("label").attr("class", "sja_clbtext").html("&nbsp;Hi-C, juicebox format").attr("for", id + 1);
  }
  {
    const row = td.append("div");
    row.append("input").attr("type", "radio").attr("name", id).attr("id", id + 2).on("change", () => change(2));
    row.append("label").attr("class", "sja_clbtext").html("&nbsp;BED file, compressed and indexed").attr("for", id + 2);
  }
  {
    const row = td.append("div");
    row.append("input").attr("type", "radio").attr("name", id).attr("id", id + 3).on("change", () => change(3));
    row.append("label").attr("class", "sja_clbtext").html("&nbsp;Text input").attr("for", id + 3);
  }
  const div1 = box.append("div");
  {
    div1.append("p").html(
      "Juicebox: <a href=https://github.com/theaidenlab/Juicebox target=_blank>github.com/theaidenlab/Juicebox</a>"
    );
    const urlinput = div1.append("p").append("input").attr("type", "text").attr("placeholder", "*.hic file URL or server-side path").attr("size", 40);
    let enzymeselect;
    if (block.genome.hicenzymefragment) {
      const p = div1.append("p");
      p.append("span").html("Restriction enzyme:&nbsp;");
      enzymeselect = p.append("select");
      enzymeselect.append("option").text("none");
      for (const e of block.genome.hicenzymefragment) {
        enzymeselect.append("option").text(e.enzyme).property("value", e.enzyme);
      }
    }
    div1.append("p").append("button").text("Add track").on("click", () => {
      const str = urlinput.property("value");
      if (!str) return;
      const tk = {
        type: tkt.hicstraw,
        name: tknameinput.property("value") || "Custom interaction",
        mode_hm: true,
        mode_arc: false,
        iscustom: 1
      };
      if (stringisurl(str)) tk.url = str;
      else tk.file = str;
      if (enzymeselect) {
        const s = enzymeselect.node();
        tk.enzyme = s.options[s.selectedIndex].value;
        if (tk.enzyme == "none") delete tk.enzyme;
      }
      may_add_customtk(tk, block, div);
    });
  }
  const div2 = box.append("div").style("display", "none");
  {
    div2.append("p").html(
      "<a href=https://github.com/stjude/proteinpaint/wiki/Tracks#track-json-bed-track-format target=_blank>BED file format</a>"
    );
    const urlinput = div2.append("p").append("input").attr("type", "text").attr("placeholder", "*.gz file URL or server-side path").attr("size", 40);
    div2.append("p").append("button").text("Add track").on("click", () => {
      const str = urlinput.property("value");
      if (!str) return;
      const tk = {
        type: tkt.hicstraw,
        name: tknameinput.property("value") || "Custom interaction",
        mode_hm: false,
        mode_arc: true,
        iscustom: 1
      };
      if (stringisurl(str)) tk.bedurl = str;
      else tk.bedfile = str;
      may_add_customtk(tk, block, div);
    });
  }
  const div3 = box.append("div").style("display", "none");
  {
    div3.append("p").html(
      "Enter interaction data as <a href=https://github.com/stjude/proteinpaint/wiki/Tracks#Track-splice-junction target=_blank>tab-delimited text</a>."
    );
    const textinput = div3.append("textarea").attr("placeholder", "One line per interaction").attr("cols", 45).attr("rows", 5);
    div3.append("p").append("button").text("Add track").on("click", () => {
      const str = textinput.property("value");
      if (!str) return;
      const tk = {
        type: tkt.hicstraw,
        name: tknameinput.property("value") || "Custom interaction",
        mode_hm: false,
        mode_arc: true,
        iscustom: 1,
        textdata: { raw: str }
      };
      may_add_customtk(tk, block, div);
    });
  }
  const change = (i) => {
    div1.style("display", i == 1 ? "block" : "none");
    div2.style("display", i == 2 ? "block" : "none");
    div3.style("display", i == 3 ? "block" : "none");
  };
}
function facettrigger(block, holder, menutip) {
  const toshow = [];
  for (const tkset of block.genome.tkset) {
    if (tkset.facetlst) {
      toshow.push(tkset);
      continue;
    }
    if (tkset.isfacet) {
      toshow.push(tkset);
      continue;
    }
    console.log("the .isfacet flag is missing on this tkset and may need to be supported");
  }
  if (toshow.length == 0) {
    return;
  }
  const div = holder.append("div").style("margin", "15px");
  div.append("div").text("FACET").style("color", "#858585").style("font-size", ".7em");
  for (const tkset of toshow) {
    if (tkset.facetlst) {
      for (const flet of tkset.facetlst) {
        div.append("div").style("display", "inline-block").attr("class", "sja_menuoption").text((flet.name ? flet.name + ": " : "") + tkset.name).on("click", (event) => {
          menutip.hide();
          if (flet.facetpane) {
            document.body.appendChild(flet.facetpane.pane.node());
            appear(flet.facetpane.pane);
          } else {
            const pane = newpane({
              x: event.clientX - 100,
              y: event.clientY - 20,
              closekeep: true
            });
            flet.facetpane = pane;
          }
          facetmake(block, tkset, flet);
        });
      }
      continue;
    }
    div.append("div").style("display", "inline-block").attr("class", "sja_menuoption").text(tkset.tklst.length + " tracks from " + tkset.name).on("click", (event) => {
      menutip.hide();
      if (tkset.facetpane) {
        document.body.appendChild(tkset.facetpane.pane.node());
        appear(tkset.facetpane.pane);
      } else {
        const pane = newpane({
          x: event.clientX - 100,
          y: event.clientY - 20,
          closekeep: true
        });
        tkset.facetpane = pane;
      }
      facetmake(block, tkset);
    });
  }
}
function facetmake(block, tkset, flet) {
  const tip = new Menu();
  const facetpane = (flet || tkset).facetpane;
  facetpane.header.html('<span style="color:#858585;font-size:.8em">Tracks from</span> ' + tkset.name);
  facetpane.body.selectAll("*").remove();
  backward_compatible(tkset.tklst);
  const [assays, sample2assay2tracks, level2sample, L1_2_L2, samplewithlevel] = get_dimensions(tkset, flet);
  const [assaynamelst] = sort_dimensions(assays, flet);
  const scrollholder = facetpane.body.append("div");
  if (sample2assay2tracks.size > 50) {
    scrollholder.style("height", "500px").style("overflow-y", "scroll").style("resize", "vertical");
  }
  const table = scrollholder.append("table").style("margin", "10px").style("border-spacing", "3px").style("border-collapse", "separate").attr("class", "sja_simpletable");
  const tr = table.append("tr");
  if (L1_2_L2) {
    tr.append("td");
    tr.append("td");
  } else if (level2sample) {
    tr.append("td");
  }
  tr.append("td");
  for (const assay of assaynamelst) {
    tr.append("td").text(assay).attr("class", "sja_clbtext").on("click", () => {
      batchselect_assay(assay);
    });
  }
  if (L1_2_L2) {
    for (const [L1, o] of L1_2_L2) {
      let samplecount = 0;
      for (const s of o.values()) {
        samplecount += s.size;
      }
      let tr2 = table.append("tr");
      let createnewrow_at_L2 = false;
      tr2.append("td").text(L1).attr("class", "sja_clbtext").attr("rowspan", samplecount).on("click", () => {
        batchselect_sample({ L1 });
      });
      for (const [L2, sampleset] of o) {
        if (createnewrow_at_L2) tr2 = table.append("tr");
        let createnewrow_at_sample = false;
        tr2.append("td").text(L2).attr("rowspan", sampleset.size).attr("class", "sja_clbtext").on("click", () => {
          batchselect_sample({ L1, L2 });
        });
        for (const sample of sampleset) {
          if (createnewrow_at_sample) tr2 = table.append("tr");
          tr2.append("td").text(sample).attr("class", "sja_clbtext").on("click", () => {
            batchselect_sample({ L1, L2, sample });
          });
          for (const assay of assaynamelst) {
            makecell(sample, assay, tr2);
          }
          createnewrow_at_sample = true;
        }
        createnewrow_at_L2 = true;
      }
    }
  }
  if (level2sample) {
    for (const [level, sampleset] of level2sample) {
      let tr2 = table.append("tr");
      let createnewrow = false;
      const td = tr2.append("td").text(level).attr("rowspan", sampleset.size).attr("class", "sja_clbtext").on("click", () => {
        batchselect_sample({ level });
      });
      if (L1_2_L2) {
        td.attr("colspan", 2);
      }
      for (const sample of sampleset) {
        if (createnewrow) tr2 = table.append("tr");
        tr2.append("td").text(sample).attr("class", "sja_clbtext").on("click", () => {
          batchselect_sample({ level, sample });
        });
        for (const assay of assaynamelst) {
          makecell(sample, assay, tr2);
        }
        createnewrow = true;
      }
      createnewrow = true;
    }
  }
  for (const [sample, o] of sample2assay2tracks) {
    if (samplewithlevel.has(sample)) continue;
    const tr2 = table.append("tr");
    const td = tr2.append("td").text(sample).attr("class", "sja_clbtext").on("click", () => {
      batchselect_sample({ sample });
    });
    if (L1_2_L2) {
      td.attr("colspan", 3);
    } else if (level2sample) {
      td.attr("colspan", 2);
    }
    for (const assay of assaynamelst) {
      makecell(sample, assay, tr2);
    }
  }
  function makecell(sample, assay, tr2) {
    const td = tr2.append("td");
    const s = sample2assay2tracks.get(sample);
    if (!s) return;
    const tklst = s.get(assay);
    if (!tklst) return;
    td.attr("class", "sja_menuoption").style("font-size", ".7em").style("text-align", "center");
    let numdisplayed = 0;
    for (const t of tklst) {
      if (findtkbytkid(block, t.tkid)) {
        numdisplayed++;
      }
    }
    if (tklst.length > 1) {
      td.text(tklst.length).on("click", (event) => {
        tip.clear().show(event.clientX, event.clientY);
        const table2 = tip.d.append("table");
        for (const t of tklst) {
          const tr3 = table2.append("tr");
          const td1 = tr3.append("td").style("color", "#555").style("font-size", ".7em");
          if (findtkbytkid(block, t.tkid)) {
            td1.text("SHOWN");
          }
          tr3.append("td").text(t.partname || t.name).attr("class", "sja_menuoption").on("click", () => {
            tkhandleclick(block, t, td1);
          });
        }
      });
    } else {
      if (findtkbytkid(block, tklst[0].tkid)) {
        td.text("SHOWN");
      }
      td.on("click", () => {
        tkhandleclick(block, tklst[0], td);
      });
    }
  }
  function batchselect_assay(assay) {
    const tklst = [];
    for (const t of tkset.tklst) {
      if (flet) {
        if (!assays.has(t.assay)) continue;
      }
      if (t.assay == assay) {
        tklst.push(t);
      }
    }
    toggle_tracks(tklst);
    facetmake(block, tkset, flet);
  }
  function batchselect_sample({ L1, L2, level, sample }) {
    const tklst = [];
    for (const t of tkset.tklst) {
      if (flet) {
        if (!assays.has(t.assay)) continue;
      }
      const l1 = t.level1;
      const l2 = t.level2;
      if (L1) {
        if (l1 != L1) continue;
        if (L2) {
          if (l2 != L2) continue;
          if (sample) {
            if (t.sample == sample) tklst.push(t);
          } else {
            tklst.push(t);
          }
        } else {
          tklst.push(t);
        }
      } else if (level) {
        if (l1 && l2 || !l1 && !l2) continue;
        const l = l1 || l2;
        if (l != level) continue;
        if (sample) {
          if (t.sample == sample) tklst.push(t);
        } else {
          tklst.push(t);
        }
      } else if (sample) {
        if (l1 || l2) continue;
        if (t.sample == sample) tklst.push(t);
      }
    }
    toggle_tracks(tklst);
    facetmake(block, tkset, flet);
  }
  function toggle_tracks(lst) {
    if (lst.length == 0) return;
    const notshown = [];
    for (const t of lst) {
      if (!findtkbytkid(block, t.tkid)) {
        notshown.push(t);
      }
    }
    if (notshown.length) {
      for (const t of notshown) {
        const t2 = block.block_addtk_template(t);
        if (t2) {
          block.tk_load(t2);
        } else {
        }
      }
    } else {
      for (const t of lst) {
        for (let i = 0; i < block.tklst.length; i++) {
          if (block.tklst[i].tkid == t.tkid) {
            block.tk_remove(i);
            break;
          }
        }
      }
    }
  }
}
function get_dimensions(tkset, flet) {
  const assays = /* @__PURE__ */ new Map();
  const sample2assay2tracks = /* @__PURE__ */ new Map();
  let level2sample;
  let L1_2_L2;
  const samplewithlevel = /* @__PURE__ */ new Set();
  if (flet) {
    for (const n of flet.assays) {
      assays.set(n, 0);
    }
    for (const n of flet.samples) {
      sample2assay2tracks.set(n, /* @__PURE__ */ new Map());
    }
    for (const t of tkset.tklst) {
      if (!assays.has(t.assay)) continue;
      const sample = t.patient || t.sample;
      if (!sample2assay2tracks.has(sample)) continue;
      assays.set(t.assay, assays.get(t.assay) + 1);
      if (!sample2assay2tracks.get(sample).has(t.assay)) sample2assay2tracks.get(sample).set(t.assay, []);
      sample2assay2tracks.get(sample).get(t.assay).push(t);
    }
    return [assays, sample2assay2tracks, null, null, samplewithlevel];
  }
  for (const t of tkset.tklst) {
    if (!assays.has(t.assay)) assays.set(t.assay, 0);
    assays.set(t.assay, assays.get(t.assay) + 1);
  }
  let hasl1 = false, hasl2 = false;
  for (const t of tkset.tklst) {
    if (t.level1) hasl1 = true;
    if (t.level2) hasl2 = true;
  }
  if (hasl1 || hasl2) {
    level2sample = /* @__PURE__ */ new Map();
    if (hasl1 && hasl2) {
      L1_2_L2 = /* @__PURE__ */ new Map();
    }
  }
  for (const t of tkset.tklst) {
    const sample = t.sample;
    const assay = t.assay;
    if (!assay || !sample) {
      continue;
    }
    if (!sample2assay2tracks.has(sample)) sample2assay2tracks.set(sample, /* @__PURE__ */ new Map());
    if (!sample2assay2tracks.get(sample).has(assay)) sample2assay2tracks.get(sample).set(assay, []);
    sample2assay2tracks.get(sample).get(assay).push(t);
    const L1 = t.level1, L2 = t.level2;
    if (L1 || L2) {
      samplewithlevel.add(sample);
      if (L1 && L2) {
        if (!L1_2_L2.has(L1)) L1_2_L2.set(L1, /* @__PURE__ */ new Map());
        if (!L1_2_L2.get(L1).has(L2)) L1_2_L2.get(L1).set(L2, /* @__PURE__ */ new Set());
        L1_2_L2.get(L1).get(L2).add(sample);
      } else {
        const L = L1 || L2;
        if (!level2sample.has(L)) level2sample.set(L, /* @__PURE__ */ new Set());
        level2sample.get(L).add(sample);
      }
    }
  }
  return [assays, sample2assay2tracks, level2sample, L1_2_L2, samplewithlevel];
}
function sort_dimensions(assays, flet) {
  let assaynamelst;
  if (flet && flet.nosortassay) {
    assaynamelst = [...assays].map((a) => a[0]);
  } else {
    assaynamelst = [...assays].sort((a, b) => {
      const [aname, atknum] = a;
      const [bname, btknum] = b;
      if (atknum == btknum) {
        if (aname < bname) return -1;
        return 1;
      } else {
        return btknum - atknum;
      }
    }).map((a) => a[0]);
  }
  return [assaynamelst];
}
function backward_compatible(lst) {
  for (const t of lst) {
    if (t.assayname) {
      t.assay = t.assayname;
      delete t.assayname;
    }
    if (!t.assay) continue;
    if (t.patient) {
      if (t.sampletype && t.patient == t.sampletype) {
        delete t.sampletype;
      }
      if (!t.sample) {
        t.sample = t.patient;
        delete t.patient;
      }
    }
    if (!t.sample) continue;
    if (t.patient) {
      t.level1 = t.patient;
      delete t.patient;
      if (t.sampletype) {
        t.level2 = t.sampletype;
        delete t.sampletype;
      }
    }
  }
}
function findtkbytkid(block, tkid) {
  for (const t of block.tklst) {
    if (t.tkid == tkid) return true;
  }
  return false;
}
function tkhandleclick(block, tk, td1) {
  for (let i = 0; i < block.tklst.length; i++) {
    const t = block.tklst[i];
    let equal = false;
    if (tk.ds && tk.ds.iscustom) {
      if (t.ds && t.ds.label == tk.ds.label) {
        equal = true;
      }
    } else if (tk.tkid) {
      if (t.tkid == tk.tkid) equal = true;
    } else if (tk.id) {
      if (t.id == tk.id && t.file == tk.file && t.url == tk.url) {
        equal = true;
      }
    }
    if (equal) {
      block.tk_remove(i);
      block.tkchangeaffectlegend(tk);
      if (td1) {
        td1.text("");
      }
      return;
    }
  }
  let newt;
  if (tk.type == tkt.ds) {
    const newtemplate = {
      type: tk.type,
      tkid: tk.tkid,
      // must retain tkid
      ds: tk.ds,
      isvcf: tk.isvcf,
      itemlabelname: tk.itemlabelname,
      iscustom: tk.iscustom,
      vcfinfofilter: tk.vcfinfofilter,
      populationfrequencyfilter: tk.populationfrequencyfilter,
      url4variant: tk.url4variant,
      button4variant: tk.button4variant,
      viewrangeupperlimit: tk.viewrangeupperlimit
    };
    if (tk.ds.iscustom) {
      block.addchilddsnoload(tk.ds);
    }
    newt = block.block_addtk_template(newtemplate);
  } else {
    newt = block.block_addtk_template(tk);
  }
  block.tk_load(newt);
  if (td1) {
    td1.text("SHOWN");
  }
}
function tkhtmllabel(tk, block) {
  let basename;
  if (tk.type == tkt.usegm) {
    if (block) {
      switch (block.gmmode) {
        case gmmode.gmsum:
          const usecount = block.allgm.reduce((i, j) => i + (j.hidden ? 0 : 1), 0);
          basename = tk.name + ", sum of " + (usecount < block.allgm.length ? usecount + " of " + block.allgm.length : usecount) + " isoforms";
          break;
        case gmmode.splicingrna:
          basename = tk.name + " exons";
          break;
        case gmmode.exononly:
          basename = tk.name + " RNA";
          break;
        case gmmode.genomic:
          basename = tk.name + " genomic view";
          break;
        case gmmode.protein:
          basename = tk.name + " protein";
          break;
      }
    } else {
      basename = tk.name;
    }
  } else if (tk.type == tkt.ds) {
    basename = tk.ds.label;
  } else if (tk.name) {
    basename = tk.name;
  } else {
    if (tk.dslabel) {
      basename = tk.dslabel;
    } else {
      const lst = [];
      if (tk.patient) lst.push(tk.patient);
      if (tk.sampletype) lst.push(tk.sampletype);
      if (tk.assayname) lst.push(tk.assayname);
      basename = lst.join(" ");
    }
  }
  if (tk.type == tkt.junction) {
    if (tk.totalsamplecount == void 0) {
      return basename;
    }
    if (tk.totalsamplecount == 1) {
      return basename;
    }
    return `${basename} (${tk.totalsamplecount})`;
  }
  if (!tk.tracks || tk.tracks.length == 1) {
    return basename;
  }
  return `${basename} (${tk.tracks.length})`;
}
function stringisurl(s) {
  const ss = s.toLowerCase();
  if (ss.startsWith("http://")) return true;
  if (ss.startsWith("https://")) return true;
  if (ss.startsWith("ftp://")) return true;
  return false;
}
function notAllowedToHideThisTrack(tk) {
  if (tk.type == tkt.usegm) return true;
  if (tk.type == "mds3" && tk.dslabel) return true;
  if (tk.type == "bam" && tk.gdcFile) return true;
  return false;
}
export {
  block_tk_menu_default as default
};
//# sourceMappingURL=block.tk.menu-57OP5UW5.js.map
