import {
  blocklazyload
} from "./chunk-3SZ6GKLB.js";
import {
  bulkin,
  content2flag
} from "./chunk-ZTYNN6G5.js";
import "./chunk-DKVUOBIE.js";
import {
  getsjcharts
} from "./chunk-MKAF2BHB.js";
import "./chunk-VGYTAYFK.js";
import {
  block_init_default
} from "./chunk-67DBIM6H.js";
import {
  appear2 as appear,
  disappear2 as disappear,
  export_data,
  filetypeselect,
  font,
  newpane,
  sayerror
} 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 {
  init_bulk_flag
} 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 {
  dtcloss,
  dtdel,
  dtitd,
  dtnloss,
  dtsnvindel,
  mclass,
  mclasscnvgain,
  mclasscnvloss,
  mclassfusionrna,
  mclasssv,
  mclassutr3,
  mclassutr5
} from "./chunk-4UWS5Y3N.js";
import "./chunk-DD4R5P6W.js";
import "./chunk-JNITUVXP.js";
import {
  json_default
} from "./chunk-KSGA62R2.js";
import "./chunk-LOZEKOES.js";
import "./chunk-TOU7EVFQ.js";
import "./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/tp.classes.js
function tp_classes_default(cohort, button, folder) {
  let nothing = true;
  for (const k in cohort.dsset) {
    nothing = false;
  }
  if (nothing) {
    button.remove();
    folder.remove();
    return null;
  }
  const cbreakdown = /* @__PURE__ */ new Map();
  let totalcount = 0;
  for (const dskey in cohort.dsset) {
    const data = cohort.dsset[dskey].bulkdata;
    if (!data) continue;
    const class2count = /* @__PURE__ */ new Map();
    const svstr = /* @__PURE__ */ new Set();
    const fusionstr = /* @__PURE__ */ new Set();
    for (const n in data) {
      for (const m of data[n]) {
        const c = m.class;
        if (c == mclasssv) {
          svstr.add((m.sample ? m.sample : "") + "." + (m.sampletype ? m.sampletype : "") + JSON.stringify(m.pairlst));
          continue;
        }
        if (c == mclassfusionrna) {
          fusionstr.add(
            (m.sample ? m.sample : "") + "." + (m.sampletype ? m.sampletype : "") + JSON.stringify(m.pairlst)
          );
          continue;
        }
        totalcount++;
        if (!class2count.has(c)) {
          class2count.set(c, 0);
        }
        class2count.set(c, class2count.get(c) + 1);
      }
    }
    if (svstr.size) {
      class2count.set(mclasssv, svstr.size);
      totalcount += svstr.size;
    }
    if (fusionstr.size) {
      class2count.set(mclassfusionrna, fusionstr.size);
      totalcount += fusionstr.size;
    }
    cbreakdown.set(dskey, class2count);
  }
  button.html(totalcount + ' <span style="font-size:.8em">VARIANTS</span>').attr("aria-label", "A summary of variant hits from all genes, in descending order.");
  const table = folder.append("table").style("margin-right", "20px");
  const trup = table.append("tr");
  const trdown = table.append("tr");
  const showclst = (lst, holder, number) => {
    holder.selectAll("*").remove();
    for (const i of lst) {
      const d = holder.append("div").style("margin", "10px");
      d.append("span").attr("class", "sja_mcdot").style("background-color", i.color).style("padding", "2px 5px").style("margin-right", "5px").html(number ? i.count : "&nbsp;&nbsp;");
      d.append("span").style("color", i.color).text(i.label);
    }
  };
  const ds2clst = {};
  for (const [dskey, class2count] of cbreakdown) {
    const lst = [];
    for (const [k, count] of class2count) {
      const mc = mclass[k];
      if (mc.dt == dtsnvindel || mc.dt == dtitd || mc.dt == dtdel || mc.dt == dtnloss || mc.dt == dtcloss) {
        lst.push({
          key: k,
          label: mc.label,
          color: mc.color,
          count
        });
      }
    }
    lst.sort((a, b) => b.count - a.count);
    for (const thisclass of [mclasscnvloss, mclasscnvgain, mclasssv, mclassfusionrna]) {
      if (class2count.has(thisclass)) {
        const c = mclass[thisclass];
        lst.push({
          key: thisclass,
          label: c.label,
          color: c.color,
          count: class2count.get(thisclass)
        });
      }
    }
    ds2clst[dskey] = lst;
    const cholder = trdown.append("td").attr("valign", "top").attr("shownumber", 0);
    showclst(lst, cholder, true);
    const td = trup.append("td").style("border-bottom", "solid 1px #ccc").style("padding", "5px 10px").style("color", "#858585").style("font-size", ".8em").text(cohort.dsset[dskey].label);
    td.append("button").style("margin", "5px").text("Hide number").on("click", (event) => {
      const number = cholder.attr("shownumber") == "1";
      showclst(lst, cholder, number);
      cholder.attr("shownumber", number ? "0" : "1");
      event.target.innerHTML = number ? "Hide number" : "Show number";
    });
  }
  return totalcount ? ds2clst : null;
}

// src/tp.gene.geneexpression.js
function tp_getgeneexpression(arg) {
  Promise.resolve().then(() => {
    if (!arg.gene) throw { message: "gene name missing" };
    if (!arg.genome) throw { message: "genome name missing" };
    if (arg.hostURL == void 0) throw { message: "no hostURL" };
    if (!arg.loadgeneexpressionfromofficialds) throw { message: "loadgeneexpressionfromofficialds missing" };
    if (!arg.loadgeneexpressionfromofficialds.dataset) throw { message: "dataset missing from loadgeneexpressionfromofficialds" };
    const par = {
      genome: arg.genome,
      dsname: arg.loadgeneexpressionfromofficialds.dataset,
      expressiononly: 1,
      genename: arg.gene,
      jwt: arg.jwt
    };
    return fetch(new Request(arg.hostURL + "/dsdata", {
      method: "POST",
      body: JSON.stringify(par)
    })).then((data) => {
      return data.json();
    }).then((data) => {
      if (data.error) throw { message: data.error };
      if (!data.data) throw { message: "cannot get data" };
      return data.data;
    });
  }).then((data) => {
    for (let i = 0; i < data.length; i++) {
      const par = {
        data: data[i].lst,
        expp: data[i].config,
        genename: arg.gene,
        presize: {
          x: arg.x + 40 * i,
          y: arg.y + 40 * i,
          width: 350,
          height: 650
        }
      };
      import("./ep-CXCATXYH.js").then((p) => {
        new p.default(par);
      });
    }
  }).catch((err) => {
    const pane = newpane({ x: arg.x || 600, y: arg.y || 80 });
    pane.body.append("p").text("Error getting gene expression: " + err);
  });
}

// src/tp.gene.js
var tip = new Menu();
function tp_gene_default(cohort, ds2clst, butt, folder, defaulthide, host) {
  if (!ds2clst) return null;
  const hostURL = host || "";
  const union = {};
  let genelst = [];
  for (const k in cohort.dsset) {
    for (const gn in cohort.dsset[k].bulkdata) {
      if (!(gn in union)) {
        union[gn] = { mcount: 0, isoform: {} };
        genelst.push(gn);
      }
      union[gn].mcount += cohort.dsset[k].bulkdata[gn].length;
      for (const m of cohort.dsset[k].bulkdata[gn]) {
        const i = m.isoform;
        if (!i) continue;
        union[gn].isoform[i] = 1;
      }
    }
  }
  let genelimit = Math.min(100, genelst.length);
  const noncodingclass = /* @__PURE__ */ new Set(["Intron", "P", "S", "E", mclassutr3, mclassutr5]);
  const gene2import = {};
  const ds2import = {};
  let usenoncoding = true, importsilent = false;
  butt.html(genelst.length + ' <span style="font-size:.8em">GENES</span>').attr("aria-label", "A summary table of gene by variant type, order by number of hits in descending order.");
  const errdiv = folder.append("div");
  const sayerror2 = (m) => {
    sayerror(errdiv, m);
  };
  const toprow = folder.append("div").style("margin-bottom", "8px");
  toprow.append("button").style("margin-right", "10px").text("Configure").on("click", () => {
    if (optiondiv.style("display") == "block") {
      disappear(optiondiv);
    } else {
      appear(optiondiv);
    }
  });
  toprow.append("button").style("margin-right", "10px").text("Download").on("click", () => {
    const txt = dotable();
    export_data("Gene summary", [{ text: txt }]);
  });
  toprow.append("input").attr("type", "search").attr("size", 10).attr("placeholder", "Find gene").style("margin", "0px 20px 0px 5px").on("keyup", (event) => {
    let n = event.target.value;
    if (n == "") {
      tip.hide();
      return;
    }
    if (cohort.geneToUpper) {
      n = n.toUpperCase();
    }
    if (event.code == "Enter") {
      tip.hide();
      event.target.value = "";
      if (n in union) {
        paintgene(n);
      }
      return;
    }
    const hit = [];
    for (const gn in union) {
      if (gn.indexOf(n) == 0) {
        hit.push({ name: gn, count: union[gn].mcount });
      }
    }
    if (hit.length == 0) {
      tip.hide();
      return;
    }
    hit.sort((a, b) => b.count - a.count);
    tip.clear().showunder(event.target);
    for (let i = 0; i < Math.min(30, hit.length); i++) {
      const n2 = hit[i].name;
      const row = tip.d.append("div").attr("class", "sja_menuoption_y").on("click", () => {
        paintgene(n2);
      });
      row.append("span").text(n2);
      row.append("span").style("font-size", ".7em").text(hit[i].count);
    }
  });
  toprow.append("a").attr("href", "https://docs.google.com/document/d/1NrH1H-FUWJtEKLk69V-k8uaYHOr9YO2obM9ZLZslEQ0/edit?usp=sharing").attr("target", "_blank").text("Help");
  const secondrow = folder.append("div").style("border", "solid 1px #ccc").style("margin", "10px 0px");
  const optiondiv = secondrow.append("div").style("display", "none").style("background-color", "#f1f1f1");
  const scrolltoppad = 140;
  const scrollholder = secondrow.append("div").style("padding-top", scrolltoppad + "px").style("position", "relative");
  const scrolldiv = scrollholder.append("div").style("overflow-y", "scroll").style("height", "400px").style("resize", "vertical");
  const table = scrolldiv.append("table").style("border-spacing", "1px").style("border-collapse", "separate");
  const oprow1 = optiondiv.append("div").style("padding", "10px").style("border-bottom", "dashed 1px #ccc");
  const oprow2 = optiondiv.append("div").style("padding", "10px").style("border-bottom", "dashed 1px #ccc");
  const oprow3 = optiondiv.append("div").style("padding", "10px").style("border-bottom", "dashed 1px #ccc");
  const gcsays = oprow1.append("span").style("padding-right", "10px").text("Showing " + (genelimit < genelst.length ? "top " + genelimit + " genes" : "all genes"));
  oprow1.append("button").text("more").on("click", () => {
    genelimit = Math.min(genelst.length, genelimit + 10);
    gcsays.text("Showing " + (genelimit < genelst.length ? "top " + genelimit : "all genes"));
    dotable();
  });
  oprow1.append("button").text("less").on("click", () => {
    genelimit = Math.max(1, genelimit - 10);
    gcsays.text("Showing " + (genelimit < genelst.length ? "top " + genelimit : "all genes"));
    dotable();
  });
  oprow2.append("span").text("Show subset").style("padding-right", "10px");
  const genesetta = oprow2.append("textarea").attr("rows", 1).attr("cols", 20).attr("placeholder", "enter gene names").style("margin-right", "10px");
  oprow2.append("button").text("Submit").on("click", () => {
    const v = genesetta.property("value").trim();
    if (v == "") return;
    const lst = v.split(/[\s\t\n]+/), good = [], nomatch = [];
    for (const s of lst) {
      if (s == "") continue;
      const n = cohort.geneToUpper ? s.trim().toUpperCase() : s.trim();
      if (n in union) {
        good.push(n);
      } else {
        nomatch.push(s);
      }
    }
    if (nomatch.length) {
      sayerror2("No match found for " + nomatch.join(", "));
    }
    if (good.length == 0) return;
    genelst = good;
    genelimit = good.length;
    dotable();
  });
  oprow2.append("button").text("Use default").on("click", () => {
    genelst = [];
    for (const n in union) {
      genelst.push(n);
    }
    genelimit = Math.min(100, genelst.length);
    dotable();
  });
  oprow3.append("span").html("Noncoding mutation visibility:&nbsp;");
  const oprow3select = oprow3.append("select").on("change", () => {
    usenoncoding = !usenoncoding;
    for (const dat of attrlst) {
      if (!dat.atlst) {
        continue;
      }
      for (const at of dat.atlst) {
        if (!at.ismclass) continue;
        if (usenoncoding) {
          at.hide = false;
          continue;
        }
        at.hide = noncodingclass.has(at.key);
      }
    }
    dotable();
  });
  oprow3select.append("option").text("show").attr("value", "y");
  oprow3select.append("option").text("hide").attr("value", "n");
  oprow3.append("p").style("font-size", ".8em").style("color", "#858585").text("Including: silent, splice_region, exon, UTR, and intron.");
  const hassamplelst = [];
  for (const k in cohort.dsset) {
    const d = cohort.dsset[k];
    if (d.hassample) {
      hassamplelst.push(d);
    }
  }
  if (hassamplelst.length) {
    const oprow5 = optiondiv.append("div").style("padding", "10px").style("border-bottom", "dashed 1px #ccc");
    oprow5.append("span").html("Gene recurrence (# of samples for each gene):&nbsp;");
    for (const ds of hassamplelst) {
      oprow5.append("button").text(hassamplelst.length == 1 ? "show" : ds.label).on("click", (event) => {
        const bars = [];
        for (const gene of genelst) {
          const hash = {};
          let samplecount = 0;
          if (gene in ds.bulkdata) {
            for (const m of ds.bulkdata[gene]) {
              if (!usenoncoding && noncodingclass.has(m.class)) return;
              if (!(m.sample in hash)) {
                hash[m.sample] = 1;
                samplecount++;
              }
            }
          }
          bars.push({
            name: gene,
            size: samplecount
          });
        }
        const pos = event.target.getBoundingClientRect();
        barplot(bars, "#76B38C", "Number of samples" + (usenoncoding ? "" : ", excluding noncoding mutations"), pos);
      });
    }
    const oprow6 = optiondiv.append("div").style("padding", "10px").style("border-bottom", "dashed 1px #ccc");
    oprow6.append("span").html("Mutation burden (# mutations for each sample):&nbsp;");
    for (const ds of hassamplelst) {
      oprow6.append("button").text(hassamplelst.length == 1 ? "show" : ds.label).on("click", (event) => {
        const samplehash = {};
        for (const g in ds.bulkdata) {
          for (const m of ds.bulkdata[g]) {
            const n = m.sample;
            if (n) {
              if (!usenoncoding && noncodingclass.has(m.class)) continue;
              if (!(n in samplehash)) {
                samplehash[n] = 0;
              }
              samplehash[n]++;
            }
          }
        }
        const bars = [];
        for (const n in samplehash) {
          bars.push({
            name: n,
            size: samplehash[n]
          });
        }
        const pos = event.target.getBoundingClientRect();
        barplot(bars, "#76B38C", "Mutation burden" + (usenoncoding ? "" : ", excluding noncoding mutations"), pos);
      });
    }
  }
  const oprow7 = optiondiv.append("div").style("padding", "10px").style("border-bottom", "dashed 1px #ccc").text("Click on a column header to rank genes.");
  const attrlst = [
    {
      label: "Name",
      isgenename: true
    }
  ];
  let firstsort = true;
  let dscount = 0;
  for (const dsname in cohort.dsset) {
    dscount++;
    const thisds = {
      name: cohort.dsset[dsname].label,
      atlst: [
        {
          label: "# mutation",
          get: (gn) => {
            if (!(gn in cohort.dsset[dsname].bulkdata)) return 0;
            if (usenoncoding) {
              return cohort.dsset[dsname].bulkdata[gn].length;
            }
            let c = 0;
            for (const i of cohort.dsset[dsname].bulkdata[gn]) {
              if (!noncodingclass.has(i.class)) c++;
            }
            return c;
          },
          rotate: true,
          descend: true,
          sort: firstsort
          //secondsort:true, // secondary, so to keep order persistant when sorting on classes with many genes having same number in sorted class
        }
      ]
    };
    firstsort = false;
    if (cohort.dsset[dsname].hassample) {
      thisds.atlst.push({
        label: "# sample",
        get: (gn) => {
          if (!(gn in cohort.dsset[dsname].bulkdata)) return 0;
          const set = /* @__PURE__ */ new Set();
          for (const m of cohort.dsset[dsname].bulkdata[gn]) {
            if (!usenoncoding && noncodingclass.has(m.class)) continue;
            if (!m.sample) continue;
            set.add(m.sample);
          }
          return set.size;
        },
        rotate: true,
        descend: true
      });
    }
    for (const c of ds2clst[dsname]) {
      c.ismclass = true;
      c.get = (gn) => {
        if (!(gn in cohort.dsset[dsname].bulkdata)) return 0;
        let total = 0;
        for (const m of cohort.dsset[dsname].bulkdata[gn]) {
          if (m.class == c.key) total++;
        }
        return total;
      };
      c.rotate = true;
      c.descend = true;
      thisds.atlst.push(c);
    }
    attrlst.push(thisds);
  }
  const dotable = () => {
    let sortkey = null, sortkey2 = null;
    for (const a of attrlst) {
      if (a.hide) continue;
      if (a.atlst) {
        for (const b of a.atlst) {
          if (b.hide) continue;
          if (b.sort) {
            sortkey = b;
            continue;
          }
          if (b.secondsort) {
            sortkey2 = b;
            continue;
          }
        }
        continue;
      }
      if (a.sort) {
        sortkey = a;
        continue;
      }
      if (a.secondsort) {
        sortkey2 = a;
      }
    }
    if (sortkey) {
      genelst.sort((a, b) => {
        if (sortkey.isgenename) {
          if (a < b) {
            return sortkey.descend ? 1 : -1;
          }
          return sortkey.descend ? -1 : 1;
        }
        const i = sortkey.get(a), j = sortkey.get(b);
        if (typeof i == "string") {
          if (i < j) {
            return sortkey.descend ? 1 : -1;
          }
          return sortkey.descend ? -1 : 1;
        }
        if (i == j) {
          if (sortkey2) {
            const i2 = sortkey2.get(a), j2 = sortkey2.get(b);
            if (i2 == j2) {
              if (a in gene2import) {
                if (!(b in gene2import)) return -1;
              } else if (b in gene2import) {
                return 1;
              }
            } else {
              return j2 - i2;
            }
          } else {
            if (a in gene2import) {
              if (!(b in gene2import)) return -1;
            } else if (b in gene2import) {
              return 1;
            }
          }
          return a < b ? -1 : 1;
        }
        return sortkey.descend ? j - i : i - j;
      });
    }
    const importclass = {};
    let hasimport = false;
    for (const dsname in ds2import) {
      hasimport = true;
      const classcount = {};
      for (let i = 0; i < genelimit; i++) {
        const gene = genelst[i];
        if (gene in gene2import && dsname in gene2import[gene]) {
          for (const c in gene2import[gene][dsname].class) {
            if (!(c in classcount)) {
              classcount[c] = 0;
            }
            classcount[c] += gene2import[gene][dsname].class[c];
          }
        }
      }
      const clst = [];
      for (const c in classcount) {
        clst.push({
          class: c,
          n: classcount[c]
        });
      }
      clst.sort((a, b) => b.n - a.n);
      importclass[dsname] = clst;
    }
    const impspace = "solid 10px white";
    table.selectAll("*").remove();
    const tr1 = table.append("tr");
    tr1.append("td").style("height", "0px").style("padding", "0px");
    tr1.append("td").style("height", "0px").style("padding", "0px");
    for (const ds of attrlst) {
      if (!ds.atlst) continue;
      let spannum = 0;
      for (const a of ds.atlst) {
        if (!a.hide) spannum++;
      }
      tr1.append("td").attr("colspan", spannum).style("text-align", "center").style("border-right", impspace).append("div").style("position", "absolute").style("top", "1px").style("border-bottom", dscount > 1 ? "solid 1px black" : "").text(dscount > 1 ? ds.name : "");
    }
    for (const dsname in ds2import) {
      const td = tr1.append("td").attr("colspan", 2 + importclass[dsname].length).style("border-right", impspace).append("div").style("top", "2px").style("position", "absolute").style("color", cohort.genome.datasets[dsname].color).style("border-bottom", "solid 1px " + cohort.genome.datasets[dsname].color);
      td.append("span").text(
        cohort.genome.datasets[dsname].label + (ds2import[dsname].totalsample ? ", " + ds2import[dsname].totalsample + " total samples" : "")
      );
      td.append("div").style("position", "absolute").style("right", "0px").style("top", "-5px").attr("class", "sja_clb").html("&#10005;").on("click", () => {
        delete ds2import[dsname];
        for (const n in gene2import) {
          delete gene2import[n][dsname];
        }
        dotable();
      });
    }
    const exportlines = [];
    const exportheader = [];
    const tr2 = table.append("tr");
    tr2.append("td").style("height", "0px").style("padding", "0px");
    for (const a of attrlst) {
      if (a.hide) continue;
      let lst = [];
      if (a.atlst) {
        lst = a.atlst;
      } else {
        lst = [a];
      }
      let td;
      for (const at of lst) {
        if (at.hide) continue;
        td = tr2.append("td").attr("class", "sja_clbtext").style("font-size", ".8em").style("height", "0px").style("padding", "0px").style("color", at.color ? at.color : "black").style("white-space", "nowrap");
        td.append("div").html(
          at.rotate ? at.sort ? (at.descend ? "&#9664;" : "&#9654;") + " " + at.label : at.label : at.label + (at.sort ? " " + (at.descend ? "&#9662;" : "&#9652;") : "")
        ).style("position", "absolute").style("top", scrolltoppad - 25 + "px").style("transform", at.rotate ? "translate(-3px,0px) rotate(-90deg)" : "").style("width", at.rotate ? "25px" : "auto").on("click", () => {
          const ps = at.sort;
          for (const a2 of attrlst) {
            if (a2.atlst) {
              for (const b of a2.atlst) {
                b.sort = false;
              }
            } else {
              a2.sort = false;
            }
          }
          at.sort = true;
          if (ps) {
            at.descend = !at.descend;
          }
          dotable();
        });
        exportheader.push(at.label + (a.name ? "." + a.name : ""));
      }
      td.style("border-right", impspace);
    }
    for (const dsname in ds2import) {
      tr2.append("td").style("font-size", ".8em").style("height", "0px").style("padding", "0px").style("white-space", "nowrap").append("div").html("# mutation").style("position", "absolute").style("top", scrolltoppad - 25 + "px").style("transform", "translate(-3px,0px) rotate(-90deg)").style("width", "25px");
      exportheader.push(dsname + ".#mutation");
      tr2.append("td").style("font-size", ".8em").style("height", "0px").style("padding", "0px").style("white-space", "nowrap").append("div").html("# sample").style("position", "absolute").style("top", scrolltoppad - 25 + "px").style("transform", "translate(-3px,0px) rotate(-90deg)").style("width", "25px");
      exportheader.push(dsname + ".#sample");
      let td;
      for (const cls of importclass[dsname]) {
        td = tr2.append("td").style("font-size", "80%").style("overflow-y", "hidden").style("height", "0px").style("padding", "0px").style("color", mclass[cls.class].color).style("white-space", "nowrap");
        td.append("div").html(mclass[cls.class].label).style("position", "absolute").style("top", scrolltoppad - 25 + "px").style("transform", "translate(-3px,0px) rotate(-90deg)").style("width", "25px");
        exportheader.push(dsname + "." + mclass[cls.class].label);
      }
      if (td) {
        td.style("border-right", impspace);
      }
    }
    exportlines.push(exportheader.join("	"));
    for (let i = 0; i < genelimit; i++) {
      const gene = genelst[i];
      const exportline = [gene];
      const tr = table.append("tr");
      tr.append("td").text(i + 1).style("font-size", ".7em").style("text-align", "right");
      for (const at of attrlst) {
        if (at.hide) continue;
        if (at.isgenename) {
          tr.append("td").text(genelst[i]).attr("class", "sja_menuoption_y").style("color", "black").style("display", "table-cell").on("click", () => {
            paintgene(genelst[i]);
          });
          continue;
        }
        let td;
        for (const bt of at.atlst) {
          if (bt.hide) continue;
          td = tr.append("td").style("color", "black").style("background-color", "#f1f1f1");
          const m = bt.get(gene);
          if (typeof m == "number") {
            if (bt.color) {
              if (m > 0) {
                td.style("text-align", "center").append("span").attr("class", "sja_mcdot").style("background-color", bt.color).html(m > 1 ? m : "&nbsp;");
              } else {
                td.append("span").attr("class", "sja_mcdot").style("margin", "0px 4px").html("&nbsp;");
              }
            } else {
              td.text(m);
            }
          } else {
            td.text(m);
          }
          exportline.push(m);
        }
        td.style("border-right", impspace);
      }
      for (const dsname in ds2import) {
        let sample = 0, total = 0, classsum = {}, notexist = true, pending = false;
        if (gene in gene2import) {
          const ipd = gene2import[gene][dsname];
          if (!ipd) continue;
          notexist = false;
          if (ipd.pending) {
            pending = true;
            continue;
          }
          sample += ipd.sample;
          total += ipd.total;
          for (const c in ipd.class) {
            if (!(c in classsum)) {
              classsum[c] = 0;
            }
            classsum[c] += ipd.class[c];
          }
        }
        if (notexist) {
          tr.append("td").attr("colspan", 2 + importclass[dsname].length);
          continue;
        }
        if (pending) {
          tr.append("td").attr("colspan", 2 + importclass[dsname].length).text("loading ...");
          continue;
        }
        tr.append("td").text(total).style("background-color", "#f1f1f1");
        exportline.push(total);
        tr.append("td").text(sample).style("background-color", "#f1f1f1");
        exportline.push(sample);
        let td;
        for (const cls of importclass[dsname]) {
          td = tr.append("td").style("text-align", "center").style("background-color", "#f1f1f1");
          const _count = classsum[cls.class];
          if (_count) {
            td.append("span").attr("class", "sja_mcdot").style("background-color", mclass[cls.class].color).html(_count > 1 ? _count : "&nbsp;");
          } else {
            td.append("span").attr("class", "sja_mcdot").style("margin", "0px 4px").html("&nbsp;");
          }
          exportline.push(_count);
        }
        td.style("border-right", impspace);
      }
      exportlines.push(exportline.join("	"));
    }
    return exportlines.join("\n");
  };
  dotable();
  function paintgene(gene) {
    if (!(gene in union)) return;
    tip.hide();
    const dslst = [];
    for (const k in cohort.dsset) {
      dslst.push(k);
    }
    let pane;
    for (const isoform in union[gene].isoform) {
      if (!pane) {
        pane = newpane({ x: 100, y: 100 });
      }
      block_init_default({
        hostURL,
        jwt: cohort.jwt,
        holder: pane.body,
        genome: cohort.genome,
        query: isoform,
        nopopup: true,
        dataset: dslst
      });
    }
    if (cohort.loadgeneexpressionfromofficialds) {
      tp_getgeneexpression({
        gene,
        genome: cohort.genome.name,
        loadgeneexpressionfromofficialds: cohort.loadgeneexpressionfromofficialds,
        hostURL: cohort.hostURL,
        jwt: cohort.jwt,
        x: 1e3,
        y: 80
      });
    }
  }
}
async function barplot(bars, color, label, pos) {
  const barplot2 = await import("./plot.barplot-342AYQC7.js");
  return barplot2.default(bars, color, label, pos);
}

// src/tp.pathway.js
var tip2 = new Menu();

// src/hcmap.js
function inithcmap(hm, holder) {
  const err = (m) => {
    sayerror(holder, m);
  };
  if (!hm.metadata) return err("no metadata");
  const mdh = hm.metadata;
  const legendholder = holder.append("div").style("display", "inline-block").style("border", "solid 1px #ccc").style("margin", "20px").style("padding", "20px");
  const svg = holder.append("svg");
  if (!hm.text) return err("text missing");
  const lines = hm.text.trim().split("\n");
  hm.samples = [];
  const l = lines[0].split("	");
  for (let i = 2; i < l.length; i++) {
    hm.samples.push(l[i]);
  }
  if (hm.samples.length == 0) return err("no column names");
  hm.items = [];
  for (let i = 1; i < lines.length; i++) {
    const l2 = lines[i].split("	");
    const type = l2[0];
    const md = mdh[type];
    if (!md) return err("invalid data type " + type);
    const name = l2[1];
    const lst = [];
    for (let j = 2; j < l2.length; j++) {
      const vlst = l2[j].split(";");
      const colorlst = [];
      for (const v of vlst) {
        if (!md[v]) {
          return err("invalid value " + v + " at " + name + " and " + hm.samples[j - 2]);
        }
        colorlst.push(md[v].color);
      }
      lst.push(colorlst);
    }
    hm.items.push({
      name,
      type,
      lst
    });
  }
  hm.geneonrow = true;
  if (!hm.rowh) {
    hm.rowh = 20;
  }
  if (!hm.colw) {
    hm.colw = 20;
  }
  if (!hm.rowspace) {
    hm.rowspace = 2;
  }
  if (!hm.colspace) {
    hm.colspace = 2;
  }
  if (!hm.rowlabtickspace) {
    hm.rowlabtickspace = 4;
  }
  if (!hm.collabtickspace) {
    hm.collabtickspace = 4;
  }
  if (!hm.rowtick) {
    hm.rowtick = 5;
  }
  if (!hm.coltick) {
    hm.coltick = 5;
  }
  render(hm, svg, legendholder, err);
}
function render(hm, svg, legendholder, err) {
  const mdh = hm.metadata;
  for (const key in mdh) {
    for (const value in mdh[key]) {
      const o = mdh[key][value];
      if (!o.label) return err(".label missing for metadata " + key + "[" + value + "]");
      if (!o.color) return err(".color missing for metadata " + key + "[" + value + "]");
    }
  }
  for (const key in mdh) {
    const d1 = legendholder.append("div").style("display", "inline-block").style("margin", "20px").style("vertical-align", "top");
    d1.append("div").text(key).style("margin", "5px 3px").style("font-weight", "bold");
    const d2 = d1.append("div").style("margin", "3px");
    for (const v in mdh[key]) {
      const o = mdh[key][v];
      const row = d2.append("div").style("margin", "3px");
      row.append("div").style("display", "inline-block").style("background-color", o.color).style("width", "14px").style("height", "14px").style("margin-right", "10px");
      row.append("span").text(o.label);
    }
  }
  const rowlabfontsize = hm.rowh - 3, collabfontsize = hm.colw - 3;
  let labels = [];
  for (const i of hm.items) {
    labels.push(i.name);
  }
  let genenamewidth = 0;
  for (const n of labels) {
    svg.append("text").text(n).attr("font-size", hm.geneonrow ? rowlabfontsize : collabfontsize).attr("font-family", font).each(function() {
      genenamewidth = Math.max(genenamewidth, this.getBBox().width);
    }).remove();
  }
  let samplenamewidth = 0;
  for (const n of hm.samples) {
    svg.append("text").text(n).attr("font-size", hm.geneonrow ? collabfontsize : rowlabfontsize).attr("font-family", font).each(function() {
      samplenamewidth = Math.max(samplenamewidth, this.getBBox().width);
    }).remove();
  }
  const rowlabw = hm.geneonrow ? genenamewidth : samplenamewidth;
  const collabh = hm.geneonrow ? samplenamewidth : genenamewidth;
  const mapwidth = hm.samples.length * (hm.colw + hm.colspace) - hm.colspace;
  const mapheight = hm.items.length * (hm.rowh + hm.rowspace) - hm.rowspace;
  svg.attr("width", rowlabw + hm.rowlabtickspace + hm.rowtick + mapwidth + 100).attr("height", collabh + hm.collabtickspace + hm.coltick + mapheight);
  const originx = rowlabw + hm.rowlabtickspace + hm.rowtick;
  const originy = collabh + hm.collabtickspace + hm.coltick;
  let y = originy;
  for (const item of hm.items) {
    const g = svg.append("g").attr("transform", "translate(" + (originx - hm.rowlabtickspace - hm.rowtick) + "," + (y + hm.rowh / 2) + ")");
    g.append("text").text(item.name).attr("font-size", rowlabfontsize).attr("font-family", font).attr("fill", "black").attr("text-anchor", "end").attr("dominant-baseline", "central");
    g.append("line").attr("stroke", "black").attr("shape-rendering", "crispEdges").attr("x1", hm.rowlabtickspace).attr("x2", hm.rowlabtickspace + hm.rowtick);
    y += hm.rowh + hm.rowspace;
  }
  let x = originx;
  for (const sample of hm.samples) {
    const g = svg.append("g").attr("transform", "translate(" + (x + hm.colw / 2) + "," + collabh + ")");
    g.append("text").text(sample).attr("font-size", collabfontsize).attr("font-family", font).attr("fill", "black").attr("dominant-baseline", "central").attr("transform", "rotate(-90)");
    g.append("line").attr("stroke", "black").attr("shape-rendering", "crispEdges").attr("y1", hm.collabtickspace).attr("y2", hm.collabtickspace + hm.coltick);
    x += hm.colw + hm.colspace;
  }
  y = originy;
  for (const item of hm.items) {
    let x2 = originx;
    for (let i = 0; i < hm.samples.length; i++) {
      const sample = hm.samples[i];
      const g = svg.append("g").attr("transform", "translate(" + (x2 + hm.colw / 2) + "," + (y + hm.rowh / 2) + ")");
      const pieceh = hm.rowh / item.lst[i].length;
      const colorlst = item.lst[i];
      for (let j = 0; j < colorlst.length; j++) {
        const v = colorlst[j];
        g.append("rect").attr("x", -hm.colw / 2).attr("y", -hm.rowh / 2 + j * pieceh).attr("width", hm.colw).attr("height", pieceh).attr("fill", v).attr("shape-rendering", "crispEdges");
      }
      x2 += hm.colw + hm.colspace;
    }
    y += hm.rowh + hm.rowspace;
  }
  svg.append("rect").attr("x", originx).attr("y", originy).attr("width", hm.samples.length * (hm.colw + hm.colspace) - hm.colspace).attr("height", hm.items.length * (hm.rowh + hm.rowspace) - hm.rowspace).attr("stroke", "black").attr("fill", "none").attr("shape-rendering", "crispEdges");
}

// src/tp.e2pca.js
function tp_e2pca_default(cohort, folder) {
  for (const obj of cohort.e2pca.list) {
    const holder = folder.append("div").style("display", "inline-block").style("margin", "20px").style("vertical-align", "top");
    if (cohort.e2pca.list.length > 1) {
      holder.style("border", "solid 1px #ededed");
    }
    if (obj.name) {
      holder.append("div").text(obj.name).style("background-color", "#f1f1f1").style("padding", "5px 10px");
    }
    const toprow = holder.append("div").style("margin", "20px");
    json_default(cohort.hostURL + "/textfile").post(JSON.stringify({ file: obj.vectorfile, jwt: cohort.jwt }), (data) => {
      if (data.error) {
        sayerror(holder, "Error getting vector file: " + data.error);
        return;
      }
      import("./e2pca-KOAAU2JX.js").then((p) => {
        const [err, numdata2plot] = p.e2pca_plot({
          holder,
          toprow,
          text: data.text,
          mdanno: cohort.patientannotation,
          obj
        });
        if (err) {
          sayerror(holder, "Error: " + err);
          return;
        }
        p.e2pca_genesearchui({
          holder: toprow,
          numdata2plot,
          hostURL: cohort.hostURL,
          jwt: cohort.jwt,
          obj,
          callback: () => {
            boxplot4sampleannotation(cohort, obj);
          }
        });
        if (cohort.patientannotation) {
          obj.boxplotdiv = holder.append("div");
          const div = toprow.append("div").style("display", "inline-block").style("margin-left", "10px");
          metadataselector4pca(cohort, obj, div);
        }
      });
    });
  }
}
function boxplot4sampleannotation(cohort, obj) {
  if (!cohort.patientannotation) {
    return;
  }
  if (!obj.expressiondata) {
    return;
  }
  if (!obj.usetermkey) {
    obj.usetermkey = cohort.patientannotation.metadata[0].key;
  }
  let term = null;
  for (const t of cohort.patientannotation.metadata) {
    if (t.key == obj.usetermkey) {
      term = t;
      break;
    }
  }
  if (!term) {
    sayerror(obj.boxplotdiv, "invalid term key " + obj.usetermkey);
    return;
  }
  const samplegroups = [];
  for (const v of term.values) {
    samplegroups.push({
      valuekey: v.key,
      label: v.label,
      color: v.color,
      samples: []
    });
  }
  let minv = obj.expressiondata[0].value;
  let maxv = obj.expressiondata[0].value;
  const noattrsamples = [];
  for (const s of obj.expressiondata) {
    minv = Math.min(minv, s.value);
    maxv = Math.max(maxv, s.value);
    if (!cohort.patientannotation.annotation[s.sample]) {
      noattrsamples.push(s);
      continue;
    }
    const valuekey = cohort.patientannotation.annotation[s.sample][obj.usetermkey];
    if (valuekey == void 0) {
      noattrsamples.push(s);
      continue;
    }
    for (const sg of samplegroups) {
      if (sg.valuekey == valuekey) {
        sg.samples.push(s);
        break;
      }
    }
  }
  if (noattrsamples.length) {
    samplegroups.push({
      label: "unannotated",
      color: "#858585",
      samples: noattrsamples
    });
  }
  obj.boxplotdiv.selectAll("*").remove();
  import("./plot.boxplot-OHEJDPTW.js").then((p) => {
    const err = p.default({
      list: samplegroups,
      holder: obj.boxplotdiv,
      axislabel: obj.searchedgene
    });
    if (err) {
      sayerror(obj.boxplotdiv, "Boxplot: " + err);
    }
  });
}
function metadataselector4pca(cohort, obj, holder) {
  const tip3 = new Menu({ border: "", padding: "" });
  const noannocolor = "#858585";
  holder.append("span").text("Choose metadata").attr("class", "sja_clbtext").on("click", (event) => {
    tip3.clear();
    tip3.showunder(event.target);
    for (const term of cohort.patientannotation.metadata) {
      tip3.d.append("div").attr("class", "sja_menuoption").text(term.label).on("click", () => {
        obj.usetermkey = term.key;
        tip3.hide();
        obj.circles.attr("fill", (d) => {
          const a = cohort.patientannotation.annotation[d.sample];
          if (!a) return noannocolor;
          const valuekey = a[term.key];
          if (!valuekey) return noannocolor;
          const b = cohort.patientannotation.mdh[term.key].values[valuekey];
          if (!b) {
            console.error("invalid value key: " + valuekey + " at term: " + term.key);
            return noannocolor;
          }
          return b.color;
        });
        obj.legendholder.selectAll("*").remove();
        obj.legendholder.append("div").style("margin-bottom", "5px").text(term.label).style("font-weight", "bold");
        for (const v of term.values) {
          const row = obj.legendholder.append("div").style("margin-bottom", "3px");
          row.append("span").attr("class", "sja_mcdot").style("background-color", v.color).style("margin-right", "5px").html("&nbsp;");
          row.append("span").text(v.label);
        }
        if (obj.expressiondata) {
          boxplot4sampleannotation(cohort, obj);
        }
      });
    }
  });
}

// src/tp.ui.js
async function tpui(cohort, holder, hostURL, app = { callbacks: { sjcharts: {} } }) {
  const debugmode = app.debugmode;
  if (debugmode) {
    window.cohort = cohort;
  }
  if (!("hostURL" in cohort)) cohort.hostURL = hostURL;
  if (cohort.headerhtml) {
    holder.append("div").html(cohort.headerhtml);
  }
  let personcount = 0;
  for (const pn in cohort.p2st) {
    personcount++;
    for (const st in cohort.p2st[pn]) {
      const s = cohort.p2st[pn][st];
      s.sampletype = st;
      s.patientname = pn;
      s.cohort = cohort;
    }
  }
  const table = holder.append("table").style("margin-top", "20px");
  const tr0 = table.append("tr");
  cohort.__tdleft = tr0.append("td").style("vertical-align", "top").style("padding-right", "20px");
  cohort.__tdright = tr0.append("td").style("vertical-align", "top");
  if (cohort.hide_navigation) {
    cohort.__tdleft.style("display", "none");
  }
  if (!cohort.hide_addnewfile) {
    const [butt1, folder1] = makefolder(cohort);
    folder1.style("background-color", "#f4f4f4").style("margin", "0px 20px 20px 0px").style("padding", "20px");
    butt1.html('&#43; <span style="font-size:.8em">NEW FILE</span>');
    const saydiv = folder1.append("p");
    const filediv = folder1.append("div");
    const fileui = () => {
      filediv.selectAll("*").remove();
      filediv.append("span").html("Select data type&nbsp;");
      const typeselect = filetypeselect(filediv).style("margin-right", "20px");
      const butt = filediv.append("input").attr("type", "file").on("change", (event) => {
        saydiv.text("");
        const file = event.target.files[0];
        if (!file) {
          fileui();
          return;
        }
        if (file.size == 0) {
          saydiv.text("Wrong file: " + file.name);
          fileui();
          return;
        }
        const reader = new FileReader();
        reader.onload = (event2) => {
          saydiv.text(file.name + " loaded.");
          const flag = init_bulk_flag(cohort.genome.name);
          if (!flag) {
            saydiv.text("should not happen");
            fileui();
            return;
          }
          const error0 = content2flag(event2.target.result, typeselect.node().selectedIndex, flag);
          if (error0) {
            saydiv.text("Error with " + file.name + ": " + error0);
            fileui();
            return;
          }
          let ds = null;
          for (const k in cohort.dsset) {
            ds = cohort.dsset[k];
            break;
          }
          if (!ds) {
            saydiv.text("no dataset in cohort, this should not happen");
            fileui();
            return;
          }
          const error1 = bulkin({
            flag,
            cohort,
            flag2thisds: ds
          });
          if (error1) {
            saydiv.text("Error with " + file.name + ": " + error1);
            fileui();
            return;
          }
          if (flag.good == 0) {
            saydiv.text(file.name + ": no data loaded");
            fileui();
            return;
          }
          saydiv.text("");
          fileui();
          holder.selectAll("*").remove();
          tpui(cohort, holder, hostURL);
        };
        reader.onerror = function() {
          saydiv.text("Error reading file " + file.name);
          fileui();
          return;
        };
        saydiv.text("Parsing file " + file.name + " ...");
        reader.readAsText(file, "utf8");
      });
    };
    fileui();
  }
  const [butt2, folder2] = makefolder(cohort);
  const ds2clst = tp_classes_default(cohort, butt2, folder2);
  const hassamplelst = [];
  const hasdiseaselst = [];
  for (const k in cohort.dsset) {
    const ds = cohort.genome.datasets[k];
    if (ds.hassample) {
      hassamplelst.push(k);
    }
    if (ds.hasdisease) {
      hasdiseaselst.push(k);
    }
  }
  if (ds2clst) {
    const [butt3, folder3] = makefolder(cohort, cohort.show_genetable);
    tp_gene_default(cohort, ds2clst, butt3, folder3, personcount > 0, hostURL);
  }
  let showheatmap = false;
  if (hassamplelst.length || personcount > 0) {
    cohort.patientset = {};
    for (const patient in cohort.p2st) {
      cohort.patientset[patient] = {
        trlst: [],
        samples: cohort.p2st[patient]
      };
    }
    if (hassamplelst.length > 0 && !cohort.hardcodemap) {
      showheatmap = true;
    }
  }
  if (cohort.show_heatmap) {
    showheatmap = true;
  }
  let hm_main;
  if (showheatmap) {
    const [hmbtn, hmdiv] = makefolder(cohort);
    hmbtn.text("HEATMAP").style("font-size", ".8em");
    const sjcharts = await getsjcharts();
    const appname = (cohort.name ? cohort.name + "." : "") + "hm";
    sjcharts.heatmap({
      cohort,
      hassamplelst,
      blockinit: block_init_default,
      debugmode,
      // sjcharts has its own d3 instance so it has to
      // re-select to bind the d3 'event' properly
      dom: {
        butt: hmbtn.node(),
        holder: hmdiv.node()
      },
      tp_getgeneexpression,
      show_heatmap: cohort.show_heatmap,
      // use a subnested sjcharts object to namespace its instances
      instanceTracker: app.instanceTracker && app.instanceTracker.sjcharts,
      callbacks: app.callbacks && app.callbacks.sjcharts && (app.callbacks.sjcharts[appname] || app.callbacks.sjcharts.hm)
    });
  }
  if (cohort.hardcodemap) {
    const [hmbut, hmdiv] = makefolder(cohort, cohort.show_hardcodemap);
    hmbut.text("HEATMAP").style("font-size", ".8em");
    for (const hcmap of cohort.hardcodemap) {
      const div = hmdiv.append("div").style("display", "inline-block").style("margin-bottom", "20px");
      if (hcmap.name) {
        div.append("h3").text(hcmap.name);
      }
      inithcmap(hcmap, div);
    }
  }
  if (cohort.survivalJSON) {
    const [srvbut, srvdiv] = makefolder(cohort, cohort.show_hardcodemap);
    srvbut.text("SURVIVAL CURVE").style("font-size", ".8em").style("border-color", "transparent");
    const sjcharts = await getsjcharts();
    sjcharts.survival({
      cohort,
      dom: {
        butt: srvbut.node(),
        holder: srvdiv.node()
      },
      // use a subnested sjcharts object to namespace its instances
      instanceTracker: app.instanceTracker && app.instanceTracker.sjcharts,
      callbacks: app.callbacks && app.callbacks.sjcharts && app.callbacks.sjcharts.sv
    });
  }
  if (cohort.browserview) {
    const [butt, folder] = makefolder(cohort);
    butt.style("font-size", ".8em").text("BROWSER");
    let loaded = false;
    butt.on("click", () => {
      if (folder.style("display") == "none") {
        butt.style("border-color", "black");
        appear(folder);
      } else {
        butt.style("border-color", "transparent");
        disappear(folder);
      }
      if (loaded) return;
      loaded = true;
      const arg = {
        holder: folder,
        genome: cohort.genome,
        debugmode,
        dogtag: cohort.genome.name,
        hostURL,
        jwt: cohort.jwt,
        cohort,
        nobox: cohort.browserview.nobox,
        datasetqueries: cohort.browserview.datasetqueries,
        tklst: []
      };
      if (cohort.browserview.position) {
        arg.chr = cohort.browserview.position.chr;
        arg.start = cohort.browserview.position.start;
        arg.stop = cohort.browserview.position.stop;
      }
      if (cohort.browserview.nativetracks) {
        arg.nativetracks = cohort.browserview.nativetracks;
      }
      if (cohort.browserview.tracks) {
        for (const t of cohort.browserview.tracks) {
          arg.tklst.push(t);
        }
      }
      if (cohort.browserview.assays) {
        if (!cohort.assaylst) {
          console.error("assaylst not set!");
          cohort.assaylst = [];
        }
        for (const assayname in cohort.browserview.assays) {
          const assayview = cohort.browserview.assays[assayname];
          if (!assayview.assayobj) {
            continue;
          }
          if (assayview.combined) {
            if (assayview.combinetk) {
              arg.tklst.push(assayview.combinetk);
            }
          } else {
            for (const pn in cohort.patientset) {
              for (const st in cohort.patientset[pn].samples) {
                for (const t of cohort.patientset[pn].samples[st].tktemplate) {
                  if (t.id == assayview.assayobj.id) {
                    arg.tklst.push(t);
                  }
                }
              }
            }
          }
        }
      }
      if (cohort.browserview.defaultassaytracks) {
        const [err, lst] = cohort2assaytracks(cohort);
        if (err) {
          sayerror(holder, "error with .defaultassaytracks: " + err);
        } else {
          for (const t of lst) arg.tklst.push(t);
        }
      }
      for (const t of arg.tklst) {
        t.iscustom = true;
      }
      blocklazyload(arg);
    });
    if (cohort.show_browser) {
      butt.node().click();
    }
  }
  if (cohort.e2pca) {
    const [butt, folder] = makefolder(cohort);
    butt.text(cohort.e2pca.label).style("font-size", ".8em");
    let loaded = false;
    butt.on("click", () => {
      if (folder.style("display") == "none") {
        butt.style("border-color", "black");
        appear(folder);
      } else {
        butt.style("border-color", "transparent");
        disappear(folder);
      }
      if (loaded) return;
      loaded = true;
      tp_e2pca_default(cohort, folder);
    });
    if (cohort.show_e2pca) {
      butt.node().click();
    }
  }
}
function makefolder(cohort, show) {
  const butt = cohort.__tdleft.append("div").attr("class", "sja_menuoption").style("margin-top", "10px").style("white-space", "nowrap");
  const folder = cohort.__tdright.append("div").style("padding-bottom", "20px");
  butt.on("click", () => {
    if (folder.style("display") == "block") {
      disappear(folder);
      butt.style("border", "solid 1px transparent");
    } else {
      butt.style("border", "solid 1px #545454");
      appear(folder);
    }
  });
  if (show) {
    butt.style("border", "solid 1px #545454");
    folder.style("display", "block");
  } else {
    butt.style("border", "solid 1px transparent");
    folder.style("display", "none");
  }
  return [butt, folder];
}
function cohort2assaytracks(ct) {
  if (!ct.browserview) return [null, []];
  if (!ct.browserview.defaultassaytracks) return [null, []];
  const tklst = [];
  for (const t of ct.browserview.defaultassaytracks) {
    const p = ct.p2st[t.level1];
    if (!p) continue;
    if (t.level2) {
      const p2 = p[t.level2];
      if (!p2) continue;
      if (!p2.tktemplate) continue;
      for (const tt of p2.tktemplate) {
        if (tt.assayname == t.assay) {
          tklst.push(tt);
          if (t.justone) {
            break;
          }
        }
      }
    } else {
      for (const st in p) {
        const p2 = p[st];
        if (p2.tktemplate) {
          for (const tt of p2.tktemplate) {
            if (tt.assayname == t.assay) {
              tklst.push(tt);
            }
          }
        }
      }
    }
  }
  return [null, tklst];
}
export {
  tpui as default
};
//# sourceMappingURL=tp.ui-T7FVMTGQ.js.map
