editEdgeMode() {
    // when using the gui, enable edit mode if it wasn't already.
    if (this.editMode !== true) {
      this.enableEditMode();
    }

    // restore the state of any bound functions or events, remove control nodes, restore physics
    this._clean();

    this.inMode = "editEdge";
    if (
      typeof this.options.editEdge === "object" &&
      typeof this.options.editEdge.editWithoutDrag === "function"
    ) {
      this.edgeBeingEditedId = this.selectionHandler.getSelectedEdgeIds()[0];
      if (this.edgeBeingEditedId !== undefined) {
        const edge = this.body.edges[this.edgeBeingEditedId];
        this._performEditEdge(edge.from.id, edge.to.id);
        return;
      }
    }
    if (this.guiEnabled === true) {
      const locale = this.options.locales[this.options.locale];
      this.manipulationDOM = {};
      this._createBackButton(locale);
      this._createSeperator();
      this._createDescription(
        locale["editEdgeDescription"] ||
          this.options.locales["en"]["editEdgeDescription"]
      );

      // bind the close button
      this._bindElementEvents(this.closeDiv, this.toggleEditMode.bind(this));
    }

    this.edgeBeingEditedId = this.selectionHandler.getSelectedEdgeIds()[0];
    if (this.edgeBeingEditedId !== undefined) {
      const edge = this.body.edges[this.edgeBeingEditedId];

      // create control nodes
      const controlNodeFrom = this._getNewTargetNode(edge.from.x, edge.from.y);
      const controlNodeTo = this._getNewTargetNode(edge.to.x, edge.to.y);

      this.temporaryIds.nodes.push(controlNodeFrom.id);
      this.temporaryIds.nodes.push(controlNodeTo.id);

      this.body.nodes[controlNodeFrom.id] = controlNodeFrom;
      this.body.nodeIndices.push(controlNodeFrom.id);
      this.body.nodes[controlNodeTo.id] = controlNodeTo;
      this.body.nodeIndices.push(controlNodeTo.id);

      // temporarily overload UI functions, cleaned up automatically because of _temporaryBindUI
      this._temporaryBindUI("onTouch", this._controlNodeTouch.bind(this)); // used to get the position
      this._temporaryBindUI("onTap", () => {}); // disabled
      this._temporaryBindUI("onHold", () => {}); // disabled
      this._temporaryBindUI(
        "onDragStart",
        this._controlNodeDragStart.bind(this)
      ); // used to select control node
      this._temporaryBindUI("onDrag", this._controlNodeDrag.bind(this)); // used to drag control node
      this._temporaryBindUI("onDragEnd", this._controlNodeDragEnd.bind(this)); // used to connect or revert control nodes
      this._temporaryBindUI("onMouseMove", () => {}); // disabled

      // create function to position control nodes correctly on movement
      // automatically cleaned up because we use the temporary bind
      this._temporaryBindEvent("beforeDrawing", (ctx) => {
        const positions = edge.edgeType.findBorderPositions(ctx);
        if (controlNodeFrom.selected === false) {
          controlNodeFrom.x = positions.from.x;
          controlNodeFrom.y = positions.from.y;
        }
        if (controlNodeTo.selected === false) {
          controlNodeTo.x = positions.to.x;
          controlNodeTo.y = positions.to.y;
        }
      });

      this.body.emitter.emit("_redraw");
    } else {
      this.showManipulatorToolbar();
    }
  }
create the toolbar to edit edges