code: function Graph(opts) {
    this._isDirected = lodash_1$1.has(opts, "directed") ? opts.directed : true;
    this._isMultigraph = lodash_1$1.has(opts, "multigraph") ? opts.multigraph : false;
    this._isCompound = lodash_1$1.has(opts, "compound") ? opts.compound : false;
  
    // Label for the graph itself
    this._label = undefined;
  
    // Defaults to be set when creating a new node
    this._defaultNodeLabelFn = lodash_1$1.constant(undefined);
  
    // Defaults to be set when creating a new edge
    this._defaultEdgeLabelFn = lodash_1$1.constant(undefined);
  
    // v -> label
    this._nodes = {};
  
    if (this._isCompound) {
      // v -> parent
      this._parent = {};
  
      // v -> children
      this._children = {};
      this._children[GRAPH_NODE] = {};
    }
  
    // v -> edgeObj
    this._in = {};
  
    // u -> v -> Number
    this._preds = {};
  
    // v -> edgeObj
    this._out = {};
  
    // v -> w -> Number
    this._sucs = {};
  
    // e -> edgeObj
    this._edgeObjs = {};
  
    // e -> label
    this._edgeLabels = {};
  }
docs: Implementation notes:  * Node id query functions should return string ids for the nodes * Edge id query functions should return an "edgeObj", edge object, that is composed of enough information to uniquely identify an edge: {v, w, name}. * Internally we use an "edgeId", a stringified form of the edgeObj, to reference edges. This is because we need a performant way to look these edges up and, object properties, which have string keys, are the closest we're going to get to a performant hashtable in JavaScript.