import { t as layout } from "./dagre-VYEPqXIV.js";
import { n as isUndefined_default, t as Graph } from "./graphlib-CVPKjKCS.js";
import { t as clone_default } from "./clone-BuIIsfA8.js";
import { i as map_default } from "./min-BNz2lZfk.js";
import "./purify.es-DT70lfR0.js";
import "./chunk-S3R3BYOJ-mQeCz5CE.js";
import { i as log, r as __name } from "./src-Bf2iLOlr.js";
import { b as getConfig2 } from "./chunk-ABZYJK2D-D0cLy8Bb.js";
import "./chunk-HN2XXSSU-E3n-Ys7Z.js";
import { t as getSubGraphTitleMargins } from "./chunk-CVBHYZKI-B_c5YBcW.js";
import "./chunk-ATLVNIR6-BXsEjlHF.js";
import "./dist-BGdYVvOu.js";
import "./chunk-JA3XYJ7Z-D6c6cOBG.js";
import { a as insertNode, c as positionNode, i as insertCluster, l as setNodeElem, n as clear2, t as clear$1, u as updateNodeBounds } from "./chunk-JZLCHNYA-BvsPHJmL.js";
import { a as positionEdgeLabel, i as markers_default, n as insertEdge, r as insertEdgeLabel, t as clear } from "./chunk-QXUST7PY-DV8yRwBd.js";
function write(r) {
  var w = {
    options: {
      directed: r.isDirected(),
      multigraph: r.isMultigraph(),
      compound: r.isCompound()
    },
    nodes: writeNodes(r),
    edges: writeEdges(r)
  };
  return isUndefined_default(r.graph()) || (w.value = clone_default(r.graph())), w;
}
function writeNodes(r) {
  return map_default(r.nodes(), function(w) {
    var T = r.node(w), E = r.parent(w), D = { v: w };
    return isUndefined_default(T) || (D.value = T), isUndefined_default(E) || (D.parent = E), D;
  });
}
function writeEdges(r) {
  return map_default(r.edges(), function(w) {
    var T = r.edge(w), E = {
      v: w.v,
      w: w.w
    };
    return isUndefined_default(w.name) || (E.name = w.name), isUndefined_default(T) || (E.value = T), E;
  });
}
var clusterDb = /* @__PURE__ */ new Map(), descendants = /* @__PURE__ */ new Map(), parents = /* @__PURE__ */ new Map(), clear4 = /* @__PURE__ */ __name(() => {
  descendants.clear(), parents.clear(), clusterDb.clear();
}, "clear"), isDescendant = /* @__PURE__ */ __name((r, C) => {
  let w = descendants.get(C) || [];
  return log.trace("In isDescendant", C, " ", r, " = ", w.includes(r)), w.includes(r);
}, "isDescendant"), edgeInCluster = /* @__PURE__ */ __name((r, C) => {
  let w = descendants.get(C) || [];
  return log.info("Descendants of ", C, " is ", w), log.info("Edge is ", r), r.v === C || r.w === C ? false : w ? w.includes(r.v) || isDescendant(r.v, C) || isDescendant(r.w, C) || w.includes(r.w) : (log.debug("Tilt, ", C, ",not in descendants"), false);
}, "edgeInCluster"), copy = /* @__PURE__ */ __name((r, C, w, T) => {
  log.warn("Copying children of ", r, "root", T, "data", C.node(r), T);
  let E = C.children(r) || [];
  r !== T && E.push(r), log.warn("Copying (nodes) clusterId", r, "nodes", E), E.forEach((E2) => {
    if (C.children(E2).length > 0) copy(E2, C, w, T);
    else {
      let O = C.node(E2);
      log.info("cp ", E2, " to ", T, " with parent ", r), w.setNode(E2, O), T !== C.parent(E2) && (log.warn("Setting parent", E2, C.parent(E2)), w.setParent(E2, C.parent(E2))), r !== T && E2 !== r ? (log.debug("Setting parent", E2, r), w.setParent(E2, r)) : (log.info("In copy ", r, "root", T, "data", C.node(r), T), log.debug("Not Setting parent for node=", E2, "cluster!==rootId", r !== T, "node!==clusterId", E2 !== r));
      let k = C.edges(E2);
      log.debug("Copying Edges", k), k.forEach((E3) => {
        log.info("Edge", E3);
        let O2 = C.edge(E3.v, E3.w, E3.name);
        log.info("Edge data", O2, T);
        try {
          edgeInCluster(E3, T) ? (log.info("Copying as ", E3.v, E3.w, O2, E3.name), w.setEdge(E3.v, E3.w, O2, E3.name), log.info("newGraph edges ", w.edges(), w.edge(w.edges()[0]))) : log.info("Skipping copy of edge ", E3.v, "-->", E3.w, " rootId: ", T, " clusterId:", r);
        } catch (r2) {
          log.error(r2);
        }
      });
    }
    log.debug("Removing node", E2), C.removeNode(E2);
  });
}, "copy"), extractDescendants = /* @__PURE__ */ __name((r, C) => {
  let w = C.children(r), T = [...w];
  for (let E of w) parents.set(E, r), T = [...T, ...extractDescendants(E, C)];
  return T;
}, "extractDescendants"), findCommonEdges = /* @__PURE__ */ __name((r, C, w) => {
  let T = r.edges().filter((r2) => r2.v === C || r2.w === C), E = r.edges().filter((r2) => r2.v === w || r2.w === w), D = T.map((r2) => ({
    v: r2.v === C ? w : r2.v,
    w: r2.w === C ? C : r2.w
  })), O = E.map((r2) => ({
    v: r2.v,
    w: r2.w
  }));
  return D.filter((r2) => O.some((C2) => r2.v === C2.v && r2.w === C2.w));
}, "findCommonEdges"), findNonClusterChild = /* @__PURE__ */ __name((r, C, w) => {
  let T = C.children(r);
  if (log.trace("Searching children of id ", r, T), T.length < 1) return r;
  let E;
  for (let r2 of T) {
    let T2 = findNonClusterChild(r2, C, w), D = findCommonEdges(C, w, T2);
    if (T2) if (D.length > 0) E = T2;
    else return T2;
  }
  return E;
}, "findNonClusterChild"), getAnchorId = /* @__PURE__ */ __name((r) => !clusterDb.has(r) || !clusterDb.get(r).externalConnections ? r : clusterDb.has(r) ? clusterDb.get(r).id : r, "getAnchorId"), adjustClustersAndEdges = /* @__PURE__ */ __name((r, C) => {
  if (!r || C > 10) {
    log.debug("Opting out, no graph ");
    return;
  } else log.debug("Opting in, graph ");
  r.nodes().forEach(function(C2) {
    r.children(C2).length > 0 && (log.warn("Cluster identified", C2, " Replacement id in edges: ", findNonClusterChild(C2, r, C2)), descendants.set(C2, extractDescendants(C2, r)), clusterDb.set(C2, {
      id: findNonClusterChild(C2, r, C2),
      clusterData: r.node(C2)
    }));
  }), r.nodes().forEach(function(C2) {
    let w = r.children(C2), T = r.edges();
    w.length > 0 ? (log.debug("Cluster identified", C2, descendants), T.forEach((r2) => {
      isDescendant(r2.v, C2) ^ isDescendant(r2.w, C2) && (log.warn("Edge: ", r2, " leaves cluster ", C2), log.warn("Descendants of XXX ", C2, ": ", descendants.get(C2)), clusterDb.get(C2).externalConnections = true);
    })) : log.debug("Not a cluster ", C2, descendants);
  });
  for (let C2 of clusterDb.keys()) {
    let w = clusterDb.get(C2).id, T = r.parent(w);
    T !== C2 && clusterDb.has(T) && !clusterDb.get(T).externalConnections && (clusterDb.get(C2).id = T);
  }
  r.edges().forEach(function(C2) {
    let w = r.edge(C2);
    log.warn("Edge " + C2.v + " -> " + C2.w + ": " + JSON.stringify(C2)), log.warn("Edge " + C2.v + " -> " + C2.w + ": " + JSON.stringify(r.edge(C2)));
    let T = C2.v, E = C2.w;
    if (log.warn("Fix XXX", clusterDb, "ids:", C2.v, C2.w, "Translating: ", clusterDb.get(C2.v), " --- ", clusterDb.get(C2.w)), clusterDb.get(C2.v) || clusterDb.get(C2.w)) {
      if (log.warn("Fixing and trying - removing XXX", C2.v, C2.w, C2.name), T = getAnchorId(C2.v), E = getAnchorId(C2.w), r.removeEdge(C2.v, C2.w, C2.name), T !== C2.v) {
        let E2 = r.parent(T);
        clusterDb.get(E2).externalConnections = true, w.fromCluster = C2.v;
      }
      if (E !== C2.w) {
        let T2 = r.parent(E);
        clusterDb.get(T2).externalConnections = true, w.toCluster = C2.w;
      }
      log.warn("Fix Replacing with XXX", T, E, C2.name), r.setEdge(T, E, w, C2.name);
    }
  }), log.warn("Adjusted Graph", write(r)), extractor(r, 0), log.trace(clusterDb);
}, "adjustClustersAndEdges"), extractor = /* @__PURE__ */ __name((r, C) => {
  var _a, _b;
  if (log.warn("extractor - ", C, write(r), r.children("D")), C > 10) {
    log.error("Bailing out");
    return;
  }
  let T = r.nodes(), E = false;
  for (let C2 of T) {
    let w = r.children(C2);
    E || (E = w.length > 0);
  }
  if (!E) {
    log.debug("Done, no node has children", r.nodes());
    return;
  }
  log.debug("Nodes = ", T, C);
  for (let E2 of T) if (log.debug("Extracting node", E2, clusterDb, clusterDb.has(E2) && !clusterDb.get(E2).externalConnections, !r.parent(E2), r.node(E2), r.children("D"), " Depth ", C), !clusterDb.has(E2)) log.debug("Not a cluster", E2, C);
  else if (!clusterDb.get(E2).externalConnections && r.children(E2) && r.children(E2).length > 0) {
    log.warn("Cluster without external connections, without a parent and with children", E2, C);
    let T2 = r.graph().rankdir === "TB" ? "LR" : "TB";
    ((_b = (_a = clusterDb.get(E2)) == null ? void 0 : _a.clusterData) == null ? void 0 : _b.dir) && (T2 = clusterDb.get(E2).clusterData.dir, log.warn("Fixing dir", clusterDb.get(E2).clusterData.dir, T2));
    let O = new Graph({
      multigraph: true,
      compound: true
    }).setGraph({
      rankdir: T2,
      nodesep: 50,
      ranksep: 50,
      marginx: 8,
      marginy: 8
    }).setDefaultEdgeLabel(function() {
      return {};
    });
    log.warn("Old graph before copy", write(r)), copy(E2, r, O, E2), r.setNode(E2, {
      clusterNode: true,
      id: E2,
      clusterData: clusterDb.get(E2).clusterData,
      label: clusterDb.get(E2).label,
      graph: O
    }), log.warn("New graph after copy node: (", E2, ")", write(O)), log.debug("Old graph after copy", write(r));
  } else log.warn("Cluster ** ", E2, " **not meeting the criteria !externalConnections:", !clusterDb.get(E2).externalConnections, " no parent: ", !r.parent(E2), " children ", r.children(E2) && r.children(E2).length > 0, r.children("D"), C), log.debug(clusterDb);
  T = r.nodes(), log.warn("New list of nodes", T);
  for (let w of T) {
    let T2 = r.node(w);
    log.warn(" Now next level", w, T2), (T2 == null ? void 0 : T2.clusterNode) && extractor(T2.graph, C + 1);
  }
}, "extractor"), sorter = /* @__PURE__ */ __name((r, C) => {
  if (C.length === 0) return [];
  let w = Object.assign([], C);
  return C.forEach((C2) => {
    let T = sorter(r, r.children(C2));
    w = [...w, ...T];
  }), w;
}, "sorter"), sortNodesByHierarchy = /* @__PURE__ */ __name((r) => sorter(r, r.children()), "sortNodesByHierarchy"), recursiveRender = /* @__PURE__ */ __name(async (C, w, T, E, k, M) => {
  log.warn("Graph in recursive render:XAX", write(w), k);
  let N = w.graph().rankdir;
  log.trace("Dir in recursive render - dir:", N);
  let P = C.insert("g").attr("class", "root");
  w.nodes() ? log.info("Recursive render XXX", w.nodes()) : log.info("No nodes found for", w), w.edges().length > 0 && log.info("Recursive edges", w.edge(w.edges()[0]));
  let F = P.insert("g").attr("class", "clusters"), I = P.insert("g").attr("class", "edgePaths"), L = P.insert("g").attr("class", "edgeLabels"), R = P.insert("g").attr("class", "nodes");
  await Promise.all(w.nodes().map(async function(r) {
    let C2 = w.node(r);
    if (k !== void 0) {
      let C3 = JSON.parse(JSON.stringify(k.clusterData));
      log.trace("Setting data for parent cluster XXX\n Node.id = ", r, "\n data=", C3.height, "\nParent cluster", k.height), w.setNode(k.id, C3), w.parent(r) || (log.trace("Setting parent", r, k.id), w.setParent(r, k.id, C3));
    }
    if (log.info("(Insert) Node XXX" + r + ": " + JSON.stringify(w.node(r))), C2 == null ? void 0 : C2.clusterNode) {
      log.info("Cluster identified XBX", r, C2.width, w.node(r));
      let { ranksep: O, nodesep: k2 } = w.graph();
      C2.graph.setGraph({
        ...C2.graph.graph(),
        ranksep: O + 25,
        nodesep: k2
      });
      let A = await recursiveRender(R, C2.graph, T, E, w.node(r), M), j = A.elem;
      updateNodeBounds(C2, j), C2.diff = A.diff || 0, log.info("New compound node after recursive render XAX", r, "width", C2.width, "height", C2.height), setNodeElem(j, C2);
    } else w.children(r).length > 0 ? (log.trace("Cluster - the non recursive path XBX", r, C2.id, C2, C2.width, "Graph:", w), log.trace(findNonClusterChild(C2.id, w)), clusterDb.set(C2.id, {
      id: findNonClusterChild(C2.id, w),
      node: C2
    })) : (log.trace("Node - the non recursive path XAX", r, R, w.node(r), N), await insertNode(R, w.node(r), {
      config: M,
      dir: N
    }));
  })), await (/* @__PURE__ */ __name(async () => {
    let r = w.edges().map(async function(r2) {
      let C2 = w.edge(r2.v, r2.w, r2.name);
      log.info("Edge " + r2.v + " -> " + r2.w + ": " + JSON.stringify(r2)), log.info("Edge " + r2.v + " -> " + r2.w + ": ", r2, " ", JSON.stringify(w.edge(r2))), log.info("Fix", clusterDb, "ids:", r2.v, r2.w, "Translating: ", clusterDb.get(r2.v), clusterDb.get(r2.w)), await insertEdgeLabel(L, C2);
    });
    await Promise.all(r);
  }, "processEdges"))(), log.info("Graph before layout:", JSON.stringify(write(w))), log.info("############################################# XXX"), log.info("###                Layout                 ### XXX"), log.info("############################################# XXX"), layout(w), log.info("Graph after layout:", JSON.stringify(write(w)));
  let z = 0, { subGraphTitleTotalMargin: B } = getSubGraphTitleMargins(M);
  return await Promise.all(sortNodesByHierarchy(w).map(async function(r) {
    var _a;
    let C2 = w.node(r);
    if (log.info("Position XBX => " + r + ": (" + C2.x, "," + C2.y, ") width: ", C2.width, " height: ", C2.height), C2 == null ? void 0 : C2.clusterNode) C2.y += B, log.info("A tainted cluster node XBX1", r, C2.id, C2.width, C2.height, C2.x, C2.y, w.parent(r)), clusterDb.get(C2.id).node = C2, positionNode(C2);
    else if (w.children(r).length > 0) {
      log.info("A pure cluster node XBX1", r, C2.id, C2.x, C2.y, C2.width, C2.height, w.parent(r)), C2.height += B, w.node(C2.parentId);
      let T2 = (C2 == null ? void 0 : C2.padding) / 2 || 0, E2 = ((_a = C2 == null ? void 0 : C2.labelBBox) == null ? void 0 : _a.height) || 0, O = E2 - T2 || 0;
      log.debug("OffsetY", O, "labelHeight", E2, "halfPadding", T2), await insertCluster(F, C2), clusterDb.get(C2.id).node = C2;
    } else {
      let r2 = w.node(C2.parentId);
      C2.y += B / 2, log.info("A regular node XBX1 - using the padding", C2.id, "parent", C2.parentId, C2.width, C2.height, C2.x, C2.y, "offsetY", C2.offsetY, "parent", r2, r2 == null ? void 0 : r2.offsetY, C2), positionNode(C2);
    }
  })), w.edges().forEach(function(r) {
    let C2 = w.edge(r);
    log.info("Edge " + r.v + " -> " + r.w + ": " + JSON.stringify(C2), C2), C2.points.forEach((r2) => r2.y += B / 2), positionEdgeLabel(C2, insertEdge(I, C2, clusterDb, T, w.node(r.v), w.node(r.w), E));
  }), w.nodes().forEach(function(r) {
    let C2 = w.node(r);
    log.info(r, C2.type, C2.diff), C2.isGroup && (z = C2.diff);
  }), log.warn("Returning from recursive render XAX", P, z), {
    elem: P,
    diff: z
  };
}, "recursiveRender"), render = /* @__PURE__ */ __name(async (r, C) => {
  var _a, _b, _c, _d, _e, _f;
  let T = new Graph({
    multigraph: true,
    compound: true
  }).setGraph({
    rankdir: r.direction,
    nodesep: ((_a = r.config) == null ? void 0 : _a.nodeSpacing) || ((_c = (_b = r.config) == null ? void 0 : _b.flowchart) == null ? void 0 : _c.nodeSpacing) || r.nodeSpacing,
    ranksep: ((_d = r.config) == null ? void 0 : _d.rankSpacing) || ((_f = (_e = r.config) == null ? void 0 : _e.flowchart) == null ? void 0 : _f.rankSpacing) || r.rankSpacing,
    marginx: 8,
    marginy: 8
  }).setDefaultEdgeLabel(function() {
    return {};
  }), E = C.select("g");
  markers_default(E, r.markers, r.type, r.diagramId), clear2(), clear(), clear$1(), clear4(), r.nodes.forEach((r2) => {
    T.setNode(r2.id, { ...r2 }), r2.parentId && T.setParent(r2.id, r2.parentId);
  }), log.debug("Edges:", r.edges), r.edges.forEach((r2) => {
    if (r2.start === r2.end) {
      let C2 = r2.start, w = C2 + "---" + C2 + "---1", E2 = C2 + "---" + C2 + "---2", D = T.node(C2);
      T.setNode(w, {
        domId: w,
        id: w,
        parentId: D.parentId,
        labelStyle: "",
        label: "",
        padding: 0,
        shape: "labelRect",
        style: "",
        width: 10,
        height: 10
      }), T.setParent(w, D.parentId), T.setNode(E2, {
        domId: E2,
        id: E2,
        parentId: D.parentId,
        labelStyle: "",
        padding: 0,
        shape: "labelRect",
        label: "",
        style: "",
        width: 10,
        height: 10
      }), T.setParent(E2, D.parentId);
      let O2 = structuredClone(r2), k = structuredClone(r2), A = structuredClone(r2);
      O2.label = "", O2.arrowTypeEnd = "none", O2.id = C2 + "-cyclic-special-1", k.arrowTypeStart = "none", k.arrowTypeEnd = "none", k.id = C2 + "-cyclic-special-mid", A.label = "", D.isGroup && (O2.fromCluster = C2, A.toCluster = C2), A.id = C2 + "-cyclic-special-2", A.arrowTypeStart = "none", T.setEdge(C2, w, O2, C2 + "-cyclic-special-0"), T.setEdge(w, E2, k, C2 + "-cyclic-special-1"), T.setEdge(E2, C2, A, C2 + "-cyc<lic-special-2");
    } else T.setEdge(r2.start, r2.end, { ...r2 }, r2.id);
  }), log.warn("Graph at first:", JSON.stringify(write(T))), adjustClustersAndEdges(T), log.warn("Graph after XAX:", JSON.stringify(write(T)));
  let O = getConfig2();
  await recursiveRender(E, T, r.type, r.diagramId, void 0, O);
}, "render");
export {
  render
};
